Go to home page
Get a quotation

Backtobasics Blog


Creating Google Map Overlays With Scribble Maps

Posted on: October 22nd, 2014

Modern web designers have a plethora of tools available to make websites that provide engaging user experiences. One of the tools used by a large number of web designers is Google Maps and the Google Maps API. This powerful API can provide developers with the tools to present map-based information in ways that are visually stunning as well as useful.

One of the cool features of the API is the ability to present a map with overlays. An overlay is simply a region of the map that can be defined for the purpose of interaction or presentation. For example, you might want to highlight your home town, or define an area of the map that you can attach statistical information to present when the user hovers the mouse.

One of our clients, Samui Property Locator wished to present a map of Koh Samui, Thailand for their front page. But they wanted to be able to break up the island into regions in which their properties were located, allowing the user to better search the available properties they had to offer. This is very straightforward to create with the Google Maps API, with one requirement – the regions needed to be defined.

As with any map, points of interest and regions are defined in map coordinates – namely longitude and latitude coordinates.

Defining these regions in terms of longitude and latitude presented a formidable task. We searched the web for some source of this information, but we were not able to find precisely what the client was looking for. Of course, we could find data that provided the outline of Koh Samui, but the client needed this broken down into the regions he wished to define for his specific requirement.

Enter the awesome Scribble Map folks! The Scribble Map team has put together a fabulous set of tools for working with maps. Specifically, they have a set of tools that makes drawing regions over a map very easy for an end user. Combined with a little magic, we were able to produce a simple tool for the client to use to define the regions of Koh Samui that he wished to highlight on Google Maps. The Scribble Map team provides an excellent YouTube video describing what we are doing.

What we needed was a set of coordinates that defined the overlays for the map that he wished to present. So, we setup a simple webpage that utilized Scribble Map’s API to present Koh Samui along with the tools needed to draw outlines of the regions that the user wanted to define. We tied this into a simple PHP program that would in turn dump the regions into a JavaScript file that defined the coordinate information as JSON data. That JSON data contained the longitude and latitude coordinates that we needed to define the overlays that the user wanted to present on the Google Map.

Here is a picture of the Scribble Map page that we presented to the client:

scribble_screen

Setting up this page is very simple. The PHP code for this page looks like this:

<html>
<head>
   <script type="text/javascript" src="http://scribblemaps.com/api/js"></script>
   <script type="text/javascript" src="http://temp.bkbasic.com/scribble/scribble.js"></script>
<style>
#dump_overlays {
   position: absolute;
   z-index: 10000;
   left: 12px;
   bottom: 32px;
   padding: 6px 12px;
}
</style>
</head>
<body>
   <div id="ScribbleMap" style="width: 100%; height: 100%;"></div>
   <button id="dump_overlays" onclick="dump_overlays()">Dump</button>
</body>
</html>

In the <head> of the page, we are including the Scribble Map API JavaScript needed to drive the map tools that they provide. We are also including our own JavaScript to setup the map tools and push the client’s work up to our server. You can see that we define a simple button element and place that over the map in the lower left corner. The client will use this to push their data to our server when they have defined their overlays.

The JavaScript in our scribble.js looks like this:

theMap = null;
window.onload = function() {
   theMap = new ScribbleMap(document.getElementById('ScribbleMap'));
   theMap.settings.clearListeners();
   theMap.map.loadById( "<?php echo $map_id; ?>" );
   theMap.map.addListener( scribblemaps.MapEvent.OVERLAY_ADDED, function(event) {
      console.log( "OVERLAY ADDED..." );
   });
}

