Playing with Google Maps and encoded polylines

I’ve been playing around with the Google Maps API for a bit and it’s turned out to be a great way to get started with “mashups” and the like. One of the best uses of the API is the ability to create paths or routes on the map.

This is done by creating GPolyline object and then adding it as an overlay to the map. Basically, a polyline is just an ordered list of geographical points/coordinates on the map, each of which is a GLatLng object. For serialization/storage of polylines, there is an algorithm you can use to Base64-encode a series of points; the resultant string can later be passed directly into a factory method to regenerate the GPolyline. By using encoded polylines, you also get access to a few more interesting and useful options related to rendering and performance issues.

Encoded Polylines

Despite the algorithm for encoding polylines being readily available on the Google Maps API documentation site, there is no built-in functionality within the API for generating the encoded polyline string from an existing GPolyline object. This might be a bit strange, but it’s probably because the encoding process requires some extra values that aren’t available in the typical polyline.

As specified on the algorithm page, you also need to specify a list of encoded “levels” in addition to the points themselves. These levels tell the the Google Maps renderer when certain points can be omitted from the polyline depending on the zoom level. For example, with a polyline with n points, you’ll always want to show the first and last point, no matter what the zoom level. However, intermediate points can potentially be omitted at low zoom levels and only shown when the map has been sufficiently zoomed in to warrant the detail. This sort of optimization cannot be done with the typical GPolyline constructor that just takes an array of points. (GLatLng objects)

Making things easy

If you’ve looked at the polyline encoding algorithm, you’ll probably notice that it’s a bit tricky unless you’ve taken course in CS or done a lot of this stuff before. (At least it was tricky for me) Google has an interactive utility for generating the encoded polyline format for you. The results can then be stored and later fed into a call to the factory method GPolyline.fromEncoded() to regenerate the polyline.

However if you want to generate the encoded polyline format on-the-fly as part of your application, the interactive utility is not really an option. Instead of coding the algorithm from the ground-up, there’s a much better way of doing things, thanks to the PolylineEncoder class and other utilities provided by Mark McClure.

The PolylineEncoder class is written in JavaScript and is very straightforward in its usage. (It has been ported to several other languages as listed on his site, in case you need to use it in different contexts)

Using this class allows you to quickly and easily convert a GPolyline into a compact encoded format useful for serialization or storage. You can also use the class to convert arrays of points into encoded polylines, thus gaining the benefit of optimized rendering at different zoom levels. McClure goes into an in-depth, but easy to understand explanation of the encoding algorithm used complete with animations that show exactly how the polyline approximations work.

I highly recommend the usage of his polyline encoder as it saves you the headache of implementing it yourself. It’s well-written, thoroughly documented and is free for usage. (It isn’t licensed under open-source terms but has instead been placed in the public domain – which is perhaps even more “free”) McClure also has a few other interesing Google Maps projects that you may want to check out.

Some documentation warnings

The Google Maps API documentation is fairly thorough, but it’s out of date in some places, as some people have found. Indeed, in this case, it appears that the GPolyline.fromEncoded() is documented somewhat wrongly in the API reference, though curiously, is used properly in their examples page.

Specifically, you should not use:

GPolyline.fromEncoded(color?,  weight?,  opacity?,  latlngs,  zoomFactor,  levels,  numLevels)

if you want to generate a polyline from the encoded format. Instead, you should use something like:

GPolyline.fromEncoded({
    color: "#FF0000",
    weight: 10,
    points: "yzocFzynhVq}@n}@o}@nzD",
    levels: "BBB",
    zoomFactor: 32,
    numLevels: 4
});

This is because the API has been updated to accept an object of options instead of separate parameters. This, in my opinion, is better for readability and takes advantage of JavaScript’s ability to define inline anonymous object literals.

As a side note, the example actually calls something like new GPolyline.fromEncoded, but I’ve found that you don’t need the new keyword, and in fact, it’s a bit confusing that the example has it and that it would work – after all, you are calling a factory method that returns a type of GPolyline, and not directly instantiating an object. (At least as far as JavaScript uses the new keyword)

7 Comments »

  1. Thanks for the article. It helped to clear up a lot of confusion on my part regarding encoded polylines in Google Maps.

  2. […] Chng has written an article about encoded polylines, Playing with Google Maps and encoded polylines, that helped clear a lot of my […]

  3. I think you can still specify polyline opacity.

  4. @parxier
    Yes, you may be right, you just need to include the opacity entry in the options object passed to GPolyline.fromEncoded.

  5. Can one save the encoded polyline to a file and then read from the file instead of pasting the entire encoded message into points: “” ? I have downloaded a set of encoded polylines for most of the country borders in the world, and I’d like to be able to load the encoded polyline from this file rather than cluttering up my page source.

    Do I use a javascript method read from a file and save the contents of the file to a string, then use the string in points: instead of providing the encoded polyline enclosed in quotes?

    Thanks in advance for your help.

  6. hi,
    I have a kml file which I shown on google map by obtaining its coordinates.It is visible on map.Now I want to add another markers and polylines on map and update the kml file by combining all the markers of earlier coordinates and latest which I am unable to do.

    Anyone has done something like this?

    Thanks in advance…

  7. […] Chng has written an article about encoded polylines, Playing with Google Maps and encoded polylines, that helped clear a lot of my […]

Comments are now closed for this entry.