Skip to main content

Drawing paths on Google Maps, the Indiana Jones way

I was looking into the Google Maps API the other day and came across some APIs which are really cool. I came up with a use case to show path from the current location to a particular destination entered by the user. I was also trying to achieve that Indiana Jones like effect on the map i.e. to show an animation of the path being drawn on the map.


The idea here is to show the moving path until the destination is reached and also to pan the map accordingly.

Unable to display content. Adobe Flash is required.

As seen in the video, a marker is added to the map specifying my current location (Bangalore, India). The current location data is retrieved using the HTML5’s Geolocation API. Once the latitude and longitude information are available, a marker can be added to the map. You can now enter one of your favorite destinations in the text box provided and click the Submit button to see a path drawn from your current location to the destination. The path is drawn using the Google maps ‘Polyline’ API.

Getting the current location data using HTML5’s Geolocation API:

The Geolocation API allows users share their current location information with trusted sites. You can examine the property navigator.geolocation to see whether the browser supports the Geolocation API. Alternatively, Modernizr can be used to determine the same. All modern browsers support the Geolocation API; however users are required to provide permission to the websites. Once the user has provided the permission, the method getCurrentPosition can be invoked on the navigator.geolocation object:
 navigator.geolocation.getCurrentPosition(function(position){  
     var mapElement = document.getElementById('mapelement');  
     startLatitude = position.coords.latitude;  
     startLongitude = position.coords.longitude;  
     mapObj = new google.maps.Map(mapElement,  
     {  
         disableDefaultUI:true,  
         zoom: 3,  
         center: new google.maps.LatLng(startLatitude,startLongitude),  
         mapTypeId: google.maps.MapTypeId.TERRAIN  
     });  
     var markerPosition = new google.maps.LatLng(position.coords.latitude,position.coords.longitude);  
     var startPosition = markerPosition;                                     
     var marker = new google.maps.Marker({position:markerPosition,map:mapObj,title:'You are here'});       
});  

Once the latitude and longitude information is available, they can be used to specify the center address and to add a marker on the map.


Drawing the path using the Polyline API:


A polyline is a linear overlay of connected line segments on the map. To draw a line on the map using the Polyline API, you have to pass the map object along with the coordinates specifying the end points as arguments. However, to get the Indiana Jones like effect, you must get as many points between the start and the end location. The latitude and longitude information of these points are then stored in an array and will later be used to achieve the desired effect.


For the purpose of this example, I’ve assumed 30 animation frames and have calculated the increment:

 function getPathData(destLatitude,destLongitude){  
    var xInc,yInc;  
    xInc = (destLatitude - startLatitude)/30;  
    yInc = (destLongitude - startLongitude)/30;  
    for(var i=0;i<30;i++){  
      path[i] = new google.maps.LatLng(startLatitude += xInc,startLongitude += yInc);       
    }  
 }  

The path array would then contain the latitude and longitude information for the points between the start and the end location. This information can then be used to draw the path and get the desired effect:

 function drawPath(){  
    var polyLine = new google.maps.Polyline({  
                       path: [startPosition,path[positionIndex]],  
                       strokeColor:'#FF0000',  
                       strokeOpacity:2,  
                       strokeWeight:8,  
                   });  
    polyLine.setMap(mapObj);  
    mapObj.panTo(path[positionIndex]);  
    positionIndex = positionIndex + 1;  
    if(positionIndex < 30){  
      setTimeout(drawPath,200);  
    }                            
 }  

As seen in the above code snippet, the Polyline API is invoked with the arguments path, strokeColor, strokeOpacity, and strokeWeight. Also, the map is panned to the current position while the path is being drawn on the map.


Can I use ColdFusion’s CFMAP tag to get this effect?


This was the initial idea and I did attempt to get this effect using the CFMAP tag. However, I found that the map object retrieved using the ColdFusion.map.getMapObject was not compatible with the Polyline API and hence decided to use the Google maps API to get that effect.

Comments

Popular posts from this blog

File upload and Progress events with HTML5 XmlHttpRequest Level 2

The XmlHttpRequest Level 2 specification adds several enhancements to the XmlHttpRequest object. Last week I had blogged about cross-origin-requests and how it is different from Flash\Silverlight's approach .  With Level 2 specification one can upload the file to the server by passing the file object to the send method. In this post I'll try to explore uploading file using XmlHttpRequest 2 in conjunction with the progress events. I'll also provide a description on the new HTML5 tag -  progress which can be updated while the file is being uploaded to the server. And of course, some ColdFusion code that will show how the file is accepted and stored on the server directory.

Server sent events with HTML5 and ColdFusion

There are several ways to interact with the server apart from the traditional request\response and refresh all protocol. They are polling, long polling, Ajax and Websockets ( pusherapp ). Of all these Ajax and Websockets have been very popular. There is another way to interact with the server such that the server can send notifications to the client using Server Sent Events (SSE) . SSE is a part of HTML5 spec:  http://dev.w3.org/html5/eventsource/

Adding beforeRender and afterRender functions to a Backbone View

I was working on a Backbone application that updated the DOM when a response was received from the server. In a Backbone View, the initialize method would perform some operations and then call the render method to update the view. This worked fine, however there was scenario where in I wanted to perform some tasks before and after rendering the view. This can be considered as firing an event before and after the function had completed its execution. I found a very simple way to do this with Underscore's wrap method.