developmentseed / developmentseed/deck.gl-raster
Single-file no-build-step example
- Dominant language
- TypeScript
- Stars
- 228
- Forks
- 29
- Avg merge
- 12h 27m
- Merged PRs (30d)
- 4
Description
See https://github.com/microsoft/PlanetaryComputerDataCatalog/pull/530/changes#diff-75f8c328e1b62b6317e072b79dea671d5638af89f2c75bbe1b7f29491bf559f7
```html
Planetary Computer · deck.gl-raster (no build)
html, body { margin: 0; height: 100%; font-family: system-ui, sans-serif; }
#map { position: absolute; inset: 0; }
#panel {
position: absolute; top: 16px; left: 16px; z-index: 2; width: 240px;
background: #ffffff; border-radius: 10px; padding: 16px 18px;
box-shadow: 0 2px 14px #0003; font-size: 13px; color: #1a1a1a;
}
#panel h1 { font-size: 15px; margin: 0 0 6px; }
#panel .muted { color: #666; line-height: 1.4; }
#panel label { display: block; margin-top: 14px; font-weight: 600; }
#panel input[type=range] { width: 100%; }
#scene { font-family: ui-monospace, monospace; font-size: 11px; word-break: break-all; }
{
"imports": {
"maplibre-gl": "https://esm.sh/maplibre-gl@4.7.1",
"@deck.gl/core": "https://esm.sh/@deck.gl/core@9.3.2",
"@deck.gl/layers": "https://esm.sh/@deck.gl/layers@9.3.2",
"@deck.gl/geo-layers": "https://esm.sh/@deck.gl/geo-layers@9.3.2",
"@deck.gl/mesh-layers": "https://esm.sh/@deck.gl/mesh-layers@9.3.2",
"@deck.gl/mapbox": "https://esm.sh/@deck.gl/mapbox@9.3.2?external=@deck.gl/core,maplibre-gl",
"@luma.gl/core": "https://esm.sh/@luma.gl/core@9.3.2",
"@developmentseed/geotiff": "https://esm.sh/@developmentseed/geotiff@0.7.0",
"@developmentseed/deck.gl-geotiff": "https://esm.sh/@developmentseed/deck.gl-geotiff@0.7.0?external=@deck.gl/core,@deck.gl/layers,@deck.gl/geo-layers,@deck.gl/mesh-layers,@luma.gl/core,@developmentseed/geotiff"
}
}
NAIP over Portland
Imagery opacity
Scene
import maplibregl from "maplibre-gl";
import { MapboxOverlay } from "@deck.gl/mapbox";
import { COGLayer } from "@developmentseed/deck.gl-geotiff";
import { DecoderPool } from "@developmentseed/geotiff";
const STAC = "https://planetarycomputer.microsoft.com/api/stac/v1";
const SIGN = "https://planetarycomputer.microsoft.com/api/sas/v1/sign?href=";
const map = new maplibregl.Map({
container: "map",
style: "https://basemaps.cartocdn.com/gl/positron-gl-style/style.json",
center: [-122.62, 45.52],
zoom: 11,
});
// size: 0 keeps decoding on the main thread. The default pool spawns a
// Web Worker from the package URL, which browsers block when that URL is
// cross-origin (a CDN). Main-thread decoding sidesteps that for a
// single-file app; add a same-origin worker if you need the throughput.
const pool = new DecoderPool({ size: 0 });
const overlay = new MapboxOverlay({ interleaved: true, layers: [] });
map.addControl(overlay);
let opacity = 1;
let geotiff = null;
let beforeId = null; // draw imagery beneath the basemap's labels
let styleReady = false;
let fitted = false;
function render() {
if (!geotiff || !styleReady) return;
overlay.setProps({
layers: [
new COGLayer({
id: "naip",
geotiff,
pool,
opacity,
beforeId,
// Frame the map to the COG's own bounds once it has loaded.
onGeoTIFFLoad: (tiff, { geographicBounds }) => {
if (fitted) return;
fitted = true;
const { west, south, east, north } = geographicBounds;
map.fitBounds([[west, south], [east, north]], { padding: 40, duration: 0 });
},
}),
],
});
}
document.getElementById("opacity").addEventListener("input", (e) => {
opacity = e.target.value / 100;
render();
});
map.on("load", () => {
// Insert deck layers before the first label layer so basemap text
// (place names, roads) stays legible on top of the imagery.
beforeId = map.getStyle().layers.find((l) => l.type === "symbol")?.id;
styleReady = true;
render();
});
// Find a NAIP scene over Portland, then sign its asset href. The Planetary
// Computer signing endpoint is public. No key, no backend.
const search = await fetch(`${STAC}/search`, {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
collections: ["naip"],
bbox: [-122.70, 45.50, -122.55, 45.57],
datetime: "2022-01-01/2023-01-01",
limit: 1,
}),
}).then((r) => r.json());
const item = search.features[0];
const signed = await fetch(SIGN + encodeURIComponent(item.assets.image.href)).then((r) => r.json());
geotiff = signed.href;
document.getElementById("scene").textContent = item.id;
render();
```
Contributor guide
No contributing guide indexed for this repository
Assessment
This issue has not been assessed yet.