Skip to content

Commit

Permalink
polygon from string
Browse files Browse the repository at this point in the history
  • Loading branch information
cleder committed Apr 3, 2023
1 parent f3b1c4d commit b099d96
Show file tree
Hide file tree
Showing 2 changed files with 90 additions and 0 deletions.
49 changes: 49 additions & 0 deletions fastkml/geometry.py
Original file line number Diff line number Diff line change
Expand Up @@ -980,6 +980,55 @@ def etree_element(
)
return element

@classmethod
def _get_polygon_kwargs(
cls,
*,
ns: str,
element: Element,
strict: bool,
) -> Dict[str, Any]:
outer_boundary = element.find(f"{ns}outerBoundaryIs")
if outer_boundary is None:
error = config.etree.tostring( # type: ignore[attr-defined]
element,
encoding="UTF-8",
).decode("UTF-8")
raise KMLParseError(f"Missing outerBoundaryIs in {error}")
outer_ring = outer_boundary.find(f"{ns}LinearRing")
if outer_ring is None:
error = config.etree.tostring( # type: ignore[attr-defined]
element,
encoding="UTF-8",
).decode("UTF-8")
raise KMLParseError(f"Missing LinearRing in {error}")
exterior = cls._get_geometry(ns=ns, element=outer_ring, strict=strict)
interiors = []
for inner_boundary in element.findall(f"{ns}innerBoundaryIs"):
inner_ring = inner_boundary.find(f"{ns}LinearRing")
if inner_ring is None:
error = config.etree.tostring( # type: ignore[attr-defined]
element,
encoding="UTF-8",
).decode("UTF-8")
raise KMLParseError(f"Missing LinearRing in {error}")
interiors.append(
cls._get_geometry(ns=ns, element=inner_ring, strict=strict)
)
return {"geometry": geo.Polygon.from_linear_rings(exterior, *interiors)}

@classmethod
def _get_kwargs(
cls,
*,
ns: str,
element: Element,
strict: bool,
) -> Dict[str, Any]:
kwargs = super()._get_kwargs(ns=ns, element=element, strict=strict)
kwargs.update(cls._get_polygon_kwargs(ns=ns, element=element, strict=strict))
return kwargs


class MultiGeometry(_Geometry):
...
41 changes: 41 additions & 0 deletions tests/geometries/polygon_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA

"""Test the geometry classes."""
from typing import cast

import pygeoif.geometry as geo

from fastkml.geometry import Polygon
Expand Down Expand Up @@ -60,6 +62,45 @@ def test_exterior_interior(self):
"0.900000,0.100000 0.100000,0.100000"
) in polygon.to_string()

def test_from_string_exterior_only(self):
"""Test exterior only."""
doc = """<kml:Polygon xmlns:kml="http://www.opengis.net/kml/2.2">
<kml:outerBoundaryIs>
<kml:LinearRing>
<kml:coordinates>0.000000,0.000000 1.000000,0.000000 1.000000,1.000000
0.000000,0.000000</kml:coordinates>
</kml:LinearRing>
</kml:outerBoundaryIs>
</kml:Polygon>"""

polygon2 = cast(Polygon, Polygon.class_from_string(doc))

assert polygon2.geometry == geo.Polygon([(0, 0), (1, 0), (1, 1), (0, 0)])

def test_from_string_exterior_interior(self):
doc = """<kml:Polygon xmlns:kml="http://www.opengis.net/kml/2.2">
<kml:outerBoundaryIs>
<kml:LinearRing>
<kml:coordinates>-1.000000,-1.000000 2.000000,-1.000000 2.000000,2.000000
-1.000000,-1.000000</kml:coordinates>
</kml:LinearRing>
</kml:outerBoundaryIs>
<kml:innerBoundaryIs>
<kml:LinearRing>
<kml:coordinates>0.000000,0.000000 1.000000,0.000000 1.000000,1.000000
0.000000,0.000000</kml:coordinates>
</kml:LinearRing>
</kml:innerBoundaryIs>
</kml:Polygon>
"""

polygon2 = cast(Polygon, Polygon.class_from_string(doc))

assert polygon2.geometry == geo.Polygon(
[(-1, -1), (2, -1), (2, 2), (-1, -1)],
[[(0, 0), (1, 0), (1, 1), (0, 0)]],
)


class TestLxml(Lxml, TestStdLibrary):
"""Test with lxml."""

0 comments on commit b099d96

Please sign in to comment.