diff --git a/pyproject.toml b/pyproject.toml index 23c76b4..723e53f 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -31,7 +31,8 @@ dependencies = [ "affine", "click >7.1, !=8.2.1", "cligj >=0.4", - "fiona", + "pyogrio >=0.12", + "geopandas >=0.12", "numpy >=1.9", "rasterio >=1.0", "simplejson", diff --git a/src/rasterstats/io.py b/src/rasterstats/io.py index 7ae8d87..b7f733f 100644 --- a/src/rasterstats/io.py +++ b/src/rasterstats/io.py @@ -29,21 +29,15 @@ "MultiPolygon", ] -try: - # Fiona 1.9+ - import fiona.model - - def fiona_generator(obj, layer=0): - with fiona.open(obj, "r", layer=layer) as src: - for feat in src: - yield fiona.model.to_dict(feat) - -except ModuleNotFoundError: - # Fiona <1.9 - def fiona_generator(obj, layer=0): - with fiona.open(obj, "r", layer=layer) as src: - yield from src +from pyogrio import read_dataframe +from pyogrio.errors import DataLayerError,DataSourceError +from json import loads +def pyogrio_generator(obj,layer=0): + collection=loads(read_dataframe(obj,layer).to_json()) + for feat in collection["features"]: + yield feat +fiona_generator=pyogrio_generator # for compatibility with old ocde def wrap_geom(geom): """Wraps a geometry dict in an GeoJSON Feature""" @@ -98,10 +92,11 @@ def read_features(obj, layer=0): with fiona.open(obj, "r", layer=layer) as src: assert len(src) > 0 - features_iter = fiona_generator(obj, layer) + features_iter = pyogrio_generator(obj, layer) except ( AssertionError, - DriverError, + DataSourceError, + DataLayerError, OSError, TypeError, UnicodeDecodeError, diff --git a/tests/test_io.py b/tests/test_io.py index 3199658..f7fa972 100644 --- a/tests/test_io.py +++ b/tests/test_io.py @@ -11,7 +11,7 @@ Raster, boundless_array, bounds_window, - fiona_generator, + pyogrio_generator, read_featurecollection, read_features, rowcol, @@ -28,7 +28,7 @@ eps = 1e-6 -target_features = [f for f in fiona_generator(polygons)] +target_features = [f for f in pyogrio_generator(polygons)] target_geoms = [shape(f["geometry"]) for f in target_features] @@ -82,63 +82,63 @@ def test_featurecollection(): def test_shapely(): - indata = [shape(f["geometry"]) for f in fiona_generator(polygons)] + indata = [shape(f["geometry"]) for f in pyogrio_generator(polygons)] _test_read_features(indata) _test_read_features_single(indata[0]) def test_wkt(): - indata = [shape(f["geometry"]).wkt for f in fiona_generator(polygons)] + indata = [shape(f["geometry"]).wkt for f in pyogrio_generator(polygons)] _test_read_features(indata) _test_read_features_single(indata[0]) def test_wkb(): - indata = [shape(f["geometry"]).wkb for f in fiona_generator(polygons)] + indata = [shape(f["geometry"]).wkb for f in pyogrio_generator(polygons)] _test_read_features(indata) _test_read_features_single(indata[0]) def test_mapping_features(): # list of Features - indata = [f for f in fiona_generator(polygons)] + indata = [f for f in pyogrio_generator(polygons)] _test_read_features(indata) def test_mapping_feature(): # list of Features - indata = [f for f in fiona_generator(polygons)] + indata = [f for f in pyogrio_generator(polygons)] _test_read_features(indata[0]) def test_mapping_geoms(): - indata = [f for f in fiona_generator(polygons)] + indata = [f for f in pyogrio_generator(polygons)] _test_read_features(indata[0]["geometry"]) def test_mapping_collection(): indata = {"type": "FeatureCollection"} - indata["features"] = [f for f in fiona_generator(polygons)] + indata["features"] = [f for f in pyogrio_generator(polygons)] _test_read_features(indata) def test_jsonstr(): # Feature str - indata = [f for f in fiona_generator(polygons)] + indata = [f for f in pyogrio_generator(polygons)] indata = json.dumps(indata[0]) _test_read_features(indata) def test_jsonstr_geom(): # geojson geom str - indata = [f for f in fiona_generator(polygons)] + indata = [f for f in pyogrio_generator(polygons)] indata = json.dumps(indata[0]["geometry"]) _test_read_features(indata) def test_jsonstr_collection(): indata = {"type": "FeatureCollection"} - indata["features"] = [f for f in fiona_generator(polygons)] + indata["features"] = [f for f in pyogrio_generator(polygons)] indata = json.dumps(indata) _test_read_features(indata) @@ -163,19 +163,19 @@ def __init__(self, f): def test_geo_interface(): - indata = [MockGeoInterface(f) for f in fiona_generator(polygons)] + indata = [MockGeoInterface(f) for f in pyogrio_generator(polygons)] _test_read_features(indata) def test_geo_interface_geom(): - indata = [MockGeoInterface(f["geometry"]) for f in fiona_generator(polygons)] + indata = [MockGeoInterface(f["geometry"]) for f in pyogrio_generator(polygons)] _test_read_features(indata) def test_geo_interface_collection(): # geointerface for featurecollection? indata = {"type": "FeatureCollection"} - indata["features"] = [f for f in fiona_generator(polygons)] + indata["features"] = [f for f in pyogrio_generator(polygons)] indata = MockGeoInterface(indata) _test_read_features(indata)