@defra/interactive-map 0.0.31-alpha → 0.0.32-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/README.md +2 -2
- package/assets/images/bright-ofm-thumb.jpg +0 -0
- package/assets/images/dark-ofm-thumb.jpg +0 -0
- package/assets/images/road-ofm-thumb.jpg +0 -0
- package/assets/templates/add-polygons.njk +143 -0
- package/assets/templates/add-symbols.njk +119 -0
- package/assets/templates/{map.njk → basic-map.njk} +9 -17
- package/assets/templates/button-map.njk +56 -0
- package/assets/templates/draw-tools.njk +161 -0
- package/assets/templates/marker-panel.njk +91 -0
- package/assets/templates/place-marker.njk +104 -0
- package/assets/templates/search-control.njk +98 -0
- package/assets/templates/select-feature.njk +101 -0
- package/assets/templates/style-switcher.njk +87 -0
- package/assets/templates/toggle-marker-label.njk +74 -0
- package/dist/esm/im-core.js +1 -1
- package/dist/esm/im-shell.js +1 -1
- package/dist/umd/im-core.js +1 -1
- package/dist/umd/index.js +1 -1
- package/docs/api.md +55 -0
- package/docs/assets/css/docusaurus.scss +22 -6
- package/docs/assets/images/add-polygons.jpg +0 -0
- package/docs/assets/images/add-symbols.jpg +0 -0
- package/docs/assets/images/place-marker.jpg +0 -0
- package/docs/assets/images/screenshot.jpg +0 -0
- package/docs/examples/add-marker-with-panel.mdx +1 -1
- package/docs/examples/add-polygons.mdx +225 -0
- package/docs/examples/add-symbols.mdx +177 -0
- package/docs/examples/{draw.mdx → draw-tools.mdx} +2 -2
- package/docs/examples/index.mdx +38 -2
- package/docs/examples/place-marker.mdx +151 -0
- package/docs/plugins/datasets.md +144 -96
- package/docs/plugins/interact.md +1 -4
- package/docusaurus.config.cjs +5 -2
- package/govuk-prototype-kit.config.json +52 -2
- package/package.json +1 -1
- package/plugins/beta/datasets/dist/css/index.css +1 -2
- package/plugins/beta/datasets/dist/esm/im-datasets-ml-adapter.js +1 -1
- package/plugins/beta/datasets/dist/esm/im-datasets-plugin.js +1 -1
- package/plugins/beta/datasets/dist/umd/im-datasets-ml-adapter.js +1 -1
- package/plugins/beta/datasets/dist/umd/im-datasets-plugin.js +1 -1
- package/plugins/beta/datasets/dist/umd/index.js +1 -1
- package/plugins/beta/datasets/src/adapters/maplibre/registry/mapLibreDataset.js +27 -9
- package/plugins/beta/datasets/src/adapters/maplibre/registry/mapLibreDataset.test.js +46 -4
- package/plugins/beta/datasets/src/api/setFeatureVisibility.js +10 -1
- package/plugins/beta/datasets/src/api/setFeatureVisibility.test.js +48 -6
- package/plugins/beta/datasets/src/components/LayersMenu/Layers.module.scss +12 -12
- package/plugins/beta/datasets/src/reducers/datasetsToMenu.js +11 -6
- package/plugins/beta/datasets/src/reducers/datasetsToMenu.test.js +49 -0
- package/plugins/beta/datasets/src/reducers/mappedDatasetsReducer.js +8 -1
- package/plugins/beta/datasets/src/reducers/pluginState.js +1 -1
- package/plugins/beta/datasets/src/registry/dataset.js +7 -3
- package/plugins/beta/datasets/src/registry/dataset.test.js +14 -0
- package/plugins/beta/datasets/src/registry/dynamicGeoJson.js +1 -1
- package/plugins/beta/draw-es/dist/esm/im-draw-es-plugin.js +1 -1
- package/plugins/beta/draw-es/src/api/addFeature.js +12 -3
- package/plugins/beta/draw-es/src/events.js +8 -3
- package/plugins/beta/draw-es/src/events.test.js +2 -0
- package/plugins/beta/draw-es/src/graphic.js +26 -2
- 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 +8 -0
- package/plugins/beta/draw-ml/src/api/newLine.js +1 -0
- package/plugins/beta/draw-ml/src/api/newPolygon.js +1 -0
- package/plugins/beta/draw-ml/src/modes/createDrawMode.js +21 -12
- package/plugins/beta/draw-ml/src/modes/editVertexMode.js +4 -0
- package/plugins/beta/draw-ol/dist/esm/EditMode.js +1 -1
- package/plugins/beta/draw-ol/dist/esm/im-draw-ol-plugin.js +1 -1
- package/plugins/beta/draw-ol/src/edit/keyboardHandler.js +4 -2
- package/plugins/beta/map-styles/src/mapStyles.scss +41 -41
- package/plugins/interact/dist/esm/im-interact-plugin.js +1 -1
- package/plugins/interact/dist/umd/im-interact-plugin.js +1 -1
- package/plugins/interact/dist/umd/index.js +1 -1
- package/plugins/interact/src/InteractInit.jsx +1 -3
- package/plugins/interact/src/InteractInit.test.js +0 -2
- package/plugins/interact/src/events.test.js +1 -1
- package/plugins/interact/src/hooks/useCrossHairVisibility.js +4 -10
- package/plugins/interact/src/hooks/useCrossHairVisibility.test.js +5 -10
- package/plugins/interact/src/hooks/useHighlightSync.js +1 -10
- package/plugins/interact/src/hooks/useHighlightSync.test.js +2 -21
- package/plugins/interact/src/hooks/useInteractionHandlers.js +5 -11
- package/plugins/interact/src/hooks/useInteractionHandlers.test.js +5 -25
- package/plugins/interact/src/reducer.js +4 -22
- package/plugins/interact/src/reducer.test.js +11 -39
- package/plugins/search/dist/css/index.css +5 -2
- package/plugins/search/src/components/Form/Form.module.scss +5 -2
- package/plugins/search/src/search.scss +4 -4
- package/src/App/components/CrossHair/CrossHair.module.scss +8 -8
- package/src/App/hooks/useLayoutMeasurements.js +10 -2
- package/src/App/hooks/useResizeObserver.js +4 -2
- package/src/InteractiveMap/InteractiveMap.js +4 -4
- package/src/InteractiveMap/InteractiveMap.test.js +3 -3
- package/src/InteractiveMap/behaviourController.js +3 -1
- package/src/InteractiveMap/behaviourController.test.js +6 -3
- package/src/InteractiveMap/domStateManager.js +2 -0
- package/src/config/events.js +21 -3
- package/docs/assets/images/screens-blue.jpg +0 -0
- package/docs/assets/images/screens-white.jpg +0 -0
|
@@ -1,32 +1,74 @@
|
|
|
1
1
|
import { setFeatureVisibility } from './setFeatureVisibility.js'
|
|
2
|
+
import { datasetRegistry } from '../registry/datasetRegistry.js'
|
|
3
|
+
import { logger } from '../../../../../src/services/logger.js'
|
|
4
|
+
|
|
5
|
+
jest.mock('../registry/datasetRegistry.js', () => ({
|
|
6
|
+
datasetRegistry: { getDataset: jest.fn() }
|
|
7
|
+
}))
|
|
8
|
+
|
|
9
|
+
jest.mock('../../../../../src/services/logger.js', () => ({
|
|
10
|
+
logger: { warn: jest.fn() }
|
|
11
|
+
}))
|
|
2
12
|
|
|
3
13
|
describe('setFeatureVisibility', () => {
|
|
4
14
|
const dispatch = jest.fn()
|
|
5
15
|
const featureIds = [1, 2, 3]
|
|
16
|
+
const datasetId = 'my-dataset'
|
|
17
|
+
|
|
18
|
+
beforeEach(() => {
|
|
19
|
+
jest.clearAllMocks()
|
|
20
|
+
datasetRegistry.getDataset.mockReturnValue({ idProperty: 'id', generateIds: false })
|
|
21
|
+
})
|
|
22
|
+
|
|
6
23
|
it('dispatches SHOW_FEATURES when visible is true', () => {
|
|
7
|
-
setFeatureVisibility({ pluginState: { dispatch } }, true, featureIds, { datasetId
|
|
24
|
+
setFeatureVisibility({ pluginState: { dispatch } }, true, featureIds, { datasetId })
|
|
8
25
|
|
|
9
26
|
expect(dispatch).toHaveBeenCalledWith({
|
|
10
27
|
type: 'SHOW_FEATURES',
|
|
11
|
-
payload: { datasetId
|
|
28
|
+
payload: { datasetId, featureIds }
|
|
12
29
|
})
|
|
13
30
|
})
|
|
14
31
|
|
|
15
32
|
it('dispatches HIDE_FEATURES when visible is false', () => {
|
|
16
|
-
setFeatureVisibility({ pluginState: { dispatch } }, false, featureIds, { datasetId
|
|
33
|
+
setFeatureVisibility({ pluginState: { dispatch } }, false, featureIds, { datasetId })
|
|
17
34
|
|
|
18
35
|
expect(dispatch).toHaveBeenCalledWith({
|
|
19
36
|
type: 'HIDE_FEATURES',
|
|
20
|
-
payload: { datasetId
|
|
37
|
+
payload: { datasetId, featureIds }
|
|
21
38
|
})
|
|
22
39
|
})
|
|
23
40
|
|
|
24
|
-
it('uses
|
|
41
|
+
it('uses null datasetId when options are not provided', () => {
|
|
25
42
|
setFeatureVisibility({ pluginState: { dispatch } }, true, featureIds)
|
|
26
43
|
|
|
27
44
|
expect(dispatch).toHaveBeenCalledWith({
|
|
28
45
|
type: 'SHOW_FEATURES',
|
|
29
|
-
payload: { datasetId:
|
|
46
|
+
payload: { datasetId: null, featureIds }
|
|
30
47
|
})
|
|
31
48
|
})
|
|
49
|
+
|
|
50
|
+
it('does not warn when dataset has idProperty set', () => {
|
|
51
|
+
datasetRegistry.getDataset.mockReturnValue({ idProperty: 'parcel_id', generateIds: false })
|
|
52
|
+
setFeatureVisibility({ pluginState: { dispatch } }, false, featureIds, { datasetId })
|
|
53
|
+
expect(logger.warn).not.toHaveBeenCalled()
|
|
54
|
+
})
|
|
55
|
+
|
|
56
|
+
it('does not warn when dataset has generateIds set', () => {
|
|
57
|
+
datasetRegistry.getDataset.mockReturnValue({ idProperty: null, generateIds: true })
|
|
58
|
+
setFeatureVisibility({ pluginState: { dispatch } }, false, featureIds, { datasetId })
|
|
59
|
+
expect(logger.warn).not.toHaveBeenCalled()
|
|
60
|
+
})
|
|
61
|
+
|
|
62
|
+
it('warns when dataset has neither idProperty nor generateIds', () => {
|
|
63
|
+
datasetRegistry.getDataset.mockReturnValue({ idProperty: null, generateIds: false })
|
|
64
|
+
setFeatureVisibility({ pluginState: { dispatch } }, false, featureIds, { datasetId })
|
|
65
|
+
expect(logger.warn).toHaveBeenCalledWith(expect.stringContaining(`"${datasetId}"`))
|
|
66
|
+
expect(logger.warn).toHaveBeenCalledWith(expect.stringContaining('idProperty'))
|
|
67
|
+
})
|
|
68
|
+
|
|
69
|
+
it('does not warn or look up registry when datasetId is not provided', () => {
|
|
70
|
+
setFeatureVisibility({ pluginState: { dispatch } }, false, featureIds)
|
|
71
|
+
expect(datasetRegistry.getDataset).not.toHaveBeenCalled()
|
|
72
|
+
expect(logger.warn).not.toHaveBeenCalled()
|
|
73
|
+
})
|
|
32
74
|
})
|
|
@@ -35,19 +35,19 @@
|
|
|
35
35
|
margin-bottom: 0;
|
|
36
36
|
}
|
|
37
37
|
}
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
.im-c-datasets-layers__item-label {
|
|
41
|
-
width: 100%;
|
|
42
|
-
max-width: none;
|
|
43
|
-
align-items: start;
|
|
44
|
-
padding-top: 12px;
|
|
45
|
-
padding-bottom: 10px;
|
|
46
|
-
align-self: auto;
|
|
47
|
-
font-size: 1rem;
|
|
48
|
-
line-height: 1.2;
|
|
49
38
|
|
|
50
|
-
|
|
39
|
+
.im-c-datasets-layers__item-label {
|
|
40
|
+
width: 100%;
|
|
41
|
+
max-width: none;
|
|
42
|
+
align-items: start;
|
|
43
|
+
padding-top: 12px;
|
|
44
|
+
padding-bottom: 10px;
|
|
45
|
+
align-self: auto;
|
|
46
|
+
font-size: 1rem;
|
|
47
|
+
line-height: 1.2;
|
|
48
|
+
|
|
49
|
+
color: var(--foreground-color);
|
|
50
|
+
}
|
|
51
51
|
}
|
|
52
52
|
|
|
53
53
|
// GovUK style overide
|
|
@@ -1,20 +1,25 @@
|
|
|
1
1
|
export const datasetsToMenu = (state) => {
|
|
2
2
|
const { datasets = [] } = state
|
|
3
3
|
const menu = []
|
|
4
|
-
const datasetsForMenu = datasets.filter(dataset =>
|
|
4
|
+
const datasetsForMenu = datasets.filter(dataset =>
|
|
5
|
+
dataset.showInMenu || dataset.sublayers?.some(s => s.showInMenu)
|
|
6
|
+
)
|
|
5
7
|
const groups = new Map()
|
|
6
8
|
datasetsForMenu.forEach(dataset => {
|
|
7
9
|
if (dataset.sublayers?.length) {
|
|
10
|
+
const visibleSublayers = dataset.sublayers.filter(sublayer =>
|
|
11
|
+
dataset.showInMenu ? sublayer.showInMenu !== false : sublayer.showInMenu
|
|
12
|
+
)
|
|
13
|
+
if (!visibleSublayers.length) { return }
|
|
8
14
|
menu.push({
|
|
9
15
|
id: dataset.id,
|
|
10
16
|
groupLabel: dataset.label,
|
|
11
17
|
visibleWhen: true,
|
|
12
18
|
type: 'checkbox',
|
|
13
|
-
items:
|
|
14
|
-
.
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
}))
|
|
19
|
+
items: visibleSublayers.map(sublayer => ({
|
|
20
|
+
id: `${dataset.id}-${sublayer.id}`,
|
|
21
|
+
label: sublayer.label
|
|
22
|
+
}))
|
|
18
23
|
})
|
|
19
24
|
} else if (dataset.groupLabel) {
|
|
20
25
|
// Check for existing group object for this groupLabel, or create it if it doesn't exist,
|
|
@@ -32,4 +32,53 @@ describe('datasetsToMenu', () => {
|
|
|
32
32
|
.toEqual(expectedDatasetsMenuConfigWithGroups)
|
|
33
33
|
})
|
|
34
34
|
})
|
|
35
|
+
|
|
36
|
+
describe('showInMenu inheritance for sublayers', () => {
|
|
37
|
+
const sublayerDataset = (datasetShowInMenu, sublayerShowInMenu) => ({
|
|
38
|
+
id: 'test',
|
|
39
|
+
label: 'Test',
|
|
40
|
+
showInMenu: datasetShowInMenu,
|
|
41
|
+
sublayers: [
|
|
42
|
+
{ id: 'a', label: 'A', ...(sublayerShowInMenu !== undefined && { showInMenu: sublayerShowInMenu }) },
|
|
43
|
+
{ id: 'b', label: 'B', ...(sublayerShowInMenu !== undefined && { showInMenu: sublayerShowInMenu }) }
|
|
44
|
+
]
|
|
45
|
+
})
|
|
46
|
+
|
|
47
|
+
it('sublayers inherit showInMenu: true from the dataset when not explicitly set', () => {
|
|
48
|
+
const result = datasetsToMenu({ datasets: [sublayerDataset(true, undefined)] })
|
|
49
|
+
expect(result[0].items).toHaveLength(2)
|
|
50
|
+
})
|
|
51
|
+
|
|
52
|
+
it('sublayer can opt out with showInMenu: false when dataset has showInMenu: true', () => {
|
|
53
|
+
const dataset = {
|
|
54
|
+
id: 'test',
|
|
55
|
+
label: 'Test',
|
|
56
|
+
showInMenu: true,
|
|
57
|
+
sublayers: [
|
|
58
|
+
{ id: 'a', label: 'A', showInMenu: false },
|
|
59
|
+
{ id: 'b', label: 'B' }
|
|
60
|
+
]
|
|
61
|
+
}
|
|
62
|
+
const result = datasetsToMenu({ datasets: [dataset] })
|
|
63
|
+
expect(result[0].items).toEqual([{ id: 'test-b', label: 'B' }])
|
|
64
|
+
})
|
|
65
|
+
|
|
66
|
+
it('sublayers with showInMenu: true appear when dataset does not have showInMenu set', () => {
|
|
67
|
+
const dataset = {
|
|
68
|
+
id: 'test',
|
|
69
|
+
label: 'Test',
|
|
70
|
+
sublayers: [
|
|
71
|
+
{ id: 'a', label: 'A', showInMenu: true },
|
|
72
|
+
{ id: 'b', label: 'B' }
|
|
73
|
+
]
|
|
74
|
+
}
|
|
75
|
+
const result = datasetsToMenu({ datasets: [dataset] })
|
|
76
|
+
expect(result[0].items).toEqual([{ id: 'test-a', label: 'A' }])
|
|
77
|
+
})
|
|
78
|
+
|
|
79
|
+
it('does not add a menu entry when dataset has showInMenu: true but all sublayers opt out', () => {
|
|
80
|
+
const result = datasetsToMenu({ datasets: [sublayerDataset(true, false)] })
|
|
81
|
+
expect(result).toHaveLength(0)
|
|
82
|
+
})
|
|
83
|
+
})
|
|
35
84
|
})
|
|
@@ -11,7 +11,14 @@ const flattenSublayer = (parentId, sublayer) => {
|
|
|
11
11
|
|
|
12
12
|
const reduceDatasets = (acc, dataset) => {
|
|
13
13
|
const { id } = dataset
|
|
14
|
-
|
|
14
|
+
const processed = applyDatasetDefaultsWithoutFlattening(dataset)
|
|
15
|
+
// For sublayers, don't let defaults override the absence of showInKey/showInMenu —
|
|
16
|
+
// the Dataset class inherits these from the parent when not explicitly set by the user
|
|
17
|
+
if (dataset.parentId) {
|
|
18
|
+
if (!('showInKey' in dataset)) { delete processed.showInKey }
|
|
19
|
+
if (!('showInMenu' in dataset)) { delete processed.showInMenu }
|
|
20
|
+
}
|
|
21
|
+
acc[id] = processed
|
|
15
22
|
const { orderedDatasets } = acc
|
|
16
23
|
orderedDatasets.push(id)
|
|
17
24
|
const flattenedSublayers = dataset.sublayers?.map((sublayer) => flattenSublayer(id, sublayer))
|
|
@@ -116,7 +116,7 @@ const hideFeatures = (state, payload) => {
|
|
|
116
116
|
}
|
|
117
117
|
const mappedDataset = { ...state.mappedDatasets[datasetId] }
|
|
118
118
|
const existingIds = mappedDataset.hiddenFeatures || []
|
|
119
|
-
const newIds =
|
|
119
|
+
const newIds = Array.from(new Set([...existingIds, ...featureIds]))
|
|
120
120
|
mappedDataset.hiddenFeatures = newIds
|
|
121
121
|
|
|
122
122
|
return addAction('applyFeatureFilter', [datasetId], {
|
|
@@ -18,12 +18,16 @@ export class Dataset {
|
|
|
18
18
|
get tiles () { return this._datasetDefinition.tiles }
|
|
19
19
|
get geojson () { return this._datasetDefinition.geojson }
|
|
20
20
|
get idProperty () { return this._datasetDefinition.idProperty }
|
|
21
|
-
|
|
22
|
-
// get transformRequest () { return this._datasetDefinition.transformRequest }
|
|
21
|
+
get generateIds () { return this._datasetDefinition.generateIds }
|
|
23
22
|
get parentId () { return this._datasetDefinition.parentId }
|
|
24
23
|
get minZoom () { return this._datasetDefinition.minZoom || this.parent?.minZoom }
|
|
25
24
|
get maxZoom () { return this._datasetDefinition.maxZoom || this.parent?.maxZoom }
|
|
26
|
-
get showInKey () {
|
|
25
|
+
get showInKey () {
|
|
26
|
+
const own = this._datasetDefinition.showInKey
|
|
27
|
+
if (own !== undefined) { return own }
|
|
28
|
+
return this.parent?.showInKey ?? false
|
|
29
|
+
}
|
|
30
|
+
|
|
27
31
|
get groupLabel () { return this._datasetDefinition.groupLabel }
|
|
28
32
|
|
|
29
33
|
get opacity () {
|
|
@@ -201,6 +201,20 @@ describe('Dataset class', () => {
|
|
|
201
201
|
datasetRegistry.attach({ parent: parentDef, child: childDef })
|
|
202
202
|
expect(new Dataset(childDef).showInKey).toBe(false)
|
|
203
203
|
})
|
|
204
|
+
|
|
205
|
+
it('allows a sublayer to opt out with showInKey: false even when parent has showInKey: true', () => {
|
|
206
|
+
const parentDef = { id: 'parent', showInKey: true, style: {} }
|
|
207
|
+
const childDef = { id: 'child', parentId: 'parent', showInKey: false, style: {} }
|
|
208
|
+
datasetRegistry.attach({ parent: parentDef, child: childDef })
|
|
209
|
+
expect(new Dataset(childDef).showInKey).toBe(false)
|
|
210
|
+
})
|
|
211
|
+
|
|
212
|
+
it('allows a sublayer to opt in with showInKey: true even when parent has showInKey: false', () => {
|
|
213
|
+
const parentDef = { id: 'parent', showInKey: false, style: {} }
|
|
214
|
+
const childDef = { id: 'child', parentId: 'parent', showInKey: true, style: {} }
|
|
215
|
+
datasetRegistry.attach({ parent: parentDef, child: childDef })
|
|
216
|
+
expect(new Dataset(childDef).showInKey).toBe(true)
|
|
217
|
+
})
|
|
204
218
|
})
|
|
205
219
|
|
|
206
220
|
describe('tiles, geojson, idProperty, parentId', () => {
|
|
@@ -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 a from"@arcgis/core/layers/GraphicsLayer.js";import o from"@babel/runtime/helpers/asyncToGenerator";import*as n from"@arcgis/core/geometry/operators/simplifyOperator.js";import i from"@arcgis/core/Graphic.js";function p(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);t&&(a=a.filter(function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable})),r.push.apply(r,a)}return r}function l(t){for(var r=1;r<arguments.length;r++){var a=null!=arguments[r]?arguments[r]:{};r%2?p(Object(a),!0).forEach(function(r){e(t,r,a[r])}):Object.getOwnPropertyDescriptors?Object.defineProperties(t,Object.getOwnPropertyDescriptors(a)):p(Object(a)).forEach(function(e){Object.defineProperty(t,e,Object.getOwnPropertyDescriptor(a,e))})}return t}var c={APP_ADD_MARKER:"app:addmarker",APP_UPDATE_MARKER:"app:updatemarker",APP_REMOVE_MARKER:"app:removemarker",APP_SET_MODE:"app:setmode",APP_REVERT_MODE:"app:revertmode",APP_ADD_BUTTON:"app:addbutton",APP_TOGGLE_BUTTON_STATE:"app:togglebuttonstate",APP_ADD_PANEL:"app:addpanel",APP_REMOVE_PANEL:"app:removepanel",APP_SHOW_PANEL:"app:showpanel",APP_HIDE_PANEL:"app:hidepanel",APP_ADD_CONTROL:"app:addcontrol",APP_READY:"app:ready",APP_OPENED:"app:opened",APP_CLOSED:"app:closed",APP_PANEL_OPENED:"app:panelopened",APP_PANEL_CLOSED:"app:panelclosed",MAP_SET_STYLE:"map:setstyle",MAP_SET_SIZE:"map:setsize",MAP_SET_FEATURES:"map:setfeatures",MAP_SET_ACTIVE_FEATURE:"map:setactivefeature",MAP_SELECT_FEATURE:"map:selectfeature",MAP_SET_PIXEL_RATIO:"map:setpixelratio",MAP_FIT_TO_BOUNDS:"map:fittobounds",MAP_SET_VIEW:"map:setview",MAP_INIT_MAP_STYLES:"map:initmapstyles",MAP_STYLE_CHANGE:"map:stylechange",MAP_LOADED:"map:loaded",MAP_READY:"map:ready",MAP_SIZE_CHANGE:"map:sizechange",MAP_FIRST_IDLE:"map:firstidle",MAP_MOVE_START:"map:movestart",MAP_MOVE:"map:move",MAP_MOVE_END:"map:moveend",MAP_STATE_UPDATED:"map:stateupdated",MAP_DATA_CHANGE:"map:datachange",MAP_RENDER:"map:render",MAP_CLICK:"map:click",MAP_DESTROY:"map:destroy"};function s(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);t&&(a=a.filter(function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable})),r.push.apply(r,a)}return r}function d(t){for(var r=1;r<arguments.length;r++){var a=null!=arguments[r]?arguments[r]:{};r%2?s(Object(a),!0).forEach(function(r){e(t,r,a[r])}):Object.getOwnPropertyDescriptors?Object.defineProperties(t,Object.getOwnPropertyDescriptors(a)):s(Object(a)).forEach(function(e){Object.defineProperty(t,e,Object.getOwnPropertyDescriptor(a,e))})}return t}function u(e){return{type:"simple-fill",color:[0,120,255,.2],outline:{color:"dark"===e?"#ffffff":"#d4351c",width:2}}}function m(e,t,r){return new i({geometry:{type:"polygon",rings:t,spatialReference:27700},attributes:{id:e},symbol:u(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:d({},r)};case"polyline":return{type:"Feature",geometry:{type:"LineString",coordinates:t.paths[0]},properties:d({},r)};case"polygon":return{type:"Feature",geometry:{type:"Polygon",coordinates:t.rings},properties:d({},r)};default:throw new Error("Unsupported geometry type: ".concat(t.type))}}function v(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);t&&(a=a.filter(function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable})),r.push.apply(r,a)}return r}function E(t){for(var r=1;r<arguments.length;r++){var a=null!=arguments[r]?arguments[r]:{};r%2?v(Object(a),!0).forEach(function(r){e(t,r,a[r])}):Object.getOwnPropertyDescriptors?Object.defineProperties(t,Object.getOwnPropertyDescriptors(a)):v(Object(a)).forEach(function(e){Object.defineProperty(t,e,Object.getOwnPropertyDescriptor(a,e))})}return t}var f={mobile:{slot:"actions",showLabel:!0},tablet:{slot:"actions",showLabel:!0},desktop:{slot:"actions",showLabel:!0}},P={reducer:{initialState:{mode:null,feature:null,tempFeature:null},actions:{SET_MODE:(e,t)=>l(l({},e),{},{mode:t}),SET_FEATURE:(e,t)=>l(l({},e),{},{feature:void 0===t.feature?e.feature:t.feature,tempFeature:void 0===t.tempFeature?e.tempFeature:t.tempFeature})}},InitComponent:e=>{var i,p,l,s,{appState:d,mapState:v,pluginConfig:E,pluginState:f,services:P,mapProvider:h,buttonConfig:g}=e,{eventBus:_}=P,{mapColorScheme:O}=v.mapStyle||{},A=null===(i=null===(p=E.includeModes)||void 0===p?void 0:p.includes(d.mode))||void 0===i||i,S=null!==(l=null===(s=E.excludeModes)||void 0===s?void 0:s.includes(d.mode))&&void 0!==l&&l,b=v.isMapReady&&A&&!S;t(()=>{if(b&&!h.sketchViewModel){var{sketchViewModel:e,sketchLayer:t,emptySketchLayer:o}=(e=>{var{mapProvider:t}=e,{view:o}=t,n=new a({id:"sketchLayer"});o.map.add(n);var i=new a({id:"emptySketchLayer"});return o.map.add(i),{sketchViewModel:new r({view:o,layer:i,defaultUpdateOptions:{tool:"reshape",updateOnGraphicClick:!1,multipleSelectionEnabled:!1,toggleToolOnClick:!1,highlightOptions:{enabled:!1}}}),emptySketchLayer:i,sketchLayer:n}})({mapProvider:h});return h.sketchViewModel=e,h.sketchLayer=t,h.emptySketchLayer=o,_.emit("draw:ready"),()=>{h.sketchViewModel=null,h.sketchLayer=null,h.emptySketchLayer=null}}},[v.isMapReady,d.mode]),t(()=>{if(b&&h.sketchViewModel){var e=function(e){var{pluginState:t,mapProvider:r,events:a,eventBus:i,buttonConfig:p,mapColorScheme:l}=e,{view:c,sketchViewModel:s,sketchLayer:d,emptySketchLayer:v}=r;if(!s)return null;var{drawDone:E,drawCancel:f}=p,{dispatch:P,mode:h,feature:g}=t,_=function(){var e=o(function*(){var e,r=null===(e=t.feature)||void 0===e||null===(e=e.properties)||void 0===e?void 0:e.id,a=null,o="active"===s.state&&!r;if("active"===s.state&&r&&(s.cancel(),yield new Promise(e=>setTimeout(e,50))),s.polygonSymbol=u(l),null==d||d.graphics.items.forEach(e=>{var t=m(e.attributes.id,e.geometry.rings,l);e.symbol=t.symbol,r===e.attributes.id&&(a=e)}),a&&!o&&s.layer===d)try{yield s.update(a,{tool:"reshape",toggleToolOnClick:!1})}catch(e){"AbortError"!==e.name&&console.error("Error updating sketch:",e)}});return function(){return e.apply(this,arguments)}}(),O=()=>{var e,t,r=null!==(e=null===(t=d.graphics)||void 0===t||null===(t=t.items)||void 0===t?void 0:t[0])&&void 0!==e?e:null;r&&setTimeout(()=>s.update(r),0)},A=()=>_(),S=e=>{if(e){var t=y(e);i.emit("draw:updated",t),P({type:"SET_FEATURE",payload:{tempFeature:t}})}},b=function(){var e=o(function*(){h&&((s.updateGraphics||[]).length||O())});return function(){return e.apply(this,arguments)}}(),T=function(){var e=o(function*(e){var{toolEventInfo:t}=e,r=null==e?void 0:e.graphic;if(r&&"vertex-add"===(null==t?void 0:t.type)){var a,o,n=null===(a=r.geometry)||void 0===a?void 0:a.rings;(null==n?void 0:n.length)>1?setTimeout(()=>s.undo(),0):(null==n||null===(o=n[0])||void 0===o?void 0:o.length)>3&&S(r)}});return function(t){return e.apply(this,arguments)}}(),w=function(){var e=o(function*(e){var t,r=null==e||null===(t=e.graphics)||void 0===t?void 0:t[0];S(r)});return function(t){return e.apply(this,arguments)}}();i.on(a.MAP_STYLE_CHANGE,A);var M=s.on("update",e=>{var t,r=null===(t=e.toolEventInfo)||void 0===t?void 0:t.type,a=e.graphics[0];"move-start"===r&&(s.cancel(),O()),"reshape"===r&&(n.isSimple(a.geometry)||s.undo()),"reshape-stop"!==r&&"vertex-remove"!==r||S(a)}),k=c.on("click",b),D=s.on("create",T),L=s.on("undo",w),j=E.onClick,C=f.onClick;return E.onClick=()=>{s.cancel(),s.layer=v,P({type:"SET_MODE",payload:null}),P({type:"SET_FEATURE",payload:{feature:null,tempFeature:null}}),i.emit("draw:done",{newFeature:t.tempFeature})},f.onClick=()=>{if(s.cancel(),d.removeAll(),g){var e=m(g.id||g.properties.id,g.geometry.coordinates,l);d.add(e)}s.layer=v,P({type:"SET_MODE",payload:null}),i.emit("draw:cancelled")},()=>{i.off(a.MAP_STYLE_CHANGE,A),M.remove(),k.remove(),D.remove(),L.remove(),E.onClick=j,f.onClick=C}}({pluginState:f,mapProvider:h,events:c,eventBus:_,buttonConfig:g,mapColorScheme:O});return()=>{e()}}},[b,O,f])},buttons:[E({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),E({id:"drawCancel",label:"Cancel",variant:"tertiary",hiddenWhen:e=>{var{pluginState:t}=e;return!t.mode}},f)],api:{newPolygon:(e,t)=>{var{mapState:r,pluginState:a,mapProvider:o,services:n}=e,{dispatch:i}=a,{sketchViewModel:p,sketchLayer:l}=o,{eventBus:c}=n;p.layer=l;var s=p.on("create",e=>{if("complete"===e.state){e.graphic.attributes={id:t},requestAnimationFrame(()=>{p.update(e.graphic,{tool:"reshape",toggleToolOnClick:!1})});var r=y(e.graphic);c.emit("draw:created",r),i({type:"SET_FEATURE",payload:{tempFeature:r}}),s.remove()}});p.polygonSymbol=u(r.mapStyle.mapColorScheme),p.create("polygon"),i({type:"SET_MODE",payload:"new-polygon"})},editFeature:(e,t)=>{var{pluginState:r,mapProvider:a}=e,{dispatch:o}=r,{sketchViewModel:n,sketchLayer:i}=a,p=i.graphics.items.find(e=>e.attributes.id===t),l=p.geometry.extent,c=[l.xmin,l.ymin,l.xmax,l.ymax];a.fitToBounds(c),n.layer=i,n.update(p,{tool:"reshape",toggleToolOnClick:!1,enableRotation:!1,enableScaling:!1}),o({type:"SET_FEATURE",payload:{feature:y(p)}}),o({type:"SET_MODE",payload:"edit-feature"})},addFeature:(e,t)=>{var{pluginState:r,mapState:a,mapProvider:o,services:n}=e,{dispatch:i}=r,{mapStyle:p}=a,{sketchViewModel:l,sketchLayer:c,emptySketchLayer:s}=o,{eventBus:d}=n,u=m(t.id,t.geometry.coordinates,p.mapColorScheme);c.add(u),l.layer=s,i({type:"SET_FEATURE",payload:{feature:t}}),d.emit("draw:add",t)},deleteFeature:(e,t)=>{var{pluginState:r,mapProvider:a,services:o}=e,{dispatch:n}=r,{sketchViewModel:i,sketchLayer:p,emptySketchLayer:l}=a,{eventBus:c}=o,s=p.graphics.items.find(e=>e.attributes.id===t);i.cancel(),p.remove(s),i.layer=l,n({type:"SET_FEATURE",payload:{feature:null,tempFeature:null}}),c.emit("draw:delete",{featureId:t}),n({type:"SET_MODE",payload:null})}}};export{P as manifest};
|
|
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 a from"@arcgis/core/layers/GraphicsLayer.js";import o from"@babel/runtime/helpers/asyncToGenerator";import*as n from"@arcgis/core/geometry/operators/simplifyOperator.js";import i from"@arcgis/core/Graphic.js";function p(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);t&&(a=a.filter(function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable})),r.push.apply(r,a)}return r}function l(t){for(var r=1;r<arguments.length;r++){var a=null!=arguments[r]?arguments[r]:{};r%2?p(Object(a),!0).forEach(function(r){e(t,r,a[r])}):Object.getOwnPropertyDescriptors?Object.defineProperties(t,Object.getOwnPropertyDescriptors(a)):p(Object(a)).forEach(function(e){Object.defineProperty(t,e,Object.getOwnPropertyDescriptor(a,e))})}return t}var c={APP_ADD_MARKER:"app:addmarker",APP_UPDATE_MARKER:"app:updatemarker",APP_REMOVE_MARKER:"app:removemarker",APP_SET_MODE:"app:setmode",APP_REVERT_MODE:"app:revertmode",APP_ADD_BUTTON:"app:addbutton",APP_TOGGLE_BUTTON_STATE:"app:togglebuttonstate",APP_ADD_PANEL:"app:addpanel",APP_REMOVE_PANEL:"app:removepanel",APP_SHOW_PANEL:"app:showpanel",APP_HIDE_PANEL:"app:hidepanel",APP_ADD_CONTROL:"app:addcontrol",APP_READY:"app:ready",APP_OPENED:"app:opened",APP_CLOSED:"app:closed",APP_FULLSCREEN_CHANGE:"app:fullscreenchange",APP_PANEL_OPENED:"app:panelopened",APP_PANEL_CLOSED:"app:panelclosed",MAP_SET_STYLE:"map:setstyle",MAP_SET_SIZE:"map:setsize",MAP_SET_FEATURES:"map:setfeatures",MAP_SET_ACTIVE_FEATURE:"map:setactivefeature",MAP_SELECT_FEATURE:"map:selectfeature",MAP_SET_PIXEL_RATIO:"map:setpixelratio",MAP_FIT_TO_BOUNDS:"map:fittobounds",MAP_SET_VIEW:"map:setview",MAP_INIT_MAP_STYLES:"map:initmapstyles",MAP_STYLE_CHANGE:"map:stylechange",MAP_LOADED:"map:loaded",MAP_READY:"map:ready",MAP_SIZE_CHANGE:"map:sizechange",MAP_FIRST_IDLE:"map:firstidle",MAP_MOVE_START:"map:movestart",MAP_MOVE:"map:move",MAP_MOVE_END:"map:moveend",MAP_STATE_UPDATED:"map:stateupdated",MAP_DATA_CHANGE:"map:datachange",MAP_RENDER:"map:render",MAP_CLICK:"map:click",MAP_DESTROY:"map:destroy"},s="[interactive-map]",u=function(){for(var e=arguments.length,t=new Array(e),r=0;r<e;r++)t[r]=arguments[r];return console.warn(s,...t)},d=function(){for(var e=arguments.length,t=new Array(e),r=0;r<e;r++)t[r]=arguments[r];return console.error(s,...t)};function m(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);t&&(a=a.filter(function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable})),r.push.apply(r,a)}return r}function y(t){for(var r=1;r<arguments.length;r++){var a=null!=arguments[r]?arguments[r]:{};r%2?m(Object(a),!0).forEach(function(r){e(t,r,a[r])}):Object.getOwnPropertyDescriptors?Object.defineProperties(t,Object.getOwnPropertyDescriptors(a)):m(Object(a)).forEach(function(e){Object.defineProperty(t,e,Object.getOwnPropertyDescriptor(a,e))})}return t}function v(e){return{type:"simple-fill",color:[0,120,255,.2],outline:{color:"dark"===e?"#ffffff":"#d4351c",width:2}}}function f(e,t,r){var a=arguments.length>3&&void 0!==arguments[3]?arguments[3]:{},{simplify:o=!0,allowHoles:p=!1}=a,l=new i({geometry:{type:"polygon",rings:t,spatialReference:27700},attributes:{id:e},symbol:v(r)});return o||!1===p?((e,t)=>{var{simplify:r=!0,allowHoles:a=!1}=t;return!r||n.isSimple(e.geometry)||(u("Feature geometry is not simple, attempting to simplify"),e.geometry=n.execute(e.geometry),n.isSimple(e.geometry))?!1===a&&(null==e?void 0:e.geometry.rings.length)>1?(d("Feature contains multiple polygons, which are not supported."),null):e:(d("Failed to simplify geometry, cannot add feature"),null)})(l,a):l}function E(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:y({},r)};case"polyline":return{type:"Feature",geometry:{type:"LineString",coordinates:t.paths[0]},properties:y({},r)};case"polygon":return{type:"Feature",geometry:{type:"Polygon",coordinates:t.rings},properties:y({},r)};default:throw new Error("Unsupported geometry type: ".concat(t.type))}}function g(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);t&&(a=a.filter(function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable})),r.push.apply(r,a)}return r}function h(t){for(var r=1;r<arguments.length;r++){var a=null!=arguments[r]?arguments[r]:{};r%2?g(Object(a),!0).forEach(function(r){e(t,r,a[r])}):Object.getOwnPropertyDescriptors?Object.defineProperties(t,Object.getOwnPropertyDescriptors(a)):g(Object(a)).forEach(function(e){Object.defineProperty(t,e,Object.getOwnPropertyDescriptor(a,e))})}return t}var P={mobile:{slot:"actions",showLabel:!0},tablet:{slot:"actions",showLabel:!0},desktop:{slot:"actions",showLabel:!0}},_={reducer:{initialState:{mode:null,feature:null,tempFeature:null},actions:{SET_MODE:(e,t)=>l(l({},e),{},{mode:t}),SET_FEATURE:(e,t)=>l(l({},e),{},{feature:void 0===t.feature?e.feature:t.feature,tempFeature:void 0===t.tempFeature?e.tempFeature:t.tempFeature})}},InitComponent:e=>{var i,p,l,s,{appState:u,mapState:d,pluginConfig:m,pluginState:y,services:g,mapProvider:h,buttonConfig:P}=e,{eventBus:_}=g,{mapColorScheme:A}=d.mapStyle||{},O=null===(i=null===(p=m.includeModes)||void 0===p?void 0:p.includes(u.mode))||void 0===i||i,S=null!==(l=null===(s=m.excludeModes)||void 0===s?void 0:s.includes(u.mode))&&void 0!==l&&l,b=d.isMapReady&&O&&!S;t(()=>{if(b&&!h.sketchViewModel){var{sketchViewModel:e,sketchLayer:t,emptySketchLayer:o}=(e=>{var{mapProvider:t}=e,{view:o}=t,n=new a({id:"sketchLayer"});o.map.add(n);var i=new a({id:"emptySketchLayer"});return o.map.add(i),{sketchViewModel:new r({view:o,layer:i,defaultUpdateOptions:{tool:"reshape",updateOnGraphicClick:!1,multipleSelectionEnabled:!1,toggleToolOnClick:!1,highlightOptions:{enabled:!1}}}),emptySketchLayer:i,sketchLayer:n}})({mapProvider:h});return h.sketchViewModel=e,h.sketchLayer=t,h.emptySketchLayer=o,_.emit("draw:ready"),()=>{h.sketchViewModel=null,h.sketchLayer=null,h.emptySketchLayer=null}}},[d.isMapReady,u.mode]),t(()=>{if(b&&h.sketchViewModel){var e=function(e){var{pluginState:t,mapProvider:r,events:a,eventBus:i,buttonConfig:p,mapColorScheme:l}=e,{view:c,sketchViewModel:s,sketchLayer:u,emptySketchLayer:d}=r;if(!s)return null;var{drawDone:m,drawCancel:y}=p,{dispatch:g,mode:h,feature:P}=t,_=function(){var e=o(function*(){var e,r=null===(e=t.feature)||void 0===e||null===(e=e.properties)||void 0===e?void 0:e.id,a=null,o="active"===s.state&&!r;if("active"===s.state&&r&&(s.cancel(),yield new Promise(e=>setTimeout(e,50))),s.polygonSymbol=v(l),null==u||u.graphics.items.forEach(e=>{var t=f(e.attributes.id,e.geometry.rings,l);t&&(e.symbol=t.symbol),r===e.attributes.id&&(a=e)}),a&&!o&&s.layer===u)try{yield s.update(a,{tool:"reshape",toggleToolOnClick:!1})}catch(e){"AbortError"!==e.name&&console.error("Error updating sketch:",e)}});return function(){return e.apply(this,arguments)}}(),A=()=>{var e,t,r=null!==(e=null===(t=u.graphics)||void 0===t||null===(t=t.items)||void 0===t?void 0:t[0])&&void 0!==e?e:null;r&&setTimeout(()=>s.update(r),0)},O=()=>_(),S=e=>{if(e){var t=E(e);i.emit("draw:updated",t),g({type:"SET_FEATURE",payload:{tempFeature:t}})}},b=function(){var e=o(function*(){h&&((s.updateGraphics||[]).length||A())});return function(){return e.apply(this,arguments)}}(),w=function(){var e=o(function*(e){var{toolEventInfo:t}=e,r=null==e?void 0:e.graphic;if(r&&"vertex-add"===(null==t?void 0:t.type)){var a,o,n=null===(a=r.geometry)||void 0===a?void 0:a.rings;(null==n?void 0:n.length)>1?setTimeout(()=>s.undo(),0):(null==n||null===(o=n[0])||void 0===o?void 0:o.length)>3&&S(r)}});return function(t){return e.apply(this,arguments)}}(),T=function(){var e=o(function*(e){var t,r=null==e||null===(t=e.graphics)||void 0===t?void 0:t[0];S(r)});return function(t){return e.apply(this,arguments)}}();i.on(a.MAP_STYLE_CHANGE,O);var M=s.on("update",e=>{var t,r=null===(t=e.toolEventInfo)||void 0===t?void 0:t.type,a=e.graphics[0];"move-start"===r&&(s.cancel(),A()),"reshape"===r&&(n.isSimple(a.geometry)&&1===a.geometry.rings.length||s.undo()),"reshape-stop"!==r&&"vertex-remove"!==r||S(a)}),k=c.on("click",b),D=s.on("create",w),L=s.on("undo",T),C=m.onClick,j=y.onClick;return m.onClick=()=>{s.cancel(),s.layer=d,g({type:"SET_MODE",payload:null}),g({type:"SET_FEATURE",payload:{feature:null,tempFeature:null}}),i.emit("draw:done",{newFeature:t.tempFeature})},y.onClick=()=>{if(s.cancel(),u.removeAll(),P){var e=f(P.id||P.properties.id,P.geometry.coordinates,l);e&&u.add(e)}s.layer=d,g({type:"SET_MODE",payload:null}),i.emit("draw:cancelled")},()=>{i.off(a.MAP_STYLE_CHANGE,O),M.remove(),k.remove(),D.remove(),L.remove(),m.onClick=C,y.onClick=j}}({pluginState:y,mapProvider:h,events:c,eventBus:_,buttonConfig:P,mapColorScheme:A});return()=>{e()}}},[b,A,y])},buttons:[h({id:"drawDone",label:"Done",variant:"primary",hiddenWhen:e=>{var{pluginState:t}=e;return!t.mode},enableWhen:e=>{var{pluginState:t}=e;return!!t.tempFeature}},P),h({id:"drawCancel",label:"Cancel",variant:"tertiary",hiddenWhen:e=>{var{pluginState:t}=e;return!t.mode}},P)],api:{newPolygon:(e,t)=>{var{mapState:r,pluginState:a,mapProvider:o,services:n}=e,{dispatch:i}=a,{sketchViewModel:p,sketchLayer:l}=o,{eventBus:c}=n;p.layer=l;var s=p.on("create",e=>{if("complete"===e.state){e.graphic.attributes={id:t},requestAnimationFrame(()=>{p.update(e.graphic,{tool:"reshape",toggleToolOnClick:!1})});var r=E(e.graphic);c.emit("draw:created",r),i({type:"SET_FEATURE",payload:{tempFeature:r}}),s.remove()}});p.polygonSymbol=v(r.mapStyle.mapColorScheme),p.create("polygon"),i({type:"SET_MODE",payload:"new-polygon"})},editFeature:(e,t)=>{var{pluginState:r,mapProvider:a}=e,{dispatch:o}=r,{sketchViewModel:n,sketchLayer:i}=a,p=i.graphics.items.find(e=>e.attributes.id===t),l=p.geometry.extent,c=[l.xmin,l.ymin,l.xmax,l.ymax];a.fitToBounds(c),n.layer=i,n.update(p,{tool:"reshape",toggleToolOnClick:!1,enableRotation:!1,enableScaling:!1}),o({type:"SET_FEATURE",payload:{feature:E(p)}}),o({type:"SET_MODE",payload:"edit-feature"})},addFeature:function(e,t){var{pluginState:r,mapState:a,mapProvider:o,services:n}=e,i=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{},{dispatch:p}=r,{mapStyle:l}=a,{sketchViewModel:c,sketchLayer:s,emptySketchLayer:u}=o,{eventBus:d}=n,m=f(t.id,t.geometry.coordinates,l.mapColorScheme,i),y={success:!0};return m?(s.add(m),c.layer=u,p({type:"SET_FEATURE",payload:{feature:t}}),d.emit("draw:add",t),y):(y.success=!1,y)},deleteFeature:(e,t)=>{var{pluginState:r,mapProvider:a,services:o}=e,{dispatch:n}=r,{sketchViewModel:i,sketchLayer:p,emptySketchLayer:l}=a,{eventBus:c}=o,s=p.graphics.items.find(e=>e.attributes.id===t);i.cancel(),p.remove(s),i.layer=l,n({type:"SET_FEATURE",payload:{feature:null,tempFeature:null}}),c.emit("draw:delete",{featureId:t}),n({type:"SET_MODE",payload:null})}}};export{_ as manifest};
|
|
@@ -1,13 +1,21 @@
|
|
|
1
1
|
import { createGraphic } from '../graphic.js'
|
|
2
2
|
|
|
3
|
-
export const addFeature = ({ pluginState, mapState, mapProvider, services }, feature) => {
|
|
3
|
+
export const addFeature = ({ pluginState, mapState, mapProvider, services }, feature, simplifyOptions = {}) => {
|
|
4
4
|
const { dispatch } = pluginState
|
|
5
5
|
const { mapStyle } = mapState
|
|
6
6
|
const { sketchViewModel, sketchLayer, emptySketchLayer } = mapProvider
|
|
7
7
|
const { eventBus } = services
|
|
8
8
|
|
|
9
|
-
const graphic = createGraphic(feature.id, feature.geometry.coordinates, mapStyle.mapColorScheme)
|
|
10
|
-
|
|
9
|
+
const graphic = createGraphic(feature.id, feature.geometry.coordinates, mapStyle.mapColorScheme, simplifyOptions)
|
|
10
|
+
const result = {
|
|
11
|
+
success: true
|
|
12
|
+
}
|
|
13
|
+
if (!graphic) {
|
|
14
|
+
result.success = false
|
|
15
|
+
// TODO - enhance the results with the specific reason the feature could not be added,
|
|
16
|
+
// e.g. invalid geometry, unsupported geometry type, etc.
|
|
17
|
+
return result
|
|
18
|
+
}
|
|
11
19
|
// Add the graphic to the layer
|
|
12
20
|
sketchLayer.add(graphic)
|
|
13
21
|
|
|
@@ -18,4 +26,5 @@ export const addFeature = ({ pluginState, mapState, mapProvider, services }, fea
|
|
|
18
26
|
dispatch({ type: 'SET_FEATURE', payload: { feature } })
|
|
19
27
|
|
|
20
28
|
eventBus.emit('draw:add', feature)
|
|
29
|
+
return result
|
|
21
30
|
}
|
|
@@ -35,7 +35,9 @@ export function attachEvents ({ pluginState, mapProvider, events, eventBus, butt
|
|
|
35
35
|
graphic.geometry.rings,
|
|
36
36
|
mapColorScheme
|
|
37
37
|
)
|
|
38
|
-
|
|
38
|
+
if (newGraphic) {
|
|
39
|
+
graphic.symbol = newGraphic.symbol
|
|
40
|
+
}
|
|
39
41
|
|
|
40
42
|
if (activeGraphicId === graphic.attributes.id) {
|
|
41
43
|
activeGraphic = graphic
|
|
@@ -88,8 +90,9 @@ export function attachEvents ({ pluginState, mapProvider, events, eventBus, butt
|
|
|
88
90
|
}
|
|
89
91
|
|
|
90
92
|
// Prevent self-intersect
|
|
93
|
+
// TODO - refactor this when rings and/or multipolygons are supported
|
|
91
94
|
if (toolInfoType === 'reshape') {
|
|
92
|
-
const isSimple = simplifyOperator.isSimple(graphic.geometry)
|
|
95
|
+
const isSimple = simplifyOperator.isSimple(graphic.geometry) && graphic.geometry.rings.length === 1
|
|
93
96
|
if (!isSimple) {
|
|
94
97
|
sketchViewModel.undo()
|
|
95
98
|
}
|
|
@@ -157,7 +160,9 @@ export function attachEvents ({ pluginState, mapProvider, events, eventBus, butt
|
|
|
157
160
|
feature.geometry.coordinates,
|
|
158
161
|
mapColorScheme
|
|
159
162
|
)
|
|
160
|
-
|
|
163
|
+
if (graphic) {
|
|
164
|
+
sketchLayer.add(graphic)
|
|
165
|
+
}
|
|
161
166
|
}
|
|
162
167
|
|
|
163
168
|
// Prevent selection
|
|
@@ -5,6 +5,8 @@ import * as graphicJs from './graphic.js'
|
|
|
5
5
|
jest.mock('./graphic.js')
|
|
6
6
|
const createGraphic = jest.spyOn(graphicJs, 'createGraphic')
|
|
7
7
|
const createSymbol = jest.spyOn(graphicJs, 'createSymbol')
|
|
8
|
+
const simplifyGraphic = jest.spyOn(graphicJs, 'createGraphic')
|
|
9
|
+
simplifyGraphic.mockImplementation((graphic, options) => graphic)
|
|
8
10
|
// const graphicToGeoJSON = jest.spyOn(graphicJs, 'graphicToGeoJSON')
|
|
9
11
|
|
|
10
12
|
const dispatch = jest.fn()
|
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
import Graphic from '@arcgis/core/Graphic.js'
|
|
2
|
+
import * as simplifyOperator from '@arcgis/core/geometry/operators/simplifyOperator.js'
|
|
3
|
+
import { logger } from '../../../../src/services/logger.js'
|
|
2
4
|
|
|
3
5
|
function createSymbol (mapColorScheme) {
|
|
4
6
|
return {
|
|
@@ -11,8 +13,26 @@ function createSymbol (mapColorScheme) {
|
|
|
11
13
|
}
|
|
12
14
|
}
|
|
13
15
|
|
|
14
|
-
|
|
15
|
-
|
|
16
|
+
// TODO - add support for multipolygons and polygons with holes
|
|
17
|
+
const simplifyGraphic = (graphic, { simplify = true, allowHoles = false }) => {
|
|
18
|
+
if (simplify && !simplifyOperator.isSimple(graphic.geometry)) {
|
|
19
|
+
logger.warn('Feature geometry is not simple, attempting to simplify')
|
|
20
|
+
graphic.geometry = simplifyOperator.execute(graphic.geometry)
|
|
21
|
+
if (!simplifyOperator.isSimple(graphic.geometry)) {
|
|
22
|
+
logger.error('Failed to simplify geometry, cannot add feature')
|
|
23
|
+
return null
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
if (allowHoles === false && graphic?.geometry.rings.length > 1) {
|
|
27
|
+
logger.error('Feature contains multiple polygons, which are not supported.')
|
|
28
|
+
return null
|
|
29
|
+
}
|
|
30
|
+
return graphic
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
function createGraphic (id, coordinates, mapColorScheme, simplifyOptions = {}) {
|
|
34
|
+
const { simplify = true, allowHoles = false } = simplifyOptions
|
|
35
|
+
const graphic = new Graphic({
|
|
16
36
|
geometry: {
|
|
17
37
|
type: 'polygon',
|
|
18
38
|
rings: coordinates,
|
|
@@ -23,6 +43,10 @@ function createGraphic (id, coordinates, mapColorScheme) {
|
|
|
23
43
|
},
|
|
24
44
|
symbol: createSymbol(mapColorScheme)
|
|
25
45
|
})
|
|
46
|
+
if (simplify || allowHoles === false) {
|
|
47
|
+
return simplifyGraphic(graphic, simplifyOptions)
|
|
48
|
+
}
|
|
49
|
+
return graphic
|
|
26
50
|
}
|
|
27
51
|
|
|
28
52
|
function graphicToGeoJSON (graphic) {
|