Maps API Workshop
2007-10-16, Chris Atenasio
Materials by Doug Ricket

http://atenasio.googlepages.com/gdn-examples.html

Documentation

Examples

Each of the following examples shows only the relevant JavaScript code, not the full HTML file. You can plug the JS code into the skeleton HTML file shown earlier, or you can download the full HTML file for each example by clicking the link after the example.

The Basics

The following example creates a map and centers it on Palo Alto, California.

var map = new GMap2(document.getElementById("map"));
map.setCenter(new GLatLng(37.4419, -122.1419), 13);

Map Movement and Animation

The following example displays a map, waits two seconds, and then pans to a new center point.

The panTo method centers the map at a given point. If the specified point is in the visible part of the map, then the map pans smoothly to the point; if not, the map jumps to the point.

var map = new GMap2(document.getElementById("map"));
map.setCenter(new GLatLng(37.4419, -122.1419), 13);
window.setTimeout(function() {
  map.panTo(new GLatLng(37.4569, -122.1569));
}, 1000);

Adding Controls to the Map

You can add controls to the map with the addControl method. In this case, we add the built-in GSmallMapControl and GMapTypeControl controls, which let us pan/zoom the map and switch between Map and Satellite modes, respectively.

var map = new GMap2(document.getElementById("map"));
map.addControl(new GSmallMapControl());
map.addControl(new GMapTypeControl());
map.setCenter(new GLatLng(37.4419, -122.1419), 13);

Event Listeners

To register an event listener, call the GEvent.addListener method. Pass it a map, an event to listen for, and a function to call when the specified event occurs. In the following example code, we display the latitude and longitude of the center of the map after the user drags the map.

var map = new GMap2(document.getElementById("map"));
GEvent.addListener(map, "moveend", function() {
  var center = map.getCenter();
  document.getElementById("message").innerHTML = center.toString();
});
map.setCenter(new GLatLng(37.4419, -122.1419), 13);

For more information about events, see the Events Overview. For a complete list of GMap2 events and the arguments they generate, see the documentation for GMap2.Events.

Opening an Info Window

To create an info window, call the openInfoWindow method, passing it a location and a DOM element to display. The following example code displays an info window anchored to the center of the map with a simple "Hello, world" message.

var map = new GMap2(document.getElementById("map"));
map.setCenter(new GLatLng(37.4419, -122.1419), 13);
map.openInfoWindow(map.getCenter(),
                   document.createTextNode("Hello, world"));

Map Overlays

This example displays 10 markers at random locations on the map and a polyline with 5 random points. GMarker use the default Google Maps icon if no other icon is given. See Creating Icons for an example using custom icons.

Remember that you must include the VML namespace and CSS in your HTML document to view polylines in IE.

var map = new GMap2(document.getElementById("map"));
map.addControl(new GSmallMapControl());
map.addControl(new GMapTypeControl());
map.setCenter(new GLatLng(37.4419, -122.1419), 13); 

// Add 10 markers in random locations on the map
var bounds = map.getBounds();
var southWest = bounds.getSouthWest();
var northEast = bounds.getNorthEast();
var lngSpan = northEast.lng() - southWest.lng();
var latSpan = northEast.lat() - southWest.lat();
for (var i = 0; i < 10; i++) {
  var point = new GLatLng(southWest.lat() + latSpan * Math.random(),
                          southWest.lng() + lngSpan * Math.random());
  map.addOverlay(new GMarker(point));
}

// Add a polyline with five random points. Sort the points by
// longitude so that the line does not intersect itself.
var points = [];
for (var i = 0; i < 5; i++) {
  points.push(new GLatLng(southWest.lat() + latSpan * Math.random(),
                          southWest.lng() + lngSpan * Math.random()));
}
points.sort(function(p1, p2) {
  return p1.lng() - p2.lng();
});
map.addOverlay(new GPolyline(points));

Click Handling

To trigger an action when a user clicks the map, register a listener for the "click" event on your GMap2 instance. When the event is triggered, the event handler will receive two arguments: the marker that was clicked (if any), and the GLatLng of the clicked point. If no marker was clicked, the first argument will be null.

Note: Markers are the only built-in overlay that supports the "click" event. Other types of overlays, like GPolyline, are not clickable.

In the following example, when the visitor clicks a point on the map without a marker, we create a new marker at that point. When the visitor clicks a marker, we remove it from the map.

