@defra/interactive-map 0.0.30-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/css/index.css +1 -1
- 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/context.md +4 -4
- package/docs/api.md +166 -37
- package/docs/assets/css/docusaurus.scss +36 -4
- package/docs/assets/images/add-polygons.jpg +0 -0
- package/docs/assets/images/add-symbols.jpg +0 -0
- package/docs/assets/images/basic-map.jpg +0 -0
- package/docs/assets/images/button-first.jpg +0 -0
- package/docs/assets/images/deuteranopia-ozs-map-thumb.jpg +0 -0
- package/docs/assets/images/draw.jpg +0 -0
- package/docs/assets/images/marker-panel.jpg +0 -0
- package/docs/assets/images/night-ozs-map-thumb.jpg +0 -0
- package/docs/assets/images/outdoor-ozs-map-thumb.jpg +0 -0
- package/docs/assets/images/place-marker.jpg +0 -0
- package/docs/assets/images/screenshot.jpg +0 -0
- package/docs/assets/images/search.jpg +0 -0
- package/docs/assets/images/select-feature.jpg +0 -0
- package/docs/assets/images/style-switcher.jpg +0 -0
- package/docs/assets/images/toggle-marker-label.jpg +0 -0
- package/docs/assets/images/tritanopia-ozs-map-thumb.jpg +0 -0
- package/docs/examples/add-marker-with-panel.mdx +3 -3
- package/docs/examples/add-polygons.mdx +225 -0
- package/docs/examples/add-symbols.mdx +177 -0
- package/docs/examples/basic-map.mdx +2 -2
- package/docs/examples/draw-tools.mdx +271 -0
- package/docs/examples/index.mdx +95 -11
- package/docs/examples/place-marker.mdx +151 -0
- package/docs/examples/search-control.mdx +71 -0
- package/docs/examples/select-feature.mdx +146 -0
- package/docs/examples/style-switcher.mdx +135 -0
- package/docs/examples/toggle-marker-label.mdx +3 -3
- package/docs/plugins/datasets.md +157 -122
- package/docs/plugins/interact.md +1 -4
- package/docusaurus.config.cjs +9 -2
- package/govuk-prototype-kit.config.json +52 -2
- package/package.json +1 -1
- package/plugins/beta/datasets/dist/css/index.css +5 -2
- package/plugins/beta/datasets/dist/esm/im-datasets-ml-adapter.js +1 -0
- package/plugins/beta/datasets/dist/esm/im-datasets-plugin.js +1 -1
- package/plugins/beta/datasets/dist/esm/index.js +1 -1
- package/plugins/beta/datasets/dist/umd/im-datasets-ml-adapter.js +2 -0
- package/plugins/beta/datasets/dist/umd/im-datasets-plugin.js +2 -0
- package/plugins/beta/datasets/dist/umd/index.js +2 -0
- package/plugins/beta/datasets/src/adapters/loadLayerAdapter.js +33 -0
- package/plugins/beta/datasets/src/adapters/maplibre/layerBuilders.js +44 -120
- package/plugins/beta/datasets/src/adapters/maplibre/maplibreLayerAdapter.js +145 -245
- package/plugins/beta/datasets/src/adapters/maplibre/maplibreLayerAdapter.test.js +516 -0
- package/plugins/beta/datasets/src/adapters/maplibre/registry/mapLibreDataset.js +209 -0
- package/plugins/beta/datasets/src/adapters/maplibre/registry/mapLibreDataset.test.js +483 -0
- package/plugins/beta/datasets/src/api/addDataset.js +2 -5
- package/plugins/beta/datasets/src/api/addDataset.test.js +16 -0
- package/plugins/beta/datasets/src/api/getOpacity.js +14 -14
- package/plugins/beta/datasets/src/api/getOpacity.test.js +72 -0
- package/plugins/beta/datasets/src/api/getStyle.js +8 -9
- package/plugins/beta/datasets/src/api/getStyle.test.js +42 -0
- package/plugins/beta/datasets/src/api/removeDataset.js +7 -7
- package/plugins/beta/datasets/src/api/removeDataset.test.js +45 -0
- package/plugins/beta/datasets/src/api/setData.js +9 -3
- package/plugins/beta/datasets/src/api/setData.test.js +62 -0
- package/plugins/beta/datasets/src/api/setDatasetVisibility.js +5 -30
- package/plugins/beta/datasets/src/api/setDatasetVisibility.test.js +31 -0
- package/plugins/beta/datasets/src/api/setFeatureVisibility.js +9 -18
- package/plugins/beta/datasets/src/api/setFeatureVisibility.test.js +74 -0
- package/plugins/beta/datasets/src/api/setGlobals.js +20 -0
- package/plugins/beta/datasets/src/api/setGlobals.test.js +63 -0
- package/plugins/beta/datasets/src/api/setOpacity.js +8 -27
- package/plugins/beta/datasets/src/api/setOpacity.test.js +31 -0
- package/plugins/beta/datasets/src/api/setStyle.js +5 -21
- package/plugins/beta/datasets/src/api/setStyle.test.js +53 -0
- package/plugins/beta/datasets/src/components/Key/Key.jsx +51 -0
- package/plugins/beta/datasets/src/components/Key/KeyGroupItem.jsx +18 -0
- package/plugins/beta/datasets/src/components/Key/KeyItem.jsx +20 -0
- package/plugins/beta/datasets/src/components/Key/KeySvg.jsx +22 -0
- package/plugins/beta/datasets/src/components/Key/KeySvg.test.jsx +87 -0
- package/plugins/beta/datasets/src/components/Key/KeySvgLine.jsx +19 -0
- package/plugins/beta/datasets/src/components/Key/KeySvgLine.test.jsx +71 -0
- package/plugins/beta/datasets/src/components/{KeySvgPattern.jsx → Key/KeySvgPattern.jsx} +3 -4
- package/plugins/beta/datasets/src/components/Key/KeySvgPattern.test.jsx +55 -0
- package/plugins/beta/datasets/src/components/Key/KeySvgRect.jsx +22 -0
- package/plugins/beta/datasets/src/components/Key/KeySvgRect.test.jsx +85 -0
- package/plugins/beta/datasets/src/components/{KeySvgSymbol.jsx → Key/KeySvgSymbol.jsx} +5 -5
- package/plugins/beta/datasets/src/components/Key/KeySvgSymbol.test.jsx +80 -0
- package/plugins/beta/datasets/src/components/Key/svgProperties.test.js +61 -0
- package/plugins/beta/datasets/src/{panels → components/LayersMenu}/Layers.module.scss +15 -11
- package/plugins/beta/datasets/src/components/LayersMenu/LayersMenu.jsx +33 -0
- package/plugins/beta/datasets/src/components/LayersMenu/LayersMenuCheckbox.jsx +31 -0
- package/plugins/beta/datasets/src/components/LayersMenu/LayersMenuGroupWrapper.jsx +19 -0
- package/plugins/beta/datasets/src/datasets.scss +2 -2
- package/plugins/beta/datasets/src/fetch/createDynamicSource.js +8 -8
- package/plugins/beta/datasets/src/{DatasetsInit.jsx → initialise/DatasetsInit.jsx} +19 -21
- package/plugins/beta/datasets/src/{defaults.js → initialise/defaults.js} +17 -2
- package/plugins/beta/datasets/src/initialise/defaults.test.js +127 -0
- package/plugins/beta/datasets/src/{datasets.js → initialise/initialiseDatasets.js} +30 -26
- package/plugins/beta/datasets/src/initialise/initialiseDatasets.test.js +273 -0
- package/plugins/beta/datasets/src/manifest.js +8 -6
- package/plugins/beta/datasets/src/reducers/__data__/demoDatasets.js +253 -0
- package/plugins/beta/datasets/src/reducers/datasetsToMenu.js +83 -0
- package/plugins/beta/datasets/src/reducers/datasetsToMenu.test.js +84 -0
- package/plugins/beta/datasets/src/reducers/mappedDatasetsReducer.js +41 -0
- package/plugins/beta/datasets/src/reducers/mappedDatasetsReducer.test.js +117 -0
- package/plugins/beta/datasets/src/reducers/pluginState.js +206 -0
- package/plugins/beta/datasets/src/reducers/pluginState.test.js +386 -0
- package/plugins/beta/datasets/src/registry/__mocks__/datasetRegistry.js +29 -0
- package/plugins/beta/datasets/src/registry/createDataset.js +5 -0
- package/plugins/beta/datasets/src/registry/dataset.js +176 -0
- package/plugins/beta/datasets/src/registry/dataset.test.js +497 -0
- package/plugins/beta/datasets/src/registry/datasetDefinitionCache.js +35 -0
- package/plugins/beta/datasets/src/registry/datasetRegistry.js +116 -0
- package/plugins/beta/datasets/src/registry/datasetRegistry.test.js +335 -0
- package/plugins/beta/datasets/src/registry/dynamicGeoJson.js +17 -0
- package/plugins/beta/datasets/src/registry/globalDataset.js +36 -0
- 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/events.js +13 -1
- package/plugins/beta/draw-ml/src/index.js +1 -1
- package/plugins/beta/draw-ml/src/manifest.js +3 -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 +3 -5
- package/plugins/interact/src/InteractInit.test.js +1 -3
- package/plugins/interact/src/events.js +2 -29
- package/plugins/interact/src/events.test.js +4 -102
- package/plugins/interact/src/hooks/useAttachEvents.js +3 -4
- package/plugins/interact/src/hooks/useAttachEvents.test.js +1 -3
- 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 +15 -12
- package/plugins/interact/src/hooks/useInteractionHandlers.test.js +28 -29
- package/plugins/interact/src/manifest.js +0 -35
- package/plugins/interact/src/manifest.test.js +3 -43
- 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/providers/beta/esri/dist/esm/im-esri-provider.js +1 -1
- package/providers/beta/esri/src/esriProvider.js +4 -0
- package/providers/beta/openlayers/dist/esm/im-openlayers-provider.js +1 -1
- package/providers/beta/openlayers/dist/umd/im-openlayers-provider.js +1 -1
- package/providers/beta/openlayers/src/openlayersProvider.js +4 -0
- package/providers/beta/openlayers/src/openlayersProvider.test.js +5 -0
- package/providers/maplibre/dist/esm/im-maplibre-provider.js +1 -1
- package/providers/maplibre/dist/umd/im-maplibre-provider.js +1 -1
- package/providers/maplibre/src/maplibreProvider.js +6 -4
- package/providers/maplibre/src/maplibreProvider.test.js +5 -0
- package/providers/maplibre/src/utils/highlightFeatures.js +74 -25
- package/providers/maplibre/src/utils/highlightFeatures.test.js +132 -0
- package/providers/maplibre/src/utils/patternImages.js +2 -4
- package/providers/maplibre/src/utils/symbolImages.js +1 -4
- package/rollup.esm.mjs +2 -8
- package/src/App/components/CrossHair/CrossHair.module.scss +8 -8
- package/src/App/components/MapButton/MapButton.jsx +16 -1
- package/src/App/components/MapButton/MapButton.module.scss +12 -1
- package/src/App/components/MapButton/MapButton.test.jsx +40 -1
- package/src/App/hooks/useContinueEnabledEvaluator.js +31 -0
- package/src/App/hooks/useContinueEnabledEvaluator.test.js +118 -0
- package/src/App/hooks/useEvaluateProp.js +15 -15
- package/src/App/hooks/useEvaluateProp.test.js +80 -76
- package/src/App/hooks/useLayoutMeasurements.js +11 -5
- package/src/App/hooks/useResizeObserver.js +15 -2
- package/src/App/hooks/useResizeObserver.test.js +1 -0
- package/src/App/renderer/PluginInits.jsx +2 -0
- package/src/App/renderer/mapButtons.js +21 -1
- package/src/App/renderer/mapButtons.test.js +46 -1
- package/src/App/store/appReducer.js +1 -1
- package/src/App/store/appReducer.test.js +37 -0
- package/src/InteractiveMap/InteractiveMap.js +14 -4
- package/src/InteractiveMap/InteractiveMap.test.js +11 -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/appConfig.js +25 -0
- package/src/config/appConfig.test.js +50 -0
- package/src/config/defaults.js +1 -0
- package/src/config/events.js +21 -3
- package/src/scss/settings/_dimensions.scss +1 -0
- package/src/services/patternRegistry.js +8 -4
- package/src/types.js +7 -0
- package/src/utils/patternUtils.js +1 -2
- package/src/utils/patternUtils.test.js +9 -0
- package/webpack.dev.mjs +10 -0
- package/webpack.umd.mjs +1 -1
- package/docs/assets/images/screens-blue.jpg +0 -0
- package/docs/assets/images/screens-white.jpg +0 -0
- package/plugins/beta/datasets/dist/adapters/maplibre/esm/im-datasets-ml-adapter.js +0 -1
- package/plugins/beta/datasets/dist/adapters/maplibre/esm/index.js +0 -1
- package/plugins/beta/datasets/dist/umd/maplibre/im-datasets-maplibre-adapter.js +0 -2
- package/plugins/beta/datasets/dist/umd/maplibre/im-datasets-plugin.js +0 -2
- package/plugins/beta/datasets/dist/umd/maplibre/index.js +0 -2
- package/plugins/beta/datasets/src/adapters/maplibre/index.js +0 -18
- package/plugins/beta/datasets/src/adapters/maplibre/layerIds.js +0 -75
- package/plugins/beta/datasets/src/adapters/maplibre/patternImages.js +0 -27
- package/plugins/beta/datasets/src/adapters/maplibre/symbolImages.js +0 -31
- package/plugins/beta/datasets/src/components/KeySvg.jsx +0 -24
- package/plugins/beta/datasets/src/components/KeySvgLine.jsx +0 -19
- package/plugins/beta/datasets/src/components/KeySvgRect.jsx +0 -22
- package/plugins/beta/datasets/src/index.maplibre.umd.js +0 -23
- package/plugins/beta/datasets/src/panels/Key.jsx +0 -62
- package/plugins/beta/datasets/src/panels/Layers.jsx +0 -141
- package/plugins/beta/datasets/src/reducer.js +0 -219
- package/plugins/beta/datasets/src/reducers/keyReducer.js +0 -34
- package/plugins/beta/datasets/src/utils/filters.js +0 -34
- package/plugins/beta/datasets/src/utils/mergeSublayer.js +0 -86
- package/plugins/beta/draw-ml/dist/css/index.css +0 -21
- /package/plugins/beta/datasets/dist/umd/{maplibre/im-datasets-maplibre-adapter.js.LICENSE.txt → im-datasets-ml-adapter.js.LICENSE.txt} +0 -0
- /package/plugins/beta/datasets/dist/umd/{maplibre/im-datasets-plugin.js.LICENSE.txt → im-datasets-plugin.js.LICENSE.txt} +0 -0
- /package/plugins/beta/datasets/dist/umd/{maplibre/index.js.LICENSE.txt → index.js.LICENSE.txt} +0 -0
- /package/plugins/beta/datasets/src/components/{EmptyKey.jsx → Key/EmptyKey.jsx} +0 -0
- /package/plugins/beta/datasets/src/components/{EmptyKey.test.jsx → Key/EmptyKey.test.jsx} +0 -0
- /package/plugins/beta/datasets/src/{panels → components/Key}/Key.module.scss +0 -0
- /package/plugins/beta/datasets/src/components/{svgProperties.js → Key/svgProperties.js} +0 -0
|
@@ -0,0 +1,335 @@
|
|
|
1
|
+
import { Dataset } from './dataset.js'
|
|
2
|
+
import { datasetRegistry } from './datasetRegistry.js'
|
|
3
|
+
import { mappedDatasetsReducer } from '../reducers/mappedDatasetsReducer.js'
|
|
4
|
+
import { datasetsWithGroups } from '../reducers/__data__/demoDatasets.js'
|
|
5
|
+
// Use the mock datasetRegistry with the demo datasets attached before each test.
|
|
6
|
+
// Dataset must be imported before datasetRegistry so that dataset.js is cached before
|
|
7
|
+
// the mock initialization triggers requireActual, avoiding a circular re-entry that
|
|
8
|
+
// would leave datasetRegistry undefined inside the mock.
|
|
9
|
+
jest.mock('./datasetRegistry.js')
|
|
10
|
+
|
|
11
|
+
describe('datasetRegistry', () => {
|
|
12
|
+
beforeEach(() => {
|
|
13
|
+
jest.clearAllMocks()
|
|
14
|
+
datasetRegistry._invalidateCache()
|
|
15
|
+
})
|
|
16
|
+
describe('attach', () => {
|
|
17
|
+
it("doesn't throw when no datasets are attached", () => {
|
|
18
|
+
expect(() => datasetRegistry.attach(undefined)).not.toThrow()
|
|
19
|
+
})
|
|
20
|
+
})
|
|
21
|
+
|
|
22
|
+
describe('getDataset', () => {
|
|
23
|
+
it('returns a Dataset instance for a known id', () => {
|
|
24
|
+
const dataset = datasetRegistry.getDataset('land-covers')
|
|
25
|
+
expect(dataset).toBeInstanceOf(Dataset)
|
|
26
|
+
})
|
|
27
|
+
|
|
28
|
+
it('returns the correct id', () => {
|
|
29
|
+
const dataset = datasetRegistry.getDataset('existing-fields')
|
|
30
|
+
expect(dataset.id).toBe('existing-fields')
|
|
31
|
+
})
|
|
32
|
+
|
|
33
|
+
it('returns a Dataset instance for a sublayer id', () => {
|
|
34
|
+
const dataset = datasetRegistry.getDataset('land-covers-130-131')
|
|
35
|
+
expect(dataset).toBeInstanceOf(Dataset)
|
|
36
|
+
expect(dataset.id).toBe('land-covers-130-131')
|
|
37
|
+
})
|
|
38
|
+
|
|
39
|
+
it('returns undefined for an unknown id', () => {
|
|
40
|
+
expect(datasetRegistry.getDataset('non-existent')).toBeUndefined()
|
|
41
|
+
})
|
|
42
|
+
})
|
|
43
|
+
|
|
44
|
+
describe('forEach', () => {
|
|
45
|
+
it('calls the callback once per dataset in orderedDatasets order', () => {
|
|
46
|
+
const ids = []
|
|
47
|
+
datasetRegistry.forEach(dataset => ids.push(dataset.id))
|
|
48
|
+
expect(ids).toEqual(datasetRegistry._orderedDatasets)
|
|
49
|
+
})
|
|
50
|
+
|
|
51
|
+
it('passes Dataset instances to the callback', () => {
|
|
52
|
+
datasetRegistry.forEach(dataset => expect(dataset).toBeInstanceOf(Dataset))
|
|
53
|
+
})
|
|
54
|
+
})
|
|
55
|
+
|
|
56
|
+
describe('forEachDataset', () => {
|
|
57
|
+
it('calls the callback only for top-level datasets', () => {
|
|
58
|
+
const ids = []
|
|
59
|
+
datasetRegistry.forEachDataset(dataset => ids.push(dataset.id))
|
|
60
|
+
expect(ids).toEqual(['land-covers', 'existing-fields', 'historic-monuments', 'hedge-control'])
|
|
61
|
+
})
|
|
62
|
+
|
|
63
|
+
it('does not include sublayers', () => {
|
|
64
|
+
const ids = []
|
|
65
|
+
datasetRegistry.forEachDataset(dataset => ids.push(dataset.id))
|
|
66
|
+
expect(ids).not.toContain('land-covers-130-131')
|
|
67
|
+
})
|
|
68
|
+
|
|
69
|
+
it('passes Dataset instances to the callback', () => {
|
|
70
|
+
datasetRegistry.forEachDataset(dataset => expect(dataset).toBeInstanceOf(Dataset))
|
|
71
|
+
})
|
|
72
|
+
})
|
|
73
|
+
|
|
74
|
+
describe('topLevelDatasets', () => {
|
|
75
|
+
it('returns only top-level dataset ids', () => {
|
|
76
|
+
const ids = datasetRegistry.topLevelDatasets().map(d => d.id)
|
|
77
|
+
expect(ids).toEqual(['land-covers', 'existing-fields', 'historic-monuments', 'hedge-control'])
|
|
78
|
+
})
|
|
79
|
+
|
|
80
|
+
it('does not include sublayers', () => {
|
|
81
|
+
const ids = datasetRegistry.topLevelDatasets().map(d => d.id)
|
|
82
|
+
expect(ids).not.toContain('land-covers-130-131')
|
|
83
|
+
})
|
|
84
|
+
|
|
85
|
+
it('returns Dataset instances', () => {
|
|
86
|
+
datasetRegistry.topLevelDatasets().forEach(d => expect(d).toBeInstanceOf(Dataset))
|
|
87
|
+
})
|
|
88
|
+
})
|
|
89
|
+
|
|
90
|
+
describe('getPatternAndSymbolConfigs', () => {
|
|
91
|
+
it('returns an object with patternConfigs and symbolConfigs arrays', () => {
|
|
92
|
+
const result = datasetRegistry.getPatternAndSymbolConfigs()
|
|
93
|
+
expect(Array.isArray(result.patternConfigs)).toBe(true)
|
|
94
|
+
expect(Array.isArray(result.symbolConfigs)).toBe(true)
|
|
95
|
+
})
|
|
96
|
+
|
|
97
|
+
it('collects fill pattern configs from sublayers', () => {
|
|
98
|
+
const { patternConfigs } = datasetRegistry.getPatternAndSymbolConfigs()
|
|
99
|
+
// land-covers sublayers each have a fillPattern style
|
|
100
|
+
expect(patternConfigs.length).toBeGreaterThan(0)
|
|
101
|
+
})
|
|
102
|
+
|
|
103
|
+
it('collects symbol configs from sublayers', () => {
|
|
104
|
+
const { symbolConfigs } = datasetRegistry.getPatternAndSymbolConfigs()
|
|
105
|
+
// historic-monuments sublayers inherit symbol: 'square' from their parent
|
|
106
|
+
expect(symbolConfigs.length).toBeGreaterThan(0)
|
|
107
|
+
})
|
|
108
|
+
|
|
109
|
+
it('returns empty arrays when no datasets have patterns or symbols', () => {
|
|
110
|
+
datasetRegistry.attach({ simple: { id: 'simple', style: { stroke: '#ff0000' } } })
|
|
111
|
+
const { patternConfigs, symbolConfigs } = datasetRegistry.getPatternAndSymbolConfigs()
|
|
112
|
+
expect(patternConfigs).toHaveLength(0)
|
|
113
|
+
expect(symbolConfigs).toHaveLength(0)
|
|
114
|
+
})
|
|
115
|
+
})
|
|
116
|
+
|
|
117
|
+
describe('keyItems', () => {
|
|
118
|
+
it('returns an object with an items array and hasGroups boolean', () => {
|
|
119
|
+
const { items, hasGroups } = datasetRegistry.keyItems()
|
|
120
|
+
expect(Array.isArray(items)).toBe(true)
|
|
121
|
+
expect(typeof hasGroups).toBe('boolean')
|
|
122
|
+
})
|
|
123
|
+
|
|
124
|
+
it('includes a sublayers entry for each dataset that has sublayers', () => {
|
|
125
|
+
const { items } = datasetRegistry.keyItems()
|
|
126
|
+
const sublayerItems = items.filter(item => item.type === 'sublayers')
|
|
127
|
+
expect(sublayerItems).toHaveLength(2) // land-covers and historic-monuments
|
|
128
|
+
})
|
|
129
|
+
|
|
130
|
+
it('includes a flat entry for datasets without sublayers and no groupLabel', () => {
|
|
131
|
+
const { items } = datasetRegistry.keyItems()
|
|
132
|
+
const flatItems = items.filter(item => item.type === 'flat')
|
|
133
|
+
expect(flatItems).toHaveLength(1) // existing-fields
|
|
134
|
+
})
|
|
135
|
+
|
|
136
|
+
it('sets hasGroups to true when any item has sublayers', () => {
|
|
137
|
+
const { hasGroups } = datasetRegistry.keyItems()
|
|
138
|
+
expect(hasGroups).toBe(true)
|
|
139
|
+
})
|
|
140
|
+
|
|
141
|
+
it('sets hasGroups to false when all items are flat with no groupLabel', () => {
|
|
142
|
+
datasetRegistry.attach({ simple: { id: 'simple', showInKey: true, visible: true, style: {} } })
|
|
143
|
+
const { hasGroups } = datasetRegistry.keyItems()
|
|
144
|
+
expect(hasGroups).toBe(false)
|
|
145
|
+
})
|
|
146
|
+
|
|
147
|
+
it('sets hasGroups to false when a dataset has only one sublayer and it is not visible', () => {
|
|
148
|
+
const { mappedDatasets: singleHiddenSublayer } = mappedDatasetsReducer({
|
|
149
|
+
datasets: [{
|
|
150
|
+
id: 'single-sublayer-dataset',
|
|
151
|
+
showInKey: true,
|
|
152
|
+
visible: true,
|
|
153
|
+
style: {},
|
|
154
|
+
sublayers: [{ id: 'sub', visible: false, style: {} }]
|
|
155
|
+
}]
|
|
156
|
+
})
|
|
157
|
+
datasetRegistry.attach(singleHiddenSublayer)
|
|
158
|
+
const { hasGroups } = datasetRegistry.keyItems()
|
|
159
|
+
expect(hasGroups).toBe(false)
|
|
160
|
+
})
|
|
161
|
+
|
|
162
|
+
it('only includes visible sublayers in sublayers items', () => {
|
|
163
|
+
const { items } = datasetRegistry.keyItems()
|
|
164
|
+
const landCoversItem = items.find(item => item.type === 'sublayers' && item.dataset.id === 'land-covers')
|
|
165
|
+
const sublayerIds = landCoversItem.sublayers.map(s => s.id)
|
|
166
|
+
expect(sublayerIds).not.toContain('land-covers-379') // land-covers-379 has visible: false
|
|
167
|
+
})
|
|
168
|
+
|
|
169
|
+
it('includes a group entry for datasets sharing a groupLabel', () => {
|
|
170
|
+
const { mappedDatasets: grouped } = mappedDatasetsReducer({ datasets: datasetsWithGroups })
|
|
171
|
+
datasetRegistry.attach(grouped)
|
|
172
|
+
const { items } = datasetRegistry.keyItems()
|
|
173
|
+
const groupItems = items.filter(item => item.type === 'group')
|
|
174
|
+
expect(groupItems).toHaveLength(1)
|
|
175
|
+
expect(groupItems[0].groupLabel).toBe('Test group')
|
|
176
|
+
})
|
|
177
|
+
|
|
178
|
+
it('only adds one group entry per unique groupLabel', () => {
|
|
179
|
+
const { mappedDatasets: grouped } = mappedDatasetsReducer({ datasets: datasetsWithGroups })
|
|
180
|
+
datasetRegistry.attach(grouped)
|
|
181
|
+
const { items } = datasetRegistry.keyItems()
|
|
182
|
+
const groupLabels = items.filter(i => i.type === 'group').map(i => i.groupLabel)
|
|
183
|
+
expect(groupLabels.length).toBe(new Set(groupLabels).size)
|
|
184
|
+
})
|
|
185
|
+
|
|
186
|
+
it('populates group item datasets with matching showInKey datasets', () => {
|
|
187
|
+
const { mappedDatasets: grouped } = mappedDatasetsReducer({ datasets: datasetsWithGroups })
|
|
188
|
+
datasetRegistry.attach(grouped)
|
|
189
|
+
const { items } = datasetRegistry.keyItems()
|
|
190
|
+
const groupItem = items.find(item => item.type === 'group' && item.groupLabel === 'Test group')
|
|
191
|
+
const ids = groupItem.datasets.map(d => d.id)
|
|
192
|
+
expect(ids).toContain('existing-fields')
|
|
193
|
+
expect(ids).toContain('hedge-control')
|
|
194
|
+
})
|
|
195
|
+
|
|
196
|
+
it('caches the result when datasets ref has not changed', () => {
|
|
197
|
+
const result1 = datasetRegistry.keyItems()
|
|
198
|
+
const result2 = datasetRegistry.keyItems()
|
|
199
|
+
expect(result1).toBe(result2)
|
|
200
|
+
})
|
|
201
|
+
|
|
202
|
+
it('recomputes when the datasets ref changes', () => {
|
|
203
|
+
const result1 = datasetRegistry.keyItems()
|
|
204
|
+
datasetRegistry.attach({ simple: { id: 'simple', showInKey: true, visible: true, style: {} } })
|
|
205
|
+
const result2 = datasetRegistry.keyItems()
|
|
206
|
+
expect(result1).not.toBe(result2)
|
|
207
|
+
})
|
|
208
|
+
})
|
|
209
|
+
|
|
210
|
+
describe('attachCreateDataset', () => {
|
|
211
|
+
let originalCreateDataset
|
|
212
|
+
|
|
213
|
+
beforeEach(() => {
|
|
214
|
+
originalCreateDataset = datasetRegistry._createDataset
|
|
215
|
+
})
|
|
216
|
+
|
|
217
|
+
afterEach(() => {
|
|
218
|
+
datasetRegistry._createDataset = originalCreateDataset
|
|
219
|
+
})
|
|
220
|
+
|
|
221
|
+
it('overrides the factory used by getDataset', () => {
|
|
222
|
+
const customFactory = jest.fn((def) => new Dataset(def))
|
|
223
|
+
datasetRegistry.attachCreateDataset(customFactory)
|
|
224
|
+
datasetRegistry.getDataset('land-covers')
|
|
225
|
+
expect(customFactory).toHaveBeenCalled()
|
|
226
|
+
})
|
|
227
|
+
|
|
228
|
+
it('uses the return value of the custom factory', () => {
|
|
229
|
+
const sentinel = { id: 'sentinel' }
|
|
230
|
+
datasetRegistry.attachCreateDataset(() => sentinel)
|
|
231
|
+
const result = datasetRegistry.getDataset('land-covers')
|
|
232
|
+
expect(result).toBe(sentinel)
|
|
233
|
+
})
|
|
234
|
+
})
|
|
235
|
+
|
|
236
|
+
describe('avoid recreating Dataset instances', () => {
|
|
237
|
+
// Because the registryDataset instances are pure and immutable wrappers
|
|
238
|
+
// around the dataset definition, we can return the same registryDataset
|
|
239
|
+
// instances as long as the definitions are the same.
|
|
240
|
+
// Avoiding unnecessary re-calculation of registryDataset instance members
|
|
241
|
+
// like patternConfigs and symbolConfigs which are derived from the definition.
|
|
242
|
+
const createDatasetSpy = jest.spyOn(datasetRegistry, '_createDataset')
|
|
243
|
+
|
|
244
|
+
it("doesn't throw invalidating before caching anything", () => {
|
|
245
|
+
expect(() => {
|
|
246
|
+
datasetRegistry.attach({
|
|
247
|
+
...datasetRegistry.datasets,
|
|
248
|
+
'land-covers-130-131': { id: 'land-covers-130-131', style: { stroke: '#00ff00' } }
|
|
249
|
+
})
|
|
250
|
+
}).not.toThrow()
|
|
251
|
+
})
|
|
252
|
+
|
|
253
|
+
it("doesn't throw if a sublayer without a valid parent is attached", () => {
|
|
254
|
+
expect(() => {
|
|
255
|
+
datasetRegistry.attach({
|
|
256
|
+
...datasetRegistry.datasets,
|
|
257
|
+
'no-parent': { id: 'no-parent', parentId: 'no-exists', style: {} }
|
|
258
|
+
|
|
259
|
+
})
|
|
260
|
+
datasetRegistry.getDataset('no-parent')
|
|
261
|
+
datasetRegistry.attach({
|
|
262
|
+
...datasetRegistry.datasets,
|
|
263
|
+
'no-parent': { id: 'no-parent', parentId: 'no-exists', style: {} }
|
|
264
|
+
})
|
|
265
|
+
}).not.toThrow()
|
|
266
|
+
})
|
|
267
|
+
|
|
268
|
+
it('returns the same Dataset instance for the same dataset definition', () => {
|
|
269
|
+
expect(datasetRegistry.getDataset('land-covers'))
|
|
270
|
+
.toBe(datasetRegistry.getDataset('land-covers'))
|
|
271
|
+
expect(createDatasetSpy).toHaveBeenCalledTimes(1)
|
|
272
|
+
})
|
|
273
|
+
|
|
274
|
+
it('removes cached Dataset instances when new datasets definition are attached', () => {
|
|
275
|
+
const landCovers1 = datasetRegistry.getDataset('land-covers') // createDatasetSpy called once
|
|
276
|
+
const landCovers1Definition = landCovers1._datasetDefinition
|
|
277
|
+
// attach new definitions, with a different land-covers definition
|
|
278
|
+
datasetRegistry.attach({ ...datasetRegistry.datasets, 'land-covers': { id: 'land-covers', style: {} } })
|
|
279
|
+
|
|
280
|
+
expect(datasetRegistry.getDataset('land-covers')).not.toBe(landCovers1) // should be different as the definition has changed
|
|
281
|
+
expect(createDatasetSpy).toHaveBeenCalledTimes(2)
|
|
282
|
+
// ensure the old definition is no longer cached - which could cause a memory leak
|
|
283
|
+
expect(datasetRegistry._definitionCache.getByDefinition(landCovers1Definition)).toBeUndefined()
|
|
284
|
+
})
|
|
285
|
+
|
|
286
|
+
it('should invalidate the cache of sublayers(children) when a parent dataset definition is updated', () => {
|
|
287
|
+
const landCovers = datasetRegistry.getDataset('land-covers')
|
|
288
|
+
const landCoversSublayer = datasetRegistry.getDataset('land-covers-130-131')
|
|
289
|
+
expect(createDatasetSpy).toHaveBeenCalledTimes(2)
|
|
290
|
+
const landCoversDefinition = landCovers._datasetDefinition
|
|
291
|
+
|
|
292
|
+
// Update the parent dataset definition, which should invalidate both the parent and sublayer cache entries
|
|
293
|
+
const newLandCoversDefinition = { ...landCoversDefinition, style: { stroke: '#00ff00' } }
|
|
294
|
+
datasetRegistry.attach({ ...datasetRegistry.datasets, 'land-covers': newLandCoversDefinition })
|
|
295
|
+
|
|
296
|
+
expect(datasetRegistry.getDataset('land-covers')).not.toBe(landCovers)
|
|
297
|
+
expect(datasetRegistry.getDataset('land-covers-130-131')).not.toBe(landCoversSublayer)
|
|
298
|
+
expect(createDatasetSpy).toHaveBeenCalledTimes(4)
|
|
299
|
+
})
|
|
300
|
+
|
|
301
|
+
it('should invalidate the cache of the parent and siblings when a sublayers dataset definition is updated', () => {
|
|
302
|
+
const landCovers = datasetRegistry.getDataset('land-covers')
|
|
303
|
+
const landCoversSublayer130 = datasetRegistry.getDataset('land-covers-130-131')
|
|
304
|
+
const landCoversSublayer332 = datasetRegistry.getDataset('land-covers-332')
|
|
305
|
+
expect(createDatasetSpy).toHaveBeenCalledTimes(3)
|
|
306
|
+
const sublayerDefinition = landCoversSublayer130._datasetDefinition
|
|
307
|
+
|
|
308
|
+
// Update the parent dataset definition, which should invalidate both the parent and sublayer cache entries
|
|
309
|
+
const newSublayerDefinition = { ...sublayerDefinition, style: { stroke: '#00ff00' } }
|
|
310
|
+
datasetRegistry.attach({ ...datasetRegistry.datasets, 'land-covers-130-131': newSublayerDefinition })
|
|
311
|
+
|
|
312
|
+
expect(datasetRegistry.getDataset('land-covers')).not.toBe(landCovers)
|
|
313
|
+
expect(datasetRegistry.getDataset('land-covers-130-131')).not.toBe(landCoversSublayer130)
|
|
314
|
+
expect(datasetRegistry.getDataset('land-covers-332')).not.toBe(landCoversSublayer332)
|
|
315
|
+
|
|
316
|
+
expect(createDatasetSpy).toHaveBeenCalledTimes(6)
|
|
317
|
+
})
|
|
318
|
+
|
|
319
|
+
it('should not invalidate the cache of different datasets when a definition is updated', () => {
|
|
320
|
+
const landCovers = datasetRegistry.getDataset('land-covers')
|
|
321
|
+
const existingFields = datasetRegistry.getDataset('existing-fields')
|
|
322
|
+
expect(createDatasetSpy).toHaveBeenCalledTimes(2)
|
|
323
|
+
const existingFieldsDefinition = existingFields._datasetDefinition
|
|
324
|
+
|
|
325
|
+
// Update existing-fields, which should not invalidate land-covers
|
|
326
|
+
const newExistingFieldsDefinition = { id: 'existing-fields', style: {} }
|
|
327
|
+
datasetRegistry.attach({ ...datasetRegistry.datasets, 'existing-fields': newExistingFieldsDefinition })
|
|
328
|
+
|
|
329
|
+
expect(datasetRegistry.getDataset('land-covers')).toBe(landCovers)
|
|
330
|
+
expect(datasetRegistry.getDataset('existing-fields')).not.toBe(existingFields)
|
|
331
|
+
expect(createDatasetSpy).toHaveBeenCalledTimes(3) // should have been called one more time
|
|
332
|
+
expect(datasetRegistry._definitionCache.getByDefinition(existingFieldsDefinition)).toBeUndefined() // old definition should no longer be cached
|
|
333
|
+
})
|
|
334
|
+
})
|
|
335
|
+
})
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
export class DynamicGeoJson {
|
|
2
|
+
constructor (dynamicGeoJSONDefinition) {
|
|
3
|
+
this.id = dynamicGeoJSONDefinition.id
|
|
4
|
+
this.url = dynamicGeoJSONDefinition.url
|
|
5
|
+
this.transformRequest = dynamicGeoJSONDefinition.transformRequest
|
|
6
|
+
this.maxFeatures = dynamicGeoJSONDefinition.maxFeatures
|
|
7
|
+
this.minZoom = dynamicGeoJSONDefinition.minZoom
|
|
8
|
+
this.idProperty = dynamicGeoJSONDefinition.idProperty
|
|
9
|
+
this.hiddenFeaturesIdExpression = ['to-string', ['get', this.idProperty]]
|
|
10
|
+
this.sourceId = `geojson-dynamic-${this.id}`
|
|
11
|
+
this.source = {
|
|
12
|
+
type: 'geojson',
|
|
13
|
+
data: { type: 'FeatureCollection', features: [] },
|
|
14
|
+
...(this.idProperty ? { promoteId: this.idProperty } : { generateId: true })
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
let globalState = {}
|
|
2
|
+
|
|
3
|
+
export const attachGlobalState = (globalStateRef) => {
|
|
4
|
+
globalState = globalStateRef
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
// TODO - remove this once testing finishes
|
|
8
|
+
window.getGlobalState = () => Object.freeze(globalState)
|
|
9
|
+
|
|
10
|
+
const calculateLocalOpacity = (opacityValue, parentOpacityValue) => {
|
|
11
|
+
if (opacityValue === undefined) {
|
|
12
|
+
if (parentOpacityValue === undefined) {
|
|
13
|
+
return globalState.opacity
|
|
14
|
+
}
|
|
15
|
+
return parentOpacityValue
|
|
16
|
+
}
|
|
17
|
+
return opacityValue
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
const multiplyOpacities = (opacityValue = 1, parentOpacityValue = 1) => {
|
|
21
|
+
return Math.round((opacityValue * parentOpacityValue * globalState.opacity + Number.EPSILON) * 100) / 100
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export const calculateOpacity = (opacityValue, parentOpacityValue) => {
|
|
25
|
+
switch (globalState.opacityMode) {
|
|
26
|
+
case 'global':
|
|
27
|
+
return globalState.opacity
|
|
28
|
+
case 'multiply':
|
|
29
|
+
return multiplyOpacities(opacityValue, parentOpacityValue)
|
|
30
|
+
case 'dataset':
|
|
31
|
+
default:
|
|
32
|
+
return calculateLocalOpacity(opacityValue, parentOpacityValue)
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
export const getGlobalVisibility = () => globalState.visible
|
|
@@ -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) {
|