Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add auto detection of driver for .geojson, .geojsonl and .geojsons files #101

3 changes: 3 additions & 0 deletions pyogrio/raw.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,9 @@
".gpkg": "GPKG",
".shp": "ESRI Shapefile",
".json": "GeoJSON",
".geojson": "GeoJSON",
".geojsons": "GeoJSONSeq",
".geojsonl": "GeoJSONSeq",
".fgb": "FlatGeobuf",
}

Expand Down
2 changes: 1 addition & 1 deletion pyogrio/tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@


_data_dir = Path(__file__).parent.resolve() / "fixtures"
ALL_EXTS = [".shp", ".gpkg", ".json"]
ALL_EXTS = [".shp", ".gpkg", ".geojson", ".geojsonl"]


def pytest_report_header(config):
Expand Down
29 changes: 22 additions & 7 deletions pyogrio/tests/test_geopandas_io.py
Original file line number Diff line number Diff line change
Expand Up @@ -448,21 +448,36 @@ def test_write_dataframe(tmpdir, naturalearth_lowres, driver, ext):

@pytest.mark.filterwarnings("ignore:.*Layer .* does not have any features to read")
@pytest.mark.parametrize(
"driver,ext", [("ESRI Shapefile", "shp"), ("GeoJSON", "geojson"), ("GPKG", "gpkg")]
"ext", [ext for ext in ALL_EXTS if ext not in [".geojsonl", ".geojsons"]]
)
def test_write_empty_dataframe(tmpdir, driver, ext):
def test_write_empty_dataframe(tmp_path, ext):
expected = gp.GeoDataFrame(geometry=[], crs=4326)

filename = os.path.join(str(tmpdir), f"test.{ext}")
write_dataframe(expected, filename, driver=driver)

assert os.path.exists(filename)
filename = tmp_path / f"test{ext}"
write_dataframe(expected, filename)

assert filename.exists()
df = read_dataframe(filename)

assert_geodataframe_equal(df, expected)


@pytest.mark.parametrize("ext", [".geojsonl", ".geojsons"])
def test_write_read_empty_dataframe_unsupported(tmp_path, ext):
# Writing empty dataframe to .geojsons or .geojsonl results logically in a 0 byte
# file, but gdal isn't able to read those again at the time of writing.
# Issue logged here: https://github.com/geopandas/pyogrio/issues/94
expected = gp.GeoDataFrame(geometry=[], crs=4326)

filename = tmp_path / f"test{ext}"
write_dataframe(expected, filename)

assert filename.exists()
with pytest.raises(
Exception, match=".* not recognized as a supported file format."
):
_ = read_dataframe(filename)


def test_write_dataframe_gdalparams(tmp_path, naturalearth_lowres):
original_df = read_dataframe(naturalearth_lowres)

Expand Down
30 changes: 28 additions & 2 deletions pyogrio/tests/test_raw_io.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,9 @@
import pytest

from pyogrio import list_layers, list_drivers
from pyogrio.raw import read, write
from pyogrio.raw import DRIVERS, read, write
from pyogrio.errors import DataSourceError, DataLayerError, FeatureError
from pyogrio.tests.conftest import prepare_testfile


def test_read(naturalearth_lowres):
Expand All @@ -33,6 +34,32 @@ def test_read(naturalearth_lowres):
assert geometry[0][:6] == b"\x01\x06\x00\x00\x00\x03"


@pytest.mark.parametrize("ext", DRIVERS)
def test_read_autodetect_driver(tmp_path, naturalearth_lowres, ext):
# Test all supported autodetect drivers
testfile = prepare_testfile(naturalearth_lowres, dst_dir=tmp_path, ext=ext)

assert testfile.suffix == ext
assert testfile.exists()
meta, _, geometry, fields = read(testfile)

assert meta["crs"] == "EPSG:4326"
assert meta["geometry_type"] in ("Polygon", "Unknown")
assert meta["encoding"] == "UTF-8"
assert meta["fields"].shape == (5,)

assert meta["fields"].tolist() == [
"pop_est",
"continent",
"name",
"iso_a3",
"gdp_md_est",
]

assert len(fields) == 5
assert len(geometry) == len(fields[0])


def test_read_invalid_layer(naturalearth_lowres):
with pytest.raises(DataLayerError, match="Layer 'invalid' could not be opened"):
read(naturalearth_lowres, layer="invalid")
Expand Down Expand Up @@ -407,4 +434,3 @@ def test_read_data_types_numeric_with_null(test_gpkg_nulls):
assert field.dtype == "float32"
else:
assert field.dtype == "float64"