function dump_overlays() {
   overlays = theMap.map.getOverlays();
   json_data = "var overlay_data = { \"map_id\": \"<?php echo $map_id; ?>\", \"overlays\": [ ";
   for ( var oIdx = 0 ; oIdx < overlays.length ; oIdx++ ) {
      overlay = overlays[oIdx];
      coords = overlay.getCoords();
      json_data += "{ \"idx\": " + oIdx + ", \"coordinates\": [";
      for ( var cIdx = 0 ; cIdx < coords.length ; cIdx++ ) {
         coord = coords[cIdx];
         json_data += "{ \"long\": " + coord.lng() + ", \"lat\": " + coord.lat() + " }";
         if ( cIdx < (coords.length - 1) ) { json_data += ", "; }
      }
      json_data += "] }";
      if ( oIdx < (overlays.length - 1) ) { json_data = json_data + ", "; }
   }
   json_data += " ] };";
   var xmlhttp = new XMLHttpRequest();
   xmlhttp.open( "POST", "/scribble/dump_coords.php", true );
   xmlhttp.setRequestHeader( "Content-type", "application/x-www-form-urlencoded" );
   xmlhttp.onreadystatechange = function() {
      if ( xmlhttp.readyState == 4 && xmlhttp.status == 200 ) {
         eval( xmlhttp.responseText );
      }
   }
   xmlhttp.send( "map_id=<?php echo $map_id; ?>&overlay_data=" + json_data );
}

The window.onload function is what sets up the map for the client to work with. Scribble Map provides an excellent video describing how to use their API, which describes precisely what we are doing there.

The dump_overlays() function is what gets called when the client clicks the “Dump” button that you see in the lower left corner of the map. This function grabs the overlays that the client has defined with the Scribble Map, packages it up into a JSON data structure, then submits it to our server.

This is what the client’s map looked like after he had added his regions:

scribble_map

Finally, on the server side, we have the simple PHP program dump_coords.php that looks like this:

<?php
   $filename = $_POST["map_id"] . "-map.json";
   error_log( "Filename: " . $filename );
   $filepath = "/tmp/scribble/" . $filename;
   error_log( "Filepath: " . $filepath );
   $cfile = fopen( $filepath, "w" ) or die("Unable to open file!");
   if ( $cfile ) {
      $bytes = fwrite( $cfile, $_POST["overlay_data"] );
      fclose( $cfile );
      if ( ! $bytes ) {
         echo "alert( 'An error occurred while saving the coordinates.' );";
      } else {
         echo "alert( 'Overlay coordinate files written successfully.' );";
      }
   } else {
      echo "alert( 'An error occurred creating the file to save the coordinates.' );";
   }
?>

This simply stores the JSON data JavaScript code to a file in the /tmp directory so that we can grab it and integrate it into the Google Map overlays when we present the client’s map on their website. To do that, we implement some simple JavaScript into the client’s map page:

<script type="text/javascript" src="http://client.website.com/data/overlay_data.js"></script>
<script>

function initialize() {
   var mapOptions = {
      center: { lat: 9.4936498, lng: 100.0041434 },
      zoom: 12
   };

   map = new google.maps.Map( document.getElementById( 'map-canvas' ), mapOptions );
   for ( var oIdx = 0 ; oIdx < overlay_count ; oIdx++ ) {
      var overlay_coords = overlay_data.overlays[oIdx].coordinates;
      if ( overlay_coords.length > 1 ) { // Make sure the overlay has valid data...
         vertices = new Array( overlay_coords.length );
         for ( var cIdx = 0 ; cIdx < overlay_coords.length ; cIdx++ ) {
            vertices[cIdx] = new google.maps.LatLng( overlay_coords[cIdx].lat, overlay_coords[cIdx].long );
         }
         var overlay = new google.maps.Polygon({
            paths: vertices,
            strokeColor: "#FF0000",
            strokeOpacity: 0.60,
            strokeWeight: 0.5,
            fillColor: "#999999",
            fillOpacity: 0.20,
         });
         overlay.setMap( map );

         var marker = new google.maps.Marker({
            map: map,
            position: new google.maps.LatLng( overlay_coords[0].lat, overlay_coords[0].long ),
            title: "Overlay #" + oIdx
         });
      }
   }
}

google.maps.event.addDomListener( window, 'load', initialize );
</script>

With this code, the first <script> element is importing the JSON datafile that we generated, which is conveniently formatted to be valid JavaScript. Loading the file initializes a JavaScript variable named overlay_data. We then use that variable in the inline <script> that follows, which sets up the Google Map, places it into the <div> with id=”map-canvas”, then adds the overlays, along with markers on each overlay.

And here is the resulting Google Map display with the client’s overlays:

samui_google_map