Working with Google Maps API in ASP.NET

Recently I have been working on a project where I needed to make use of some geographical data and I decided to use Google Maps for that. So, in this particular tutorial I will explain how one can start working with the Google Maps API in ASP.NET. Basically, the following topic will be covered:

  • How to find a place on the map by address
  • How to let a user choose a place on the map and retrieve its coordinates and save them in a database.

What is Google Maps API?

But first we need to learn some basic of working with Google Maps. As a matter of fact when integrating Google Maps in your application you have to use the Google Maps API, which is in fact just a set of JavaScript functions. As a result you don’t interact directly with the Google Maps API in ASP.NET, I mean server-side, but instead you place your code to client-side and work with JavaScript.

architecture

So, the Google Maps can be used with any server-side technology/language, like ASP.NET, PHP, Ruby on Rails, Python and etc., but this tutorial is about ASP.NET.

Getting Google Maps API Key

The first important step of getting started with the Google Maps API is obtaining the Google Maps API Key. Don’t worry it is free of charge and you receive the key immediately after filling in a form here. Creating a Simple Map Okay, now it’s the right time to open Visual Studio and create a new web site. Then, add the following code to the <head> tag:

<script src="http://maps.google.com/maps?file=api&amp;v=2&amp;key=<YOUR_API_KEY>&sensor=false"
        type="text/javascript"></script>
<script type="text/javascript">
    function initialize() {
        if (GBrowserIsCompatible()) {
            var map = new GMap2(document.getElementById("map"));
            map.setCenter(new GLatLng(51.5, -0.1), 10);
            map.setUIToDefault();
        }
    }

Don’t forget to change <YOUR_API_KEY> to an appropriate value. As you can see we have just one function called initialize() that creates a new instance of the map object. We also pass the object – a div – that will be a map container. Then, we invoke the setCenter() method that receives two arguments –coordinates and a zoom level. The setUIToDefault() method just adds the UI manipulators, if you remove or comment that line, you will receive a bare map without any UI controls. Also, you need to add some code that will run the initialize() function and the HTML code for the map container.

<body onload="initialize()" onunload="GUnload()">
  <form id="form1" runat="server">
    <div id="map" style="width: 500px; height: 500px"></div>
  </form>
</body>

The code is pretty self-explanatory, it just adds the handlers for the onLoad and onUnLoad events of the page and also we put a div that will contain the map, you can adjust its width and height in order to get a bigger or a smaller map. After compiling this page you should see a map similar to this one:

map

Finding a place by its address

Well, it was pretty simple, but in real life project you usually have to find a place on the maps by its address. This is also possible with the Google Maps API. All you have to do is to make use of the GClientGeocoder class and its method called getLatLang() that accepts two parameters:

  • address – the address to look for
  • function – a callback function with one parameter point that posses the coordinates of the found place

So, if we want to find a house where Sherlock Holmes lived we have to write the following code:

<script type="text/javascript">
        var map;
        var geocoder;
        function initialize() {
            if (GBrowserIsCompatible()) {
                map = new GMap2(document.getElementById("map"));
                map.setCenter(new GLatLng(51.5, -0.1), 10);
                map.setUIToDefault();

                geocoder = new GClientGeocoder();

                showAddress("221B Baker Street, London, United Kingdom");
            }
        }
        function showAddress(address) {
            geocoder.getLatLng(
                address,
                function (point) {
                    if (!point) {
                        alert(address + " not found");
                    }
                    else {
                        map.setCenter(point, 15);
                        var marker = new GMarker(point);
                        map.addOverlay(marker);
                        marker.openInfoWindow(address);
                    }
                }
            );
        }
</script>

Also, we create a map overlay that will contain the address information, for this purpose we create an instance of the GMarker class and use the openInfoWindow() method. User Interaction with Map Okay, but what if we want to let user enter an address in a form and find its on the map? No problems! Just add the necessary field and write an event-handler.

<script type="text/javascript">
        var map;
        var geocoder;
        function initialize() {
            if (GBrowserIsCompatible()) {
                map = new GMap2(document.getElementById("map"));
                map.setCenter(new GLatLng(51.5, -0.1), 10);
                map.setUIToDefault();

                geocoder = new GClientGeocoder();
            }
        }
        function showAddress() {
            var txtAddress = document.getElementById("<%=txtAddress.ClientID %>");
            var address = txtAddress.value;

            geocoder.getLatLng(
                address,
                function (point) {
                    if (!point) {
                        alert(address + " not found");
                    }
                    else {
                        map.setCenter(point, 15);
                        var marker = new GMarker(point);
                        map.addOverlay(marker);
                        marker.openInfoWindow(address);
                    }
                }
            );
        }
        </script>
