Skip to content

Instantly share code, notes, and snippets.

@joaofig
Created November 29, 2024 12:06
Show Gist options
  • Save joaofig/e76856da2fbc4b7eb2f197d5857d1ba0 to your computer and use it in GitHub Desktop.
Save joaofig/e76856da2fbc4b7eb2f197d5857d1ba0 to your computer and use it in GitHub Desktop.
This is a slightly adapted version of Valhalla's code to decode a polyline
def decode_polyline(encoded: str,
order: str = "lonlat") -> List[List]:
"""
Code drawn from https://valhalla.github.io/valhalla/decoding/
:param order: Coordinate order: 'lonlat' (default) or 'latlon'
:param encoded: String-encoded polyline
:return: Decoded polyline as a list of [lat, lon] coordinates
"""
inv = 1.0 / 1e6
decoded = []
previous = [0, 0]
i = 0
# for each byte
while i < len(encoded):
# for each coord (lat, lon)
ll = [0, 0]
for j in [0, 1]:
shift = 0
byte = 0x20
# keep decoding bytes until you have this coord
while byte >= 0x20:
byte = ord(encoded[i]) - 63
i += 1
ll[j] |= (byte & 0x1f) << shift
shift += 5
# get the final value adding the previous offset and remember it for the next
ll[j] = previous[j] + (~(ll[j] >> 1) if ll[j] & 1 else (ll[j] >> 1))
previous[j] = ll[j]
# scale by the precision and chop off long coords also flip the positions so
# its the far more standard lon,lat instead of lat,lon
if order == "lonlat":
decoded.append([float('%.6f' % (ll[1] * inv)), float('%.6f' % (ll[0] * inv))])
else:
decoded.append([float('%.6f' % (ll[0] * inv)), float('%.6f' % (ll[1] * inv))])
# hand back the list of coordinates
return decoded
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment