Skip to content

Commit 96488e5

Browse files
author
Jin Igarashi
authored
feat: add measure control to map editor (#4951)
* feat: add measure control to map editor * feat: added MeasureControl to GeoHub map editor and viewer * fix: delete terradraw layers from saved style
1 parent 80149b7 commit 96488e5

6 files changed

Lines changed: 81 additions & 24 deletions

File tree

.changeset/sour-melons-exercise.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"geohub": minor
3+
---
4+
5+
feat: added MeasureControl to GeoHub map editor and viewer

pnpm-lock.yaml

Lines changed: 28 additions & 19 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

sites/geohub/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,7 @@
7676
"@undp-data/svelte-undp-components": "workspace:*",
7777
"@undp-data/svelte-undp-design": "workspace:*",
7878
"@undp-data/undp-bulma": "workspace:*",
79+
"@watergis/maplibre-gl-terradraw": "^1.3.13",
7980
"@watergis/svelte-splitter": "^2.0.0",
8081
"@zerodevx/svelte-toast": "^0.9.6",
8182
"arraystat": "^1.7.81",

sites/geohub/src/components/pages/map/layers/StyleSaveDialog.svelte

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
import type { DashboardMapStyle } from '$lib/types';
88
import type { LayerListStore } from '$stores';
99
import { ModalTemplate, Notification } from '@undp-data/svelte-undp-components';
10+
import { cleanMaplibreStyle } from '@watergis/maplibre-gl-terradraw';
1011
import type { Map, StyleSpecification } from 'maplibre-gl';
1112
import { untrack } from 'svelte';
1213
@@ -139,11 +140,13 @@
139140
140141
const createStyleJSON2Generate = () => {
141142
if (!map) return;
142-
const style: StyleSpecification = map.getStyle();
143+
let style: StyleSpecification = map.getStyle();
143144
if ($layerList.length === 0) {
144145
return;
145146
}
146147
148+
style = cleanMaplibreStyle(style, { excludeTerraDrawLayers: true });
149+
147150
style.name = styleName;
148151
const center = map.getCenter();
149152
style.center = [center.lng, center.lat];

sites/geohub/src/routes/(app)/maps/[[id]]/edit/+page.svelte

Lines changed: 33 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,8 @@
3131
import MaplibreCgazAdminControl from '@undp-data/cgaz-admin-tool';
3232
import MaplibreStyleSwitcherControl from '@undp-data/style-switcher';
3333
import { MAPSTORE_CONTEXT_KEY, type MapStore } from '@undp-data/svelte-undp-components';
34+
import { MaplibreMeasureControl } from '@watergis/maplibre-gl-terradraw';
35+
import '@watergis/maplibre-gl-terradraw/dist/maplibre-gl-terradraw.css';
3436
import {
3537
AttributionControl,
3638
GeolocateControl,
@@ -73,6 +75,7 @@
7375
7476
let container: HTMLDivElement | undefined = $state();
7577
let styleSwitcher: MaplibreStyleSwitcherControl;
78+
let measureControl: MaplibreMeasureControl | undefined = $state();
7679
7780
const layerListStorageKey = storageKeys.layerList(page.url.host);
7881
const mapStyleStorageKey = storageKeys.mapStyle(page.url.host);
@@ -224,15 +227,24 @@
224227
step: 9,
225228
scrollTo: 'off'
226229
},
227-
230+
{
231+
title: 'Measuring distance, area and elevation',
232+
intro: `
233+
You can measure distance, area and elevation by drawing point, line or polygon.
234+
`,
235+
element: '.maplibregl-terradraw-render-button',
236+
position: 'left',
237+
step: 10,
238+
scrollTo: 'off'
239+
},
228240
{
229241
title: 'Disable hillshade layer',
230242
intro: `
231243
As default, a hillshade layer is shown on the basemap. You can also disable hillshade layer if you want.
232244
`,
233245
element: '.maplibregl-ctrl-hillshade-visibility',
234246
position: 'left',
235-
step: 10,
247+
step: 11,
236248
scrollTo: 'off'
237249
},
238250
{
@@ -242,7 +254,7 @@
242254
`,
243255
element: '.maplibregl-ctrl-geolocate',
244256
position: 'left',
245-
step: 11,
257+
step: 12,
246258
scrollTo: 'off'
247259
},
248260
{
@@ -251,7 +263,7 @@
251263
'You have completed map editor tour. Now you can start exploring GeoHub to create a beautiful map. You can always come back to the tour by clicking this button',
252264
element: '.tour-control-button',
253265
position: 'left',
254-
step: 12,
266+
step: 13,
255267
scrollTo: 'off'
256268
}
257269
]
@@ -448,6 +460,14 @@
448460
});
449461
$map.addControl(styleSwitcher, 'bottom-left');
450462
463+
measureControl = new MaplibreMeasureControl({
464+
modes: ['render', 'point', 'linestring', 'polygon', 'delete'],
465+
open: false,
466+
computeElevation: true
467+
});
468+
measureControl.fontGlyphs = ['Proxima Nova Italic'];
469+
$map.addControl(measureControl, 'bottom-right');
470+
451471
$map.once('load', mapInitializeAfterLoading);
452472
};
453473
@@ -474,6 +494,9 @@
474494
475495
map.subscribe((value) => {
476496
let storageValue = value ? value.getStyle() : null;
497+
if (storageValue && measureControl) {
498+
storageValue = measureControl.cleanStyle(storageValue, { excludeTerraDrawLayers: true });
499+
}
477500
toLocalStorage(mapStyleStorageKey, storageValue);
478501
});
479502
@@ -497,10 +520,16 @@
497520
$map.on('styledata', async () => {
498521
$showProgressBarStore = false;
499522
let storageValue = $map.getStyle();
523+
if (storageValue && measureControl) {
524+
storageValue = measureControl.cleanStyle(storageValue, { excludeTerraDrawLayers: true });
525+
}
500526
toLocalStorage(mapStyleStorageKey, storageValue);
501527
});
502528
$map.on('projectiontransition', () => {
503529
let storageValue = $map.getStyle();
530+
if (storageValue && measureControl) {
531+
storageValue = measureControl.cleanStyle(storageValue, { excludeTerraDrawLayers: true });
532+
}
504533
toLocalStorage(mapStyleStorageKey, storageValue);
505534
});
506535
};

sites/geohub/src/routes/(app)/maps/[id]/+page.svelte

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,8 @@
3434
type BreadcrumbPage,
3535
type Tab
3636
} from '@undp-data/svelte-undp-components';
37+
import { MaplibreMeasureControl } from '@watergis/maplibre-gl-terradraw';
38+
import '@watergis/maplibre-gl-terradraw/dist/maplibre-gl-terradraw.css';
3739
import { toast } from '@zerodevx/svelte-toast';
3840
import {
3941
AttributionControl,
@@ -192,6 +194,14 @@
192194
});
193195
map.addControl(styleSwitcher, 'bottom-left');
194196
197+
const measureControl = new MaplibreMeasureControl({
198+
modes: ['render', 'point', 'linestring', 'polygon', 'delete'],
199+
open: false,
200+
computeElevation: true
201+
});
202+
measureControl.fontGlyphs = ['Proxima Nova Italic'];
203+
map.addControl(measureControl, 'bottom-right');
204+
195205
map.once('load', async () => {
196206
map.resize();
197207
await styleSwitcher.initialise();

0 commit comments

Comments
 (0)