var map = new GMap2(document.getElementById("map"));
map.addControl(new GSmallMapControl());
map.addControl(new GMapTypeControl());
map.setCenter(new GLatLng(37.4419, -122.1419), 13);

GEvent.addListener(map, "click", function(marker, point) {
  if (marker) {
    map.removeOverlay(marker);
  } else {
    map.addOverlay(new GMarker(point));
  }
});

For more information about events, see the Events Overview. For a complete list of GMap2 events and the arguments they generate, see the documentation on GMap2.Events.

Display Info Windows Above Markers

In this example, we show a custom info window above each marker by listening to the click event for each marker. We take advantage of JavaScript function closures to customize the info window content for each marker.

var map = new GMap2(document.getElementById("map"));
map.addControl(new GSmallMapControl());
map.addControl(new GMapTypeControl());
map.setCenter(new GLatLng(37.4419, -122.1419), 13);

// Creates a marker at the given point with the given number label
function createMarker(point, number) {
  var marker = new GMarker(point);
  GEvent.addListener(marker, "click", function() {
    marker.openInfoWindowHtml("Marker #<b>" + number + "</b>");
  });
  return marker;
}

// Add 10 markers to the map at random locations
var bounds = map.getBounds();
var southWest = bounds.getSouthWest();
var northEast = bounds.getNorthEast();
var lngSpan = northEast.lng() - southWest.lng();
var latSpan = northEast.lat() - southWest.lat();
for (var i = 0; i < 10; i++) {
  var point = new GLatLng(southWest.lat() + latSpan * Math.random(),
                          southWest.lng() + lngSpan * Math.random());
  map.addOverlay(createMarker(point, i + 1));
}

For more information about events, see the Events Overview. For a complete list of GMap2 events and the arguments they generate, see the documentation on GMap2.Events.

Tabbed Info Windows

Version 2 of the API introduces openInfoWindowTabs() and the GInfoWindowTab class to support info windows with multiple, named tabs. The example below displays a simple tabbed info window above a single marker.

var map = new GMap2(document.getElementById("map"));
map.addControl(new GSmallMapControl());
map.addControl(new GMapTypeControl());
map.setCenter(new GLatLng(37.4419, -122.1419), 13);

// Our info window content
var infoTabs = [
  new GInfoWindowTab("Tab #1", "This is tab #1 content"),
  new GInfoWindowTab("Tab #2", "This is tab #2 content")
];

// Place a marker in the center of the map and open the info window
// automatically
var marker = new GMarker(map.getCenter());
GEvent.addListener(marker, "click", function() {
  marker.openInfoWindowTabsHtml(infoTabs);
});
map.addOverlay(marker);
marker.openInfoWindowTabsHtml(infoTabs);

Creating Icons

This example creates a new type of icon, using the Google Ride Finder "mini" markers as an example. We have to specify the foreground image, the shadow image, and the points at which we anchor the icon to the map and anchor the info window to the icon.

var map = new GMap2(document.getElementById("map"));
map.addControl(new GSmallMapControl());
map.addControl(new GMapTypeControl());
map.setCenter(new GLatLng(37.4419, -122.1419), 13);

// Create our "tiny" marker icon
var icon = new GIcon();
icon.image = "http://labs.google.com/ridefinder/images/mm_20_red.png";
icon.shadow = "http://labs.google.com/ridefinder/images/mm_20_shadow.png";
icon.iconSize = new GSize(12, 20);
icon.shadowSize = new GSize(22, 20);
icon.iconAnchor = new GPoint(6, 20);
icon.infoWindowAnchor = new GPoint(5, 1);

// Add 10 markers to the map at random locations
var bounds = map.getBounds();
var southWest = bounds.getSouthWest();
var northEast = bounds.getNorthEast();
var lngSpan = northEast.lng() - southWest.lng();
var latSpan = northEast.lat() - southWest.lat();
for (var i = 0; i < 10; i++) {
  var point = new GLatLng(southWest.lat() + latSpan * Math.random(),
                          southWest.lng() + lngSpan * Math.random());
  map.addOverlay(new GMarker(point, icon));
}

Using Icon Classes

In many cases, your icons may have different foregrounds, but the same shape and shadow. The easiest way to achieve this behavior is to use the copy constructor for the =GIcon= class, which copies all the properties over to a new icon which you can then customize.

var map = new GMap2(document.getElementById("map"));
map.addControl(new GSmallMapControl());
map.addControl(new GMapTypeControl());
map.setCenter(new GLatLng(37.4419, -122.1419), 13);

