In usability we trust

UX and all things web

Polylines in Google Maps [Part 1]

Polylines are used to mark out roads, borders and other things that are made of lines in maps. The Google Maps API offers a class for drawing these lines on a Google Map called GPolyline. In this article I will show you how to use these and how to deal with potential performance issues when the polylines gets more complex.

A basic polyline

Polylines consists of several points forming a line. Like for example a road on a map.

Normally you create a GPolyline and add it to the map using GMap2.addOverlay().

// Create an instance of Google map
var map = new GMap2(document.getElementById("map"));

// Tell the map where to start
map.setCenter(new GLatLng(59.3324, 17.8857), 9);

// Create an array with points
var points = [
   new GLatLng(59.6919, 17.8582), 
   new GLatLng(59.3030, 18.0395),	
   new GLatLng(58.9789, 17.5341)
];

// Create a new polyline
var polyline = new GPolyline(points, '#ff0000', 5, 0.7);

// Add the polyline to the map using map.addOverlay()
map.addOverlay(polyline);

As you can see GPolyline takes four arguments. The first one is the only required one, and it’s the coordinates for the polyline. The other ones are optional and are settings for how the polyline will appear. They are, from left to right, the color, the thickness and the opacity of the polyline.

Watch the small polyline example.

This works fine as long as the polyline doesn’t consist of too many coordinates. However when the polyline is more complex the rendering becomes really slow.

More complex polylines

Here’s an example of five polylines with a total of 7841 coordinates which are added to the map the same way as the previous example. You’ll notice that the performance is really starting to degrade. The load time is longer and when you zoom in or out on the map you’ll notice a significant delay.

Watch the complex polylines example (Warning: The loading time can be long)

The performance vary from browser to browser. So if you try the example with Internet Explorer it’s really slow, but with Safari or Google Chrome it’s still pretty fast.

Data format

In the example the coordinates are fetched through an AJAX call to a file containing the coordinates in JSON format. The data structure looks like this:

[{
    "Name":"Section 1",
    "Geom":[[59.1949,17.6596],[59.1942,17.6591],[59.1941,17.659]]
}, 
{
    "Name":"Section 2",
    "Geom":[[59.3819,18.0088],[59.3819,18.0089],[59.3818,18.0091]]
}]

I only show three points per Section here but in the used file there a total of five Sections with thousands of points each.

Better performance

Decrease the number of coordinates

One easy way to make it faster is to try to limit the number of coordinates that you serve to the map. You gain some performance but loose accuracy, especially when you zoom in on the page.

Encoded polylines on the fly

A far better solution is to encode the polylines. It provides much better performance than just decreasing the number of coordinates plus you get better accuracy. The algorithm that encodes the coordinates removes some coordinates but more importantly decreases the number of coordinates when you zoom out, and increase them when zooming in.

Here’s how it’s done.

Instead of just feeding the map with coordinates you first encode them. An excellent encoder is Mark McClure’s PolylineEncoder class. It’s available from Encoding polylines for Google Maps. You can also download PolylineEncoder.js from there.

The encoder doesn’t make a very big difference on the loading time of the page, but when you start zooming and panning, the difference is huge.

Encoding the coordinates

Put all your coordinates in an array and feed it to dpEncodeToGPolyline() in the polylineEncoder class. The coordinates should be in the GLatLng format.

As you may notice dpEncodeToGPolyline() takes exactly the same arguments as GPolyline() and returns a GPolyline. So basically you just call dpEncodeToGPolyline() instead of GPolyline() and then add it to the map with addOverlay(), just like you did with the regular polyline.

// Create an array that will hold the coordinates
var points = [];

// Loop through the coordinates.
// In this case the coordinates are in a JSON object 
for(var j = 0; j < json[i].Geom.length; j++) {
    var coords = json[i].Geom[j];
    //Convert the coordinates to GLatLng and insert into the array
    points.push(new GLatLng(parseFloat(coords[0]), parseFloat(coords[1])));
}

// Create a new instance of PolylineEncoder
var polylineEncoder = new PolylineEncoder();

// Assign the array to dpEncodeToGPolyline  to get an encoded polyline
var polyline = polylineEncoder.dpEncodeToGPolyline(points, '#ff0000', 5, 0.7);

// Add the returned polyline to the map with map.addOverlay()
map.addOverlay(polyline);

The performance boost with this technique is enormous. The loading time can still be quite long but interacting with the map is a totally different experience. Watch the encoded polylines example to see what I mean.

About the encoding algorithm