</head>
<body onload="initialize()" onunload="GUnload()">
    <form id="form1" runat="server">
        <div>
            <asp:TextBox ID="txtAddress" runat="server" />
            <input type="button" value="Find" onclick="showAddress();" />
        </div>

        <div id="map" style="width: 500px; height: 500px"></div>
    </form>
</body>

Letting Users to Manually Select a Place on the Map

Well, finding a place by its address is certainly cool, but we can add yet another level of interactivity to our map. Basically, we can let users to use manually choose a place on the map by just dragging a marker.

<script type="text/javascript">
        var map;
        var geocoder;
        function initialize() {
            if (GBrowserIsCompatible()) {
                map = new GMap2(document.getElementById("map"));
                var center = new GLatLng(51.5, -0.1);
                map.setCenter(center, 10);
                map.setUIToDefault();

                var marker = new GMarker(center, { draggable: true });
                map.addOverlay(marker);
                marker.openInfoWindow("Drag the marker to a specific position");

                GEvent.addListener(marker, "dragstart", function() {
                    map.closeInfoWindow();
                });

                GEvent.addListener(marker, "dragend", function() {
                    var hdnLat = document.getElementById("<%=hdnLat.ClientID %>");
                    var hdnLng = document.getElementById("<%=hdnLng.ClientID %>");

                    hdnLat.value = this.getLatLng().lat();
                    hdnLng.value = this.getLatLng().lng();

                    marker.openInfoWindow("New position has been set");
                });
            }
        }
        </script>

</head>
<body onload="initialize()" onunload="GUnload()">
    <form id="form1" runat="server">
        <asp:HiddenField ID="hdnLat" runat="server" />
        <asp:HiddenField ID="hdnLng" runat="server" />
        <div id="map" style="width: 500px; height: 500px"></div>
        <asp:Button ID="btnSubmit" runat="server" Text="Submit"
            onclick="btnSubmit_Click" />
    </form>
</body>

If you look at the HTML code, then you will notice that we have added to hidden field that will contain the coordinates of a chosen place, so the first field is for keeping the latitude and the second one is for keeping the longitude. This time when creating a marker we set its options and one of the option is “draggable: true”, so it lets users to drag the marker over the map. Then, we should add event handlers, the main event is “dragend”. It occurs ever time a user place a marker on a new place. As a result, in its event handler we receive the coordinates of a new position and save them in the hidden fields. Also, we wrote an event handler for the “dragstart” event, just to close the info window while dragging the marker. In a real world application there would be some server-side code that would place the received coordinates into a database, but in this particular case, we will just output them:

protected void btnSubmit_Click(object sender, EventArgs e)
{
    Response.Write("Latitude: " + hdnLat.Value + " Longitude: " + hdnLng.Value);
}

Passing the Coordinates from Server-Side to Google Maps

Now, what if we have the coordinates stores somewhere in the database and want to point to that place on the map? Well, it’s still not difficult. We just have to pass the values from server-side to JavaScript.

<script type="text/javascript">
    var map;
    function initialize() {
        if (GBrowserIsCompatible()) {
            map = new GMap2(document.getElementById("map"));

            var lat = <asp:Literal ID="ltrLat" runat="server" />;
            var lng = <asp:Literal ID="ltrLng" runat="server" />;

            var center = new GLatLng(lat, lng);

            map.setCenter(center, 10);
            map.setUIToDefault();

            var marker = new GMarker(center);
            map.addOverlay(marker);
            marker.openInfoWindow("Here");
        }
    }
</script>

The easiest way to achieve this is to use the ASP.NET Literal controls that doesn’t generate any tags around their values. Since, those Literal controls are outside of the form tag, we have to use the FindControl() method to access them in code-behind:

protected void Page_Load(object sender, EventArgs e)
{
    Literal ltrLat = (Literal)FindControl("ltrLat");
    Literal ltrLng = (Literal)FindControl("ltrLng");

    ltrLat.Text = "51";
    ltrLng.Text = "0";
}

Conclusion

In this tutorial we have covered the basics of working with the Google Maps API. We have learnt how to add a map on a page, how to use geo coding for finding a place by its address on the map. We have also got to know how we can let users interact with a map by dragging a marker and how to receive the marker coordinates and store them on server-side. Finally, we have learnt how to pass the coordinates stored on server-side to the Google Maps API and point to that place on a map.

Also, in this tutorial version 2 of the API was covered, however the 3rd version is currently in Google Labs.

Resources

The main resource for the developers willing to work with the Google Maps API is certainly the Google Code reference page.

Mike Borozdin (Twitter)
28 July 2009

The opinions expressed herein are my own personal opinions and do not represent my employer's view in any way. My personal thoughts tend to change, hence the articles in this blog might not provide an accurate reflection of my present standpoint.

© Mike Borozdin