How to implement Google Maps on your page

1. useful links:
- Main Google Maps API intro page
- All you need to understand about Maps and kml
- Main Google Maps API documentation
- Google Maps example code
- Signup for a free Google Maps key
2. Get a key from Google (see link above), and include the relevant JavaScript code file:

<script src="http://maps.google.com/maps?file=api&v=3.x&key=xxxxxxxxxxxxxxxxxx" type="text/javascript"></script>
This includes all of the files you require to run Google Maps on your page. The API version in the url may be updated from time to time, but you will be notified by Google when this happens. Your key will work on a single domain/directory, but there are no other restrictions.
3. You need a div on your page where the map will be, and the size is up to you. If you only have one map on a page, call it 'map' to save confusion.

<div id="map" style="width: 462px; height: 350px"></div>
3. You need a function which is called onLoad on the page (you can do this by adding the call to it as a Startup script in C# or by just calling it directly at the bottom of the page) which sets up the div to contain the map. If you want custom markers, points, or other floating elements on your map, then you will need to call a function to set these up as part of the load process (as well as adding event handlers for when certain events happen, such as move, zoom, if the set of points or floating elements needs to change as you move around the map):

function load() {
  if (GBrowserIsCompatible()) {
    map = new GMap2(document.getElementById("map"),{ mapTypes: [G_PHYSICAL_MAP] });
    map.enableDoubleClickZoom();
    map.enableContinuousZoom();
    map.addControl(new GSmallMapControl());
    map.setCenter(new GLatLng(startLat,startLon), 9);
    GEvent.addListener(map, "moveend", loadPoints );  // optional if you want custom points
    GEvent.addListener(map, "load", loadPoints );  // optional if you want custom points
    GEvent.addListener(map, "zoom", loadPoints );  // optional if you want custom points
    loadPoints();   // optional if you want custom points
  }
}
GBrowserIsCompatible()is an API function which protects the code from browsers which won't support Google Maps.
GMap2is the main map object
[G_PHYSICAL_MAP]is the map type (physical/terrain) - the others are G_NORMAL_MAP, G_SATELLITE_MAP, G_HYBRID_MAP
map.enableDoubleClickZoom()and map.enableDoubleClickZoom() are map behaviour features
GSmallMapControl()is the small control which allows users to flip between map types
map.setCenter()allows you to set an initial latitude, longitude and zoom
GEvent.addListener()allows you to call a function whenever a certain action happens, such as load, zoom or move
loadPointsthe name of a function to call when a certain event happens (or when the page loads)
4. If you are going for custom points on your map, then you get them from a file called a kml file. This is a file in a special format suitable for geomapping applications. This can be a fixed static file, or more interestingly, a script/program which returns a kml file. Because you potentially have thousands of points over the entire country or world, you may not want to return them all, every time the map is zoomed or moved. Instead, you could pass your script some arguments (such as the latitude and longitude of the bounds of the map being displayed) and only return the relevant points within those bounds such as:

function loadPoints()
{
    var bounds = map.getBounds();
    var p1 = bounds.getSouthWest();
    var p2 = bounds.getNorthEast();
    var url = "MyKML.ashx?lat1=" + p1.lat() + "&lat2=" + p2.lat() + "&lon1=" + p1.lng() + "&lon2=" + p2.lng();
    GDownloadUrl(url,  receivePoints);
}
GDownloadUrl uses AJAX callbacks to go fetch the contents of the url and calls the function receivePoints with the results as a single large string. This will happen every time one of the events described above fires, so be careful.
5. The function which receives the KML data from the external file/script has to decode it and for each point, add a Google Maps custom marker to the chart. The easiest way to do this is to not worry so much about the KML structure, but simply to return the points as a JSON string. We'll look at the formatting of this in a moment, for now, just assume that when we eval the returned json string, it creates a JavaScript array of Point objects with their own properties such as .latitude, .longitude, .title, .html (for the popup window, if any) etc but first let us look at creating two types of marker point

Type 1 - simple default marker with popup window

function receivePoints( json )
{
    eval( "var points = " + json );
    for( var i= 0; i<points.length; i++ )
    {
        var marker = new GMarker( new GLatLng( points[i].latitude, points[i].longitude ),
                                  {'title': points[i].title} );
        map.addOverlay( marker );
        marker.bindInfoWindowHtml( points[i].html );
    }
}
eval just gets the JSON data from the external file and turns it into Google Points. Then we loop through each of these points, and create a new Google Marker object, set up it's position suing the latitude and longitude stored in the Point object, and set up the title text of the box using a JSON options string (this doesn't really do anything except show a tooltip when you hover over the point). The marker is added to the map as an overlay, and then we bind the .html of the point to the InfoWindow, which will be displayed when the user clicks on the point as a huge bubble.
Or if we want to use our own graphic as an icon, and make clicking it do something, it's slightly more complex:

