Skip to content

Commit 78b74b2

Browse files
authored
DOC/TST: document and test read_dataframe with on_invalid=fix (#532)
* document read_dataframe on_invalid=fix parameter value * Add test * skip for shapely < 2.1
1 parent 7aed64d commit 78b74b2

File tree

3 files changed

+22
-8
lines changed

3 files changed

+22
-8
lines changed

pyogrio/_compat.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,3 +47,4 @@
4747
HAS_GDAL_GEOS = __gdal_geos_version__ is not None
4848

4949
HAS_SHAPELY = shapely is not None and Version(shapely.__version__) >= Version("2.0.0")
50+
SHAPELY_GE_21 = shapely is not None and Version(shapely.__version__) >= Version("2.1.0")

pyogrio/geopandas.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -209,6 +209,9 @@ def read_dataframe(
209209
warning will be raised.
210210
- **ignore**: invalid WKB geometries will be returned as ``None``
211211
without a warning.
212+
- **fix**: an effort is made to fix invalid input geometries (currently
213+
just unclosed rings). If this is not possible, they are returned as
214+
``None`` without a warning. Requires GEOS >= 3.11 and shapely >= 2.1.
212215
213216
arrow_to_pandas_kwargs : dict, optional (default: None)
214217
When `use_arrow` is True, these kwargs will be passed to the `to_pandas`_

pyogrio/tests/test_geopandas_io.py

Lines changed: 18 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
HAS_ARROW_WRITE_API,
2323
HAS_PYPROJ,
2424
PANDAS_GE_15,
25+
SHAPELY_GE_21,
2526
)
2627
from pyogrio.errors import DataLayerError, DataSourceError, FeatureError, GeometryError
2728
from pyogrio.geopandas import PANDAS_GE_20, read_dataframe, write_dataframe
@@ -1803,23 +1804,29 @@ def test_write_geometry_z_types_auto(
18031804

18041805

18051806
@pytest.mark.parametrize(
1806-
"on_invalid, message",
1807+
"on_invalid, message, expected_wkt",
18071808
[
18081809
(
18091810
"warn",
18101811
"Invalid WKB: geometry is returned as None. IllegalArgumentException: "
1811-
"Invalid number of points in LinearRing found 2 - must be 0 or >=",
1812+
"Points of LinearRing do not form a closed linestring",
1813+
None,
18121814
),
1813-
("raise", "Invalid number of points in LinearRing found 2 - must be 0 or >="),
1814-
("ignore", None),
1815+
("raise", "Points of LinearRing do not form a closed linestring", None),
1816+
("ignore", None, None),
1817+
("fix", None, "POLYGON ((0 0, 0 1, 0 0))"),
18151818
],
18161819
)
1817-
def test_read_invalid_poly_ring(tmp_path, use_arrow, on_invalid, message):
1820+
@pytest.mark.filterwarnings("ignore:Non closed ring detected:RuntimeWarning")
1821+
def test_read_invalid_poly_ring(tmp_path, use_arrow, on_invalid, message, expected_wkt):
1822+
if on_invalid == "fix" and not SHAPELY_GE_21:
1823+
pytest.skip("on_invalid=fix not available for Shapely < 2.1")
1824+
18181825
if on_invalid == "raise":
18191826
handler = pytest.raises(shapely.errors.GEOSException, match=message)
18201827
elif on_invalid == "warn":
18211828
handler = pytest.warns(match=message)
1822-
elif on_invalid == "ignore":
1829+
elif on_invalid in ("fix", "ignore"):
18231830
handler = contextlib.nullcontext()
18241831
else:
18251832
raise ValueError(f"unknown value for on_invalid: {on_invalid}")
@@ -1833,7 +1840,7 @@ def test_read_invalid_poly_ring(tmp_path, use_arrow, on_invalid, message):
18331840
"properties": {},
18341841
"geometry": {
18351842
"type": "Polygon",
1836-
"coordinates": [ [ [0, 0], [0, 0] ] ]
1843+
"coordinates": [ [ [0, 0], [0, 1] ] ]
18371844
}
18381845
}
18391846
]
@@ -1849,7 +1856,10 @@ def test_read_invalid_poly_ring(tmp_path, use_arrow, on_invalid, message):
18491856
use_arrow=use_arrow,
18501857
on_invalid=on_invalid,
18511858
)
1852-
df.geometry.isnull().all()
1859+
if expected_wkt is None:
1860+
assert df.geometry.iloc[0] is None
1861+
else:
1862+
assert df.geometry.iloc[0].wkt == expected_wkt
18531863

18541864

18551865
def test_read_multisurface(multisurface_file, use_arrow):

0 commit comments

Comments
 (0)