Friday, February 26, 2010

Developing with Online Mapping APIs - Part 1: Displaying a Map

The very first objective is to be able to display a map on a web page. There are just a few basic things we need in order to make this happen:
  • A reference to the mapping API
  • An HTML element to display the map in
  • A bit of script to initialize the map
To start, let's write a simple HTML page that will display our map.
<HTML>
<HEAD>
</HEAD>
<BODY>
<DIV id="mapDiv" style="position:relative;width:640px;height:480px"></DIV>
</BODY>
</HTML>

Nothing particularly fancy here. We've created a page with a single DIV that will be the display area for our map. There are no size restrictions on the map, but you'll want to pick something that fits well with your page design.

Next we need to add a reference to the script that will allow us to create and interact with maps. We also need a bit of custom script to create the map and set the initial display. The method for doing this is largely similar across APIs, but we will look at them individually in the following sections to highlight the differences in each.

Bing

To embed a Bing map on your page the first thing you will need to add is the reference to the Bing map JavaScript API.
<script type="text/javascript" src="http://ecn.dev.virtualearth.net/mapcontrol/mapcontrol.ashx?v=6.2"></script>

The only item of interest in the script reference is the v=6.2. This indicates the version of the mapping API that your code would prefer to use. This can be useful if there is a API change resulting in behavior that breaks your interface. Next, we need to add a bit of code to initialize our map. We will want to create a global variable to hold a reference to our map object. For this example, we will initialize the map on the page's onload event. There are two steps to initializing the map. The first step is to create the map object. The second step is to load the map content centered on a location.

<HTML>
<HEAD>
<script type="text/javascript" src="http://ecn.dev.virtualearth.net/mapcontrol/mapcontrol.ashx?v=6.2"></script>
<SCRIPT>
var bingMap;
function bingInitializer()
{
bingMap = new VEMap('mapDiv');
bingMap.LoadMap(new VELatLong(39.768519, -86.158041), 13);
}
</SCRIPT>
</HEAD>
<BODY onload="bingInitializer()">
<DIV id="mapDiv" style="position:relative;width:640px;height:480px"></DIV>
</BODY>
</HTML>

The constructor for the VEMap takes the HTML element that will host the map as an argument. The LoadMap method requires a lattitude and longitude for centering the map, as well as a zoom level. Unfortunately there is no standard for zoom levels across all APIs. In the case of Bing, the smaller the number the farther out the camera view. The greater the number the closer in the view. When developing a page that will host a Bing map, be absolutely certain that the 'position:relative' style is set on the HTML element the map will be displayed within. If this style attribute is missing the Bing map will overflow beyond the bounds of the DIV in the Google Chrome and Mozilla Firefox browsers.

Google

To embed a Google map on your page the first thing you will need to add is the reference to the Google map JavaScript API.

<script type="text/javascript" src="http://maps.google.com/maps?file=api&v=2&key=abcdefg&sensor=false"></script>

There are a few new items here. Again, we have a version refere (v=2) but now we also see a key parameter. Your site must register with Google to obtain a key for using the API. Failing to do so will result in a pop-up nag on your page. The advantage of registering for a key is that it eliminates the pop-up nag, and if you decide to purchase the support, will allow access to additional calls and features. The sensor parameter is used for enabling location aware services on mobile devices. We will leave this off for now, but I may cover it a bit in a future post.

As with the Bing map, we need to write a bit of script to initialize our Google map. We will create a global variable to hold reference to the map. Just like the Bing script, the Google script needs to both create the map object and then load the map content centered on a location and zoom level.

<HTML>
<HEAD>
<SCRIPT type="text/javascript" src="http://maps.google.com/maps?file=api&v=2&key=abcdefg&sensor=false"></SCRIPT>
<SCRIPT>
var googleMap;
function googleInitializer()
{
googleMap = new GMap2(document.getElementById("mapDiv"));
googleMap.setCenter(new GLatLng(39.768519, -86.158041), 13);
}
</SCRIPT>
</HEAD>
<BODY onload="googleInitializer()">
<DIV id="mapDiv" style="position:relative;width:640px;height:480px"></DIV>
</BODY>
</HTML>

Of note here is that, while the constructor for the Google Map object (GMap2) takes the HTML element that will host the map as the argument, you must get a reference to the element rather than supplying only the element ID. The zoom level value for Google Maps works just like Bing maps.

Yahoo

To embed a Yahoo map on your page the first thing you will need to add is the reference to the Yahoo map JavaScript API.

<script type="text/javascript" src="http://api.maps.yahoo.com/ajaxymap?v=3.8&appid=YD-eQRpTl0_JX2E95l_xAFs5UwZUlNQhhn7lj1H"></script>

Here again we see a version number (v=3.8) and a application ID.

No surprises when writing script to initialize the Yahoo map.

