Skip to content

Commit

Permalink
Merge branch 'aseelye-master'
Browse files Browse the repository at this point in the history
  • Loading branch information
frederickjansen committed Jun 26, 2019
2 parents 0764302 + 59495b8 commit 747c518
Show file tree
Hide file tree
Showing 5 changed files with 37 additions and 8 deletions.
4 changes: 4 additions & 0 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@ This should return ``_p~iF~ps|U_ulL~ugC_hgN~eq`@``.

You can set the required precision with the optional ``precision`` parameter. The default value is 5.

You can encode lon-lat tuples by setting ``geojson=True``.

Decoding
--------

Expand All @@ -44,3 +46,5 @@ To get a set of coordinates represented by a given encoded polyline string::
polyline.decode('u{~vFvyys@fS]')

This should return ``[(40.63179, -8.65708), (40.62855, -8.65693)]``.

You can decode into lon-lat tuples by setting ``geojson=True``.
10 changes: 6 additions & 4 deletions polyline/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,28 +3,30 @@
__version__ = '1.3.2'


def decode(expression, precision=5):
def decode(expression, precision=5, geojson=False):
"""
Decode a polyline string into a set of coordinates.
:param expression: Polyline string, e.g. 'u{~vFvyys@fS]'.
:param precision: Precision of the encoded coordinates. Google Maps uses 5, OpenStreetMap uses 6.
The default value is 5.
:param geojson: Set output of tuples to (lon, lat), as per https://tools.ietf.org/html/rfc7946#section-3.1.1
:return: List of coordinate tuples
"""
return PolylineCodec().decode(expression, precision)
return PolylineCodec().decode(expression, precision, geojson)


def encode(coordinates, precision=5):
def encode(coordinates, precision=5, geojson=False):
"""
Encode a set of coordinates in a polyline string.
:param coordinates: List of coordinate tuples, e.g. [(0, 0), (1, 0)].
:param precision: Precision of the coordinates to encode. Google Maps uses 5, OpenStreetMap uses 6.
The default value is 5.
:param geojson: Set to True in order to encode lon-lat tuples.
:return: The encoded polyline string.
"""
return PolylineCodec().encode(coordinates, precision)
return PolylineCodec().encode(coordinates, precision, geojson)


__all__ = ['decode', 'encode']
10 changes: 8 additions & 2 deletions polyline/codec.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ def _trans(self, value, index):

return ~(result >> 1) if comp else (result >> 1), index

def decode(self, expression, precision=5):
def decode(self, expression, precision=5, geojson=False):
coordinates, index, lat, lng, length, factor = [], 0, 0, 0, len(expression), float(10 ** precision)

while index < length:
Expand All @@ -46,9 +46,15 @@ def decode(self, expression, precision=5):
lng += lng_change
coordinates.append((lat / factor, lng / factor))

if geojson is True:
coordinates = [t[::-1] for t in coordinates]

return coordinates

def encode(self, coordinates, precision=5):
def encode(self, coordinates, precision=5, geojson=False):
if geojson is True:
coordinates = [t[::-1] for t in coordinates]

output, factor = six.StringIO(), int(10 ** precision)

self._write(output, coordinates[0][0], 0, factor)
Expand Down
3 changes: 2 additions & 1 deletion requirements/test.txt
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
flake8==2.2.4
nose==1.3.4
nose==1.3.7
coverage==4.5.3
18 changes: 17 additions & 1 deletion test/test_codec.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,14 @@ def test_decode_official_example(self):
(43.252, -126.453)
])

def test_decode_geojson(self):
d = polyline.decode('_p~iF~ps|U_ulLnnqC_mqNvxq`@', geojson=True)
self.assertEqual(d, [
(-120.200, 38.500),
(-120.950, 40.700),
(-126.453, 43.252)
])

def test_decode_official_example_precision(self):
d = polyline.decode('_izlhA~rlgdF_{geC~ywl@_kwzCn`{nI', 6)
self.assertEqual(d, [
Expand Down Expand Up @@ -111,6 +119,14 @@ def test_encode_official_example(self):
])
self.assertEqual(e, '_p~iF~ps|U_ulLnnqC_mqNvxq`@')

def test_encode_geojson(self):
e = polyline.encode([
(-120.200, 38.500),
(-120.950, 40.700),
(-126.453, 43.252)
], geojson=True)
self.assertEqual(e, '_p~iF~ps|U_ulLnnqC_mqNvxq`@')

def test_encode_official_example_precision(self):
e = polyline.encode([
(38.500, -120.200),
Expand Down Expand Up @@ -178,7 +194,7 @@ def generator():
else:
okays += 1

assert okays == waypoints
self.assertEqual(okays, waypoints)
print("encoded and decoded {0:.2f}% correctly for {1} waypoints @ {2} wp/sec".format(
100 * okays / float(waypoints),
waypoints,
Expand Down

0 comments on commit 747c518

Please sign in to comment.