1
2
3
4
5
6
7import { MapView } from "mapgpu";
8import { RasterTileLayer, VectorTileLayer } from "mapgpu/layers";
9import { RenderEngine } from "mapgpu/render";
10import { ClassBreaksRenderer } from "mapgpu/core";
11
12import type { RunResultObject } from "@/components/examples/ExampleCanvas";
13
14const HEIGHT_COLORS: Array<[number, number, number]> = [
15 [65, 182, 196], [127, 205, 187], [199, 233, 180],
16 [237, 248, 177], [255, 255, 204], [255, 237, 160],
17 [254, 217, 118], [254, 178, 76], [253, 141, 60],
18 [252, 78, 42], [227, 26, 28], [189, 0, 38], [128, 0, 38],
19];
20const HEIGHT_BREAKS = [0, 3, 6, 9, 12, 15, 20, 30, 50, 80, 120, 200, 500];
21
22export async function run(container: HTMLElement): Promise<RunResultObject> {
23 const view = new MapView({
24 container,
25 renderEngine: new RenderEngine(),
26 mode: "3d",
27 center: [28.9784, 41.0082],
28 zoom: 15,
29 pitch: 60,
30 bearing: -30,
31 backgroundColor: "transparent",
32 globeEffects: {
33 atmosphere: { enabled: true, strength: 1.2, falloff: 3 },
34 },
35 });
36
37 view.map.add(
38 new RasterTileLayer({
39 id: "carto-dark",
40 urlTemplate: "https://{s}.basemaps.cartocdn.com/dark_all/{z}/{x}/{y}.png",
41 subdomains: ["a", "b", "c", "d"],
42 maxZoom: 19,
43 attribution: "© CARTO · © OpenStreetMap contributors",
44 }),
45 );
46
47 const heightRenderer = new ClassBreaksRenderer({
48 field: "render_height",
49 defaultSymbol: {
50 type: "fill-extrusion",
51 color: [...HEIGHT_COLORS[4]!, 220] as [number, number, number, number],
52 heightField: "render_height",
53 minHeightField: "render_min_height",
54 ambient: 0.35,
55 shininess: 32,
56 specularStrength: 0.15,
57 },
58 breaks: HEIGHT_COLORS.map((c, i) => ({
59 min: HEIGHT_BREAKS[i]!,
60 max: HEIGHT_BREAKS[i + 1] ?? Infinity,
61 symbol: {
62 type: "fill-extrusion",
63 color: [...c, 220] as [number, number, number, number],
64 heightField: "render_height",
65 minHeightField: "render_min_height",
66 ambient: 0.35,
67 shininess: 32,
68 specularStrength: 0.15,
69 },
70 })),
71 });
72
73 const buildings = new VectorTileLayer({
74 id: "nyc-buildings",
75 url: "https://tiles.openfreemap.org/planet/20260311_001001_pt/{z}/{x}/{y}.pbf",
76 sourceLayer: "building",
77 minZoom: 13,
78 maxZoom: 14,
79 renderer: heightRenderer,
80 });
81 view.map.add(buildings);
82
83 await view.when();
84
85 return {
86 dispose: () => view.destroy(),
87 controls: [],
88 };
89}