Skip to content

feat: filtering based on multiple variables (no dask) - #166

Open
maxrjones wants to merge 5 commits into
mainfrom
feat/where-mask
Open

maxrjones wants to merge 5 commits into
mainfrom
feat/where-mask

Conversation

@maxrjones

Copy link
Copy Markdown
Member

This PR allows filtering the rendered data based on conditions from the same or other variables (e.g., show temperature where elevation is >0).

This is a dask-free alternative to #151. It's motivated by realizing that masking doesn't need deferred computations, just lazy loading. This approach is similar to that of rio-tiler, in evaluating expressions after windows are read. In contrast to rio-tiler, expressions are applied before warping.

If we eventually want full expression support evaluated lazily on the native grid (similar to titiler-cmr), we'd need a computational graph library like dask.

It also removed dask from the dev env, since it's not actually needed for creating the test fixtures.
Closes #151

Testing

  • added new tests

PR checks

  • Standard CI runs automatically on each push.
  • To run the CDK synth check, add the run-cdk-checks label to this PR.
  • If you push more commits after that run completes, remove and re-add the label to run it again.
  • To trigger a dev deployment, add the deploy-dev label. It smoke-tests tiles from the native MUR, virtual MUR, and virtual NLDAS Icechunk stores after deployment.

maxrjones and others added 2 commits October 1, 2026 15:30
Every data endpoint accepts `where={variable}{op}{number}` (op one of
==, !=, <, <=, >, >=), ANDed across repeats; pixels failing any
condition render as nodata. Condition variables are sliced with the
same `sel` as the main variable, and tilejson.json forwards `where`
into its tile template.

Masks are applied inside xarray's lazy-indexing layer (`_MaskedArray`,
a BackendArray wrapped in LazilyIndexedArray) rather than through dask:
rio-tiler's clip_box stays lazy, and the first materialization reads
only the window of the data and of each mask variable, combines them
in numpy and returns NaN for failing pixels, so masking happens before
warping/resampling. Fill values fail every operator, masks whose
coordinates don't match the data are rejected with a 400, and the
variable's encoding survives masking.

Also: drop dask from the dev group, add titiler-xarray to the mypy
pre-commit hook, document `where` in the README, and add a MUR SST where= case
to the deployment smoke test.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Relocking in the development sandbox wrote two things unrelated to this
branch into uv.lock:
- an [options] block with exclude-newer-span = "P1W" (the sandbox's
  package-install cooldown), which does not belong upstream;
- four dependency markers removed (pycparser, h11, truststore,
  ptyprocess) by a different uv version; relocking an untouched main
  with that uv produces the same lines.

Restore main's lines for both; the branch's own dependency change and the
titiler-multidim 0.9.0 -> 0.9.1 self-version (main's lock is stale after
the 0.9.1 release) are kept.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@maxrjones

Copy link
Copy Markdown
Member Author

Hey @hrodmn @chuckwondo @jsignell, I'm not 100% sure this is the long-term design we want, given that we may need Dask anyways for next quarter's area-based time series anyways. But it does have better performance than the dask-based approach, which is why I prefer this PR.

Do you think it'd be possible for us to merge this feature next week? It'd be great to get it in for the next deployment cycle, since it's needed for AIR4US. I have an HTML page I was using for comparing the outputs from titiler-multidim with GIBS, that I could share over slack if helpful?

This branch was successfully deployed

1 active deployment
dev — b215b8b9 Deployed Oct 2, 2026 by maxrjones via Deploy to dev #273
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant