Created
November 29, 2024 12:06
-
-
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
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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