Type 2 - custom icon without popup window but clickable

function receivePoints( json )
{
    eval( "var points = " + json );
    var myIcon = new GIcon(G_DEFAULT_ICON);
    myIcon.image = "http://url.to.the/image.gif";
    var markerOptions = { icon:myIcon };
    for( var i= 0; i<points.length; i++ )
    {
        var thisPoint = new GLatLng( points[i].latitude, points[i].longitude );
        GEvent.addListener(map, "click", function(marker,point) { if(marker) { clickedIcon(marker);} });
        map.addOverlay( new GMarker(thisPoint, markerOptions) );
    }
}
eval just gets the JSON data from the external file and turns it into Google Points. Then we set up a new icon to use, by creating a new default icon image, and then refer to it in the markerOptions JSON string. Then we loop through each of these points, and create a new Google Marker object, with the markerOptions (new Icon). We make the icon clickable by adding an event handler listening for a click on the map - if we have clicked on a marker, we jump out to our own Javascript function clickedIcon(marker) - where we can interrogate the marker object (to find out which one we clicked) and do some action, such as redirecting to another page, zooming the map, opening up our own info window, or whatever.
6. The receive code requires the KML data to be in a specific format which it can decode easily into point objects in Javascript. This is the JSON format, which specifies name:value pairs in a comma separated list. When JavaScript evals JSON, it creates an object with properties according to the names, e.g.

[ {'title':'Hello World', 'latitude':'2324.342', 'longitude':'9344.34', 'html':'<h1>Hello</h1>'} ]
when evaluated using eval("var p = " + json) will create a JavaScript object p with attributes, p.title, p.latitude, p.longitude and p.html, each containing the values specified in the JSON. By specifiying several of these in a row (comma separated, each entity, surrounded by {}) we can create an array of such objects, which JavaScript decodes as an array of object p.

If our script can use, for instance, the bounds of the map passed in as URL arguments to query a database of points, it can build up a JSON list of entities which are relavant to the map, and pass them back in a long string. Simple scripting languages such as perl can just spit back a string as the HTTP Response. For C# you have to set up a Webservice. The following section discusses how to do this.

7. Create a new ashx file in your project - this will be the file called by the JavaScript when it is looking for the KML file. It should look a bit like this:

<%@ WebHandler Language="C#" Class="MyWebServiceClass"  %>

using System;
using System.Text;
using System.Web;

public class MyWebServiceClass : IHttpHandler
{
    public void ProcessRequest(HttpContext context)
    {
        StringBuilder sb = new StringBuilder();
	
        // 1. Get the URL parameters from the Request["var"] objects
        // 2. Query your data source, DataBase etc to get a table of relevant points/data
        // 3. Loop through this data, building up a JSON string in your string builder

	context.Response(sb.ToString());
    }
}
You can use the optional URL parameters to query your datasource, be it files, databases, other webpages, and build up a string of [{ json data}] which you return to the HTTP context. This is fed by the magic of AJAX into your receive function in Javascript, which uses eval to turn it into an array of points, and from there the Google Markers are added to the map.
And that is all there is! When we run the page, the map is displayed, and if we have custom points on the map, they will be drawn on top of the map, scroll with it, and if we have requested it, redraw depending on where on the map we have dragged/zoomed to. The markers can do various things, according to the marker options. We can retrieve the markers from various sources, via static files, scripts or a webservice.