diff --git a/docs/history.rst b/docs/history.rst index 2dc362b..9c91204 100644 --- a/docs/history.rst +++ b/docs/history.rst @@ -3,6 +3,7 @@ History Latest ------- +- BUG: Update minimize dtype for int64 & int8 support (issue #139) 0.4.2 ------- diff --git a/geocube/rasterize.py b/geocube/rasterize.py index 62680f0..3f6601e 100644 --- a/geocube/rasterize.py +++ b/geocube/rasterize.py @@ -7,11 +7,17 @@ import numpy import odc.geo.geobox import pandas +import rasterio import rasterio.features from numpy.typing import NDArray +from packaging import version from rasterio.enums import MergeAlg from scipy.interpolate import Rbf, griddata +_INT8_SUPPORTED = version.parse(rasterio.__gdal_version__) >= version.parse( + "3.7.0" +) and version.parse(rasterio.__version__) >= version.parse("1.3.7") + def _is_numeric(data_values: NDArray) -> bool: """ @@ -44,12 +50,9 @@ def _minimize_dtype(dtype: numpy.dtype, fill: float) -> numpy.dtype: Attempt to convert to float32 if fill is NaN and dtype is integer. """ if numpy.issubdtype(dtype, numpy.integer): - if dtype.name == "int8": - # GDAL/rasterio doesn't support int8 + if not _INT8_SUPPORTED and dtype.name == "int8": + # GDAL<3.7/rasterio<1.3.7 doesn't support int8 dtype = numpy.dtype("int16") - if dtype.name == "int64": - # GDAL/rasterio doesn't support int64 - dtype = numpy.dtype("float64") if numpy.isnan(fill): dtype = ( numpy.dtype("float64") if dtype.itemsize > 2 else numpy.dtype("float32") # type: ignore diff --git a/setup.cfg b/setup.cfg index b63b71b..94507c3 100644 --- a/setup.cfg +++ b/setup.cfg @@ -37,7 +37,7 @@ install_requires = click>=6.0 geopandas>=0.7 odc_geo - rasterio + rasterio>=1.3 rioxarray>=0.4 scipy xarray>=0.17 diff --git a/test/integration/api/test_core_integration.py b/test/integration/api/test_core_integration.py index 23399f2..8cd4b41 100644 --- a/test/integration/api/test_core_integration.py +++ b/test/integration/api/test_core_integration.py @@ -15,6 +15,7 @@ from geocube.api.core import make_geocube from geocube.exceptions import VectorDataError from geocube.rasterize import ( + _INT8_SUPPORTED, rasterize_image, rasterize_points_griddata, rasterize_points_radial, @@ -101,7 +102,7 @@ def test_make_geocube__categorical(input_geodata, tmpdir): categorical_enums={"soil_type": ("sand", "silt", "clay")}, fill=-9999.0, ) - assert out_grid.soil_type.dtype.name == "int16" + assert out_grid.soil_type.dtype.name == "int8" if _INT8_SUPPORTED else "int16" # test writing to netCDF out_grid.to_netcdf( @@ -451,7 +452,7 @@ def test_make_geocube__group_by__categorical(input_geodata, tmpdir): fill=-9999.0, ) - assert out_grid.soil_type.dtype.name == "int16" + assert out_grid.soil_type.dtype.name == "int8" if _INT8_SUPPORTED else "int16" # test writing to netCDF out_grid.to_netcdf( tmpdir.mkdir("make_geocube_soil") / "soil_grid_group_categorical.nc" @@ -816,7 +817,7 @@ def test_make_geocube__custom_rasterize_function__filter_null( ("uint16", float("NaN"), "float32"), ("int32", 0, "int32"), ("int32", float("NaN"), "float64"), - ("int64", 0, "float64"), + ("int64", 0, "int64"), ("int64", float("NaN"), "float64"), ], )