1
2
3
4
5
6
7
8import { MapView } from "mapgpu";
9import { RasterTileLayer } from "mapgpu/layers";
10import { RenderEngine } from "mapgpu/render";
11import { TerrainRGBLayer } from "mapgpu/terrain";
12
13import type { RunResultObject } from "@/components/examples/ExampleCanvas";
14
15type Provider = "terrarium" | "terrain-rgb";
16
17const PROVIDERS: Record<Provider, { url: string; encoding: Provider }> = {
18 terrarium: {
19 url: "https://s3.amazonaws.com/elevation-tiles-prod/terrarium/{z}/{x}/{y}.png",
20 encoding: "terrarium",
21 },
22 "terrain-rgb": {
23 url: "https://elevation-tiles-prod.s3.amazonaws.com/v2/terrarium/{z}/{x}/{y}.png",
24 encoding: "terrain-rgb",
25 },
26};
27
28export async function run(container: HTMLElement): Promise<RunResultObject> {
29 const view = new MapView({
30 container,
31 renderEngine: new RenderEngine(),
32 mode: "3d",
33 center: [-122.45, 38.5],
34 zoom: 9,
35 pitch: 45,
36 bearing: -25,
37 backgroundColor: "transparent",
38 globeEffects: {
39 atmosphere: { enabled: true, strength: 1.0, falloff: 3 },
40 },
41 });
42
43 view.map.add(
44 new RasterTileLayer({
45 id: "carto-light",
46 urlTemplate: "https://{s}.basemaps.cartocdn.com/light_all/{z}/{x}/{y}.png",
47 subdomains: ["a", "b", "c", "d"],
48 maxZoom: 19,
49 attribution: "© CARTO · © OpenStreetMap contributors",
50 }),
51 );
52
53 const state: { provider: Provider; exag: number } = { provider: "terrarium", exag: 1.3 };
54 let terrain = new TerrainRGBLayer({
55 id: "terrain",
56 tileUrls: [PROVIDERS.terrarium.url],
57 encoding: PROVIDERS.terrarium.encoding,
58 exaggeration: state.exag,
59 });
60 view.map.add(terrain);
61
62 await view.when();
63
64 const rebuild = () => {
65 const p = PROVIDERS[state.provider];
66 view.map.remove(terrain);
67 terrain = new TerrainRGBLayer({
68 id: "terrain",
69 tileUrls: [p.url],
70 encoding: p.encoding,
71 exaggeration: state.exag,
72 });
73 view.map.add(terrain);
74 };
75
76 return {
77 dispose: () => view.destroy(),
78 controls: [
79 {
80 kind: "segmented",
81 id: "encoding",
82 initial: "terrarium",
83 options: [
84 { value: "terrarium", label: "Terrarium" },
85 { value: "terrain-rgb", label: "Mapbox RGB" },
86 ],
87 onChange: (value) => {
88 state.provider = value as Provider;
89 rebuild();
90 },
91 },
92 {
93 kind: "segmented",
94 id: "exag",
95 initial: "1.3",
96 options: [
97 { value: "1", label: "1×" },
98 { value: "1.3", label: "1.3×" },
99 { value: "2", label: "2×" },
100 ],
101 onChange: (value) => {
102 state.exag = Number(value);
103 rebuild();
104 },
105 },
106 ],
107 };
108}