<HTML>
<HEAD>
<SCRIPT type="text/javascript" src="http://api.maps.yahoo.com/ajaxymap?v=3.8&appid=YD-eQRpTl0_JX2E95l_xAFs5UwZUlNQhhn7lj1H"></SCRIPT>
<SCRIPT>
var yahooMap;
function yahooInitializer()
{
yahooMap = new YMap(document.getElementById('mapDiv'));
yahooMap.drawZoomAndCenter(new YGeoPoint(39.768519, -86.158041), 5);
}
</SCRIPT>
</HEAD>
<BODY onload="yahooInitializer()">
<DIV id="mapDiv" style="position:relative;width:640;height:480"></DIV>
</BODY>
</HTML>

The only difference to note between the Yahoo map and the other mapping APIs is that the zoom value is reversed. Lower numbers mean closer to the ground while higher numbers mean farther away. One interesting quirk: the yahoo scripts for displaying a map use a global JavaScript variable 'i'. This is a common counting variable, and I'm guessing a bug on Yahoo's part. In any case, if you are using 'i' as a variable in the same code that is loading a map, you are highly advised to rename the variable to something more descriptive lest you find the Yahoo code has given it a new and unexpected value.

MapQuest

To embed a MapQuest map on your page the first thing you will need to add is the reference to the MapQuest map JavaScript API.

<script type="text/javascript" src="http://btilelog.access.mapquest.com/tilelog/transaction?transaction=script&key=mjtd%7Clu6t2h07n1%2C2x%3Do5-lw7l9&itk=true&v=5.3.s&ipkg=controls1,traffic&ipr=false"></script>

Again we see a key parameter (key=) and a version number parameter (v=). There are a few new players here though. The itk parameter is needed to include the Tile Map Toolkit in the scripts. Make sure this is part of the include string, and always set to true. The ipkg paramter indicates which features of the map are available to the user. Make sure this includes the controls1 value at a minimum. The ipr parameter is to indicate if you are using the premium features of the API (true) or the free version (false).

<HTML>
<HEAD>
<SCRIPT type="text/javascript" src="http://btilelog.access.mapquest.com/tilelog/transaction?transaction=script&key=mjtd%7Clu6t2h07n1%2C2x%3Do5-lw7l9&itk=true&v=5.3.s&ipkg=controls1,traffic&ipr=false"></SCRIPT>
<SCRIPT>
var mapquestMap;
function mapquestInitializer()
{
mapquestMap = new MQA.TileMap(document.getElementById('mapDiv'));
mapquestMap.setCenter(new MQA.LatLng(39.768519, -86.158041), 10);
}
</SCRIPT>
</HEAD>
<BODY onload="mapquestInitializer()">
<DIV id="mapDiv" style="position:relative;width:640px;height:480px"></DIV>
</BODY>
</HTML>

The MapQuest map zoom values are like the Bing and Google maps (bigger number is closer in) but the values do not correlate one to one like the Bing and Google maps do. A couple of notes are in order with regard to the dimensions of the DIV used for displaying the MapQuest map. First, the MapQuest API will not honor percentages when used for the map dimensions. If you try to create a map with an in-line style of 100% for height and width you will find the map actually displayed at 100 pixels by 100 pixels. Second, the MapQuest map API seems to have an issue with cascading style sheets. If the DIV that is hosting your map gets the height and width set from CSS rather than an inline style attribute the API may apply the height dimension to both height and width. This bug may be addressed in the future, but at present be sure to specify the height and width values inline with the DIV tag.

Is That It?

Getting the map on the page is just the start, and in the coming posts I will show you how to do some more interesting things with the map, such as displaying a point of interest and getting a lattitude and longitude value for an address. Until then, if you would like to read more about each API you can check out the following resources.

Developing with Online Map APIs

I'm planning to give a talk providing a basic introduction to the use of online mapping APIs. I plan to cover the big four: AOL (MapQuest), Google, Microsoft (Bing nee Virtual Earth), and Yahoo. The goal of the talk is to whet the appetite of site developers with the ease of putting a map on their site, and how valuable that map can be. I also hope to demonstrate where one mapping system provides particular advantages or disadvantages.
To kick things off, a bit of trivia: what is the most popular website for travel (and thus mapping)? If you said Google, you were right, but that has only been true for a few months. As recently as 2009 MapQuest had the crown as the number one portal for travel. HitWise has published their report for January 2010, and there you can see that Google Maps has opened a commanding lead. Travel is a pretty broad topic though, and we're talking about mapping. I've chosen AOL, Google, Microsoft, and Yahoo for this discussion as they are the most popular services offering a public API to their mapping technology.
Over the course of the next few weeks I will provide a series of posts covering the following mapping tasks:
  • Displaying a map on a page
  • Adding controls to the map
  • Adding points of interest to the map
  • Geocoding and Reverse Geocoding
  • Map events
  • Unique features to each API
I hope that this series is informative and useful.