// Create a base icon for all of our markers that specifies the
// shadow, icon dimensions, etc.
var baseIcon = new GIcon();
baseIcon.shadow = "http://www.google.com/mapfiles/shadow50.png";
baseIcon.iconSize = new GSize(20, 34);
baseIcon.shadowSize = new GSize(37, 34);
baseIcon.iconAnchor = new GPoint(9, 34);
baseIcon.infoWindowAnchor = new GPoint(9, 2);
baseIcon.infoShadowAnchor = new GPoint(18, 25);

// Creates a marker whose info window displays the letter corresponding
// to the given index.
function createMarker(point, index) {
  // Create a lettered icon for this point using our icon class
  var letter = String.fromCharCode("A".charCodeAt(0) + index);
  var icon = new GIcon(baseIcon);
  icon.image = "http://www.google.com/mapfiles/marker" + letter + ".png";
  var marker = new GMarker(point, icon);

  GEvent.addListener(marker, "click", function() {
    marker.openInfoWindowHtml("Marker <b>" + letter + "</b>");
  });
  return marker;
}

// Add 10 markers to the map at random locations
var bounds = map.getBounds();
var southWest = bounds.getSouthWest();
var northEast = bounds.getNorthEast();
var lngSpan = northEast.lng() - southWest.lng();
var latSpan = northEast.lat() - southWest.lat();
for (var i = 0; i < 10; i++) {
  var point = new GLatLng(southWest.lat() + latSpan * Math.random(),
                          southWest.lng() + lngSpan * Math.random());
  map.addOverlay(createMarker(point, i));
}

Using XML and Asynchronous HTTP with Maps

In this example, we download a static file ("points.xml") that contains a list of lat/lng coordinates in XML using the GDownloadUrl method. When the download completes, we parse the XML with GXml and create a marker at each of those points in the XML document.

var map = new GMap2(document.getElementById("map"));
map.addControl(new GSmallMapControl());
map.addControl(new GMapTypeControl());
map.setCenter(new GLatLng(37.4419, -122.1419), 13);

// Download the data in points.xml and load it on the map. The format we
// expect is:
// <markers>
//   <marker lat="37.441" lng="-122.141"/>
//   <marker lat="37.322" lng="-121.213"/>

// </markers>
GDownloadUrl("points.xml", function(data, responseCode) {
  var xml = GXml.parse(data);
  var markers = xml.documentElement.getElementsByTagName("marker");
  for (var i = 0; i < markers.length; i++) {
    var point = new GLatLng(parseFloat(markers[i].getAttribute("lat")),
                            parseFloat(markers[i].getAttribute("lng")));
    map.addOverlay(new GMarker(point));
  }
});

This example uses the external XML data file points.xml.

Custom Map Controls

Version 2 of the Maps API introduces the ability to create custom map controls, like the built-in pan and zoom controls, by subclassing the built-in GControl class. In this example, we create a simple zoom control that has textual links rather than the graphical icons used in the standard Google Maps zoom control.

The GTextualZoomControl class defines the two required methods of the GControl interface: initialize(), in which we create the DOM elements representing our control; and getDefaultPosition(), in which we return the GControlPosition used if another position is not given when this control is added to a map. See the class reference for GControl for more information about the methods you can override when you create your custom controls.

All map controls should be added to the map container which can be accessed with the getContainer() method on GMap2.

// A TextualZoomControl is a GControl that displays textual "Zoom In"
// and "Zoom Out" buttons (as opposed to the iconic buttons used in
// Google Maps).
function TextualZoomControl() {
}
TextualZoomControl.prototype = new GControl();

// Creates a one DIV for each of the buttons and places them in a container
// DIV which is returned as our control element. We add the control to
// to the map container and return the element for the map class to
// position properly.
TextualZoomControl.prototype.initialize = function(map) {
  var container = document.createElement("div");

  var zoomInDiv = document.createElement("div");
  this.setButtonStyle_(zoomInDiv);
  container.appendChild(zoomInDiv);
  zoomInDiv.appendChild(document.createTextNode("Zoom In"));
  GEvent.addDomListener(zoomInDiv, "click", function() {
    map.zoomIn();
  });

  var zoomOutDiv = document.createElement("div");
  this.setButtonStyle_(zoomOutDiv);
  container.appendChild(zoomOutDiv);
  zoomOutDiv.appendChild(document.createTextNode("Zoom Out"));
  GEvent.addDomListener(zoomOutDiv, "click", function() {
    map.zoomOut();
  });

  map.getContainer().appendChild(container);
  return container;
}

