maplibre-gl-raster 0.1.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/LICENSE +21 -0
- package/README.md +362 -0
- package/dist/LercDecode.es-CZm5toNk.js +442 -0
- package/dist/LercDecode.es-CZm5toNk.js.map +1 -0
- package/dist/RasterControl-B7XdXYSu.js +18838 -0
- package/dist/RasterControl-B7XdXYSu.js.map +1 -0
- package/dist/__vite-browser-external-BgMKmFg9.js +9 -0
- package/dist/__vite-browser-external-BgMKmFg9.js.map +1 -0
- package/dist/assets/LercDecode.es-Bvg6-wb5.js +442 -0
- package/dist/assets/LercDecode.es-Bvg6-wb5.js.map +1 -0
- package/dist/assets/__vite-browser-external-BgMKmFg9.js +9 -0
- package/dist/assets/__vite-browser-external-BgMKmFg9.js.map +1 -0
- package/dist/assets/chunk-FDOR9p9I.js +24 -0
- package/dist/assets/decode-BvR5vy7g.js +940 -0
- package/dist/assets/decode-BvR5vy7g.js.map +1 -0
- package/dist/assets/lerc-By2TvjAX.js +34 -0
- package/dist/assets/lerc-By2TvjAX.js.map +1 -0
- package/dist/assets/lzw-CQJJDca2.js +174 -0
- package/dist/assets/lzw-CQJJDca2.js.map +1 -0
- package/dist/assets/worker-C6cg9T3Y.js +51 -0
- package/dist/assets/worker-C6cg9T3Y.js.map +1 -0
- package/dist/assets/zstd-DBZv9xja.js +569 -0
- package/dist/assets/zstd-DBZv9xja.js.map +1 -0
- package/dist/chunk-FDOR9p9I.js +24 -0
- package/dist/decode-BMFOVF9X.js +1966 -0
- package/dist/decode-BMFOVF9X.js.map +1 -0
- package/dist/index.mjs +223 -0
- package/dist/index.mjs.map +1 -0
- package/dist/lerc-B7WY-v3y.js +34 -0
- package/dist/lerc-B7WY-v3y.js.map +1 -0
- package/dist/lzw-YEsReV21.js +174 -0
- package/dist/lzw-YEsReV21.js.map +1 -0
- package/dist/maplibre-gl-raster.css +670 -0
- package/dist/react.mjs +145 -0
- package/dist/react.mjs.map +1 -0
- package/dist/types/index.d.ts +649 -0
- package/dist/types/react.d.ts +477 -0
- package/dist/zstd-DBZv9xja.js +569 -0
- package/dist/zstd-DBZv9xja.js.map +1 -0
- package/package.json +125 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Qiusheng Wu
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,362 @@
|
|
|
1
|
+
# maplibre-gl-raster
|
|
2
|
+
|
|
3
|
+
A MapLibre GL JS plugin for visualizing local and remote raster datasets (GeoTIFF / Cloud Optimized GeoTIFF) directly in the browser. No tile server required: COGs are read with HTTP range requests and rendered on the GPU through a deck.gl pipeline.
|
|
4
|
+
|
|
5
|
+
[](https://www.npmjs.com/package/maplibre-gl-raster)
|
|
6
|
+
[](https://opensource.org/licenses/MIT)
|
|
7
|
+
[](https://codesandbox.io/p/github/opengeos/maplibre-gl-raster)
|
|
8
|
+
[](https://stackblitz.com/github/opengeos/maplibre-gl-raster)
|
|
9
|
+
|
|
10
|
+
## Features
|
|
11
|
+
|
|
12
|
+
- **Local and remote rasters** - Load Cloud Optimized GeoTIFFs from any CORS-enabled URL, or drag-and-drop local GeoTIFF files
|
|
13
|
+
- **Multiple layers** - Layer list with visibility toggles, reordering, zoom-to, and per-layer settings
|
|
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
|
+
- **Auto statistics** - Per-band min/max and histograms sampled from COG overviews (or GDAL metadata), with draggable histogram handles for the rescale range
|
|
16
|
+
- **Collapsible control** - A compact 29x29 map button that expands into a floating panel
|
|
17
|
+
- **TypeScript + React** - Full type definitions, a React wrapper component, and hooks
|
|
18
|
+
- **GeoLibre bundle output** - Builds a zip with root `plugin.json`, bundled ESM, and CSS for GeoLibre Desktop
|
|
19
|
+
|
|
20
|
+
## Installation
|
|
21
|
+
|
|
22
|
+
```bash
|
|
23
|
+
npm install maplibre-gl-raster
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
The plugin declares `maplibre-gl`, `@deck.gl/*`, and `@luma.gl/*` as peer dependencies (npm 7+ installs them automatically). This package is ESM-only.
|
|
27
|
+
|
|
28
|
+
## Quick Start
|
|
29
|
+
|
|
30
|
+
### Vanilla JavaScript/TypeScript
|
|
31
|
+
|
|
32
|
+
```typescript
|
|
33
|
+
import maplibregl from "maplibre-gl";
|
|
34
|
+
import { RasterControl } from "maplibre-gl-raster";
|
|
35
|
+
import "maplibre-gl-raster/style.css";
|
|
36
|
+
|
|
37
|
+
const map = new maplibregl.Map({
|
|
38
|
+
container: "map",
|
|
39
|
+
style: "https://basemaps.cartocdn.com/gl/positron-gl-style/style.json",
|
|
40
|
+
center: [0, 0],
|
|
41
|
+
zoom: 2,
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
map.on("load", () => {
|
|
45
|
+
const control = new RasterControl({ collapsed: false });
|
|
46
|
+
map.addControl(control, "top-right");
|
|
47
|
+
|
|
48
|
+
// Optionally add a raster programmatically (users can also paste a URL
|
|
49
|
+
// or drop a local GeoTIFF file in the panel).
|
|
50
|
+
control.addRaster("https://example.com/data/cog.tif");
|
|
51
|
+
});
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
### React
|
|
55
|
+
|
|
56
|
+
```tsx
|
|
57
|
+
import { useEffect, useRef, useState } from "react";
|
|
58
|
+
import maplibregl, { Map } from "maplibre-gl";
|
|
59
|
+
import { RasterControlReact, useRasterState } from "maplibre-gl-raster/react";
|
|
60
|
+
import "maplibre-gl-raster/style.css";
|
|
61
|
+
|
|
62
|
+
function App() {
|
|
63
|
+
const mapContainer = useRef<HTMLDivElement>(null);
|
|
64
|
+
const [map, setMap] = useState<Map | null>(null);
|
|
65
|
+
const { state, toggle } = useRasterState();
|
|
66
|
+
|
|
67
|
+
useEffect(() => {
|
|
68
|
+
if (!mapContainer.current) return;
|
|
69
|
+
|
|
70
|
+
const mapInstance = new maplibregl.Map({
|
|
71
|
+
container: mapContainer.current,
|
|
72
|
+
style: "https://basemaps.cartocdn.com/gl/positron-gl-style/style.json",
|
|
73
|
+
center: [0, 0],
|
|
74
|
+
zoom: 2,
|
|
75
|
+
});
|
|
76
|
+
|
|
77
|
+
mapInstance.on("load", () => setMap(mapInstance));
|
|
78
|
+
|
|
79
|
+
return () => mapInstance.remove();
|
|
80
|
+
}, []);
|
|
81
|
+
|
|
82
|
+
return (
|
|
83
|
+
<div style={{ width: "100%", height: "100vh" }}>
|
|
84
|
+
<div ref={mapContainer} style={{ width: "100%", height: "100%" }} />
|
|
85
|
+
{map && (
|
|
86
|
+
<RasterControlReact
|
|
87
|
+
map={map}
|
|
88
|
+
collapsed={state.collapsed}
|
|
89
|
+
onReady={(control) => control.addRaster("https://example.com/cog.tif")}
|
|
90
|
+
/>
|
|
91
|
+
)}
|
|
92
|
+
</div>
|
|
93
|
+
);
|
|
94
|
+
}
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
## API
|
|
98
|
+
|
|
99
|
+
### RasterControl
|
|
100
|
+
|
|
101
|
+
The main control class implementing MapLibre's `IControl` interface.
|
|
102
|
+
|
|
103
|
+
#### Constructor Options
|
|
104
|
+
|
|
105
|
+
| Option | Type | Default | Description |
|
|
106
|
+
| ------------- | --------- | ------------- | ------------------------------------------------------------------------- |
|
|
107
|
+
| `collapsed` | `boolean` | `true` | Whether the panel starts collapsed (showing only the 29x29 toggle button) |
|
|
108
|
+
| `position` | `string` | `'top-right'` | Control position on the map |
|
|
109
|
+
| `title` | `string` | `'Raster'` | Title displayed in the header |
|
|
110
|
+
| `panelWidth` | `number` | `360` | Width of the dropdown panel in pixels |
|
|
111
|
+
| `className` | `string` | `''` | Custom CSS class name |
|
|
112
|
+
| `interleaved` | `boolean` | `true` | Render the deck.gl overlay interleaved with the basemap layers |
|
|
113
|
+
| `defaultUrl` | `string` | `''` | Prefills the Add data URL input (not loaded until the user clicks Load) |
|
|
114
|
+
| `autoLoad` | `boolean` | `false` | Load `defaultUrl` automatically when the control is added to the map |
|
|
115
|
+
|
|
116
|
+
#### Raster Methods
|
|
117
|
+
|
|
118
|
+
- `addRaster(source, options?)` - Add a raster from a COG URL (`string`) or a local GeoTIFF `File`; resolves with the layer id
|
|
119
|
+
- `removeRaster(id)` - Remove a raster layer
|
|
120
|
+
- `getRaster(id)` / `getRasters()` - Get layer snapshots (`RasterLayerInfo`)
|
|
121
|
+
- `setRasterState(id, patch)` - Update visualization state (mode, bands, rescale, colormap, nodata, opacity, gamma, stretch, visible)
|
|
122
|
+
- `setVisible(id, visible)` - Show / hide a layer
|
|
123
|
+
- `selectRaster(id | null)` - Choose which layer the panel's settings edit
|
|
124
|
+
- `zoomToRaster(id)` - Fit the map to a layer's bounds
|
|
125
|
+
- `reorderRaster(id, toIndex)` - Move a layer in the draw order (0 = bottom)
|
|
126
|
+
|
|
127
|
+
`addRaster` options (`AddRasterOptions`): `id`, `name`, `state` (initial `Partial<RasterLayerState>` overrides), `zoomTo` (default `true`), and `beforeId` (insert the raster beneath an existing style layer, e.g. a label layer; also available as an input in the panel's Add data section).
|
|
128
|
+
|
|
129
|
+
#### Panel Methods
|
|
130
|
+
|
|
131
|
+
- `toggle()` / `expand()` / `collapse()` - Control the panel
|
|
132
|
+
- `getState()` / `setState(state)` - Control-level state (collapsed, panelWidth)
|
|
133
|
+
- `on(event, handler)` / `off(event, handler)` - Event handlers
|
|
134
|
+
- `getMap()` / `getContainer()` - Access the map / container
|
|
135
|
+
|
|
136
|
+
#### Events
|
|
137
|
+
|
|
138
|
+
- `collapse` / `expand` / `statechange` - Panel state events
|
|
139
|
+
- `rasteradd` / `rasterremove` / `rasterchange` / `rasterselect` - Layer lifecycle events (payload includes `layerId`)
|
|
140
|
+
- `error` - Loading or rendering errors (payload includes `error`)
|
|
141
|
+
|
|
142
|
+
### RasterLayerState
|
|
143
|
+
|
|
144
|
+
Per-layer visualization state, editable via the panel or `setRasterState`:
|
|
145
|
+
|
|
146
|
+
```typescript
|
|
147
|
+
interface RasterLayerState {
|
|
148
|
+
mode: "rgb" | "single"; // RGB composite or single band + colormap
|
|
149
|
+
bands: number[]; // 1-indexed band selection
|
|
150
|
+
rescale: [number, number][] | null; // per-channel min/max; null = auto (2-98%)
|
|
151
|
+
colormap: string; // colormap name; "palette" = embedded color table
|
|
152
|
+
nodata: number | "off" | "auto"; // nodata handling
|
|
153
|
+
opacity: number; // 0..1
|
|
154
|
+
gamma: number; // power-law correction (1 = off)
|
|
155
|
+
stretch: "linear" | "log" | "sqrt"; // curve applied after rescale
|
|
156
|
+
visible: boolean;
|
|
157
|
+
}
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
When a raster loads, the mode and bands are picked automatically (3+ bands → RGB `[1, 2, 3]`; otherwise single-band), and the rescale range defaults to the 2-98% percentile of sampled statistics. Single-band rasters use the image's embedded color table when it carries one (`colormap: "palette"`) and grayscale otherwise. The first four bands are fetched as GPU textures, so band combinations among them re-render instantly without re-downloading tiles.
|
|
161
|
+
|
|
162
|
+
### RasterControlReact
|
|
163
|
+
|
|
164
|
+
React wrapper component for `RasterControl`.
|
|
165
|
+
|
|
166
|
+
#### Props
|
|
167
|
+
|
|
168
|
+
All `RasterControl` options plus:
|
|
169
|
+
|
|
170
|
+
| Prop | Type | Description |
|
|
171
|
+
| --------------- | ---------- | ------------------------------------------------------ |
|
|
172
|
+
| `map` | `Map` | MapLibre GL map instance (required) |
|
|
173
|
+
| `onStateChange` | `function` | Callback fired when the control state changes |
|
|
174
|
+
| `onReady` | `function` | Receives the `RasterControl` instance after map attach |
|
|
175
|
+
|
|
176
|
+
### useRasterState
|
|
177
|
+
|
|
178
|
+
Custom React hook for managing control state.
|
|
179
|
+
|
|
180
|
+
```typescript
|
|
181
|
+
const {
|
|
182
|
+
state, // Current state
|
|
183
|
+
setState, // Update entire state
|
|
184
|
+
setCollapsed, // Set collapsed state
|
|
185
|
+
setPanelWidth, // Set panel width
|
|
186
|
+
setData, // Set custom data
|
|
187
|
+
reset, // Reset to initial state
|
|
188
|
+
toggle, // Toggle collapsed state
|
|
189
|
+
} = useRasterState(initialState);
|
|
190
|
+
```
|
|
191
|
+
|
|
192
|
+
### Utilities
|
|
193
|
+
|
|
194
|
+
The package also exports lower-level building blocks for advanced use:
|
|
195
|
+
|
|
196
|
+
- `loadGeoTIFF(url)` - Open a (CORS-safe) GeoTIFF from a URL or blob URL
|
|
197
|
+
- `computeAutoStats(tiff, signal, onProgress?)` - Per-band min/max + histograms
|
|
198
|
+
- `summarizeGeoTIFF(tiff)` - Image / CRS / band / GDAL metadata summary
|
|
199
|
+
- `readBandNames(tiff)` / `percentileFromHistogram(stats, p)`
|
|
200
|
+
- `COLORMAP_NAMES` / `COLORMAP_OPTIONS` / `colormapsPngUrl`
|
|
201
|
+
- `clamp`, `formatNumericValue`, `generateId`, `debounce`, `throttle`, `classNames`
|
|
202
|
+
|
|
203
|
+
## CORS requirements for remote COGs
|
|
204
|
+
|
|
205
|
+
Remote COGs must be served with CORS enabled (`Access-Control-Allow-Origin`). The loader includes a workaround for buckets that do not expose `Content-Range` via `Access-Control-Expose-Headers`, so most public S3/R2 buckets work out of the box.
|
|
206
|
+
|
|
207
|
+
## Build a GeoLibre plugin zip
|
|
208
|
+
|
|
209
|
+
GeoLibre Desktop loads external plugins from an app data `plugins/` directory. The zip must contain `plugin.json` at the root, plus a bundled ESM entry and optional CSS file.
|
|
210
|
+
|
|
211
|
+
```bash
|
|
212
|
+
npm install
|
|
213
|
+
npm run package:geolibre
|
|
214
|
+
```
|
|
215
|
+
|
|
216
|
+
This creates:
|
|
217
|
+
|
|
218
|
+
```text
|
|
219
|
+
geolibre-plugin/maplibre-gl-raster-0.1.0.zip
|
|
220
|
+
```
|
|
221
|
+
|
|
222
|
+
The generated zip contains:
|
|
223
|
+
|
|
224
|
+
```text
|
|
225
|
+
plugin.json
|
|
226
|
+
dist/index.js
|
|
227
|
+
dist/style.css
|
|
228
|
+
```
|
|
229
|
+
|
|
230
|
+
Copy the zip into GeoLibre Desktop's app data `plugins/` directory and restart GeoLibre. On Linux with the default app identifier, that directory is usually:
|
|
231
|
+
|
|
232
|
+
```text
|
|
233
|
+
~/.local/share/org.geolibre.desktop/plugins/
|
|
234
|
+
```
|
|
235
|
+
|
|
236
|
+
For the GeoLibre web app, serve the unpacked plugin with CORS enabled:
|
|
237
|
+
|
|
238
|
+
```bash
|
|
239
|
+
npm run package:geolibre
|
|
240
|
+
npm run serve:geolibre -- 8000
|
|
241
|
+
```
|
|
242
|
+
|
|
243
|
+
Then add this manifest URL in GeoLibre Settings > Plugins:
|
|
244
|
+
|
|
245
|
+
```text
|
|
246
|
+
http://localhost:8000/plugin.json
|
|
247
|
+
```
|
|
248
|
+
|
|
249
|
+
Using `python -m http.server` for this cross-origin web app case is not enough
|
|
250
|
+
because it does not send `Access-Control-Allow-Origin`.
|
|
251
|
+
|
|
252
|
+
## Development
|
|
253
|
+
|
|
254
|
+
### Setup
|
|
255
|
+
|
|
256
|
+
```bash
|
|
257
|
+
# Clone the repository
|
|
258
|
+
git clone https://github.com/opengeos/maplibre-gl-raster.git
|
|
259
|
+
cd maplibre-gl-raster
|
|
260
|
+
|
|
261
|
+
# Install dependencies
|
|
262
|
+
npm install
|
|
263
|
+
|
|
264
|
+
# Start development server
|
|
265
|
+
npm run dev
|
|
266
|
+
```
|
|
267
|
+
|
|
268
|
+
### Scripts
|
|
269
|
+
|
|
270
|
+
| Script | Description |
|
|
271
|
+
| -------------------------- | ---------------------------------------- |
|
|
272
|
+
| `npm run dev` | Start development server |
|
|
273
|
+
| `npm run build` | Build the library and GeoLibre bundle |
|
|
274
|
+
| `npm run build:lib` | Build the standalone MapLibre library |
|
|
275
|
+
| `npm run build:geolibre` | Build the GeoLibre ESM and CSS bundle |
|
|
276
|
+
| `npm run package:geolibre` | Build and zip the GeoLibre plugin bundle |
|
|
277
|
+
| `npm run build:examples` | Build examples for deployment |
|
|
278
|
+
| `npm run test` | Run tests |
|
|
279
|
+
| `npm run test:ui` | Run tests with UI |
|
|
280
|
+
| `npm run test:coverage` | Run tests with coverage |
|
|
281
|
+
| `npm run lint` | Lint the code |
|
|
282
|
+
| `npm run format` | Format the code |
|
|
283
|
+
|
|
284
|
+
### Project Structure
|
|
285
|
+
|
|
286
|
+
```text
|
|
287
|
+
maplibre-gl-raster/
|
|
288
|
+
├── geolibre-plugin/
|
|
289
|
+
│ └── plugin.json # GeoLibre external plugin manifest
|
|
290
|
+
├── scripts/
|
|
291
|
+
│ └── package-geolibre-plugin.mjs
|
|
292
|
+
├── src/
|
|
293
|
+
│ ├── index.ts # Main entry point
|
|
294
|
+
│ ├── geolibre.ts # GeoLibre plugin wrapper entry point
|
|
295
|
+
│ ├── react.ts # React entry point
|
|
296
|
+
│ ├── index.css # Root styles
|
|
297
|
+
│ └── lib/
|
|
298
|
+
│ ├── core/ # RasterControl, React wrapper, types
|
|
299
|
+
│ ├── raster/ # GeoTIFF loading, stats, GPU render pipeline
|
|
300
|
+
│ ├── state/ # RasterLayer model + LayerManager
|
|
301
|
+
│ ├── ui/ # Vanilla DOM panel components
|
|
302
|
+
│ ├── hooks/ # React hooks
|
|
303
|
+
│ ├── utils/ # Utility functions
|
|
304
|
+
│ └── styles/ # Component styles
|
|
305
|
+
├── tests/ # Test files
|
|
306
|
+
├── examples/ # Example applications
|
|
307
|
+
│ ├── basic/ # Vanilla JS example
|
|
308
|
+
│ └── react/ # React example
|
|
309
|
+
└── .github/workflows/ # CI/CD workflows
|
|
310
|
+
```
|
|
311
|
+
|
|
312
|
+
## Docker
|
|
313
|
+
|
|
314
|
+
The examples can be run using Docker. The image is automatically built and published to GitHub Container Registry.
|
|
315
|
+
|
|
316
|
+
### Pull and Run
|
|
317
|
+
|
|
318
|
+
```bash
|
|
319
|
+
# Pull the latest image
|
|
320
|
+
docker pull ghcr.io/opengeos/maplibre-gl-raster:latest
|
|
321
|
+
|
|
322
|
+
# Run the container
|
|
323
|
+
docker run -p 8080:80 ghcr.io/opengeos/maplibre-gl-raster:latest
|
|
324
|
+
```
|
|
325
|
+
|
|
326
|
+
Then open http://localhost:8080/maplibre-gl-raster/ in your browser to view the examples.
|
|
327
|
+
|
|
328
|
+
### Build Locally
|
|
329
|
+
|
|
330
|
+
```bash
|
|
331
|
+
# Build the image
|
|
332
|
+
docker build -t maplibre-gl-raster .
|
|
333
|
+
|
|
334
|
+
# Run the container
|
|
335
|
+
docker run -p 8080:80 maplibre-gl-raster
|
|
336
|
+
```
|
|
337
|
+
|
|
338
|
+
### Available Tags
|
|
339
|
+
|
|
340
|
+
| Tag | Description |
|
|
341
|
+
| -------- | -------------------------------- |
|
|
342
|
+
| `latest` | Latest release |
|
|
343
|
+
| `x.y.z` | Specific version (e.g., `1.0.0`) |
|
|
344
|
+
| `x.y` | Minor version (e.g., `1.0`) |
|
|
345
|
+
|
|
346
|
+
### Publish to npm
|
|
347
|
+
|
|
348
|
+
```bash
|
|
349
|
+
npm login
|
|
350
|
+
npm whoami
|
|
351
|
+
npm publish --access public
|
|
352
|
+
```
|
|
353
|
+
|
|
354
|
+
Set up Trusted Publisher on npmjs.com
|
|
355
|
+
|
|
356
|
+
## Credits
|
|
357
|
+
|
|
358
|
+
The rendering pipeline, GeoTIFF loading strategy, statistics sampling, and much of the visualization UX are ported from Source Cooperative's [cog-viewer](https://github.com/source-cooperative/cog-viewer), built on their excellent [@developmentseed/deck.gl-geotiff](https://github.com/developmentseed/deck.gl-raster) and [@developmentseed/deck.gl-raster](https://github.com/developmentseed/deck.gl-raster) libraries.
|
|
359
|
+
|
|
360
|
+
## License
|
|
361
|
+
|
|
362
|
+
MIT License - see [LICENSE](LICENSE) for details.
|