Adding A Google Map to your site

From Docupedia

The map we will build. Together. As a team.
The map we will build. Together. As a team.

Written By: Bryan Rite

Date: 11/23/2005

Contents

Overview

The goal of this tutorial is to bang out a simple Google Map for your own website. I'll take you through the steps that made this beauty. There is nothing too fancy on there but I did write a couple of methods and some behaviours that will make the map easier to use and get your feet wet.

Pre-Installation

Checklist

  • Get a Google Map API Key
    • You need one of these for every domain your map will appear on. Presumably that is just one, but i'm super awesome and have had the need for a db generated key (see: RealCLIP).
    • Get a key at: http://www.google.com/apis/maps/signup.html, they are free but you need a google account.
    • Use your website URL as it asks, I used www.brybot.ca for the example.
    • Note: As of 23/11/2005, there have been a couple changes in the way the key works with the given domain and I suspect they're will be more changes. I'll update as needed.
  • Co-ordinates
    • The co-ordinates for Google Map work in decimal degrees(47.12345678, -119.1728192837) as apposed to standard lat/long degrees, mins, seconds (47 12.345, 119 17.39291).
    • If you have a bunch of standard latitude/longitude co-ordinates, you'll have to convert them. There are lots of online utils to do this: http://www.fcc.gov/mb/audio/bickel/DDDMMSS-decimal.html worked at time of writing.
    • If you don't, i'll show you the way I get super-leet Google precise ones using the map once we build it.

Set Up

Basics

Ok, when you went through the Google Map API Key form you got a key similar to this:

 ABQQAAAANnPPFPvHpfiBrm6GIQmsvhSMCEdsB22PH6-dAmfjtTBoEE6TPxTnPTg5W_z50inv2osV6W5Y4wJg4g

This is a simply encrypted hash of your domain so it will only work for your website (therefore the need to get one for each domain).

You also got a skeleton page:

 <!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>
     <script src="http://maps.google.com/maps?file=api&v=1&key=*key*" type="text/javascript"></script>
   </head>
   <body>
     <div id="map" style="width: 500px; height: 400px"></div>
     <script type="text/javascript">
     //<![CDATA[
       var map = new GMap(document.getElementById("map"));
       map.addControl(new GSmallMapControl());
       map.centerAndZoom(new GPoint(-122.1419, 37.4419), 4);
     //]]>
     </script>
   </body>
 </html>

This will set up a page with a super basic map centered on California or something and zoomed way out. Lets start with this... its a good place to start.

Page Layout - Watch out for Bugs!

At the time of writing this, there is a bug in the IE version of Google Maps that displays blank if the javascript comes before the body. What we need to do is make sure that the script part of the skeleton:

 <script type="text/javascript">
   //<![CDATA[
     var map = new GMap(document.getElementById("map"));
     map.addControl(new GSmallMapControl());
     map.centerAndZoom(new GPoint(-122.1419, 37.4419), 4);
   //]]>
 </script>

stays below all your presentation etc. code. The

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

is the line that actually displays the map and this can go wherever it fits in your page design.

I trust this is clear but just in case:

 *all your head code*
 <div id="map" style="width: 500px; height: 400px"></div>
 *code under your map*
 <script type="text/javascript">
   //<![CDATA[
     var map = new GMap(document.getElementById("map"));
     map.addControl(new GSmallMapControl());
     map.centerAndZoom(new GPoint(-122.1419, 37.4419), 4);
   //]]>
 </script>
 </body>
 </html>

Change the Map Look

Width and Height

Ok, now that its positioned in the right place we can play with our map. Our display line:

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

obviously contains the size of the div container which the map fills. Now on Google's Map Home, the width and height are dynamic. Lets do that. Simply change the width: 500px to a percentage (%) that works with your page design. On mine its 80% or something.

Heights a bit more interesting. We cannot specify a percentage height because that doesn't work. I've opted for simply hardcoding a pixel value in but if you really want to have a dynamic height, you'll have to do some javascript magic, grabbing browser size and making on event methods to re-display. Problem is that it isn't really all that cross-browser compliant, so I don't bother.

Finally, we'll want to move our style information into a CSS file under #map so that our page is XML 1.0 Strict compliant. There you can add padding and borders and whatnot to pretty up the map. My CSS looks like:

 #map {
   width: 79%; 
   height: 350px;
   margin: 0px 0px 0px 0px;
   float: right;
 }

and my code becomes:

 <div id="map"></div>

Nice and simple.

Menus and Such

We now have totally control on what is displayed within the map. The slider and navigation or map types are changeable to get what we want. Our skeleton gives us a small controller bar.

 map.addControl(new GSmallMapControl());

Personally i don't like these for big maps, I want the big slider. I change the line to:

 map.addControl(new GLargeMapControl());

Rocket science... i know.

Now I want the option of having the map, or satellite, or hybrid types. Simply add the line:

 map.addControl(new GMapTypeControl());