The encoding algorithm is basically a reduction of unnecessary coordinates at different zoom-levels. The more you zoom-in, the more detail is revealed and the opposite around when you zoom-out.

For an in-depth explanation of how the algorithm works, check out Mark McClure's excellent articles on the subject: Description of encoded polylines and An explanation of the algorithm. Also read Encoded Polyline Algorithm Format on Google.

Encode polylines on the server

Loading time could still be too long, especially in Internet Explorer which has a a notoriously slow Javascript engine. To improve on that you should perform the encoding server side. In the second part of this article I describe how to do just that using PHP, to get dramatically shorter load-times.

Further reading

Mark MacClure, as I've already mentioned, has written a lot on the subject and also provides several examples, so don't miss checking Encoding polylines for Google Maps out.

Peter Chng has written an article about encoded polylines, Playing with Google Maps and encoded polylines, that helped clear a lot of my confusion.

My Google Maps book

If you found this article useful you might be interested in my book Beginning Google Maps API 3. It covers everything you need to know to create awesome maps on your web sites. Buy it on Amazon.com

26 Comments

  1. Excellent posting. Thank you!
    /chris

  2. Cool article! Can I link to it from the documentation?

    – pamela

  3. For sure Pamela, please do!

    /Gabriel

  4. It is really great !

    I need your favour

    Accuracy is not a big matter for us, we have to load large US block groups which may contain around 1 lakhs coordinates It will be great help if you can provide any logic to reduce the coordinates ?
    If I use encoder to load 1 lakh BGPs I am afraid it will fail when user zoom-in.

    Please help me.

    Thanks
    Venkat

  5. @Venkat: Keep your eyes open for my upcoming article about how to encode a polyline on the server. That way you can handle bigger sets of data and dramatically boost load times. It should be out in a couple of days or so. But considering how much data you have you could probably remove a lot of the coordinates before even starting to encode it.

    P.S I had to look up lakh in Wikipedia, I didn’t know that it means 100.000 :-)

    /Gabriel

  6. Hi Gabriel,

    Thanks for your immediate reply. Is there any algoritham to reduce the coordinates ?

    Venkat

  7. @Venkat: You could probably use the Douglas-Peucker Algorithm. It’s the same algorithm that’s used in the PolylineEncoder to reduce the number of points.

    /Gabriel

  8. Gabriel, Thanks for your reply. I already started using it. It works greatly.

    Thanks, Venkat

  9. @Venkat: I’m glad that I could help! :-)

  10. i wanna draw grid on maps how can i do it ?
    for example maps divide 12 cols and 12 rows
    anyone can help me ?

  11. I’ve read about a tool called GE-Path in the article Drawing Grids, Paths And Polygons In Google Earth Using GE-Path which makes it easy to draw a grid on a map. Maybe that’s something you can check out. Otherwise I suggest that you simply draw a bunch of polylines in a grid pattern.

    If you just want a grid that has nothing to do with coordinates on the map but is a part of the UI, you could probably just make an image and put it on top of the map with the help of CSS.

  12. hi

    How to pass the encoded polylines to google map in C#.

  13. Suresh: I make an AJAX call from the web page with the map to an URL that returns the Encoded Polyline in JSON format. Check out Polylines in Google Maps [Part 2] to see how you add it to the map.

    If you’re using the ASP.NET MVC Framework it’s extremely easy to return objects as JSON. Check out the article ASP.NET MVC and JSON to see how it’s done. If your not using the MVC framework you can still do it, it just takes some more work.

  14. Thanks for this cool article. Very informative!

  15. Thank you, this is exactly what I looked for :)

  16. How can I display several PolyLines once a time ?

  17. how to get an array of latlong of intermediate points?

  18. google maps api is very well,
    now i use to my website for bus.

  19. AurelioAbelPatricio

    May 14, 2010 at 4:24 am

    Really nice!!
    Thanks.

  20. great article! thanks for your sharing!

  21. Hi great.,
    How to clear poly line. any example articles…?

  22. Very Good

  23. This article is really good one…
    This article may solve my lots of problem.
    I am using big polygons top of Google and it make google die…
    I think that will solve the issue ….

    Thanks .. :)

    Sudip Barman

  24. I’ve done the performance test with khtml.maplib. Have a look at:
    http://maplib.khtml.org/wordpress/?p=80

  25. Hi
    You should mention that it is maps V2 (deprecated) and now one should use V3.
    Best
    Lotfi

Leave a Reply

Your email address will not be published.

*

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>