maplibre-gl-raster 0.2.4 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -14,6 +14,7 @@ A MapLibre GL JS plugin for visualizing local and remote raster datasets (GeoTIF
14
14
  - **GPU rendering pipeline** - Band compositing, per-band rescale, 90+ colormaps, nodata filtering, linear/sqrt/log stretch, and gamma correction as deck.gl shader modules; parameter changes re-render without re-fetching tiles
15
15
  - **Auto statistics** - Per-band min/max and histograms sampled from COG overviews (or GDAL metadata), with draggable histogram handles for the rescale range
16
16
  - **Pixel inspector** - Toggle inspect mode and click the map to read the raw source values of every band of the selected layer at that location, shown in a popup (works for COGs in any CRS)
17
+ - **Colorbar legend** - A standalone `Colorbar` control: gradient + tick labels for a named colormap (or custom colors), with configurable min/max, title, units, orientation, and position
17
18
  - **Collapsible control** - A compact 29x29 map button that expands into a floating panel
18
19
  - **TypeScript + React** - Full type definitions, a React wrapper component, and hooks
19
20
  - **GeoLibre bundle output** - Builds a zip with root `plugin.json`, bundled ESM, and CSS for GeoLibre Desktop
@@ -119,7 +120,7 @@ The main control class implementing MapLibre's `IControl` interface.
119
120
  - `addRaster(source, options?)` - Add a raster from a COG URL (`string`) or a local GeoTIFF `File`; resolves with the layer id
120
121
  - `removeRaster(id)` - Remove a raster layer
121
122
  - `getRaster(id)` / `getRasters()` - Get layer snapshots (`RasterLayerInfo`)
122
- - `setRasterState(id, patch)` - Update visualization state (mode, bands, rescale, colormap, nodata, opacity, gamma, stretch, visible)
123
+ - `setRasterState(id, patch)` - Update visualization state (mode, bands, rescale, colormap, reversed, nodata, opacity, gamma, stretch, visible)
123
124
  - `setVisible(id, visible)` - Show / hide a layer
124
125
  - `selectRaster(id | null)` - Choose which layer the panel's settings edit
125
126
  - `zoomToRaster(id)` - Fit the map to a layer's bounds
@@ -150,11 +151,20 @@ interface RasterLayerState {
150
151
  bands: number[]; // 1-indexed band selection
151
152
  rescale: [number, number][] | null; // per-channel min/max; null = auto (2-98%)
152
153
  colormap: string; // colormap name; "palette" = embedded color table
154
+ reversed: boolean; // sample the named colormap back-to-front
153
155
  nodata: number | "off" | "auto"; // nodata handling
154
156
  opacity: number; // 0..1
155
157
  gamma: number; // power-law correction (1 = off)
156
158
  stretch: "linear" | "log" | "sqrt"; // curve applied after rescale
157
159
  visible: boolean;
160
+ colorbar?: {
161
+ // optional on-map legend for this single-band layer
162
+ visible: boolean;
163
+ title?: string;
164
+ units?: string;
165
+ orientation?: "horizontal" | "vertical";
166
+ position?: "top-left" | "top-right" | "bottom-left" | "bottom-right";
167
+ };
158
168
  }
159
169
  ```
160
170
 
@@ -190,6 +200,66 @@ const {
190
200
  } = useRasterState(initialState);
191
201
  ```
192
202
 
203
+ ### Colorbar
204
+
205
+ The settings panel has a **"Show colorbar"** toggle for single-band layers
206
+ (with title, units, orientation, and position controls). Enabling it shows a
207
+ legend on the map driven by that layer's colormap, `reversed` flag, and
208
+ effective value range, and it follows rescale / colormap changes live. This is
209
+ persisted per layer in `RasterLayerState.colorbar`.
210
+
211
+ You can also use the legend directly as a standalone control. Add it like any
212
+ MapLibre control; it docks into a map corner and renders a gradient with tick
213
+ labels. The ramp is sampled from the same colormap sprite the renderer uses, so
214
+ a named colormap (and the `reversed` flag) matches the map exactly — or supply
215
+ your own `colors`.
216
+
217
+ ```typescript
218
+ import { Colorbar } from "maplibre-gl-raster";
219
+
220
+ const colorbar = new Colorbar({
221
+ colormap: "viridis", // or colors: ["#000", "#f00", "#ff0"]
222
+ min: 0,
223
+ max: 3000,
224
+ title: "Elevation",
225
+ units: "m",
226
+ orientation: "horizontal", // or "vertical"
227
+ position: "bottom-right",
228
+ ticks: 5,
229
+ });
230
+ map.addControl(colorbar);
231
+ ```
232
+
233
+ Keep it in sync with a single-band raster by updating it from the control's
234
+ `rasterchange` event:
235
+
236
+ ```typescript
237
+ control.on("rasterchange", ({ layerId }) => {
238
+ const info = layerId ? control.getRaster(layerId) : undefined;
239
+ const range = info?.state.rescale?.[0]; // [min, max] when set explicitly
240
+ // 'palette' uses the image's embedded table, not a named colormap.
241
+ if (info && range && info.state.colormap !== "palette") {
242
+ colorbar.update({
243
+ colormap: info.state.colormap,
244
+ reversed: info.state.reversed,
245
+ min: range[0],
246
+ max: range[1],
247
+ });
248
+ }
249
+ });
250
+ ```
251
+
252
+ `ColorbarOptions`: `colormap?` (default `"viridis"`), `colors?` (custom ramp,
253
+ overrides `colormap`), `reversed?`, `min?` / `max?` (default `0` / `1`),
254
+ `title?`, `titleAlign?` (`"left"` | `"center"` | `"right"`), `units?`,
255
+ `stretch?` (`"linear"` | `"log"` | `"sqrt"` — spaces tick values to match the
256
+ layer's stretch), `orientation?` (`"horizontal"` | `"vertical"`, default
257
+ `"horizontal"`), `position?` (map corner, default `"bottom-right"`), `ticks?`
258
+ (count, default `5`), `tickValues?` (explicit ticks), `decimals?` (fixed
259
+ decimal places; omit for a compact auto format), `barLength?` /
260
+ `barThickness?` (px), `className?`. Reconfigure live with
261
+ `colorbar.update(partial)`.
262
+
193
263
  ### Utilities
194
264
 
195
265
  The package also exports lower-level building blocks for advanced use:
@@ -199,6 +269,8 @@ The package also exports lower-level building blocks for advanced use:
199
269
  - `summarizeGeoTIFF(tiff)` - Image / CRS / band / GDAL metadata summary
200
270
  - `readBandNames(tiff)` / `percentileFromHistogram(stats, p)`
201
271
  - `COLORMAP_NAMES` / `COLORMAP_OPTIONS` / `colormapsPngUrl`
272
+ - `sampleColormapStops(name, steps, reversed?)` / `loadColormapSprite()` / `isKnownColormap(name)` - sample a colormap's colors in plain JS
273
+ - `autoRangeFor(stats)` / `statsForBand(autoStats, band)` - resolve a band's effective rescale range
202
274
  - `clamp`, `formatNumericValue`, `generateId`, `debounce`, `throttle`, `classNames`
203
275
 
204
276
  ## CORS requirements for remote COGs