Using OpenStreetMaps with the Google Maps API

Joor Loohuis, August 6, 2009, 18261 views.

It is relatively easy to add a new map type to Google Maps, provided you have access to a tile server. As an example, we use the OpenStreetMaps data set to display a map that doesn't have all the usage restrictions that the regular map types have.

Tags: , , , , ,

Most applications of Google Maps happily use the few existing map types, the normal road map, the satellite map, the hybrid satellite/road map and/or the physical map. These are all available as tilesets from Google under their terms of use. However, you may have reasons to load a different tileset into a Google Map, for example because the terms of use of the standard tilesets don't suit your application. In that case, and depending on your location, OpenStreetMaps (OSM) might be a reasonable alternative. Many applications of OpenStreetMaps use the OpenLayers JavaScript API, but if you have invested time in learning the Google Maps JavaScript API, or if you already have code using it, you may be looking for a way of getting OSM tiles into your existing Google Maps application.

Getting OSM tiles in a Google Map.

Since the OSM people are generous by nature, they've already provided a bare bones example of the principle in the OpenStreetMaps Wiki. It occurred to us that a little background and explanation might be nice, and so we've created a working example of using OSM data in a Google Map.

The basis is a little web page in which we embed the map. The HTML is intentionally kept sober.

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
  <script src="/js/prototype.js" type="text/javascript"></script>
  <script src="http://maps.google.com/maps?file=api&v=2&key=GOOGLE-API-KEY" type="text/javascript"></script>
  <script src="/js/osm.js" type="text/javascript"></script>
  <link rel="stylesheet" href="/skin/osm.css">
</head>
<body>
  <form>
    <input type="hidden" id="maplat" value="52.1">
    <input type="hidden" id="maplng" value="5.1">
    <input type="hidden" id="mapzoom" value="10">
  </form>
  <div id="osmmap"></div>
</body>
</html>

Of course we still load the Google Maps API, so you do need an API key for the domain in which the map is used. We use a little hidden form to pass the center and zoom level of the map. We typically do this since it's an easy way of communicating the map state that may have been stored in a user session. If that is not the case, it is still an easy way of defining the defaults from HTML. In this particular case the coordinates happen to be very close to where we're located. For the sake of brevity we'll omit what is in de stylesheet. The essence is that the dimensions of the div that will hold the map are defined.

The JavaScript which does the actual map generation is contained in a class using the Prototype JavaScript library, so that the map can be cleanly integrated into an existing site or application, and can also be easily extended.

// osm.js: integrate OSM map in Google Maps API
// derived from http://wiki.openstreetmap.org/wiki/Google_Maps_Example
// Creative Commons Attribution-ShareAlike 2.0
// http://wiki.openstreetmap.org/wiki/OpenStreetMap_License
 
// use the Prototype pseudo event to set up the map when the document has loaded
document.observe('dom:loaded', function() 
{
    // only load the map code when the div is in the document
    if ($('osmmap') && GBrowserIsCompatible()) {
        new OSMMap($('osmmap'));
        // application cleanup when the page unloads
        Event.observe(window, 'unload', function() {GUnload();});
    }
});
 
// map handler class
var OSMMap = Class.create({
 
    // Prototype automatically calls this method when an object is instantiated
    initialize: function(mapElm)
    {
        // create a copyright statement for the OSM layer
        var copyOSM = new GCopyrightCollection('<a href="http://www.openstreetmap.org/">OpenStreetMap</a>');
        // apply the statement to the whole world
        copyOSM.addCopyright(new GCopyright(1, 
            new GLatLngBounds(new GLatLng(-90, -180), new GLatLng(90, 180)), // region
            0, // minimum zoom level
            ' ' // no additional copyright message, but empty string hides entire copyright
        ));
        // create a tile layer
        var tilesMapnik = new GTileLayer(
            copyOSM, // copyright statement
            7, // minimum zoom level
            18, // maximum zoom level
            {
                // options includes URL template for addressing individual tiles
                // X, Y, Z respectively are tile coordinates for lattitude and longitude,
                // and the zoom level
                tileUrlTemplate: 'http://tile.openstreetmap.org/{Z}/{X}/{Y}.png',
                isPng: true // otherwize assumes GIF images
            }
        );
        // create a new map type
        var mapMapnik = new GMapType(
            tilesMapnik, // list of layers
            G_NORMAL_MAP.getProjection(), // borrow the Mercator projection from the standard map
            'OSM' // name should be short enough to fit in button
        );
        // finally, create actual map
        this.map = new GMap2(
            mapElm, // element that will contain map
            {mapTypes: [mapMapnik, G_NORMAL_MAP]} // list of map types
        );
        this.map.addControl(new GMapTypeControl()); // allow map type selection
        this.map.addControl(new GLargeMapControl()); // large zoom/pan controls
        this.map.enableScrollWheelZoom(); // convenient zooming with scroll wheel
        // get center and zoom level from hidden form
        this.map.setCenter(
            new GLatLng(parseFloat($F('maplat')), parseFloat($F('maplng'))),
            parseInt($F('mapzoom'))
        );
    }
 
    // add your own methods here
});

The commented code should be self explanatory, but detailed information is of course available in the Google Maps JavaScript API reference If you happen to have access to another tile server, it should be clear how you can add it to your maps. A working example of the code in this article can be found here.

Social networking: Tweet this article on Twitter Pass on this article on LinkedIn Bookmark this article on Google Bookmark this article on Yahoo! Bookmark this article on Technorati Bookmark this article on Delicious Share this article on Facebook Digg this article on Digg Submit this article to Reddit Thumb this article up at StumbleUpon Submit this article to Furl

Talkback

respond to this article

Re: Using OpenStreetMaps with the Google Maps API (sh, 2012-01-29 06:29 CET)
I'm trying to integrate this code into a Google Maps ASP.NET Control, would you be able to help me, please?