Friday, November 13, 2009

GPolyline decoding in Python

I am currently working on providing GPX data for routes on http://zoomaroundtown.appspot.com. As the routes are stored as Google Map GPolyline encoded strings in the datastore, I need a way to decode them back into latitude and longitude points before I can create the respective GPX files. Mark McClure has an excellent page on this topic. Apart from his Javascript implementation, I have also found a PHP port of the decoder function. However, there does not seem to the any Python port, so I created a straightforward port:

You can donwload the Python file here.



def decode_line(encoded):

"""Decodes a polyline that was encoded using the Google Maps method.

See http://code.google.com/apis/maps/documentation/polylinealgorithm.html

This is a straightforward Python port of Mark McClure's JavaScript polyline decoder
(http://facstaff.unca.edu/mcmcclur/GoogleMaps/EncodePolyline/decode.js)
and Peter Chng's PHP polyline decode
(http://unitstep.net/blog/2008/08/02/decoding-google-maps-encoded-polylines-using-php/)
"""

encoded_len = len(encoded)
index = 0
array = []
lat = 0
lng = 0

while index < encoded_len:

b = 0
shift = 0
result = 0

while True:
b = ord(encoded[index]) - 63
index = index + 1
result |= (b & 0x1f) << shift
shift += 5
if b < 0x20:
break

dlat = ~(result >> 1) if result & 1 else result >> 1
lat += dlat

shift = 0
result = 0

while True:
b = ord(encoded[index]) - 63
index = index + 1
result |= (b & 0x1f) << shift
shift += 5
if b < 0x20:
break

dlng = ~(result >> 1) if result & 1 else result >> 1
lng += dlng

array.append((lat * 1e-5, lng * 1e-5))

return array

if __name__ == "__main__":
latlngs = decode_line("grkyHhpc@B[[_IYiLiEgj@a@q@yEoAGi@bEyH_@aHj@m@^qAB{@IkHi@cHcAkPSiMJqEj@s@CkFp@sDfB}Ex@iBj@S_AyIkCcUWgAaA_JUyAFk@{D_]~KiLwAeCsHqJmBlAmFuXe@{DcByIZIYiBxBwAc@eCcAl@y@aEdCcBVJpHsEyAeE")
for latlng in latlngs:
print str(latlng[0]) + "," + str(latlng[1])


Hope you Python GMap coders out there will find this useful!

6 comments:

Juarez Bochi said...

Thank you! That was exactly what I needed.

See Wah Cheng said...

Great I am glad you have found this helpful :-)

Anonymous said...

Thank you for sharing. This was very helpful.

Ylan said...

Very helpful. Thanks!

Robert said...

Hi,

Can we assume you're licensing this as public domain (or rather CC0)?

Anonymous said...

Works Perfectly! thanks!