xarray-spatial 0.10.13__tar.gz → 0.10.14__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.13 → xarray_spatial-0.10.14}/.claude/sweep-api-consistency-state.csv +19 -18
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/.claude/sweep-documentation-state.csv +4 -2
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/.claude/sweep-test-coverage-state.csv +2 -1
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/CHANGELOG.md +26 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/PKG-INFO +2 -2
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/README.md +1 -1
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xarray_spatial.egg-info/PKG-INFO +2 -2
- xarray_spatial-0.10.14/xarray_spatial.egg-info/scm_version.json +8 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/_template_data.py +185 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/_version.py +3 -3
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/accessor.py +126 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/classify.py +22 -1
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/curvature.py +3 -9
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/geotiff/tests/write/test_symbology_sidecar_3537.py +55 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/interpolate/_idw.py +25 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/kde.py +15 -2
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/pathfinding.py +8 -3
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/preview.py +28 -1
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/proximity.py +35 -23
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/rasterize.py +20 -13
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/templates.py +283 -31
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/terrain.py +161 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/tests/test_accessor.py +153 -1
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/tests/test_classify.py +40 -20
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/tests/test_kde.py +65 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/tests/test_preview.py +63 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/tests/test_proximity.py +105 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/tests/test_rasterize.py +22 -16
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/tests/test_rasterize_coverage_2026_05_21.py +5 -6
- xarray_spatial-0.10.14/xrspatial/tests/test_templates.py +1102 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/tests/test_terrain.py +73 -0
- xarray_spatial-0.10.13/xarray_spatial.egg-info/scm_version.json +0 -8
- xarray_spatial-0.10.13/xrspatial/tests/test_templates.py +0 -507
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/.claude/sweep-accuracy-state.csv +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/.claude/sweep-metadata-state.csv +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/.claude/sweep-performance-state.csv +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/.claude/sweep-security-state.csv +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/.claude/sweep-style-state.csv +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/.codex/sweep-accuracy-state.csv +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/.codex/sweep-api-consistency-state.csv +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/.codex/sweep-metadata-state.csv +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/.codex/sweep-performance-state.csv +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/.codex/sweep-security-state.csv +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/.codex/sweep-style-state.csv +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/.codex/sweep-test-coverage-state.csv +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/.efficiency-audit-baseline.json +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/.efficiency-audit-baseline.prev.json +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/.gitattributes +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/.github/ISSUE_TEMPLATE/bug_report.md +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/.github/ISSUE_TEMPLATE/feature-proposal.md +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/.github/ISSUE_TEMPLATE/new-contributor.md +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/.github/labeler.yml +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/.github/pull_request_template.md +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/.github/workflows/benchmarks.yml +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/.github/workflows/copilot-review.yml +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/.github/workflows/docs.yml +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/.github/workflows/labeler.yml +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/.github/workflows/pypi-publish.yml +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/.github/workflows/test-cog-validator.yml +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/.github/workflows/test-geotiff-corpus.yml +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/.github/workflows/test.yml +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/.github/workflows/welcome-contributor.yml +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/.gitignore +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/.kilo/sweep-accuracy-state.csv +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/.kilo/sweep-api-consistency-state.csv +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/.kilo/sweep-metadata-state.csv +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/.kilo/sweep-performance-state.csv +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/.kilo/sweep-security-state.csv +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/.kilo/sweep-style-state.csv +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/.kilo/sweep-test-coverage-state.csv +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/.readthedocs.yml +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/AI_POLICY.md +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/CLAUDE.md +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/CODE_OF_CONDUCT.md +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/CONTRIBUTING.md +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/Citation-styles.md +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/LICENSE.txt +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/MANIFEST.in +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/RELEASE.md +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/codecov.yml +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/pyproject.toml +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/setup.cfg +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/setup.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xarray_spatial.egg-info/SOURCES.txt +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xarray_spatial.egg-info/dependency_links.txt +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xarray_spatial.egg-info/entry_points.txt +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xarray_spatial.egg-info/not-zip-safe +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xarray_spatial.egg-info/requires.txt +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xarray_spatial.egg-info/scm_file_list.json +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xarray_spatial.egg-info/top_level.txt +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/__init__.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/__main__.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/analytics.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/aspect.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/balanced_allocation.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/bilateral.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/bump.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/contour.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/convolution.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/corridor.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/cost_distance.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/dasymetric.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/dataset_support.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/datasets/__init__.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/datasets/sentinel-2/blue_band.nc +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/datasets/sentinel-2/green_band.nc +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/datasets/sentinel-2/nir_band.nc +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/datasets/sentinel-2/red_band.nc +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/datasets/sentinel-2/swir1_band.nc +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/datasets/sentinel-2/swir2_band.nc +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/diagnostics.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/diffusion.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/edge_detection.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/emerging_hotspots.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/erosion.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/experimental/__init__.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/experimental/min_observable_height.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/fire.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/flood.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/focal.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/geodesic.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/geotiff/__init__.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/geotiff/_attrs.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/geotiff/_backends/__init__.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/geotiff/_backends/_gpu_helpers.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/geotiff/_backends/dask.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/geotiff/_backends/gpu.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/geotiff/_backends/vrt.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/geotiff/_cog_http.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/geotiff/_compression.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/geotiff/_coords.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/geotiff/_crs.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/geotiff/_decode.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/geotiff/_dtypes.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/geotiff/_encode.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/geotiff/_errors.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/geotiff/_geotags.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/geotiff/_gpu_decode.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/geotiff/_header.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/geotiff/_layout.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/geotiff/_nodata.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/geotiff/_overview.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/geotiff/_overview_kernels.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/geotiff/_pam.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/geotiff/_reader.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/geotiff/_runtime.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/geotiff/_safe_xml.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/geotiff/_sidecar.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/geotiff/_sources.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/geotiff/_symbology.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/geotiff/_validation.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/geotiff/_vrt.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/geotiff/_vrt_validation.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/geotiff/_write_layout.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/geotiff/_writer.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/geotiff/_writers/__init__.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/geotiff/_writers/eager.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/geotiff/_writers/gpu.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/geotiff/_writers/vrt.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/geotiff/_xarray_backend.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/geotiff/tests/__init__.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/geotiff/tests/_geotiff_fixtures.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/geotiff/tests/_helpers/__init__.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/geotiff/tests/_helpers/markers.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/geotiff/tests/_helpers/tiff_builders.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/geotiff/tests/_helpers/tiff_surgery.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/geotiff/tests/attrs/__init__.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/geotiff/tests/attrs/test_contract.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/geotiff/tests/bench_vs_rioxarray.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/geotiff/tests/conftest.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/geotiff/tests/golden_corpus/README.md +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/geotiff/tests/golden_corpus/__init__.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/geotiff/tests/golden_corpus/_marks.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/geotiff/tests/golden_corpus/_oracle.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/geotiff/tests/golden_corpus/fixtures/cog_internal_overview_uint16.tif +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/geotiff/tests/golden_corpus/fixtures/compression_deflate_predictor2_uint16.tif +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/geotiff/tests/golden_corpus/fixtures/compression_deflate_predictor3_float32.tif +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/geotiff/tests/golden_corpus/fixtures/compression_jpeg_uint8_ycbcr.tif +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/geotiff/tests/golden_corpus/fixtures/compression_lerc_float32.tif +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/geotiff/tests/golden_corpus/fixtures/compression_lzw_predictor2_int16.tif +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/geotiff/tests/golden_corpus/fixtures/compression_none_uint8.tif +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/geotiff/tests/golden_corpus/fixtures/crs_citation_only.tif +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/geotiff/tests/golden_corpus/fixtures/crs_epsg_3857.tif +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/geotiff/tests/golden_corpus/fixtures/crs_wkt_utm10n.tif +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/geotiff/tests/golden_corpus/fixtures/dtype_float32.tif +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/geotiff/tests/golden_corpus/fixtures/dtype_float64.tif +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/geotiff/tests/golden_corpus/fixtures/dtype_int16.tif +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/geotiff/tests/golden_corpus/fixtures/dtype_int32.tif +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/geotiff/tests/golden_corpus/fixtures/dtype_int8.tif +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/geotiff/tests/golden_corpus/fixtures/dtype_uint16.tif +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/geotiff/tests/golden_corpus/fixtures/dtype_uint32.tif +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/geotiff/tests/golden_corpus/fixtures/dtype_uint8.tif +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/geotiff/tests/golden_corpus/fixtures/extra_tags_uint16.tif +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/geotiff/tests/golden_corpus/fixtures/gdal_metadata_namespaced_uint16.tif +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/geotiff/tests/golden_corpus/fixtures/nodata_int_sentinel_uint16.tif +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/geotiff/tests/golden_corpus/fixtures/nodata_miniswhite_uint8.tif +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/geotiff/tests/golden_corpus/fixtures/nodata_nan_float32.tif +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/geotiff/tests/golden_corpus/fixtures/overview_external_ovr_uint16.tif +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/geotiff/tests/golden_corpus/fixtures/overview_external_ovr_uint16.tif.ovr +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/geotiff/tests/golden_corpus/fixtures/overview_internal_uint16.tif +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/geotiff/tests/golden_corpus/fixtures/planar_separate_uint8_rgb.tif +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/geotiff/tests/golden_corpus/fixtures/sparse_tiled_uint16.tif +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/geotiff/tests/golden_corpus/fixtures/stripped_be_uint16.tif +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/geotiff/tests/golden_corpus/fixtures/stripped_le_uint16.tif +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/geotiff/tests/golden_corpus/fixtures/tiled_be_uint16.tif +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/geotiff/tests/golden_corpus/fixtures/tiled_le_uint16.tif +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/geotiff/tests/golden_corpus/generate.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/geotiff/tests/golden_corpus/manifest.yaml +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/geotiff/tests/golden_corpus/test_compression.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/geotiff/tests/golden_corpus/test_corpus_determinism.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/geotiff/tests/golden_corpus/test_dask_gpu.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/geotiff/tests/golden_corpus/test_dask_numpy.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/geotiff/tests/golden_corpus/test_dtype_variants.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/geotiff/tests/golden_corpus/test_eager_numpy.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/geotiff/tests/golden_corpus/test_fsspec.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/geotiff/tests/golden_corpus/test_gpu.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/geotiff/tests/golden_corpus/test_http.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/geotiff/tests/golden_corpus/test_layout_endian.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/geotiff/tests/golden_corpus/test_manifest.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/geotiff/tests/golden_corpus/test_metadata_tags.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/geotiff/tests/golden_corpus/test_nodata_sentinels.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/geotiff/tests/golden_corpus/test_oracle.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/geotiff/tests/golden_corpus/test_overview_cog.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/geotiff/tests/golden_corpus/test_vrt.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/geotiff/tests/gpu/__init__.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/geotiff/tests/gpu/test_codec.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/geotiff/tests/gpu/test_kernels_and_kwargs.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/geotiff/tests/gpu/test_reader.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/geotiff/tests/gpu/test_writer.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/geotiff/tests/integration/__init__.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/geotiff/tests/integration/test_dask_pipeline.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/geotiff/tests/integration/test_gpu_pipeline.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/geotiff/tests/integration/test_http_sources.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/geotiff/tests/integration/test_sidecar.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/geotiff/tests/parity/__init__.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/geotiff/tests/parity/test_api_consolidation.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/geotiff/tests/parity/test_backend_matrix.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/geotiff/tests/parity/test_finalization.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/geotiff/tests/parity/test_pixel_equality.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/geotiff/tests/parity/test_reference.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/geotiff/tests/parity/test_signature_contract.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/geotiff/tests/read/__init__.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/geotiff/tests/read/test_basic.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/geotiff/tests/read/test_bbox_2555.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/geotiff/tests/read/test_bbox_vrt_2668.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/geotiff/tests/read/test_cloud_source_concurrency_3361.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/geotiff/tests/read/test_compression.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/geotiff/tests/read/test_coords.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/geotiff/tests/read/test_crs.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/geotiff/tests/read/test_degenerate_shapes.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/geotiff/tests/read/test_dtypes.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/geotiff/tests/read/test_endianness.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/geotiff/tests/read/test_georef.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/geotiff/tests/read/test_mask_and_scale_dtype_parity_3066.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/geotiff/tests/read/test_nodata.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/geotiff/tests/read/test_overview.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/geotiff/tests/read/test_rioxarray_compat_2961.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/geotiff/tests/read/test_scale_zero_3104.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/geotiff/tests/read/test_streaming.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/geotiff/tests/read/test_tiling.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/geotiff/tests/read/test_unpack_noop_doc_3263.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/geotiff/tests/release_gates/__init__.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/geotiff/tests/release_gates/test_features.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/geotiff/tests/release_gates/test_stable_features.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/geotiff/tests/test_edge_cases.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/geotiff/tests/test_fuzz_hypothesis.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/geotiff/tests/test_polish.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/geotiff/tests/test_round_trip.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/geotiff/tests/test_security.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/geotiff/tests/test_shutdown_cleanup_2486.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/geotiff/tests/test_stable_only_bbox_ordering_2869.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/geotiff/tests/test_stable_only_remote_2821.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/geotiff/tests/test_xarray_backend_3365.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/geotiff/tests/test_xarray_backend_coregister_3376.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/geotiff/tests/test_xarray_backend_coregister_target_3379.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/geotiff/tests/unit/__init__.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/geotiff/tests/unit/test_codec_roundtrip.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/geotiff/tests/unit/test_compression.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/geotiff/tests/unit/test_degenerate_pixel_size_3331.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/geotiff/tests/unit/test_exception_exports_3265.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/geotiff/tests/unit/test_geotags.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/geotiff/tests/unit/test_header.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/geotiff/tests/unit/test_ifd.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/geotiff/tests/unit/test_input_validation.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/geotiff/tests/unit/test_metadata.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/geotiff/tests/unit/test_photometric.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/geotiff/tests/unit/test_predictor.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/geotiff/tests/unit/test_safe_xml.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/geotiff/tests/unit/test_signatures.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/geotiff/tests/vrt/__init__.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/geotiff/tests/vrt/test_dtype_conversion.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/geotiff/tests/vrt/test_metadata.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/geotiff/tests/vrt/test_missing_sources.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/geotiff/tests/vrt/test_non_georef_placement_3116.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/geotiff/tests/vrt/test_parity.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/geotiff/tests/vrt/test_source_opt_ins_2672.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/geotiff/tests/vrt/test_validation.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/geotiff/tests/vrt/test_window.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/geotiff/tests/write/__init__.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/geotiff/tests/write/test_basic.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/geotiff/tests/write/test_bigtiff.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/geotiff/tests/write/test_category_sidecar_backends_3483.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/geotiff/tests/write/test_cog.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/geotiff/tests/write/test_crs.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/geotiff/tests/write/test_nodata.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/geotiff/tests/write/test_overview.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/geotiff/tests/write/test_pack_3064.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/geotiff/tests/write/test_pack_64bit_sentinel_3264.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/geotiff/tests/write/test_pack_band_subset_3161.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/geotiff/tests/write/test_pack_float_width_3080.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/geotiff/tests/write/test_pack_lazy_nan_guard_3235.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/geotiff/tests/write/test_pack_nodata_kwarg_3168.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/geotiff/tests/write/test_pack_range_guard_3260.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/geotiff/tests/write/test_streaming.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/geotiff/tests/write/test_vrt_atomic.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/glcm.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/gpu_rtx/__init__.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/gpu_rtx/_memory.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/gpu_rtx/cuda_utils.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/gpu_rtx/hillshade.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/gpu_rtx/mesh_utils.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/gpu_rtx/viewshed.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/hillshade.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/hydro/__init__.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/hydro/_boundary_store.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/hydro/basin_d8.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/hydro/fill_d8.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/hydro/flow_accumulation_d8.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/hydro/flow_accumulation_dinf.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/hydro/flow_accumulation_mfd.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/hydro/flow_direction_d8.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/hydro/flow_direction_dinf.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/hydro/flow_direction_mfd.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/hydro/flow_length_d8.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/hydro/flow_length_dinf.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/hydro/flow_length_mfd.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/hydro/flow_path_d8.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/hydro/flow_path_dinf.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/hydro/flow_path_mfd.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/hydro/hand_d8.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/hydro/hand_dinf.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/hydro/hand_mfd.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/hydro/sink_d8.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/hydro/snap_pour_point_d8.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/hydro/stream_link_d8.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/hydro/stream_link_dinf.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/hydro/stream_link_mfd.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/hydro/stream_order_d8.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/hydro/stream_order_dinf.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/hydro/stream_order_mfd.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/hydro/tests/__init__.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/hydro/tests/conftest.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/hydro/tests/test_basin_d8.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/hydro/tests/test_fill_d8.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/hydro/tests/test_flow_accumulation_d8.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/hydro/tests/test_flow_accumulation_dinf.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/hydro/tests/test_flow_accumulation_mfd.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/hydro/tests/test_flow_direction_d8.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/hydro/tests/test_flow_direction_dinf.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/hydro/tests/test_flow_direction_mfd.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/hydro/tests/test_flow_length_d8.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/hydro/tests/test_flow_length_dinf.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/hydro/tests/test_flow_length_mfd.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/hydro/tests/test_flow_path_d8.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/hydro/tests/test_flow_path_dinf.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/hydro/tests/test_flow_path_mfd.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/hydro/tests/test_hand_d8.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/hydro/tests/test_hand_dinf.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/hydro/tests/test_hand_mfd.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/hydro/tests/test_routing_public_api.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/hydro/tests/test_sink_d8.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/hydro/tests/test_snap_pour_point_d8.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/hydro/tests/test_stream_link_d8.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/hydro/tests/test_stream_link_dinf.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/hydro/tests/test_stream_link_mfd.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/hydro/tests/test_stream_order_d8.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/hydro/tests/test_stream_order_dinf.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/hydro/tests/test_stream_order_mfd.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/hydro/tests/test_twi_d8.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/hydro/tests/test_validate_cellsize.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/hydro/tests/test_validate_mfd_companion_shape.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/hydro/tests/test_validate_mfd_fractions.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/hydro/tests/test_validate_scalar_params.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/hydro/tests/test_validate_secondary_args.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/hydro/tests/test_watershed_d8.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/hydro/tests/test_watershed_dinf.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/hydro/tests/test_watershed_mfd.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/hydro/twi_d8.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/hydro/watershed_d8.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/hydro/watershed_dinf.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/hydro/watershed_mfd.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/interpolate/__init__.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/interpolate/_kriging.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/interpolate/_spline.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/interpolate/_validation.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/interpolate/_vector.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/mahalanobis.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/mcda/__init__.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/mcda/combine.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/mcda/constrain.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/mcda/sensitivity.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/mcda/standardize.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/mcda/weights.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/morphology.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/multispectral.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/normalize.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/perlin.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/polygon_clip.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/polygonize.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/reproject/__init__.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/reproject/_crs_utils.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/reproject/_grid.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/reproject/_interpolate.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/reproject/_itrf.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/reproject/_lite_crs.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/reproject/_merge.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/reproject/_projections.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/reproject/_projections_cuda.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/reproject/_transform.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/reproject/_vertical.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/reproject/grids/us_nga_egm96_15.tif +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/resample.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/sieve.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/sky_view_factor.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/slope.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/surface_distance.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/terrain_metrics.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/tests/__init__.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/tests/bench_reproject_vs_rioxarray.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/tests/conftest.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/tests/general_checks.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/tests/test_analytics.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/tests/test_aspect.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/tests/test_balanced_allocation.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/tests/test_bilateral.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/tests/test_bump.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/tests/test_contour.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/tests/test_contract_validate.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/tests/test_convolution.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/tests/test_corridor.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/tests/test_cost_distance.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/tests/test_curvature.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/tests/test_dask_cupy_gaps.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/tests/test_dask_laziness.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/tests/test_dask_task_names.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/tests/test_dasymetric.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/tests/test_dataset_support.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/tests/test_datasets.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/tests/test_diagnostics.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/tests/test_diffusion.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/tests/test_edge_detection.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/tests/test_emerging_hotspots.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/tests/test_erosion.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/tests/test_fire.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/tests/test_flood.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/tests/test_focal.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/tests/test_fused_overlap.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/tests/test_geodesic_aspect.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/tests/test_geodesic_slope.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/tests/test_glcm.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/tests/test_glcm_metric_order.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/tests/test_gpu_rtx_has_rtx.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/tests/test_gpu_rtx_memory.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/tests/test_gpu_rtx_mesh.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/tests/test_hillshade.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/tests/test_hypsometric_integral.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/tests/test_interpolate_vector.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/tests/test_interpolation.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/tests/test_lite_crs.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/tests/test_mahalanobis.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/tests/test_mcda.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/tests/test_min_observable_height.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/tests/test_morphology.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/tests/test_morphology_derived.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/tests/test_multi_overlap.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/tests/test_multispectral.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/tests/test_normalize.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/tests/test_northness_eastness.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/tests/test_open_geotiff_coregister.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/tests/test_open_geotiff_resampling.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/tests/test_optional_shapely.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/tests/test_pathfinding.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/tests/test_perlin.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/tests/test_polygon_clip.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/tests/test_polygonize.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/tests/test_polygonize_atol_rtol_backend_coverage_2026_05_27.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/tests/test_polygonize_coverage_2026_05_19.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/tests/test_polygonize_dask_row_batch_2608.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/tests/test_polygonize_issue_2172.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/tests/test_polygonize_issue_2583.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/tests/test_polygonize_issue_2606.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/tests/test_polygonize_issue_2666.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/tests/test_polygonize_issue_2677.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/tests/test_polygonize_issue_3292.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/tests/test_polygonize_issue_3303.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/tests/test_polygonize_mask_chunk_mismatch_3299.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/tests/test_polygonize_mask_dtype_coverage_2026_05_29.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/tests/test_rasterize_accuracy.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/tests/test_rasterize_all_touched_dask_grid_line_3384.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/tests/test_rasterize_all_touched_supercover_2169.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/tests/test_rasterize_alloc_3107.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/tests/test_rasterize_categorical_3482.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/tests/test_rasterize_coregister_3492.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/tests/test_rasterize_coverage_2026_05_17.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/tests/test_rasterize_coverage_2026_05_27.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/tests/test_rasterize_coverage_2026_05_29.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/tests/test_rasterize_coverage_2026_06_09.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/tests/test_rasterize_crs_mismatch_3058.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/tests/test_rasterize_descending_x_2568.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/tests/test_rasterize_dtype_annot_3291.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/tests/test_rasterize_fill_dtype_3054.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/tests/test_rasterize_geom_crs_3087.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/tests/test_rasterize_gpu_alias_3089.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/tests/test_rasterize_gpu_callable_warn_3057.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/tests/test_rasterize_gpu_race_2167.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/tests/test_rasterize_int_precision_3056.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/tests/test_rasterize_linearring_3055.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/tests/test_rasterize_lines_all_touched_3102.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/tests/test_rasterize_merge_dedup_3304.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/tests/test_rasterize_mixed_type_ordered_merge_3296.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/tests/test_rasterize_nan_int_fill_2504.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/tests/test_rasterize_nan_propagation_2255.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/tests/test_rasterize_nonfinite_burn_3085.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/tests/test_rasterize_nonfinite_burn_3088.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/tests/test_rasterize_nonfinite_coords_3295.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/tests/test_rasterize_partial_dims_2569.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/tests/test_rasterize_props_hoist_2506.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/tests/test_rasterize_resolution_exact_2573.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/tests/test_rasterize_resolution_validation_2576.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/tests/test_rasterize_signature_annot_2250.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/tests/test_rasterize_signed_step_2566.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/tests/test_rasterize_tile_props_slice_2020.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/tests/test_rechunk_no_shuffle.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/tests/test_reproject.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/tests/test_reproject_coverage_2026_05_27.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/tests/test_reproject_cupy_gate_2564.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/tests/test_reproject_cupy_promotion_3281.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/tests/test_reproject_inverse_kernels_3274.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/tests/test_reproject_itrf_scale_3276.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/tests/test_reproject_parallel_kernels_3141.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/tests/test_reproject_pyproj_warning_3242.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/tests/test_reproject_sphere_ellipsoid_guard_3275.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/tests/test_reproject_streaming_3101.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/tests/test_resample.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/tests/test_resample_coverage_2026_05_27.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/tests/test_resample_cupy_agg_fallback_2615.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/tests/test_resample_input_validation_2574.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/tests/test_resample_irregular_coords_2663.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/tests/test_resample_nodata_dask_parity_3073.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/tests/test_resample_signature_annot_2544.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/tests/test_sieve.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/tests/test_sieve_gdal_parity.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/tests/test_sky_view_factor.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/tests/test_slope.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/tests/test_surface_distance.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/tests/test_sweep_state_csv_merge_2754.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/tests/test_terrain_metrics.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/tests/test_utils.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/tests/test_validation.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/tests/test_viewshed.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/tests/test_visibility.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/tests/test_zonal.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/tests/test_zonal_backend_coverage_2026_05_27.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/utils.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/validate.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/viewshed.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/visibility.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/worley.py +0 -0
- {xarray_spatial-0.10.13 → xarray_spatial-0.10.14}/xrspatial/zonal.py +0 -0
|
@@ -1,18 +1,19 @@
|
|
|
1
|
-
module,last_inspected,issue,severity_max,categories_found,notes
|
|
2
|
-
classify,2026-06-20,3398,MEDIUM,1;3,"Sweep 2026-06-20 (deep-sweep-api-consistency-classify-2026-06-20). 1 MEDIUM Cat 1 finding filed as #3398 and fixed on this branch. (MEDIUM Cat 1 positional-order drift) natural_breaks ordered its params (agg, num_sample, name, k) while the other two classifiers that take the same trio order them (agg, k, num_sample, name): quantile(agg, k=4, num_sample, name), maximum_breaks(agg, k=5, num_sample, name). So natural_breaks(raster, 5) silently set num_sample=5 instead of k=5. Fix reorders natural_breaks to (agg, k=5, num_sample=20000, name) and adds a _natural_breaks_legacy_order shim: when k= is a keyword AND a second positional is present (the only way pre-1.0 callers passed num_sample, since k was last and always keyword), the positional is treated as the old num_sample with a DeprecationWarning. Keeps the one example notebook call natural_breaks(raster, 20000, k=4) working. Bundled trivial Cat 3 fix in same PR: binary() was the only public classifier with no type hints -- added agg: xr.DataArray, name: Optional[str], -> xr.DataArray to match the other 9. Tests: test_natural_breaks_positional_k_matches_siblings (new positional k == keyword k) and test_natural_breaks_legacy_positional_num_sample_warns (legacy order warns + maps identically). Full test_classify.py (now 91) + test_validation.py pass. Cat 4 considered NOT a finding: quantile k=4 (quartiles) vs k=5 (quintiles) elsewhere is the documented PySAL/mapclassify convention, not drift. No Cat 2 return drift (all 10 publics return xr.DataArray/Dataset via @supports_dataset, coords/dims/attrs preserved). No Cat 5 orphan API (all 10 re-exported in __init__.py; no __all__ but consistent with module convention). Cross-cutting, notes only: first-arg agg (classify family) vs raster (reproject/rasterize/polygonize) is library-wide drift, out of per-module scope. cuda-validated: CUDA_AVAILABLE=True on this host; natural_breaks new order + legacy shim smoke-tested on numpy AND cupy entry points (both warn + remap), dataset path binds name correctly, binary verified on cupy."
|
|
3
|
-
focal,2026-06-10,3215;3216,MEDIUM,3;4,"Sweep 2026-06-10 (deep-sweep-api-consistency-focal-2026-06-10). 2 MEDIUM findings filed, fixed on branches -01/-02 off this one. (#3215, MEDIUM Cat 4 cross-backend default parity, branch -01) apply() default func=_calc_mean is an @ngjit CPU function but the cupy/dask+cupy paths launch func as a CUDA kernel via _focal_stats_func_cupy func[griddim, blockdim], so apply(cupy_agg, kernel) raises TypeError 'CPUDispatcher' object is not subscriptable (dask+cupy builds the graph and fails at compute). Prior 2026-05-29 sweep dispositioned this LOW as 'documented in the docstring', but the docstring covers explicit funcs -- the default itself is unusable on 2 of 4 backends. Fix: func=None sentinel resolved per backend (_calc_mean CPU, _focal_mean_cuda GPU), explicit-func behavior unchanged; same PR adds the missing name= param to the apply() docstring (signature has name='focal_apply'; mean/focal_stats/hotspots document theirs). (#3216, MEDIUM Cat 3, branch -02) hotspots() docstring lists 3 backends but dask_cupy_func=_hotspots_dask_cupy is dispatched and works; kernel param documented as binary ('values of 1 indicate the kernel') while hotspots accepts weighted kernels and the Gi* formula in the same docstring uses weights w_ij (apply/focal_stats reject non-binary via _validate_binary_kernel, hotspots deliberately does not). Docs-only fix. LOW documented, not fixed: among the 4 focal publics only mean() has @supports_dataset (Dataset-support drift; feature gap, not an API bug). Cross-cutting, notes only per template: emerging_hotspots(raster=), viewshed(raster=), calc_cellsize(raster) still use raster while focal standardized on agg with a DeprecationWarning shim (#2689/PR #2699); library-wide first-arg drift, belongs to those modules' sweeps. No Cat 1 in-module (agg canonical, raster alias warns, both-args raises). No Cat 2 return drift (mean/apply/hotspots 2D same-type, focal_stats 3D (stats,y,x) as documented). No Cat 5 orphan API (apply/focal_stats/hotspots documented in focal.rst autosummary and consumed via xrspatial.focal module path; only mean re-exported top-level; emerging_hotspots top-level vs hotspots module-level asymmetry noted, additive export would be a design call, not filed). cuda-validated: CUDA_AVAILABLE=True on this host; mean/apply/focal_stats/hotspots smoke-tested on cupy with kwarg parity; the apply default crash reproduced on GPU; hotspots weighted-kernel acceptance verified empirically."
|
|
4
|
-
geotiff,2026-06-12,3263;3265,MEDIUM,3;5,"Re-sweep 2026-06-12 (deep-sweep-api-consistency-geotiff-2026-06-12); prior pass 2026-06-09 (#3086). Scope: surface changes since 2026-06-09 (pack/unpack fixes #3171-#3241, SUPPORTED_FEATURES reader.unpack/writer.pack/reader.coregister, coregister docs #3248) plus a fresh 5-category pass on open_geotiff/to_geotiff. 2 MEDIUM findings filed and fixed on branches -01/-02 off this one. (#3263, MEDIUM Cat 3, PR #3269, branch -01) open_geotiff unpack docstring said 'A source without scale / offset metadata is a no-op', but unpack=True folds into the masking gate (_finalize_eager_read: mask_and_scale implies masking, rioxarray parity), so a sentinel-bearing uint16 source still comes back float64 with NaN holes; verified identical on all 4 backends (not a parity bug), only a source with neither scale/offset nor a sentinel reads unchanged. Docs-only fix + test_unpack_noop_doc_3263.py pinning wording (scoped to the unpack paragraph) and behavior. (#3265, MEDIUM Cat 5, PR #3273, branch -02) exception-export drift: VRTUnsupportedError (raised 10+ times in _vrt_validation.py on public .vrt reads, documented in geotiff_safe_io.rst which steered users to the private _errors module), CloudSizeLimitError (importable but not in __all__, sibling UnsafeURLError IS exported), and PixelSafetyLimitError (raised by the [stable] max_pixels cap, only importable from _layout/_reader) were the only 3 exceptions raised on public open_geotiff paths missing from the public surface (other 17 exported). Additive fix: import + __all__ + :class: roles in safe_io doc + trigger-point docs naming the exceptions in max_pixels/max_cloud_bytes param docs and geotiff.rst; test_exception_exports_3265.py pins export, identity with private definitions, and a functional max_pixels raise. Clean elsewhere: docstring/signature parity exact on both publics (programmatic check + 218 existing contract tests); no Cat 1 (signatures unchanged since 2026-06-09; pack/unpack pair deliberate), no Cat 2 (DataArray / path returns unchanged), no Cat 4 (shared allow_* defaults match reader/writer; gpu False-vs-None auto-detect documented). SUPPORTED_FEATURES tiers (reader.unpack/writer.pack/reader.coregister experimental) agree with docstring tier markers. coregister= itself lives on accessor.py (excluded module) -- only its SUPPORTED_FEATURES registration is in geotiff, consistent. cuda-validated: CUDA_AVAILABLE=True; open_geotiff smoke-tested with identical kwargs on numpy/cupy/dask/dask+cupy (cpu/gpu pixel parity), to_geotiff gpu=True, cupy pack=True write (#3240 fix confirmed), deprecated aliases mask_and_scale/name/mask_nodata all warn. Both PRs reviewed (COMMENTED) with findings fixed in follow-up commits c14844a8/af3c8a66; branches up to date with origin/main; left for user merge per REVIEW_REQUIRED."
|
|
5
|
-
hydro-d8,2026-05-29,2709,HIGH,1;5,"Sweep 2026-05-29 (deep-sweep-api-consistency-hydro-d8-2026-05-29). Scope = the 13 D8-variant files only; dinf/mfd read for reference but not modified. 1 HIGH Cat 1 + 1 MEDIUM Cat 5 fixed in this branch (#2709, PR #2716). HIGH Cat 1: stream_order_d8 named its strahler/shreve selector `ordering` while sibling stream_order_dinf/stream_order_mfd use `method`; both names live in the public API and the __init__.py _StreamOrderDispatch special-cases the drift (translates ordering->method for non-d8). Fix adds `method` as an accepted alias on stream_order_d8 (case-insensitive; takes precedence; conflicting ordering+method raises ValueError), keeping `ordering` working so the out-of-scope dispatcher (passes ordering=) and existing callers are unaffected. Full rename to `method` deferred because deprecating `ordering` would warn on every stream_order(routing='d8') call via the dispatcher I cannot touch in this scope. MEDIUM Cat 5: basins_d8 (watershed_d8.py) is a backward-compat wrapper whose docstring said 'use basin instead' but emitted no warning; added DeprecationWarning(stacklevel=2). Tests added for alias parity/precedence/conflict/case-insensitivity and for the basins_d8 warning. Findings documented but NOT filed per template: (LOW Cat 1 cross-module, out of scope) dinf siblings name the first arg `flow_dir_dinf` (stream_link/flow_path/hand/watershed_dinf) while all D8 funcs use the cleaner `flow_dir`; D8 is the better convention so no D8 change -- the drift lives in the dinf files. (LOW Cat 4 defensive-validation drift) hand_d8 validates np.isfinite(threshold) but stream_link_d8/stream_order_d8 (same threshold: float = 100 param) do not; not user-facing signature surprise, document only. No Cat 2 return drift (every D8 public fn returns xr.DataArray with coords/dims/attrs preserved; Dataset in -> Dataset out via @supports_dataset). No Cat 3 missing-hints beyond fill_d8 z_limit (optional, no hint) which mirrors its sibling style. All 13 D8 funcs are re-exported in xrspatial/hydro/__init__.py (no orphan API). cuda-validated: CUDA_AVAILABLE=True on this host; method-alias parity smoke-tested on a cupy DataArray. CI: ubuntu/windows/3.12 GitHub Actions green; macOS-3.14 + ReadTheDocs slow but no failures. NOTE: the /review-pr review comment could not be posted to GitHub (auto-mode permission denial on gh pr review); review findings were applied to code instead (case-insensitive conflict check + str|None hint, commit f8467320)."
|
|
6
|
-
interpolate,2026-06-12,3285,MEDIUM,2,"Sweep 2026-06-12 (deep-sweep-api-consistency-interpolate-2026-06-12). Scope: idw/_idw.py, kriging/_kriging.py, spline/_spline.py, shared _validation.py. 1 MEDIUM Cat 2 finding filed as #3285, fixed on branch -01 off this one: kriging(return_variance=True) singular-matrix fallback (_kriging.py:499) returns prediction, prediction.copy() so the variance DataArray keeps the prediction's name instead of f'{name}_variance' (normal path :523 names it correctly); reproduced by monkeypatching _build_kriging_matrix to None; anything keying on .name (xr.merge, Dataset build) silently collapses the pair. One-line fix + regression test on the singular path. Clean elsewhere: Cat 1 in-module exact (idw/kriging/spline share x, y, z, template positionals and name= default '<func>'; template matches kde's template=); docstring/signature parity exact on all 3 publics (every param documented, Returns sections match incl. kriging's tuple); Cat 4 no default drift (power=2.0, k=None, fill_value=nan, variogram_model='spherical', nlags=15, smoothing=0.0, all single-owner params); Cat 5 no orphan API (all 3 re-exported in xrspatial/__init__.py and autosummaried in docs/source/reference/interpolation.rst; tests touch private helpers only via module paths). Cross-cutting, notes only per template: fill_value (idw) vs fill (rasterize) for the uncovered-pixel value is library-wide drift (idw matches numpy's fill_value convention, left alone); public functions are untyped module-wide (consistent internally, drifts from typed kde/rasterize/proximity siblings -- annotation pass would span the whole module, LOW, not filed); kde's keyword-only style is the library minority so interpolate's positional style matches the rasterize/proximity majority. GPU k-nearest rejection (NotImplementedError) is deliberate and documented in the k param docstring. cuda-validated: CUDA_AVAILABLE=True on this host; idw/kriging/spline smoke-tested with full kwargs on numpy AND cupy DataArrays (variance name parity confirmed on both), dask+numpy and dask+cupy graph construction verified without compute."
|
|
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
|
-
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
|
-
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."
|
|
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."
|
|
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)."
|
|
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
|
-
reproject,2026-06-09,3095;3097,HIGH,1;2;3,"Sweep 2026-06-09 (deep-sweep-api-consistency-reproject-2026-06-09). 2 findings filed and fixed: #3095 -> PR #3125, #3097 -> PR #3134 (branches -01/-02 off this one). (HIGH Cat 2, #3095) merge() raises TypeError ('Implicit conversion to a NumPy array is not allowed') on cupy-backed inputs while sibling reproject() supports numpy/cupy/dask+numpy/dask+cupy; crash site _merge_inmemory info['raster'].values (__init__.py:2572); dask-of-cupy fails the same way at compute via _merge_block_adapter -> _reproject_chunk_numpy/np.asarray. _merge.py has a complete _merge_arrays_cupy that is imported in __init__.py:38 but never called (dead GPU plumbing; the unused import alone is lint issue #3083 from the style sweep). Fix: host round-trip on entry (same pattern as _apply_vertical_shift), GPU result out, docstring documents backend handling. (MEDIUM Cat 3, #3097) _vertical.py Returns docstrings claim 'same type as input/height' but geoid_height(DataArray) returns np.ndarray (verified empirically) and the four conversion wrappers return np.float64/np.ndarray; geoid_height converts scalars to Python float but the wrappers do not (sibling scalar-return drift). Docs-only fix. Documented but NOT fixed: (LOW Cat 1) itrf_transform(src=/tgt=) abbreviations vs source_/target_ elsewhere -- prior 2026-05-29 sweep already weighed this and left it as-is (frames, not CRSes); filed #3099 before noticing the prior disposition, then closed it as not-planned to avoid churn. (LOW Cat 5) module docstring 'Public API' section lists only reproject/merge while __all__ exports 10 names (vertical+itrf funcs invisible in help() header; docs/source/reference/reproject.rst autosummary likewise lists only reproject/merge). Cross-cutting, notes only per template: raster/rasters (reproject) vs agg (terrain family) vs source (geotiff); chunk_size (reproject/merge) vs chunks (open_geotiff); resampling+resolution (reproject/merge/accessor) vs method+target_resolution (resample.py -- resample is the outlier, belongs to a resample-module pass, already in resample row's notes). No Cat 4 default drift (resampling='bilinear'/transform_precision=16/chunk_size=None/bounds_policy='auto'/model='EGM96' consistent across siblings). reproject()/merge() kwarg parity smoke-tested on numpy AND cupy DataArrays (merge cupy crash found exactly there). cuda-validated: CUDA_AVAILABLE=True on this host. CI: all GitHub Actions checks green on both PRs; RTD flapped (pending on #3125, fail on #3134 -- repo-wide backlog, change not docs-rendered); PRs left BLOCKED on REVIEW_REQUIRED for the user to merge."
|
|
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."
|
|
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."
|
|
17
|
-
|
|
18
|
-
|
|
1
|
+
module,last_inspected,issue,severity_max,categories_found,notes
|
|
2
|
+
classify,2026-06-20,3398,MEDIUM,1;3,"Sweep 2026-06-20 (deep-sweep-api-consistency-classify-2026-06-20). 1 MEDIUM Cat 1 finding filed as #3398 and fixed on this branch. (MEDIUM Cat 1 positional-order drift) natural_breaks ordered its params (agg, num_sample, name, k) while the other two classifiers that take the same trio order them (agg, k, num_sample, name): quantile(agg, k=4, num_sample, name), maximum_breaks(agg, k=5, num_sample, name). So natural_breaks(raster, 5) silently set num_sample=5 instead of k=5. Fix reorders natural_breaks to (agg, k=5, num_sample=20000, name) and adds a _natural_breaks_legacy_order shim: when k= is a keyword AND a second positional is present (the only way pre-1.0 callers passed num_sample, since k was last and always keyword), the positional is treated as the old num_sample with a DeprecationWarning. Keeps the one example notebook call natural_breaks(raster, 20000, k=4) working. Bundled trivial Cat 3 fix in same PR: binary() was the only public classifier with no type hints -- added agg: xr.DataArray, name: Optional[str], -> xr.DataArray to match the other 9. Tests: test_natural_breaks_positional_k_matches_siblings (new positional k == keyword k) and test_natural_breaks_legacy_positional_num_sample_warns (legacy order warns + maps identically). Full test_classify.py (now 91) + test_validation.py pass. Cat 4 considered NOT a finding: quantile k=4 (quartiles) vs k=5 (quintiles) elsewhere is the documented PySAL/mapclassify convention, not drift. No Cat 2 return drift (all 10 publics return xr.DataArray/Dataset via @supports_dataset, coords/dims/attrs preserved). No Cat 5 orphan API (all 10 re-exported in __init__.py; no __all__ but consistent with module convention). Cross-cutting, notes only: first-arg agg (classify family) vs raster (reproject/rasterize/polygonize) is library-wide drift, out of per-module scope. cuda-validated: CUDA_AVAILABLE=True on this host; natural_breaks new order + legacy shim smoke-tested on numpy AND cupy entry points (both warn + remap), dataset path binds name correctly, binary verified on cupy."
|
|
3
|
+
focal,2026-06-10,3215;3216,MEDIUM,3;4,"Sweep 2026-06-10 (deep-sweep-api-consistency-focal-2026-06-10). 2 MEDIUM findings filed, fixed on branches -01/-02 off this one. (#3215, MEDIUM Cat 4 cross-backend default parity, branch -01) apply() default func=_calc_mean is an @ngjit CPU function but the cupy/dask+cupy paths launch func as a CUDA kernel via _focal_stats_func_cupy func[griddim, blockdim], so apply(cupy_agg, kernel) raises TypeError 'CPUDispatcher' object is not subscriptable (dask+cupy builds the graph and fails at compute). Prior 2026-05-29 sweep dispositioned this LOW as 'documented in the docstring', but the docstring covers explicit funcs -- the default itself is unusable on 2 of 4 backends. Fix: func=None sentinel resolved per backend (_calc_mean CPU, _focal_mean_cuda GPU), explicit-func behavior unchanged; same PR adds the missing name= param to the apply() docstring (signature has name='focal_apply'; mean/focal_stats/hotspots document theirs). (#3216, MEDIUM Cat 3, branch -02) hotspots() docstring lists 3 backends but dask_cupy_func=_hotspots_dask_cupy is dispatched and works; kernel param documented as binary ('values of 1 indicate the kernel') while hotspots accepts weighted kernels and the Gi* formula in the same docstring uses weights w_ij (apply/focal_stats reject non-binary via _validate_binary_kernel, hotspots deliberately does not). Docs-only fix. LOW documented, not fixed: among the 4 focal publics only mean() has @supports_dataset (Dataset-support drift; feature gap, not an API bug). Cross-cutting, notes only per template: emerging_hotspots(raster=), viewshed(raster=), calc_cellsize(raster) still use raster while focal standardized on agg with a DeprecationWarning shim (#2689/PR #2699); library-wide first-arg drift, belongs to those modules' sweeps. No Cat 1 in-module (agg canonical, raster alias warns, both-args raises). No Cat 2 return drift (mean/apply/hotspots 2D same-type, focal_stats 3D (stats,y,x) as documented). No Cat 5 orphan API (apply/focal_stats/hotspots documented in focal.rst autosummary and consumed via xrspatial.focal module path; only mean re-exported top-level; emerging_hotspots top-level vs hotspots module-level asymmetry noted, additive export would be a design call, not filed). cuda-validated: CUDA_AVAILABLE=True on this host; mean/apply/focal_stats/hotspots smoke-tested on cupy with kwarg parity; the apply default crash reproduced on GPU; hotspots weighted-kernel acceptance verified empirically."
|
|
4
|
+
geotiff,2026-06-12,3263;3265,MEDIUM,3;5,"Re-sweep 2026-06-12 (deep-sweep-api-consistency-geotiff-2026-06-12); prior pass 2026-06-09 (#3086). Scope: surface changes since 2026-06-09 (pack/unpack fixes #3171-#3241, SUPPORTED_FEATURES reader.unpack/writer.pack/reader.coregister, coregister docs #3248) plus a fresh 5-category pass on open_geotiff/to_geotiff. 2 MEDIUM findings filed and fixed on branches -01/-02 off this one. (#3263, MEDIUM Cat 3, PR #3269, branch -01) open_geotiff unpack docstring said 'A source without scale / offset metadata is a no-op', but unpack=True folds into the masking gate (_finalize_eager_read: mask_and_scale implies masking, rioxarray parity), so a sentinel-bearing uint16 source still comes back float64 with NaN holes; verified identical on all 4 backends (not a parity bug), only a source with neither scale/offset nor a sentinel reads unchanged. Docs-only fix + test_unpack_noop_doc_3263.py pinning wording (scoped to the unpack paragraph) and behavior. (#3265, MEDIUM Cat 5, PR #3273, branch -02) exception-export drift: VRTUnsupportedError (raised 10+ times in _vrt_validation.py on public .vrt reads, documented in geotiff_safe_io.rst which steered users to the private _errors module), CloudSizeLimitError (importable but not in __all__, sibling UnsafeURLError IS exported), and PixelSafetyLimitError (raised by the [stable] max_pixels cap, only importable from _layout/_reader) were the only 3 exceptions raised on public open_geotiff paths missing from the public surface (other 17 exported). Additive fix: import + __all__ + :class: roles in safe_io doc + trigger-point docs naming the exceptions in max_pixels/max_cloud_bytes param docs and geotiff.rst; test_exception_exports_3265.py pins export, identity with private definitions, and a functional max_pixels raise. Clean elsewhere: docstring/signature parity exact on both publics (programmatic check + 218 existing contract tests); no Cat 1 (signatures unchanged since 2026-06-09; pack/unpack pair deliberate), no Cat 2 (DataArray / path returns unchanged), no Cat 4 (shared allow_* defaults match reader/writer; gpu False-vs-None auto-detect documented). SUPPORTED_FEATURES tiers (reader.unpack/writer.pack/reader.coregister experimental) agree with docstring tier markers. coregister= itself lives on accessor.py (excluded module) -- only its SUPPORTED_FEATURES registration is in geotiff, consistent. cuda-validated: CUDA_AVAILABLE=True; open_geotiff smoke-tested with identical kwargs on numpy/cupy/dask/dask+cupy (cpu/gpu pixel parity), to_geotiff gpu=True, cupy pack=True write (#3240 fix confirmed), deprecated aliases mask_and_scale/name/mask_nodata all warn. Both PRs reviewed (COMMENTED) with findings fixed in follow-up commits c14844a8/af3c8a66; branches up to date with origin/main; left for user merge per REVIEW_REQUIRED."
|
|
5
|
+
hydro-d8,2026-05-29,2709,HIGH,1;5,"Sweep 2026-05-29 (deep-sweep-api-consistency-hydro-d8-2026-05-29). Scope = the 13 D8-variant files only; dinf/mfd read for reference but not modified. 1 HIGH Cat 1 + 1 MEDIUM Cat 5 fixed in this branch (#2709, PR #2716). HIGH Cat 1: stream_order_d8 named its strahler/shreve selector `ordering` while sibling stream_order_dinf/stream_order_mfd use `method`; both names live in the public API and the __init__.py _StreamOrderDispatch special-cases the drift (translates ordering->method for non-d8). Fix adds `method` as an accepted alias on stream_order_d8 (case-insensitive; takes precedence; conflicting ordering+method raises ValueError), keeping `ordering` working so the out-of-scope dispatcher (passes ordering=) and existing callers are unaffected. Full rename to `method` deferred because deprecating `ordering` would warn on every stream_order(routing='d8') call via the dispatcher I cannot touch in this scope. MEDIUM Cat 5: basins_d8 (watershed_d8.py) is a backward-compat wrapper whose docstring said 'use basin instead' but emitted no warning; added DeprecationWarning(stacklevel=2). Tests added for alias parity/precedence/conflict/case-insensitivity and for the basins_d8 warning. Findings documented but NOT filed per template: (LOW Cat 1 cross-module, out of scope) dinf siblings name the first arg `flow_dir_dinf` (stream_link/flow_path/hand/watershed_dinf) while all D8 funcs use the cleaner `flow_dir`; D8 is the better convention so no D8 change -- the drift lives in the dinf files. (LOW Cat 4 defensive-validation drift) hand_d8 validates np.isfinite(threshold) but stream_link_d8/stream_order_d8 (same threshold: float = 100 param) do not; not user-facing signature surprise, document only. No Cat 2 return drift (every D8 public fn returns xr.DataArray with coords/dims/attrs preserved; Dataset in -> Dataset out via @supports_dataset). No Cat 3 missing-hints beyond fill_d8 z_limit (optional, no hint) which mirrors its sibling style. All 13 D8 funcs are re-exported in xrspatial/hydro/__init__.py (no orphan API). cuda-validated: CUDA_AVAILABLE=True on this host; method-alias parity smoke-tested on a cupy DataArray. CI: ubuntu/windows/3.12 GitHub Actions green; macOS-3.14 + ReadTheDocs slow but no failures. NOTE: the /review-pr review comment could not be posted to GitHub (auto-mode permission denial on gh pr review); review findings were applied to code instead (case-insensitive conflict check + str|None hint, commit f8467320)."
|
|
6
|
+
interpolate,2026-06-12,3285,MEDIUM,2,"Sweep 2026-06-12 (deep-sweep-api-consistency-interpolate-2026-06-12). Scope: idw/_idw.py, kriging/_kriging.py, spline/_spline.py, shared _validation.py. 1 MEDIUM Cat 2 finding filed as #3285, fixed on branch -01 off this one: kriging(return_variance=True) singular-matrix fallback (_kriging.py:499) returns prediction, prediction.copy() so the variance DataArray keeps the prediction's name instead of f'{name}_variance' (normal path :523 names it correctly); reproduced by monkeypatching _build_kriging_matrix to None; anything keying on .name (xr.merge, Dataset build) silently collapses the pair. One-line fix + regression test on the singular path. Clean elsewhere: Cat 1 in-module exact (idw/kriging/spline share x, y, z, template positionals and name= default '<func>'; template matches kde's template=); docstring/signature parity exact on all 3 publics (every param documented, Returns sections match incl. kriging's tuple); Cat 4 no default drift (power=2.0, k=None, fill_value=nan, variogram_model='spherical', nlags=15, smoothing=0.0, all single-owner params); Cat 5 no orphan API (all 3 re-exported in xrspatial/__init__.py and autosummaried in docs/source/reference/interpolation.rst; tests touch private helpers only via module paths). Cross-cutting, notes only per template: fill_value (idw) vs fill (rasterize) for the uncovered-pixel value is library-wide drift (idw matches numpy's fill_value convention, left alone); public functions are untyped module-wide (consistent internally, drifts from typed kde/rasterize/proximity siblings -- annotation pass would span the whole module, LOW, not filed); kde's keyword-only style is the library minority so interpolate's positional style matches the rasterize/proximity majority. GPU k-nearest rejection (NotImplementedError) is deliberate and documented in the k param docstring. cuda-validated: CUDA_AVAILABLE=True on this host; idw/kriging/spline smoke-tested with full kwargs on numpy AND cupy DataArrays (variance name parity confirmed on both), dask+numpy and dask+cupy graph construction verified without compute."
|
|
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
|
+
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
|
+
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."
|
|
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."
|
|
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)."
|
|
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
|
+
reproject,2026-06-09,3095;3097,HIGH,1;2;3,"Sweep 2026-06-09 (deep-sweep-api-consistency-reproject-2026-06-09). 2 findings filed and fixed: #3095 -> PR #3125, #3097 -> PR #3134 (branches -01/-02 off this one). (HIGH Cat 2, #3095) merge() raises TypeError ('Implicit conversion to a NumPy array is not allowed') on cupy-backed inputs while sibling reproject() supports numpy/cupy/dask+numpy/dask+cupy; crash site _merge_inmemory info['raster'].values (__init__.py:2572); dask-of-cupy fails the same way at compute via _merge_block_adapter -> _reproject_chunk_numpy/np.asarray. _merge.py has a complete _merge_arrays_cupy that is imported in __init__.py:38 but never called (dead GPU plumbing; the unused import alone is lint issue #3083 from the style sweep). Fix: host round-trip on entry (same pattern as _apply_vertical_shift), GPU result out, docstring documents backend handling. (MEDIUM Cat 3, #3097) _vertical.py Returns docstrings claim 'same type as input/height' but geoid_height(DataArray) returns np.ndarray (verified empirically) and the four conversion wrappers return np.float64/np.ndarray; geoid_height converts scalars to Python float but the wrappers do not (sibling scalar-return drift). Docs-only fix. Documented but NOT fixed: (LOW Cat 1) itrf_transform(src=/tgt=) abbreviations vs source_/target_ elsewhere -- prior 2026-05-29 sweep already weighed this and left it as-is (frames, not CRSes); filed #3099 before noticing the prior disposition, then closed it as not-planned to avoid churn. (LOW Cat 5) module docstring 'Public API' section lists only reproject/merge while __all__ exports 10 names (vertical+itrf funcs invisible in help() header; docs/source/reference/reproject.rst autosummary likewise lists only reproject/merge). Cross-cutting, notes only per template: raster/rasters (reproject) vs agg (terrain family) vs source (geotiff); chunk_size (reproject/merge) vs chunks (open_geotiff); resampling+resolution (reproject/merge/accessor) vs method+target_resolution (resample.py -- resample is the outlier, belongs to a resample-module pass, already in resample row's notes). No Cat 4 default drift (resampling='bilinear'/transform_precision=16/chunk_size=None/bounds_policy='auto'/model='EGM96' consistent across siblings). reproject()/merge() kwarg parity smoke-tested on numpy AND cupy DataArrays (merge cupy crash found exactly there). cuda-validated: CUDA_AVAILABLE=True on this host. CI: all GitHub Actions checks green on both PRs; RTD flapped (pending on #3125, fail on #3134 -- repo-wide backlog, change not docs-rendered); PRs left BLOCKED on REVIEW_REQUIRED for the user to merge."
|
|
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."
|
|
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."
|
|
17
|
+
templates,2026-06-26,,MEDIUM,3,"Cat3 MEDIUM: from_template/list_templates lacked type hints while sibling generate_terrain is annotated; added hints (non-breaking). resolution param vs res attr naming intentional, not flagged. No __all__ (library norm)."
|
|
18
|
+
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."
|
|
19
|
+
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."
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
module,last_inspected,issue,severity_max,categories_found,notes,doc_coverage
|
|
2
|
-
flood,2026-06-25,,HIGH,1;4;5,"Cat4 HIGH: vegetation_roughness, vegetation_curve_number, flood_depth_vegetation public but absent from reference/flood.rst; Cat1 MEDIUM: no Examples on any of 7 public funcs; Cat5 MEDIUM: backend support undocumented (all 4 backends) + NaN propagation undocumented for curve_number_runoff/travel_time. Fixed in deep-sweep-documentation-flood-2026-06-25: added 3 rst entries, Examples+backend Notes to all 7 funcs (examples executed OK on CUDA host), NaN notes. PR #3502 opened with the fix; gh issue create blocked by auto-mode classifier so no issue number.",7/7
|
|
3
2
|
classify,2026-06-25,3506,MEDIUM,1;3,"Cat3: reclassify (numpy/dask/cupy blocks) + equal_interval example outputs were stale/wrong, binary used np.nan in array repr; corrected to actual output (tests confirm code is correct). Cat1: added missing Examples to std_mean, head_tail_breaks, percentiles, maximum_breaks, box_plot. Fixed in deep-sweep-documentation-classify-2026-06-25 (PR for #3506). Cat2 natural_breaks num_sample-None omission already tracked in #3501 (left alone). All 10 public funcs listed in reference/classification.rst (no Cat4 gap). CUDA available: ran numpy examples; cupy/dask reprs reviewed statically.",10/10
|
|
4
|
-
geotiff,2026-06-25,,MEDIUM,1,"to_geotiff (public write entry point) had Parameters/Returns/Raises but no Examples section while open_geotiff does (Cat1 MEDIUM); added Examples block (plain GeoTIFF, cog=True, .vrt mosaic) modeled on open_geotiff; fixed on deep-sweep-documentation-geotiff-2026-06-25; repo issues disabled so no issue number. Cat2/3/4/5 clean: open_geotiff/to_geotiff signature-docstring parity locked by parity/test_signature_contract.py + write/test_bigtiff.py + test_polish.py; both funcs in autosummary in reference/geotiff.rst; reference page mirrors SUPPORTED_FEATURES tiers (tier-parity gate); CUDA available, all docstring examples are +SKIP illustrative only",2/2
|
|
5
3
|
fire,2026-06-25,,MEDIUM,1;5,"all 7 public funcs (dnbr, rdnbr, burn_severity_class, fireline_intensity, flame_length, rate_of_spread, kbdi) lacked Examples section (Cat1 MEDIUM) and backend-support note (Cat5 MEDIUM); fixed in deep-sweep-documentation-fire-2026-06-25-01; repo issues disabled so no issue number; examples run and outputs match numpy backend; all 7 listed in reference/fire.rst; no Cat2/Cat3/Cat4 issues",7/7
|
|
4
|
+
flood,2026-06-25,,HIGH,1;4;5,"Cat4 HIGH: vegetation_roughness, vegetation_curve_number, flood_depth_vegetation public but absent from reference/flood.rst; Cat1 MEDIUM: no Examples on any of 7 public funcs; Cat5 MEDIUM: backend support undocumented (all 4 backends) + NaN propagation undocumented for curve_number_runoff/travel_time. Fixed in deep-sweep-documentation-flood-2026-06-25: added 3 rst entries, Examples+backend Notes to all 7 funcs (examples executed OK on CUDA host), NaN notes. PR #3502 opened with the fix; gh issue create blocked by auto-mode classifier so no issue number.",7/7
|
|
5
|
+
geotiff,2026-06-25,,MEDIUM,1,"to_geotiff (public write entry point) had Parameters/Returns/Raises but no Examples section while open_geotiff does (Cat1 MEDIUM); added Examples block (plain GeoTIFF, cog=True, .vrt mosaic) modeled on open_geotiff; fixed on deep-sweep-documentation-geotiff-2026-06-25; repo issues disabled so no issue number. Cat2/3/4/5 clean: open_geotiff/to_geotiff signature-docstring parity locked by parity/test_signature_contract.py + write/test_bigtiff.py + test_polish.py; both funcs in autosummary in reference/geotiff.rst; reference page mirrors SUPPORTED_FEATURES tiers (tier-parity gate); CUDA available, all docstring examples are +SKIP illustrative only",2/2
|
|
6
|
+
interpolate-idw,2026-06-26,,MEDIUM,1;5,"Cat1 MEDIUM: idw (only public func in _idw.py) had Parameters/Returns/Raises but no Examples section. Cat5 MEDIUM: backend support undocumented (numpy/cupy/dask+numpy/dask+cupy via ArrayTypeFunctionMapping) + k-nearest GPU rejection (NotImplementedError) and NaN/inf input-point dropping undocumented. Doc-only fix on deep-sweep-documentation-interpolate-idw-2026-06-26: added backend-support line, Examples block (executed, output matches), Returns dtype/NaN/fill_value notes. Cat2 clean (all 9 params documented, defaults/types match signature). Cat3 n/a (no prior examples). Cat4 clean (idw listed in reference/interpolation.rst autosummary). CUDA available: ran numpy example; cupy/dask paths covered by test_interpolation.py (92 pass). repo issues disabled so no issue number.",1/1
|
|
6
7
|
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
|
|
8
|
+
templates,2026-06-26,3541,MEDIUM,3;5,"Cat3/Cat5 MEDIUM: from_template docstring example 'from_template(""FRA"", preserve=""shape"").attrs[""crs""]' showed 32631/UTM 31N but code returns 32630/UTM 30N (GADM FRA bbox includes overseas territories, centroid lon -2.98 -> UTM 30N; code correct per documented centroid-UTM contract). Doc-only fix on deep-sweep-documentation-templates-2026-06-26; issue #3541, PR pending. Both public funcs (from_template, list_templates) fully documented and in reference/templates.rst (no Cat1/Cat2/Cat4). CUDA available: ran all docstring examples incl. preserve paths; 63/63 test_templates.py pass.",2/2
|
|
@@ -9,7 +9,7 @@ diffusion,2026-06-20,3422,HIGH,1;2;3;4,"Pass 1 (2026-06-20, deep-sweep test-cove
|
|
|
9
9
|
fire,2026-06-25,,HIGH,2,"Deep-sweep 2026-06-25 test-coverage on a CUDA host. Backend matrix already complete: all 7 public funcs (dnbr/rdnbr/burn_severity_class/fireline_intensity/flame_length/rate_of_spread/kbdi) x 4 backends present and green (Cat 1 no gap). NaN covered (per-func nan_propagation + #3394 dtype parity). Cat 4 covered: rate_of_spread tests all 13 fuel models + invalid 0/14; kbdi annual_precip invalid 0/-100; fireline heat_content default+custom. Cat 5 covered via general_output_checks on every func. Found one gap: Cat 2 +Inf/-Inf inputs were untested on every function. Probed all 4 backends live: behavior is fully consistent and well-defined (no divergence, no bug) -- e.g. dnbr inf-inf->nan, burn_severity_class +inf->7/-inf->1, kbdi prev=inf clamps to 800, rate_of_spread slope=inf->nan. Added test-only regression: per-func numpy Inf contract (locks exact values) + 4-backend Inf parity (28 new tests, all RAN and PASSED on GPU). No source change; the kernels' only finite guard is v!=v so these lock that contract. Cat 3 1x1/strip: per-pixel kernels (no neighborhood window) so no degeneracy risk, and 1x1/1xN already exercised by kbdi/rdnbr/flame tests -> LOW, not added."
|
|
10
10
|
flood,2026-06-25,,MEDIUM,1,"Deep-sweep 2026-06-25 test-coverage on a CUDA host. Module is densely tested (1051 test LOC vs 966 source). Backend matrix nearly complete: all 7 public funcs x 4 backends present and green EXCEPT vegetation_roughness mode='ndvi' on dask+cupy -- _veg_roughness_ndvi_dask_cupy was dispatched (flood.py:585) but never invoked by any test (nlcd dask+cupy, ndvi cupy, ndvi dask all tested). Cat 1 MEDIUM: added TestVegRoughnessDaskCuPy::test_ndvi_numpy_equals_dask_cupy mirroring the nlcd case; GPU-validated locally (passed, full file 89 passed). Cat 2 NaN well covered per-func incl #1104 (NaN curve_number) and #1437 (mannings_n DataArray) regressions; Inf inputs untested but low-risk (HAND/rainfall Inf -> NaN), not flagged. Cat 3 1xN strips + 1x1 covered for several funcs. Cat 5 metadata preserved is asserted on every backend test via general_output_checks (verify_attrs defaults True), so inundation/curve_number_runoff lacking a dedicated coords test is NOT a real gap. No source bugs found."
|
|
11
11
|
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."
|
|
12
|
-
geotiff,2026-06-
|
|
12
|
+
geotiff,2026-06-26,3545,MEDIUM,1;4,"Pass 24 (2026-06-26, deep-sweep test-coverage, CUDA host): delta audit of the geotiff commits since pass 23 (06-25): #3537/#3538 continuous-symbology sidecars (_symbology.py + color_ramp/color_ramp_range wired into the shared _write_sidecars closure in _writers/eager.py), #3522 short-row/non-well-formed PAM RAT crash fix, #3521 docstring, #3517 isort. Filed #3545 (tests). MEDIUM Cat 1/Cat 4: #3537's emit is covered on eager numpy but four branches had no test driving them -- color_ramp_range asserted bounds only on numpy (its documented purpose is the dask escape hatch that skips _finite_stats; the dask test only checked file existence); dask+cupy write emission (gpu=True over a dask array) untested; _is_single_band 3D length-1-band branch untested (only 2D + multiband-skip covered); attrs['nodata'] exclusion verified only in the _finite_stats unit, never end-to-end through to_geotiff. Live-probed all four on this CUDA host: correct behaviour (coverage gaps, not bugs). Added 4 tests to write/test_symbology_sidecar_3537.py (test_dask_gpu_write_emits_sidecars [requires_gpu, RAN+passing], test_dask_color_ramp_range_sets_bounds, test_3d_single_band_emits_sidecars, test_nodata_attr_excluded_from_ramp_bounds); full file 25 passed incl. GPU legs. Verified NOT gaps this pass: #3522 short-row + non-well-formed XML RAT covered by test_rasterize_categorical_3482.py (40-line block); #3518/#3519 categorical sidecar dask/GPU added in pass 23. LOW (carried, documented not fixed): Inf as the declared nodata sentinel still never tested."
|
|
13
13
|
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
14
|
interpolate,2026-06-12,3290,MEDIUM,2;3;4;5,"Deep-sweep 2026-06-12 on CUDA host. Backend coverage already complete: all 4 backends exercised for idw/kriging/spline incl. cross-backend equivalence and variance paths; no Cat 1 gaps. Filed #3290 for MEDIUM gaps, all verified correct-by-probe before filing (test-only fix): idw fill_value zero-weight branch (deterministic via 1e200 distance weight underflow; added numpy+dask+cupy, cupy RAN+PASSED), idw power only tested at default (exact oracle 10/(2^p+1)), spline collinear lstsq fallback, kriging duplicate points + all-equal-z (zero-variance variogram) + exactly-singular K regularisation retry (unit test on _build_kriging_matrix with all-zero variogram), spline/kriging 1x1 template, Inf/-Inf point filtering (only NaN was tested), lat/lon dim-name propagation (parametrized all 3 funcs), idw attrs preservation, 0-column template. Remaining minor untested: _build_kriging_matrix warn-then-NaN branch (needs mocked LinAlgError on retry). LOW documented not fixed: no asv benchmarks, non-uniform cell spacing unasserted. Full file 82 passed 0 skipped locally."
|
|
15
15
|
interpolate-kriging,2026-06-04,2920;2921,HIGH,1;2;3;4;5,"Single public fn kriging(); all 4 backends already had cross-backend parity tests (numpy/cupy/dask+numpy/dask+cupy) incl. cupy & dask+cupy variance -- ran green on CUDA host. Gaps closed (test-only, #2921): Cat1 dask+numpy return_variance branch (_chunk_var) was untested -> added test_dask_return_variance_matches_numpy (atol=1e-12, var ~1e-14). Cat4 nlags only default(15) tested -> added non-default nlags=5 + invalid paths (nlags=0/-1 ValueError, nlags=2.5 TypeError). Cat2/3 two-point <3-lag-bins UserWarning branch -> test_two_point_warns_few_lag_bins. Cat2 all-NaN kriging input -> test_kriging_all_nan_points (only idw covered before). Cat5 output metadata (coords/dims/attrs/name) untested -> added test_output_metadata. Single-point kriging CRASHES (zero-size array reduction in _experimental_variogram, N=1) -- real source bug filed #2920; added xfail(strict, raises=ValueError) test_single_point documenting expected graceful behavior; source fix left to #2920 (test-only PR). LOW/not filed: singular-matrix K_inv-is-None all-NaN branch is defensive and unreachable via public API. GPU-validated."
|
|
@@ -25,6 +25,7 @@ rasterize,2026-06-18,2614;3102;3105;3296;3383,HIGH,4,"Pass 7 (2026-06-18, deep-s
|
|
|
25
25
|
reproject,2026-06-09,2618;3050;3100;3101;3141,MEDIUM,1,"CI follow-up same day: first CI run of the threaded streaming branch hard-crashed macos-arm64 py3.14 (SIGABRT in numba call_cfunc, two ThreadPoolExecutor threads concurrently inside try_numba_transform/tmerc_inverse) -- the projection kernels are @njit(parallel=True) and numba's workqueue threading layer aborts on concurrent entry; filed source bug #3141. Test fix: threaded parity test now uses transform_precision=0 (per-thread pyproj Transformer, no numba), the NaN multi-tile test and 3-D xfail forced serial (max_memory=1) so the numba fast path stays covered without concurrent entry. windows-3.14 failure was fail-fast collateral (its suite fully passed). Pass 2026-06-09 (deep-sweep test-coverage): delta re-sweep one day after the 2026-06-08 pass; module modified today by #3077 (datum-probe warning silencing) and #3081 (merge output-size guard backend-aware) -- both landed WITH their own tests (TestDatumProbeNoProjWarning; TestSecurityGuards merge-guard trio incl. the monkeypatched in-memory raise), so the delta added no gap; the guard branching is is_dask-only, so cupy eager shares the tested numpy branch (no per-backend guard test needed). Found one MEDIUM Cat 1 gap every prior pass missed: the 5th dispatch branch of reproject() -- the streaming fallback (_reproject_streaming / _process_tile_batch / _parse_max_memory, taken when source >512MB and dask is not importable) -- had zero coverage anywhere; _parse_max_memory only runs on that branch so the existing max_memory kwarg tests never reached it. Filed #3101, added test_reproject_streaming_3101.py (15 tests: parity vs in-memory numpy for threaded / serial(max_memory=1) / single-tile / nearest+NaN, plus 10 _parse_max_memory unit cases). Probe surfaced source bug #3100: streaming assembly allocates a 2-D output buffer but 3-D sources yield (h,w,b) tiles -> ValueError broadcast in both assembly loops; pinned with strict xfail, source fix left to #3100 (test-only PR, source untouched). CPU-only path so no GPU tests needed (CUDA host; file ran 14 passed + 1 xfailed). LOW carried (documented, not fixed): reproject(name=) / merge(name=) override values untested (only merge name fallback covered); non-square-cellsize successful anisotropic run; dask.bag distributed branch of _reproject_streaming still unexercised (needs a live distributed client). || PREVIOUS: Pass 2026-06-08 (deep-sweep test-coverage): #3050 closes the one live gap found this pass. reproject()'s dask+cupy backend was parity-tested only with resampling='cubic' (TestCupyPyprojFallbackParity::test_projected_to_projected_dask_cupy_match); nearest/bilinear were covered on numpy (end-to-end) and eager cupy (parametrized test_projected_to_projected_numpy_cupy_match) but never on the dask+cupy chunk-assembly path. Parametrized that test over ['nearest','bilinear','cubic']; all 3 RUN+PASS on a CUDA host. Cat 4 MEDIUM (resampling-mode parameter coverage on the dask+cupy backend). Test-only, source untouched. Re-confirmed _merge.merge() has NO genuine cupy/dask+cupy backend (_merge_inmemory/_merge_dask use _merge_arrays_numpy + raster.values; _merge_arrays_cupy is imported but never dispatched = dead code, not a test gap) matching the prior pass's observation. reproject() otherwise saturated across all 4 backends, NaN/Inf/all-NaN, degenerate shapes, metadata, vertical, bounds_policy, integer nodata. LOW (documented, not filed): dask+cupy resampling-mode parity is the only per-mode-per-backend cell that had been missing. || PREVIOUS: Pass 2026-05-29: reproject already has a deep suite (369 tests in test_reproject.py + coverage/gate files) covering all 4 backends, NaN/Inf/all-NaN/all-Inf, 1x1/2x2, metadata, vertical shift, bounds_policy x backends, integer nodata x backends. Gaps found: Cat 3 HIGH single-row (1xN) and single-col (Nx1) strip rasters never tested (hit size<2 branch of _validate_regular_axis + degenerate resampling axis); Cat 3 MEDIUM constant-value/zero-gradient raster never reprojected. Added TestDegenerateShapeReproject (12 tests): 1xN+Nx1 strips x numpy/dask/cupy/dask+cupy, constant raster numpy value-preservation + cross-backend parity. All 12 executed and passed on a CUDA host. Test-only, no source change (#2618). LOW (documented only): _merge._merge_arrays_cupy imported but never called by merge() (host-bounces via _merge_arrays_numpy) - dead-code source observation not a test gap; non-square cellsize reproject only covered via resolution-tuple validation errors not a successful anisotropic run."
|
|
26
26
|
resample,2026-05-29,2547;2615,HIGH,1;2;3;5,"Pass 2 (2026-05-29): added test_resample_cupy_agg_fallback_2615.py (6 tests, all passing on CUDA host). Closes Cat 1 MEDIUM backend-coverage gap: the cupy eager aggregate CPU fallback for average/min/max at a NON-integer downsample factor (_run_cupy fy==int(fy) branch in resample.py ~L957-973) was never exercised; existing TestCuPyParity used 12x12 scale 0.5 (integer factor 2 -> GPU reshape path) and only median/mode hit the host fallback. New tests use 10x10 scale 0.3 (factor 3.33) for average/min/max parity vs numpy plus a NaN-masked variant. Issue #2615. Module is otherwise very thoroughly covered (test_resample.py + 3 supplementary files); no remaining HIGH gaps found. Pass 1 (2026-05-27): added test_resample_coverage_2026_05_27.py with 70 tests (68 passing, 2 skipped). Closes Cat 3 HIGH Nx1 single-column gap across numpy/cupy/dask+numpy/dask+cupy x 8 methods (nearest/bilinear/cubic/average/min/max/median/mode) plus Nx1 upsample-nearest parity and Nx1 cross-backend aggregate parity. Closes Cat 2 MEDIUM NaN-parity gap on cupy and dask+cupy (existing TestCuPyParity/TestDaskCuPyParity used random data without NaN; the weight-mask gate and spline-prepad had no GPU NaN coverage). Closes Cat 3 MEDIUM all-equal-value raster across 8 methods (downsample) and 3 interp methods (upsample) plus a constant-with-NaN aggregate variant. Closes Cat 5 MEDIUM non-default dim-name propagation: lat/lon, latitude/longitude, and (channel, lat, lon) 3D round-trip without being renamed to y/x; per-dim attrs (units) preserved. Closes Cat 3 MEDIUM empty-raster behaviour pin: 0-row and 0-col rasters raise (currently IndexError) -- contract covered. Filed source-bug issue #2547: cubic on dask backends fails for Nx1 / arrays smaller than depth=16; the 2 skipped tests in this file gate on that fix landing. Source untouched."
|
|
27
27
|
slope,2026-05-29,2697,MEDIUM,3,"PR #2703: added degenerate-shape tests (1x1/1xN/Nx1) for all 4 planar backends + geodesic; no live bug, pins all-NaN+shape contract. CUDA host: cupy/dask+cupy ran. Backend/NaN/param/metadata coverage already complete."
|
|
28
|
+
templates,2026-06-26,3540,MEDIUM,3;4,"Deep-sweep test-coverage on a CUDA host (cuda available). Backend matrix already complete: from_template x4 backends (numpy/dask+numpy/cupy/dask+cupy) + dask alias + bad-backend all tested and green; preserve path also covers dask+cupy. Cat 2 N/A (procedural generator, no raster input; fill=NaN and fill=0 tested). Cat 5 covered (attrs/dims/coords + dask-vs-eager attrs equality asserted). Found two MEDIUM coverage gaps, no source bug. Cat 3: the max(1,...) width/height floor (single-pixel + Nx1/1xN strip) was untested -- probed live, (1,1) and (1,N) build correctly. Cat 4: the _normalize_resolution wrong-length tuple ValueError was the one validation error path with no test (all siblings tested). Added test-only test_single_pixel_grid, test_strip_grid, test_resolution_tuple_wrong_length; all RAN and PASSED on the CUDA host (66 passed, 0 skipped). LOW (documented, no test): dask+cupy block test does not assert value/coord parity with numpy; chunks param only exercised at default 'auto'. PR #3540 opened with the three tests. Standalone issue creation was blocked by the auto-mode classifier; humanized issue draft saved to scratchpad."
|
|
28
29
|
viewshed,2026-05-29,2693,HIGH,1;2;5,"Pass 1 (2026-05-29): added 4 new test groups to test_viewshed.py (13 new tests + 1 xfail, all passing/xfailing on a CUDA+RTX host). Closes Cat 1 HIGH backend-coverage gap: the dask+cupy dispatch path in _viewshed_dask (Tier B) and _viewshed_windowed (max_distance) was registered but never invoked by any test -- added test_viewshed_dask_cupy_flat (analytical-angle parity, atol 0.03) and test_viewshed_dask_cupy_max_distance (windowed GPU run; observer cell 180, corners INVISIBLE). Both use non-zero flat terrain (1.3) because the RTX mesh builder rejects an all-zero raster (#1378). Closes Cat 5 HIGH metadata-preservation gap: only the numpy test_viewshed called general_output_checks; the cupy/dask/dask+cupy and max_distance paths never asserted attrs/coords/dims/array-type preservation. Added parametrised test_viewshed_metadata_preserved over {numpy,cupy,dask+numpy,dask+cupy} x {full, max_distance=2.0}: asserts attrs==, dims==, shape==, x/y coords allclose; runs general_output_checks (full type parity) for all backends except dask+cupy. Closes Cat 2 HIGH NaN-input gap and surfaced source bug #2693: viewshed on a numpy raster crashes with ValueError 'node not found' from _delete_from_tree when a NaN cell sits at certain positions (e.g. (2,4) in a 5x5 with observer at (2,2)), while NaN at (1,1)/(0,0)/(4,4) runs fine. Added test_viewshed_nan_input_supported_positions (parametrised working positions, asserts observer=180 and NaN cell is INVISIBLE/NaN) plus test_viewshed_nan_input_crashing_position (xfail strict, raises, links #2693). Noted but NOT fixed (source change out of scope for test sweep): the dask+cupy backend does not preserve the cupy backing -- _viewshed_dask computes then rewraps via da.from_array(result_np), so the output computes to numpy not cupy; general_output_checks is skipped for dask+cupy for that reason (candidate for the metadata/backend-parity sweep). LOW (documented only): non-square cell sizes; 1x1 and 1xN geometry covered behaviourally by probing (run without error). Test-only PR; viewshed.py untouched."
|
|
29
30
|
visibility,2026-06-10,3192,HIGH,1;2;4,"cupy cumulative_viewshed/visibility_frequency broken (numpy count + cupy viewshed) -> issue #3192 (dup #3193), fix in flight in #3205 with its own cupy parity tests, xfail pins dropped to avoid an XPASS race; added cupy _extract_transect+line_of_sight parity, NaN LOS, Fresnel-blocked branch; dask+metadata already covered"
|
|
30
31
|
zonal,2026-06-10,,HIGH,1,"deep-sweep test-coverage on CUDA host (cupy + dask+cupy live). Cat1 HIGH: regions() cupy/dask+cupy backends (_regions_cupy/_regions_dask_cupy via cupyx.scipy.ndimage.label) had ZERO test coverage -- every test_regions_* was ['numpy','dask+numpy'] only. Added test_regions_gpu_matches_numpy (cupy + dask+cupy, cell-by-cell parity vs numpy + general_output_checks). Cat1 MEDIUM: crosstab() 2D count and percentage aggs were ['numpy','dask+numpy'] only; extended test_count_crosstab_2d and test_percentage_crosstab_2d to all 4 backends (_crosstab_cupy/_crosstab_dask_cupy now exercised for count AND percentage; previously only count via the cat_ids #2560 test). All new/modified tests RAN and PASSED on GPU; full test_zonal.py 185 passed. No source bugs surfaced -- test-only change, no rockout PR needed beyond test additions. hypsometric_integral already fully covered in test_hypsometric_integral.py (4 backends, NaN/flat/single-cell/all-NaN/metadata). NOT gaps. LOW (documented, not fixed): trim()/crop() exercise cupy via _crop_backends_2561 but trim() has no cupy/dask+cupy parametrized parity test (trim source supports cupy); stats() return_type='xarray.DataArray' rejected on non-numpy so no GPU gap there."
|
|
@@ -2,6 +2,32 @@
|
|
|
2
2
|
-----------
|
|
3
3
|
|
|
4
4
|
|
|
5
|
+
### Version 0.10.14 - 2026-06-28
|
|
6
|
+
|
|
7
|
+
#### New features
|
|
8
|
+
- templates: add regional templates to from_template for Africa, Asia, the Americas, and Oceania (#3553)
|
|
9
|
+
- templates: add global-projection templates to from_template (web_mercator, wgs84/latlon, equal_earth) (#3550)
|
|
10
|
+
- templates: accept explicit height/width and produce dask-aligned extents in from_template (#3567)
|
|
11
|
+
- templates: add coregister and neighborhood-friendly dask chunks to from_template (#3562)
|
|
12
|
+
- accessor: expose multi_stop_search on the .xrs DataArray and Dataset accessors (#3564)
|
|
13
|
+
|
|
14
|
+
#### Bug fixes and improvements
|
|
15
|
+
- preview: recompute the res attribute for downsampled preview() output (#3570)
|
|
16
|
+
- rasterize/kde/line_density: set output attrs['res'] when the grid resolution changes (#3572)
|
|
17
|
+
- classify: return all-NaN instead of crashing on all-non-finite input (#3548)
|
|
18
|
+
- proximity: match the cKDTree max_distance check to the brute-force float32 convention (#3555)
|
|
19
|
+
- templates: guard dask grids against task-graph explosion (#3559)
|
|
20
|
+
- templates: skip the cell cap for lazy dask grids when chunks is supplied (#3556)
|
|
21
|
+
- terrain: speed up the generate_terrain numpy backend with a fused parallel kernel (#3566)
|
|
22
|
+
- templates: add type hints to from_template and list_templates (#3543)
|
|
23
|
+
- interpolate: add IDW examples and backend-support notes to the docs (#3547)
|
|
24
|
+
- templates: fix a stale UTM zone in the from_template FRA example (#3544)
|
|
25
|
+
- benchmark: guard the datashader import in the rasterizer benchmark (#3560)
|
|
26
|
+
- geotiff: cover symbology sidecars on dask, dask+GPU, 3D single-band, and color_ramp_range (#3546)
|
|
27
|
+
- templates: cover single-pixel/strip grids and resolution-tuple validation in tests (#3540)
|
|
28
|
+
- curvature: fix isort import-ordering (#3568)
|
|
29
|
+
|
|
30
|
+
|
|
5
31
|
### Version 0.10.13 - 2026-06-26
|
|
6
32
|
|
|
7
33
|
#### New features
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: xarray-spatial
|
|
3
|
-
Version: 0.10.
|
|
3
|
+
Version: 0.10.14
|
|
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
|
|
@@ -349,7 +349,7 @@ Built-in Numba JIT and CUDA projection kernels bypass pyproj for per-pixel coord
|
|
|
349
349
|
|
|
350
350
|
| Name | Description | Source | NumPy xr.DataArray | Dask xr.DataArray | CuPy GPU xr.DataArray | Dask GPU xr.DataArray |
|
|
351
351
|
|:----------:|:------------|:------:|:----------------------:|:--------------------:|:-------------------:|:------:|
|
|
352
|
-
| [from_template](xrspatial/templates.py) | Empty study-area grid for a named region (CONUS, NYC, ...), a world city (London, Tokyo, ... in its UTM zone)
|
|
352
|
+
| [from_template](xrspatial/templates.py) | Empty study-area grid for a named region (CONUS, NYC, ...), a world city (London, Tokyo, ... in its UTM zone), a country code, or a whole-world projection (web_mercator, wgs84/latlon, equal_earth); `preserve='area'/'shape'` picks an EPSG projection by property; `list_templates()` lists every accepted name | Custom | ✅ | 🔼 | 🔼 | 🔼 |
|
|
353
353
|
|
|
354
354
|
-----------
|
|
355
355
|
|
|
@@ -274,7 +274,7 @@ Built-in Numba JIT and CUDA projection kernels bypass pyproj for per-pixel coord
|
|
|
274
274
|
|
|
275
275
|
| Name | Description | Source | NumPy xr.DataArray | Dask xr.DataArray | CuPy GPU xr.DataArray | Dask GPU xr.DataArray |
|
|
276
276
|
|:----------:|:------------|:------:|:----------------------:|:--------------------:|:-------------------:|:------:|
|
|
277
|
-
| [from_template](xrspatial/templates.py) | Empty study-area grid for a named region (CONUS, NYC, ...), a world city (London, Tokyo, ... in its UTM zone)
|
|
277
|
+
| [from_template](xrspatial/templates.py) | Empty study-area grid for a named region (CONUS, NYC, ...), a world city (London, Tokyo, ... in its UTM zone), a country code, or a whole-world projection (web_mercator, wgs84/latlon, equal_earth); `preserve='area'/'shape'` picks an EPSG projection by property; `list_templates()` lists every accepted name | Custom | ✅ | 🔼 | 🔼 | 🔼 |
|
|
278
278
|
|
|
279
279
|
-----------
|
|
280
280
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: xarray-spatial
|
|
3
|
-
Version: 0.10.
|
|
3
|
+
Version: 0.10.14
|
|
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
|
|
@@ -349,7 +349,7 @@ Built-in Numba JIT and CUDA projection kernels bypass pyproj for per-pixel coord
|
|
|
349
349
|
|
|
350
350
|
| Name | Description | Source | NumPy xr.DataArray | Dask xr.DataArray | CuPy GPU xr.DataArray | Dask GPU xr.DataArray |
|
|
351
351
|
|:----------:|:------------|:------:|:----------------------:|:--------------------:|:-------------------:|:------:|
|
|
352
|
-
| [from_template](xrspatial/templates.py) | Empty study-area grid for a named region (CONUS, NYC, ...), a world city (London, Tokyo, ... in its UTM zone)
|
|
352
|
+
| [from_template](xrspatial/templates.py) | Empty study-area grid for a named region (CONUS, NYC, ...), a world city (London, Tokyo, ... in its UTM zone), a country code, or a whole-world projection (web_mercator, wgs84/latlon, equal_earth); `preserve='area'/'shape'` picks an EPSG projection by property; `list_templates()` lists every accepted name | Custom | ✅ | 🔼 | 🔼 | 🔼 |
|
|
353
353
|
|
|
354
354
|
-----------
|
|
355
355
|
|
|
@@ -45,6 +45,156 @@ _REGIONS = {
|
|
|
45
45
|
'nyc': dict(bounds=(558916, 4481270, 614426, 4534084), crs=32618,
|
|
46
46
|
default_resolution=30, label='New York City (UTM 18N)',
|
|
47
47
|
lonlat=(-74.30, 40.48, -73.65, 40.95)),
|
|
48
|
+
# Continental regions in their EPSG-coded GLANCE equal-area projection
|
|
49
|
+
# (Lambert azimuthal equal-area), the same family as Europe's LAEA. bounds
|
|
50
|
+
# are the lon/lat box projected into the GLANCE CRS. No shape_epsg is set:
|
|
51
|
+
# there is no EPSG conformal projection for these continental extents, so
|
|
52
|
+
# preserve='shape' falls back to the centroid's UTM zone (covers a slice
|
|
53
|
+
# only). The lon/lat boxes follow the real region extent and may run a
|
|
54
|
+
# degree past the GLANCE area of use near the equator; LAEA still projects
|
|
55
|
+
# those points finitely.
|
|
56
|
+
'southeast_asia': dict(
|
|
57
|
+
bounds=(-987821, -5961342, 4923248, -932582), crs=10594,
|
|
58
|
+
default_resolution=10000, label='Southeast Asia (GLANCE Asia LAEA)',
|
|
59
|
+
lonlat=(92.0, -11.0, 141.0, 28.0), area_epsg=10594),
|
|
60
|
+
'central_america': dict(
|
|
61
|
+
bounds=(821182, -4620810, 2695977, -3111382), crs=10598,
|
|
62
|
+
default_resolution=2000, label='Central America (GLANCE N. America LAEA)',
|
|
63
|
+
lonlat=(-92.5, 7.0, -77.0, 18.5), area_epsg=10598),
|
|
64
|
+
'caribbean': dict(
|
|
65
|
+
bounds=(1500961, -4302986, 4618873, -1455289), crs=10598,
|
|
66
|
+
default_resolution=5000, label='Caribbean (GLANCE N. America LAEA)',
|
|
67
|
+
lonlat=(-85.0, 9.0, -59.0, 27.5), area_epsg=10598),
|
|
68
|
+
'west_africa': dict(
|
|
69
|
+
bounds=(-4141633, -109304, -404383, 2659299), crs=10592,
|
|
70
|
+
default_resolution=5000, label='West Africa (GLANCE Africa LAEA)',
|
|
71
|
+
lonlat=(-18.0, 4.0, 16.0, 27.0), area_epsg=10592),
|
|
72
|
+
'north_africa': dict(
|
|
73
|
+
bounds=(-3867207, 1434990, 1804670, 3865653), crs=10592,
|
|
74
|
+
default_resolution=10000, label='North Africa (GLANCE Africa LAEA)',
|
|
75
|
+
lonlat=(-17.0, 18.0, 37.0, 38.0), area_epsg=10592),
|
|
76
|
+
'east_africa': dict(
|
|
77
|
+
bounds=(851984, -1872363, 3520386, 1573813), crs=10592,
|
|
78
|
+
default_resolution=5000, label='East Africa (GLANCE Africa LAEA)',
|
|
79
|
+
lonlat=(28.0, -12.0, 52.0, 18.0), area_epsg=10592),
|
|
80
|
+
'southern_africa': dict(
|
|
81
|
+
bounds=(-997536, -4373971, 2316937, -1421722), crs=10592,
|
|
82
|
+
default_resolution=5000, label='Southern Africa (GLANCE Africa LAEA)',
|
|
83
|
+
lonlat=(11.0, -35.0, 41.0, -8.0), area_epsg=10592),
|
|
84
|
+
'south_asia': dict(
|
|
85
|
+
bounds=(-4560937, -4342133, -175948, 56016), crs=10594,
|
|
86
|
+
default_resolution=5000, label='South Asia (GLANCE Asia LAEA)',
|
|
87
|
+
lonlat=(60.0, 5.0, 98.0, 38.0), area_epsg=10594),
|
|
88
|
+
'east_asia': dict(
|
|
89
|
+
bounds=(-2888124, -2967169, 4752508, 1872058), crs=10594,
|
|
90
|
+
default_resolution=10000, label='East Asia (GLANCE Asia LAEA)',
|
|
91
|
+
lonlat=(73.0, 18.0, 146.0, 54.0), area_epsg=10594),
|
|
92
|
+
'central_asia': dict(
|
|
93
|
+
bounds=(-4529046, -1031518, -748494, 2365024), crs=10594,
|
|
94
|
+
default_resolution=5000, label='Central Asia (GLANCE Asia LAEA)',
|
|
95
|
+
lonlat=(46.0, 35.0, 88.0, 56.0), area_epsg=10594),
|
|
96
|
+
'middle_east': dict(
|
|
97
|
+
bounds=(-6742347, -2794074, -2936764, 1798849), crs=10594,
|
|
98
|
+
default_resolution=5000, label='Middle East (GLANCE Asia LAEA)',
|
|
99
|
+
lonlat=(34.0, 12.0, 63.0, 42.0), area_epsg=10594),
|
|
100
|
+
'south_america': dict(
|
|
101
|
+
bounds=(-2461362, -4624186, 2901620, 3066400), crs=10603,
|
|
102
|
+
default_resolution=10000, label='South America (GLANCE S. America LAEA)',
|
|
103
|
+
lonlat=(-82.0, -56.0, -34.0, 13.0), area_epsg=10603),
|
|
104
|
+
# Oceania bounded west of the antimeridian (Australia, New Guinea, New
|
|
105
|
+
# Zealand) so the lon/lat box does not wrap 180.
|
|
106
|
+
'oceania': dict(
|
|
107
|
+
bounds=(-2736534, -4140479, 4725674, 773877), crs=10601,
|
|
108
|
+
default_resolution=10000, label='Oceania (GLANCE Oceania LAEA)',
|
|
109
|
+
lonlat=(110.0, -48.0, 179.0, -8.0), area_epsg=10601),
|
|
110
|
+
'australia': dict(
|
|
111
|
+
bounds=(-2397336, -3314170, 2074139, 552968), crs=10601,
|
|
112
|
+
default_resolution=5000, label='Australia (GLANCE Oceania LAEA)',
|
|
113
|
+
lonlat=(113.0, -44.0, 154.0, -10.0), area_epsg=10601),
|
|
114
|
+
'new_zealand': dict(
|
|
115
|
+
bounds=(2357704, -4140479, 3965299, -2362651), crs=10601,
|
|
116
|
+
default_resolution=2000, label='New Zealand (GLANCE Oceania LAEA)',
|
|
117
|
+
lonlat=(166.0, -48.0, 179.0, -34.0), area_epsg=10601),
|
|
118
|
+
'central_africa': dict(
|
|
119
|
+
bounds=(-1335054, -2091682, 1224158, 789768), crs=10592,
|
|
120
|
+
default_resolution=5000, label='Central Africa (GLANCE Africa LAEA)',
|
|
121
|
+
lonlat=(8.0, -14.0, 31.0, 12.0), area_epsg=10592),
|
|
122
|
+
'north_asia': dict(
|
|
123
|
+
bounds=(-2829330, 333534, 4672506, 4568106), crs=10594,
|
|
124
|
+
default_resolution=10000, label='North Asia (GLANCE Asia LAEA)',
|
|
125
|
+
lonlat=(60.0, 48.0, 179.0, 78.0), area_epsg=10594),
|
|
126
|
+
'greenland': dict(
|
|
127
|
+
bounds=(307428, 1266923, 3614205, 4339302), crs=10598,
|
|
128
|
+
default_resolution=5000, label='Greenland (GLANCE N. America LAEA)',
|
|
129
|
+
lonlat=(-74.0, 59.0, -11.0, 84.0), area_epsg=10598),
|
|
130
|
+
'canada': dict(
|
|
131
|
+
bounds=(-3271722, -999331, 3748086, 3935367), crs=10598,
|
|
132
|
+
default_resolution=10000, label='Canada (GLANCE N. America LAEA)',
|
|
133
|
+
lonlat=(-141.0, 41.0, -52.0, 84.0), area_epsg=10598),
|
|
134
|
+
'mexico': dict(
|
|
135
|
+
bounds=(-2026872, -3928666, 1581449, -1690630), crs=10598,
|
|
136
|
+
default_resolution=5000, label='Mexico (GLANCE N. America LAEA)',
|
|
137
|
+
lonlat=(-118.0, 14.0, -86.0, 33.0), area_epsg=10598),
|
|
138
|
+
'great_lakes': dict(
|
|
139
|
+
bounds=(506191, -972693, 2067092, 243847), crs=10598,
|
|
140
|
+
default_resolution=2000, label='Great Lakes (GLANCE N. America LAEA)',
|
|
141
|
+
lonlat=(-93.0, 41.0, -75.0, 49.5), area_epsg=10598),
|
|
142
|
+
'pacific_northwest': dict(
|
|
143
|
+
bounds=(-2033861, -823605, -752346, 508938), crs=10598,
|
|
144
|
+
default_resolution=2000, label='Pacific Northwest (GLANCE N. America LAEA)',
|
|
145
|
+
lonlat=(-125.0, 42.0, -111.0, 52.0), area_epsg=10598),
|
|
146
|
+
'gulf_coast': dict(
|
|
147
|
+
bounds=(193569, -2859113, 1963599, -1884446), crs=10598,
|
|
148
|
+
default_resolution=2000, label='Gulf Coast (GLANCE N. America LAEA)',
|
|
149
|
+
lonlat=(-98.0, 24.0, -81.0, 31.0), area_epsg=10598),
|
|
150
|
+
'new_england': dict(
|
|
151
|
+
bounds=(1914015, -633460, 2686814, 258722), crs=10598,
|
|
152
|
+
default_resolution=1000, label='New England (GLANCE N. America LAEA)',
|
|
153
|
+
lonlat=(-74.0, 41.0, -67.0, 47.5), area_epsg=10598),
|
|
154
|
+
'great_plains': dict(
|
|
155
|
+
bounds=(-483626, -2100615, 387002, -99072), crs=10598,
|
|
156
|
+
default_resolution=5000, label='Great Plains (GLANCE N. America LAEA)',
|
|
157
|
+
lonlat=(-105.0, 31.0, -96.0, 49.0), area_epsg=10598),
|
|
158
|
+
'american_southwest': dict(
|
|
159
|
+
bounds=(-1913308, -2095218, -249048, -674284), crs=10598,
|
|
160
|
+
default_resolution=2000, label='American Southwest (GLANCE N. America LAEA)',
|
|
161
|
+
lonlat=(-120.0, 31.0, -103.0, 42.0), area_epsg=10598),
|
|
162
|
+
'amazon_basin': dict(
|
|
163
|
+
bounds=(-2129139, -422334, 1795411, 2309720), crs=10603,
|
|
164
|
+
default_resolution=5000, label='Amazon Basin (GLANCE S. America LAEA)',
|
|
165
|
+
lonlat=(-79.0, -18.0, -44.0, 6.0), area_epsg=10603),
|
|
166
|
+
'andes': dict(
|
|
167
|
+
bounds=(-2350812, -4564243, -133276, 2958360), crs=10603,
|
|
168
|
+
default_resolution=10000, label='Andes (GLANCE S. America LAEA)',
|
|
169
|
+
lonlat=(-81.0, -56.0, -62.0, 12.0), area_epsg=10603),
|
|
170
|
+
'southern_cone': dict(
|
|
171
|
+
bounds=(-1697271, -4517109, 744960, -221307), crs=10603,
|
|
172
|
+
default_resolution=5000, label='Southern Cone (GLANCE S. America LAEA)',
|
|
173
|
+
lonlat=(-76.0, -56.0, -53.0, -17.0), area_epsg=10603),
|
|
174
|
+
'western_europe': dict(
|
|
175
|
+
bounds=(-2382583, -1327155, -191916, 406028), crs=10596,
|
|
176
|
+
default_resolution=5000, label='Western Europe (GLANCE Europe LAEA)',
|
|
177
|
+
lonlat=(-10.0, 43.0, 17.0, 55.0), area_epsg=10596),
|
|
178
|
+
'eastern_europe': dict(
|
|
179
|
+
bounds=(-482758, -1221647, 2340946, 916013), crs=10596,
|
|
180
|
+
default_resolution=5000, label='Eastern Europe (GLANCE Europe LAEA)',
|
|
181
|
+
lonlat=(14.0, 44.0, 50.0, 60.0), area_epsg=10596),
|
|
182
|
+
'northern_europe': dict(
|
|
183
|
+
bounds=(-1039068, -111313, 782636, 1847310), crs=10596,
|
|
184
|
+
default_resolution=2000, label='Northern Europe (GLANCE Europe LAEA)',
|
|
185
|
+
lonlat=(4.0, 54.0, 32.0, 71.0), area_epsg=10596),
|
|
186
|
+
'southern_europe': dict(
|
|
187
|
+
bounds=(-2698894, -2211793, 739758, -416605), crs=10596,
|
|
188
|
+
default_resolution=5000, label='Southern Europe (GLANCE Europe LAEA)',
|
|
189
|
+
lonlat=(-10.0, 35.0, 28.0, 47.0), area_epsg=10596),
|
|
190
|
+
# Antarctica uses the de-facto standard Antarctic Polar Stereographic
|
|
191
|
+
# (EPSG:3031, conformal), so preserve='area' falls back to the EPSG-coded
|
|
192
|
+
# south-polar equal-area grid (EPSG:6932) rather than claiming 3031 is
|
|
193
|
+
# equal-area. shape_epsg is 3031 itself (already conformal).
|
|
194
|
+
'antarctica': dict(
|
|
195
|
+
bounds=(-3333134, -3333134, 3333134, 3333134), crs=3031,
|
|
196
|
+
default_resolution=10000, label='Antarctica (Polar Stereographic)',
|
|
197
|
+
lonlat=(-180.0, -90.0, 180.0, -60.0), area_epsg=6932, shape_epsg=3031),
|
|
48
198
|
# The default (non-preserve) world grid spans the full +/-90 in EPSG:4326.
|
|
49
199
|
# The preserve path uses a +/-85 latitude band (the conventional Web
|
|
50
200
|
# Mercator limit) so 'shape' (World Mercator) does not diverge at the poles.
|
|
@@ -52,6 +202,41 @@ _REGIONS = {
|
|
|
52
202
|
default_resolution=0.5, label='World (WGS84)',
|
|
53
203
|
lonlat=(-180.0, -85.0, 180.0, 85.0), area_epsg=8857,
|
|
54
204
|
shape_epsg=3395),
|
|
205
|
+
# Global Web Mercator (EPSG:3857). Native bounds are the canonical square
|
|
206
|
+
# extent +/-20037508 m, which is +/-180 lon and +/-85.0511287798 lat (the
|
|
207
|
+
# latitude where the Mercator y matches the x half-extent). lonlat stops at
|
|
208
|
+
# that latitude because Mercator y diverges to infinity at the poles.
|
|
209
|
+
'web_mercator': dict(
|
|
210
|
+
bounds=(-20037508, -20037508, 20037508, 20037508), crs=3857,
|
|
211
|
+
default_resolution=50000, label='World (Web Mercator)',
|
|
212
|
+
lonlat=(-180.0, -85.0511287798, 180.0, 85.0511287798),
|
|
213
|
+
area_epsg=8857, shape_epsg=3395),
|
|
214
|
+
# Global equal-area grid (EPSG:8857, Equal Earth). Native bounds are the
|
|
215
|
+
# +/-90 world projected into Equal Earth.
|
|
216
|
+
'equal_earth': dict(
|
|
217
|
+
bounds=(-17243959, -8392928, 17243959, 8392928), crs=8857,
|
|
218
|
+
default_resolution=50000, label='World (Equal Earth)',
|
|
219
|
+
lonlat=(-180.0, -90.0, 180.0, 90.0),
|
|
220
|
+
area_epsg=8857, shape_epsg=3395),
|
|
221
|
+
# Pacific-centered world (EPSG:3832, WGS 84 / PDC Mercator). lon_0=150 so the
|
|
222
|
+
# Pacific Ocean is continuous, with the map seam in the Atlantic (~30 W). x
|
|
223
|
+
# spans the full a*pi longitude extent; y is the ellipsoidal Mercator value
|
|
224
|
+
# at the conventional +/-85.0511287798 latitude limit. Conformal, so
|
|
225
|
+
# area_epsg falls back to Equal Earth for preserve='area'.
|
|
226
|
+
'pacific': dict(
|
|
227
|
+
bounds=(-20037508, -19994875, 20037508, 19994875), crs=3832,
|
|
228
|
+
default_resolution=50000, label='Pacific-centered World (PDC Mercator)',
|
|
229
|
+
lonlat=(-180.0, -85.0511287798, 180.0, 85.0511287798),
|
|
230
|
+
area_epsg=8857, shape_epsg=3832),
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
# Alternate spellings that resolve to a curated region (single source of truth).
|
|
234
|
+
# 'wgs84' / 'latlon' are friendly names for the EPSG:4326 'world' grid; 'pdc' is
|
|
235
|
+
# the Pacific Disaster Center's name for its Pacific-centered Mercator.
|
|
236
|
+
_REGION_ALIASES = {
|
|
237
|
+
'wgs84': 'world',
|
|
238
|
+
'latlon': 'world',
|
|
239
|
+
'pdc': 'pacific',
|
|
55
240
|
}
|
|
56
241
|
|
|
57
242
|
# Equal-area fallback when a template has no curated ``area_epsg``
|