// By default, the control will appear in the top left corner of the
// map with 7 pixels of padding.
TextualZoomControl.prototype.getDefaultPosition = function() {
  return new GControlPosition(G_ANCHOR_TOP_LEFT, new GSize(7, 7));
}

// Sets the proper CSS for the given button element.
TextualZoomControl.prototype.setButtonStyle_ = function(button) {
  button.style.textDecoration = "underline";
  button.style.color = "#0000cc";
  button.style.backgroundColor = "white";
  button.style.font = "small Arial";
  button.style.border = "1px solid black";
  button.style.padding = "2px";
  button.style.marginBottom = "3px";
  button.style.textAlign = "center";
  button.style.width = "6em";
  button.style.cursor = "pointer";
}

var map = new GMap2(document.getElementById("map"));
map.addControl(new TextualZoomControl());
map.setCenter(new GLatLng(37.441944, -122.141944), 13);

Custom Overlays

Version 2 of the Maps API introduces the ability to create custom map overlays, like the built-in GMarker and GPolyline overlays, by subclassing the built-in GOverlay class. In this example, we create a Rectangle overlay that outlines a geographic region on the map.

The Rectangle class defines the four required methods of the GOverlay interface: initialize(), in which we create the DOM elements representing our overlay; remove(), in which we remove the overlay elements from the map; copy(), which copies the overlay for use in another map instance; and redraw(), which positions and sizes the overlay on the map based on the current projection and zoom level. See the class reference for GOverlay for more information about the methods you can override when you create your custom overlays.

Every DOM element that makes up an overlay exists on a map pane that defines the z-order at which it will be drawn. For example, polylines are flat against the map, so they are drawn in the lowest G_MAP_MAP_PANE. Markers place their shadow elements in the G_MAP_MARKER_SHADOW_PANE and their foreground elements in the G_MAP_MARKER_PANE. Placing your overlay elements in the correct panes ensures that polylines are drawn below marker shadows and the info window is drawn above other overlays on the map. In this example, our overlay is flat against the map, so we add it to the lowest z-order pane G_MAP_MAP_PANE, just like GPolyline. See the class reference for a complete list of map panes.

// A Rectangle is a simple overlay that outlines a lat/lng bounds on the
// map. It has a border of the given weight and color and can optionally
// have a semi-transparent background color.
function Rectangle(bounds, opt_weight, opt_color) {
  this.bounds_ = bounds;
  this.weight_ = opt_weight || 2;
  this.color_ = opt_color || "#888888";
}
Rectangle.prototype = new GOverlay();

// Creates the DIV representing this rectangle.
Rectangle.prototype.initialize = function(map) {
  // Create the DIV representing our rectangle
  var div = document.createElement("div");
  div.style.border = this.weight_ + "px solid " + this.color_;
  div.style.position = "absolute";

  // Our rectangle is flat against the map, so we add our selves to the
  // MAP_PANE pane, which is at the same z-index as the map itself (i.e.,
  // below the marker shadows)
  map.getPane(G_MAP_MAP_PANE).appendChild(div);

  this.map_ = map;
  this.div_ = div;
}

// Remove the main DIV from the map pane
Rectangle.prototype.remove = function() {
  this.div_.parentNode.removeChild(this.div_);
}

// Copy our data to a new Rectangle
Rectangle.prototype.copy = function() {
  return new Rectangle(this.bounds_, this.weight_, this.color_,
                       this.backgroundColor_, this.opacity_);
}

// Redraw the rectangle based on the current projection and zoom level
Rectangle.prototype.redraw = function(force) {
  // We only need to redraw if the coordinate system has changed
  if (!force) return;

  // Calculate the DIV coordinates of two opposite corners of our bounds to
  // get the size and position of our rectangle
  var c1 = this.map_.fromLatLngToDivPixel(this.bounds_.getSouthWest());
  var c2 = this.map_.fromLatLngToDivPixel(this.bounds_.getNorthEast());

  // Now position our DIV based on the DIV coordinates of our bounds
  this.div_.style.width = Math.abs(c2.x - c1.x) + "px";
  this.div_.style.height = Math.abs(c2.y - c1.y) + "px";
  this.div_.style.left = (Math.min(c2.x, c1.x) - this.weight_) + "px";
  this.div_.style.top = (Math.min(c2.y, c1.y) - this.weight_) + "px";
}

