Saturday, February 10, 2007

Creating Custom Controls for Google Maps

With the release of the Google Maps API, usage of the fantastic framework Google has laid is now possible. Fueled by the easy to use, highly abstracted and well documented API, customized versions of Google Maps are running all over the Internet. With the API it is possible to create custom effects, tools, data, etc. for your map -- basically, the possibilities are endless because you have access to the whole world of the Javascript language. This article will show how to create a custom control for google maps, which will allow a user to click and drag a rectangle over a selected area on the map which will then be centered on and magnified.

What is a Google Maps Control?

While there is no specific definition of a maps API control per se, however basically a control is this: some tool ("control") that is displayed in the google maps window and provides some custom functionally that doesn't come with the maps API. Technically, a control is anything that implements the GControl Interface. The maps API already comes with a hand full of helpful controls:
  • GLargeMapControl - a large pan/zoom control used on Google Maps. Appears in the top left corner of the map.
  • GSmallMapControl - a smaller pan/zoom control used on Google Maps. Appears in the top left corner of the map.
  • GSmallZoomControl - a small zoom control (no panning controls) used in the small map blowup windows used to display driving directions steps on Google Maps.
  • GScaleControl - a map scale
  • GMapTypeControl - buttons that let the user toggle between map types (such as Map and Satellite)
  • GOverviewMapControl New! - a collapsible overview map in the corner of the screen
If you've ever used the maps API you should be familiar with at least one of these controls. They are already implemented and included in the maps API, however now, we are going to make our own custom control, that allows the user to click a point on the map and drag a rectangle over and area to another point. This area will then be centered upon and magnified to the appropriate level.

The Hello World of GMaps Controls

As I alluded to above, the most minimal amount of code you have to write to create a true gmaps control is implement the GControl interface.

// base definition and inheritance
function MyCustomControl()
{
}

//Default constructor for GControl
MyCustomControl.prototype = new GControl(false,false);

// Default location for the control
MyCustomControl.prototype.getDefaultPosition = function() {
return new GControlPosition(G_ANCHOR_TOP_LEFT,new GSize(700,8));
};

GControlSelector.prototype.initialize = function(gmapref)
{

var container=gmapref.getContainer();

var c = document.createElement("div");
c.innerHTML="This is a custom control";

container.appendChild(c);

return c;
}


The first function MyCustomControl()is the name of the class and the control, this is your base class for the control. The next block of code simply initializes an instance of the GControl() interface using it's default constructor, so now we must implement all it's required interfaces.

The required members of the GControl interface are:
  • printable() > bool -- Returns to the map if the control should be printable.
  • selectable() > bool -- Returns to the map if the control contains selectable text.
  • initialize(map) > Node -- Will be called by the map so the control can initialize itself.
  • getDefaultPosition() > GControlPosition -- Returns to the map the position in the map view at which the control appears by default. This will be overridden by the second argument to GMap2.addControl().
We already have 2 of these implimented by means of our call to the GControl contstructor which has this signature: GControl(printable?, selectable?). Since we passed false to both the parameters we only need to impliment initialize(map) and getDefaultPosition().

initialize(map) - The purpose of the initialize method is to build the control, i.e. load it's code for use. For, all we are doing in initialize is build the UI, which is a simple div element with some text inside. Once we build the UI we add it the map and return it.
getDefaultPosition() - The purpose of the getDefaultPosition() method is so the maps API knows where to place the control if the user doesn't specify a custom location.

Almost there. Once we have designed our custom control we have one step left, we must add it to the map using the method Gmap2.addControl().

Adding the control to the map

Now we have to add our control to the map, this is the last step of creating your custom control.

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8"/>
<title>Google Maps JavaScript API Example</title>
<script src="http://maps.google.com/maps?file=api&amp;v=2&amp;key=abcdefg"
type="text/javascript"></script>
<script type="text/javascript">
//<![CDATA[

function load() {
if (GBrowserIsCompatible()) {
var map = new GMap2(document.getElementById("map"));
map.addControl(new MyCustomControl());
map.setCenter(new GLatLng(37.4419, -122.1419), 13);
}
}

//]]>
</script>
</head>
<body onload="load()" onunload="GUnload()">
<div id="map" style="width: 500px; height: 300px"></div>
</body>
</html>

The above is a stock google maps page. The above highlighted text is all we need to do to use
our new google maps custom control.






1 comment:

Anonymous said...

I suppose, there should be "MyCustomControl" instead of "GControlSelector"?