diff --git a/CHANGES.md b/CHANGES.md index 99c837ae..626f3eb2 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -2,6 +2,15 @@ ## 0.9.1 (yyyy-mm-dd) +### Packaging + +- For the conda-forge package, change the dependency from `libgdal` to + `libgdal-core`. This package is significantly smaller as it doesn't contain + some large GDAL plugins. Extra plugins can be installed as seperate conda + packages if needed: more info [here](https://gdal.org/download.html#conda). + This also leads to `pyproj` becoming an optional dependency; you will need + to install `pyproj` in order to support spatial reference systems (#452). + ### Bug fixes - Silence warning from `write_dataframe` with `GeoSeries.notna()` (#435). diff --git a/ci/envs/latest.yml b/ci/envs/latest.yml index 0643a67f..c75ab4b7 100644 --- a/ci/envs/latest.yml +++ b/ci/envs/latest.yml @@ -3,9 +3,8 @@ channels: - conda-forge dependencies: - numpy - - libgdal + - libgdal-core - pytest - shapely>=2 - geopandas-base - pyarrow - diff --git a/ci/envs/minimal.yml b/ci/envs/minimal.yml index 8cd6e83d..a20d2e39 100644 --- a/ci/envs/minimal.yml +++ b/ci/envs/minimal.yml @@ -3,5 +3,5 @@ channels: - conda-forge dependencies: - numpy - - libgdal + - libgdal-core - pytest diff --git a/ci/envs/nightly-deps.yml b/ci/envs/nightly-deps.yml index d6df4e94..2bca259d 100644 --- a/ci/envs/nightly-deps.yml +++ b/ci/envs/nightly-deps.yml @@ -2,7 +2,7 @@ name: test channels: - conda-forge dependencies: - - libgdal + - libgdal-core - pytest - geopandas-base - pip diff --git a/environment-dev.yml b/environment-dev.yml index e9992f65..1deb497c 100644 --- a/environment-dev.yml +++ b/environment-dev.yml @@ -2,14 +2,17 @@ name: pyogrio-dev channels: - conda-forge dependencies: + # Required - numpy + - libgdal-core + - shapely>=2 + # Optional - geopandas-base - - libgdal==3.8.3 + - pyproj - pyarrow - - shapely>=2 # Specific for dev - cython - pre-commit - pytest - - versioneer - ruff + - versioneer \ No newline at end of file diff --git a/pyogrio/_compat.py b/pyogrio/_compat.py index cd67247e..fc3df94d 100644 --- a/pyogrio/_compat.py +++ b/pyogrio/_compat.py @@ -8,6 +8,11 @@ except ImportError: pyarrow = None +try: + import pyproj +except ImportError: + pyproj = None + try: import shapely except ImportError: @@ -27,6 +32,7 @@ HAS_ARROW_API = __gdal_version__ >= (3, 6, 0) HAS_ARROW_WRITE_API = __gdal_version__ >= (3, 8, 0) HAS_PYARROW = pyarrow is not None +HAS_PYPROJ = pyproj is not None HAS_GEOPANDAS = geopandas is not None diff --git a/pyogrio/geopandas.py b/pyogrio/geopandas.py index b700d99c..cc50189a 100644 --- a/pyogrio/geopandas.py +++ b/pyogrio/geopandas.py @@ -447,7 +447,6 @@ def write_dataframe( from geopandas.array import to_wkb import pandas as pd - from pyproj.enums import WktVersion # if geopandas is available so is pyproj if not isinstance(df, pd.DataFrame): raise ValueError("'df' must be a DataFrame or GeoDataFrame") @@ -579,7 +578,7 @@ def write_dataframe( if epsg: crs = f"EPSG:{epsg}" # noqa: E231 else: - crs = geometry.crs.to_wkt(WktVersion.WKT1_GDAL) + crs = geometry.crs.to_wkt("WKT1_GDAL") if use_arrow: import pyarrow as pa diff --git a/pyogrio/tests/conftest.py b/pyogrio/tests/conftest.py index d562a4d1..85508464 100644 --- a/pyogrio/tests/conftest.py +++ b/pyogrio/tests/conftest.py @@ -14,6 +14,7 @@ HAS_ARROW_WRITE_API, HAS_GDAL_GEOS, HAS_PYARROW, + HAS_PYPROJ, HAS_SHAPELY, ) from pyogrio.raw import read, write @@ -54,6 +55,8 @@ def pytest_report_header(config): not HAS_ARROW_API or not HAS_PYARROW, reason="GDAL>=3.6 and pyarrow required" ) +requires_pyproj = pytest.mark.skipif(not HAS_PYPROJ, reason="pyproj required") + requires_arrow_write_api = pytest.mark.skipif( not HAS_ARROW_WRITE_API or not HAS_PYARROW, reason="GDAL>=3.8 required for Arrow write API", diff --git a/pyogrio/tests/test_geopandas_io.py b/pyogrio/tests/test_geopandas_io.py index 12146c3d..7786afb1 100644 --- a/pyogrio/tests/test_geopandas_io.py +++ b/pyogrio/tests/test_geopandas_io.py @@ -20,9 +20,10 @@ DRIVERS, requires_pyarrow_api, requires_arrow_write_api, + requires_pyproj, requires_gdal_geos, ) -from pyogrio._compat import PANDAS_GE_15, HAS_ARROW_WRITE_API +from pyogrio._compat import HAS_PYPROJ, PANDAS_GE_15, HAS_ARROW_WRITE_API try: import pandas as pd @@ -126,7 +127,8 @@ def test_read_csv_platform_encoding(tmp_path): def test_read_dataframe(naturalearth_lowres_all_ext): df = read_dataframe(naturalearth_lowres_all_ext) - assert df.crs == "EPSG:4326" + if HAS_PYPROJ: + assert df.crs == "EPSG:4326" assert len(df) == 177 assert df.columns.tolist() == [ "pop_est", @@ -1071,6 +1073,8 @@ def test_write_empty_geometry(tmp_path): # Check that no warning is raised with GeoSeries.notna() with warnings.catch_warnings(): warnings.simplefilter("error", UserWarning) + if not HAS_PYPROJ: + warnings.filterwarnings("ignore", message="'crs' was not provided.") write_dataframe(expected, filename) assert filename.exists() @@ -1460,6 +1464,7 @@ def test_write_dataframe_infer_geometry_with_nulls(tmp_path, geoms, ext, use_arr "ignore: You will likely lose important projection information" ) @pytest.mark.requires_arrow_write_api +@requires_pyproj def test_custom_crs_io(tmp_path, naturalearth_lowres_all_ext, use_arrow): df = read_dataframe(naturalearth_lowres_all_ext) # project Belgium to a custom Albers Equal Area projection diff --git a/pyogrio/tests/test_path.py b/pyogrio/tests/test_path.py index 3dde5363..5c61f05e 100644 --- a/pyogrio/tests/test_path.py +++ b/pyogrio/tests/test_path.py @@ -6,6 +6,7 @@ import pytest import pyogrio +from pyogrio._compat import HAS_PYPROJ import pyogrio.raw from pyogrio.util import vsi_path, get_vsi_path_or_buffer @@ -238,6 +239,9 @@ def test_detect_zip_path(tmp_path, naturalearth_lowres): path = tmp_path / "test.zip" with ZipFile(path, mode="w", compression=ZIP_DEFLATED, compresslevel=5) as out: for ext in ["dbf", "prj", "shp", "shx"]: + if not HAS_PYPROJ and ext == "prj": + continue + filename = f"test1.{ext}" out.write(tmp_path / filename, filename)