February 27, 2010 6

AS3 Encoded Polyline Algorithm For Google Maps

By duncanhall in Actionscript

The Google Maps API uses Polyline objects to represent a series of straight lines between a set of latitude and longitude points. Long and complicated lines can become quite cumbersome to describe (especially when needing to send Polyline data to a remote service for example). For this reason, Google provides a method for encoding a Polyline as a series of ASCII characters, with each vertex defined by its distance from the last, rather than the absolute location of each one.

The Encoded Polyline Algorithm Format page documents the steps necessary to encode a set of lat/long points in the required format. For those of us working with the Google Maps API for Flash, I have written an Actionscript 3 implementation of the encoder, in the form of the PolylineEncoder Class.

PolylineEncoder.fromPoints()
Takes a Vector of LatLng objects and returns the encoded string representation:

var points:Vector. = new Vector.();
points.push(new LatLng(38.5, -120.2), new LatLng(40.7, -120.95), new LatLng(43.252, -126.453))
var encoded:String = PolylineEncoder.fromPoints(points);
trace(encoded); //Outputs _p~iF~ps|U_ulLnnqC_mqNvxq`@

PolylineEncoder.fromPolyline()
Takes an existing IPolyline object and returns the encoded string representation:

var poly:Polyline = new Polyline([new LatLng(38.5, -120.2), new LatLng(40.7, -120.95), new LatLng(43.252, -126.453)]);
var encoded:String = PolylineEncoder.fromPolyline(poly);
trace(encoded); //Outputs _p~iF~ps|U_ulLnnqC_mqNvxq`@

PolylineEncoder.encodeLevels()
Takes an Array of uint level values and returns the encoded string representation:

var encodedLevels:String = PolylineEncoder.encodeLevels([174, 100, 100, 174]);
trace(levels); //Outputs mDcBcBmD

The use of the ‘level’ value is described by Google:

An encoded polyline also stores information specifying the precision when drawing the polyline. This information allows the map to ignore drawing segments at zoom levels where that precision is not necessary. Each point in an encoded polyline stores this information in a levels string which is also encoded alongside the encoded points.

Note: this encoded “level” does not correspond directly to a zoom level, though they are related. More accurately, the numLevels parameter divides up the existing zoom levels (currently 18) into groups of zoom levels.

In other words, if you are encoding a Polyline purely for storing locational data, it’s not necessary to encode a level value for each point on the line. The lat/lng of the original point is unaffected by its level value.

var encodedPoints:String = PolylineEncoder.encodeFromPolyline(existingPolyline);
var encodedLevels:String = PoylineEncoder.encodeLevels([100]);
var encodedPolyline:EncodedPolylineData = new EncodedPolylineData(encodedPoints, 4, encodedLevels, 16)
var decodedPolyline:Polyline = Polyline.fromEncoded(encodedPolyline);
trace(existingPolyline.getLength() == decodedPolyline.getLength()); //true!

View source for PolylineEncoder.as
Download PolylineEncoder.as
View PolylineEncoder Documentatation

  • Twitter
  • del.icio.us
  • Digg
  • Reddit
  • Tumblr
  • Posterous
  • Live
  • Google Bookmarks
  • RSS

Tags: , , ,

6 Responses to “AS3 Encoded Polyline Algorithm For Google Maps”

  1. Rosco says:

    Hi,

    This looks like exactly what I needed. I was trying to come up with a way to take an array of LatLng values and save them to a database but I guess with this I can save the encoded value?

    Also, do we need to decode or am I right in saying we can simply draw an encoded polyline?

    Cheers

  2. Dan Homerick says:

    Hi,
    I’d like to use this code in an open-source project I’m working on, but I didn’t find a copyright disclaimer in the download. Would you be willing license the code under a permissive license such as the MIT license, and include a copy of the license in the code?

    http://www.opensource.org/licenses/mit-license.php

    Cheers,
    – Dan

  3. duncanhall says:

    Hey Dan,

    yep, you’re free to use this as you please and I’m glad you’ve found it useful. I’m not sure what issues you’re having with the license though, if you look at the source at http://code.google.com/p/duncanhall-lib/source/browse/trunk/net/duncanhall/gmaps/PolylineEncoder.as you can see it’s licensed under GNU General Public License which should cover your needs.

  4. Dan Homerick says:

    GPLv3 will work just fine. The download link on this page (2nd paragraph) goes to an apparently older version that lacks the license info.

    Thanks!

  5. Marco says:

    Hi, Duncan.

    Thank you so much for posting this! I’ve spent the last six hours trying to get the encoded String that results from a Directions request. After reading this post, it only took me 15 minutes.

    I wonder why Google doesn’t allow access to it? It is part of the response you get from their servers, a simple Directions.getEncodedPoints() would’ve been great. Nonetheless, you’re a lifesaver, so thank you for taking the time to share this with us.

    - Marco

  6. duncanhall says:

    @Dan – You’re right, the first link was pointing to an older version of the source, which I’ve now updated. Cheers for pointing that out, I’d be interested to hear your uses.

    @Marco – Thanks a lot for your kind words, I’m glad it was helpful. I spent a decent amount of time smashing my face into the desk when I first stumbled across the encoded Polyline problem, which is what prompted me to create this in the first place.

    As you say, it does seem odd that the ‘native’ Google Maps Flash API doesn’t expose the encoded String given that it must exist somewhere. Perhaps it’s a consequence of trying to keep the Flash API featureset common with the JS version. In any case, it’s definatly something worth adding as a feature request, which I shall do very soon.

Leave a Reply

*