Skip to content

Commit

Permalink
feat: Add a from_geo_json to Transformer
Browse files Browse the repository at this point in the history
  • Loading branch information
gjclark committed Aug 27, 2024
1 parent c0f68b7 commit cac329c
Show file tree
Hide file tree
Showing 2 changed files with 138 additions and 1 deletion.
14 changes: 13 additions & 1 deletion geo_extensions/transformer.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
from typing import Iterable, List, Sequence, Tuple

from shapely import Geometry, wkt
from shapely.geometry import MultiPolygon, Polygon
from shapely.geometry import MultiPolygon, Polygon, shape

from geo_extensions.types import Transformation, TransformationResult

Expand All @@ -12,6 +12,18 @@ class Transformer:
def __init__(self, transformations: Sequence[Transformation]):
self.transformations = transformations

def from_geo_json(self, geo_json: dict) -> List[Polygon]:
"""Load and transform an object from a GeoJSON dict.
:returns: a list of transformed polygons
:raises: ShapelyError, Exception
"""

obj = shape(geo_json)
polygons = to_polygons(obj)

return self.transform(polygons)

def from_wkt(self, wkt_str: str) -> List[Polygon]:
"""Load and transform an object from a WKT string.
Expand Down
125 changes: 125 additions & 0 deletions tests/test_transformer.py
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,117 @@ def test_from_wkt_multipolygon(simplify_transformer):
]


def test_from_geo_json(simplify_transformer):
# Clockwise polygon remains clockwise
assert simplify_transformer.from_geo_json({
"type": "Polygon",
"coordinates": [
[
[50, 20],
[50, 21],
[51, 21],
[51, 20],
[50, 20],
],
],
}) == [
Polygon([
(50.0, 20.0),
(50.0, 21.0),
(51.0, 21.0),
(51.0, 20.0),
(50.0, 20.0),
]),
]
assert simplify_transformer.from_geo_json({
"type": "Polygon",
"coordinates": [
[
[1, 1],
[2, 1],
[1, 2],
[1, 1],
],
],
}) == [
Polygon([
(1, 1),
(2, 1),
(1, 2),
(1, 1),
]),
]
# Duplicate point is removed
assert simplify_transformer.from_geo_json({
"type": "Polygon",
"coordinates": [
[
[50.0, 20.0],
[50.0, 21.0],
[51.0, 21.0],
[51.0, 20.0],
[50.0, 20.0],
[50.0, 20.0],
],
],
}) == [
Polygon(
[
(50.0, 20.0),
(50.0, 21.0),
(51.0, 21.0),
(51.0, 20.0),
(50.0, 20.0),
],
),
]


def test_from_geo_json_multipolygon(simplify_transformer):
assert simplify_transformer.from_geo_json(
{
"type": "MultiPolygon",
"coordinates": [
[
[
[30, 20],
[45, 40],
[10, 40],
[30, 20],
],
],
[
[
[15, 5],
[40, 10],
[10, 20],
[5, 10],
[15, 5],
],
],
],
},
) == [
Polygon(
[
(30.0, 20.0),
(45.0, 40.0),
(10.0, 40.0),
(30.0, 20.0),
],
),
Polygon(
[
(15.0, 5.0),
(40.0, 10.0),
(10.0, 20.0),
(5.0, 10.0),
(15.0, 5.0),
],
),
]

Check failure on line 182 in tests/test_transformer.py

View workflow job for this annotation

GitHub Actions / flake8

continuation line missing indentation or outdented


def test_from_wkt_bad_points(simplify_transformer):
with pytest.raises(
Exception,
Expand All @@ -80,3 +191,17 @@ def test_from_wkt_bad_points(simplify_transformer):

with pytest.raises(ShapelyError):
simplify_transformer.from_wkt("")


def test_from_geo_json_bad_points(simplify_transformer):
with pytest.raises(
Exception,
match=r"WKT: 'POINT \(30 10\)' is not a Polygon or MultiPolygon",
):
simplify_transformer.from_geo_json({
"type": "Point",

Check failure on line 202 in tests/test_transformer.py

View workflow job for this annotation

GitHub Actions / flake8

continuation line missing indentation or outdented
"coordinates": [[30, 10]],

Check failure on line 203 in tests/test_transformer.py

View workflow job for this annotation

GitHub Actions / flake8

continuation line missing indentation or outdented
})

Check failure on line 204 in tests/test_transformer.py

View workflow job for this annotation

GitHub Actions / flake8

continuation line missing indentation or outdented

with pytest.raises(AttributeError):
simplify_transformer.from_geo_json({})

0 comments on commit cac329c

Please sign in to comment.