Duncan's blog

February 14, 2013

Google Maps API – polylines and distances

Filed under: Google Maps,Javascript — duncan @ 6:56 pm
Tags: , , , ,

So after a basic introduction to polylines, let’s try doing a bit more with them. Here’s a simple example based on something I was doing for work. Supposing you have a bunch of different locations, and you want to show the distance between them? In this case I had one central destination, and I wanted to show the distance from there to several nearby towns. I did this initially using polylines, as in this example, although in reality it would be more useful to show driving directions (more on that in a future post).

Here’s what I came up with:

ambleside

And I displayed this table beneath the map:

Destination Distance from Ambleside
Keswick 22.2 km 13.8 miles
Coniston 9.9 km 6.1 miles
Lake District 11.3 km 7 miles
Cumbria 19.7 km 12.2 miles

And here’s the Javascript I used to do it. Originally I was getting my coordinates from the database using ColdFusion, and then writing them into the Javascript. I was also doing some infowindows attached to the markers, and labels on the polylines indicating the distances. But for this post I’ve just kept it simple for now.

<!DOCTYPE html>
<html>
<head>
<title>lines between the nearest destinations showing distance</title>

<meta name="viewport" content="initial-scale=1.0, user-scalable=no" />
<style type="text/css">
html { height: 100% }
body { height: 100%; margin: 0; padding: 0 }
#map_canvas { width:600px; height:500px }
</style>
<!-- need to load the geometry library for calculating distances -->
<script type="text/javascript" src="http://maps.googleapis.com/maps/api/js?libraries=geometry&sensor=false"></script>

<script src="//ajax.googleapis.com/ajax/libs/jquery/1.9.0/jquery.min.js" type="text/javascript"></script>

<script type="text/javascript">
    function initialize() {
        var map, i, latLng, marker, polyline, stuDistances;
    
        var arrDestinations = [
            {title: 'Keswick',        lat: 54.60039,   lng: -3.13632},
            {title: 'Coniston',       lat: 54.36897,   lng: -3.07561},
            {title: 'Lake District',  lat: 54.5003526, lng: -3.0844116},
            {title: 'Cumbria',        lat: 54.57723,   lng: -2.79748}
        ];
        
        var stuHome = {title: 'Ambleside', lat: 54.42838, lng: -2.9623};
        
        var homeLatlng = new google.maps.LatLng(stuHome.lat, stuHome.lng);
        var myOptions = {
            zoom: 10,
            center: homeLatlng,
            mapTypeId: google.maps.MapTypeId.ROADMAP
        };
        map = new google.maps.Map(document.getElementById("map_canvas"), myOptions);
                
        var homeMarker = new google.maps.Marker({
            position: homeLatlng, 
            map: map, 
            title: stuHome.title
        });
        
        $('#tableNeighbours').append(
              '<tr>'
            + '<th>Destination</th>'
            + '<th colspan="2">' + stuHome.title + '</th>'
            + '</tr>'
        );
                  
        for (i = 0; i < arrDestinations.length; i++) {
            latLng = new google.maps.LatLng(arrDestinations[i].lat, arrDestinations[i].lng);
            marker = new google.maps.Marker({
                position: latLng,
                map: map, 
                title: arrDestinations[i].title,
                icon: 'http://maps.google.co.uk/intl/en_ALL/mapfiles/ms/micons/green-dot.png'
            });
                        
            // draw lines between each marker and home.  these are curved lines, not as the crow flies, i.e. they take into account the curvature of the earth (only noticable on longer distances)
            polyline = new google.maps.Polyline({
                path: [homeLatlng, latLng],
                strokeColor: "#FF0000",
                strokeOpacity: 0.5,
                strokeWeight: 4,
                geodesic: true,
                map: map
            });
            
            // calculate the distance between home and this marker
            stuDistances = calculateDistances(homeLatlng, latLng);
            $('#tableNeighbours').append(
                  '<tr>' 
                + '<td>' + arrDestinations[i].title + '</td>'
                + '<td>' + stuDistances.km + ' km</td>'
                + '<td>' + stuDistances.miles + ' miles</td>'
                + '</tr>'
            );
        }
    }
    
    function calculateDistances(start,end) {
        var stuDistances = {};
        
        stuDistances.metres = google.maps.geometry.spherical.computeDistanceBetween(start, end);    // distance in metres
        stuDistances.km = Math.round(stuDistances.metres / 1000 *10)/10;                            // distance in km rounded to 1dp
        stuDistances.miles = Math.round(stuDistances.metres / 1000 * 0.6214 *10)/10;                // distance in miles rounded to 1dp
        
        return stuDistances;
    }
    
    google.maps.event.addDomListener(window, 'load', initialize);
</script>

</head>
<body>
    <div id="map_canvas"></div>
    
    <table id="tableNeighbours" border="1"></table>
</body>
</html>

So I’m dynamically adding the distance information from each location to the table as each marker is added. You’ll notice that in the calculateDistances function, instead of simply dividing the metres distance by 1000 to get it in kilometres, I multiply by 10, then round, then divide by 10. This is in order to round the distances to 1 decimal place.

e.g. the distance between my Ambleside and Keswick markers is 22205.96176105692 metres, according to Google. So to convert that to kilometres if I just divide by 1000 it gives:
22.20596176105692
The Round() function rounds to the nearest integer. So instead let’s only divide by 100 (or divide by 1000 then multiply by 10, as I’m doing, same thing). Which gives:
222.0596176105692
Then we call Math.round(), which gives:
222
And finally divide that by 10:
22.2
There are other ways to achieve this in javascript of course!

Notice as well that we’ve added the optional `libraries=geometry` parameter to the URL for the Google Maps JS file. This is so we can use the Geometry Library to calculate the distance between locations, using the computeDistanceBetween function. Also read this useful article which explains some more about using the Geometry Library.

Advertisements

2 Comments »

  1. Hi Duncan,
    I’m working on a website and I need some help with a little bit of JS. This is my code: https://www.dropbox.com/s/e45bszg9vuiblu3/js.txt
    I needed to add total distance (miles) traveled in the HTML (gps points from a vehicle). I think I need to convert the array to a polyline and then do a ‘computeLength’, but I’m not a JS programmer. Can you help? Maybe I can paypal you for your time.
    Thanks

    Comment by Jim Pennington — August 15, 2013 @ 7:35 pm | Reply

  2. I’d love to see this post with your CF code. Perhaps a future post? Great stuff here, thanks!

    Comment by Tom — October 17, 2013 @ 6:59 pm | Reply


RSS feed for comments on this post. TrackBack URI

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Blog at WordPress.com.

%d bloggers like this: