@defra/interactive-map 0.0.15-alpha → 0.0.16-alpha
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/assets/css/docusaurus.css +104 -0
- package/assets/images/favicon.svg +1 -0
- package/assets/images/hero.png +0 -0
- package/dist/esm/im-core.js +1 -1
- package/dist/umd/im-core.js +1 -1
- package/dist/umd/index.js +1 -1
- package/docs/api/slot-map.svg +1 -0
- package/docs/api/slots.md +89 -6
- package/docs/api.md +1 -1
- package/docs/architecture.md +3 -1
- package/docs/{demo.mdx → examples.mdx} +1 -1
- package/docs/getting-started.md +1 -3
- package/docs/index.mdx +42 -0
- package/docs/plugins/interact.md +176 -55
- package/docs/plugins/map-styles.md +64 -7
- package/docs/plugins/search.md +207 -63
- package/docs/plugins.md +7 -15
- package/docusaurus.config.cjs +34 -34
- package/jest.setup.js +1 -1
- package/package.json +5 -4
- package/plugins/beta/datasets/src/DatasetsInit.jsx +1 -1
- package/plugins/beta/datasets/src/api/addDataset.js +1 -1
- package/plugins/beta/datasets/src/api/hideDataset.js +1 -1
- package/plugins/beta/datasets/src/api/hideFeatures.js +1 -1
- package/plugins/beta/datasets/src/api/removeDataset.js +1 -1
- package/plugins/beta/datasets/src/api/showDataset.js +1 -1
- package/plugins/beta/datasets/src/api/showFeatures.js +1 -1
- package/plugins/beta/datasets/src/datasets.js +4 -4
- package/plugins/beta/datasets/src/defaults.js +1 -1
- package/plugins/beta/datasets/src/fetch/createDynamicSource.js +5 -5
- package/plugins/beta/datasets/src/handleSetMapStyle.js +1 -1
- package/plugins/beta/datasets/src/manifest.js +3 -3
- package/plugins/beta/datasets/src/mapLayers.js +2 -3
- package/plugins/beta/datasets/src/panels/Key.jsx +31 -29
- package/plugins/beta/datasets/src/panels/Layers.jsx +8 -9
- package/plugins/beta/datasets/src/utils/bbox.js +4 -4
- package/plugins/beta/draw-es/dist/esm/im-draw-es-plugin.js +1 -1
- package/plugins/beta/draw-es/src/DrawInit.jsx +16 -16
- package/plugins/beta/draw-es/src/api/addFeature.js +3 -3
- package/plugins/beta/draw-es/src/api/deleteFeature.js +3 -3
- package/plugins/beta/draw-es/src/api/editFeature.js +3 -3
- package/plugins/beta/draw-es/src/api/newPolygon.js +3 -3
- package/plugins/beta/draw-es/src/events.js +52 -20
- package/plugins/beta/draw-es/src/events.test.js +301 -0
- package/plugins/beta/draw-es/src/graphic.js +1 -1
- package/plugins/beta/draw-es/src/manifest.js +4 -4
- package/plugins/beta/draw-es/src/reducer.js +1 -1
- package/plugins/beta/draw-es/src/sketchViewModel.js +1 -1
- package/plugins/beta/draw-ml/dist/esm/im-draw-ml-plugin.js +1 -1
- package/plugins/beta/draw-ml/dist/umd/im-draw-ml-plugin.js +1 -1
- package/plugins/beta/draw-ml/src/DrawInit.jsx +49 -52
- package/plugins/beta/draw-ml/src/api/deleteFeature.js +1 -1
- package/plugins/beta/draw-ml/src/api/editFeature.js +8 -5
- package/plugins/beta/draw-ml/src/api/newLine.js +0 -1
- package/plugins/beta/draw-ml/src/api/newPolygon.js +0 -1
- package/plugins/beta/draw-ml/src/api/split.js +4 -4
- package/plugins/beta/draw-ml/src/defaults.js +1 -1
- package/plugins/beta/draw-ml/src/events.js +8 -6
- package/plugins/beta/draw-ml/src/manifest.js +15 -15
- package/plugins/beta/draw-ml/src/mapboxDraw.js +1 -1
- package/plugins/beta/draw-ml/src/mapboxSnap.js +17 -18
- package/plugins/beta/draw-ml/src/modes/createDrawMode.js +31 -31
- package/plugins/beta/draw-ml/src/modes/disabledMode.js +1 -1
- package/plugins/beta/draw-ml/src/modes/editVertex/touchHandlers.js +11 -11
- package/plugins/beta/draw-ml/src/modes/editVertex/undoHandlers.js +7 -7
- package/plugins/beta/draw-ml/src/modes/editVertex/vertexOperations.js +8 -8
- package/plugins/beta/draw-ml/src/modes/editVertex/vertexQueries.js +7 -7
- package/plugins/beta/draw-ml/src/modes/editVertexMode.js +32 -24
- package/plugins/beta/draw-ml/src/reducer.js +1 -1
- package/plugins/beta/draw-ml/src/undoStack.js +4 -4
- package/plugins/beta/draw-ml/src/utils/snapHelpers.js +12 -12
- package/plugins/beta/draw-ml/src/utils/spatial.js +11 -11
- package/plugins/beta/frame/src/Frame.jsx +4 -4
- package/plugins/beta/frame/src/FrameInit.jsx +4 -4
- package/plugins/beta/frame/src/api/addFrame.js +1 -1
- package/plugins/beta/frame/src/api/editFeature.js +1 -1
- package/plugins/beta/frame/src/config.js +1 -1
- package/plugins/beta/frame/src/manifest.js +3 -3
- package/plugins/beta/frame/src/reducer.js +1 -1
- package/plugins/beta/frame/src/utils.js +1 -1
- package/plugins/beta/map-styles/src/MapStyles.jsx +18 -18
- package/plugins/beta/scale-bar/src/ScaleBar.jsx +5 -5
- package/plugins/beta/use-location/src/UseLocation.jsx +1 -1
- package/plugins/beta/use-location/src/defaults.js +1 -1
- package/plugins/beta/use-location/src/events.js +3 -3
- package/plugins/interact/src/InteractInit.jsx +1 -2
- package/plugins/interact/src/api/enable.js +8 -5
- package/plugins/interact/src/api/enable.test.js +2 -2
- package/plugins/interact/src/api/selectFeature.js +4 -4
- package/plugins/interact/src/api/unselectFeature.js +5 -5
- package/plugins/interact/src/defaults.js +0 -1
- package/plugins/interact/src/events.test.js +15 -15
- package/plugins/interact/src/hooks/useHighlightSync.js +1 -1
- package/plugins/interact/src/hooks/useInteractionHandlers.js +2 -2
- package/plugins/interact/src/hooks/useInteractionHandlers.test.js +5 -5
- package/plugins/interact/src/manifest.js +2 -2
- package/plugins/interact/src/manifest.test.js +3 -4
- package/plugins/interact/src/reducer.js +3 -3
- package/plugins/interact/src/reducer.test.js +0 -1
- package/plugins/interact/src/utils/spatial.js +10 -10
- package/plugins/interact/src/utils/spatial.test.js +14 -14
- package/plugins/search/dist/css/index.css +1 -1
- package/plugins/search/dist/esm/im-search-plugin.js +1 -1
- package/plugins/search/dist/esm/index.js +1 -1
- package/plugins/search/dist/umd/im-search-plugin.js +1 -1
- package/plugins/search/dist/umd/index.js +1 -1
- package/plugins/search/src/Search.jsx +7 -6
- package/plugins/search/src/Search.test.jsx +23 -23
- package/plugins/search/src/components/CloseButton/CloseButton.jsx +15 -15
- package/plugins/search/src/components/CloseButton/CloseButton.test.jsx +2 -2
- package/plugins/search/src/components/Form/Form.jsx +14 -14
- package/plugins/search/src/components/Form/Form.test.jsx +11 -11
- package/plugins/search/src/components/OpenButton/OpenButton.jsx +16 -15
- package/plugins/search/src/components/OpenButton/OpenButton.test.jsx +6 -2
- package/plugins/search/src/components/SubmitButton/SubmitButton.jsx +15 -15
- package/plugins/search/src/components/Suggestions/Suggestions.jsx +6 -6
- package/plugins/search/src/components/Suggestions/Suggestions.test.jsx +4 -4
- package/plugins/search/src/datasets.js +12 -13
- package/plugins/search/src/datasets.test.js +1 -1
- package/plugins/search/src/defaults.js +1 -1
- package/plugins/search/src/events/fetchSuggestions.js +3 -3
- package/plugins/search/src/events/fetchSuggestions.test.js +1 -1
- package/plugins/search/src/events/formHandlers.js +3 -3
- package/plugins/search/src/events/formHandlers.test.js +1 -1
- package/plugins/search/src/events/index.js +2 -2
- package/plugins/search/src/events/index.test.js +2 -2
- package/plugins/search/src/events/inputHandlers.js +4 -4
- package/plugins/search/src/events/inputHandlers.test.js +1 -1
- package/plugins/search/src/events/suggestionHandlers.js +2 -2
- package/plugins/search/src/events/suggestionHandlers.test.js +1 -1
- package/plugins/search/src/index.js +2 -1
- package/plugins/search/src/index.test.js +3 -3
- package/plugins/search/src/manifest.js +6 -4
- package/plugins/search/src/reducer.js +1 -2
- package/plugins/search/src/reducer.test.js +2 -2
- package/plugins/search/src/search.scss +10 -3
- package/plugins/search/src/utils/parseOsNamesResults.js +1 -2
- package/plugins/search/src/utils/parseOsNamesResults.test.js +2 -2
- package/plugins/search/src/utils/updateMap.js +1 -1
- package/plugins/search/src/utils/updateMap.test.js +5 -5
- package/providers/beta/esri/dist/esm/im-esri-provider.js +1 -1
- package/providers/beta/esri/src/esriProvider.js +5 -5
- package/providers/beta/esri/src/utils/coords.js +1 -1
- package/providers/beta/esri/src/utils/esriFixes.js +1 -1
- package/providers/beta/esri/src/utils/query.js +4 -4
- package/providers/beta/esri/src/utils/spatial.js +1 -2
- package/providers/beta/esri/src/utils/spatial.test.js +4 -1
- package/providers/beta/open-names/src/utils/mapToLocationModel.test.js +1 -1
- package/providers/maplibre/src/appEvents.test.js +1 -1
- package/providers/maplibre/src/index.js +1 -1
- package/providers/maplibre/src/index.test.js +3 -5
- package/providers/maplibre/src/mapEvents.test.js +15 -5
- package/providers/maplibre/src/maplibreProvider.test.js +6 -2
- package/providers/maplibre/src/utils/calculateLinearTextSize.js +4 -4
- package/providers/maplibre/src/utils/calculateLinearTextSize.test.js +3 -3
- package/providers/maplibre/src/utils/detectWebgl.test.js +1 -1
- package/providers/maplibre/src/utils/highlightFeatures.js +2 -2
- package/providers/maplibre/src/utils/highlightFeatures.test.js +12 -6
- package/providers/maplibre/src/utils/labels.js +19 -20
- package/providers/maplibre/src/utils/labels.test.js +15 -13
- package/providers/maplibre/src/utils/maplibreFixes.test.js +1 -1
- package/providers/maplibre/src/utils/queryFeatures.js +6 -6
- package/providers/maplibre/src/utils/queryFeatures.test.js +13 -13
- package/providers/maplibre/src/utils/spatial.js +0 -1
- package/providers/maplibre/src/utils/spatial.test.js +26 -27
- package/src/App/registry/pluginRegistry.js +17 -0
- package/src/App/registry/pluginRegistry.test.js +33 -0
- package/src/App/renderer/mapButtons.js +3 -2
- package/src/App/store/appDispatchMiddleware.js +33 -1
- package/src/App/store/appDispatchMiddleware.test.js +250 -222
- package/src/config/appConfig.js +2 -2
- package/src/utils/logger.js +6 -0
- package/src/utils/logger.test.js +32 -0
- package/webpack.dev.mjs +22 -18
- package/docs/govuk-prototype.md +0 -23
- package/docs/index.md +0 -19
|
@@ -3,70 +3,67 @@ import { attachEvents } from './events.js'
|
|
|
3
3
|
import { createMapboxDraw } from './mapboxDraw.js'
|
|
4
4
|
|
|
5
5
|
export const DrawInit = ({ appState, appConfig, mapState, pluginConfig, pluginState, services, mapProvider, buttonConfig }) => {
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
6
|
+
const { events, eventBus } = services
|
|
7
|
+
const { crossHair } = mapState
|
|
8
|
+
const isTouchOrKeyboard = ['touch', 'keyboard'].includes(appState.interfaceType)
|
|
9
9
|
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
10
|
+
// Create draw instance once
|
|
11
|
+
useEffect(() => {
|
|
12
|
+
// Don't run init if the app is in non-specified mode
|
|
13
|
+
const inModeWhitelist = pluginConfig.includeModes?.includes(appState.mode) ?? true
|
|
14
|
+
const inExcludeModes = pluginConfig.excludeModes?.includes(appState.mode) ?? false
|
|
15
15
|
|
|
16
16
|
if (!mapState.isMapReady || !inModeWhitelist || inExcludeModes) {
|
|
17
17
|
return
|
|
18
18
|
}
|
|
19
19
|
|
|
20
20
|
const { remove } = createMapboxDraw({
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
21
|
+
mapStyle: mapState.mapStyle,
|
|
22
|
+
snapLayers: pluginConfig.snapLayers,
|
|
23
|
+
mapProvider,
|
|
24
|
+
events,
|
|
25
|
+
eventBus
|
|
26
|
+
})
|
|
27
27
|
|
|
28
|
-
|
|
29
|
-
|
|
28
|
+
// Initialize snap layers flag from config
|
|
29
|
+
pluginState.dispatch({ type: 'SET_HAS_SNAP_LAYERS', payload: pluginConfig.snapLayers?.length > 0 })
|
|
30
30
|
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
return () => remove()
|
|
31
|
+
// Draw ready
|
|
32
|
+
eventBus.emit('draw:ready')
|
|
35
33
|
|
|
34
|
+
return () => remove()
|
|
36
35
|
}, [mapState.isMapReady, appState.mode])
|
|
37
36
|
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
// Attach events when plgin state changes
|
|
52
|
-
useEffect(() => {
|
|
53
|
-
|
|
54
|
-
if (!mapProvider.draw) {
|
|
55
|
-
return
|
|
56
|
-
}
|
|
37
|
+
// Show crosshair immediately on touch/keyboard when entering draw mode
|
|
38
|
+
useEffect(() => {
|
|
39
|
+
if (['draw_polygon', 'draw_line'].includes(pluginState.mode) && isTouchOrKeyboard) {
|
|
40
|
+
const wasAlreadyVisible = crossHair.isVisible
|
|
41
|
+
crossHair.fixAtCenter()
|
|
42
|
+
return () => {
|
|
43
|
+
if (!wasAlreadyVisible) {
|
|
44
|
+
crossHair.hide()
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
}, [pluginState.mode, appState.interfaceType])
|
|
57
49
|
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
buttonConfig,
|
|
64
|
-
pluginState,
|
|
65
|
-
events,
|
|
66
|
-
eventBus
|
|
67
|
-
})
|
|
50
|
+
// Attach events when plgin state changes
|
|
51
|
+
useEffect(() => {
|
|
52
|
+
if (!mapProvider.draw) {
|
|
53
|
+
return
|
|
54
|
+
}
|
|
68
55
|
|
|
69
|
-
|
|
56
|
+
const cleanupEvents = attachEvents({
|
|
57
|
+
appState,
|
|
58
|
+
appConfig,
|
|
59
|
+
mapState,
|
|
60
|
+
mapProvider,
|
|
61
|
+
buttonConfig,
|
|
62
|
+
pluginState,
|
|
63
|
+
events,
|
|
64
|
+
eventBus
|
|
65
|
+
})
|
|
70
66
|
|
|
71
|
-
|
|
72
|
-
}
|
|
67
|
+
return () => cleanupEvents()
|
|
68
|
+
}, [mapProvider, appState, pluginState])
|
|
69
|
+
}
|
|
@@ -55,13 +55,16 @@ export const editFeature = ({ appState, appConfig, mapState, pluginConfig, plugi
|
|
|
55
55
|
|
|
56
56
|
// Put feature in state
|
|
57
57
|
const feature = draw.get(featureId)
|
|
58
|
-
dispatch({
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
58
|
+
dispatch({
|
|
59
|
+
type: 'SET_FEATURE',
|
|
60
|
+
payload: {
|
|
61
|
+
feature,
|
|
62
|
+
tempFeature: feature
|
|
63
|
+
}
|
|
64
|
+
})
|
|
62
65
|
|
|
63
66
|
// Set mode to edit_vertex
|
|
64
67
|
dispatch({ type: 'SET_MODE', payload: 'edit_vertex' })
|
|
65
68
|
|
|
66
69
|
return true
|
|
67
|
-
}
|
|
70
|
+
}
|
|
@@ -53,7 +53,7 @@ export const split = ({ appState, appConfig, pluginState, mapProvider }, feature
|
|
|
53
53
|
const lineFeature = e.features[0]
|
|
54
54
|
const featureCollection = splitPolygon(polygonFeature, lineFeature)
|
|
55
55
|
draw.setFeatureProperty('_splitter', 'splitter', featureCollection ? 'valid' : 'invalid')
|
|
56
|
-
dispatch({ type: 'SET_ACTION', payload: { name: 'split', isValid: !!featureCollection }})
|
|
56
|
+
dispatch({ type: 'SET_ACTION', payload: { name: 'split', isValid: !!featureCollection } })
|
|
57
57
|
})
|
|
58
58
|
|
|
59
59
|
// Real time check for valid line
|
|
@@ -62,13 +62,13 @@ export const split = ({ appState, appConfig, pluginState, mapProvider }, feature
|
|
|
62
62
|
if (e.coordinates.length < 2) {
|
|
63
63
|
return
|
|
64
64
|
}
|
|
65
|
-
const lineFeature = { id: '_splitter', geometry: { type: 'LineString', coordinates: e.coordinates }}
|
|
65
|
+
const lineFeature = { id: '_splitter', geometry: { type: 'LineString', coordinates: e.coordinates } }
|
|
66
66
|
const featureCollection = splitPolygon(polygonFeature, lineFeature)
|
|
67
67
|
const isValid = !!featureCollection
|
|
68
68
|
e.properties.splitter = isValid ? 'valid' : 'invalid'
|
|
69
69
|
e.ctx.store.render()
|
|
70
70
|
if (draw.getMode() === 'edit_vertex') {
|
|
71
|
-
dispatch({ type: 'SET_ACTION', payload: { name: 'split', isValid }})
|
|
71
|
+
dispatch({ type: 'SET_ACTION', payload: { name: 'split', isValid } })
|
|
72
72
|
}
|
|
73
73
|
}, DEBOUNCE_SPLIT_POLYGON)
|
|
74
74
|
map.on('draw.geometrychange', onGeometryChange)
|
|
@@ -77,5 +77,5 @@ export const split = ({ appState, appConfig, pluginState, mapProvider }, feature
|
|
|
77
77
|
dispatch({ type: 'SET_MODE', payload: 'draw_line' })
|
|
78
78
|
|
|
79
79
|
// Set action to 'split'
|
|
80
|
-
dispatch({ type: 'SET_ACTION', payload: { name: 'split' }})
|
|
80
|
+
dispatch({ type: 'SET_ACTION', payload: { name: 'split' } })
|
|
81
81
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { clearSnapState, getSnapInstance } from './utils/snapHelpers.js'
|
|
2
2
|
|
|
3
|
-
export function attachEvents({ pluginState, mapProvider, buttonConfig, eventBus }) {
|
|
3
|
+
export function attachEvents ({ pluginState, mapProvider, buttonConfig, eventBus }) {
|
|
4
4
|
const { drawDone, drawAddPoint, drawUndo, drawDeletePoint, drawSnap, drawCancel } = buttonConfig
|
|
5
5
|
const { map, draw } = mapProvider
|
|
6
6
|
const { dispatch, feature, tempFeature } = pluginState
|
|
@@ -23,7 +23,7 @@ export function attachEvents({ pluginState, mapProvider, buttonConfig, eventBus
|
|
|
23
23
|
const resetDrawModeAndFeature = () => {
|
|
24
24
|
mapProvider.undoStack?.clear()
|
|
25
25
|
dispatch({ type: 'SET_MODE', payload: null })
|
|
26
|
-
dispatch({ type: 'SET_FEATURE', payload: { feature: null, tempFeature: null }})
|
|
26
|
+
dispatch({ type: 'SET_FEATURE', payload: { feature: null, tempFeature: null } })
|
|
27
27
|
}
|
|
28
28
|
|
|
29
29
|
// --- Button handlers
|
|
@@ -156,9 +156,11 @@ export function attachEvents({ pluginState, mapProvider, buttonConfig, eventBus
|
|
|
156
156
|
|
|
157
157
|
// --- Cleanup
|
|
158
158
|
return () => {
|
|
159
|
-
[drawDone, drawAddPoint, drawUndo, drawDeletePoint, drawSnap, drawCancel].forEach(btn => {
|
|
160
|
-
btn
|
|
161
|
-
|
|
159
|
+
[drawDone, drawAddPoint, drawUndo, drawDeletePoint, drawSnap, drawCancel].forEach(btn => {
|
|
160
|
+
if (btn) {
|
|
161
|
+
btn.onClick = null
|
|
162
|
+
}
|
|
163
|
+
})
|
|
162
164
|
map.off('styledata', handleStyleData)
|
|
163
165
|
map.off('draw.cancel', handleCancel)
|
|
164
166
|
map.off('draw.create', onCreate)
|
|
@@ -168,4 +170,4 @@ export function attachEvents({ pluginState, mapProvider, buttonConfig, eventBus
|
|
|
168
170
|
map.off('draw.vertexchange', onVertexChange)
|
|
169
171
|
map.off('draw.undochange', onUndoChange)
|
|
170
172
|
}
|
|
171
|
-
}
|
|
173
|
+
}
|
|
@@ -10,8 +10,8 @@ import { split } from './api/split.js'
|
|
|
10
10
|
import { merge } from './api/merge.js'
|
|
11
11
|
|
|
12
12
|
const createButtonSlots = (showLabel) => ({
|
|
13
|
-
mobile:
|
|
14
|
-
tablet:
|
|
13
|
+
mobile: { slot: 'actions', showLabel },
|
|
14
|
+
tablet: { slot: 'actions', showLabel },
|
|
15
15
|
desktop: { slot: 'actions', showLabel }
|
|
16
16
|
})
|
|
17
17
|
|
|
@@ -30,13 +30,13 @@ export const manifest = {
|
|
|
30
30
|
variant: 'touch',
|
|
31
31
|
hiddenWhen: ({ appState, pluginState }) => !['draw_polygon', 'draw_line'].includes(pluginState.mode) || appState.interfaceType !== 'touch',
|
|
32
32
|
...createButtonSlots(false)
|
|
33
|
-
},{
|
|
33
|
+
}, {
|
|
34
34
|
id: 'drawCancel',
|
|
35
35
|
label: 'Cancel',
|
|
36
36
|
variant: 'tertiary',
|
|
37
37
|
hiddenWhen: ({ pluginState }) => !pluginState.mode,
|
|
38
38
|
...createButtonSlots(true)
|
|
39
|
-
},{
|
|
39
|
+
}, {
|
|
40
40
|
id: 'drawMenu',
|
|
41
41
|
label: 'Menu',
|
|
42
42
|
iconId: 'menu',
|
|
@@ -47,22 +47,22 @@ export const manifest = {
|
|
|
47
47
|
label: 'Undo',
|
|
48
48
|
iconId: 'undo',
|
|
49
49
|
hiddenWhen: ({ pluginState }) => !['draw_polygon', 'draw_line', 'edit_vertex'].includes(pluginState.mode),
|
|
50
|
-
enableWhen: ({ pluginState }) => pluginState.undoStackLength > 0
|
|
51
|
-
},{
|
|
50
|
+
enableWhen: ({ pluginState }) => pluginState.undoStackLength > 0
|
|
51
|
+
}, {
|
|
52
52
|
id: 'drawSnap',
|
|
53
53
|
label: 'Snap to feature',
|
|
54
54
|
iconId: 'magnet',
|
|
55
55
|
hiddenWhen: ({ pluginState }) => !pluginState.mode || !pluginState.hasSnapLayers,
|
|
56
|
-
pressedWhen: ({ pluginState }) => !!pluginState.snap
|
|
57
|
-
},{
|
|
56
|
+
pressedWhen: ({ pluginState }) => !!pluginState.snap
|
|
57
|
+
}, {
|
|
58
58
|
id: 'drawDeletePoint',
|
|
59
59
|
label: 'Delete point',
|
|
60
60
|
iconId: 'trash',
|
|
61
61
|
enableWhen: ({ pluginState }) => pluginState.selectedVertexIndex >= 0 && pluginState.numVertecies > (pluginState.tempFeature?.geometry?.type === 'Polygon' ? 3 : 2),
|
|
62
|
-
hiddenWhen: ({ pluginState }) => !(['simple_select', 'edit_vertex'].includes(pluginState.mode))
|
|
62
|
+
hiddenWhen: ({ pluginState }) => !(['simple_select', 'edit_vertex'].includes(pluginState.mode))
|
|
63
63
|
}],
|
|
64
64
|
...createButtonSlots(true)
|
|
65
|
-
},{
|
|
65
|
+
}, {
|
|
66
66
|
id: 'drawDone',
|
|
67
67
|
label: 'Done',
|
|
68
68
|
variant: 'primary',
|
|
@@ -81,16 +81,16 @@ export const manifest = {
|
|
|
81
81
|
icons: [{
|
|
82
82
|
id: 'menu',
|
|
83
83
|
svgContent: '<path d="m6 9 6 6 6-6"/>'
|
|
84
|
-
},{
|
|
84
|
+
}, {
|
|
85
85
|
id: 'undo',
|
|
86
86
|
svgContent: '<path d="M9 14 4 9l5-5"/><path d="M4 9h10.5a5.5 5.5 0 0 1 5.5 5.5a5.5 5.5 0 0 1-5.5 5.5H11"/>'
|
|
87
|
-
},{
|
|
87
|
+
}, {
|
|
88
88
|
id: 'check',
|
|
89
89
|
svgContent: '<path d="M20 6 9 17l-5-5"/>'
|
|
90
|
-
},{
|
|
90
|
+
}, {
|
|
91
91
|
id: 'magnet',
|
|
92
92
|
svgContent: '<path d="m12 15 4 4"/><path d="M2.352 10.648a1.205 1.205 0 0 0 0 1.704l2.296 2.296a1.205 1.205 0 0 0 1.704 0l6.029-6.029a1 1 0 1 1 3 3l-6.029 6.029a1.205 1.205 0 0 0 0 1.704l2.296 2.296a1.205 1.205 0 0 0 1.704 0l6.365-6.367A1 1 0 0 0 8.716 4.282z"/><path d="m5 8 4 4"/>'
|
|
93
|
-
},{
|
|
93
|
+
}, {
|
|
94
94
|
id: 'trash',
|
|
95
95
|
svgContent: '<path d="M10 11v6"/><path d="M14 11v6"/><path d="M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6"/><path d="M3 6h18"/><path d="M8 6V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2"/>'
|
|
96
96
|
}],
|
|
@@ -104,4 +104,4 @@ export const manifest = {
|
|
|
104
104
|
split,
|
|
105
105
|
merge
|
|
106
106
|
}
|
|
107
|
-
}
|
|
107
|
+
}
|
|
@@ -122,7 +122,7 @@ export const createMapboxDraw = ({ mapStyle, mapProvider, events, eventBus, snap
|
|
|
122
122
|
// --- Return instance and cleanup function ---
|
|
123
123
|
return {
|
|
124
124
|
draw,
|
|
125
|
-
remove() {
|
|
125
|
+
remove () {
|
|
126
126
|
// Remove touch workaround listeners
|
|
127
127
|
canvas.removeEventListener('touchstart', handleTouchStart)
|
|
128
128
|
canvas.removeEventListener('touchend', handleTouchEnd)
|
|
@@ -5,7 +5,7 @@ import { DEFAULTS } from './defaults.js'
|
|
|
5
5
|
const SNAP_HELPER_LAYER = 'snap-helper-circle'
|
|
6
6
|
|
|
7
7
|
/** Apply patches to MapboxSnap prototype (once only) */
|
|
8
|
-
function applyMapboxSnapPatches(colors) {
|
|
8
|
+
function applyMapboxSnapPatches (colors) {
|
|
9
9
|
if (MapboxSnap.prototype.__snapPatched) {
|
|
10
10
|
return
|
|
11
11
|
}
|
|
@@ -27,7 +27,7 @@ function applyMapboxSnapPatches(colors) {
|
|
|
27
27
|
proto.changeSnappedPoints = () => {}
|
|
28
28
|
|
|
29
29
|
// Skip setMapData when disabled, ensure layer visibility when enabled
|
|
30
|
-
proto.setMapData = function(data) {
|
|
30
|
+
proto.setMapData = function (data) {
|
|
31
31
|
if (!this.status) {
|
|
32
32
|
return
|
|
33
33
|
}
|
|
@@ -39,7 +39,7 @@ function applyMapboxSnapPatches(colors) {
|
|
|
39
39
|
}
|
|
40
40
|
|
|
41
41
|
// Skip drawingSnapCheck when disabled
|
|
42
|
-
proto.drawingSnapCheck = function() {
|
|
42
|
+
proto.drawingSnapCheck = function () {
|
|
43
43
|
if (!this.status) {
|
|
44
44
|
return
|
|
45
45
|
}
|
|
@@ -48,7 +48,7 @@ function applyMapboxSnapPatches(colors) {
|
|
|
48
48
|
|
|
49
49
|
// Fix typo: original uses 'coodinates' instead of 'coordinates' for Multi* types
|
|
50
50
|
// Also validate coordinates to prevent "coordinates must contain numbers" errors
|
|
51
|
-
proto.getLines = function(feature, mouse, radiusArg) {
|
|
51
|
+
proto.getLines = function (feature, mouse, radiusArg) {
|
|
52
52
|
const geom = feature.geometry
|
|
53
53
|
if (!geom || !geom.coordinates) {
|
|
54
54
|
return []
|
|
@@ -74,7 +74,7 @@ function applyMapboxSnapPatches(colors) {
|
|
|
74
74
|
}
|
|
75
75
|
|
|
76
76
|
// Query within radius bbox instead of just point, filter to existing layers
|
|
77
|
-
proto.getCloseFeatures = function(e, radiusInMeters) {
|
|
77
|
+
proto.getCloseFeatures = function (e, radiusInMeters) {
|
|
78
78
|
if (!this.status) {
|
|
79
79
|
return []
|
|
80
80
|
}
|
|
@@ -90,21 +90,21 @@ function applyMapboxSnapPatches(colors) {
|
|
|
90
90
|
}
|
|
91
91
|
|
|
92
92
|
// Custom colors for snap indicators
|
|
93
|
-
proto.searchInVertex = function(...args) {
|
|
93
|
+
proto.searchInVertex = function (...args) {
|
|
94
94
|
const r = orig.searchInVertex.apply(this, args)
|
|
95
95
|
if (r) {
|
|
96
96
|
r.color = colors.vertex
|
|
97
97
|
}
|
|
98
98
|
return r
|
|
99
99
|
}
|
|
100
|
-
proto.searchInMidPoint = function(...args) {
|
|
100
|
+
proto.searchInMidPoint = function (...args) {
|
|
101
101
|
const r = orig.searchInMidPoint.apply(this, args)
|
|
102
102
|
if (r) {
|
|
103
103
|
r.color = colors.midpoint
|
|
104
104
|
}
|
|
105
105
|
return r
|
|
106
106
|
}
|
|
107
|
-
proto.searchInEdge = function(...args) {
|
|
107
|
+
proto.searchInEdge = function (...args) {
|
|
108
108
|
const r = orig.searchInEdge.apply(this, args)
|
|
109
109
|
if (r) {
|
|
110
110
|
r.color = colors.edge
|
|
@@ -113,7 +113,7 @@ function applyMapboxSnapPatches(colors) {
|
|
|
113
113
|
}
|
|
114
114
|
|
|
115
115
|
// Skip when disabled or zooming, clean up internal arrays to prevent memory accumulation
|
|
116
|
-
proto.snapToClosestPoint = function(e) {
|
|
116
|
+
proto.snapToClosestPoint = function (e) {
|
|
117
117
|
if (!this.status || this.map?._isZooming) {
|
|
118
118
|
return
|
|
119
119
|
}
|
|
@@ -131,14 +131,13 @@ function applyMapboxSnapPatches(colors) {
|
|
|
131
131
|
console.log(err)
|
|
132
132
|
this.snapStatus = false
|
|
133
133
|
this.snapCoords = null
|
|
134
|
-
return
|
|
135
134
|
}
|
|
136
135
|
}
|
|
137
136
|
}
|
|
138
137
|
|
|
139
138
|
/** Poll until checkFn returns truthy, then call onSuccess with the result */
|
|
140
|
-
function pollUntil(checkFn, onSuccess) {
|
|
141
|
-
(function poll() {
|
|
139
|
+
function pollUntil (checkFn, onSuccess) {
|
|
140
|
+
(function poll () {
|
|
142
141
|
const result = checkFn()
|
|
143
142
|
// null signals to stop polling, falsy continues polling
|
|
144
143
|
if (result === null) return
|
|
@@ -150,7 +149,7 @@ function pollUntil(checkFn, onSuccess) {
|
|
|
150
149
|
* Patch a GeoJSON source to expose _data for MapboxSnap compatibility
|
|
151
150
|
* MapboxSnap expects source._data.features but MapLibre doesn't expose this
|
|
152
151
|
*/
|
|
153
|
-
export function patchSourceData(source) {
|
|
152
|
+
export function patchSourceData (source) {
|
|
154
153
|
if (!source || (source._data && Array.isArray(source._data?.features))) {
|
|
155
154
|
return
|
|
156
155
|
}
|
|
@@ -168,7 +167,7 @@ export function patchSourceData(source) {
|
|
|
168
167
|
}
|
|
169
168
|
|
|
170
169
|
/** Initialize MapboxSnap with MapLibre + MapboxDraw */
|
|
171
|
-
export function initMapLibreSnap(map, draw, snapOptions = {}) {
|
|
170
|
+
export function initMapLibreSnap (map, draw, snapOptions = {}) {
|
|
172
171
|
// Prevent multiple initializations (causes event listener duplication)
|
|
173
172
|
if (map._snapInitialized) {
|
|
174
173
|
return map._snapInstance
|
|
@@ -188,7 +187,7 @@ export function initMapLibreSnap(map, draw, snapOptions = {}) {
|
|
|
188
187
|
applyMapboxSnapPatches({ ...DEFAULTS.snapColors, ...colors })
|
|
189
188
|
|
|
190
189
|
// Clean up old snap instance's source and layer
|
|
191
|
-
function cleanupOldSnap() {
|
|
190
|
+
function cleanupOldSnap () {
|
|
192
191
|
if (map.getLayer(SNAP_HELPER_LAYER)) {
|
|
193
192
|
map.removeLayer(SNAP_HELPER_LAYER)
|
|
194
193
|
}
|
|
@@ -198,7 +197,7 @@ export function initMapLibreSnap(map, draw, snapOptions = {}) {
|
|
|
198
197
|
}
|
|
199
198
|
|
|
200
199
|
// Create snap instance once source is available
|
|
201
|
-
function createSnap(source) {
|
|
200
|
+
function createSnap (source) {
|
|
202
201
|
// Prevent duplicate creation (race condition between initial poll and style.load)
|
|
203
202
|
if (map._snapInstance || map._snapCreating) {
|
|
204
203
|
return map._snapInstance
|
|
@@ -247,9 +246,9 @@ export function initMapLibreSnap(map, draw, snapOptions = {}) {
|
|
|
247
246
|
// Set snap layers (overrides defaults, pass null to reset to defaults)
|
|
248
247
|
snap.setSnapLayers = (overrideLayers) => {
|
|
249
248
|
if (overrideLayers === null || overrideLayers === undefined) {
|
|
250
|
-
snap._activeLayers = null
|
|
249
|
+
snap._activeLayers = null // Use defaults
|
|
251
250
|
} else if (Array.isArray(overrideLayers)) {
|
|
252
|
-
snap._activeLayers = overrideLayers
|
|
251
|
+
snap._activeLayers = overrideLayers // Override defaults
|
|
253
252
|
} else {
|
|
254
253
|
// No action
|
|
255
254
|
}
|