Add deck.gl-raster as a client-side COG renderer option (deck.gl missions)#172
Draft
slesaad wants to merge 14 commits into
Draft
Add deck.gl-raster as a client-side COG renderer option (deck.gl missions)#172slesaad wants to merge 14 commits into
slesaad wants to merge 14 commits into
Conversation
- Bump @deck.gl/{core,geo-layers,layers,mapbox} from 9.2.x to ^9.3.0
- Add @deck.gl/extensions ^9.3.0 (required peer dep for geo-layers 9.3)
- Add @deck.gl/mesh-layers ^9.3.0 (new explicit dep)
- Add @developmentseed/deck.gl-geotiff, deck.gl-raster, morecantile at ^0.7.0
- Add @luma.gl/core ^9.3.2 and @luma.gl/shadertools ^9.3.2 (explicit peers)
- Add leaflet ^1.9.4 (missing peer dep for terra-draw-leaflet-adapter)
Adds composeColormapPipeline (pure, unit-tested), ColormappedCOGLayer (COGLayer subclass that appends LinearRescale + Colormap GPU modules), and buildDeckCOGLayer factory. Map_.js makeTileLayer now routes cogRendererMode=deckRaster layers to the new path with the raw COG URL, bypassing TiTiler entirely.
…cedence Part A: applyCogFieldsToUrl now prefers currentCogColormap ?? cogColormap, matching the existing currentCogMin/Max override pattern. TDD: failing test added, then implementation made it green (24/24 pass). Part B: layers:refresh handler gains a deckRaster branch — rebuilds the ColormappedCOGLayer with updated current* values via buildDeckCOGLayer and re-registers it through engine.addLayer so deck.gl diffs GPU resources in place. Leaflet .refresh() path remains the unchanged fallback.
…act pruned by dedup
…xture pipeline COGLayer's default inferRenderPipeline only supports unsigned-integer COGs (throws 'non-unsigned integers not yet supported' for SampleFormat 3/float). Supply our own getTileData (uploads the band as r32float) and renderTile ([CreateTexture, FilterNoDataVal?, LinearRescale, Colormap]) so _parseGeoTIFF skips that inference. Verified live: CMIP6 tasmax (float32) renders with gist_heat_r + rescale 225-315, no tile-server render requests.
Float scientific COGs encode nodata as NaN (GDAL_NODATA=nan); FilterNoDataVal's == equality never matches NaN. Add a FilterNaN GPU module (color.r != color.r self-inequality test) after CreateTexture so NaN fill pixels are discarded. Verified live on CMIP6 tasmax: oceans render transparent (basemap shows through).
… follow-up forward) Band-count branch in the tile loader: single-band -> r32float + colormap (as before); multi-band uint -> rgba8unorm displayed directly via CreateTexture, no colormap/rescale. Adds FilterBlack to discard black nodata edges (Sentinel UTM tile corners) -> transparent. Verified live: Sentinel-2 TCI renders in true color client-side with correct zoom refinement across its 5-level overview pyramid. Assumes 8-bit multi-band samples.
93a649e to
d1efd40
Compare
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.
Summary
Adds an optional client-side COG renderer for deck.gl-based missions, so a Cloud-Optimized GeoTIFF can be decoded and colorized in the browser on the GPU via
@developmentseed/deck.gl-raster/deck.gl-geotiff— with no tile server in the loop. TiTiler remains the default and is unchanged.Implements #158.
What it does
cogRendererModeon the COG tab (titilerdefault /deckRaster). It only takes effect in deck.gl missions; in Leaflet missions the layer falls back to TiTiler, and the field is hidden entirely from the configure UI (not just disabled).deckRasterin a deck.gl mission, the COG is read directly (HTTP range requests) and rendered on the GPU:js-colormapsevaluate_cmap, so the client render matches TiTiler'scolormap_name(including_rreversed variants). NaN nodata is discarded (transparent).updateTriggers).How it works
shouldUseDeckRaster(engine, type, layer)gates the deck branch ofmakeTileLayer(); when false, the existing TiTiler path runs untouched.ColormappedCOGLayer(aCOGLayersubclass) supplies its owngetTileData/renderTile. This is required because the library's default pipeline auto-inference only supports unsigned-integer COGs and throws for float (the common scientific case). The custom loader uploads single-band data asr32floatand composes[CreateTexture, FilterNaN, LinearRescale, Colormap]; multi-band uint is uploaded asrgba8unormand displayed via[CreateTexture, FilterBlack]. Overview selection (finer tiles at higher zoom) is handled by the base layer.^9.3and luma.gl to^9.3.2(peer requirements of the new packages); adds@developmentseed/deck.gl-geotiff,@developmentseed/deck.gl-raster,@developmentseed/morecantile. A prunedfocus-trap-react(USWDS build dep) is restored and.npmrcpinslegacy-peer-depsfor a pre-existing peer conflict.Testing
tests/unit/): colormap LUT parity withevaluate_cmap, the routing decision, the configure-UI field gating, the colormap-override precedence, the pipeline composition, and the live-update handlers.Known follow-ups (out of scope here)
/colorMaps) — shared legend/UI infra, independent of the renderer; could be rendered from localjs-colormapsfor full decoupling.OES_texture_float_linearis available.🤖 Generated with Claude Code