@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
|
@@ -164,7 +164,7 @@ export const createDynamicSource = ({ dataset, map, sourceId, onUpdate }) => {
|
|
|
164
164
|
/**
|
|
165
165
|
* Clean up event listeners
|
|
166
166
|
*/
|
|
167
|
-
destroy() {
|
|
167
|
+
destroy () {
|
|
168
168
|
map.off('moveend', handleMoveEnd)
|
|
169
169
|
debouncedFetch.cancel()
|
|
170
170
|
},
|
|
@@ -172,7 +172,7 @@ export const createDynamicSource = ({ dataset, map, sourceId, onUpdate }) => {
|
|
|
172
172
|
/**
|
|
173
173
|
* Clear all cached features and reset fetch tracking
|
|
174
174
|
*/
|
|
175
|
-
clear() {
|
|
175
|
+
clear () {
|
|
176
176
|
features.clear()
|
|
177
177
|
fetchedBbox = null
|
|
178
178
|
onUpdate(sourceId, { type: 'FeatureCollection', features: [] })
|
|
@@ -181,7 +181,7 @@ export const createDynamicSource = ({ dataset, map, sourceId, onUpdate }) => {
|
|
|
181
181
|
/**
|
|
182
182
|
* Force refresh - clear cache and fetch current viewport
|
|
183
183
|
*/
|
|
184
|
-
refresh() {
|
|
184
|
+
refresh () {
|
|
185
185
|
features.clear()
|
|
186
186
|
fetchedBbox = null
|
|
187
187
|
fetchData()
|
|
@@ -190,14 +190,14 @@ export const createDynamicSource = ({ dataset, map, sourceId, onUpdate }) => {
|
|
|
190
190
|
/**
|
|
191
191
|
* Get current feature count
|
|
192
192
|
*/
|
|
193
|
-
getFeatureCount() {
|
|
193
|
+
getFeatureCount () {
|
|
194
194
|
return features.size
|
|
195
195
|
},
|
|
196
196
|
|
|
197
197
|
/**
|
|
198
198
|
* Re-push cached features to the source (e.g., after style change)
|
|
199
199
|
*/
|
|
200
|
-
reapply() {
|
|
200
|
+
reapply () {
|
|
201
201
|
if (features.size > 0) {
|
|
202
202
|
onUpdate(sourceId, toFeatureCollection())
|
|
203
203
|
}
|
|
@@ -40,7 +40,7 @@ export const manifest = {
|
|
|
40
40
|
width: '320px'
|
|
41
41
|
},
|
|
42
42
|
render: Layers
|
|
43
|
-
},{
|
|
43
|
+
}, {
|
|
44
44
|
id: 'datasetsKey',
|
|
45
45
|
label: 'Key',
|
|
46
46
|
mobile: {
|
|
@@ -76,7 +76,7 @@ export const manifest = {
|
|
|
76
76
|
slot: 'top-left',
|
|
77
77
|
showLabel: true
|
|
78
78
|
}
|
|
79
|
-
},{
|
|
79
|
+
}, {
|
|
80
80
|
id: 'datasetsKey',
|
|
81
81
|
label: 'Key',
|
|
82
82
|
panelId: 'datasetsKey',
|
|
@@ -99,7 +99,7 @@ export const manifest = {
|
|
|
99
99
|
icons: [{
|
|
100
100
|
id: 'layers',
|
|
101
101
|
svgContent: '<path d="M13 13.74a2 2 0 0 1-2 0L2.5 8.87a1 1 0 0 1 0-1.74L11 2.26a2 2 0 0 1 2 0l8.5 4.87a1 1 0 0 1 0 1.74z"></path><path d="m20 14.285 1.5.845a1 1 0 0 1 0 1.74L13 21.74a2 2 0 0 1-2 0l-8.5-4.87a1 1 0 0 1 0-1.74l1.5-.845"></path>'
|
|
102
|
-
},{
|
|
102
|
+
}, {
|
|
103
103
|
id: 'key',
|
|
104
104
|
svgContent: '<path d="M3 5h.01"/><path d="M3 12h.01"/><path d="M3 19h.01"/><path d="M8 5h13"/><path d="M8 12h13"/><path d="M8 19h13"/>'
|
|
105
105
|
}],
|
|
@@ -81,7 +81,6 @@ const addMapLayers = (map, mapStyleId, dataset) => {
|
|
|
81
81
|
|
|
82
82
|
// --- Add source (shared across datasets with same tiles/data URL) ---
|
|
83
83
|
if (!map.getSource(sourceId)) {
|
|
84
|
-
|
|
85
84
|
if (dataset.tiles) {
|
|
86
85
|
// Tiles
|
|
87
86
|
map.addSource(sourceId, {
|
|
@@ -111,7 +110,7 @@ const addMapLayers = (map, mapStyleId, dataset) => {
|
|
|
111
110
|
const hasStroke = !!dataset.stroke
|
|
112
111
|
const fillLayerId = hasFill ? dataset.id : null
|
|
113
112
|
const strokeLayerId = hasStroke ? (hasFill ? `${dataset.id}-stroke` : dataset.id) : null
|
|
114
|
-
|
|
113
|
+
|
|
115
114
|
// --- Determie visiblity ---
|
|
116
115
|
const visibility = dataset.visibility === 'hidden' ? 'none' : 'visible'
|
|
117
116
|
|
|
@@ -162,4 +161,4 @@ export {
|
|
|
162
161
|
addMapLayers,
|
|
163
162
|
isDynamicSource,
|
|
164
163
|
updateSourceData
|
|
165
|
-
}
|
|
164
|
+
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import React from
|
|
1
|
+
import React from 'react'
|
|
2
2
|
import { getValueForStyle } from '../../../../../src/utils/getValueForStyle'
|
|
3
3
|
|
|
4
4
|
export const Key = ({ mapState, pluginState }) => {
|
|
@@ -13,42 +13,44 @@ export const Key = ({ mapState, pluginState }) => {
|
|
|
13
13
|
aria-hidden='true'
|
|
14
14
|
focusable='false'
|
|
15
15
|
>
|
|
16
|
-
{dataset.keySymbolShape === 'line'
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
16
|
+
{dataset.keySymbolShape === 'line'
|
|
17
|
+
? (
|
|
18
|
+
<line
|
|
19
|
+
x1={dataset.strokeWidth / 2}
|
|
20
|
+
y1='10'
|
|
21
|
+
x2={20 - dataset.strokeWidth / 2}
|
|
22
|
+
y2='10'
|
|
23
|
+
stroke={getValueForStyle(dataset.stroke, mapStyle.id)}
|
|
24
|
+
strokeWidth={dataset.strokeWidth}
|
|
25
|
+
strokeLinecap='round'
|
|
26
|
+
/>
|
|
27
|
+
)
|
|
28
|
+
: (
|
|
29
|
+
<rect
|
|
30
|
+
x={dataset.strokeWidth / 2}
|
|
31
|
+
y={dataset.strokeWidth / 2}
|
|
32
|
+
width={20 - dataset.strokeWidth}
|
|
33
|
+
height={20 - dataset.strokeWidth}
|
|
34
|
+
rx={dataset.strokeWidth}
|
|
35
|
+
ry={dataset.strokeWidth}
|
|
36
|
+
fill={getValueForStyle(dataset.fill, mapStyle.id)}
|
|
37
|
+
stroke={getValueForStyle(dataset.stroke, mapStyle.id)}
|
|
38
|
+
strokeWidth={dataset.strokeWidth}
|
|
39
|
+
strokeLinejoin='round'
|
|
40
|
+
/>
|
|
41
|
+
)}
|
|
40
42
|
</svg>
|
|
41
43
|
)
|
|
42
44
|
|
|
43
45
|
return (
|
|
44
|
-
<div className=
|
|
46
|
+
<div className='im-c-datasets-key'>
|
|
45
47
|
{(pluginState.datasets || []).filter(dataset => dataset.showInKey && dataset.visibility !== 'hidden').map(dataset => (
|
|
46
|
-
<div key={dataset.id} className=
|
|
47
|
-
<div className=
|
|
48
|
+
<div key={dataset.id} className='im-c-datasets-key__item'>
|
|
49
|
+
<div className='im-c-datasets-key__item-label'>
|
|
48
50
|
{itemSymbol(dataset)}
|
|
49
51
|
{dataset.label}
|
|
50
52
|
{dataset.symbolDescription && (
|
|
51
|
-
<span className=
|
|
53
|
+
<span className='govuk-visually-hidden'>
|
|
52
54
|
({getValueForStyle(dataset.symbolDescription, mapStyle.id)})
|
|
53
55
|
</span>
|
|
54
56
|
)}
|
|
@@ -3,7 +3,6 @@ import { showDataset } from '../api/showDataset'
|
|
|
3
3
|
import { hideDataset } from '../api/hideDataset'
|
|
4
4
|
|
|
5
5
|
export const Layers = ({ pluginState, mapProvider }) => {
|
|
6
|
-
|
|
7
6
|
const handleChange = (e) => {
|
|
8
7
|
const { value, checked } = e.target
|
|
9
8
|
if (checked) {
|
|
@@ -14,18 +13,18 @@ export const Layers = ({ pluginState, mapProvider }) => {
|
|
|
14
13
|
}
|
|
15
14
|
|
|
16
15
|
return (
|
|
17
|
-
<div className=
|
|
18
|
-
<div className=
|
|
19
|
-
<fieldset className=
|
|
20
|
-
<legend className=
|
|
16
|
+
<div className='im-c-datasets-layers'>
|
|
17
|
+
<div className='govuk-form-group'>
|
|
18
|
+
<fieldset className='govuk-fieldset'>
|
|
19
|
+
<legend className='govuk-visually-hidden'>
|
|
21
20
|
Layers
|
|
22
21
|
</legend>
|
|
23
|
-
<div className=
|
|
22
|
+
<div className='govuk-checkboxes govuk-checkboxes--small' data-module='govuk-checkboxes'>
|
|
24
23
|
{(pluginState.datasets || []).filter(dataset => dataset.showInLayers).map(dataset => (
|
|
25
24
|
<div key={dataset.id} className={`im-c-datasets-layers__item${dataset.visibility !== 'hidden' ? ' im-c-datasets-layers__item--checked' : ''}`}>
|
|
26
|
-
<div className=
|
|
27
|
-
<input className=
|
|
28
|
-
<label className=
|
|
25
|
+
<div className='govuk-checkboxes__item'>
|
|
26
|
+
<input className='govuk-checkboxes__input' id={dataset.id} name='layers' type='checkbox' value={dataset.id} checked={dataset.visibility !== 'hidden'} onChange={handleChange} />
|
|
27
|
+
<label className='im-c-datasets-layers__item-label govuk-label govuk-checkboxes__label' htmlFor={dataset.id}>
|
|
29
28
|
{dataset.label}
|
|
30
29
|
</label>
|
|
31
30
|
</div>
|
|
@@ -22,7 +22,7 @@ export const bboxContains = (outer, inner) => {
|
|
|
22
22
|
inner[0] >= outer[0] && // west
|
|
23
23
|
inner[1] >= outer[1] && // south
|
|
24
24
|
inner[2] <= outer[2] && // east
|
|
25
|
-
inner[3] <= outer[3]
|
|
25
|
+
inner[3] <= outer[3] // north
|
|
26
26
|
)
|
|
27
27
|
}
|
|
28
28
|
|
|
@@ -40,7 +40,7 @@ export const expandBbox = (existing, addition) => {
|
|
|
40
40
|
Math.min(existing[0], addition[0]), // west
|
|
41
41
|
Math.min(existing[1], addition[1]), // south
|
|
42
42
|
Math.max(existing[2], addition[2]), // east
|
|
43
|
-
Math.max(existing[3], addition[3])
|
|
43
|
+
Math.max(existing[3], addition[3]) // north
|
|
44
44
|
]
|
|
45
45
|
}
|
|
46
46
|
|
|
@@ -58,7 +58,7 @@ export const bboxIntersects = (a, b) => {
|
|
|
58
58
|
a[2] < b[0] || // a is left of b
|
|
59
59
|
a[0] > b[2] || // a is right of b
|
|
60
60
|
a[3] < b[1] || // a is below b
|
|
61
|
-
a[1] > b[3]
|
|
61
|
+
a[1] > b[3] // a is above b
|
|
62
62
|
)
|
|
63
63
|
}
|
|
64
64
|
|
|
@@ -68,7 +68,7 @@ export const bboxIntersects = (a, b) => {
|
|
|
68
68
|
* @returns {number[]} bbox as [west, south, east, north]
|
|
69
69
|
*/
|
|
70
70
|
export const getGeometryBbox = (geometry) => {
|
|
71
|
-
let minX = Infinity
|
|
71
|
+
let minX = Infinity; let minY = Infinity; let maxX = -Infinity; let maxY = -Infinity
|
|
72
72
|
|
|
73
73
|
const processCoord = (coord) => {
|
|
74
74
|
minX = Math.min(minX, coord[0])
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import e from"@babel/runtime/helpers/defineProperty";import{useEffect as t}from"preact/compat";import r from"@arcgis/core/widgets/Sketch/SketchViewModel.js";import o from"@arcgis/core/layers/GraphicsLayer.js";import a from"@babel/runtime/helpers/asyncToGenerator";import*as n from"@arcgis/core/geometry/operators/simplifyOperator.js";import i from"@arcgis/core/Graphic.js";function l(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);t&&(o=o.filter(function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable})),r.push.apply(r,o)}return r}function p(t){for(var r=1;r<arguments.length;r++){var o=null!=arguments[r]?arguments[r]:{};r%2?l(Object(o),!0).forEach(function(r){e(t,r,o[r])}):Object.getOwnPropertyDescriptors?Object.defineProperties(t,Object.getOwnPropertyDescriptors(o)):l(Object(o)).forEach(function(e){Object.defineProperty(t,e,Object.getOwnPropertyDescriptor(o,e))})}return t}function c(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);t&&(o=o.filter(function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable})),r.push.apply(r,o)}return r}function
|
|
1
|
+
import e from"@babel/runtime/helpers/defineProperty";import{useEffect as t}from"preact/compat";import r from"@arcgis/core/widgets/Sketch/SketchViewModel.js";import o from"@arcgis/core/layers/GraphicsLayer.js";import a from"@babel/runtime/helpers/asyncToGenerator";import*as n from"@arcgis/core/geometry/operators/simplifyOperator.js";import i from"@arcgis/core/Graphic.js";function l(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);t&&(o=o.filter(function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable})),r.push.apply(r,o)}return r}function p(t){for(var r=1;r<arguments.length;r++){var o=null!=arguments[r]?arguments[r]:{};r%2?l(Object(o),!0).forEach(function(r){e(t,r,o[r])}):Object.getOwnPropertyDescriptors?Object.defineProperties(t,Object.getOwnPropertyDescriptors(o)):l(Object(o)).forEach(function(e){Object.defineProperty(t,e,Object.getOwnPropertyDescriptor(o,e))})}return t}function c(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);t&&(o=o.filter(function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable})),r.push.apply(r,o)}return r}function u(t){for(var r=1;r<arguments.length;r++){var o=null!=arguments[r]?arguments[r]:{};r%2?c(Object(o),!0).forEach(function(r){e(t,r,o[r])}):Object.getOwnPropertyDescriptors?Object.defineProperties(t,Object.getOwnPropertyDescriptors(o)):c(Object(o)).forEach(function(e){Object.defineProperty(t,e,Object.getOwnPropertyDescriptor(o,e))})}return t}function s(e){return{type:"simple-fill",color:[0,120,255,.2],outline:{color:"dark"===e?"#ffffff":"#d4351c",width:2}}}function d(e,t,r){return new i({geometry:{type:"polygon",rings:t,spatialReference:27700},attributes:{id:e},symbol:s(r)})}function y(e){if(null==e||!e.geometry)throw new Error("Invalid graphic");var{geometry:t,attributes:r={}}=e;switch(t.type){case"point":return{type:"Feature",geometry:{type:"Point",coordinates:[t.x,t.y]},properties:u({},r)};case"polyline":return{type:"Feature",geometry:{type:"LineString",coordinates:t.paths[0]},properties:u({},r)};case"polygon":return{type:"Feature",geometry:{type:"Polygon",coordinates:t.rings},properties:u({},r)};default:throw new Error("Unsupported geometry type: ".concat(t.type))}}function m(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);t&&(o=o.filter(function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable})),r.push.apply(r,o)}return r}function v(t){for(var r=1;r<arguments.length;r++){var o=null!=arguments[r]?arguments[r]:{};r%2?m(Object(o),!0).forEach(function(r){e(t,r,o[r])}):Object.getOwnPropertyDescriptors?Object.defineProperties(t,Object.getOwnPropertyDescriptors(o)):m(Object(o)).forEach(function(e){Object.defineProperty(t,e,Object.getOwnPropertyDescriptor(o,e))})}return t}var f={mobile:{slot:"actions",showLabel:!0},tablet:{slot:"actions",showLabel:!0},desktop:{slot:"actions",showLabel:!0}},h={reducer:{initialState:{mode:null,feature:null,tempFeature:null},actions:{SET_MODE:(e,t)=>p(p({},e),{},{mode:t}),SET_FEATURE:(e,t)=>p(p({},e),{},{feature:void 0===t.feature?e.feature:t.feature,tempFeature:void 0===t.tempFeature?e.tempFeature:t.tempFeature})}},InitComponent:e=>{var i,l,p,c,{appState:u,mapState:m,pluginConfig:v,pluginState:f,services:h,mapProvider:g,buttonConfig:b}=e,{events:O,eventBus:w}=h,{mapColorScheme:S}=m.mapStyle||{},E=null===(i=null===(l=v.includeModes)||void 0===l?void 0:l.includes(u.mode))||void 0===i||i,k=null!==(p=null===(c=v.excludeModes)||void 0===c?void 0:c.includes(u.mode))&&void 0!==p&&p,P=m.isMapReady&&E&&!k;t(()=>{if(P&&!g.sketchViewModel){var{sketchViewModel:e,sketchLayer:t,emptySketchLayer:a}=(e=>{var{mapProvider:t}=e,{view:a}=t,n=new o({id:"sketchLayer"});a.map.add(n);var i=new o({id:"emptySketchLayer"});return a.map.add(i),{sketchViewModel:new r({view:a,layer:i,defaultUpdateOptions:{tool:"reshape",updateOnGraphicClick:!1,multipleSelectionEnabled:!1,toggleToolOnClick:!1,highlightOptions:{enabled:!1}}}),emptySketchLayer:i,sketchLayer:n}})({mapProvider:g});return g.sketchViewModel=e,g.sketchLayer=t,g.emptySketchLayer=a,w.emit("draw:ready"),()=>{g.sketchViewModel=null,g.sketchLayer=null,g.emptySketchLayer=null}}},[m.isMapReady,u.mode]),t(()=>{if(P&&g.sketchViewModel){var e=function(e){var{pluginState:t,mapProvider:r,events:o,eventBus:i,buttonConfig:l,mapColorScheme:p}=e,{view:c,sketchViewModel:u,sketchLayer:m,emptySketchLayer:v}=r;if(!u)return null;var{drawDone:f,drawCancel:h}=l,{dispatch:g,mode:b,feature:O}=t,w=function(){var e=a(function*(){var e,r=null===(e=t.feature)||void 0===e||null===(e=e.properties)||void 0===e?void 0:e.id,o=null,a="active"===u.state&&!r;if("active"===u.state&&r&&(u.cancel(),yield new Promise(e=>setTimeout(e,50))),u.polygonSymbol=s(p),null==m||m.graphics.items.forEach(e=>{var t=d(e.attributes.id,e.geometry.rings,p);e.symbol=t.symbol,r===e.attributes.id&&(o=e)}),o&&!a&&u.layer===m)try{yield u.update(o,{tool:"reshape",toggleToolOnClick:!1})}catch(e){"AbortError"!==e.name&&console.error("Error updating sketch:",e)}});return function(){return e.apply(this,arguments)}}(),S=()=>{var e,t,r=null!==(e=null===(t=m.graphics)||void 0===t||null===(t=t.items)||void 0===t?void 0:t[0])&&void 0!==e?e:null;r&&setTimeout(()=>u.update(r),0)},E=()=>w(),k=e=>{if(e){var t=y(e);i.emit("draw:updated",t),g({type:"SET_FEATURE",payload:{tempFeature:t}})}},P=function(){var e=a(function*(){b&&((u.updateGraphics||[]).length||S())});return function(){return e.apply(this,arguments)}}(),j=function(){var e=a(function*(e){var{toolEventInfo:t}=e,r=null==e?void 0:e.graphic;if(r&&"vertex-add"===(null==t?void 0:t.type)){var o,a,n=null===(o=r.geometry)||void 0===o?void 0:o.rings;(null==n?void 0:n.length)>1?setTimeout(()=>u.undo(),0):(null==n||null===(a=n[0])||void 0===a?void 0:a.length)>3&&k(r)}});return function(t){return e.apply(this,arguments)}}(),T=function(){var e=a(function*(e){var t,r=null==e||null===(t=e.graphics)||void 0===t?void 0:t[0];k(r)});return function(t){return e.apply(this,arguments)}}();i.on(o.MAP_STYLE_CHANGE,E);var C=u.on("update",e=>{var t,r=null===(t=e.toolEventInfo)||void 0===t?void 0:t.type,o=e.graphics[0];"move-start"===r&&(u.cancel(),S()),"reshape"===r&&(n.isSimple(o.geometry)||u.undo()),"reshape-stop"!==r&&"vertex-remove"!==r||k(o)}),F=c.on("click",P),L=u.on("create",j),M=u.on("undo",T),D=f.onClick,_=h.onClick;return f.onClick=()=>{u.cancel(),u.layer=v,g({type:"SET_MODE",payload:null}),g({type:"SET_FEATURE",payload:{feature:null,tempFeature:null}}),i.emit("draw:done",{newFeature:t.tempFeature})},h.onClick=()=>{if(u.cancel(),m.removeAll(),O){var e=d(O.id||O.properties.id,O.geometry.coordinates,p);m.add(e)}u.layer=v,g({type:"SET_MODE",payload:null}),i.emit("draw:cancelled")},()=>{i.off(o.MAP_STYLE_CHANGE,E),C.remove(),F.remove(),L.remove(),M.remove(),f.onClick=D,h.onClick=_}}({pluginState:f,mapProvider:g,events:O,eventBus:w,buttonConfig:b,mapColorScheme:S});return()=>{e()}}},[P,S,f])},buttons:[v({id:"drawDone",label:"Done",variant:"primary",hiddenWhen:e=>{var{pluginState:t}=e;return!t.mode},enableWhen:e=>{var{pluginState:t}=e;return!!t.tempFeature}},f),v({id:"drawCancel",label:"Cancel",variant:"tertiary",hiddenWhen:e=>{var{pluginState:t}=e;return!t.mode}},f)],api:{newPolygon:(e,t)=>{var{mapState:r,pluginState:o,mapProvider:a,services:n}=e,{dispatch:i}=o,{sketchViewModel:l,sketchLayer:p}=a,{eventBus:c}=n;l.layer=p;var u=l.on("create",e=>{if("complete"===e.state){e.graphic.attributes={id:t},requestAnimationFrame(()=>{l.update(e.graphic,{tool:"reshape",toggleToolOnClick:!1})});var r=y(e.graphic);c.emit("draw:created",r),i({type:"SET_FEATURE",payload:{tempFeature:r}}),u.remove()}});l.polygonSymbol=s(r.mapStyle.mapColorScheme),l.create("polygon"),i({type:"SET_MODE",payload:"new-polygon"})},editFeature:(e,t)=>{var{pluginState:r,mapProvider:o}=e,{dispatch:a}=r,{sketchViewModel:n,sketchLayer:i}=o,l=i.graphics.items.find(e=>e.attributes.id===t),p=l.geometry.extent,c=[p.xmin,p.ymin,p.xmax,p.ymax];o.fitToBounds(c),n.layer=i,n.update(l,{tool:"reshape",toggleToolOnClick:!1,enableRotation:!1,enableScaling:!1}),a({type:"SET_FEATURE",payload:{feature:y(l)}}),a({type:"SET_MODE",payload:"edit-feature"})},addFeature:(e,t)=>{var{pluginState:r,mapState:o,mapProvider:a,services:n}=e,{dispatch:i}=r,{mapStyle:l}=o,{sketchViewModel:p,sketchLayer:c,emptySketchLayer:u}=a,{eventBus:s}=n,y=d(t.id,t.geometry.coordinates,l.mapColorScheme);c.add(y),p.layer=u,i({type:"SET_FEATURE",payload:{feature:t}}),s.emit("draw:add",t)},deleteFeature:(e,t)=>{var{pluginState:r,mapProvider:o,services:a}=e,{dispatch:n}=r,{sketchViewModel:i,sketchLayer:l,emptySketchLayer:p}=o,{eventBus:c}=a,u=l.graphics.items.find(e=>e.attributes.id===t);i.cancel(),l.remove(u),i.layer=p,n({type:"SET_FEATURE",payload:{feature:null,tempFeature:null}}),c.emit("draw:delete",{featureId:t}),n({type:"SET_MODE",payload:null})}}};export{h as manifest};
|
|
@@ -2,14 +2,14 @@ import { useEffect } from 'react'
|
|
|
2
2
|
import { createSketchViewModel } from './sketchViewModel.js'
|
|
3
3
|
import { attachEvents } from './events.js'
|
|
4
4
|
|
|
5
|
-
export const DrawInit = ({
|
|
6
|
-
appState,
|
|
7
|
-
mapState,
|
|
8
|
-
pluginConfig,
|
|
9
|
-
pluginState,
|
|
10
|
-
services,
|
|
11
|
-
mapProvider,
|
|
12
|
-
buttonConfig
|
|
5
|
+
export const DrawInit = ({
|
|
6
|
+
appState,
|
|
7
|
+
mapState,
|
|
8
|
+
pluginConfig,
|
|
9
|
+
pluginState,
|
|
10
|
+
services,
|
|
11
|
+
mapProvider,
|
|
12
|
+
buttonConfig
|
|
13
13
|
}) => {
|
|
14
14
|
const { events, eventBus } = services
|
|
15
15
|
const { mapColorScheme } = mapState.mapStyle || {}
|
|
@@ -22,9 +22,9 @@ export const DrawInit = ({
|
|
|
22
22
|
// Initialize sketch components once
|
|
23
23
|
useEffect(() => {
|
|
24
24
|
if (!isActive || mapProvider.sketchViewModel) {
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
25
|
+
return
|
|
26
|
+
}
|
|
27
|
+
|
|
28
28
|
const { sketchViewModel, sketchLayer, emptySketchLayer } = createSketchViewModel({
|
|
29
29
|
pluginState,
|
|
30
30
|
mapProvider,
|
|
@@ -33,21 +33,21 @@ export const DrawInit = ({
|
|
|
33
33
|
|
|
34
34
|
mapProvider.sketchViewModel = sketchViewModel
|
|
35
35
|
mapProvider.sketchLayer = sketchLayer
|
|
36
|
-
|
|
36
|
+
mapProvider.emptySketchLayer = emptySketchLayer
|
|
37
37
|
eventBus.emit('draw:ready')
|
|
38
38
|
|
|
39
39
|
return () => {
|
|
40
40
|
mapProvider.sketchViewModel = null
|
|
41
41
|
mapProvider.sketchLayer = null
|
|
42
|
-
|
|
42
|
+
mapProvider.emptySketchLayer = null
|
|
43
43
|
}
|
|
44
44
|
}, [mapState.isMapReady, appState.mode])
|
|
45
45
|
|
|
46
46
|
// Attach/detach events
|
|
47
47
|
useEffect(() => {
|
|
48
48
|
if (!isActive || !mapProvider.sketchViewModel) {
|
|
49
|
-
|
|
50
|
-
|
|
49
|
+
return
|
|
50
|
+
}
|
|
51
51
|
|
|
52
52
|
const cleanup = attachEvents({
|
|
53
53
|
pluginState,
|
|
@@ -62,4 +62,4 @@ export const DrawInit = ({
|
|
|
62
62
|
cleanup()
|
|
63
63
|
}
|
|
64
64
|
}, [isActive, mapColorScheme, pluginState])
|
|
65
|
-
}
|
|
65
|
+
}
|
|
@@ -7,7 +7,7 @@ export const addFeature = ({ pluginState, mapState, mapProvider, services }, fea
|
|
|
7
7
|
const { eventBus } = services
|
|
8
8
|
|
|
9
9
|
const graphic = createGraphic(feature.id, feature.geometry.coordinates, mapStyle.mapColorScheme)
|
|
10
|
-
|
|
10
|
+
|
|
11
11
|
// Add the graphic to the layer
|
|
12
12
|
sketchLayer.add(graphic)
|
|
13
13
|
|
|
@@ -15,7 +15,7 @@ export const addFeature = ({ pluginState, mapState, mapProvider, services }, fea
|
|
|
15
15
|
sketchViewModel.layer = emptySketchLayer
|
|
16
16
|
|
|
17
17
|
// Store initial feature in plugin state
|
|
18
|
-
dispatch({ type: 'SET_FEATURE', payload: { feature }})
|
|
18
|
+
dispatch({ type: 'SET_FEATURE', payload: { feature } })
|
|
19
19
|
|
|
20
20
|
eventBus.emit('draw:add', feature)
|
|
21
|
-
}
|
|
21
|
+
}
|
|
@@ -10,13 +10,13 @@ export const deleteFeature = ({ pluginState, mapProvider, services }, featureId)
|
|
|
10
10
|
sketchViewModel.cancel()
|
|
11
11
|
sketchLayer.remove(graphic)
|
|
12
12
|
sketchViewModel.layer = emptySketchLayer
|
|
13
|
-
|
|
13
|
+
|
|
14
14
|
// Reset state
|
|
15
|
-
dispatch({ type: 'SET_FEATURE', payload: { feature: null, tempFeature: null }})
|
|
15
|
+
dispatch({ type: 'SET_FEATURE', payload: { feature: null, tempFeature: null } })
|
|
16
16
|
|
|
17
17
|
// Emit event
|
|
18
18
|
eventBus.emit('draw:delete', { featureId })
|
|
19
19
|
|
|
20
20
|
// Clear mode
|
|
21
21
|
dispatch({ type: 'SET_MODE', payload: null })
|
|
22
|
-
}
|
|
22
|
+
}
|
|
@@ -18,12 +18,12 @@ export const editFeature = ({ pluginState, mapProvider }, featureId) => {
|
|
|
18
18
|
tool: 'reshape',
|
|
19
19
|
toggleToolOnClick: false,
|
|
20
20
|
enableRotation: false,
|
|
21
|
-
enableScaling: false
|
|
21
|
+
enableScaling: false
|
|
22
22
|
})
|
|
23
23
|
|
|
24
24
|
// Set original feature
|
|
25
25
|
const feature = graphicToGeoJSON(graphic)
|
|
26
|
-
dispatch({ type: 'SET_FEATURE', payload: { feature }})
|
|
26
|
+
dispatch({ type: 'SET_FEATURE', payload: { feature } })
|
|
27
27
|
|
|
28
28
|
dispatch({ type: 'SET_MODE', payload: 'edit-feature' })
|
|
29
|
-
}
|
|
29
|
+
}
|
|
@@ -12,7 +12,7 @@ export const newPolygon = ({ mapState, pluginState, mapProvider, services }, fea
|
|
|
12
12
|
const handleCreateComplete = sketchViewModel.on('create', (e) => {
|
|
13
13
|
if (e.state === 'complete') {
|
|
14
14
|
e.graphic.attributes = { id: featureId }
|
|
15
|
-
|
|
15
|
+
|
|
16
16
|
// Fix: to address calling some sketchViewModel methods syncronously
|
|
17
17
|
requestAnimationFrame(() => {
|
|
18
18
|
sketchViewModel.update(e.graphic, {
|
|
@@ -24,7 +24,7 @@ export const newPolygon = ({ mapState, pluginState, mapProvider, services }, fea
|
|
|
24
24
|
// Store temp feature in state and emit create
|
|
25
25
|
const tempFeature = graphicToGeoJSON(e.graphic)
|
|
26
26
|
eventBus.emit('draw:created', tempFeature)
|
|
27
|
-
dispatch({ type: 'SET_FEATURE', payload: { tempFeature }})
|
|
27
|
+
dispatch({ type: 'SET_FEATURE', payload: { tempFeature } })
|
|
28
28
|
|
|
29
29
|
handleCreateComplete.remove()
|
|
30
30
|
}
|
|
@@ -34,4 +34,4 @@ export const newPolygon = ({ mapState, pluginState, mapProvider, services }, fea
|
|
|
34
34
|
sketchViewModel.create('polygon')
|
|
35
35
|
|
|
36
36
|
dispatch({ type: 'SET_MODE', payload: 'new-polygon' })
|
|
37
|
-
}
|
|
37
|
+
}
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import * as simplifyOperator from
|
|
1
|
+
import * as simplifyOperator from '@arcgis/core/geometry/operators/simplifyOperator.js'
|
|
2
2
|
import { createGraphic, createSymbol, graphicToGeoJSON } from './graphic.js'
|
|
3
3
|
|
|
4
4
|
const MODE_CHANGE_DELAY = 50
|
|
5
5
|
|
|
6
|
-
export function attachEvents({ pluginState, mapProvider, events, eventBus, buttonConfig, mapColorScheme }) {
|
|
6
|
+
export function attachEvents ({ pluginState, mapProvider, events, eventBus, buttonConfig, mapColorScheme }) {
|
|
7
7
|
const { view, sketchViewModel, sketchLayer, emptySketchLayer } = mapProvider
|
|
8
8
|
|
|
9
9
|
if (!sketchViewModel) {
|
|
@@ -12,36 +12,36 @@ export function attachEvents({ pluginState, mapProvider, events, eventBus, butto
|
|
|
12
12
|
|
|
13
13
|
const { drawDone, drawCancel } = buttonConfig
|
|
14
14
|
const { dispatch, mode, feature } = pluginState
|
|
15
|
-
|
|
15
|
+
|
|
16
16
|
// Re-colour graphics when map style changes
|
|
17
17
|
const reColour = async () => {
|
|
18
18
|
const activeGraphicId = pluginState.feature?.properties?.id
|
|
19
19
|
let activeGraphic = null
|
|
20
20
|
const isCreating = sketchViewModel.state === 'active' && !activeGraphicId
|
|
21
|
-
|
|
21
|
+
|
|
22
22
|
// Cancel and wait, but only if we're in update mode (not create mode)
|
|
23
23
|
if (sketchViewModel.state === 'active' && activeGraphicId) {
|
|
24
24
|
sketchViewModel.cancel()
|
|
25
25
|
await new Promise(resolve => setTimeout(resolve, MODE_CHANGE_DELAY))
|
|
26
26
|
}
|
|
27
|
-
|
|
27
|
+
|
|
28
28
|
// Update the default symbol for new polygons
|
|
29
29
|
sketchViewModel.polygonSymbol = createSymbol(mapColorScheme)
|
|
30
|
-
|
|
30
|
+
|
|
31
31
|
// Update existing graphics
|
|
32
32
|
sketchLayer?.graphics.items.forEach(graphic => {
|
|
33
33
|
const newGraphic = createGraphic(
|
|
34
|
-
graphic.attributes.id,
|
|
35
|
-
graphic.geometry.rings,
|
|
34
|
+
graphic.attributes.id,
|
|
35
|
+
graphic.geometry.rings,
|
|
36
36
|
mapColorScheme
|
|
37
37
|
)
|
|
38
38
|
graphic.symbol = newGraphic.symbol
|
|
39
|
-
|
|
39
|
+
|
|
40
40
|
if (activeGraphicId === graphic.attributes.id) {
|
|
41
41
|
activeGraphic = graphic
|
|
42
42
|
}
|
|
43
43
|
})
|
|
44
|
-
|
|
44
|
+
|
|
45
45
|
// Re-enter update mode only if we were editing (not creating)
|
|
46
46
|
if (activeGraphic && !isCreating && sketchViewModel.layer === sketchLayer) {
|
|
47
47
|
try {
|
|
@@ -68,10 +68,19 @@ export function attachEvents({ pluginState, mapProvider, events, eventBus, butto
|
|
|
68
68
|
// Event handlers
|
|
69
69
|
const handleMapStyleChange = () => reColour()
|
|
70
70
|
|
|
71
|
+
const onGraphicChanged = (graphic) => {
|
|
72
|
+
if (!graphic) {
|
|
73
|
+
return
|
|
74
|
+
}
|
|
75
|
+
const tempFeature = graphicToGeoJSON(graphic)
|
|
76
|
+
eventBus.emit('draw:updated', tempFeature)
|
|
77
|
+
dispatch({ type: 'SET_FEATURE', payload: { tempFeature } })
|
|
78
|
+
}
|
|
79
|
+
|
|
71
80
|
const handleSketchUpdate = (e) => {
|
|
72
81
|
const toolInfoType = e.toolEventInfo?.type
|
|
73
82
|
const graphic = e.graphics[0]
|
|
74
|
-
|
|
83
|
+
|
|
75
84
|
// Prevent polygon move
|
|
76
85
|
if (toolInfoType === 'move-start') {
|
|
77
86
|
sketchViewModel.cancel()
|
|
@@ -87,10 +96,8 @@ export function attachEvents({ pluginState, mapProvider, events, eventBus, butto
|
|
|
87
96
|
}
|
|
88
97
|
|
|
89
98
|
// Emit event on update
|
|
90
|
-
if (toolInfoType === 'reshape-stop') {
|
|
91
|
-
|
|
92
|
-
eventBus.emit('draw:updated', tempFeature)
|
|
93
|
-
dispatch({ type: 'SET_FEATURE', payload: { tempFeature }})
|
|
99
|
+
if (toolInfoType === 'reshape-stop' || toolInfoType === 'vertex-remove') {
|
|
100
|
+
onGraphicChanged(graphic)
|
|
94
101
|
}
|
|
95
102
|
}
|
|
96
103
|
|
|
@@ -108,17 +115,38 @@ export function attachEvents({ pluginState, mapProvider, events, eventBus, butto
|
|
|
108
115
|
updateGraphic()
|
|
109
116
|
}
|
|
110
117
|
|
|
118
|
+
const handleCreate = async (event) => {
|
|
119
|
+
const { toolEventInfo } = event
|
|
120
|
+
const graphic = event?.graphic
|
|
121
|
+
if (graphic && toolEventInfo?.type === 'vertex-add') {
|
|
122
|
+
const rings = graphic.geometry?.rings
|
|
123
|
+
// rings.length is > 1 occurs when the shape becomes complex (ie self intersects)
|
|
124
|
+
// setTimeout is required to cause the undo to be called after handleCreate completes
|
|
125
|
+
// otherwise the previous change, rather than this one, is undone
|
|
126
|
+
if (rings?.length > 1) {
|
|
127
|
+
setTimeout(() => sketchViewModel.undo(), 0)
|
|
128
|
+
} else if (rings?.[0]?.length > 3) {
|
|
129
|
+
onGraphicChanged(graphic) // emit a graphic update on draw, once the graphic is 2D
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
const handleUndo = async (event) => {
|
|
135
|
+
const graphic = event?.graphics?.[0]
|
|
136
|
+
onGraphicChanged(graphic)
|
|
137
|
+
}
|
|
138
|
+
|
|
111
139
|
const handleDone = () => {
|
|
112
140
|
sketchViewModel.cancel()
|
|
113
141
|
sketchViewModel.layer = emptySketchLayer
|
|
114
142
|
dispatch({ type: 'SET_MODE', payload: null })
|
|
115
|
-
dispatch({ type: 'SET_FEATURE', payload: { feature: null, tempFeature: null }})
|
|
143
|
+
dispatch({ type: 'SET_FEATURE', payload: { feature: null, tempFeature: null } })
|
|
116
144
|
eventBus.emit('draw:done', { newFeature: pluginState.tempFeature })
|
|
117
145
|
}
|
|
118
146
|
|
|
119
147
|
const handleCancel = () => {
|
|
120
148
|
sketchViewModel.cancel()
|
|
121
|
-
|
|
149
|
+
|
|
122
150
|
// Clear all graphics
|
|
123
151
|
sketchLayer.removeAll()
|
|
124
152
|
|
|
@@ -143,10 +171,12 @@ export function attachEvents({ pluginState, mapProvider, events, eventBus, butto
|
|
|
143
171
|
eventBus.on(events.MAP_STYLE_CHANGE, handleMapStyleChange)
|
|
144
172
|
const sketchUpdateHandler = sketchViewModel.on('update', handleSketchUpdate)
|
|
145
173
|
const viewClickHandler = view.on('click', handleViewClick)
|
|
146
|
-
|
|
174
|
+
const createHandler = sketchViewModel.on('create', handleCreate)
|
|
175
|
+
const undoHandler = sketchViewModel.on('undo', handleUndo)
|
|
176
|
+
|
|
147
177
|
const prevDoneClick = drawDone.onClick
|
|
148
178
|
const prevCancelClick = drawCancel.onClick
|
|
149
|
-
|
|
179
|
+
|
|
150
180
|
drawDone.onClick = handleDone
|
|
151
181
|
drawCancel.onClick = handleCancel
|
|
152
182
|
|
|
@@ -155,7 +185,9 @@ export function attachEvents({ pluginState, mapProvider, events, eventBus, butto
|
|
|
155
185
|
eventBus.off(events.MAP_STYLE_CHANGE, handleMapStyleChange)
|
|
156
186
|
sketchUpdateHandler.remove()
|
|
157
187
|
viewClickHandler.remove()
|
|
188
|
+
createHandler.remove()
|
|
189
|
+
undoHandler.remove()
|
|
158
190
|
drawDone.onClick = prevDoneClick
|
|
159
191
|
drawCancel.onClick = prevCancelClick
|
|
160
192
|
}
|
|
161
|
-
}
|
|
193
|
+
}
|