var map = new GMap2(document.getElementById("map"));
map.addControl(new GSmallMapControl());
map.addControl(new GMapTypeControl());
map.setCenter(new GLatLng(37.4419, -122.1419), 13);

// Display a rectangle in the center of the map at about a quarter of
// the size of the main map
var bounds = map.getBounds();
var southWest = bounds.getSouthWest();
var northEast = bounds.getNorthEast();
var lngDelta = (northEast.lng() - southWest.lng()) / 4;
var latDelta = (northEast.lat() - southWest.lat()) / 4;
var rectBounds = new GLatLngBounds(
    new GLatLng(southWest.lat() + latDelta, southWest.lng() + lngDelta),
    new GLatLng(northEast.lat() - latDelta, northEast.lng() - lngDelta));
map.addOverlay(new Rectangle(rectBounds));

Geocoder Examples

You can access the Maps API geocoder directly by sending HTTP requests to Google, or you can use the GClientGeocoder object to send those requests from within the Javascript. Whether you make the geocoding calls from your server or the user's browser is up to you. If you have a fairly stable database of addresses (e.g. a list of properties for sale), we recommend that you geocode them once using the HTTP request method and cache the coordinates in your own database. This means your site will be faster for your users and also uses up less of your daily quota of geocode requests. However, if you don't have access to server-side scripting, you can send geocode requests from the JavaScript.

Geocoding using JavaScript

The geocoder can be accessed from within the JavaScript using the GClientGeocoder object. The getLatLng method can be used to convert an address into a GLatLng. Because geocoding involves sending a request to Google's servers, it can take some time. To avoid making your script wait, you need to pass in a function to call after the response comes back. In this example, we geocode an address, add a marker at that point, and open an info window displaying the address.

var map = new GMap2(document.getElementById("map"));
var geocoder = new GClientGeocoder();

function showAddress(address) {
  geocoder.getLatLng(
    address,
    function(point) {
      if (!point) {
        alert(address + " not found");
      } else {
        map.setCenter(point, 13);
        var marker = new GMarker(point);
        map.addOverlay(marker);
        marker.openInfoWindowHtml(address);
      }
    }
  );
}

Extracting Structured Address Information

If you would like to access structured information about an address, GClientGeocoder also provides a getLocations method that returns a JSON object consisting of the following information.

Here we show the JSON object returned by the geocoder for the address of Google's headquarters.

{ 
  name: "1600 Amphitheatre Parkway, Mountain View, CA, USA",
  Status: {
    code: 200, 
    request: "geocode"
  }, 
  Placemark: [
    {
      address: "1600 Amphitheatre Pkwy, Mountain View, CA 94043, USA",
      AddressDetails: {
        Country: {
          CountryNameCode: "US",
          AdministrativeArea: {
            AdministrativeAreaName: "CA",
            SubAdministrativeArea: {
              SubAdministrativeAreaName: "Santa Clara",
              Locality: {
                LocalityName: "Mountain View",
                Thoroughfare: {
                  ThoroughfareName: "1600 Amphitheatre Pkwy"
                },
                PostalCode: {
                  PostalCodeNumber: "94043"
                }
              }
            }
          }
        }
      },
      Point: {
        coordinates: [-122.083739, 37.423021, 0]
      }
    }
  ]
}

In this example, we use the getLocations method to geocode addresses, and extract the nicely formatted version of the address and the two-letter country from the JSON and display it in the info window.

var map;
var geocoder;

map = new GMap2(document.getElementById("map"));
map.setCenter(new GLatLng(34, 0), 1);
geocoder = new GClientGeocoder();


function addAddressToMap(response) {
  map.clearOverlays();
  if (!response || response.Status.code != 200) {
    alert("\"" + address + "\" not found");
  } else {
    place = response.Placemark[0];
    point = new GLatLng(place.Point.coordinates[1],
                        place.Point.coordinates[0]);
    marker = new GMarker(point);
    map.addOverlay(marker);
    marker.openInfoWindowHtml(place.address + '<br>' + 
    '<b>Country code:</b> ' + place.AddressDetails.Country.CountryNameCode);
  }
}

var input = document.getElementById('in16');

// showLocation() is called when you click on the Search button
// in the form.  It geocodes the address entered into the form
// and adds a marker to the map at that location.
function showLocation() {
  var address = input.value;
  geocoder.getLocations(address, addAddressToMap);
}

// findLocation() is used to enter the sample addresses into the form.
function findLocation(address) {
  input.value = address;
  showLocation();
}

