1
2
3
4
5
6
7
8import { MapView } from "mapgpu";
9import { GraphicsLayer, RasterTileLayer } from "mapgpu/layers";
10import { RenderEngine } from "mapgpu/render";
11import { setupDrawingTools } from "mapgpu/tools";
12
13import type { RunResultObject } from "@/components/examples/ExampleCanvas";
14
15type ToolKind = "point" | "polyline" | "polygon" | "edit";
16
17export async function run(container: HTMLElement): Promise<RunResultObject> {
18 const view = new MapView({
19 container,
20 renderEngine: new RenderEngine(),
21 mode: "2d",
22 center: [29.0, 41.0],
23 zoom: 11,
24 minZoom: 4,
25 maxZoom: 19,
26 backgroundColor: "transparent",
27 });
28
29 view.map.add(
30 new RasterTileLayer({
31 id: "carto-light",
32 urlTemplate: "https://{s}.basemaps.cartocdn.com/light_all/{z}/{x}/{y}.png",
33 subdomains: ["a", "b", "c", "d"],
34 maxZoom: 19,
35 attribution: "© CARTO · © OpenStreetMap contributors",
36 }),
37 );
38
39
40
41 const drawings = new GraphicsLayer({ id: "drawings" });
42 const preview = new GraphicsLayer({ id: "__tool-preview__" });
43 view.map.add(drawings);
44 view.map.add(preview);
45
46 const tm = setupDrawingTools(view.toolManager, {
47 targetLayer: drawings,
48 previewLayer: preview,
49 });
50
51 await view.when();
52
53 const state: { kind: ToolKind; active: boolean } = { kind: "polyline", active: false };
54 const toolId = (k: ToolKind) =>
55 k === "point" ? "draw-point"
56 : k === "polyline" ? "draw-polyline"
57 : k === "polygon" ? "draw-polygon"
58 : "edit";
59 const sync = () => {
60 if (state.active) tm.activateTool(toolId(state.kind));
61 else tm.deactivateTool();
62 };
63
64 return {
65 dispose: () => view.destroy(),
66 controls: [
67 {
68 kind: "segmented",
69 id: "tool",
70 initial: "polyline",
71 options: [
72 { value: "point", label: "Point" },
73 { value: "polyline", label: "Polyline" },
74 { value: "polygon", label: "Polygon" },
75 { value: "edit", label: "Edit" },
76 ],
77 onChange: (value) => {
78 state.kind = value as ToolKind;
79 sync();
80 },
81 },
82 {
83 kind: "toggle",
84 id: "active",
85 labels: ["idle", "active"],
86 initial: false,
87 onChange: (on) => {
88 state.active = on;
89 sync();
90 },
91 },
92 {
93 kind: "button",
94 id: "undo",
95 label: "Undo",
96 onClick: () => tm.undo(),
97 },
98 {
99 kind: "button",
100 id: "clear",
101 label: "Clear",
102 onClick: () => {
103 drawings.clear();
104 preview.clear();
105 },
106 },
107 ],
108 };
109}