Skip to content

Commit

Permalink
Refactor WKT parsing
Browse files Browse the repository at this point in the history
introduce split_wkt_components function for improved handling of geometries allowing for nested GeometryCollections #216
  • Loading branch information
cleder committed Dec 3, 2024
1 parent d535c7d commit 0dd8cca
Show file tree
Hide file tree
Showing 2 changed files with 22 additions and 12 deletions.
31 changes: 22 additions & 9 deletions pygeoif/factories.py
Original file line number Diff line number Diff line change
Expand Up @@ -56,9 +56,6 @@
),
flags=re.IGNORECASE,
)
gcre: Pattern[str] = re.compile(
r"POINT|LINESTRING|LINEARRING|POLYGON|MULTIPOINT|MULTILINESTRING|MULTIPOLYGON",
)
outer: Pattern[str] = re.compile(r"\((.+)\)")
inner: Pattern[str] = re.compile(r"\([^)]*\)")
mpre: Pattern[str] = re.compile(r"\(\((.+?)\)\)")
Expand Down Expand Up @@ -280,13 +277,29 @@ def _multipolygon_from_wkt_coordinates(coordinates: str) -> MultiPolygon:
return MultiPolygon(polygons)


def split_wkt_components(wkt: str) -> List[str]:
components = []
start = 0
open_count = 0

for i, char in enumerate(wkt):
if char == "(":
open_count += 1
elif char == ")":
open_count -= 1
elif char == "," and open_count == 0:
# Split only at commas outside parentheses
components.append(wkt[start:i].strip())
start = i + 1

# Add the final component
components.append(wkt[start:].strip())
return components


def _multigeometry_from_wkt_coordinates(coordinates: str) -> GeometryCollection:
gc_types = gcre.findall(coordinates)
gc_coords = gcre.split(coordinates)[1:]
geometries: List[Geometry] = []
for gc_type, gc_coord in zip(gc_types, gc_coords):
gc_wkt = gc_type + gc_coord[: gc_coord.rfind(")") + 1]
geometries.append(cast(Geometry, from_wkt(gc_wkt)))
components = split_wkt_components(coordinates)
geometries = (cast(Geometry, from_wkt(gc_wkt)) for gc_wkt in components)
return GeometryCollection(geometries)


Expand Down
3 changes: 0 additions & 3 deletions tests/test_geometrycollection.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
"""Test Baseclass."""

import pytest

from pygeoif import geometry
from pygeoif.factories import from_wkt

Expand Down Expand Up @@ -463,7 +461,6 @@ def test_multi_geometry_collection_wkt() -> None:
assert from_wkt(str(gc)) == gc


@pytest.mark.xfail(reason="WKT parsing for nested GeometryCollections not implemented.")
def test_nested_geometry_collections_wkt() -> None:
multipoint = geometry.MultiPoint([(0, 0), (1, 1), (1, 2), (2, 2)])
gc1 = geometry.GeometryCollection([geometry.Point(0, 0), multipoint])
Expand Down

0 comments on commit 0dd8cca

Please sign in to comment.