Search for an address:

Try these:
1600 amphitheatre mtn view ca
1 Telegraph Hill Blvd, San Francisco, CA, USA
4144 Avenue Pierre-De-Coubertin, Montréal, Canada
Champ de Mars 75007 Paris, France
Piazza del Colosseo, Roma, Italia
Domkloster 3, 50667 Köln, Deutschland
Plaza de la Virgen de los Reyes, 41920, Sevilla, España
東京タワー (Tokyo Tower, Tokyo Japan)
123 Main St, Googleville

Caching Geocodes

GClientGeocoder is equipped with a client-side cache by default. The cache stores geocoder responses, so that if the same address is geocoded again, the response will be returned from the cache rather than from Google's geocoder. To turn off caching, pass null to the setCache method of GClientGeocoder. However, we recommend that you leave caching on because it improves performance. To change the cache being used by GClientGeocoder, use the setCache method and pass in the new cache. To empty the contents of the current cache, use the reset method on the geocoder or on the cache directly.

Developers are encouraged to build their own client-side caches. In this example, we construct a cache that contains pre-computed geocoder responses to six capital cities in countries covered by geocoding API. First, we build an array of geocode responses. Next, we create a custom cache that extends a standard GeocodeCache. Once the cache is defined, we call the setCache method. There is no strict checking of objects stored in the cache, so you may store other information (such as population size) in the cache as well.