Voila.

And finally I want the map to default to a hybrid view. Hybrid is so hot right now, so we add the line:

 map.setMapType(G_HYBRID_TYPE);

Cowabunga. The other mode you can default to is G_SATELLITE_TYPE, leaving it out gives you the map type.

So our script now looks along these lines:

 <script type="text/javascript">
   //<![CDATA[
     var map = new GMap(document.getElementById("map"));
     map.addControl(new GLargeMapControl());
     map.addControl(new GMapTypeControl());
     map.setMapType(G_HYBRID_TYPE);
     map.centerAndZoom(new GPoint(-122.1419, 37.4419), 4);
   //]]>
 </script>
 </body>
 </html>

Fantastic!

Add some Points

Alright, now we need some data on here. First off, we want the point to open a balloon when someone clicks on it. So we're gonna write a little method to create the points, I call them overlays... because thats what Google calls them... and while it creates the points, it creates the open popup event and displays HTML in the bubble.

This little baby'll do her:

 function createMarker(point, popup) {
   var marker = new GMarker(point);
   // Show this markers index in the info window when it is clicked
   var html = popup;
   GEvent.addListener(marker, "click", function() {marker.openInfoWindowHtml(html);});
   return marker;
 };

Basically what we're going to do, is when we want a new overlay we call createMarker, send it a GPoint (a container for co-ordinates) and some HTML code to go in the popup. We create a listener for click events on the overlay and use some api methods to display our HTML code in the bubble.

Now a simple call like so:

 map.addOverlay(createMarker(new GPoint(-119.9923324584961, 47.100687383755975), '<p>Earth</p>'));

will give us a single overlay on the map near Seattle, its actually the Gorge Amphitheatre, and clicking on it gives us an awesome bubble with our text in it.

A little Extra Functionality

Zoom and Center

I'm not sure how exactly you want to bring your data into the page. I use a MySQL database because I have one but you could do it as easily with a text file or something. I'll leave all that to you but what we want to do is center and zoom our map to best fit our dataset.

We'll need to rip through the dataset once and calculate the center lat/lng as well as the map span so we can keep our display time to O(n).

The center can be calculated by finding your bounding box. That is finding which points occupy your extremes: the latitudes of your most northern and southern points and the longitudes of your most eastern and western points. Now I know the Earth is sphereical so there are not techincally any extremes but view it like a 2-D map cause co-ordinates rollover at certain points to make the earth seem flat. Anyways, within a while loop just if stack or case your values to get the extremes. Mine, written in PHP with MySQL looks like so:

 $topLat = $row_getMapData['lat'];
 $topLng = $row_getMapData['lng'];
 $btmLat = $row_getMapData['lat'];
 $btmLng = $row_getMapData['lng'];
 $points = "";
 do { 
   if ($topLat < $row_getMapData['lat']) {$topLat = $row_getMapData['lat'];}
   if ($topLng < $row_getMapData['lng']) {$topLng = $row_getMapData['lng'];}
   if ($btmLat > $row_getMapData['lat']) {$btmLat = $row_getMapData['lat'];}
   if ($btmLng > $row_getMapData['lng']) {$btmLng = $row_getMapData['lng'];}		
   
   //Output the overlay
   
 } while ($row_getMapData = mysql_fetch_assoc($getMapData));	
 
 $centerLat = ($topLat + $btmLat) / 2;
 $centerLng = ($topLng + $btmLng) / 2;

The span is simply the difference between the extremes. abs(Northern Lat - Southern Lat), abs(Eastern Long - Western Long). My code:

 $spanLat = $topLat - $btmLat;
 $spanLng = $topLng - $btmLng;

Now that we have the values we add the following lines to our script:

 var center = new GPoint(<?php echo $centerLng ?>, <?php echo $centerLat ?>);
 var span = new GSize(<?php echo $spanLng ?>, <?php echo $spanLat ?>);
 var zoom = map.spec.getLowestZoomLevel(center, span, map.viewSize);
 map.centerAndZoom(center, zoom);

Pretty straight forward. We make use of the undocumented map.spec.getLowestZoomLevel(). This was not publicly available as of version 1 but i'm sure will be included in version 2 or whatever is next.

Now I would loop through my dataset populating the map with the map.addOverlay line from above and there you go. Center and zoom should be dependant on your dataset so that if it changes with filters or different queries, it'll still work.

Notes on Bubble HTML

It is possible to have the bubbles display XML or simple text but I thought HTML is a nice simple, but not too simple, way of doing it. You can have fully featured HTML within the bubbles but be sure to take out any line carriages or new line characters as google's javascript bombs on it and won't display the map or give an error.

Conclusion

Thats that. Simple, no frills map that emulates Google's Map very closely. I have a couple more little scripts for it that i'll post shortly such as getting decimal degrees from mouse clicks and some cool onClick events.



--- Bryan Rite 13:23, 23 Nov 2005 (PST)