xarray-spatial 0.10.11__tar.gz → 0.10.12__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/.claude/sweep-accuracy-state.csv +1 -1
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/.claude/sweep-api-consistency-state.csv +2 -1
- xarray_spatial-0.10.12/.claude/sweep-documentation-state.csv +2 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/.claude/sweep-metadata-state.csv +2 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/.claude/sweep-performance-state.csv +1 -1
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/.claude/sweep-style-state.csv +1 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/.claude/sweep-test-coverage-state.csv +3 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/CHANGELOG.md +27 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/PKG-INFO +15 -6
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/README.md +14 -5
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xarray_spatial.egg-info/PKG-INFO +15 -6
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xarray_spatial.egg-info/SOURCES.txt +12 -0
- xarray_spatial-0.10.12/xarray_spatial.egg-info/scm_file_list.json +847 -0
- xarray_spatial-0.10.12/xarray_spatial.egg-info/scm_version.json +8 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/__init__.py +2 -0
- xarray_spatial-0.10.12/xrspatial/_template_data.py +311 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/_version.py +3 -3
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/accessor.py +392 -6
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/corridor.py +48 -5
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/geotiff/__init__.py +22 -8
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/geotiff/_attrs.py +6 -0
- xarray_spatial-0.10.12/xrspatial/geotiff/_pam.py +195 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/geotiff/_writers/eager.py +20 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/interpolate/_idw.py +10 -3
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/interpolate/_kriging.py +10 -3
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/interpolate/_spline.py +10 -2
- xarray_spatial-0.10.12/xrspatial/interpolate/_vector.py +122 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/kde.py +36 -2
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/perlin.py +38 -12
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/proximity.py +40 -7
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/rasterize.py +103 -8
- xarray_spatial-0.10.12/xrspatial/templates.py +288 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/terrain.py +34 -7
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/tests/test_accessor.py +157 -0
- xarray_spatial-0.10.12/xrspatial/tests/test_contract_validate.py +327 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/tests/test_corridor.py +339 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/tests/test_fire.py +122 -0
- xarray_spatial-0.10.12/xrspatial/tests/test_interpolate_vector.py +288 -0
- xarray_spatial-0.10.12/xrspatial/tests/test_perlin.py +338 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/tests/test_proximity.py +99 -0
- xarray_spatial-0.10.12/xrspatial/tests/test_rasterize_categorical_3482.py +273 -0
- xarray_spatial-0.10.12/xrspatial/tests/test_templates.py +297 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/tests/test_terrain.py +104 -0
- xarray_spatial-0.10.12/xrspatial/validate.py +539 -0
- xarray_spatial-0.10.11/xrspatial/tests/test_perlin.py +0 -120
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/.claude/sweep-security-state.csv +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/.codex/sweep-accuracy-state.csv +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/.codex/sweep-api-consistency-state.csv +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/.codex/sweep-metadata-state.csv +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/.codex/sweep-performance-state.csv +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/.codex/sweep-security-state.csv +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/.codex/sweep-style-state.csv +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/.codex/sweep-test-coverage-state.csv +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/.efficiency-audit-baseline.json +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/.efficiency-audit-baseline.prev.json +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/.gitattributes +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/.github/ISSUE_TEMPLATE/bug_report.md +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/.github/ISSUE_TEMPLATE/feature-proposal.md +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/.github/ISSUE_TEMPLATE/new-contributor.md +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/.github/labeler.yml +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/.github/pull_request_template.md +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/.github/workflows/benchmarks.yml +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/.github/workflows/copilot-review.yml +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/.github/workflows/docs.yml +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/.github/workflows/labeler.yml +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/.github/workflows/pypi-publish.yml +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/.github/workflows/test-cog-validator.yml +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/.github/workflows/test-geotiff-corpus.yml +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/.github/workflows/test.yml +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/.github/workflows/welcome-contributor.yml +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/.gitignore +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/.kilo/sweep-accuracy-state.csv +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/.kilo/sweep-api-consistency-state.csv +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/.kilo/sweep-metadata-state.csv +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/.kilo/sweep-performance-state.csv +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/.kilo/sweep-security-state.csv +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/.kilo/sweep-style-state.csv +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/.kilo/sweep-test-coverage-state.csv +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/.readthedocs.yml +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/AI_POLICY.md +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/CLAUDE.md +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/CODE_OF_CONDUCT.md +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/CONTRIBUTING.md +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/Citation-styles.md +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/LICENSE.txt +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/MANIFEST.in +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/RELEASE.md +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/codecov.yml +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/pyproject.toml +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/setup.cfg +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/setup.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xarray_spatial.egg-info/dependency_links.txt +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xarray_spatial.egg-info/entry_points.txt +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xarray_spatial.egg-info/not-zip-safe +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xarray_spatial.egg-info/requires.txt +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xarray_spatial.egg-info/top_level.txt +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/__main__.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/analytics.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/aspect.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/balanced_allocation.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/bilateral.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/bump.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/classify.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/contour.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/convolution.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/cost_distance.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/curvature.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/dasymetric.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/dataset_support.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/datasets/__init__.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/datasets/sentinel-2/blue_band.nc +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/datasets/sentinel-2/green_band.nc +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/datasets/sentinel-2/nir_band.nc +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/datasets/sentinel-2/red_band.nc +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/datasets/sentinel-2/swir1_band.nc +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/datasets/sentinel-2/swir2_band.nc +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/diagnostics.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/diffusion.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/edge_detection.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/emerging_hotspots.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/erosion.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/experimental/__init__.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/experimental/min_observable_height.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/fire.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/flood.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/focal.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/geodesic.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/geotiff/_backends/__init__.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/geotiff/_backends/_gpu_helpers.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/geotiff/_backends/dask.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/geotiff/_backends/gpu.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/geotiff/_backends/vrt.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/geotiff/_cog_http.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/geotiff/_compression.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/geotiff/_coords.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/geotiff/_crs.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/geotiff/_decode.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/geotiff/_dtypes.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/geotiff/_encode.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/geotiff/_errors.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/geotiff/_geotags.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/geotiff/_gpu_decode.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/geotiff/_header.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/geotiff/_layout.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/geotiff/_nodata.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/geotiff/_overview.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/geotiff/_overview_kernels.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/geotiff/_reader.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/geotiff/_runtime.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/geotiff/_safe_xml.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/geotiff/_sidecar.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/geotiff/_sources.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/geotiff/_validation.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/geotiff/_vrt.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/geotiff/_vrt_validation.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/geotiff/_write_layout.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/geotiff/_writer.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/geotiff/_writers/__init__.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/geotiff/_writers/gpu.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/geotiff/_writers/vrt.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/geotiff/_xarray_backend.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/geotiff/tests/__init__.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/geotiff/tests/_geotiff_fixtures.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/geotiff/tests/_helpers/__init__.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/geotiff/tests/_helpers/markers.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/geotiff/tests/_helpers/tiff_builders.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/geotiff/tests/_helpers/tiff_surgery.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/geotiff/tests/attrs/__init__.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/geotiff/tests/attrs/test_contract.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/geotiff/tests/bench_vs_rioxarray.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/geotiff/tests/conftest.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/geotiff/tests/golden_corpus/README.md +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/geotiff/tests/golden_corpus/__init__.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/geotiff/tests/golden_corpus/_marks.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/geotiff/tests/golden_corpus/_oracle.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/geotiff/tests/golden_corpus/fixtures/cog_internal_overview_uint16.tif +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/geotiff/tests/golden_corpus/fixtures/compression_deflate_predictor2_uint16.tif +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/geotiff/tests/golden_corpus/fixtures/compression_deflate_predictor3_float32.tif +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/geotiff/tests/golden_corpus/fixtures/compression_jpeg_uint8_ycbcr.tif +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/geotiff/tests/golden_corpus/fixtures/compression_lerc_float32.tif +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/geotiff/tests/golden_corpus/fixtures/compression_lzw_predictor2_int16.tif +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/geotiff/tests/golden_corpus/fixtures/compression_none_uint8.tif +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/geotiff/tests/golden_corpus/fixtures/crs_citation_only.tif +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/geotiff/tests/golden_corpus/fixtures/crs_epsg_3857.tif +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/geotiff/tests/golden_corpus/fixtures/crs_wkt_utm10n.tif +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/geotiff/tests/golden_corpus/fixtures/dtype_float32.tif +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/geotiff/tests/golden_corpus/fixtures/dtype_float64.tif +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/geotiff/tests/golden_corpus/fixtures/dtype_int16.tif +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/geotiff/tests/golden_corpus/fixtures/dtype_int32.tif +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/geotiff/tests/golden_corpus/fixtures/dtype_int8.tif +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/geotiff/tests/golden_corpus/fixtures/dtype_uint16.tif +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/geotiff/tests/golden_corpus/fixtures/dtype_uint32.tif +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/geotiff/tests/golden_corpus/fixtures/dtype_uint8.tif +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/geotiff/tests/golden_corpus/fixtures/extra_tags_uint16.tif +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/geotiff/tests/golden_corpus/fixtures/gdal_metadata_namespaced_uint16.tif +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/geotiff/tests/golden_corpus/fixtures/nodata_int_sentinel_uint16.tif +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/geotiff/tests/golden_corpus/fixtures/nodata_miniswhite_uint8.tif +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/geotiff/tests/golden_corpus/fixtures/nodata_nan_float32.tif +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/geotiff/tests/golden_corpus/fixtures/overview_external_ovr_uint16.tif +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/geotiff/tests/golden_corpus/fixtures/overview_external_ovr_uint16.tif.ovr +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/geotiff/tests/golden_corpus/fixtures/overview_internal_uint16.tif +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/geotiff/tests/golden_corpus/fixtures/planar_separate_uint8_rgb.tif +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/geotiff/tests/golden_corpus/fixtures/sparse_tiled_uint16.tif +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/geotiff/tests/golden_corpus/fixtures/stripped_be_uint16.tif +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/geotiff/tests/golden_corpus/fixtures/stripped_le_uint16.tif +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/geotiff/tests/golden_corpus/fixtures/tiled_be_uint16.tif +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/geotiff/tests/golden_corpus/fixtures/tiled_le_uint16.tif +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/geotiff/tests/golden_corpus/generate.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/geotiff/tests/golden_corpus/manifest.yaml +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/geotiff/tests/golden_corpus/test_compression.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/geotiff/tests/golden_corpus/test_corpus_determinism.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/geotiff/tests/golden_corpus/test_dask_gpu.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/geotiff/tests/golden_corpus/test_dask_numpy.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/geotiff/tests/golden_corpus/test_dtype_variants.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/geotiff/tests/golden_corpus/test_eager_numpy.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/geotiff/tests/golden_corpus/test_fsspec.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/geotiff/tests/golden_corpus/test_gpu.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/geotiff/tests/golden_corpus/test_http.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/geotiff/tests/golden_corpus/test_layout_endian.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/geotiff/tests/golden_corpus/test_manifest.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/geotiff/tests/golden_corpus/test_metadata_tags.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/geotiff/tests/golden_corpus/test_nodata_sentinels.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/geotiff/tests/golden_corpus/test_oracle.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/geotiff/tests/golden_corpus/test_overview_cog.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/geotiff/tests/golden_corpus/test_vrt.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/geotiff/tests/gpu/__init__.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/geotiff/tests/gpu/test_codec.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/geotiff/tests/gpu/test_kernels_and_kwargs.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/geotiff/tests/gpu/test_reader.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/geotiff/tests/gpu/test_writer.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/geotiff/tests/integration/__init__.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/geotiff/tests/integration/test_dask_pipeline.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/geotiff/tests/integration/test_gpu_pipeline.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/geotiff/tests/integration/test_http_sources.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/geotiff/tests/integration/test_sidecar.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/geotiff/tests/parity/__init__.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/geotiff/tests/parity/test_api_consolidation.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/geotiff/tests/parity/test_backend_matrix.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/geotiff/tests/parity/test_finalization.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/geotiff/tests/parity/test_pixel_equality.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/geotiff/tests/parity/test_reference.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/geotiff/tests/parity/test_signature_contract.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/geotiff/tests/read/__init__.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/geotiff/tests/read/test_basic.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/geotiff/tests/read/test_bbox_2555.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/geotiff/tests/read/test_bbox_vrt_2668.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/geotiff/tests/read/test_cloud_source_concurrency_3361.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/geotiff/tests/read/test_compression.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/geotiff/tests/read/test_coords.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/geotiff/tests/read/test_crs.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/geotiff/tests/read/test_degenerate_shapes.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/geotiff/tests/read/test_dtypes.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/geotiff/tests/read/test_endianness.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/geotiff/tests/read/test_georef.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/geotiff/tests/read/test_mask_and_scale_dtype_parity_3066.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/geotiff/tests/read/test_nodata.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/geotiff/tests/read/test_overview.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/geotiff/tests/read/test_rioxarray_compat_2961.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/geotiff/tests/read/test_scale_zero_3104.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/geotiff/tests/read/test_streaming.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/geotiff/tests/read/test_tiling.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/geotiff/tests/read/test_unpack_noop_doc_3263.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/geotiff/tests/release_gates/__init__.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/geotiff/tests/release_gates/test_features.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/geotiff/tests/release_gates/test_stable_features.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/geotiff/tests/test_edge_cases.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/geotiff/tests/test_fuzz_hypothesis.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/geotiff/tests/test_polish.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/geotiff/tests/test_round_trip.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/geotiff/tests/test_security.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/geotiff/tests/test_shutdown_cleanup_2486.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/geotiff/tests/test_stable_only_bbox_ordering_2869.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/geotiff/tests/test_stable_only_remote_2821.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/geotiff/tests/test_xarray_backend_3365.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/geotiff/tests/test_xarray_backend_coregister_3376.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/geotiff/tests/test_xarray_backend_coregister_target_3379.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/geotiff/tests/unit/__init__.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/geotiff/tests/unit/test_codec_roundtrip.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/geotiff/tests/unit/test_compression.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/geotiff/tests/unit/test_degenerate_pixel_size_3331.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/geotiff/tests/unit/test_exception_exports_3265.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/geotiff/tests/unit/test_geotags.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/geotiff/tests/unit/test_header.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/geotiff/tests/unit/test_ifd.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/geotiff/tests/unit/test_input_validation.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/geotiff/tests/unit/test_metadata.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/geotiff/tests/unit/test_photometric.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/geotiff/tests/unit/test_predictor.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/geotiff/tests/unit/test_safe_xml.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/geotiff/tests/unit/test_signatures.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/geotiff/tests/vrt/__init__.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/geotiff/tests/vrt/test_dtype_conversion.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/geotiff/tests/vrt/test_metadata.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/geotiff/tests/vrt/test_missing_sources.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/geotiff/tests/vrt/test_non_georef_placement_3116.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/geotiff/tests/vrt/test_parity.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/geotiff/tests/vrt/test_source_opt_ins_2672.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/geotiff/tests/vrt/test_validation.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/geotiff/tests/vrt/test_window.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/geotiff/tests/write/__init__.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/geotiff/tests/write/test_basic.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/geotiff/tests/write/test_bigtiff.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/geotiff/tests/write/test_cog.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/geotiff/tests/write/test_crs.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/geotiff/tests/write/test_nodata.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/geotiff/tests/write/test_overview.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/geotiff/tests/write/test_pack_3064.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/geotiff/tests/write/test_pack_64bit_sentinel_3264.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/geotiff/tests/write/test_pack_band_subset_3161.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/geotiff/tests/write/test_pack_float_width_3080.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/geotiff/tests/write/test_pack_lazy_nan_guard_3235.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/geotiff/tests/write/test_pack_nodata_kwarg_3168.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/geotiff/tests/write/test_pack_range_guard_3260.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/geotiff/tests/write/test_streaming.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/geotiff/tests/write/test_vrt_atomic.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/glcm.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/gpu_rtx/__init__.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/gpu_rtx/_memory.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/gpu_rtx/cuda_utils.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/gpu_rtx/hillshade.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/gpu_rtx/mesh_utils.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/gpu_rtx/viewshed.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/hillshade.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/hydro/__init__.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/hydro/_boundary_store.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/hydro/basin_d8.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/hydro/fill_d8.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/hydro/flow_accumulation_d8.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/hydro/flow_accumulation_dinf.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/hydro/flow_accumulation_mfd.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/hydro/flow_direction_d8.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/hydro/flow_direction_dinf.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/hydro/flow_direction_mfd.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/hydro/flow_length_d8.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/hydro/flow_length_dinf.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/hydro/flow_length_mfd.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/hydro/flow_path_d8.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/hydro/flow_path_dinf.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/hydro/flow_path_mfd.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/hydro/hand_d8.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/hydro/hand_dinf.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/hydro/hand_mfd.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/hydro/sink_d8.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/hydro/snap_pour_point_d8.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/hydro/stream_link_d8.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/hydro/stream_link_dinf.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/hydro/stream_link_mfd.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/hydro/stream_order_d8.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/hydro/stream_order_dinf.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/hydro/stream_order_mfd.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/hydro/tests/__init__.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/hydro/tests/conftest.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/hydro/tests/test_basin_d8.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/hydro/tests/test_fill_d8.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/hydro/tests/test_flow_accumulation_d8.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/hydro/tests/test_flow_accumulation_dinf.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/hydro/tests/test_flow_accumulation_mfd.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/hydro/tests/test_flow_direction_d8.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/hydro/tests/test_flow_direction_dinf.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/hydro/tests/test_flow_direction_mfd.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/hydro/tests/test_flow_length_d8.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/hydro/tests/test_flow_length_dinf.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/hydro/tests/test_flow_length_mfd.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/hydro/tests/test_flow_path_d8.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/hydro/tests/test_flow_path_dinf.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/hydro/tests/test_flow_path_mfd.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/hydro/tests/test_hand_d8.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/hydro/tests/test_hand_dinf.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/hydro/tests/test_hand_mfd.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/hydro/tests/test_sink_d8.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/hydro/tests/test_snap_pour_point_d8.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/hydro/tests/test_stream_link_d8.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/hydro/tests/test_stream_link_dinf.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/hydro/tests/test_stream_link_mfd.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/hydro/tests/test_stream_order_d8.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/hydro/tests/test_stream_order_dinf.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/hydro/tests/test_stream_order_mfd.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/hydro/tests/test_twi_d8.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/hydro/tests/test_validate_cellsize.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/hydro/tests/test_validate_mfd_companion_shape.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/hydro/tests/test_validate_mfd_fractions.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/hydro/tests/test_validate_scalar_params.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/hydro/tests/test_validate_secondary_args.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/hydro/tests/test_watershed_d8.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/hydro/tests/test_watershed_dinf.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/hydro/tests/test_watershed_mfd.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/hydro/twi_d8.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/hydro/watershed_d8.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/hydro/watershed_dinf.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/hydro/watershed_mfd.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/interpolate/__init__.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/interpolate/_validation.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/mahalanobis.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/mcda/__init__.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/mcda/combine.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/mcda/constrain.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/mcda/sensitivity.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/mcda/standardize.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/mcda/weights.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/morphology.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/multispectral.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/normalize.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/pathfinding.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/polygon_clip.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/polygonize.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/preview.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/reproject/__init__.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/reproject/_crs_utils.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/reproject/_grid.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/reproject/_interpolate.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/reproject/_itrf.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/reproject/_lite_crs.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/reproject/_merge.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/reproject/_projections.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/reproject/_projections_cuda.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/reproject/_transform.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/reproject/_vertical.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/reproject/grids/us_nga_egm96_15.tif +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/resample.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/sieve.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/sky_view_factor.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/slope.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/surface_distance.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/terrain_metrics.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/tests/__init__.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/tests/bench_reproject_vs_rioxarray.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/tests/conftest.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/tests/general_checks.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/tests/test_analytics.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/tests/test_aspect.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/tests/test_balanced_allocation.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/tests/test_bilateral.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/tests/test_bump.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/tests/test_classify.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/tests/test_contour.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/tests/test_convolution.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/tests/test_cost_distance.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/tests/test_curvature.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/tests/test_dask_cupy_gaps.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/tests/test_dask_laziness.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/tests/test_dask_task_names.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/tests/test_dasymetric.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/tests/test_dataset_support.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/tests/test_datasets.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/tests/test_diagnostics.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/tests/test_diffusion.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/tests/test_edge_detection.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/tests/test_emerging_hotspots.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/tests/test_erosion.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/tests/test_flood.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/tests/test_focal.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/tests/test_fused_overlap.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/tests/test_geodesic_aspect.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/tests/test_geodesic_slope.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/tests/test_glcm.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/tests/test_glcm_metric_order.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/tests/test_gpu_rtx_has_rtx.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/tests/test_gpu_rtx_memory.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/tests/test_gpu_rtx_mesh.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/tests/test_hillshade.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/tests/test_hypsometric_integral.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/tests/test_interpolation.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/tests/test_kde.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/tests/test_lite_crs.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/tests/test_mahalanobis.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/tests/test_mcda.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/tests/test_min_observable_height.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/tests/test_morphology.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/tests/test_morphology_derived.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/tests/test_multi_overlap.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/tests/test_multispectral.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/tests/test_normalize.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/tests/test_northness_eastness.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/tests/test_open_geotiff_coregister.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/tests/test_open_geotiff_resampling.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/tests/test_optional_shapely.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/tests/test_pathfinding.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/tests/test_polygon_clip.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/tests/test_polygonize.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/tests/test_polygonize_atol_rtol_backend_coverage_2026_05_27.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/tests/test_polygonize_coverage_2026_05_19.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/tests/test_polygonize_dask_row_batch_2608.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/tests/test_polygonize_issue_2172.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/tests/test_polygonize_issue_2583.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/tests/test_polygonize_issue_2606.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/tests/test_polygonize_issue_2666.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/tests/test_polygonize_issue_2677.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/tests/test_polygonize_issue_3292.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/tests/test_polygonize_issue_3303.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/tests/test_polygonize_mask_chunk_mismatch_3299.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/tests/test_polygonize_mask_dtype_coverage_2026_05_29.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/tests/test_preview.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/tests/test_rasterize.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/tests/test_rasterize_accuracy.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/tests/test_rasterize_all_touched_dask_grid_line_3384.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/tests/test_rasterize_all_touched_supercover_2169.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/tests/test_rasterize_alloc_3107.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/tests/test_rasterize_coverage_2026_05_17.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/tests/test_rasterize_coverage_2026_05_21.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/tests/test_rasterize_coverage_2026_05_27.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/tests/test_rasterize_coverage_2026_05_29.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/tests/test_rasterize_coverage_2026_06_09.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/tests/test_rasterize_crs_mismatch_3058.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/tests/test_rasterize_descending_x_2568.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/tests/test_rasterize_dtype_annot_3291.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/tests/test_rasterize_fill_dtype_3054.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/tests/test_rasterize_geom_crs_3087.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/tests/test_rasterize_gpu_alias_3089.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/tests/test_rasterize_gpu_callable_warn_3057.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/tests/test_rasterize_gpu_race_2167.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/tests/test_rasterize_int_precision_3056.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/tests/test_rasterize_linearring_3055.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/tests/test_rasterize_lines_all_touched_3102.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/tests/test_rasterize_merge_dedup_3304.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/tests/test_rasterize_mixed_type_ordered_merge_3296.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/tests/test_rasterize_nan_int_fill_2504.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/tests/test_rasterize_nan_propagation_2255.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/tests/test_rasterize_nonfinite_burn_3085.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/tests/test_rasterize_nonfinite_burn_3088.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/tests/test_rasterize_nonfinite_coords_3295.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/tests/test_rasterize_partial_dims_2569.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/tests/test_rasterize_props_hoist_2506.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/tests/test_rasterize_resolution_exact_2573.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/tests/test_rasterize_resolution_validation_2576.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/tests/test_rasterize_signature_annot_2250.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/tests/test_rasterize_signed_step_2566.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/tests/test_rasterize_tile_props_slice_2020.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/tests/test_rechunk_no_shuffle.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/tests/test_reproject.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/tests/test_reproject_coverage_2026_05_27.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/tests/test_reproject_cupy_gate_2564.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/tests/test_reproject_cupy_promotion_3281.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/tests/test_reproject_inverse_kernels_3274.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/tests/test_reproject_itrf_scale_3276.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/tests/test_reproject_parallel_kernels_3141.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/tests/test_reproject_pyproj_warning_3242.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/tests/test_reproject_sphere_ellipsoid_guard_3275.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/tests/test_reproject_streaming_3101.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/tests/test_resample.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/tests/test_resample_coverage_2026_05_27.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/tests/test_resample_cupy_agg_fallback_2615.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/tests/test_resample_input_validation_2574.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/tests/test_resample_irregular_coords_2663.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/tests/test_resample_nodata_dask_parity_3073.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/tests/test_resample_signature_annot_2544.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/tests/test_sieve.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/tests/test_sieve_gdal_parity.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/tests/test_sky_view_factor.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/tests/test_slope.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/tests/test_surface_distance.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/tests/test_sweep_state_csv_merge_2754.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/tests/test_terrain_metrics.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/tests/test_utils.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/tests/test_validation.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/tests/test_viewshed.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/tests/test_visibility.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/tests/test_zonal.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/tests/test_zonal_backend_coverage_2026_05_27.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/utils.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/viewshed.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/visibility.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/worley.py +0 -0
- {xarray_spatial-0.10.11 → xarray_spatial-0.10.12}/xrspatial/zonal.py +0 -0
|
@@ -27,7 +27,7 @@ normalize,2026-05-01,,,,rescale and standardize across all 4 backends. NaN/inf f
|
|
|
27
27
|
perlin,2026-04-10T12:00:00Z,,,,Improved Perlin noise implementation correct. Fade/gradient functions verified. Backend-consistent. Continuous at cell boundaries.
|
|
28
28
|
polygon_clip,2026-06-10,3186,HIGH,5,"Cat5 backend inconsistency: dask+cupy clip_polygon rasterizes the mask with a uniform chunk size from the raster's first chunk, then feeds raster+mask to da.map_blocks (positional block pairing). Non-uniform raster chunks gave the mask a different block layout -> IndexError/ValueError (or silent mis-stamp). Repro (8,6) rechunk ((3,5),(6,)) on dask+cupy raised ValueError Shapes do not align; dask+numpy was fine via xarray.where rechunk. Fix #3186/PR: rechunk cond to raster.data.chunks[-2:] before map_blocks; added non-uniform regression tests for dask+numpy and dask+cupy. use_cuda->gpu migration in that branch was already landed by #3089/#3122. CUDA available; cupy+dask+cupy verified, 25 tests pass. Cats 1-4 clean: numpy path uses raster.where, cupy path operates on raw arrays, NaN inputs preserved, no neighborhood ops/curvature. Prior fix #1197/#1200 (crop+all_touched) merged and unrelated."
|
|
29
29
|
polygonize,2026-05-29,2606,HIGH,5,"Cat 5 HIGH: dask connectivity=8 cross-chunk merge filled diagonal notch where same-value regions meet only at a corner across a chunk boundary; total area exceeded raster. Hole ring was dropped because containment tested hole[0] (on exterior at pinch). Fixed via _ring_interior_point in PR for #2606. numpy, dask+numpy, dask+cupy area parity now holds; 4-conn was already correct. cupy + dask+cupy paths validated on GPU host. Other cats clean: NaN masked on numpy/cupy float paths (tested), _is_close handles +/-inf via exact-equality short-circuit, atol/rtol/simplify_tolerance reject NaN/inf, integer GPU CCL matches numpy."
|
|
30
|
-
proximity,2026-06-
|
|
30
|
+
proximity,2026-06-22,3442,MEDIUM,5,"Cat5 backend divergence: EUCLIDEAN proximity/allocation/direction on numpy and dask+numpy use cKDTree, which dropped a target sitting exactly at max_distance to NaN (clearest at max_distance=0: a target pixel is distance 0 from itself), while cupy/dask+cupy brute-force kept it (0.0 / target value / 0). Root cause: cKDTree squares its exclusive distance_upper_bound for p=2, and the old np.nextafter(0,inf) widen underflows when squared, collapsing the bound back to max_distance; _kdtree_query_lowest_index passed the raw exclusive bound with no widen at all. Fix #3442/PR #3443: route all 3 cKDTree call sites through one _inclusive_upper_bound helper (relative eps + absolute floor, robust for p=1 and p=2). MANHATTAN (p=1) was unaffected. Verified all 4 backends agree; 543 proximity tests pass incl. 25 new cross-backend regression cases. CUDA available; cupy + dask+cupy executed. Cats 1-4 clean: float32/float64 boundary already handled (#3389), antimeridian halo (#3108), irregular-coord halo (#2908), non-finite target_values rejected (#2868), non-monotonic coords rejected (#2875), tie-break row-major across backends (#3090/#2881)."
|
|
31
31
|
rasterize,2026-06-18,3384,HIGH,1;5,dask all_touched polygon-boundary supercover walk re-extracted per tile in tile-local float pixel coords; floor() tie on an on-grid boundary segment diverged from eager (Cat1 precision -> Cat5 backend split). Fixed by extracting boundary float segments in the global grid frame and shifting by integer tile offset (#3384). Verified numpy/cupy/dask+numpy/dask+cupy.
|
|
32
32
|
reproject,2026-06-12,3274,HIGH,1;4,"3 confirmed bugs, all kernel-vs-PROJ parity: #3274 HIGH LAEA inverse spurious /rq (2.6 km err for 3035) + _authalic_apa inverse series wrong (4.8 m in AEA/CEA inverses; PROJ 3-term = 1.6 mm), CPU+CUDA kernels both; #3275 HIGH _is_wgs84_compatible_ellipsoid passes R-defined spheres (MODIS sinusoidal 18.9 km err) and _aea_params/_cea_params lack the guard entirely (23.8 km on spherical aea/cea); #3276 MEDIUM itrf helmert scale 1e-9 but PROJ +s is ppm (1e-6), ~23 mm err. Verified clean: merc/emerc/UTM/tmerc/LCC/polar stere (incl lat_ts akm1) forward+inverse <=1e-5 m vs pyproj; resampling kernels NaN handling and GDAL renorm match across numpy/cupy/dask (CUDA run, gpu-vs-cpu 1.3e-7); dask footprint chunk-skip bbox is a superset in all probed cases (no holes). LOW (documented only): _source_footprint_in_target probe array typo uses x-midpoint mx as a latitude in last 3 ys entries (bbox superset, correctness unaffected)."
|
|
33
33
|
resample,2026-05-29,2610,HIGH,3;5,"dask interp (nearest/bilinear) overlap depth=1 too small on downsample; block-centered source coord landed past chunk, map_coordinates clamped to edge -> wrong seam rows. Fixed PR #2627 via per-axis _downsample_radius. cupy+dask+cupy verified."
|
|
@@ -7,6 +7,7 @@ interpolate,2026-06-12,3285,MEDIUM,2,"Sweep 2026-06-12 (deep-sweep-api-consisten
|
|
|
7
7
|
mcda,2026-06-10,3148,HIGH,1;2;3;5,"Sweep 2026-06-10 (deep-sweep-api-consistency-mcda-2026-06-10). Fixed in this branch (#3148): (HIGH Cat 1) owa() named its criterion-weight dict criterion_weights while wlc/wpm/sensitivity use weights (same semantics, same _validate_weights); renamed to weights with keyword-only criterion_weights deprecation shim (DeprecationWarning; both names -> TypeError; positional callers untouched). (MEDIUM Cat 2) boolean_overlay annotated criteria as dict-only while every sibling combiner takes xr.Dataset; Dataset already worked via the Mapping interface -- now annotated/documented as xr.Dataset | dict. (MEDIUM Cat 3) ahp_weights docstring Raises claimed ValueError on incomplete comparisons but code warns (UserWarning) and defaults missing pairs to 1 -- docstring now documents Warns behaviour. (MEDIUM Cat 5) ConsistencyResult returned by public ahp_weights but absent from xrspatial/mcda __all__ and docs/source/reference/mcda.rst -- exported and documented. Documented, NOT fixed here: (MEDIUM Cat 2, deferred to parallel sweep-metadata sibling to avoid duplicate PR) constrain() drops attrs via xr.where while the other nine public functions preserve them. (LOW Cat 2) ahp_weights returns (weights, ConsistencyResult) tuple vs rank_weights bare dict -- intentional, documented in both docstrings, no fix. (LOW Cat 4) name=None inherit-input-name (standardize/constrain) vs literal-name defaults (combiners) -- defensible split, document only. Pre-existing backend bugs surfaced by the mandated cupy smoke (accuracy/test-coverage lane, recorded in #3148 body): owa fails on cupy (numpy order-weights array mixed into cupy multiply, combine.py ~336-340) and on ANY dask backend at graph construction (da.sort does not exist, combine.py:356, despite the owa MemoryError message recommending dask); sensitivity(method=monte_carlo) fails on cupy (template.values implicit-conversion guard). constrain on cupy blocked by the known library-wide cupy 13.6 + xarray xr.where astype incompat (dependency-pin issue), not mcda-specific. cuda-validated: CUDA_AVAILABLE=True; all 10 public functions smoke-tested on cupy DataArrays; owa weights=/criterion_weights= shim verified on numpy AND cupy entry points (cupy execution stops at the pre-existing mixed-array bug, signature acceptance confirmed)."
|
|
8
8
|
morphology,2026-06-20,3399,MEDIUM,5,"Sweep 2026-06-20 (deep-sweep-api-consistency-morphology-2026-06-20). 1 MEDIUM Cat 5 finding filed as #3399, fixed in this branch (PR #3409). Cat 5 accessor-parity gap: all 7 public morphology functions are exported in xrspatial/__init__.py, documented, and tested, but the .xrs accessor exposed only morph_erode/dilate/opening/closing on both XrsSpatialDataArrayAccessor and XrsSpatialDatasetAccessor; morph_gradient/white_tophat/black_tophat were missing (da.xrs.morph_gradient -> AttributeError while da.xrs.morph_erode works). Root cause: base 4 ops landed #949 + accessors #1042; derived 3 ops landed later #1026 and the accessor was never updated. Fix adds the 3 forwarding methods to both accessor classes (mechanical, matches existing pattern) plus accessor tests (none existed for morph before) and guards all 7 method names in the expected-methods checks. Clean elsewhere: Cat 1 no in-module naming drift -- all 7 publics share the exact signature (agg, kernel=None, boundary='nan', name='<op>'), verified programmatically; matches kernel-op siblings convolution_2d/focal.apply/hotspots which also use agg/kernel/boundary/name. Cat 2 no return drift (all 7 return xr.DataArray with coords/dims/attrs preserved via _dispatch / @supports_dataset). Cat 3 docstring/signature parity exact on all 7 (every param documented, Returns sections all DataArray). Cat 4 no default drift (kernel=None->3x3 ones, boundary='nan' uniform across all 7). Cross-cutting, notes only per template: convolution_2d orders name before boundary while morphology orders boundary before name (both keyword-defaulted, cosmetic); focal.apply/hotspots accept a keyword-only raster= alias for agg but that alias is focal-only (not a library convention) so morphology lacking it is not drift; library-wide first-arg agg vs raster drift spans 20+ modules, out of per-module scope. cuda-validated: CUDA_AVAILABLE=True on this host; all 7 publics smoke-tested with identical kwargs on numpy AND cupy DataArrays (shape parity, no signature drift between numpy/cupy entry points). PR reviewed (COMMENTED), no findings; branch merged with origin/main (clean), left BLOCKED on REVIEW_REQUIRED for user merge."
|
|
9
9
|
multispectral,2026-06-20,3433,MEDIUM,3,"Sweep 2026-06-20 (deep-sweep-api-consistency-multispectral). 18 public funcs, all single 2D DataArray returns except true_color (3D composite, inherently different). (#3433 MEDIUM Cat 3) nbr() docstring documented swir_agg but signature param is swir2_agg; copying the name from docs raises TypeError. Docs-only rename to swir2_agg + guard test test_docstring_params_match_signature over the 17 index funcs. No deprecation needed. LOW, documented not fixed: (Cat 5) gci/nbr2/ndmi/true_color/ebbi are NOT re-exported in xrspatial/__init__.py while 13 module siblings are; not an orphan API since the canonical documented path is xrspatial.multispectral.X (all 18 in multispectral.rst) and tests import from the submodule -- convenience-surface gap only. (Cat 3 LOW) only savi types name: str; true_color lacks band type hints and uses r/g/b (conventional for an RGB composite). Cross-module note (not filed per template): multispectral has no -> xr.DataArray return annotations while sibling fire.py annotates all 7 -- library-wide convention drift. No Cat 1 in-module (all band inputs are <band>_agg), no Cat 2 (return shapes consistent), no Cat 4 (no mutable defaults; soil_factor=1.0 consistent evi/savi). CUDA available: numpy+cupy smoke-tested, signatures parity-clean, full suite 171 passed."
|
|
10
|
+
perlin,2026-06-23,3465,MEDIUM,3,"Sweep 2026-06-23 (deep-sweep-api-consistency-perlin-2026-06-23). 1 MEDIUM Cat 3 finding filed as #3465, fixed in PR #3468. perlin() signature has name: str = 'perlin' (perlin.py:288) but the docstring Parameters section documented only agg/freq/seed, omitting name; sibling generate_terrain() documents its identical name param (terrain.py:607). Fix adds 'name : str, default=""perlin"" / Name for the output DataArray.' matching the terrain style. Pure docstring fix, no signature/behavior change, no deprecation shim needed. Tests: test_perlin_name_param (default+custom name honored), test_perlin_docstring_documents_name (regression). 14/14 test_perlin.py pass incl GPU paths. No HIGH/CRITICAL. Cat 1 clean: agg/seed/name consistent with generate_terrain. Cat 2 clean: all generators return xr.DataArray. Cat 4: seed default 5 (perlin) vs 10 (terrain) is a per-generator domain default, not surprise drift. Cat 5 clean: perlin in __init__.py. cuda-validated: CUDA_AVAILABLE=True on this host, numpy and cupy entry points both accept/propagate name. Cross-cutting, notes only: bump() exposes no name param while perlin/generate_terrain both do -- adding name to bump is a separate bump-module change, out of per-module scope."
|
|
10
11
|
polygonize,2026-06-12,3306;3307,MEDIUM,1;3,"Re-sweep 2026-06-12 (deep-sweep-api-consistency-polygonize-2026-06-12); prior pass 2026-05-19 (#2148). 2 MEDIUM findings filed and fixed on branches -01/-02 off this one. (#3306, MEDIUM Cat 3, branch -01) column_name docstring says 'Only used if return_type is geopandas or spatialpandas' but _to_geojson also consumes it as the per-feature property key (verified: properties={'myval': 1}); docs-only fix + test pinning geojson property naming. (#3307, MEDIUM sibling-behavior drift, branch -02) return_type is the only polygonize parameter validated AFTER the computation: invalid value runs the full backend (spy-verified 1 invocation before raise) while sibling contours() validates up front and lists allowed values; fix hoists the check into the top validation block with an allowed-values message (existing test matches on prefix, unaffected). Re-confirmed prior dispositions, still documented-only per cross-module rule: (HIGH Cat 1 cross-module) connectivity (polygonize, matches GDAL/rasterio/skimage) vs neighborhood (sieve.py, zonal.regions) for the identical 4|8 rook/queen concept -- rename shim belongs in sieve/zonal, out of polygonize scope; (LOW Cat 1 cross-cutting) raster (polygonize/sieve/clip_polygon) vs agg (contours/terrain family) first-arg drift, library-wide, not filed per-module. No new Cat 2 (return_type dispatch shapes match docstring Returns section exactly); no Cat 4 (atol/rtol mirror numpy.isclose, connectivity=4 == sieve neighborhood=4); Cat 5 LOW documented-only: module has no __all__ and the non-underscore internals generated_jit + Turn leak via import-star; polygonize re-exported in __init__.py and accessor, no orphan API. Docstring/signature parity otherwise exact (all 10 params documented, all annotated). Open polygonize issues #3292/#3293 checked -- no overlap with these findings. cuda-validated: CUDA_AVAILABLE=True on this host; polygonize smoke-tested with identical full kwargs on numpy, cupy (int + float atol/rtol=0), and dask+cupy; no backend signature drift."
|
|
11
12
|
proximity,2026-06-09,3090;3091,HIGH,2;3,"Sweep 2026-06-09 (deep-sweep-api-consistency-proximity-2026-06-09). 1 HIGH Cat 2 finding (#3090): dask+numpy (and unbounded dask+cupy, which converts to it) KDTree path violates the documented lowest-flat-index tie-break in allocation()/direction() whenever the raster has >1 chunk column. _collect_region_targets concatenates targets chunk-major (iy outer, ix inner) so the tree's target order is not global row-major; _kdtree_query_lowest_index then ties to the wrong target. Existing tie-break tests put both targets in the same raster row where chunk order coincides with row-major, so they pass. Repro: 5x5, targets 2@(1,3) and 3@(2,2), chunks (5,3), pixel (2,3) tied at d=1 -> numpy gives 2, dask gives 3. Bounded map_overlap paths are fine (local row-major order is offset-invariant). 1 MEDIUM Cat 3 finding (#3091): all 3 public docstrings claim numpy + dask+numpy support only while cupy/dask+cupy backends exist, are dispatched, and are tested (the tie-break paragraphs in the same docstrings name all 4 backends); direction() opens with a stray copy-pasted slope line ('downward slope direction') plus a doubled 'the the'; allocation example output reads as float64 but the function returns float32; stale '# convert to have same type as of input @raster' comment. Within-module Cat 1/4/5 clean: proximity/allocation/direction share an identical signature (raster, x='x', y='y', target_values=None, max_distance=np.inf, distance_metric='EUCLIDEAN'); consistent with surface_distance siblings (raster/x/y/target_values/max_distance); all 6 public symbols (incl. euclidean/manhattan/great_circle_distance) re-exported in __init__.py, no orphan API. Cross-cutting, documented not filed: sibling distance modules (surface_distance, cost_distance, balanced_allocation) use mutable default target_values: list = [] while proximity uses the None sentinel - the mutable-default fix belongs to those modules; proximity's target_values: list = None hint would be more precise as Optional[list] (LOW, matches library style). cuda-validated: CUDA_AVAILABLE=True on this host; proximity/allocation/direction smoke-tested with identical kwargs on numpy, cupy, dask+numpy, dask+cupy (proximity parity passed; allocation/direction parity failure is finding #3090)."
|
|
12
13
|
rasterize,2026-06-09,3089,HIGH,1,"Sweep 2026-06-09 (deep-sweep-api-consistency-rasterize-2026-06-09). 1 HIGH Cat 1 fixed in this branch (#3089): rasterize(use_cuda=) vs open_geotiff(gpu=) named the identical GPU-backend opt-in differently; these are the only two public entry points with an explicit GPU boolean (no input array to dispatch on; both pair it with chunks= for dask) and both names were live in the public API at once. Fix renames the positional param to gpu (same slot, positional callers unaffected) and appends use_cuda=None as a deprecated alias: DeprecationWarning on use, TypeError when combined with gpu=True. Docstring, GPU merge warning text, CuPy ImportError text, and polygon_clip.py's internal dask+cupy caller updated (guarded so a legacy use_cuda in rasterize_kw does not collide with the new default); all rasterize test call sites migrated to gpu=; regression tests in test_rasterize_gpu_alias_3089.py pin slot position, warning, TypeError, backend parity, and the warning-free clip_polygon path. Re-inspection after the 2026-05-21 pass (#2250); prior cross-module notes (clip_polygon nodata vs fill, name default drift, polygonize column_name vs column) still documented-only. Docstring/signature parity verified programmatically (17/17 params, order matches). New params since last pass (check_crs, max_pixels) consistent with geotiff naming (max_pixels matches geotiff's). No Cat 2/4/5 findings. LOW noted, not fixed (other module's docs): docs/source/user_guide/focal.ipynb claims convolve_2d takes use_cuda, which it does not. cuda-validated: CUDA_AVAILABLE=True; numpy/cupy/dask+numpy/dask+cupy smoke-tested with identical kwargs, values equal."
|
|
@@ -14,4 +15,4 @@ reproject,2026-06-09,3095;3097,HIGH,1;2;3,"Sweep 2026-06-09 (deep-sweep-api-cons
|
|
|
14
15
|
resample,2026-05-27,2544,MEDIUM,3,"Sweep 2026-05-27 (deep-sweep-api-consistency-resample-2026-05-27). 1 MEDIUM Cat 3 finding fixed in this branch (#2544): resample() was the only public symbol in xrspatial.resample without type annotations on any parameter or return; siblings slope/aspect/hillshade/curvature all annotate `agg: xr.DataArray` and `-> xr.DataArray`. Fix adds annotations matching the docstring (agg: xr.DataArray; scale_factor / target_resolution: float | tuple[float, float] | None; method: str; nodata: float | None; name: str) and a `-> xr.DataArray` return type, plus a docstring note that the @supports_dataset decorator accepts Dataset too. Regression test test_resample_signature_annot_2544.py pins every param and the return annotation. Other findings documented but not filed per template: (MEDIUM Cat 1 cross-module) `method` (resample) vs `resampling` (reproject/merge) -- same conceptual parameter, different name, cross-cutting rename, needs design issue. (LOW Cat 1 cross-cutting) first-arg `agg` (resample/slope/aspect/...) vs `raster` (reproject/rasterize/polygonize/sieve) -- library-wide drift, not per-module. (LOW Cat 5) ALL_METHODS imported by tests but not in __all__ (module has no __all__); borderline orphan but used for test parametrisation only. No Cat 2 (returns xr.DataArray as documented). No Cat 4 mutable defaults. resample is exported in xrspatial/__init__.py. cuda-validated: cupy backend smoke-tested with nearest, bilinear, and average on host with CUDA_AVAILABLE=True."
|
|
15
16
|
slope,2026-05-29,2681,MEDIUM,3,"Sweep 2026-05-29 (deep-sweep-api-consistency-slope-2026-05-29). 1 MEDIUM Cat 3 finding fixed in this branch (#2681, PR #2687): slope() annotated name as `str` while every terrain-family sibling (aspect/northness/eastness in aspect.py, curvature in curvature.py) uses Optional[str]. name flows into xr.DataArray(name=name) which accepts None, so slope(agg, name=None) already worked at runtime -- the annotation was just wrong and inconsistent. Fix widens to Optional[str] and imports Optional (module previously imported only Union). Non-breaking (type-hint widening), no deprecation shim. Added test_name_annotation_matches_terrain_family (pins parity vs the 4 siblings via get_type_hints, unwrapping @supports_dataset) and test_name_none_accepted (slope(agg, name=None).name is None). Full test_slope.py passes (43). No backend logic touched -- numpy/cupy/dask+numpy/dask+cupy paths unchanged; public signature is shared across backends via ArrayTypeFunctionMapping. Other categories: no Cat 1 in-module rename (slope/aspect share identical public param names agg/name/method/z_unit/boundary); no Cat 2 return drift (returns xr.DataArray/Dataset via @supports_dataset, same coords/dims/attrs convention as siblings); no Cat 4 default drift (name/method='planar'/z_unit='meter'/boundary='nan' match across the family); no Cat 5 orphan API (slope re-exported in __init__.py, documented, no __all__ but consistent with module convention). Cross-cutting (documented, not filed per template): first-arg `agg` (slope/aspect/curvature) vs `raster` (reproject/rasterize/polygonize) is library-wide drift. cuda-validated: CUDA_AVAILABLE=True on this host; cupy slope smoke-tested (planar) and signature parity confirmed between numpy and cupy entry points."
|
|
16
17
|
visibility,2026-06-10,3183,MEDIUM,3;5,"Sweep 2026-06-10 (deep-sweep-api-consistency-visibility-2026-06-10). 2 MEDIUM findings filed as issue #3183, fixed in this branch. (MEDIUM Cat 5) output-name convention drift: viewshed() sets a fixed output name and exposes name=, but cumulative_viewshed (visibility.py:289) and visibility_frequency built/returned DataArrays with name=None. Fix adds name='cumulative_viewshed'/'visibility_frequency' params (Optional[str]) and sets result.name; additive, non-breaking, no shim. coords/attrs were already preserved on both. (MEDIUM Cat 3) line_of_sight (visibility.py:162) annotated frequency_mhz: float = None; default contradicts the float hint and the docstring already says optional. Fix -> Optional[float] (imported typing.Optional). Tests added: cumulative/frequency default+custom name. No Cat 1 naming drift: observer_elev/target_elev/max_distance/x/y and the x0/y0/x1/y1 two-point extension match viewshed and the observers dict keys. No Cat 2 arbitrary return drift: line_of_sight -> Dataset fits its per-sample multi-variable result; the two cumulative funcs -> DataArray like viewshed. No Cat 4 default drift (observer_elev=0/target_elev=0/max_distance=None match). No Cat 5 orphan API: all 3 funcs re-exported in __init__.py; no __all__ but consistent with module convention. cuda-validated: CUDA_AVAILABLE=True on this host; cupy entry points accept the new name= kwarg and the line_of_sight Optional hint. PRE-EXISTING backend bug (out of scope, not an api-consistency issue, NOT filed here): cumulative_viewshed on a cupy raster raises TypeError 'Unsupported type numpy.ndarray' in the count + (vs_data != INVISIBLE) accumulation (numpy accumulator vs cupy viewshed result); reproduced on origin/main without this branch's changes -- a backend-parity gap for a future backend-parity sweep."
|
|
17
|
-
zonal,2026-06-10,3188,MEDIUM,1;3;5,"Re-sweep 2026-06-10 (deep-sweep-api-consistency-zonal-2026-06-10). Prior sweep's HIGH zones_ids/zone_ids typo confirmed already fixed on main (#2521). Several previously-documented MEDIUM Cat 3 items also fixed on main since 2026-05-27: crosstab layer docstring now says default=None; hypsometric_integral now has param+return annotations; apply now has -> xr.DataArray. Two remaining safe Cat 3 fixes filed+PR'd this run (issue #3188 / PR #3196): (1) crosstab zone_ids/cat_ids annotated List[...]=None -> wrapped in Optional[...] to match stats()/crop(); (2) crosstab nodata_values docstring said 'Cells with nodata' (copy-paste from apply) -> now references nodata_values. Non-breaking, 17 crosstab tests pass. Documented-not-fixed: (MEDIUM Cat 1) nodata vs nodata_values drift across stats/crosstab (nodata_values, default None, filters VALUES raster) vs apply/hypsometric_integral (nodata, default 0, filters ZONES raster) -- names differ but so do the concepts and defaults, so a blanket rename would conflate two distinct meanings; needs a design decision, not a mechanical shim. (MEDIUM Cat 5) get_full_extent has a public-style docstring+example but is not in __init__.py -- borderline orphan, minor utility, left as-is. (LOW Cat 3) crop() lacks a return type annotation while stats/crosstab/apply/regions/trim annotate theirs. Cross-cutting (not filed): first-arg name varies (stats/crosstab/crop use zones; regions/trim use raster) but regions/trim operate on the raster itself so the name matches the role; library-wide agg vs raster vs values naming spans 20+ modules, out of per-module scope. cuda-validated: CUDA_AVAILABLE=True on this host."
|
|
18
|
+
zonal,2026-06-10,3188,MEDIUM,1;3;5,"Re-sweep 2026-06-10 (deep-sweep-api-consistency-zonal-2026-06-10). Prior sweep's HIGH zones_ids/zone_ids typo confirmed already fixed on main (#2521). Several previously-documented MEDIUM Cat 3 items also fixed on main since 2026-05-27: crosstab layer docstring now says default=None; hypsometric_integral now has param+return annotations; apply now has -> xr.DataArray. Two remaining safe Cat 3 fixes filed+PR'd this run (issue #3188 / PR #3196): (1) crosstab zone_ids/cat_ids annotated List[...]=None -> wrapped in Optional[...] to match stats()/crop(); (2) crosstab nodata_values docstring said 'Cells with nodata' (copy-paste from apply) -> now references nodata_values. Non-breaking, 17 crosstab tests pass. Documented-not-fixed: (MEDIUM Cat 1) nodata vs nodata_values drift across stats/crosstab (nodata_values, default None, filters VALUES raster) vs apply/hypsometric_integral (nodata, default 0, filters ZONES raster) -- names differ but so do the concepts and defaults, so a blanket rename would conflate two distinct meanings; needs a design decision, not a mechanical shim. (MEDIUM Cat 5) get_full_extent has a public-style docstring+example but is not in __init__.py -- borderline orphan, minor utility, left as-is. (LOW Cat 3) crop() lacks a return type annotation while stats/crosstab/apply/regions/trim annotate theirs. Cross-cutting (not filed): first-arg name varies (stats/crosstab/crop use zones; regions/trim use raster) but regions/trim operate on the raster itself so the name matches the role; library-wide agg vs raster vs values naming spans 20+ modules, out of per-module scope. cuda-validated: CUDA_AVAILABLE=True on this host."
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
module,last_inspected,issue,severity_max,categories_found,notes,doc_coverage
|
|
2
|
+
perlin,2026-06-23,,MEDIUM,2;5,"name param undocumented (Cat2) + float-dtype requirement/ValueError undocumented, no Raises section (Cat5); fixed in deep-sweep-documentation-perlin-2026-06-23; repo has issues disabled so no issue number; example runs and output matches; 1 public func (perlin) listed in reference/surface.rst",1/1
|
|
@@ -1,12 +1,14 @@
|
|
|
1
1
|
module,last_inspected,issue,severity_max,categories_found,notes
|
|
2
2
|
aspect,2026-05-29,2682,MEDIUM,4;5,"Audited 2026-05-29 (agent-a3b7c82e34312ffcb worktree, branch deep-sweep-metadata-aspect-2026-05-29). CUDA available; all 4 backends (numpy/cupy/dask+numpy/dask+cupy) run live for aspect/northness/eastness across planar and geodesic methods. Cat 1 attrs, Cat 2 coords, Cat 3 dims, and .name all preserved correctly on every backend: the 3 public functions re-emit coords=agg.coords, dims=agg.dims, attrs=agg.attrs at the xr.DataArray constructor. NEW MEDIUM finding #2682 (Cat 4 + Cat 5): the planar dask backends (_run_dask_numpy, _run_dask_cupy) called map_overlap with a default-dtype meta (np.array(()) / cupy.array(())), so the lazy DataArray advertised float64 while the chunk functions _cpu / _run_cupy cast to and return float32. numpy and cupy backends already reported float32, and the geodesic dask paths already passed dtype=np.float32, so only the two planar dask paths were inconsistent: a backend-inconsistent metadata bug where agg.dtype differs by backend and silently flips float64->float32 on .compute(). Fix in PR #2741: pass dtype=np.float32 / dtype=cupy.float32 to the planar dask meta. northness/eastness derive from aspect so they inherit the corrected dtype. 5 new tests (test_dask_numpy_advertised_dtype_matches_computed parametrized over 4 boundary modes, plus test_dask_cupy_advertised_dtype_matches_computed) assert lazy dtype == computed dtype == float32. Full aspect suite 69 passed. slope.py and curvature.py share the same default-dtype meta pattern on their planar dask paths (out of scope for this aspect-only sweep; likely same inconsistency). No CRITICAL/HIGH/LOW findings."
|
|
3
3
|
contour,2026-05-29,2700,HIGH,1;5,"Audited 2026-05-29 (agent-ab7fff484a8f57de2 worktree, branch deep-sweep-metadata-contour-2026-05-29). CUDA available; cupy and dask+cupy paths exercised live. contours() returns a list of (level, ndarray) tuples or a GeoDataFrame, not a DataArray, so Cat 2/3 DataArray checks reinterpreted as coordinate-transform + CRS propagation. Coordinate transform (np.interp over input dims, descending y respected) is correct and identical across all 4 backends (tracing is host-side via _contours_numpy). Cat 4 N/A: library convention is NaN-as-nodata; slope/aspect/curvature/focal do not read attrs['nodatavals'] either, so contour not reading it is consistent, not a bug. NEW HIGH finding #2700 (Cat 1/Cat 5): contours(return_type='geopandas') crashed with 'Assigning CRS to a GeoDataFrame without a geometry column is not supported' whenever the input had attrs['crs'] but the result was empty (flat raster, levels outside data range) because _to_geopandas built gpd.GeoDataFrame([], crs=crs) with no geometry column; separately the all-NaN early-return passed crs=None and silently dropped the CRS. Fix (PR #2708): _to_geopandas builds an empty frame with an explicit geometry column so the CRS attaches; all-NaN early-return forwards agg.attrs['crs']. Both empty paths now return a well-formed empty GeoDataFrame carrying the CRS. 4 new tests in TestGeoDataFrame cover populated-CRS, empty-with-CRS, all-NaN-with-CRS, and empty-without-CRS. Full contour suite 28 passed. numpy-return path emits no DataArray attrs by design (list of tuples)."
|
|
4
|
+
corridor,2026-06-22,3446,HIGH,1;5,"Audited 2026-06-22 (agent-a8b2674b815bdfa3f worktree, branch deep-sweep-metadata-corridor-2026-06-22). CUDA available; all 4 backends (numpy/cupy/dask+numpy/dask+cupy) run live end-to-end for least_cost_corridor across single/threshold/relative/unreachable/pairwise paths. Cat 2 coords (x/y values + float64 dtype) and Cat 3 dims (y,x) preserved on every backend: they flow through cost_distance (coords=raster.coords, dims=raster.dims) and survive xarray's binary intersection. NEW HIGH finding #3446 (Cat 1 + Cat 5): the corridor is cd_a + cd_b where each cost-distance surface carries its SOURCE raster's attrs (cost_distance copies attrs from the source, not friction). xarray's default keep_attrs on binary + keeps only attrs present-and-equal in both operands, so when the source masks are plain marker rasters with no geo-attrs (the common case) the corridor came back with attrs=={} even though the friction surface that defines the grid had res/crs/transform/nodatavals; a downstream slope/clip on the corridor silently lost cellsize/CRS. Secondary Cat 5: .name was None whenever the two sources had different names (cost_distance renames each surface to its source .name; summing differently-named arrays drops the name). Fix (PR on this branch): non-precomputed path re-emits friction.attrs + friction.name on every output via new _apply_geo_metadata helper (single, threshold, all-NaN-unreachable, and pairwise-Dataset paths); precomputed path left on the existing source-derived behaviour since there is no friction to draw from. Only .attrs/.name set -- data values, coords, dims, dtype untouched, dask stays lazy (no compute). 10 new tests (test_corridor_inherits_friction_geo_attrs x4 backends, test_corridor_threshold_keeps_geo_attrs x4 backends, test_corridor_unreachable_keeps_geo_attrs, test_pairwise_inherits_friction_geo_attrs, test_precomputed_keeps_source_attrs_not_friction). Full corridor suite 43 passed. Cat 4 N/A: NaN-as-nodata is the library convention; corridor never reads attrs['nodatavals'] for masking. No CRITICAL/MEDIUM/LOW findings."
|
|
4
5
|
cost_distance,2026-06-15,3344,MEDIUM,5,"Audited 2026-06-15 (agent-ad0b84e7f7b212360 worktree, branch deep-sweep-metadata-cost_distance-2026-06-15). CUDA available; all 4 backends (numpy/cupy/dask+numpy/dask+cupy) run live end-to-end with a rich attrs set (res/crs/transform/nodatavals/_FillValue/units). Cat 1 attrs, Cat 2 coords (values + float64 dtype), and Cat 3 dims (y,x) all preserved and identical across the 4 backends -- public cost_distance() wraps with xr.DataArray(coords=raster.coords, dims=raster.dims, attrs=raster.attrs). NEW MEDIUM finding #3344 (Cat 5): the dask+numpy and dask+cupy backends leaked the internal dask graph name (_trim-<hash> from map_overlap, asarray-<hash> from the dask+cupy convert-back path) into result.name while numpy/cupy returned None; .name was a nondeterministic per-run token that breaks .to_dataset() variable keys and any name-keyed pipeline. Same .name-leak class as proximity #2723 and zonal #2611. Fix (PR #3349 on this branch): return result.rename(raster.name) -- a constructor name= kwarg does not override a named dask array, and name=None is treated as infer-from-data, so .rename() is required. supports_dataset path unaffected (keys by var_name, verified live). New parametrized regression test test_result_name_matches_input over 4 backends x {None, named}; full cost_distance suite 63 passed (post-merge with origin/main). LOW (documented, not fixed): output float32 uses NaN as the unreachable sentinel but input nodatavals/_FillValue (e.g. -9999) are carried through verbatim, so a downstream reader masks a value that never appears -- this is the library-wide attrs=raster.attrs convention shared by proximity/slope/aspect/focal, not a cost_distance-specific bug, so fixing it in isolation would diverge this module from every peer. No CRITICAL/HIGH findings."
|
|
5
6
|
focal,2026-06-10,3217,MEDIUM,4;5,"Re-audited 2026-06-10 (agent-ad0d55a894c6abc60 worktree, branch deep-sweep-metadata-focal-2026-06-10). CUDA available; all 4 backends (numpy/cupy/dask+numpy/dask+cupy) run live for mean, apply, focal_stats, hotspots. Cats 1-3 clean: attrs (res/crs/nodatavals/_FillValue/unit), coords (values, dtype, coord attrs), dims, .name, 3D per-band path, and hotspots unit=% all preserved and identical across the 4 backends. NEW MEDIUM finding #3217 (Cat 4 + Cat 5): (a) mean() hardcoded float32 on the GPU paths (_mean_cupy cupy.asarray(dtype=float32), _mean_dask_cupy astype(float32)) while numpy/dask+numpy returned float64 (mean() casts astype(float) before dispatch), so float64 input silently lost precision on cupy/dask+cupy; dask+cupy also advertised float64 (untyped meta) but computed float32. (b) apply()/focal_stats() dask paths passed untyped meta (np.array(()) / cupy.array(())) to map_overlap, so for float32/int input the lazy DataArray advertised float64 but computed the promoted float32 (#2805 typed the chunk fns but not the meta). Same class as aspect #2682 and proximity #2723. Fix: the mean() GPU dtype half landed on main first via duplicate issue #3214/PR #3221 (_promote_float contract: float dtypes preserved, ints->float32, GPU bit-exact vs CPU in float64); PR #3226 (branch deep-sweep-metadata-focal-2026-06-10-01) types every map_overlap meta with data.dtype and aligns tests to the _promote_float contract; 25 new parametrized regression tests (4 backends x 3 dtypes mean; dask backends x 3 dtypes apply/focal_stats; exact CPU/GPU parity). Full focal suite 258 passed. No other CRITICAL/HIGH/MEDIUM/LOW findings."
|
|
6
7
|
geotiff,2026-06-09,3116,HIGH,2;3,"Re-audited 2026-06-09 (agent-ae89ff94a64e3ee8f worktree, branch deep-sweep-metadata-geotiff-2026-06-09). CUDA available; all 4 backends (numpy/cupy/dask+numpy/dask+cupy) run live. Focus: surfaces changed since the 2026-05-18 audit (unpack rename + GPU/dask+GPU support #3075, pack=True #3065/#3079, masked int->float promotion #2994, bbox= reads, rioxarray param alignment #2963, no-georef VRT coord synthesis #2824, GeoTransform omission #2971). Live probes: unpack attrs (scale_factor/add_offset/mask_and_scale_dtype/nodata/masked_nodata), masked=True promotion, default masked=False, bbox window+transform shift, multi-band band=N, dims/name/coords (incl. coord dtype) all identical across the 4 backends; nodata_pixels_present absent on dask paths is the documented lazy contract, not a bug. pack->unpack round trips verified on numpy/dask/gpu-write; pack of a cupy-backed read raises via the known cupy+xarray xp.astype incompat (see memory cupy_where_astype_incompat; dependency-pin fix, raises loudly, not a metadata bug). VRT reads (full/masked/window/bbox) and no-georef TIFF reads agree across the 4 backends. NEW HIGH finding #3116 (Cat 2+3): to_geotiff(non_georef_da, out.vrt, tile_size=N) wrote a corrupt index for arrays spanning >1 tile -- write_vrt derives placement from each source GeoTransform and non-georef tiles all carry the identity transform, so rasterX/YSize collapsed to one tile and every DstRect landed at the origin; reads silently returned a single tile (24x32 in -> 16x16 out). Gap left by #2966/#2971 (tests only covered one non-georef source). Fix: _write_vrt_tiled threads per-tile pixel offsets through _build_vrt -> write_vrt via internal dst_offsets kwarg; write_vrt refuses >1 all-non-georef sources without explicit placement and rejects dst_offsets alongside georeferenced sources. 18 new tests in tests/vrt/test_non_georef_placement_3116.py incl. 4-backend round trip, dask-backed and plain-ndarray writes, XML DstRect assertions, georef placement regression, and the write_vrt error contract. Full vrt suite 520 passed; write+round-trip suites 1292 passed."
|
|
7
8
|
interpolate,2026-06-12,3288,MEDIUM,5,kriging K_inv-None fallback was numpy-backed on all backends and misnamed the variance raster; fixed via #3288. All 4 backends verified end-to-end on GPU host. LOW (documented only): template nodatavals/_FillValue copied verbatim while fill_value is the actual output sentinel; tests codify attrs==template.attrs
|
|
8
9
|
mcda,2026-06-10,3147,HIGH,1,"constrain() dropped all attrs (res/crs/nodatavals) whenever exclude non-empty (xr.where takes attrs from scalar fill); fixed via attrs restore, tests for numpy/dask/dask+cupy. All other mcda funcs keep attrs/coords/dims on all 4 backends. Out-of-scope crashes noted for backend-parity: owa broken on cupy (numpy order-weights x cupy) and on dask (da.sort does not exist); sensitivity monte_carlo crashes on cupy/dask+cupy (.values on cupy); xr.where compute on cupy/dask+cupy hits known cupy13.6/xarray2025.12 incompat."
|
|
9
10
|
multispectral,2026-06-20,3429,MEDIUM,2;3,"true_color() hardcoded y/x dims + dropped extra coords; fixed PR #3434 (all 4 backends verified, CUDA available)"
|
|
11
|
+
perlin,2026-06-23,,MEDIUM,2,perlin() dropped input x/y coords (kept attrs incl crs); fixed by passing coords=agg.coords; verified numpy/cupy/dask/dask+cupy; issues disabled on fork so no issue number; PR pending
|
|
10
12
|
polygonize,2026-06-12,3293,MEDIUM,1,"Audited 2026-06-12 (agent-a86d90abea41b04cf worktree, branch deep-sweep-metadata-polygonize-2026-06-12). CUDA available; all 4 backends (numpy/cupy/dask+numpy/dask+cupy) run live for int, float+NaN, and no-georef rasters. polygonize returns vector output (numpy/awkward/geopandas/spatialpandas/geojson), not a DataArray, so Cats 2-4 reinterpreted as transform/CRS/value-dtype propagation. Transform auto-detect (attrs['transform'] -> rio.transform() -> x/y coords, #2536/#2607) and CRS resolution run in public polygonize() before dispatch, so all 4 backends emit identical columns, bounds, and CRS (verified live). Column value dtype follows input dtype on every backend. NEW MEDIUM finding #3293 (Cat 1): _detect_raster_crs ignored the _xrspatial_no_georef marker that _detect_raster_transform honours, so a geotiff-reader crs_only raster (attrs carry both crs and the marker; metadata_to_attrs writes crs independent of has_georef) produced a GeoDataFrame claiming EPSG:#### over pixel-space geometries -- the #2536 metadata-lies-about-the-data mismatch through the marker channel. contour.py imports the same helper and inherits the fix. Fix: early return None in _detect_raster_crs on the marker + docstring note; 2 new tests in TestPolygonizeCRSPropagation. polygonize+contour suites 274 passed; all 9 auxiliary polygonize test files 303 passed. rotated-read path unaffected (reader drops CRS there). No CRITICAL/HIGH/LOW findings."
|
|
11
13
|
proximity,2026-05-29,2723,MEDIUM,4;5,"Audited 2026-05-29 (agent-a61dbadc2452a2003 worktree, branch deep-sweep-metadata-proximity-2026-05-29). CUDA+cupy available; all 4 backends (numpy/cupy/dask+numpy/dask+cupy) run live end-to-end for proximity/allocation/direction, both bounded (finite max_distance) and unbounded. Cat 1 (attrs res/crs/transform/nodatavals/_FillValue), Cat 2 (coords + coord dtype), and Cat 3 (dims) all preserved and identical across the 4 backends -- public funcs wrap with xr.DataArray(coords=raster.coords, dims=raster.dims, attrs=raster.attrs). NEW MEDIUM finding #2723 (Cat 4 + Cat 5): (a) bounded dask+numpy path (_process_dask -> da.map_overlap with meta=np.array(())) declared output dtype float64 while the chunk fn returns float32 and numpy/cupy/dask+cupy + the unbounded KDTree path all declare float32; docstrings show dtype=float32. Fix: meta=np.array((), dtype=np.float32). (b) dask backends leaked an internal dask op name (_trim-<hash>, _kdtree_chunk_fn-<hash>, asarray-<hash>) into result.name while numpy/cupy return None. Fix: assign result.name=None after construction in all 3 public funcs (xarray ignores a name=None kwarg for named dask arrays, so the reset must happen post-construction). Same .name-leak class as zonal #2611. PR #2728 off child branch deep-sweep-metadata-proximity-2026-05-29-01. New parametrized regression test test_output_metadata_consistent_across_backends asserts declared dtype float32 + name None across all 4 backends x 3 funcs x bounded/unbounded; full test_proximity.py suite 93 passed. No other CRITICAL/HIGH/MEDIUM/LOW findings."
|
|
12
14
|
rasterize,2026-06-09,3087,MEDIUM,1,GeoDataFrame .crs dropped on no-like path (Cat 1); fixed via #3087 emitting attrs crs/crs_wkt when output has no CRS. like-path attrs/coords/dims/nodata verified live on all 4 backends (CUDA available); Cats 2-5 clean.
|
|
@@ -32,7 +32,7 @@ morphology,2026-06-20,SAFE,compute-bound,1,3401,memory guard fired on full lazy-
|
|
|
32
32
|
multispectral,2026-05-02,SAFE,compute-bound,0,,"Re-audit 2026-05-02 after PRs 1292 (true_color memory guard) and 1301 (validate_arrays in true_color). Verified SAFE. No HIGH. MEDIUM: da.stack in _true_color_dask/_true_color_dask_cupy at L1702/L1731 creates (1,1,1,1) chunks along band axis (4 bands so impact is minor, scheduling overhead not OOM). LOW: np.zeros((h,w,4)) at L1681 then full overwrite -- np.empty would suffice. All 17 indices use plain map_blocks with no halo; 8192x8192 ndvi graph is 80 tasks, evi/arvi/ebbi 112 tasks."
|
|
33
33
|
normalize,2026-03-31T18:00:00Z,SAFE,compute-bound,0,1124,Boolean indexing replaced with lazy nanmin/nanmax/nanmean/nanstd.
|
|
34
34
|
pathfinding,2026-04-15T12:00:00Z,SAFE,compute-bound,0,false-positive,Downgraded. CuPy .get() is required -- A* has no GPU kernel. Per-pixel .compute() is only 2 calls for start/goal validation. seg.values in multi_stop_search collects already-computed results for stitching.
|
|
35
|
-
perlin,2026-
|
|
35
|
+
perlin,2026-06-23,SAFE,memory-bound,1,3469,"Re-audit 2026-06-23 (CUDA host). 1 HIGH: _perlin_dask_numpy (L128) and _perlin_dask_cupy (L279) called dask.persist on the full noise array before min/ptp(max) reductions -> every chunk resident at once, WILL OOM at 30TB. Persist redundant: both reductions share the named noise subgraph in one dask.compute (verified min/ptp graphs ref same 100 noise keys). Fixed by removing persist -> peak mem chunk-bounded, SAFE. map_blocks graph embarrassingly parallel (3.3 tasks/chunk). cupy kernel _perlin_gpu 36 regs/thread (no pressure); cupy path stays on GPU, no host round trip. numpy/cupy single-GPU unaffected. 13 perlin tests pass incl GPU+dask+GPU. PR #3469-fix."
|
|
36
36
|
polygon_clip,2026-06-10,SAFE,graph-bound,0,3191,"crop=True picked tiny leading edge chunk as rasterize mask size -> 13169-task graph; fixed to max(rc),max(cc) -> 1045 tasks. crop=False/numpy/cupy clean. Cat1-5 clean. GPU+dask+cupy run-validated."
|
|
37
37
|
polygonize,2026-06-12,RISKY,compute-bound,0,3303,"Pass 3 (2026-06-12): re-audit after #2817/#2913/#3041. 0 HIGH. 1 MEDIUM fixed (#3303): _compute_region_value_ranges ran a pure-Python per-pixel loop (95% of float chunk time; 0.283s of 0.299s on 1024x1024, float chunks ~30x int) and re-ran _calculate_regions on an already-labelled block; moved to jitted _region_ranges_scan + _polygonize_numpy_regions label reuse (0.299s -> 0.015s/chunk). Side fix: w_match/s_match flags were always-truthy (_is_close numba overload generator called from pure Python returns impl function); output-neutral by chunk geometry, now computed correctly in jit. Cat1/2 clean (dask.compute batching is the documented #2673 design). Cat3 validated on GPU: cupy int/float + dask+cupy run end-to-end, single documented transfer, no round-trip. Cat4/5 LOW unchanged: _calculate_regions_cupy per-unique-value labeling (low impact); per-polygon Python classify loop in _polygonize_chunk dominates only on pathological many-polygon chunks (788K polys -> 7.8s). Cat6 RISKY unchanged: driver accumulates O(total polygons); 32-chunk batches bound transient peak. 527 polygonize tests + 40 new pass."
|
|
38
38
|
proximity,2026-06-09,RISKY,graph-bound,0,3103,"Pass 2 (2026-06-09): re-audit after 16 fix commits since 2026-03-31. 0 HIGH, 2 MEDIUM found and fixed: (1) #3103/PR #3126 line-sweep @ngjit closure inside _process recompiled per call (~0.42s constant overhead; 10x10 warm call 0.44s->1ms after module-level hoist with explicit args, 1000x1000 0.49s->35ms); (2) #3132/PR #3137 dask xs/ys coordinate grids built via da.tile/da.repeat+rechunk cost ~185 tasks/chunk with the ys term scaling O(raster height) (~4.3 tasks/row, 44K tasks at 10240 rows); chunk-aligned da.broadcast_to gives identical values, bounded graph 18535->5554 tasks (3.3x) on 2560^2/256 chunks; regression test bounds tasks/chunk<80 (old 100.4, new 58.7) + ragged-chunk parity. LOW not fixed: zeros+fill(-1) row buffers in line-sweep; numpy backend materializes full float64 xs/ys grids (guarded since #1111); unbounded KDTree streaming count pass computes chunks on driver by design (gh-879). GPU validated on CUDA host: cupy 1024^2 proximity 6ms device-resident with exact numpy parity, dask+cupy bounded parity exact, _proximity_cuda_kernel 56 regs/thread (no register pressure). _halo_depth python loop measured 58ms at 100K coords - not a finding. Verdict RISKY (was WILL OOM): unbounded paths either guarded (MemoryError at 80% mem) or stream via kdtree; bounded map_overlap peak scales with chunk size."
|
|
@@ -14,6 +14,7 @@ interpolate-kriging,2026-06-04,2916,MEDIUM,1;4,"flake8 E128 x2: continuation-lin
|
|
|
14
14
|
mcda,2026-06-10,3143,HIGH,3;4,F401 dead function-local warnings import in standardize.py; isort drift in weights.py combine.py __init__.py; flake8 otherwise clean; Cat 5 greps clean; fixed via PR for #3143
|
|
15
15
|
morphology,2026-06-20,3400,HIGH,3;4,"F401 xr/has_cuda_and_cupy/not_implemented_func + F841 size (dead); isort ordering. /rockout PR off issue 3400. flake8+isort clean, 74 tests pass."
|
|
16
16
|
multispectral,2026-06-20,3428,HIGH,3;4,F401 unused not_implemented_func (Cat3 HIGH); isort dataset_support before utils (Cat4 MEDIUM); Cat1/2/5 clean; fixed via #3428
|
|
17
|
+
perlin,2026-06-23,,HIGH,3;4,"Cat3 F401: unused not_implemented_func import from xrspatial.utils (refactor leftover, not re-exported; __init__ exports only perlin). Cat4 isort: utils from-import reflowed to line_length=100 after the name was dropped. No Cat1/2/5 (grep clean: no bare except, mutable defaults, ==None/True, or shadowed builtins). flake8+isort clean after fix; import smoke test ok; 12 perlin tests pass (CUDA available). GitHub issues disabled on repo so no issue filed; fix on deep-sweep branch + PR."
|
|
17
18
|
polygon_clip,2026-06-10,3184,HIGH,3;4,"Cat 3 F401: dropped unused typing imports Sequence/Tuple/Union (line 10, only Optional used) and the dead 'import cupy' inside the _apply_mask dask+cupy closure (line 245); the other 'import cupy' at line 261 is used (cupy.asarray) and kept. None re-exported (__init__ re-exports only clip_polygon). Cat 4 isort: reflowed the 5-name xrspatial.utils from-import block to line_length=100. Cat 1/2/5 grep clean (no E/W codes, no bare except, mutable defaults, ==None/True, or shadowed builtins). flake8+isort clean after fix; 23 test_polygon_clip tests pass. PR open."
|
|
18
19
|
polygonize,2026-05-27,2534,HIGH,1;3;4,"F401 line 58 (is_cupy_array unused, not re-exported). E127 lines 83/88 (overload continuation indent in generated_jit). isort: 5-line .utils import block collapses to one line at 100-char limit. Cat 2 clean. Cat 5 grep clean."
|
|
19
20
|
proximity,2026-06-18,,MEDIUM,4,"Re-audit 2026-06-18 (file last modified 2026-06-14). Cat 4 isort: from xrspatial.utils import (...) block wrapped one name early for line_length=100; pulled has_cuda_and_cupy onto first continuation line (both lines <=100, flake8 clean). isort+flake8 now clean. Fix applied + verified imports resolve. Cat 1/2/3 clean. Cat 5 grep: target_values: list = None on L1540/1700/1859 are type annotations not builtin-shadowing vars (false positive); mutable-default already None-sentinel from prior #2725. MEDIUM. /rockout issue+PR creation BLOCKED by auto-mode classifier (external publish denied); fix committed to deep-sweep branch only."
|
|
@@ -2,9 +2,11 @@ module,last_inspected,issue,severity_max,categories_found,notes
|
|
|
2
2
|
aspect,2026-06-21,3439,MEDIUM,2,"#3439 (Cat 2): Inf/-Inf elevation input and all-NaN raster were untested. Added Inf-input finite-neighbors + 4-backend parity, and all-NaN -> all-NaN shape-preserved for aspect/northness/eastness on all 4 backends; GPU-validated (CUDA available). Both behaviors defined and consistent across backends -> coverage gap, not a bug (supersedes prior 'Inf possible source bug, not filed' note). Prior: #2742 degenerate shapes + geodesic boundary modes; #2829 northness/eastness geodesic branch -- all still covered."
|
|
3
3
|
classify,2026-06-20,,MEDIUM,3;4,"Deep-sweep 2026-06-20 test-coverage on a CUDA host. Backend matrix was already complete: all 10 public classifiers (binary/reclassify/quantile/natural_breaks/equal_interval/std_mean/head_tail_breaks/percentiles/maximum_breaks/box_plot) x 4 backends present and green (Cat 1 no gap). Cat 2 (NaN/Inf) covered: input_data() fixture embeds -inf/nan/+inf at corners on every numpy/dask/cupy test, plus all-nan/all-inf/all-same dedicated tests. Cat 5 covered via general_output_checks(verify_attrs=True) asserting attrs/dims/coords on every backend test. Found two MEDIUM gaps: Cat 3 (no 1x1 single-pixel, no Nx1/1xN strip tests for any classifier) and Cat 4 (the _validate_scalar k<min_val guards were never exercised: quantile/natural_breaks/maximum_breaks k>=2, equal_interval k>=1). Probed live: single-pixel and strip shapes all work correctly (no source bug -- lone finite pixel -> class 0; binary match -> 1; reclassify -> bin's new_value), so these are untested-but-passing paths. Added test-only (numpy, since the gaps are in shared CPU-side validation + bin-edge logic and the 4-backend dispatch is already fully covered): test_classify_single_pixel, test_binary_single_pixel, test_reclassify_single_pixel, test_classify_nx1_strip, test_classify_1xn_strip, and 4 k-below-min ValueError tests. All RAN and PASSED on the CUDA host; full file 98 passed. classify.py untouched. LOW (documented, not fixed): empty raster (0 rows) raises on numpy equal_interval (zero-size reduction) and differs across backends -- degenerate input, not pinned. Non-square cellsize not exercised (classifiers ignore cellsize, so out of scope)."
|
|
4
4
|
contour,2026-06-08,2704;2710;3044,MEDIUM,1;2,"Pass 2 (2026-06-08, deep-sweep test-coverage): re-swept on a CUDA host. Verified issue #2704 is CLOSED (fixed 2026-06-01 via #2749, kernel now uses np.isfinite at contour.py:73-74); the two prior xfail(strict) #2704 pins were already flipped to plain passing assertions in TestInfHandling (test_inf_corner_no_nan_coords / test_neg_inf_corner_no_nan_coords) -- no stale xfail remained. Found one MEDIUM Cat 1+2 gap: no cross-backend parity test fed NaN input -- TestBackendEquivalence uses elevation_raster_no_nans and test_partial_nan is numpy-only, so numpy-interior NaN-skip vs dask NaN-halo (da.overlap) parity at chunk edges was unpinned. Filed #3044, added TestNaNBackendParity (3 tests: dask, cupy, dask+cupy each assert _segments_by_level equality vs numpy on a partial-NaN ramp with a NaN edge row + interior NaN cell inside a non-edge chunk). All 3 RAN and PASSED on a CUDA host; full file 89 passed, 0 skipped. Probed and verified now-resolved: the prior-pass LOW items are no longer real gaps -- the levels=None all-NaN early-return IS asserted (result==[]) on all 4 backends (numpy L148/dask L163/cupy L178/dask+cupy L194) plus geopandas (test_geopandas_all_nan_keeps_crs). LOW (documented, NOT fixed): non-square cellsize (res[0]!=res[1]) still never exercised -- all tests use create_test_raster res (0.5,0.5); probed live that anisotropic coords transform correctly (y scaled 2.0, x scaled 0.5 -> crossing x=1.25, y spans 0..8), works, so it is a LOW coverage gap not a bug. Cat 3 1x1/Nx1/1xN remain rejected by the >=2x2 guard (tested). Test-only PR for #3044; contour.py untouched. | Pass 1 (2026-05-29): added TestInfHandling, TestCRSPropagation, TestNonDefaultDims to test_contour.py (5 passed + 2 strict-xfail on a CUDA host; full file 29 passed, 2 xfailed). All four backends (numpy / cupy / dask+numpy / dask+cupy) were already exercised with cross-backend segment-equality assertions (TestBackendEquivalence), and ran green locally on the CUDA host -- Cat 1 well covered, no new backend tests needed. Cat 2 HIGH (Inf): the marching-squares NaN-skip guard at contour.py:67 uses x!=x which does not catch infinity, so a finite level near a +/-inf corner leaks NaN coordinates into the output. Filed source bug #2704 and added two xfail(strict=True) tests pinning it (+inf and -inf) plus test_inf_far_level_no_crossing covering the safe path where the inf quad classifies as all-above (idx 15) and is skipped before any interpolation. Cat 5 MEDIUM: no test asserted gdf.crs propagation from agg.attrs['crs'] (contour.py:660) -- added test_geopandas_crs_from_attrs (to_epsg()==5070) + test_geopandas_no_crs_attr. Cat 5 MEDIUM: the index-to-coordinate transform (contour.py:644-654) reads agg.dims[0]/[1] coords but no test used non-y/x dims -- added test_lat_lon_dims_coordinate_transform + test_lat_lon_matches_yx_equivalent. PR #2710 (test-only, source untouched). LOW (documented, not fixed): non-square cellsize (cellsize_x != cellsize_y) never exercised -- all tests use res (0.5,0.5); levels=None early-return on all-NaN/all-equal works (probed) but only the explicit-levels all-NaN path is asserted. Cat 3 1x1/Nx1/1xN are rejected by the >=2x2 validation guard and that rejection is already tested (test_too_small, test_minimum_raster)."
|
|
5
|
+
corridor,2026-06-22,,HIGH,1;3;4;5,"Deep-sweep 2026-06-22 test-coverage on a CUDA host. least_cost_corridor is the only public function; it delegates all backend math to cost_distance (4 backends) plus pure xarray arithmetic. Backend matrix for the core paths was already complete: symmetry/optimal-path/abs-threshold/rel-threshold/barrier/unreachable each parametrized over numpy/dask+numpy/cupy/dask+cupy. Cat 2 (NaN barriers + all-NaN unreachable) covered. Found gaps (all paths probed live and work -> coverage gaps, not source bugs): Cat 3 HIGH (no Nx1/1xN strip), Cat 5 HIGH (no attrs/coords/dim-name preservation test; corridor reads res for cost_distance math), Cat 1 MEDIUM (no numpy==other-backend exact equivalence assertion -- per-backend property checks only), Cat 4 MEDIUM (connectivity=4 and finite max_cost forwarding untested at corridor level). Added test-only: test_1xn_strip, test_nx1_strip, test_numpy_matches_other_backends (dask+numpy/cupy/dask+cupy), test_connectivity_4, test_max_cost_forwarded, test_attrs_coords_preserved, test_custom_dim_names_preserved. All RAN and PASSED on the CUDA host (cupy + dask+cupy not skipped); full file 41 passed."
|
|
5
6
|
cost_distance,2026-06-16,3367,MEDIUM,1;2,"Pass (2026-06-16 deep-sweep test-coverage, CUDA host). cost_distance is heavily tested: 1122 test lines for 1354 src lines, all 4 backends parametrized + regression tests for #1191/#880/#1252/#1262/#3340/#3341/#3343/#3344. Found one MEDIUM Cat 1+2 gap: _cost_distance_dask f_min<=0 early return (all-impassable friction, finite max_cost -> da.full NaN preserving chunks) was unreached -- numpy equiv covered by test_source_on_impassable_cell, iterative dask by test_iterative_narrow_corridor, but the bounded map_overlap wrapper shortcut was not. Filed #3367, added test_dask_all_impassable_friction_returns_nan (all-zero friction, dask+numpy chunks(3,3), max_cost=5; asserts all-NaN, dask-backed, npartitions>1). RAN + PASSED; -W error::UserWarning confirms early return taken (no iterative warning). Full file 85 passed on CUDA host. LOW (documented, not fixed): non-square cellsize numeric correctness untested (_make_meta_raster uses res=(2,3) but test_metadata_preserved checks metadata only)."
|
|
6
7
|
dasymetric,2026-06-20,3407;3406,HIGH,2;3;4;5,"deep-sweep test-coverage on a CUDA host (CUDA available, GPU tests ran). Module is well covered (813 test loc / 834 src): 4-backend equivalence for disaggregate weighted+binary, conservation, NaN/nodata/negative-weight, limiting_variable + cupy/dask NotImplemented guards, pycnophylactic numpy+cupy+dask-raises, validate_disaggregation all backends, memory guards (#1261). Filed #3407 (test-only) for real gaps and added 4 new test classes (11 passed, 2 xfailed). Cat5 HIGH: metadata (attrs res/crs + coords) never asserted -> TestMetadataPreservation (numpy/dask). Cat3 HIGH: true 1x1 raster untested (only 1x2 strip) -> TestSinglePixel for disaggregate weighted/binary + pycnophylactic (degenerate no-shift smoothing) + dask parity. Cat2 MEDIUM: Inf weight collapses zone total to 0 (silent conservation break) -> TestInfWeight pins current behaviour. Cat4 MEDIUM: 3-class limiting_variable (multi-break + per-class caps) untested despite docstring -> TestLimitingVariableThreeClass. SOURCE BUG found (filed #3406, NOT fixed - test-only sweep): pycnophylactic raises ValueError (np.nanmax on zero-size array) when no pixel is valid for smoothing (all-NaN zones or no zone id in values); disaggregate handles same input gracefully (all-NaN). Pinned with TestPycnophylacticEmptyValid xfail(strict, raises=ValueError) -> flips red when #3406 fixed. LOW (documented, not fixed): non-square cellsize never exercised (all tests use res 0.5/0.5); disaggregate cupy/dask+cupy 1x1 + metadata not separately added (eager numpy gap was the real one, GPU dispatch already covered by TestCrossBackend)."
|
|
7
8
|
diffusion,2026-06-20,3422,HIGH,1;2;3;4,"Pass 1 (2026-06-20, deep-sweep test-coverage, CUDA host). diffuse() dispatch table registers all 4 backends but test_diffusion.py only exercised numpy + dask+numpy. Cat 1 HIGH: cupy (_diffuse_cupy/_diffuse_step_gpu) and dask+cupy (_diffuse_dask_cupy/_diffuse_chunk_cupy) registered but never invoked -- no test ran them. Cat 4 HIGH: boundary accepts nan/nearest/reflect/wrap; only nearest+wrap tested, reflect had none. Cat 3 HIGH: 1x1 single-pixel and Nx1/1xN strip rasters never tested. Cat 2 MEDIUM: NaN tested numpy-only; Inf and all-NaN inputs untested. Filed #3422, added 14 tests (PR #3424, test-only, source untouched): cupy/dask+cupy parity vs numpy (incl. spatially-varying alpha + NaN propagation), reflect boundary across all 4 backends, 1x1 + Nx1 + 1xN (numpy + chunked dask strip), all-NaN stays NaN, Inf contamination smoke test. All 14 RAN+PASSED on a CUDA host; the 4 cupy/dask+cupy tests genuinely executed (not skipped); full file 39 passed. All paths verified correct before the tests were added -- coverage gap, not a bug. LOW (documented, not fixed): non-square cellsize (res[0]!=res[1]) never exercised -- diffuse uses res[0] as dx and assumes square cells; empty 0-row/0-col raster untested; asv benchmark absent; 'nan' boundary-mode edge=NaN behaviour not directly asserted on diffuse (covered indirectly via wrap/nearest)."
|
|
9
|
+
fire,2026-06-19,,HIGH,1;5,"Cat1 HIGH: dask+cupy dispatch registered but untested for rdnbr/burn_severity_class/fireline_intensity/flame_length/rate_of_spread/kbdi (only dnbr had it). Cat5 MEDIUM: only dnbr asserted attrs/coords/dims preservation. Added 6 test_numpy_equals_dask_cupy + 6 test_output_preserves_metadata; all 66 fire tests pass on a CUDA host. Cat2 LOW (not fixed): Inf inputs untested (pure per-cell math, low risk)."
|
|
8
10
|
focal,2026-06-10,3220;3219;3225,HIGH,1;2;3;4,"Deep-sweep 2026-06-10 on CUDA host, all 4 backends executed. Filed #3220 (coverage) and added 36 tests in PR branch: Inf inputs for mean/focal_stats (HIGH Cat2 - no Inf test existed anywhere), mean NaN input (HIGH Cat2 - default excludes=[nan] semantics never asserted), 1x1 + 1xN/Nx1 strips (HIGH Cat3), empty 0-row raster numpy-only (MEDIUM Cat3), mean passes=2 == mean(mean) and excludes sentinel -9999 behavioral tests (MEDIUM Cat4), dask+cupy non-default boundary modes for mean/apply/focal_stats (MEDIUM Cat1/4). Bugs surfaced, filed separately (NOT fixed here): #3219 hotspots silently returns all zeros on Inf input (nan global std passes the std==0 guard, all 4 backends); #3225 empty raster works on numpy but crashes cupy (raw CudaAPIError) and dask (map_overlap depth ValueError). hotspots+Inf and non-numpy empty behavior left unpinned until those are fixed. Backend matrix for the 4 public funcs was already solid (all 4 backends + parity); boundary modes covered except dask+cupy. Siblings filed #3214-3217 same day (dtype/docstring/apply-default-func) - no overlap."
|
|
9
11
|
geotiff,2026-06-12,3266,MEDIUM,1,"Pass 22 (2026-06-12, deep-sweep test-coverage): delta audit of the ~20 commits since pass 21 (06-09..06-12, mostly pack/unpack fixes + #3241 GPU streaming writer + coregister #3254/#3248). Filed #3266 (tests). Cat 1 MEDIUM: pack=True gained working gpu/dask+gpu support in #3240, but three pack features were tested numpy+dask only: float32 width preservation (#3080, test_pack_float_width_3080.py), nodata kwarg fill (#3168, test_pack_nodata_kwarg_3168.py), band-subset per-band SCALE/OFFSET rewrite (#3161, test_pack_band_subset_3161.py). Live probe on this CUDA host: all six gpu/dask+gpu legs pass today (no source bug, pure coverage gap). Added one gpu/dask-gpu parametrized round-trip test per file (6 tests, requires_gpu, RUN+passing locally) and fixed two stale docstrings claiming unpack/pack is CPU-only (wrong since #3075/#3240). Verified NOT gaps this pass: #3128 int64 sentinel tests cover eager+dask+gpu; #3241 streaming writer landed with byte-identical band-first/band-last/BytesIO/small-buffer tests; #3104 scale-zero rejection has gpu legs; #3169 revived the dead compression-corpus oracle gate. Out of scope: coregister=True lives in accessor.py (excluded module); its multi-band + polar gaps are documented as experimental caveats in docs/source/reference/geotiff.rst (#3248). LOW (carried, documented not fixed): Inf as the declared nodata sentinel never tested. || PREVIOUS: Pass 21 (2026-06-09, deep-sweep test-coverage): filed #3114 (tests) + #3112 (source bug). Cat 1 HIGH: to_geotiff(pack=True) round-trip was tested only on numpy and dask+numpy (write/test_pack_3064.py); #3075 made unpack=True work on gpu and dask+gpu reads, but no test packed a GPU-read array back. Live probe on this CUDA host: BOTH GPU legs crash today -- eager gpu raises AttributeError (cupy has no astype, the known cupy 13.6/xarray 2025.12 where/astype incompat) and dask+gpu raises TypeError (numpy fill value inside cupy.where) -- both from _pack's out.fillna(nodata) in _attrs.py; _writers/gpu.py says the pre-dispatch re-pack is supposed to make every write path work. Source bug filed as #3112; test-only PR adds test_pack_round_trip_gpu (gpu + dask-gpu params, requires_gpu, xfail(strict=True) on #3112 so the fix flips them loudly) and fixes the stale module docstring claiming GPU rejects mask_and_scale. Ran on CUDA host: 13 passed, 2 xfailed. Verified NOT gaps this pass (probed before flagging): empty/zero-band writer guard is covered (test_basic.py 2075/2095 blocks incl. gpu + dask + streaming entry points); degenerate shapes covered on all 4 read backends (read/test_degenerate_shapes.py); overview_resampling all 7 modes parametrized; missing_sources raise/warn + invalid, band_nodata first/invalid, unpack on all 4 backends, masked/parse_coordinates/lock/cache/default_name/name-deprecation all exercised; attrs contract per-backend (attrs/test_contract.py). LOW (documented, not fixed): Inf as the declared nodata sentinel is never tested (only one nan+inf data round-trip in test_edge_cases.py). || PREVIOUS: Pass 20 (2026-06-06, deep-sweep test-coverage): filed #2984 and added test_writer.py degenerate-shape GPU write coverage (Cat 1 backend + Cat 3 geometric edge). Read side already covers 1x1/1xN/Nx1 on all 4 backends (read/test_degenerate_shapes.py) and the dask streaming writer covers them (integration/test_dask_pipeline.py); the GPU write path was the gap (smallest shape in gpu/test_writer.py was 2x2). Added test_write_geotiff_gpu_degenerate_round_trip (1x1/1xN/Nx1 x none/deflate) + test_to_geotiff_dask_gpu_degenerate_round_trip (dask+cupy via gpu=True). 9 new tests RUN+passing on a CUDA host. Verified paths work first (not a source bug); transform supplied explicitly via attrs. Wider tree audit (~92k test LOC vs ~33k source): rioxarray-compat (#2961), bbox NaN/Inf/rotated, 8-backend parity matrix, codec round-trips already covered -- no other real gaps. | Pass (2026-06-05 test-coverage sweep): mature module (~31k src / ~124k test LOC, 9 test dirs). Exhaustive existing coverage -- parity/test_backend_matrix.py runs all 4 backends + VRT + HTTP + fsspec; golden_corpus full-manifest parity; read_rioxarray_compat_2961 covers masked/mask_and_scale/parse_coordinates/default_name on eager+dask. Cat1+Cat3 gap found (MEDIUM): degenerate-shape READS (1x1/1xN/Nx1) were tested only on the eager numpy reader (test_edge_cases.py) and the dask streaming WRITE path (integration/test_dask_pipeline.py); the windowed dask READ (chunks=) and GPU READ (gpu=True) on a single-pixel dimension were never exercised (smallest dask-read source in read/test_tiling is 8x8/2x32, parity fixtures 32x32/64x64). Probed: paths work today, no source bug -- pure coverage gap. Added read/test_degenerate_shapes.py (18 tests): dask read x{chunks 1,3,4} x{1x1,1xN,Nx1} + coord/transform/crs parity + GPU read + dask+gpu read. GPU cells RAN and PASSED on this CUDA host (grid-size-1 launch validated). Fixture supplies explicit attrs['transform'] (writer cannot infer pixel size from a 1-element coord axis). Branch deep-sweep-test-coverage-geotiff-degenerate-read-01. NOTE: pre-existing union-merge CRLF/duplicate-record corruption in this CSV left untouched -- appended one clean record; DictReader last-write-wins picks this one."
|
|
10
12
|
idw,2026-06-04,2919,HIGH,1;4,"cupy/dask+cupy backends untested (Cat1 HIGH); GPU k-reject error path untested (Cat4 MED). Added 6 GPU tests, validated on CUDA host. Inf-in-points (Cat2) and attrs-preservation (Cat5) are LOW, documented not fixed."
|
|
@@ -14,6 +16,7 @@ interpolate_spline,2026-06-04,,HIGH,1;3;5,scope=spline-only; cupy+dask_cupy spli
|
|
|
14
16
|
mcda,2026-06-10,3149,HIGH,1;2;5,"Pass 1 (2026-06-10, deep-sweep test-coverage): test_mcda.py had 175 tests, all numpy or dask+numpy -- zero cupy/dask+cupy coverage despite explicit cupy branches in standardize._get_xp and combine._sort_descending (Cat 1 HIGH). Filed #3149, added ~70 tests: cross-backend parity for standardize (7 methods) x cupy/dask+numpy/dask+cupy, combine (wlc/wpm/fuzzy and-or-sum-product-gamma/owa) x 3 backends, constrain, boolean_overlay, sensitivity OAT+MC on GPU backends; metadata preservation (attrs/coords/dims/name) for every stage (Cat 5 MEDIUM); wpm all-NaN criterion + Inf propagation through wlc/fuzzy-and (Cat 2 MEDIUM). All RUN on a CUDA host: 233 passed, 11 xfailed. Probing surfaced real source bugs already filed by sibling sweeps as #3146 (owa raises on ALL dask backends -- _sort_descending calls nonexistent da.sort; owa cupy mixes numpy order weights into cupy stack; piecewise standardize broken on cupy + dask+cupy and categorical on dask+cupy via np.asarray on cupy chunks; monte_carlo sensitivity reads .values on cupy data) and #3147 (constrain drops attrs when masks applied) -- those paths pinned with strict xfail markers to flip on fix; constrain cupy/dask+cupy xfail(strict=False) on the known cupy 13.6 + xarray xr.where dependency incompat, not an mcda bug. Source untouched (test-only PR). LOW (documented, not fixed): name= output parameter untested across combine functions; empty (0-row) raster untested -- elementwise ops, judged low value. weights.py (ahp/rank) is pure-numpy metadata, backend matrix N/A, already well covered."
|
|
15
17
|
morphology,2026-06-20,3404,MEDIUM,2;3,"Added Inf/-Inf, all-NaN, Nx1/1xN strip, integer-dtype tests; source already correct, regression guards only; cupy + dask+cupy ran on GPU host"
|
|
16
18
|
multispectral,2026-06-20,3431,MEDIUM,2;3;4,true_color NaN/alpha + all-equal range_val==0 + nondefault nodata/c/th; evi & savi validation error paths; GPU tests ran (cupy+dask+cupy)
|
|
19
|
+
perlin,2026-06-23,,HIGH,3;4;5,"added tests: seed/freq/name params, single-row, 1x1+Nx1 degenerate (pins all-NaN bug), dims+attrs preserve, coords-drop (pins bug); GPU tests ran on CUDA host; 2 source bugs surfaced (coords dropped; 1x1/Nx1 all-NaN ptp div0) need issues filed (gh issue create blocked by auto-mode)"
|
|
17
20
|
polygon_clip,2026-06-10,3197,MEDIUM,1;2;3;5,"deep-sweep test-coverage 2026-06-10 on a CUDA host. Existing file covered numpy well + one parity test per dask/cupy/dask+cupy backend. Filed #3197 (test-only) and added 13 tests: Cat1 GPU param/NaN coverage (cupy + dask+cupy each get custom nodata, all_touched=True, and NaN-input preservation vs numpy; previously only crop=False inner polygon ran on GPU); Cat2 Inf/-Inf preserved, all-NaN input -> all-NaN, int32 + sentinel nodata=-1; Cat3 Nx1 + 1xN strip rasters; Cat5 coords preserved (crop=False) + crop coords are a contiguous subset of input coords (crop=True). All 13 RAN+PASSED on GPU (6 GPU tests not skipped); full file 36 passed 0 skipped. LOW (documented, NOT fixed): rasterize_kw forwarding never tested; non-square cellsize never tested. SOURCE NOTE (out of scope, not filed): clip_polygon docstring says 'named y and x dims' but rasterize() hard-requires literal y/x, so lat/lon-dim rasters raise -- dim-name preservation (Cat5) is therefore unsupported by contract, not a test gap. SOURCE NOTE 2: polygon_clip.py:216 still passes rasterize(use_cuda=True) on dask+cupy (renamed to gpu= in #3089); harmless deprecation alias today, candidate for an api-consistency follow-up."
|
|
18
21
|
polygonize,2026-06-12,3299,MEDIUM,1,"Pass 4 (2026-06-12): added test_polygonize_mask_chunk_mismatch_3299.py (25 tests, all passing on a CUDA host incl. dask+cupy). Closes Cat 1 MEDIUM: the _polygonize_dask mask-rechunk branch (mask_data.chunks != dask_data.chunks -> rechunk) was never exercised; every prior dask masked test used mask chunks identical to the raster's. Mismatched layouts pinned against same-backend aligned-mask reference: (6,7) same-grid-shape misalignment (the silent-corruption layout for int rasters), single-chunk (15,18), more-blocks (4,5); int+float rasters, connectivity 4/8, dask+numpy and dask+cupy; plus exact-geometry single-masked-pixel hole anchor. Mutation (delete the rechunk guard) flips all 25 red; clean md5 restore. Full polygonize suite 486 passed / 16 skipped. Test-only; source untouched. Issue #3299. Audit re-confirmed Cat 2/3/4 closed by passes 1-3 and post-2026-05-29 changes (#2913 float-mask fix flipped prior xfails, #3041 has issue-2677 test file, #2673/#2817 covered by batch-invariance and heap tests); Cat 5 N/A (no DataArray output; CRS/transform propagation already tested). | Pass 3 (2026-05-29): added test_polygonize_mask_dtype_coverage_2026_05_29.py (41 passed, 8 xfailed on a CUDA host). Closes Cat 4 MEDIUM parameter-coverage gap: mask= is documented to accept bool/integer/float values but every prior test passed only a bool mask. Integer masks (int32/int64) now pinned against the same-backend bool-mask output on all four backends x both raster dtypes x connectivity 4/8; float-mask-on-integer-raster also pinned. Each backend is compared to its OWN bool reference to isolate mask-dtype from the unrelated numpy-vs-dask hole-vs-single-ring representation difference. Mutation (drop the not-mask[ij] exclusion in _calculate_regions) flips 11 tests red incl. the pixel-exclusion sanity anchor; clean md5 restore. Surfaced source bug #2623: a float-dtype mask on a float-dtype raster raises TypeError at polygonize.py:918 (mask & nan_mask; bitwise_and undefined for float&bool; cupy/dask route floats through _polygonize_numpy so they crash too; int masks coerce fine). 8 float-mask cases marked xfail(strict, raises=TypeError) referencing #2623. Test-only; source untouched. | Pass 2 (2026-05-27): added test_polygonize_atol_rtol_backend_coverage_2026_05_27.py with 15 tests, all passing on a CUDA host. Closes Cat 4 MEDIUM parameter-coverage gap on atol/rtol forwarding through the cupy and dask+cupy backends. atol/rtol were exposed by #2173 / #2194 and thread through _polygonize_cupy (polygonize.py:808) and _polygonize_dask (polygonize.py:1719); the dask path further plumbs them into dask.delayed(_polygonize_chunk)(...) at lines 1748-1754 and into _bucket_key_for_value for cross-chunk merge bucketing at lines 1757-1758. Pre-existing tests covered non-default atol/rtol only on numpy and dask+numpy. The cupy and dask+cupy dispatchers were untested -- a regression dropping the kwargs there would silently change the float polygon count and would not be caught. Same dispatcher-silently-drops-kwarg pattern fixed by #1561 / #1605 / #1685 / #1810 / #1974 on adjacent GeoTIFF surfaces. 15 tests: cupy strict-equality + default-tolerance pin on _REPRO_2173, dask+cupy strict-equality single-chunk + multi-chunk (engages cross-chunk merge bucket) + default-tolerance multi-chunk pin, cupy intermediate-atol small/large pair, dask+cupy intermediate-atol single/multi-chunk small + single-chunk large, cupy integer atol-ignored matrix, dask+cupy integer atol-ignored single-chunk + multi-chunk, cupy rtol-only large/small matrix. Mutation against _polygonize_cupy float branch (drop atol/rtol kwargs in the _polygonize_numpy forward call at polygonize.py:823-825) flips 3 of 5 cupy tests red; mutation against dask.delayed(_polygonize_chunk)(...) at polygonize.py:1748-1754 (drop atol, rtol args) flips 2 of 6 dask+cupy tests red. Confirmed clean restore via md5sum. Source untouched. Filed issue #2537 (test-only). Cat 4 MEDIUM (parameter coverage on cupy + dask+cupy atol/rtol forwarding). Pass 1 (2026-05-19): added test_polygonize_coverage_2026_05_19.py with 58 tests, all passing on a CUDA host. Closes Cat 3 HIGH 1x1 / Nx1 single-column geometric gaps (Nx1 exercises the nx==1 padding path at polygonize.py:565 and the cupy nx==1 numpy-fallback at polygonize.py:671), Cat 3 MEDIUM 1xN single-row and all-equal-value rasters on all four backends. Closes Cat 2 HIGH NaN parity for cupy + dask+cupy (numpy/dask were already covered by test_polygonize_nan_pixels_excluded*), Cat 2 MEDIUM all-NaN raster on all four backends, Cat 2 HIGH +/-Inf pins on all four backends. Filed source-bug issue #2155: numpy/dask/dask+cupy backends silently absorb Inf cells into adjacent finite polygons because _is_close reduces abs(inf-inf) to nan; cupy backend handles Inf correctly. Pins lock the asymmetric behaviour so the fix is visible. Closes Cat 1 MEDIUM simplify_tolerance + mask= parity gaps on dask+cupy backend (numpy/cupy/dask were already covered). Closes Cat 4 MEDIUM column_name non-default value across geopandas/spatialpandas/geojson return types and Cat 4 MEDIUM validation error paths (bad connectivity, bad transform length, mask shape mismatch, mask underlying-type mismatch). Cat 5 N/A: polygonize returns lists/dataframes, not a DataArray with attrs to propagate."
|
|
19
22
|
proximity,2026-06-18,2692;3139,MEDIUM,1;4,"Pass 4 (2026-06-18, deep-sweep test-coverage): 1 MEDIUM, 1 LOW. MEDIUM (Cat 4/Cat 1): all three public funcs are @supports_dataset and document Dataset-in/Dataset-out, but no test ever passed a Dataset; the shared decorator is covered generically in test_dataset_support.py which never lists proximity/allocation/direction, so per-variable _process dispatch + attrs/coords round-trip + result.name=None reset were unpinned. Added test_dataset_input_processes_each_variable (3 funcs x 4 backends, 12 tests); numpy+dask+cupy+dask+cupy all RUN and PASS on this CUDA host, expected built from numpy baseline to avoid implicit cupy host conversion. Verified working first -- no source bug, source untouched. Full file 528 passed. LOW (documented, not fixed): public exports euclidean_distance / manhattan_distance have no direct unit test (only great_circle_distance does); both are trivial pure fns exercised indirectly through proximity. || Pass 3 (2026-06-09, deep-sweep test-coverage): module grew since Pass 2 (#2807 metric validation, #2812 GREAT_CIRCLE brute force, #2850/#2851 input validation, #2854/#2908 halo fixes, tie-break routing) and each landed with its own tests; Pass 2's stale LOW (invalid distance_metric fallback) is FIXED and tested (#2807). Found 3 MEDIUM gaps, filed #3139, added 40 tests (all RUN and PASS on a CUDA host; full file 450 passed): (1) Cat 2 integer-dtype raster untested on any backend -- bounded dask pads int arrays with boundary=np.nan which casts to INT_MIN phantom targets, only neutralized because the coordinate-grid pads are real NaNs; pinned int32 x 3 funcs x 4 backends x bounded/unbounded vs float64 numpy baseline + explicit target_values; (2) Cat 1 bounded dask+cupy (_process_dask_cupy) only ever ran EUCLIDEAN; pinned MANHATTAN+GREAT_CIRCLE x 3 funcs with a routing spy; mutation (pad=0) flips all 6 red, clean md5 restore; (3) Cat 3 empty 0-row/0-col raster unpinned; fails fast with IndexError, pinned raises. All behaviors verified correct before tests were added -- no source bug, source untouched. LOW (documented, not fixed): -inf pixel input never tested (+inf is; isfinite is symmetric). || Pass 2 (2026-06-02): added 18 tests to test_proximity.py closing the two MEDIUM gaps Pass 1 left open, all RUN and passing on a CUDA host across numpy/cupy/dask+numpy/dask+cupy (15 cross-backend + 3 error-path). Source untouched. Cat 4 MEDIUM (error path): _process raises ValueError when raster.dims != (y, x) (proximity.py:1043) but no test exercised the swapped x/y guard; test_wrong_dim_order_raises pins it for proximity/allocation/direction. Cat 2 MEDIUM (all-NaN input): Pass 1 noted all-NaN/all-zero on eager numpy+cupy was unpinned; test_all_nan_raster_all_nan_output pins an all-NaN 6x6 raster -> all-NaN float32 output on all four backends x three functions. Remaining LOW (documented): invalid distance_metric string silently falls back to EUCLIDEAN (proximity.py:1049-1051). || PREVIOUS: Pass 1 (2026-05-29): added 65 tests to test_proximity.py closing three coverage gaps, all RUN and passing on a CUDA host (numpy/cupy/dask+numpy/dask+cupy). Issue #2692, PR opened. Source untouched. Cat 3 HIGH: degenerate raster shapes (1x1 single pixel, Nx1 column strip, 1xN row strip) had zero coverage for proximity/allocation/direction on any backend; they stress the line-sweep kernel boundaries (_process_proximity_line) and the GPU brute-force kernel grid sizing (_proximity_cuda_kernel via cuda_args). Pinned all three shapes x three functions x four backends against hand-checked expected values; mutation of a pinned direction expectation confirms teeth. Cat 1/4 HIGH: allocation and direction only ran EUCLIDEAN across backends; MANHATTAN and GREAT_CIRCLE were cross-backend-tested for proximity only. Pinned both metrics x two functions x four backends against the numpy baseline (all match). Cat 5 MEDIUM: no test set non-empty res/crs attrs so the attrs-preservation assertion in general_output_checks compared two empty dicts. proximity reads attrs['res'] via get_dataarray_resolution for bounded-dask chunk padding, so added attrs round-trip tests on four backends plus a bounded-dask test where a res attr matching the coordinate spacing must equal the numpy baseline. A res attr that lies about the spacing mis-sizes the map_overlap depth; source fragility, not a test gap, left for a separate accuracy issue. Cat 2 (NaN/Inf input) already covered by the shared test_raster fixture (embeds np.inf and np.nan, runs on four backends). Remaining LOW: all-NaN / all-zero input on eager numpy+cupy not directly pinned."
|
|
@@ -2,6 +2,33 @@
|
|
|
2
2
|
-----------
|
|
3
3
|
|
|
4
4
|
|
|
5
|
+
### Version 0.10.12 - 2026-06-25
|
|
6
|
+
|
|
7
|
+
#### New features
|
|
8
|
+
- templates: add from_template() for empty study-area DataArrays over common regions (#3484) (#3487)
|
|
9
|
+
- accessor: add .xrs.validate() to check a raster against the xarray-spatial contract (#3486)
|
|
10
|
+
- accessor: add a categorized repr to the .xrs accessor (#3476) (#3477)
|
|
11
|
+
- accessor: forward per-tool repr to the accessed tool (#3478) (#3479)
|
|
12
|
+
- interpolation: accept GeoDataFrames and expose on the .xrs accessor with coregister (#3481)
|
|
13
|
+
- rasterize: support string/categorical columns with QGIS-visible labels (#3483)
|
|
14
|
+
|
|
15
|
+
#### Bug fixes and improvements
|
|
16
|
+
- proximity: fix EUCLIDEAN proximity/allocation/direction dropping targets at exact max_distance (#3443)
|
|
17
|
+
- perlin: preserve input x/y coordinates on the output (#3470)
|
|
18
|
+
- perlin: preserve input dtype on the dask backends (#3471)
|
|
19
|
+
- perlin: fix dask OOM by dropping a redundant dask.persist (#3469) (#3473)
|
|
20
|
+
- perlin: document the name parameter in the docstring (#3468)
|
|
21
|
+
- perlin: document name param, float-dtype requirement, and ValueError (#3467)
|
|
22
|
+
- perlin: drop unused not_implemented_func import, fix isort wrap (#3466)
|
|
23
|
+
- perlin: add test coverage for params, degenerate shapes, and metadata (#3472)
|
|
24
|
+
- perlin: fix stale test_perlin coords assertion after coords preservation (#3489)
|
|
25
|
+
- generate_terrain: preserve caller coords/res/crs (#3474) (#3475)
|
|
26
|
+
- least_cost_corridor: propagate friction geo-attrs (#3446) (#3449)
|
|
27
|
+
- corridor: validate matching shapes for precomputed surfaces (#3447)
|
|
28
|
+
- corridor: add strip, cross-backend, param, and metadata test coverage (#3448)
|
|
29
|
+
- fire: add test coverage for dask+cupy dispatch and metadata preservation (#3444)
|
|
30
|
+
|
|
31
|
+
|
|
5
32
|
### Version 0.10.11 - 2026-06-21
|
|
6
33
|
|
|
7
34
|
#### Bug fixes and improvements
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: xarray-spatial
|
|
3
|
-
Version: 0.10.
|
|
3
|
+
Version: 0.10.12
|
|
4
4
|
Summary: xarray-based spatial analysis tools
|
|
5
5
|
Home-page: https://github.com/xarray-contrib/xarray-spatial
|
|
6
6
|
Author: Xarray-Spatial Developers
|
|
@@ -225,7 +225,7 @@ Each cell shows the **feature tier** for that function on that backend (see [iss
|
|
|
225
225
|
|
|
226
226
|
✅ stable · 🔼 advanced · 🧪 experimental · 🔧 internal · 🚫 unsupported
|
|
227
227
|
|
|
228
|
-
[GeoTIFF / COG I/O](#geotiff--cog-io) · [Classification](#classification) · [Diffusion](#diffusion) · [Focal](#focal) · [Morphological](#morphological) · [Fire](#fire) · [Multispectral](#multispectral) · [Multivariate](#multivariate) · [MCDA](#multi-criteria-decision-analysis-mcda) · [Pathfinding](#pathfinding) · [Proximity](#proximity) · [Reproject / Merge](#reproject--merge) · [Raster / Vector Conversion](#raster--vector-conversion) · [Surface](#surface) · [Hydrology](#hydrology) · [Flood](#flood) · [Interpolation](#interpolation) · [Dasymetric](#dasymetric) · [Zonal](#zonal) · [Utilities](#utilities)
|
|
228
|
+
[GeoTIFF / COG I/O](#geotiff--cog-io) · [Classification](#classification) · [Diffusion](#diffusion) · [Focal](#focal) · [Morphological](#morphological) · [Fire](#fire) · [Multispectral](#multispectral) · [Multivariate](#multivariate) · [MCDA](#multi-criteria-decision-analysis-mcda) · [Pathfinding](#pathfinding) · [Proximity](#proximity) · [Reproject / Merge](#reproject--merge) · [Raster / Vector Conversion](#raster--vector-conversion) · [Surface](#surface) · [Hydrology](#hydrology) · [Flood](#flood) · [Interpolation](#interpolation) · [Dasymetric](#dasymetric) · [Zonal](#zonal) · [Templates](#templates) · [Utilities](#utilities)
|
|
229
229
|
|
|
230
230
|
-------
|
|
231
231
|
### **GeoTIFF / COG I/O**
|
|
@@ -341,6 +341,15 @@ Built-in Numba JIT and CUDA projection kernels bypass pyproj for per-pixel coord
|
|
|
341
341
|
| [rechunk_no_shuffle](xrspatial/utils.py) | Rechunk dask arrays using whole-chunk multiples (no shuffle) | Custom | 🔼 | 🔼 | 🔼 | 🔼 |
|
|
342
342
|
| [fused_overlap](xrspatial/utils.py) | Fuse sequential map_overlap calls into a single pass | Custom | 🔼 | 🔼 | 🔼 | 🔼 |
|
|
343
343
|
| [multi_overlap](xrspatial/utils.py) | Run multi-output kernel in a single overlap pass | Custom | 🔼 | 🔼 | 🔼 | 🔼 |
|
|
344
|
+
| [validate](xrspatial/validate.py) | Check a raster against the xarray-spatial input contract (`.xrs.validate()`) | Custom | ✅ | 🔼 | 🔼 | 🔼 |
|
|
345
|
+
|
|
346
|
+
-----------
|
|
347
|
+
|
|
348
|
+
### **Templates**
|
|
349
|
+
|
|
350
|
+
| Name | Description | Source | NumPy xr.DataArray | Dask xr.DataArray | CuPy GPU xr.DataArray | Dask GPU xr.DataArray |
|
|
351
|
+
|:----------:|:------------|:------:|:----------------------:|:--------------------:|:-------------------:|:------:|
|
|
352
|
+
| [from_template](xrspatial/templates.py) | Empty study-area grid for a named region (CONUS, NYC, ...) or country code; `preserve='area'/'shape'` picks an EPSG projection by property | Custom | ✅ | 🔼 | 🔼 | 🔼 |
|
|
344
353
|
|
|
345
354
|
-----------
|
|
346
355
|
|
|
@@ -520,9 +529,9 @@ For a broader catalog of spectral indices and sensor-specific band combinations,
|
|
|
520
529
|
|
|
521
530
|
| Name | Description | Source | NumPy xr.DataArray | Dask xr.DataArray | CuPy GPU xr.DataArray | Dask GPU xr.DataArray |
|
|
522
531
|
|:----------:|:------------|:------:|:----------------------:|:--------------------:|:-------------------:|:------:|
|
|
523
|
-
| [IDW](xrspatial/interpolate/_idw.py) | Inverse Distance Weighting from scattered points to a raster grid | Standard (IDW) | ✅ | 🔼 | 🔼 | 🔼 |
|
|
524
|
-
| [Kriging](xrspatial/interpolate/_kriging.py) | Ordinary Kriging with automatic variogram fitting (spherical, exponential, gaussian) | Standard (ordinary kriging) | 🔼 | 🔼 | 🔼 | 🔼 |
|
|
525
|
-
| [Spline](xrspatial/interpolate/_spline.py) | Thin Plate Spline interpolation with optional smoothing | Standard (TPS) | 🔼 | 🔼 | 🔼 | 🔼 |
|
|
532
|
+
| [IDW](xrspatial/interpolate/_idw.py) | Inverse Distance Weighting from scattered points (arrays or a GeoDataFrame) to a raster grid | Standard (IDW) | ✅ | 🔼 | 🔼 | 🔼 |
|
|
533
|
+
| [Kriging](xrspatial/interpolate/_kriging.py) | Ordinary Kriging with automatic variogram fitting (spherical, exponential, gaussian); accepts arrays or a GeoDataFrame | Standard (ordinary kriging) | 🔼 | 🔼 | 🔼 | 🔼 |
|
|
534
|
+
| [Spline](xrspatial/interpolate/_spline.py) | Thin Plate Spline interpolation with optional smoothing; accepts arrays or a GeoDataFrame | Standard (TPS) | 🔼 | 🔼 | 🔼 | 🔼 |
|
|
526
535
|
|
|
527
536
|
-----------
|
|
528
537
|
|
|
@@ -569,7 +578,7 @@ For a broader catalog of spectral indices and sensor-specific band combinations,
|
|
|
569
578
|
|
|
570
579
|
| Name | Description | Source | NumPy xr.DataArray | Dask xr.DataArray | CuPy GPU xr.DataArray | Dask GPU xr.DataArray |
|
|
571
580
|
|:-----|:------------|:------:|:------------------:|:-----------------:|:---------------------:|:---------------------:|
|
|
572
|
-
| [KDE](xrspatial/kde.py) | Point-to-raster kernel density estimation (Gaussian, Epanechnikov, quartic) | Silverman 1986 | 🔼 | 🔼 | 🔼 | 🔼 |
|
|
581
|
+
| [KDE](xrspatial/kde.py) | Point-to-raster kernel density estimation (Gaussian, Epanechnikov, quartic); accepts arrays or a GeoDataFrame | Silverman 1986 | 🔼 | 🔼 | 🔼 | 🔼 |
|
|
573
582
|
| [Line Density](xrspatial/kde.py) | Line-segment-to-raster density estimation | Standard | 🔼 | | | |
|
|
574
583
|
|
|
575
584
|
--------
|
|
@@ -150,7 +150,7 @@ Each cell shows the **feature tier** for that function on that backend (see [iss
|
|
|
150
150
|
|
|
151
151
|
✅ stable · 🔼 advanced · 🧪 experimental · 🔧 internal · 🚫 unsupported
|
|
152
152
|
|
|
153
|
-
[GeoTIFF / COG I/O](#geotiff--cog-io) · [Classification](#classification) · [Diffusion](#diffusion) · [Focal](#focal) · [Morphological](#morphological) · [Fire](#fire) · [Multispectral](#multispectral) · [Multivariate](#multivariate) · [MCDA](#multi-criteria-decision-analysis-mcda) · [Pathfinding](#pathfinding) · [Proximity](#proximity) · [Reproject / Merge](#reproject--merge) · [Raster / Vector Conversion](#raster--vector-conversion) · [Surface](#surface) · [Hydrology](#hydrology) · [Flood](#flood) · [Interpolation](#interpolation) · [Dasymetric](#dasymetric) · [Zonal](#zonal) · [Utilities](#utilities)
|
|
153
|
+
[GeoTIFF / COG I/O](#geotiff--cog-io) · [Classification](#classification) · [Diffusion](#diffusion) · [Focal](#focal) · [Morphological](#morphological) · [Fire](#fire) · [Multispectral](#multispectral) · [Multivariate](#multivariate) · [MCDA](#multi-criteria-decision-analysis-mcda) · [Pathfinding](#pathfinding) · [Proximity](#proximity) · [Reproject / Merge](#reproject--merge) · [Raster / Vector Conversion](#raster--vector-conversion) · [Surface](#surface) · [Hydrology](#hydrology) · [Flood](#flood) · [Interpolation](#interpolation) · [Dasymetric](#dasymetric) · [Zonal](#zonal) · [Templates](#templates) · [Utilities](#utilities)
|
|
154
154
|
|
|
155
155
|
-------
|
|
156
156
|
### **GeoTIFF / COG I/O**
|
|
@@ -266,6 +266,15 @@ Built-in Numba JIT and CUDA projection kernels bypass pyproj for per-pixel coord
|
|
|
266
266
|
| [rechunk_no_shuffle](xrspatial/utils.py) | Rechunk dask arrays using whole-chunk multiples (no shuffle) | Custom | 🔼 | 🔼 | 🔼 | 🔼 |
|
|
267
267
|
| [fused_overlap](xrspatial/utils.py) | Fuse sequential map_overlap calls into a single pass | Custom | 🔼 | 🔼 | 🔼 | 🔼 |
|
|
268
268
|
| [multi_overlap](xrspatial/utils.py) | Run multi-output kernel in a single overlap pass | Custom | 🔼 | 🔼 | 🔼 | 🔼 |
|
|
269
|
+
| [validate](xrspatial/validate.py) | Check a raster against the xarray-spatial input contract (`.xrs.validate()`) | Custom | ✅ | 🔼 | 🔼 | 🔼 |
|
|
270
|
+
|
|
271
|
+
-----------
|
|
272
|
+
|
|
273
|
+
### **Templates**
|
|
274
|
+
|
|
275
|
+
| Name | Description | Source | NumPy xr.DataArray | Dask xr.DataArray | CuPy GPU xr.DataArray | Dask GPU xr.DataArray |
|
|
276
|
+
|:----------:|:------------|:------:|:----------------------:|:--------------------:|:-------------------:|:------:|
|
|
277
|
+
| [from_template](xrspatial/templates.py) | Empty study-area grid for a named region (CONUS, NYC, ...) or country code; `preserve='area'/'shape'` picks an EPSG projection by property | Custom | ✅ | 🔼 | 🔼 | 🔼 |
|
|
269
278
|
|
|
270
279
|
-----------
|
|
271
280
|
|
|
@@ -445,9 +454,9 @@ For a broader catalog of spectral indices and sensor-specific band combinations,
|
|
|
445
454
|
|
|
446
455
|
| Name | Description | Source | NumPy xr.DataArray | Dask xr.DataArray | CuPy GPU xr.DataArray | Dask GPU xr.DataArray |
|
|
447
456
|
|:----------:|:------------|:------:|:----------------------:|:--------------------:|:-------------------:|:------:|
|
|
448
|
-
| [IDW](xrspatial/interpolate/_idw.py) | Inverse Distance Weighting from scattered points to a raster grid | Standard (IDW) | ✅ | 🔼 | 🔼 | 🔼 |
|
|
449
|
-
| [Kriging](xrspatial/interpolate/_kriging.py) | Ordinary Kriging with automatic variogram fitting (spherical, exponential, gaussian) | Standard (ordinary kriging) | 🔼 | 🔼 | 🔼 | 🔼 |
|
|
450
|
-
| [Spline](xrspatial/interpolate/_spline.py) | Thin Plate Spline interpolation with optional smoothing | Standard (TPS) | 🔼 | 🔼 | 🔼 | 🔼 |
|
|
457
|
+
| [IDW](xrspatial/interpolate/_idw.py) | Inverse Distance Weighting from scattered points (arrays or a GeoDataFrame) to a raster grid | Standard (IDW) | ✅ | 🔼 | 🔼 | 🔼 |
|
|
458
|
+
| [Kriging](xrspatial/interpolate/_kriging.py) | Ordinary Kriging with automatic variogram fitting (spherical, exponential, gaussian); accepts arrays or a GeoDataFrame | Standard (ordinary kriging) | 🔼 | 🔼 | 🔼 | 🔼 |
|
|
459
|
+
| [Spline](xrspatial/interpolate/_spline.py) | Thin Plate Spline interpolation with optional smoothing; accepts arrays or a GeoDataFrame | Standard (TPS) | 🔼 | 🔼 | 🔼 | 🔼 |
|
|
451
460
|
|
|
452
461
|
-----------
|
|
453
462
|
|
|
@@ -494,7 +503,7 @@ For a broader catalog of spectral indices and sensor-specific band combinations,
|
|
|
494
503
|
|
|
495
504
|
| Name | Description | Source | NumPy xr.DataArray | Dask xr.DataArray | CuPy GPU xr.DataArray | Dask GPU xr.DataArray |
|
|
496
505
|
|:-----|:------------|:------:|:------------------:|:-----------------:|:---------------------:|:---------------------:|
|
|
497
|
-
| [KDE](xrspatial/kde.py) | Point-to-raster kernel density estimation (Gaussian, Epanechnikov, quartic) | Silverman 1986 | 🔼 | 🔼 | 🔼 | 🔼 |
|
|
506
|
+
| [KDE](xrspatial/kde.py) | Point-to-raster kernel density estimation (Gaussian, Epanechnikov, quartic); accepts arrays or a GeoDataFrame | Silverman 1986 | 🔼 | 🔼 | 🔼 | 🔼 |
|
|
498
507
|
| [Line Density](xrspatial/kde.py) | Line-segment-to-raster density estimation | Standard | 🔼 | | | |
|
|
499
508
|
|
|
500
509
|
--------
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: xarray-spatial
|
|
3
|
-
Version: 0.10.
|
|
3
|
+
Version: 0.10.12
|
|
4
4
|
Summary: xarray-based spatial analysis tools
|
|
5
5
|
Home-page: https://github.com/xarray-contrib/xarray-spatial
|
|
6
6
|
Author: Xarray-Spatial Developers
|
|
@@ -225,7 +225,7 @@ Each cell shows the **feature tier** for that function on that backend (see [iss
|
|
|
225
225
|
|
|
226
226
|
✅ stable · 🔼 advanced · 🧪 experimental · 🔧 internal · 🚫 unsupported
|
|
227
227
|
|
|
228
|
-
[GeoTIFF / COG I/O](#geotiff--cog-io) · [Classification](#classification) · [Diffusion](#diffusion) · [Focal](#focal) · [Morphological](#morphological) · [Fire](#fire) · [Multispectral](#multispectral) · [Multivariate](#multivariate) · [MCDA](#multi-criteria-decision-analysis-mcda) · [Pathfinding](#pathfinding) · [Proximity](#proximity) · [Reproject / Merge](#reproject--merge) · [Raster / Vector Conversion](#raster--vector-conversion) · [Surface](#surface) · [Hydrology](#hydrology) · [Flood](#flood) · [Interpolation](#interpolation) · [Dasymetric](#dasymetric) · [Zonal](#zonal) · [Utilities](#utilities)
|
|
228
|
+
[GeoTIFF / COG I/O](#geotiff--cog-io) · [Classification](#classification) · [Diffusion](#diffusion) · [Focal](#focal) · [Morphological](#morphological) · [Fire](#fire) · [Multispectral](#multispectral) · [Multivariate](#multivariate) · [MCDA](#multi-criteria-decision-analysis-mcda) · [Pathfinding](#pathfinding) · [Proximity](#proximity) · [Reproject / Merge](#reproject--merge) · [Raster / Vector Conversion](#raster--vector-conversion) · [Surface](#surface) · [Hydrology](#hydrology) · [Flood](#flood) · [Interpolation](#interpolation) · [Dasymetric](#dasymetric) · [Zonal](#zonal) · [Templates](#templates) · [Utilities](#utilities)
|
|
229
229
|
|
|
230
230
|
-------
|
|
231
231
|
### **GeoTIFF / COG I/O**
|
|
@@ -341,6 +341,15 @@ Built-in Numba JIT and CUDA projection kernels bypass pyproj for per-pixel coord
|
|
|
341
341
|
| [rechunk_no_shuffle](xrspatial/utils.py) | Rechunk dask arrays using whole-chunk multiples (no shuffle) | Custom | 🔼 | 🔼 | 🔼 | 🔼 |
|
|
342
342
|
| [fused_overlap](xrspatial/utils.py) | Fuse sequential map_overlap calls into a single pass | Custom | 🔼 | 🔼 | 🔼 | 🔼 |
|
|
343
343
|
| [multi_overlap](xrspatial/utils.py) | Run multi-output kernel in a single overlap pass | Custom | 🔼 | 🔼 | 🔼 | 🔼 |
|
|
344
|
+
| [validate](xrspatial/validate.py) | Check a raster against the xarray-spatial input contract (`.xrs.validate()`) | Custom | ✅ | 🔼 | 🔼 | 🔼 |
|
|
345
|
+
|
|
346
|
+
-----------
|
|
347
|
+
|
|
348
|
+
### **Templates**
|
|
349
|
+
|
|
350
|
+
| Name | Description | Source | NumPy xr.DataArray | Dask xr.DataArray | CuPy GPU xr.DataArray | Dask GPU xr.DataArray |
|
|
351
|
+
|:----------:|:------------|:------:|:----------------------:|:--------------------:|:-------------------:|:------:|
|
|
352
|
+
| [from_template](xrspatial/templates.py) | Empty study-area grid for a named region (CONUS, NYC, ...) or country code; `preserve='area'/'shape'` picks an EPSG projection by property | Custom | ✅ | 🔼 | 🔼 | 🔼 |
|
|
344
353
|
|
|
345
354
|
-----------
|
|
346
355
|
|
|
@@ -520,9 +529,9 @@ For a broader catalog of spectral indices and sensor-specific band combinations,
|
|
|
520
529
|
|
|
521
530
|
| Name | Description | Source | NumPy xr.DataArray | Dask xr.DataArray | CuPy GPU xr.DataArray | Dask GPU xr.DataArray |
|
|
522
531
|
|:----------:|:------------|:------:|:----------------------:|:--------------------:|:-------------------:|:------:|
|
|
523
|
-
| [IDW](xrspatial/interpolate/_idw.py) | Inverse Distance Weighting from scattered points to a raster grid | Standard (IDW) | ✅ | 🔼 | 🔼 | 🔼 |
|
|
524
|
-
| [Kriging](xrspatial/interpolate/_kriging.py) | Ordinary Kriging with automatic variogram fitting (spherical, exponential, gaussian) | Standard (ordinary kriging) | 🔼 | 🔼 | 🔼 | 🔼 |
|
|
525
|
-
| [Spline](xrspatial/interpolate/_spline.py) | Thin Plate Spline interpolation with optional smoothing | Standard (TPS) | 🔼 | 🔼 | 🔼 | 🔼 |
|
|
532
|
+
| [IDW](xrspatial/interpolate/_idw.py) | Inverse Distance Weighting from scattered points (arrays or a GeoDataFrame) to a raster grid | Standard (IDW) | ✅ | 🔼 | 🔼 | 🔼 |
|
|
533
|
+
| [Kriging](xrspatial/interpolate/_kriging.py) | Ordinary Kriging with automatic variogram fitting (spherical, exponential, gaussian); accepts arrays or a GeoDataFrame | Standard (ordinary kriging) | 🔼 | 🔼 | 🔼 | 🔼 |
|
|
534
|
+
| [Spline](xrspatial/interpolate/_spline.py) | Thin Plate Spline interpolation with optional smoothing; accepts arrays or a GeoDataFrame | Standard (TPS) | 🔼 | 🔼 | 🔼 | 🔼 |
|
|
526
535
|
|
|
527
536
|
-----------
|
|
528
537
|
|
|
@@ -569,7 +578,7 @@ For a broader catalog of spectral indices and sensor-specific band combinations,
|
|
|
569
578
|
|
|
570
579
|
| Name | Description | Source | NumPy xr.DataArray | Dask xr.DataArray | CuPy GPU xr.DataArray | Dask GPU xr.DataArray |
|
|
571
580
|
|:-----|:------------|:------:|:------------------:|:-----------------:|:---------------------:|:---------------------:|
|
|
572
|
-
| [KDE](xrspatial/kde.py) | Point-to-raster kernel density estimation (Gaussian, Epanechnikov, quartic) | Silverman 1986 | 🔼 | 🔼 | 🔼 | 🔼 |
|
|
581
|
+
| [KDE](xrspatial/kde.py) | Point-to-raster kernel density estimation (Gaussian, Epanechnikov, quartic); accepts arrays or a GeoDataFrame | Silverman 1986 | 🔼 | 🔼 | 🔼 | 🔼 |
|
|
573
582
|
| [Line Density](xrspatial/kde.py) | Line-segment-to-raster density estimation | Standard | 🔼 | | | |
|
|
574
583
|
|
|
575
584
|
--------
|
|
@@ -19,6 +19,7 @@ setup.cfg
|
|
|
19
19
|
setup.py
|
|
20
20
|
.claude/sweep-accuracy-state.csv
|
|
21
21
|
.claude/sweep-api-consistency-state.csv
|
|
22
|
+
.claude/sweep-documentation-state.csv
|
|
22
23
|
.claude/sweep-metadata-state.csv
|
|
23
24
|
.claude/sweep-performance-state.csv
|
|
24
25
|
.claude/sweep-security-state.csv
|
|
@@ -58,9 +59,12 @@ xarray_spatial.egg-info/dependency_links.txt
|
|
|
58
59
|
xarray_spatial.egg-info/entry_points.txt
|
|
59
60
|
xarray_spatial.egg-info/not-zip-safe
|
|
60
61
|
xarray_spatial.egg-info/requires.txt
|
|
62
|
+
xarray_spatial.egg-info/scm_file_list.json
|
|
63
|
+
xarray_spatial.egg-info/scm_version.json
|
|
61
64
|
xarray_spatial.egg-info/top_level.txt
|
|
62
65
|
xrspatial/__init__.py
|
|
63
66
|
xrspatial/__main__.py
|
|
67
|
+
xrspatial/_template_data.py
|
|
64
68
|
xrspatial/_version.py
|
|
65
69
|
xrspatial/accessor.py
|
|
66
70
|
xrspatial/analytics.py
|
|
@@ -104,9 +108,11 @@ xrspatial/sieve.py
|
|
|
104
108
|
xrspatial/sky_view_factor.py
|
|
105
109
|
xrspatial/slope.py
|
|
106
110
|
xrspatial/surface_distance.py
|
|
111
|
+
xrspatial/templates.py
|
|
107
112
|
xrspatial/terrain.py
|
|
108
113
|
xrspatial/terrain_metrics.py
|
|
109
114
|
xrspatial/utils.py
|
|
115
|
+
xrspatial/validate.py
|
|
110
116
|
xrspatial/viewshed.py
|
|
111
117
|
xrspatial/visibility.py
|
|
112
118
|
xrspatial/worley.py
|
|
@@ -137,6 +143,7 @@ xrspatial/geotiff/_layout.py
|
|
|
137
143
|
xrspatial/geotiff/_nodata.py
|
|
138
144
|
xrspatial/geotiff/_overview.py
|
|
139
145
|
xrspatial/geotiff/_overview_kernels.py
|
|
146
|
+
xrspatial/geotiff/_pam.py
|
|
140
147
|
xrspatial/geotiff/_reader.py
|
|
141
148
|
xrspatial/geotiff/_runtime.py
|
|
142
149
|
xrspatial/geotiff/_safe_xml.py
|
|
@@ -389,6 +396,7 @@ xrspatial/interpolate/_idw.py
|
|
|
389
396
|
xrspatial/interpolate/_kriging.py
|
|
390
397
|
xrspatial/interpolate/_spline.py
|
|
391
398
|
xrspatial/interpolate/_validation.py
|
|
399
|
+
xrspatial/interpolate/_vector.py
|
|
392
400
|
xrspatial/mcda/__init__.py
|
|
393
401
|
xrspatial/mcda/combine.py
|
|
394
402
|
xrspatial/mcda/constrain.py
|
|
@@ -419,6 +427,7 @@ xrspatial/tests/test_bilateral.py
|
|
|
419
427
|
xrspatial/tests/test_bump.py
|
|
420
428
|
xrspatial/tests/test_classify.py
|
|
421
429
|
xrspatial/tests/test_contour.py
|
|
430
|
+
xrspatial/tests/test_contract_validate.py
|
|
422
431
|
xrspatial/tests/test_convolution.py
|
|
423
432
|
xrspatial/tests/test_corridor.py
|
|
424
433
|
xrspatial/tests/test_cost_distance.py
|
|
@@ -447,6 +456,7 @@ xrspatial/tests/test_gpu_rtx_memory.py
|
|
|
447
456
|
xrspatial/tests/test_gpu_rtx_mesh.py
|
|
448
457
|
xrspatial/tests/test_hillshade.py
|
|
449
458
|
xrspatial/tests/test_hypsometric_integral.py
|
|
459
|
+
xrspatial/tests/test_interpolate_vector.py
|
|
450
460
|
xrspatial/tests/test_interpolation.py
|
|
451
461
|
xrspatial/tests/test_kde.py
|
|
452
462
|
xrspatial/tests/test_lite_crs.py
|
|
@@ -485,6 +495,7 @@ xrspatial/tests/test_rasterize_accuracy.py
|
|
|
485
495
|
xrspatial/tests/test_rasterize_all_touched_dask_grid_line_3384.py
|
|
486
496
|
xrspatial/tests/test_rasterize_all_touched_supercover_2169.py
|
|
487
497
|
xrspatial/tests/test_rasterize_alloc_3107.py
|
|
498
|
+
xrspatial/tests/test_rasterize_categorical_3482.py
|
|
488
499
|
xrspatial/tests/test_rasterize_coverage_2026_05_17.py
|
|
489
500
|
xrspatial/tests/test_rasterize_coverage_2026_05_21.py
|
|
490
501
|
xrspatial/tests/test_rasterize_coverage_2026_05_27.py
|
|
@@ -539,6 +550,7 @@ xrspatial/tests/test_sky_view_factor.py
|
|
|
539
550
|
xrspatial/tests/test_slope.py
|
|
540
551
|
xrspatial/tests/test_surface_distance.py
|
|
541
552
|
xrspatial/tests/test_sweep_state_csv_merge_2754.py
|
|
553
|
+
xrspatial/tests/test_templates.py
|
|
542
554
|
xrspatial/tests/test_terrain.py
|
|
543
555
|
xrspatial/tests/test_terrain_metrics.py
|
|
544
556
|
xrspatial/tests/test_utils.py
|