// Builds an array of geocode responses for the 6 capitals
var city = [
  {
    name: "Washington, DC",
    Status: {
      code: 200,
      request: "geocode"
    },
    Placemark: [
      {
        address: "Washington, DC, USA",
        population: "0.563M",
        AddressDetails: {
          Country: {
            CountryNameCode: "US",
            AdministrativeArea: {
              AdministrativeAreaName: "DC",
              Locality: {
                LocalityName: "Washington"
              }
            }
          }
        },
        Point: {
          coordinates: [-77.036667, 38.895000, 0]
        }
      }
    ]
  },
  // ... etc., and so on for other cities
];

  var map;
  var geocoder;

  // CapitalCitiesCache is a custom cache that extends the standard GeocodeCache.
  // We call apply(this) to invoke the parent's class constructor.
  function CapitalCitiesCache() {
    GGeocodeCache.apply(this);
  }

  // Assigns an instance of the parent class as a prototype of the
  // child class, to make sure that all methods defined on the parent
  // class can be directly invoked on the child class.
  CapitalCitiesCache.prototype = new GGeocodeCache();

  // Override the reset method to populate the empty cache with
  // information from our array of geocode responses for capitals.
  CapitalCitiesCache.prototype.reset = function() {
    GGeocodeCache.prototype.reset.call(this);
    for (var i in city) {
      this.put(city[i].name, city[i]);
    }
  }

  function addAddressToMap(response) {
    map.clearOverlays();

    if (response && response.Status.code != 200) {
      alert("Unable to locate " + decodeURIComponent(response.name));
    } else {
      var place = response.Placemark[0];
      var point = new GLatLng(place.Point.coordinates[1],
                              place.Point.coordinates[0]);
      map.setCenter(point, 6);
      map.openInfoWindowHtml(point, "City: " + place.address
       + "
Population: " + place.population); } } function findCity(which) { if (which != 0) { geocoder.getLocations(city[which - 1].name, addAddressToMap); } } map = new GMap2(document.getElementById("map")); map.setCenter(new GLatLng(37.441944, -122.141944), 6); // Here we set the cache to use the UsCitiesCache custom cache. geocoder = new GClientGeocoder(); geocoder.setCache(new CapitalCitiesCache());
Go to:

HTTP Request

To access the Maps API geocoder directly using server-side scripting, send a request to http://maps.google.com/maps/geo? with the following parameters in the URI:

In this example, we request the geographic coordinates of Google's headquarters.

http://maps.google.com/maps/geo?q=1600+Amphitheatre+Parkway,+Mountain+View,+CA&output=xml&key=abcdefg

If you specify json as the output, the response is formatted as a JSON object, as shown in the example above. If you specify xml or kml, the response is returned in XML or KML. The XML and KML outputs are identical except for the MIME types.

For example, this is the response that the geocoder returns for "1600 amphitheatre mtn view ca".

<kml>
  <Response>
    <name>1600 amphitheatre mtn view ca</name>
    <Status>
      <code>200</code>

      <request>geocode</request>
    </Status>
    <Placemark>
      <address> 
        1600 Amphitheatre Pkwy, Mountain View, CA 94043, USA
      </address>

      <AddressDetails>
        <Country>
          <CountryNameCode>US</CountryNameCode>
 	  <AdministrativeArea>
            <AdministrativeAreaName>CA</AdministrativeAreaName>

           <SubAdministrativeArea>
             <SubAdministrativeAreaName>Santa Clara</SubAdministrativeAreaName>
             <Locality>
               <LocalityName>Mountain View</LocalityName>
    	       <Thoroughfare>

                 <ThoroughfareName>1600 Amphitheatre Pkwy</ThoroughfareName>
               </Thoroughfare>
               <PostalCode>
                 <PostalCodeNumber>94043</PostalCodeNumber>
               </PostalCode>

             </Locality>
           </SubAdministrativeArea>
         </AdministrativeArea>
       </Country>
     </AddressDetails>
     <Point>

       <coordinates>-122.083739,37.423021,0</coordinates>
     </Point>
   </Placemark>
  </Response>
</kml>

Troubleshooting

If your code doesn't seem to be working, here are some approaches that might help you solve your problems:

Other resources

Here are some additional resources. Note that these sites are not owned or supported by Google.

API Overview

The API Overview walks through the central concepts of the Maps API. For a complete reference of methods and classes exported by the API, see the Maps API Class Reference.

The GMap2 class

An instance of GMap2 represents a single map on the page. You can create as many instances of this class as you want (one for each map on the page). When you create a new map instance, you specify a named element in the page (usually a div element) to contain the map. Unless you specify a size explicitly, the map uses the size of the container to determine its size.

The GMap2 class has methods to manipulate the map's center and zoom level and to add and remove overlays (such as GMarker and GPolyline instances). It also has a method to open an "info window," which is the popup window you see on Google Maps.

For more information about GMap2, see the GMap2 class reference.

Events

You can add dynamic elements to your application by using event listeners. An object exports a number of named events, and your application can "listen" to those events using the static methods GEvent.addListener and GEvent.bind. For example, this code snippet shows an alert every time the user clicks on the map:

var map = new GMap2(document.getElementById("map"));
map.setCenter(new GLatLng(37.4419, -122.1419), 13);
GEvent.addListener(map, "click", function() {
  alert("You clicked the map.");
});

GEvent.addListener takes a function as the third argument, which promotes the use of function closures for event handlers. If you want to bind an event to a method on a class instance, you can use GEvent.bind. In the following example, an application class instance binds map events to its own methods, modifying class state when events are triggered:

function MyApplication() {
  this.counter = 0;
  this.map = new GMap2(document.getElementById("map"));
  this.map.setCenter(new GLatLng(37.4419, -122.1419), 13);
  GEvent.bind(this.map, "click", this, this.onMapClick);
}

MyApplication.prototype.onMapClick = function() {
  this.counter++;
  alert("You have clicked the map " + this.counter + " " +
        (this.counter == 1 ?"time" : "times"));
}

var application = new MyApplication();

The Info Window

Each map has a single "info window," which displays HTML content in a floating window above the map. The info window looks a little like a comic-book word balloon; it has a content area and a tapered stem, where the tip of the stem is at a specified point on the map. You can see the info window in action by clicking a marker in Google Maps.

You can't show more than one info window at a time for a given map, but you can move the info window and change its contents as needed.

The basic info window method is openInfoWindow, which takes a point and an HTML DOM element as arguments. The HTML DOM element is appended to the info window container, and the info window window tip is anchored to the given point.

The openInfoWindowHtml method is similar, but it takes an HTML string as its second argument rather than a DOM element.

To display an info window above an overlay like a marker, you can pass an optional third argument that specifies the pixel offset between the specified point and the tip of the info window. So, if your marker is 10 pixels tall, you might pass the pixel offset GSize(0, -10).

The GMarker class exports openInfoWindow methods that handle the pixel offset issues for you based on the size and shape of the icon, so you generally don't have to worry about calculating icon offsets in your application.

See the GMap2 and GMarker class references for more information.

Overlays

Overlays are objects on the map that are tied to latitude/longitude coordinates, so they move when you drag or zoom the map and when you switch map projections (such as when you switch from Map to Satellite mode).

The Maps API exports two types of overlays: markers, which are icons on the map, and polylines, which are lines made up of a series of points.

Markers and Icons

The GMarker constructor takes an icon and a point as arguments and exports a small set of events like "click".

The most difficult part of creating a marker is specifying the icon, which is complex because of the number of different images that make up a single icon in the Maps API.

Every icon has a foreground image and a shadow image. The shadow should be created at a 45 degree angle (upward and to the right) from the foreground image, and the bottom left corner of the shadow image should align with the bottom-left corner of the icon foreground image. The shadow should be a 24-bit PNG image with alpha transparency so that the edges of the shadow look correct on top of the map.

The GIcon class requires you specify the size of these images when you initialize the icon so the Maps API can create image elements of the appropriate size. This is the minimum amount of code required to specify an icon (in this case, the icon used on Google Maps):

var icon = new GIcon();
icon.image = "http://www.google.com/mapfiles/marker.png";
icon.shadow = "http://www.google.com/mapfiles/shadow50.png";
icon.iconSize = new GSize(20, 34);
icon.shadowSize = new GSize(37, 34);

The GIcon class also has several other properties that you should set to get maximum browser compatibility and functionality from your icons. For example, the imageMap property specifies the shape of the non-transparent parts of the icon image. If you do not set this property in your icon, the entire icon image (including the transparent parts) will be clickable in Firefox/Mozilla. See the GIcon class reference for more information.

Polylines

The GPolyline constructor takes an array of points as an argument, and creates a series of line segments that connect those points in the given sequence. You can also specify the color, weight, and opacity of the line. The color should be in the hexadecimal numeric HTML style, e.g., use #ff0000 instead of red. GPolyline does not understand named colors.

The following code snippet creates a 10-pixel-wide red polyline between two points:

var map = new GMap2(document.getElementById('map'));
map.setCenter(new GLatLng(37.44, -122.14), 14);
var polyline = new GPolyline([
  new GLatLng(37.4419, -122.1419),
  new GLatLng(37.4519, -122.1519)
], "#ff0000", 10);
map.addOverlay(polyline);

In Internet Explorer, Google Maps uses VML to draw polylines (see XHTML and VML for more information). In all other browsers, we request an image of the line from Google servers and overlay that image on the map, refreshing the image as necessary as the map is zoomed and dragged around.

Controls

To add controls like the zoom bar to your map, use the addControl method. The Maps API comes with a handful of built-in controls you can use in your maps:

For example, to add the panning/zooming control you see on Google Maps to your map, you would include the following line in your map initialization:

var map = new GMap2(document.getElementById('map'));
map.addControl(new GLargeMapControl());

addControl takes an optional second GControlPosition parameter that lets you specify the position of the control on your map. If this argument is excluded, the Maps API uses the default position specified by the control. This example adds the map type control to the bottom right corner of the map with 10 pixels of padding:

var map = new GMap2(document.getElementById('map'));

map.addControl(new GMapTypeControl(),
               new GControlPosition(G_ANCHOR_BOTTOM_RIGHT, new GSize(10, 10)));

See the GControlPosition class reference for more information.

XML and RPC

The Google Maps API exports a factory method for creating XmlHttpRequest objects that work in recent versions of IE, Firefox, and Safari. The following example downloads a file called myfile.txt and displays its contents in a JavaScript alert:

var request = GXmlHttp.create();
request.open("GET", "myfile.txt", true);
request.onreadystatechange = function() {
  if (request.readyState == 4) {
    alert(request.responseText);
  }
}
request.send(null);

The API also exports a simpler method for typical HTTP GET requests called GDownloadUrl that eliminates the need for XmlHttpRequest readyState checking. The example above could be rewritten using GDownloadUrl like this:

GDownloadUrl("myfile.txt", function(data, responseCode) {
  alert(data);
});

You can parse an XML document with the static method GXml.parse, which takes a string of XML as its only argument. This method is compatible with most modern browsers, but it throws an exception if the browser does not support XML parsing natively.

See the GXmlHttp and GXml class references for more information.

Reducing Browser Memory Leaks

The Google Maps API encourages the use of function closures, and the API event handling system GEvent attaches events to DOM nodes in such a way that almost inevitably causes some browsers to leak memory, particularly Internet Explorer. Version 2 of the Maps API introduces a new method, GUnload(), that will remove most of the circular references that cause these leaks. You should call GUnload() in the unload event of your page to reduce the potential that your application leaks memory:

<body onunload="GUnload()">

Using this function has virtually eliminated Internet Explorer memory leaks in Google Maps, though you should test for memory leaks on your own site using tools like Drip if you are noticing memory consumption problems.