Add high-level overlay API and refactor CLI to use it - #80
Merged
Conversation
Work through the remaining checklist in #54: - Add snail.overlay_raster and snail.overlay_rasters, high-level functions taking (features, raster path/s, open dataset/s or DataArray/s) and returning split features with attributed values, plus snail.split_features; export from the package root and refactor the CLI on top of them. --lazy-rasters is threaded through as a `lazy` argument - Handle multi-band rasters in `snail process`, attributing one column per band named "{key}_band_{n}" (previously each band overwrote a single column); single-band values keep the plain key. `snail split` uses the same naming, so both commands agree - Reproject features to the raster grid CRS implicitly for splitting, indexing and value lookup, returning results in the original CRS. Fixes `snail split` applying cell indices in the features CRS, which gave wrong indices whenever it differed from the raster CRS. Features or grids with no CRS are assumed to match, with a warning - Coerce MultiLineString geometries in split_linestrings (merge and explode, with a warning) instead of failing downstream - Add `snail split --all-layers` (each layer to a GeoPackage output layer) and a "*" wildcard layer value in the `snail process` features CSV, expanding to one output per layer - Default `snail process` output paths to "{features_stem}_{layer}__{rasters_csv_stem}.parquet" next to the input instead of "{path}.processed.parquet", and respect output format by extension (GeoParquet or any geopandas-writable format) in both commands - Allow a per-row missing "bands" value in the rasters CSV to default to all bands - Fix `-vv` raising TypeError: the log level was set to a bound logger method rather than logging.INFO - Document the Python API, `snail process` semantics (all features intersected with all rasters, one column per raster file/band) and the optional CSV columns in the README and docs Fixes #54 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_014foLdPo81QBhpRGUn2kkUG
Fixes ruff LOG015 (root-logger calls) and UP007/UP045 (Optional/Union annotations) reported by CI. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_014foLdPo81QBhpRGUn2kkUG
Member
Author
|
Closes #54 |
Contributor
There was a problem hiding this comment.
Pull request overview
Adds a high-level raster/vector overlay API and refactors CLI workflows around it.
Changes:
- Introduces single- and multi-raster overlay APIs with CRS handling.
- Adds multi-layer CLI processing and GeoParquet output.
- Expands overlay and CLI tests and documentation.
Reviewed changes
Copilot reviewed 10 out of 10 changed files in this pull request and generated 5 comments.
Show a summary per file
| File | Description |
|---|---|
src/snail/overlay.py |
Implements the high-level overlay API. |
src/snail/io.py |
Adds raster-source and vector-output helpers. |
src/snail/intersection.py |
Adds CRS-aware multi-grid splitting. |
src/snail/cli.py |
Refactors commands to use overlay APIs. |
src/snail/__init__.py |
Exports the new public functions. |
tests/test_overlay.py |
Tests overlay behavior and inputs. |
tests/test_cli.py |
Tests CLI layers and output formats. |
tests/conftest.py |
Adds raster and vector fixtures. |
README.md |
Documents APIs and CLI workflows. |
docs/source/index.rst |
Adds high-level usage documentation. |
Suppressed comments (1)
src/snail/io.py:74
- Duplicate user-supplied keys (or otherwise colliding generated band names) silently overwrite the earlier raster's Series in this dictionary, so the result no longer contains one column per requested raster band. Reject collisions rather than returning incomplete data.
column = band_column_name(raster.key, band_number, len(raster.bands))
raster_data[column] = get_raster_values_for_splits(
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
| band_number, | ||
| ) | ||
| raster_data[raster.key] = get_raster_values_for_splits( | ||
| column = band_column_name(raster.key, band_number, len(raster.bands)) |
And log more explicitly the CRS assumptions
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Introduce
snail.overlayto provide simplified APIs for overlaying raster values onto vector features, and refactors the CLI and internal code to use these new functions. The changes aim to make snail more accessible as a Python library while maintaining backward compatibility.snail.overlaymodule has three main functions:overlay_raster(): Split features along a single raster grid and attribute cell valuesoverlay_rasters(): Split features along multiple raster grids in one callsplit_features(): Split features along a grid without attributing raster valuesoverlayhandles point, linestring, and polygon features--all-layersflag to split all layers in a multi-layer vector file.parquetand.geoparquetextensions)Implementation notes
"{column}_band_{n}"for each band, while single-band rasters use just the column nameprocesscommand now supports wildcard layer specifications to process all layers in a file