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:
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.
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 |
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 |