Skip to content

Linestring / multi-linestring morton coverage + metric buffer helper#26

Merged
espg merged 5 commits into
mainfrom
feature/morton-linestring-coverage
Apr 15, 2026
Merged

Linestring / multi-linestring morton coverage + metric buffer helper#26
espg merged 5 commits into
mainfrom
feature/morton-linestring-coverage

Conversation

@espg
Copy link
Copy Markdown
Owner

@espg espg commented Apr 14, 2026

Summary

Adds mortie.linestring_coverage() — morton-index coverage of open polylines — and mortie.morton_buffer_meters(), a metric-width convenience wrapper around morton_buffer (from #17). Includes a real-data example notebook that queries the NSIDC InSAR Antarctic grounding line dataset. Closes #25.

What's new

linestring_coverage(lats, lons, order=18) — Python interface over a new Rust module (src_rust/src/linestring.rs). Rasterizes each segment between consecutive vertices by sampling the great-circle arc at half-cell-resolution spacing, guaranteeing a contiguous cell chain. Reuses the Phase A interpolation helpers from coverage.rs (made pub(crate)), so there's one source of truth for the vertex-neighbor logic introduced in #17.

Return shape:

  • Single line (1-D arrays) → sorted, unique np.ndarray of morton indices.
  • Multi-line (list of 1-D arrays) → list of arrays, one per input line. Lengths may differ; per-line results are not deduplicated across lines.

morton_buffer_meters(cells, width_m) — wraps morton_buffer. Infers order from the input cells, computes k = ceil(width_m / cell_width_m) using R_earth · sqrt(π/3) / 2^order, and returns the resulting border ring. The docstring is explicit that this is approximate: the achieved width is rounded up to the nearest whole cell width, so the buffer always covers at least width_m.

Why this API shape

Lat/lon array input (rather than shapely geometries) keeps mortie dependency-free. The example notebook shows the idiomatic pattern: earthaccessgeopandas → unpack shapely LineString / MultiLineString into arrays → linestring_coverage. The multi-line return is a list (not a 2-D array or single concatenated 1-D array) because per-line lengths differ, and callers who want the union can trivially do np.unique(np.concatenate(per_line)).

Files

  • src_rust/src/linestring.rs — new Rust module with linestring_to_morton_coverage (10 unit tests).
  • src_rust/src/coverage.rs — three Phase A helpers promoted to pub(crate). No behavior change.
  • src_rust/src/lib.rsrust_linestring_coverage pyfunction registered in _rustie.
  • mortie/linestring.pylinestring_coverage Python wrapper, validation, multi dispatch.
  • mortie/tools.pymorton_buffer_meters helper.
  • mortie/__init__.py — public exports.
  • mortie/tests/test_linestring.py — 27 tests (single/multi shape, sort/unique, endpoints present, interpolation fills gaps, hemisphere signs, order-range validation, NaN/inf rejection, meter-buffer monotonicity + equivalence to k).
  • examples/morton_linestring_insar_gl.ipynb — self-contained example: synthetic linestring → real NSIDC-0498 v2 InSAR grounding line via earthaccess → south-polar-stereographic plot → buffer demo (k=1, k=3, ~50 km metric).
  • pyproject.toml — new docs extra for the example notebook (jupyterlab, notebook, ipykernel, matplotlib, shapely, geopandas, pyogrio, earthaccess, cartopy, healpy, requests).

Test plan

  • cargo test — 67 Rust tests pass (10 new linestring tests).
  • pytest mortie/tests/ — 203 passed, 3 skipped (27 new linestring tests).
  • Notebook smoke-checked: synthetic linestring renders; CMR search returns granules for NSIDC-0498 v2.
  • End-to-end notebook run (Earthdata download + plots) — please verify while reviewing.

Clarifying Q&A

Design decisions and the implementation plan are documented as comments on #25 for reproducibility.

🤖 Generated with Claude Code

espg and others added 2 commits April 14, 2026 15:43
CMR registers the collection as version '2' (the file asset is named
InSAR_GL_Antarctica_v02.1.gpkg, which is where '2.1' came from). Use the
canonical short_name='NSIDC-0498' directly and drop the candidate-list
fallback. Verified earthaccess.search_data returns granules.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@codecov
Copy link
Copy Markdown

codecov Bot commented Apr 14, 2026

Codecov Report

❌ Patch coverage is 98.43750% with 3 lines in your changes missing coverage. Please review.
✅ Project coverage is 88.27%. Comparing base (b87f65e) to head (5da9f28).
⚠️ Report is 5 commits behind head on main.

Files with missing lines Patch % Lines
mortie/tools.py 87.50% 2 Missing ⚠️
mortie/linestring.py 96.15% 1 Missing ⚠️
Additional details and impacted files

Impacted file tree graph

@@            Coverage Diff             @@
##             main      #26      +/-   ##
==========================================
+ Coverage   87.30%   88.27%   +0.97%     
==========================================
  Files          15       17       +2     
  Lines        2000     2192     +192     
==========================================
+ Hits         1746     1935     +189     
- Misses        254      257       +3     
Flag Coverage Δ
unittests 88.27% <98.43%> (+0.97%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

Files with missing lines Coverage Δ
mortie/__init__.py 80.00% <100.00%> (+2.22%) ⬆️
mortie/tests/test_linestring.py 100.00% <100.00%> (ø)
mortie/linestring.py 96.15% <96.15%> (ø)
mortie/tools.py 77.71% <87.50%> (+0.46%) ⬆️

Continue to review full report in Codecov by Sentry.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update b87f65e...5da9f28. Read the comment docs.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@codspeed-hq
Copy link
Copy Markdown
Contributor

codspeed-hq Bot commented Apr 14, 2026

Merging this PR will degrade performance by 10.39%

⚠️ Different runtime environments detected

Some benchmarks with significant performance changes were compared across different runtime environments,
which may affect the accuracy of the results.

Open the report in CodSpeed to investigate

⚡ 2 improved benchmarks
❌ 1 regressed benchmark
✅ 26 untouched benchmarks

⚠️ Please fix the performance issues or acknowledge them on CodSpeed.

Performance Changes

Benchmark BASE HEAD Efficiency
order6[100] 414.7 µs 363 µs +14.23%
test_coverage_triangle_order6 618.5 µs 690.2 µs -10.39%
test_coverage_triangle_order4 307.2 µs 272 µs +12.93%

Comparing feature/morton-linestring-coverage (5da9f28) with main (b87f65e)

Open in CodSpeed

@espg espg merged commit aa99e55 into main Apr 15, 2026
15 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Support for lines, multilines, etc (with documentation)

1 participant