Skip to content

Add RasterIndex.get_indexer for vectorized point lookup - #100

Merged
dcherian merged 2 commits into
mainfrom
get-indexer
Oct 27, 2026
Merged

dcherian merged 2 commits into
mainfrom
get-indexer

Conversation

@dcherian

Copy link
Copy Markdown
Contributor

Motivation

xpublish-tiles needs a vectorized "which cell contains each point" lookup. sel({"x": arr}, method="nearest") (0.2.4) wraps correctly on a periodic axis (global 1° grid, corners -180..180: 180.5, 539.5, -180.5 → 0, 359, 359), but:

  • It has no bounds check. On a regional grid (corners -10..10, 20 cells), -100 → -90 and 180.5 → 190. A negative result is a valid numpy index, so a miss silently reads the wrong cell.
  • NaN → 0 on all grids, and inf → 0 on a periodic axis (the NaN-to-int cast gives 0 on arm64).

API

RasterIndex.get_indexer(labels: Mapping[Hashable, ArrayLike]) -> dict[str, np.ndarray]

Follows pandas.Index.get_indexer. Keys of labels are coordinate names (as for sel). Returns int64 positions keyed by dimension name, with the input shape; -1 for a point outside the extent, NaN or inf.

  • Rectilinear: each axis is looked up independently; X, Y or both may be given. On a periodic axis, the integer cell is wrapped modulo the period, then bounds-checked (so a subset of one period still gives -1 for a wrapped point outside it).
  • Rotated/skewed: both coordinates are required, with the same shape; the full inverse affine is used, and a point is a miss on both dims if either position is out of range. Periods cannot be set on these transforms (from_transform already raises NotImplementedError), so no wrap is needed.

Edge convention

With p the corner-based pixel position (~index.transform()), a point is in cell i if i <= p < i + 1, i.e. floor(p). A cell includes the edge at its lower position and excludes the one at its higher position; for a north-up raster that is the top edge included, the bottom edge excluded, and the raster's bottom edge is outside. Away from cell edges this equals sel(..., method="nearest") (which uses np.round, round-half-to-even, at ties).

🤖 Generated with Claude Code

dcherian and others added 2 commits October 27, 2026 09:40
Return the int64 position of the cell that contains each point, or -1 for a
point outside the extent, NaN or inf. Wraps on periodic axes; uses the full
inverse affine for rotated/skewed transforms.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@dcherian
dcherian marked this pull request as ready for review October 27, 2026 15:53
@dcherian
dcherian merged commit 0af186d into main Oct 27, 2026
11 checks passed
@dcherian
dcherian deleted the get-indexer branch October 27, 2026 15:54
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.

1 participant