@defra/interactive-map 0.0.39-alpha → 0.0.41-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/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/control-definition.md +9 -1
- package/docs/api/slots.md +26 -5
- package/docs/api.md +4 -4
- package/docs/assets/images/slot-map.svg +61 -262
- package/docs/examples/draw-tools.mdx +3 -3
- package/docs/plugins/draw.md +80 -17
- package/docs/plugins/search.md +1 -1
- package/govuk-prototype-kit.config.json +2 -0
- package/jest.setup.js +5 -0
- package/package.json +9 -1
- package/plugins/beta/draw-es/dist/esm/im-draw-es-plugin.js +1 -1
- package/plugins/beta/draw-ml/dist/esm/im-draw-ml-plugin.js +1 -1
- package/plugins/beta/draw-ml/dist/umd/im-draw-ml-plugin.js +1 -1
- package/plugins/beta/draw-ol/dist/esm/im-draw-ol-plugin.js +1 -1
- package/plugins/beta/map-styles/dist/esm/im-map-styles-plugin.js +1 -1
- package/plugins/beta/map-styles/dist/umd/im-map-styles-plugin.js +1 -1
- package/plugins/beta/map-styles/dist/umd/index.js +1 -1
- package/plugins/datasets/dist/css/index.css +1 -1
- package/plugins/datasets/dist/esm/esriLayerAdapter.js +1 -1
- package/plugins/datasets/dist/esm/im-datasets-ml-adapter.js +1 -1
- package/plugins/datasets/dist/esm/im-datasets-plugin.js +1 -1
- package/plugins/datasets/dist/umd/im-datasets-esri-adapter.js +1 -1
- package/plugins/datasets/dist/umd/im-datasets-ml-adapter.js +1 -1
- package/plugins/datasets/dist/umd/im-datasets-plugin.js +1 -1
- package/plugins/datasets/dist/umd/index.js +1 -1
- package/plugins/datasets/src/adapters/esri/esriLayerAdapter.js +2 -3
- package/plugins/datasets/src/adapters/esri/esriLayerAdapter.test.js +175 -0
- package/plugins/datasets/src/adapters/esri/registry/esriDataset.js +1 -1
- package/plugins/datasets/src/adapters/esri/registry/esriDataset.test.js +55 -0
- package/plugins/datasets/src/adapters/loadLayerAdapter.js +1 -1
- package/plugins/datasets/src/adapters/loadLayerAdapter.test.js +61 -0
- package/plugins/datasets/src/adapters/maplibre/maplibreLayerAdapter.js +1 -3
- package/plugins/datasets/src/adapters/maplibre/maplibreLayerAdapter.test.js +17 -3
- package/plugins/datasets/src/api/setOpacity.test.js +9 -0
- package/plugins/datasets/src/components/LayersMenu/LayersMenu.jsx +10 -25
- package/plugins/datasets/src/components/LayersMenu/LayersMenu.test.jsx +0 -42
- package/plugins/datasets/src/datasets.scss +0 -1
- package/plugins/datasets/src/fetch/createDynamicSource.js +135 -129
- package/plugins/datasets/src/fetch/createDynamicSource.test.js +318 -0
- package/plugins/datasets/src/fetch/fetchGeoJSON.test.js +83 -0
- package/plugins/datasets/src/index.test.js +36 -0
- package/plugins/datasets/src/initialise/DatasetsInit.jsx +17 -7
- package/plugins/datasets/src/initialise/DatasetsInit.test.jsx +262 -0
- package/plugins/datasets/src/initialise/initialiseDatasets.js +16 -5
- package/plugins/datasets/src/initialise/initialiseDatasets.test.js +42 -0
- package/plugins/datasets/src/manifest.js +0 -38
- package/plugins/datasets/src/manifest.test.js +49 -0
- package/plugins/datasets/src/reducers/datasetsToMenu.test.js +54 -1
- package/plugins/datasets/src/reducers/pluginState.js +3 -16
- package/plugins/datasets/src/reducers/pluginState.test.js +23 -0
- package/plugins/datasets/src/registry/dataset.js +15 -4
- package/plugins/datasets/src/registry/dataset.test.js +61 -0
- package/plugins/datasets/src/registry/datasetRegistry.js +12 -9
- package/plugins/datasets/src/registry/datasetRegistry.test.js +17 -5
- package/plugins/datasets/src/registry/globalDataset.js +0 -3
- package/plugins/datasets/src/registry/isVisibleWhen.js +6 -3
- package/plugins/datasets/src/registry/isVisibleWhen.test.js +11 -1
- package/plugins/datasets/src/utils/bbox.test.js +125 -0
- package/plugins/draw/dist/esm/im-draw-ml-adapter.js +1 -1
- package/plugins/draw/dist/esm/im-draw-ol-adapter.js +1 -1
- package/plugins/draw/dist/esm/im-draw-plugin.js +1 -1
- package/plugins/draw/dist/esm/index.js +1 -1
- package/plugins/draw/dist/umd/im-draw-ml-adapter.js +2 -1
- package/plugins/draw/dist/umd/im-draw-ml-adapter.js.LICENSE.txt +1 -0
- package/plugins/draw/dist/umd/im-draw-ol-adapter.js +1 -1
- package/plugins/draw/dist/umd/im-draw-plugin.js +1 -1
- package/plugins/draw/dist/umd/index.js +1 -1
- package/plugins/draw/src/DrawInit.jsx +12 -4
- package/plugins/draw/src/DrawInit.test.jsx +51 -10
- package/plugins/draw/src/adapters/maplibre/MaplibreDrawAdapter.js +92 -12
- package/plugins/draw/src/adapters/maplibre/MaplibreDrawAdapter.test.js +246 -4
- package/plugins/draw/src/adapters/maplibre/mapboxDraw.js +109 -14
- package/plugins/draw/src/adapters/maplibre/mapboxDraw.test.js +174 -11
- package/plugins/draw/src/adapters/maplibre/modes/drawMode/clickHandlers.test.js +12 -0
- package/plugins/draw/src/adapters/maplibre/modes/drawMode/lifecycle.js +9 -1
- package/plugins/draw/src/adapters/maplibre/modes/drawMode/lifecycle.test.js +24 -3
- package/plugins/draw/src/adapters/maplibre/modes/drawMode/pointerHandlers.js +1 -1
- package/plugins/draw/src/adapters/maplibre/modes/drawMode/pointerHandlers.test.js +1 -1
- package/plugins/draw/src/adapters/maplibre/modes/drawPointMode.js +194 -0
- package/plugins/draw/src/adapters/maplibre/modes/drawPointMode.test.js +457 -0
- package/plugins/draw/src/adapters/maplibre/modes/editPointMode/__helpers__/harness.js +102 -0
- package/plugins/draw/src/adapters/maplibre/modes/editPointMode/keyboardHandlers.js +82 -0
- package/plugins/draw/src/adapters/maplibre/modes/editPointMode/keyboardHandlers.test.js +83 -0
- package/plugins/draw/src/adapters/maplibre/modes/editPointMode/pointOperations.js +55 -0
- package/plugins/draw/src/adapters/maplibre/modes/editPointMode/pointOperations.test.js +62 -0
- package/plugins/draw/src/adapters/maplibre/modes/editPointMode/pointerHandlers.js +138 -0
- package/plugins/draw/src/adapters/maplibre/modes/editPointMode/pointerHandlers.test.js +197 -0
- package/plugins/draw/src/adapters/maplibre/modes/editPointMode/touchHandlers.js +92 -0
- package/plugins/draw/src/adapters/maplibre/modes/editPointMode/touchHandlers.test.js +101 -0
- package/plugins/draw/src/adapters/maplibre/modes/editPointMode/undoHandlers.js +46 -0
- package/plugins/draw/src/adapters/maplibre/modes/editPointMode/undoHandlers.test.js +42 -0
- package/plugins/draw/src/adapters/maplibre/modes/editPointMode.js +151 -0
- package/plugins/draw/src/adapters/maplibre/modes/editPointMode.test.js +156 -0
- package/plugins/draw/src/adapters/maplibre/modes/editVertexMode/keyboardHandlers.js +5 -28
- package/plugins/draw/src/adapters/maplibre/modes/editVertexMode/keyboardHandlers.test.js +24 -39
- package/plugins/draw/src/adapters/maplibre/modes/editVertexMode/pointerHandlers.js +4 -5
- package/plugins/draw/src/adapters/maplibre/modes/editVertexMode/touchHandlers.js +20 -23
- package/plugins/draw/src/adapters/maplibre/modes/editVertexMode/touchHandlers.test.js +25 -5
- package/plugins/draw/src/adapters/maplibre/modes/editVertexMode/undoHandlers.js +6 -36
- package/plugins/draw/src/adapters/maplibre/modes/editVertexMode/undoHandlers.test.js +7 -49
- package/plugins/draw/src/adapters/maplibre/modes/editVertexMode/vertexOperations.js +4 -54
- package/plugins/draw/src/adapters/maplibre/modes/editVertexMode/vertexOperations.test.js +8 -33
- package/plugins/draw/src/adapters/maplibre/modes/editVertexMode.js +29 -72
- package/plugins/draw/src/adapters/maplibre/modes/editVertexMode.test.js +11 -4
- package/plugins/draw/src/adapters/maplibre/pointSymbolImages.js +158 -0
- package/plugins/draw/src/adapters/maplibre/pointSymbolImages.test.js +314 -0
- package/plugins/draw/src/adapters/maplibre/snap/prototypePatches.js +6 -1
- package/plugins/draw/src/adapters/maplibre/snap/prototypePatches.test.js +21 -0
- package/plugins/draw/src/adapters/maplibre/snap/snapInstance.js +6 -2
- package/plugins/draw/src/adapters/maplibre/snap/snapInstance.test.js +12 -0
- package/plugins/draw/src/adapters/maplibre/styles.js +38 -11
- package/plugins/draw/src/adapters/maplibre/styles.test.js +39 -0
- package/plugins/draw/src/adapters/maplibre/utils/editModeEvents.js +79 -0
- package/plugins/draw/src/adapters/maplibre/utils/editModeEvents.test.js +135 -0
- package/plugins/draw/src/adapters/maplibre/utils/geometryValidation.js +42 -0
- package/plugins/draw/src/adapters/maplibre/utils/geometryValidation.test.js +85 -0
- package/plugins/draw/src/adapters/maplibre/utils/keyboardShortcuts.js +34 -0
- package/plugins/draw/src/adapters/maplibre/utils/keyboardShortcuts.test.js +78 -0
- package/plugins/draw/src/adapters/maplibre/utils/snapHelpers.js +16 -3
- package/plugins/draw/src/adapters/maplibre/utils/snapHelpers.test.js +21 -3
- package/plugins/draw/src/adapters/maplibre/utils/snapMovement.js +59 -0
- package/plugins/draw/src/adapters/maplibre/utils/snapMovement.test.js +73 -0
- package/plugins/draw/src/adapters/maplibre/utils/touchDragMath.js +33 -0
- package/plugins/draw/src/adapters/maplibre/utils/touchDragMath.test.js +70 -0
- package/plugins/draw/src/adapters/openlayers/OLDrawAdapter.js +27 -2
- package/plugins/draw/src/adapters/openlayers/OLDrawAdapter.test.js +93 -0
- package/plugins/draw/src/adapters/openlayers/__helpers__/harness.js +9 -0
- package/plugins/draw/src/adapters/openlayers/core/OLDrawManager.js +19 -1
- package/plugins/draw/src/adapters/openlayers/core/OLDrawManager.test.js +34 -1
- package/plugins/draw/src/adapters/openlayers/core/styles.js +73 -1
- package/plugins/draw/src/adapters/openlayers/core/styles.test.js +122 -3
- package/plugins/draw/src/adapters/openlayers/draw/DrawMode.js +1 -0
- package/plugins/draw/src/adapters/openlayers/draw/DrawMode.test.js +27 -1
- package/plugins/draw/src/adapters/openlayers/draw/drawInput.js +24 -4
- package/plugins/draw/src/adapters/openlayers/draw/drawInput.test.js +47 -3
- package/plugins/draw/src/adapters/openlayers/edit/EditMode.js +1 -1
- package/plugins/draw/src/adapters/openlayers/edit/EditMode.test.js +32 -1
- package/plugins/draw/src/adapters/openlayers/edit/keyboardHandler.js +9 -5
- package/plugins/draw/src/adapters/openlayers/edit/keyboardHandler.test.js +34 -1
- package/plugins/draw/src/adapters/openlayers/edit/modifyInteraction.js +5 -3
- package/plugins/draw/src/adapters/openlayers/edit/modifyInteraction.test.js +11 -0
- package/plugins/draw/src/adapters/openlayers/edit/nudge.js +12 -5
- package/plugins/draw/src/adapters/openlayers/edit/nudge.test.js +26 -3
- package/plugins/draw/src/adapters/openlayers/edit/touchHandler.js +18 -13
- package/plugins/draw/src/adapters/openlayers/edit/touchHandler.test.js +46 -1
- package/plugins/draw/src/adapters/openlayers/olDraw.js +11 -4
- package/plugins/draw/src/adapters/openlayers/olDraw.test.js +48 -6
- package/plugins/draw/src/adapters/openlayers/point/drawPointMode.js +156 -0
- package/plugins/draw/src/adapters/openlayers/point/drawPointMode.test.js +246 -0
- package/plugins/draw/src/adapters/openlayers/point/editPointMode.js +267 -0
- package/plugins/draw/src/adapters/openlayers/point/editPointMode.test.js +327 -0
- package/plugins/draw/src/adapters/openlayers/point/pointDragInteraction.js +71 -0
- package/plugins/draw/src/adapters/openlayers/point/pointOps.js +34 -0
- package/plugins/draw/src/adapters/openlayers/point/pointOps.test.js +32 -0
- package/plugins/draw/src/adapters/openlayers/point/pointSelectionState.js +82 -0
- package/plugins/draw/src/adapters/openlayers/point/pointSelectionState.test.js +107 -0
- package/plugins/draw/src/adapters/openlayers/point/pointSymbolImages.js +83 -0
- package/plugins/draw/src/adapters/openlayers/point/pointSymbolImages.test.js +214 -0
- package/plugins/draw/src/adapters/openlayers/snap/snapIndicator.js +3 -1
- package/plugins/draw/src/adapters/openlayers/snap/snapInteraction.js +6 -9
- package/plugins/draw/src/adapters/openlayers/snap/snapInteraction.test.js +15 -4
- package/plugins/draw/src/adapters/openlayers/utils/olCoords.js +1 -1
- package/plugins/draw/src/api/addFeature.js +16 -1
- package/plugins/draw/src/api/addFeature.test.js +62 -5
- package/plugins/draw/src/api/editFeature.js +7 -4
- package/plugins/draw/src/api/editFeature.test.js +16 -0
- package/plugins/draw/src/api/newPoint.js +42 -0
- package/plugins/draw/src/api/newPoint.test.js +117 -0
- package/plugins/draw/src/api/setStyle.js +43 -0
- package/plugins/draw/src/api/setStyle.test.js +75 -0
- package/plugins/draw/src/events.js +21 -14
- package/plugins/draw/src/events.test.js +15 -1
- package/plugins/draw/src/manifest.js +18 -6
- package/plugins/draw/src/manifest.test.js +32 -1
- package/plugins/draw/src/reducer.test.js +7 -0
- package/plugins/draw/src/utils/stripInternalProperties.js +19 -0
- package/plugins/draw/src/utils/stripInternalProperties.test.js +50 -0
- package/plugins/draw/src/utils/symbolKeys.js +5 -0
- package/plugins/draw/src/validation/liveDrawChecks.test.js +54 -0
- package/plugins/draw/src/validation/liveStroke.test.js +64 -1
- 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/hooks/useCrossHairVisibility.js +12 -4
- package/plugins/interact/src/hooks/useCrossHairVisibility.test.js +88 -1
- package/plugins/interact/src/hooks/useHighlightSync.js +33 -12
- package/plugins/interact/src/hooks/useHighlightSync.test.js +96 -25
- package/plugins/interact/src/utils/featureQueries.js +18 -0
- package/plugins/interact/src/utils/featureQueries.test.js +15 -0
- package/plugins/interact/src/utils/spatial.js +9 -3
- package/plugins/interact/src/utils/spatial.test.js +12 -1
- package/plugins/map-key/dist/css/index.css +62 -0
- package/plugins/map-key/dist/esm/im-map-key-plugin.js +1 -0
- package/plugins/map-key/dist/esm/index.js +1 -0
- package/plugins/map-key/dist/umd/im-map-key-plugin.js +2 -0
- package/plugins/map-key/dist/umd/im-map-key-plugin.js.LICENSE.txt +1 -0
- package/plugins/map-key/dist/umd/index.js +2 -0
- package/plugins/map-key/dist/umd/index.js.LICENSE.txt +1 -0
- package/plugins/map-key/package.json +28 -0
- package/plugins/map-key/src/components/Key/EmptyKey.jsx +7 -0
- package/plugins/{datasets → map-key}/src/components/Key/EmptyKey.test.jsx +2 -2
- package/plugins/map-key/src/components/Key/Key.jsx +41 -0
- package/plugins/{datasets → map-key}/src/components/Key/Key.module.scss +15 -14
- package/plugins/map-key/src/components/Key/Key.test.jsx +73 -0
- package/plugins/map-key/src/components/Key/KeyGroupItem.jsx +16 -0
- package/plugins/map-key/src/components/Key/KeyGroupItem.test.jsx +53 -0
- package/plugins/map-key/src/components/Key/KeyItem.jsx +29 -0
- package/plugins/map-key/src/components/Key/KeyItem.test.jsx +67 -0
- package/plugins/map-key/src/components/Key/KeySvg.jsx +42 -0
- package/plugins/{datasets → map-key}/src/components/Key/KeySvg.test.jsx +14 -12
- package/plugins/map-key/src/components/Key/KeySvgLine.jsx +28 -0
- package/plugins/{datasets → map-key}/src/components/Key/KeySvgLine.test.jsx +1 -1
- package/plugins/map-key/src/components/Key/KeySvgPattern.jsx +23 -0
- package/plugins/{datasets → map-key}/src/components/Key/KeySvgPattern.test.jsx +2 -2
- package/plugins/map-key/src/components/Key/KeySvgRect.jsx +33 -0
- package/plugins/{datasets → map-key}/src/components/Key/KeySvgRect.test.jsx +1 -1
- package/plugins/map-key/src/components/Key/KeySvgSymbol.jsx +27 -0
- package/plugins/{datasets → map-key}/src/components/Key/KeySvgSymbol.test.jsx +5 -6
- package/plugins/map-key/src/components/Key/MapKey.jsx +50 -0
- package/plugins/map-key/src/components/Key/MapKey.test.jsx +130 -0
- package/plugins/{datasets → map-key}/src/components/Key/svgProperties.js +2 -2
- package/plugins/{datasets → map-key}/src/components/Key/svgProperties.test.js +2 -2
- package/plugins/map-key/src/index.js +13 -0
- package/plugins/map-key/src/index.test.js +31 -0
- package/plugins/map-key/src/initialise/MapKeyInit.jsx +15 -0
- package/plugins/map-key/src/initialise/MapKeyInit.test.jsx +39 -0
- package/plugins/map-key/src/manifest.js +30 -0
- package/plugins/map-key/src/manifest.test.js +63 -0
- package/plugins/map-key/src/mapKey.scss +4 -0
- package/plugins/map-key/src/registry/getDatasetRegistry.js +6 -0
- package/plugins/map-key/src/registry/getDatasetRegistry.test.js +23 -0
- package/plugins/map-key/src/registry/index.js +3 -0
- package/plugins/map-key/src/registry/index.test.js +15 -0
- package/plugins/menu/dist/css/index.css +80 -0
- package/plugins/menu/dist/esm/im-menu-plugin.js +1 -0
- package/plugins/menu/dist/esm/index.js +1 -0
- package/plugins/menu/dist/umd/im-menu-plugin.js +1 -0
- package/plugins/menu/dist/umd/index.js +2 -0
- package/plugins/menu/dist/umd/index.js.LICENSE.txt +1 -0
- package/plugins/menu/package.json +28 -0
- package/plugins/menu/src/components/Menu/CheckboxGroupWrapper.jsx +21 -0
- package/plugins/menu/src/components/Menu/GroupLegend.jsx +17 -0
- package/plugins/menu/src/components/Menu/GroupLegend.test.jsx +68 -0
- package/plugins/menu/src/components/Menu/Menu.jsx +19 -0
- package/plugins/menu/src/components/Menu/Menu.module.scss +90 -0
- package/plugins/menu/src/components/Menu/Menu.test.jsx +161 -0
- package/plugins/menu/src/components/Menu/MenuCheckbox.jsx +35 -0
- package/plugins/menu/src/components/Menu/MenuCheckbox.test.jsx +93 -0
- package/plugins/menu/src/components/Menu/MenuGroup.jsx +11 -0
- package/plugins/{datasets/src/components/LayersMenu/LayersMenuRadio.jsx → menu/src/components/Menu/MenuRadio.jsx} +6 -4
- package/plugins/{datasets/src/components/LayersMenu/LayersMenuRadio.test.jsx → menu/src/components/Menu/MenuRadio.test.jsx} +18 -18
- package/plugins/menu/src/components/Menu/RadioGroupWrapper.jsx +32 -0
- package/plugins/{datasets/src/components/LayersMenu/LayersRadioGroupWrapper.test.jsx → menu/src/components/Menu/RadioGroupWrapper.test.jsx} +21 -21
- package/plugins/menu/src/components/Menu/useIdPrefix.jsx +4 -0
- package/plugins/menu/src/index.js +13 -0
- package/plugins/menu/src/index.test.js +31 -0
- package/plugins/menu/src/initialise/MenuInit.jsx +24 -0
- package/plugins/menu/src/initialise/MenuInit.test.jsx +50 -0
- package/plugins/menu/src/initialise/createMenu.js +10 -0
- package/plugins/menu/src/initialise/createMenu.test.js +37 -0
- package/plugins/menu/src/manifest.js +35 -0
- package/plugins/menu/src/manifest.test.js +63 -0
- package/plugins/menu/src/menu.scss +4 -0
- package/plugins/menu/src/reducers/menuStateReducer.test.js +38 -0
- package/plugins/menu/src/reducers/pluginState.js +35 -0
- package/plugins/menu/src/reducers/pluginState.test.js +57 -0
- package/plugins/menu/src/registry/getDatasetRegistry.js +9 -0
- package/plugins/menu/src/registry/getDatasetRegistry.test.js +23 -0
- package/plugins/menu/src/registry/index.js +3 -0
- package/plugins/menu/src/registry/index.test.js +15 -0
- package/plugins/menu/src/registry/isVisibleWhen.js +43 -0
- package/plugins/menu/src/registry/isVisibleWhen.test.js +48 -0
- package/plugins/search/dist/css/index.css +1 -1
- package/plugins/search/dist/esm/im-search-plugin.js +1 -1
- package/plugins/search/dist/esm/index.js +1 -1
- package/plugins/search/dist/umd/im-search-plugin.js +1 -1
- package/plugins/search/dist/umd/index.js +1 -1
- package/plugins/search/src/Search.jsx +7 -5
- package/plugins/search/src/components/Form/Form.module.scss +9 -20
- package/plugins/search/src/index.js +0 -1
- package/plugins/search/src/index.test.js +2 -4
- package/plugins/search/src/manifest.js +1 -1
- package/plugins/search/src/search.scss +17 -16
- 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/dist/umd/index.js +1 -1
- package/providers/beta/openlayers/src/openlayersProvider.js +4 -1
- package/providers/beta/openlayers/src/openlayersProvider.test.js +18 -0
- package/providers/beta/openlayers/src/utils/highlightFeatures.js +52 -5
- package/providers/beta/openlayers/src/utils/highlightFeatures.test.js +176 -0
- package/providers/beta/openlayers/src/utils/symbolImages.js +40 -0
- package/providers/beta/openlayers/src/utils/symbolImages.test.js +58 -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/dist/umd/index.js +1 -1
- package/providers/maplibre/src/utils/drawLayerBuckets.js +14 -0
- package/providers/maplibre/src/utils/drawLayerBuckets.test.js +18 -0
- package/providers/maplibre/src/utils/highlightFeatures.js +80 -55
- package/providers/maplibre/src/utils/highlightFeatures.test.js +156 -17
- package/providers/maplibre/src/utils/hoverCursor.js +30 -14
- package/providers/maplibre/src/utils/hoverCursor.test.js +35 -0
- package/providers/maplibre/src/utils/patternImages.js +1 -1
- package/providers/maplibre/src/utils/symbolImages.js +41 -3
- package/providers/maplibre/src/utils/symbolImages.test.js +40 -6
- package/rollup.esm.mjs +11 -1
- package/sonar-project.properties +7 -1
- package/src/App/components/Actions/Actions.test.jsx +47 -0
- package/src/App/components/Attributions/Attributions.module.scss +10 -0
- package/src/App/components/Hints/Hints.jsx +7 -2
- package/src/App/components/Hints/Hints.test.jsx +13 -0
- package/src/App/components/KeyboardHelp/KeyboardHelp.jsx +2 -3
- package/src/App/components/KeyboardHelp/KeyboardHelp.test.jsx +3 -6
- package/src/App/components/{MoveControl/MoveControl.jsx → MoveControls/MoveControls.jsx} +10 -10
- package/src/App/components/{MoveControl/MoveControl.module.scss → MoveControls/MoveControls.module.scss} +60 -29
- package/src/App/components/{MoveControl/MoveControl.test.jsx → MoveControls/MoveControls.test.jsx} +48 -48
- package/src/App/components/Panel/Panel.jsx +18 -3
- package/src/App/components/Panel/Panel.module.scss +18 -8
- package/src/App/components/Panel/Panel.test.jsx +34 -0
- package/src/App/components/Tooltip/Tooltip.test.jsx +12 -14
- package/src/App/components/Viewport/Viewport.jsx +9 -1
- package/src/App/components/Viewport/Viewport.test.jsx +11 -0
- package/src/App/hooks/useFeatureItems.js +16 -7
- package/src/App/hooks/useFeatureItems.test.js +57 -0
- package/src/App/hooks/useLayoutMeasurements.js +95 -84
- package/src/App/hooks/useLayoutMeasurements.test.js +61 -1
- package/src/App/initialiseApp.js +11 -8
- package/src/App/initialiseApp.test.js +15 -3
- package/src/App/layout/Layout.jsx +12 -11
- package/src/App/layout/Layout.test.jsx +2 -0
- package/src/App/layout/layout.module.scss +31 -17
- package/src/App/registry/keyboardShortcutRegistry.js +25 -13
- package/src/App/registry/keyboardShortcutRegistry.test.js +49 -32
- package/src/App/registry/pluginRegistry.js +2 -3
- package/src/App/registry/pluginRegistry.test.js +16 -3
- package/src/App/renderer/HtmlElementHost.jsx +18 -5
- package/src/App/renderer/HtmlElementHost.test.jsx +54 -0
- package/src/App/renderer/mapButtons.js +28 -12
- package/src/App/renderer/mapButtons.test.js +17 -4
- package/src/App/renderer/mapControls.js +3 -1
- package/src/App/renderer/mapControls.test.js +16 -0
- package/src/App/renderer/mapPanels.js +44 -9
- package/src/App/renderer/mapPanels.test.js +51 -2
- package/src/App/renderer/orderItems.js +28 -0
- package/src/App/renderer/orderItems.test.js +50 -0
- package/src/App/renderer/slotAggregator.js +2 -18
- package/src/App/renderer/slotHelpers.js +3 -1
- package/src/App/renderer/slotHelpers.test.js +5 -0
- package/src/App/renderer/slots.js +3 -0
- package/src/App/store/AppProvider.jsx +4 -2
- package/src/App/store/appDispatchMiddleware.js +1 -1
- package/src/App/store/appDispatchMiddleware.test.js +8 -0
- package/src/InteractiveMap/InteractiveMap.js +8 -2
- package/src/InteractiveMap/InteractiveMap.test.js +20 -3
- package/src/config/appConfig.js +17 -15
- package/src/config/appConfig.test.js +22 -22
- package/src/config/defaults.js +3 -1
- package/src/config/events.js +2 -0
- package/src/config/mergeConfig.js +7 -0
- package/src/config/mergeConfig.test.js +20 -0
- package/src/scss/main.scss +1 -1
- package/src/scss/settings/_colors.scss +1 -0
- package/src/scss/settings/_dimensions.scss +2 -3
- package/src/scss/settings/_transition.scss +1 -1
- package/src/services/eventBus.js +44 -0
- package/src/services/eventBus.test.js +83 -0
- package/src/services/symbolRegistry.js +1 -1
- package/src/test-utils.js +5 -0
- package/src/types.js +25 -7
- package/webpack.umd.mjs +2 -0
- package/plugins/datasets/src/components/Key/EmptyKey.jsx +0 -7
- package/plugins/datasets/src/components/Key/Key.jsx +0 -50
- package/plugins/datasets/src/components/Key/KeyGroupItem.jsx +0 -18
- package/plugins/datasets/src/components/Key/KeyItem.jsx +0 -23
- package/plugins/datasets/src/components/Key/KeySvg.jsx +0 -22
- package/plugins/datasets/src/components/Key/KeySvgLine.jsx +0 -19
- package/plugins/datasets/src/components/Key/KeySvgPattern.jsx +0 -13
- package/plugins/datasets/src/components/Key/KeySvgRect.jsx +0 -22
- package/plugins/datasets/src/components/Key/KeySvgSymbol.jsx +0 -16
- package/plugins/datasets/src/components/LayersMenu/LayersRadioGroupWrapper.jsx +0 -41
- /package/plugins/{datasets → menu}/src/reducers/menuStateReducer.js +0 -0
- /package/{providers/maplibre/src → src}/utils/rasteriseToImageData.js +0 -0
- /package/{providers/maplibre/src → src}/utils/rasteriseToImageData.test.js +0 -0
|
@@ -10,7 +10,8 @@ import {
|
|
|
10
10
|
getSnapRadius,
|
|
11
11
|
isSnapEnabled,
|
|
12
12
|
createSnappedEvent,
|
|
13
|
-
createSnappedClickEvent
|
|
13
|
+
createSnappedClickEvent,
|
|
14
|
+
setAutoSnapSuspended
|
|
14
15
|
} from './snapHelpers.js'
|
|
15
16
|
import { TOLERANCES } from '../../../defaults.js'
|
|
16
17
|
|
|
@@ -87,7 +88,10 @@ describe('triggerSnapAtPoint', () => {
|
|
|
87
88
|
|
|
88
89
|
expect(triggerSnapAtPoint(snap, map, point)).toBe(true)
|
|
89
90
|
expect(map.unproject).toHaveBeenCalledWith(point)
|
|
90
|
-
|
|
91
|
+
// _explicit: true is what lets this call through snap/prototypePatches.js's suspend gate
|
|
92
|
+
// (see setAutoSnapSuspended) even while an edit mode's own offset-aware drag has silenced
|
|
93
|
+
// the snap library's own uncontrolled mousemove-driven auto-query.
|
|
94
|
+
expect(snap.snapToClosestPoint).toHaveBeenCalledWith({ point, lngLat, _explicit: true })
|
|
91
95
|
})
|
|
92
96
|
|
|
93
97
|
test('returns false when snap is missing', () => {
|
|
@@ -112,7 +116,7 @@ describe('triggerSnapAtCenter', () => {
|
|
|
112
116
|
|
|
113
117
|
expect(triggerSnapAtCenter(snap, map)).toBe(true)
|
|
114
118
|
expect(map.project).toHaveBeenCalledWith(center)
|
|
115
|
-
expect(snap.snapToClosestPoint).toHaveBeenCalledWith({ point, lngLat: center })
|
|
119
|
+
expect(snap.snapToClosestPoint).toHaveBeenCalledWith({ point, lngLat: center, _explicit: true })
|
|
116
120
|
})
|
|
117
121
|
|
|
118
122
|
test('returns false when snap is missing', () => {
|
|
@@ -196,6 +200,20 @@ describe('clearSnapState', () => {
|
|
|
196
200
|
})
|
|
197
201
|
})
|
|
198
202
|
|
|
203
|
+
describe('setAutoSnapSuspended', () => {
|
|
204
|
+
test('sets the flag on the snap instance', () => {
|
|
205
|
+
const snap = {}
|
|
206
|
+
setAutoSnapSuspended(snap, true)
|
|
207
|
+
expect(snap._autoSnapSuspended).toBe(true)
|
|
208
|
+
setAutoSnapSuspended(snap, false)
|
|
209
|
+
expect(snap._autoSnapSuspended).toBe(false)
|
|
210
|
+
})
|
|
211
|
+
|
|
212
|
+
test('is a no-op when snap is nullish', () => {
|
|
213
|
+
expect(() => setAutoSnapSuspended(null, true)).not.toThrow()
|
|
214
|
+
})
|
|
215
|
+
})
|
|
216
|
+
|
|
199
217
|
describe('getSnapRadius', () => {
|
|
200
218
|
test('returns the configured radius', () => {
|
|
201
219
|
expect(getSnapRadius({ options: { radius: 25 } })).toBe(25)
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import { KEYBOARD } from '../defaults.js'
|
|
2
|
+
import {
|
|
3
|
+
getSnapInstance, isSnapActive, isSnapEnabled, getSnapLngLat,
|
|
4
|
+
getSnapRadius, triggerSnapAtPoint, clearSnapIndicator
|
|
5
|
+
} from './snapHelpers.js'
|
|
6
|
+
import { ARROW_OFFSETS } from './keyboardShortcuts.js'
|
|
7
|
+
|
|
8
|
+
// Shared by editPointMode/pointOperations.js and editVertexMode/vertexOperations.js — a
|
|
9
|
+
// keyboard/D-pad nudge resolves to the same pixel-offset-then-project-back coordinate math
|
|
10
|
+
// and the same snap/break-out-of-snap rule for both a single-coordinate Point and a ring
|
|
11
|
+
// vertex; only what happens to that resolved coordinate afterwards (moveVertex's ring
|
|
12
|
+
// splice vs movePoint's direct updateCoordinate) differs, so that part stays local to
|
|
13
|
+
// each mode's own operations file.
|
|
14
|
+
export const sharedSnapMovement = {
|
|
15
|
+
getOffset (coord, e) {
|
|
16
|
+
const pt = this.map.project(coord)
|
|
17
|
+
const offset = e?.shiftKey ? KEYBOARD.nudgeAmount : KEYBOARD.stepAmount
|
|
18
|
+
const [dx, dy] = e ? ARROW_OFFSETS[e.key].map(v => v * offset) : [0, 0]
|
|
19
|
+
return this.map.unproject({ x: pt.x + dx, y: pt.y + dy })
|
|
20
|
+
},
|
|
21
|
+
|
|
22
|
+
// Explicit-delta counterpart to getOffset, driven by a unit direction vector and
|
|
23
|
+
// MoveControls' own Precision toggle rather than a KeyboardEvent — used by
|
|
24
|
+
// nudgeVertexByDelta/nudgePointByDelta.
|
|
25
|
+
getOffsetByDelta (coord, dx, dy, isLargeStep) {
|
|
26
|
+
const pt = this.map.project(coord)
|
|
27
|
+
const amount = isLargeStep ? KEYBOARD.stepAmount : KEYBOARD.nudgeAmount
|
|
28
|
+
return this.map.unproject({ x: pt.x + dx * amount, y: pt.y + dy * amount })
|
|
29
|
+
},
|
|
30
|
+
|
|
31
|
+
// Resolves the destination coordinate for a nudge by (dx, dy) unit direction, applying
|
|
32
|
+
// snap or breaking out of an already-active one — shared by the keyboard arrow-key path
|
|
33
|
+
// and MoveControls' explicit-delta path so both snap identically. dx/dy are only needed
|
|
34
|
+
// for the snap-escape offset; getCandidate computes the raw, un-snapped destination the
|
|
35
|
+
// caller would otherwise have used.
|
|
36
|
+
resolveSnapTarget (state, dx, dy, currentCoord, getCandidate) {
|
|
37
|
+
const snap = getSnapInstance(this.map)
|
|
38
|
+
|
|
39
|
+
// Break out of an active snap by moving beyond the snap radius
|
|
40
|
+
if (isSnapEnabled(state) && state._isSnapped && snap) {
|
|
41
|
+
const offset = getSnapRadius(snap) + 1
|
|
42
|
+
const pt = this.map.project(currentCoord)
|
|
43
|
+
state._isSnapped = false
|
|
44
|
+
clearSnapIndicator(snap, this.map)
|
|
45
|
+
return this.map.unproject({ x: pt.x + dx * offset, y: pt.y + dy * offset })
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
const newCoord = getCandidate()
|
|
49
|
+
if (isSnapEnabled(state) && snap) {
|
|
50
|
+
triggerSnapAtPoint(snap, this.map, this.map.project(newCoord))
|
|
51
|
+
if (isSnapActive(snap)) {
|
|
52
|
+
state._isSnapped = true
|
|
53
|
+
return getSnapLngLat(snap)
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
state._isSnapped = false
|
|
57
|
+
return newCoord
|
|
58
|
+
}
|
|
59
|
+
}
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import { sharedSnapMovement } from './snapMovement.js'
|
|
2
|
+
|
|
3
|
+
// Deterministic projection: lngLat <-> pixel is a x10 scale (same convention as the mode
|
|
4
|
+
// test harnesses this logic was extracted from).
|
|
5
|
+
const project = (p) => {
|
|
6
|
+
const [lng, lat] = Array.isArray(p) ? p : [p.lng, p.lat]
|
|
7
|
+
return { x: lng * 10, y: lat * 10 }
|
|
8
|
+
}
|
|
9
|
+
const unproject = ({ x, y }) => ({ lng: x / 10, lat: y / 10 })
|
|
10
|
+
|
|
11
|
+
const makeCtx = (snapOverrides) => ({
|
|
12
|
+
...sharedSnapMovement,
|
|
13
|
+
map: {
|
|
14
|
+
project: jest.fn(project),
|
|
15
|
+
unproject: jest.fn(unproject),
|
|
16
|
+
getLayer: jest.fn(() => null),
|
|
17
|
+
setLayoutProperty: jest.fn(),
|
|
18
|
+
_snapInstance: snapOverrides
|
|
19
|
+
}
|
|
20
|
+
})
|
|
21
|
+
|
|
22
|
+
describe('getOffset', () => {
|
|
23
|
+
test('applies step/nudge amounts and returns the coord unchanged without an event', () => {
|
|
24
|
+
const ctx = makeCtx()
|
|
25
|
+
const stepped = ctx.getOffset([5, 5], { key: 'ArrowRight', shiftKey: false })
|
|
26
|
+
const nudged = ctx.getOffset([5, 5], { key: 'ArrowRight', shiftKey: true })
|
|
27
|
+
expect(stepped.lng).not.toBe(5)
|
|
28
|
+
expect(Math.abs(nudged.lng - 5)).toBeLessThan(Math.abs(stepped.lng - 5))
|
|
29
|
+
expect(ctx.getOffset([5, 5], null)).toEqual({ lng: 5, lat: 5 })
|
|
30
|
+
})
|
|
31
|
+
})
|
|
32
|
+
|
|
33
|
+
describe('getOffsetByDelta', () => {
|
|
34
|
+
test('applies step/nudge amounts along an explicit direction, mirroring getOffset\'s shiftKey polarity', () => {
|
|
35
|
+
const ctx = makeCtx()
|
|
36
|
+
const large = ctx.getOffsetByDelta([5, 5], 1, 0, true)
|
|
37
|
+
const small = ctx.getOffsetByDelta([5, 5], 1, 0, false)
|
|
38
|
+
expect(large.lng).not.toBe(5)
|
|
39
|
+
expect(Math.abs(small.lng - 5)).toBeLessThan(Math.abs(large.lng - 5))
|
|
40
|
+
expect(ctx.getOffsetByDelta([5, 5], 0, 0, true)).toEqual({ lng: 5, lat: 5 })
|
|
41
|
+
})
|
|
42
|
+
})
|
|
43
|
+
|
|
44
|
+
describe('resolveSnapTarget', () => {
|
|
45
|
+
test('is a no-op passthrough to the candidate coordinate when snap is disabled', () => {
|
|
46
|
+
const ctx = makeCtx()
|
|
47
|
+
const state = { getSnapEnabled: () => false }
|
|
48
|
+
const candidate = { lng: 3, lat: 4 }
|
|
49
|
+
expect(ctx.resolveSnapTarget(state, 1, 0, [0, 0], () => candidate)).toEqual(candidate)
|
|
50
|
+
})
|
|
51
|
+
|
|
52
|
+
test('snaps to a nearby target and breaks out of an active snap on the next call', () => {
|
|
53
|
+
const ctx = makeCtx({ status: true, snapStatus: true, snapCoords: [7, 8], snapToClosestPoint: jest.fn() })
|
|
54
|
+
const state = { getSnapEnabled: () => true }
|
|
55
|
+
|
|
56
|
+
const snapped = ctx.resolveSnapTarget(state, 0, -1, [5, 5], () => ({ lng: 5, lat: 4 }))
|
|
57
|
+
expect(state._isSnapped).toBe(true)
|
|
58
|
+
expect(snapped).toEqual({ lng: 7, lat: 8 })
|
|
59
|
+
|
|
60
|
+
// Already snapped → next call breaks out of the snap radius instead of re-snapping
|
|
61
|
+
const escaped = ctx.resolveSnapTarget(state, -1, 0, [7, 8], () => ({ lng: 6, lat: 8 }))
|
|
62
|
+
expect(state._isSnapped).toBe(false)
|
|
63
|
+
expect(escaped.lng).toBeLessThan(7)
|
|
64
|
+
})
|
|
65
|
+
|
|
66
|
+
test('falls back to the raw candidate when snap is enabled but inactive', () => {
|
|
67
|
+
const ctx = makeCtx({ status: true, snapStatus: false, snapCoords: null, snapToClosestPoint: jest.fn() })
|
|
68
|
+
const state = { getSnapEnabled: () => true }
|
|
69
|
+
const candidate = { lng: 6, lat: 6 }
|
|
70
|
+
expect(ctx.resolveSnapTarget(state, 1, 0, [5, 5], () => candidate)).toEqual(candidate)
|
|
71
|
+
expect(state._isSnapped).toBe(false)
|
|
72
|
+
})
|
|
73
|
+
})
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { getSnapInstance, isSnapEnabled, triggerSnapAtPoint, getSnapLngLat } from './snapHelpers.js'
|
|
2
|
+
|
|
3
|
+
// Shared by editPointMode/touchHandlers.js and editVertexMode/touchHandlers.js — the offset-
|
|
4
|
+
// drag math (touch position → target/coordinate deltas, then delta → snapped map coordinate)
|
|
5
|
+
// is identical for both, since it's already single-coordinate, not ring-specific. Only what's
|
|
6
|
+
// dragged (state.touchPointTarget/movePoint vs state.touchVertexTarget/moveVertex) differs,
|
|
7
|
+
// which stays local to each mode's own touchHandlers.
|
|
8
|
+
|
|
9
|
+
export const getTouchPoint = (e) => ({ x: e.touches[0].clientX, y: e.touches[0].clientY })
|
|
10
|
+
|
|
11
|
+
// touchstart-time anchoring: the fixed offset between the finger and both the visible touch
|
|
12
|
+
// target and the underlying map coordinate, so onTouchmove can re-derive each from the
|
|
13
|
+
// finger's current position without drifting off its grab point.
|
|
14
|
+
export const computeTouchDragAnchors = (map, targetEl, touch, coord, scale) => {
|
|
15
|
+
const style = window.getComputedStyle(targetEl)
|
|
16
|
+
const deltaTarget = { x: touch.x - Number.parseFloat(style.left), y: touch.y - Number.parseFloat(style.top) }
|
|
17
|
+
const coordPt = map.project(coord)
|
|
18
|
+
const deltaVertex = { x: (touch.x / scale) - coordPt.x, y: (touch.y / scale) - coordPt.y }
|
|
19
|
+
return { deltaTarget, deltaVertex }
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
// Resolves the current touch position (given the deltas computed above) to a map coordinate,
|
|
23
|
+
// honouring snap — the mid-drag counterpart to computeTouchDragAnchors' touchstart-time setup.
|
|
24
|
+
export const resolveTouchDragCoord = (map, state, touch) => {
|
|
25
|
+
const screenPt = { x: (touch.x / state.scale) - state.deltaVertex.x, y: (touch.y / state.scale) - state.deltaVertex.y }
|
|
26
|
+
let finalCoord = map.unproject(screenPt)
|
|
27
|
+
if (isSnapEnabled(state)) {
|
|
28
|
+
const snap = getSnapInstance(map)
|
|
29
|
+
triggerSnapAtPoint(snap, map, screenPt)
|
|
30
|
+
finalCoord = getSnapLngLat(snap) || finalCoord
|
|
31
|
+
}
|
|
32
|
+
return finalCoord
|
|
33
|
+
}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import { getTouchPoint, computeTouchDragAnchors, resolveTouchDragCoord } from './touchDragMath.js'
|
|
2
|
+
|
|
3
|
+
// Deterministic projection: lngLat <-> pixel is a x10 scale (same convention as the mode
|
|
4
|
+
// test harnesses this logic was extracted from).
|
|
5
|
+
const project = (p) => {
|
|
6
|
+
const [lng, lat] = Array.isArray(p) ? p : [p.lng, p.lat]
|
|
7
|
+
return { x: lng * 10, y: lat * 10 }
|
|
8
|
+
}
|
|
9
|
+
const unproject = ({ x, y }) => ({ lng: x / 10, lat: y / 10 })
|
|
10
|
+
|
|
11
|
+
afterEach(() => {
|
|
12
|
+
document.body.innerHTML = ''
|
|
13
|
+
})
|
|
14
|
+
|
|
15
|
+
describe('getTouchPoint', () => {
|
|
16
|
+
test('reads clientX/clientY off the first touch', () => {
|
|
17
|
+
expect(getTouchPoint({ touches: [{ clientX: 12, clientY: 34 }] })).toEqual({ x: 12, y: 34 })
|
|
18
|
+
})
|
|
19
|
+
})
|
|
20
|
+
|
|
21
|
+
describe('computeTouchDragAnchors', () => {
|
|
22
|
+
test('anchors both the visible target and the map coordinate to the touchstart position', () => {
|
|
23
|
+
const map = { project: jest.fn(project) }
|
|
24
|
+
const targetEl = document.createElement('div')
|
|
25
|
+
document.body.appendChild(targetEl)
|
|
26
|
+
targetEl.style.left = '15px'
|
|
27
|
+
targetEl.style.top = '25px'
|
|
28
|
+
|
|
29
|
+
const { deltaTarget, deltaVertex } = computeTouchDragAnchors(map, targetEl, { x: 20, y: 40 }, [5, 5], 1)
|
|
30
|
+
|
|
31
|
+
expect(deltaTarget).toEqual({ x: 5, y: 15 }) // touch position minus the target's current CSS position
|
|
32
|
+
expect(deltaVertex).toEqual({ x: -30, y: -10 }) // touch/scale minus the projected coord
|
|
33
|
+
expect(map.project).toHaveBeenCalledWith([5, 5])
|
|
34
|
+
})
|
|
35
|
+
|
|
36
|
+
test('divides the touch position by scale before anchoring the coordinate delta', () => {
|
|
37
|
+
const map = { project: jest.fn(project) }
|
|
38
|
+
const targetEl = document.createElement('div')
|
|
39
|
+
document.body.appendChild(targetEl)
|
|
40
|
+
|
|
41
|
+
const { deltaVertex } = computeTouchDragAnchors(map, targetEl, { x: 100, y: 100 }, [5, 5], 2)
|
|
42
|
+
expect(deltaVertex).toEqual({ x: 0, y: 0 }) // (100 / 2) - (5 * 10)
|
|
43
|
+
})
|
|
44
|
+
})
|
|
45
|
+
|
|
46
|
+
describe('resolveTouchDragCoord', () => {
|
|
47
|
+
test('unprojects the delta-adjusted touch position when snap is disabled', () => {
|
|
48
|
+
const map = { unproject: jest.fn(unproject) }
|
|
49
|
+
const state = { scale: 1, deltaVertex: { x: 10, y: 10 }, getSnapEnabled: () => false }
|
|
50
|
+
expect(resolveTouchDragCoord(map, state, { x: 30, y: 40 })).toEqual({ lng: 2, lat: 3 })
|
|
51
|
+
})
|
|
52
|
+
|
|
53
|
+
test('snaps to a nearby target when active', () => {
|
|
54
|
+
const map = {
|
|
55
|
+
unproject: jest.fn(unproject),
|
|
56
|
+
_snapInstance: { status: true, snapStatus: true, snapCoords: [7, 8], snapToClosestPoint: jest.fn() }
|
|
57
|
+
}
|
|
58
|
+
const state = { scale: 1, deltaVertex: { x: 0, y: 0 }, getSnapEnabled: () => true }
|
|
59
|
+
expect(resolveTouchDragCoord(map, state, { x: 10, y: 10 })).toEqual({ lng: 7, lat: 8 })
|
|
60
|
+
})
|
|
61
|
+
|
|
62
|
+
test('falls back to the raw coordinate when snap is enabled but inactive', () => {
|
|
63
|
+
const map = {
|
|
64
|
+
unproject: jest.fn(unproject),
|
|
65
|
+
_snapInstance: { status: true, snapStatus: false, snapCoords: null, snapToClosestPoint: jest.fn() }
|
|
66
|
+
}
|
|
67
|
+
const state = { scale: 1, deltaVertex: { x: 0, y: 0 }, getSnapEnabled: () => true }
|
|
68
|
+
expect(resolveTouchDragCoord(map, state, { x: 10, y: 10 })).toEqual({ lng: 1, lat: 1 })
|
|
69
|
+
})
|
|
70
|
+
})
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { createOLDraw } from './olDraw.js'
|
|
2
|
+
import { resolvePointSymbol, hasSymbolStyle } from './point/pointSymbolImages.js'
|
|
2
3
|
|
|
3
4
|
// split.js passes this literal — MapLibre's own always-present "already-drawn
|
|
4
5
|
// shapes" style layer id — as a snapLayers entry so the split line snaps to the
|
|
@@ -25,7 +26,7 @@ const DRAW_OUTLINE_STYLE_LAYER = 'stroke-inactive.cold'
|
|
|
25
26
|
* setInterfaceType(type)
|
|
26
27
|
* done() / cancel() / undo() / deleteVertex()
|
|
27
28
|
* nudgeSelectedVertex(dx, dy, isLargeStep)
|
|
28
|
-
* get(id) / add(feature) / delete(id) / deleteAll()
|
|
29
|
+
* get(id) / add(feature) / setStyle(id, properties) / delete(id) / deleteAll()
|
|
29
30
|
* setSnapEnabled(bool) / setSnapLayers(layers) / isSnapEnabled()
|
|
30
31
|
* setFeatureProperty(id, property, value) / setDrawingPreviewProperty(property, value)
|
|
31
32
|
* on(event, handler) / off(event, handler)
|
|
@@ -89,7 +90,31 @@ export class OLDrawAdapter {
|
|
|
89
90
|
setInvalid (invalid) { this._manager.setInvalid(invalid) }
|
|
90
91
|
|
|
91
92
|
get (id) { return this._manager.get(id) }
|
|
92
|
-
|
|
93
|
+
|
|
94
|
+
// A directly-added Point (e.g. api/addFeature.js) skips draw_point's own icon-resolving
|
|
95
|
+
// drawend handler, so it must be resolved here instead — mirrors MaplibreDrawAdapter.js.
|
|
96
|
+
add (feature) {
|
|
97
|
+
const olFeature = this._manager.add(feature)
|
|
98
|
+
if (feature.geometry?.type === 'Point' && hasSymbolStyle(feature.properties)) {
|
|
99
|
+
resolvePointSymbol({ manager: this._manager, mapProvider: this._mapProvider, olFeature })
|
|
100
|
+
}
|
|
101
|
+
return olFeature
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
// Patches an existing feature's style properties (stroke/fill/strokeWidth or symbol-family
|
|
105
|
+
// keys) and re-renders — setProperties() must not be called silently, since VectorSource
|
|
106
|
+
// only redraws in response to the propertychange event that triggers.
|
|
107
|
+
setStyle (id, properties) {
|
|
108
|
+
const olFeature = this._manager.store.getOL(id)
|
|
109
|
+
if (!olFeature) {
|
|
110
|
+
return
|
|
111
|
+
}
|
|
112
|
+
olFeature.setProperties(properties)
|
|
113
|
+
if (olFeature.getGeometry()?.getType() === 'Point' && hasSymbolStyle(olFeature.getProperties())) {
|
|
114
|
+
resolvePointSymbol({ manager: this._manager, mapProvider: this._mapProvider, olFeature })
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
|
|
93
118
|
delete (id) { return this._manager.delete(id) }
|
|
94
119
|
deleteAll () { return this._manager.deleteAll() }
|
|
95
120
|
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { OLDrawAdapter } from './OLDrawAdapter.js'
|
|
2
2
|
import { createOLDraw } from './olDraw.js'
|
|
3
|
+
import { resolvePointSymbol, hasSymbolStyle } from './point/pointSymbolImages.js'
|
|
3
4
|
|
|
4
5
|
// The literal split.js passes — see OLDrawAdapter.js's DRAW_OUTLINE_STYLE_LAYER comment.
|
|
5
6
|
const DRAW_OUTLINE_STYLE_LAYER = 'stroke-inactive.cold'
|
|
@@ -20,6 +21,7 @@ const fakeManager = () => ({
|
|
|
20
21
|
setDrawingPreviewProperty: jest.fn(),
|
|
21
22
|
get: jest.fn(() => 'feature'),
|
|
22
23
|
add: jest.fn(),
|
|
24
|
+
store: { getOL: jest.fn() },
|
|
23
25
|
delete: jest.fn(),
|
|
24
26
|
deleteAll: jest.fn(),
|
|
25
27
|
on: jest.fn(),
|
|
@@ -31,6 +33,10 @@ const fakeManager = () => ({
|
|
|
31
33
|
jest.mock('./olDraw.js', () => ({
|
|
32
34
|
createOLDraw: jest.fn(({ mapProvider }) => ({ manager: mapProvider._testManager, remove: jest.fn() }))
|
|
33
35
|
}))
|
|
36
|
+
jest.mock('./point/pointSymbolImages.js', () => ({
|
|
37
|
+
resolvePointSymbol: jest.fn(),
|
|
38
|
+
hasSymbolStyle: jest.fn()
|
|
39
|
+
}))
|
|
34
40
|
|
|
35
41
|
const setup = () => {
|
|
36
42
|
const manager = fakeManager()
|
|
@@ -132,6 +138,93 @@ test('remaining calls delegate straight through; setFeatureProperty is a deliber
|
|
|
132
138
|
expect(manager.nudgeSelectedVertex).toHaveBeenCalledWith(1, 0, true)
|
|
133
139
|
})
|
|
134
140
|
|
|
141
|
+
// A directly-added Point skips draw_point's own icon-resolving drawend handler.
|
|
142
|
+
describe('add() and point symbol resolution', () => {
|
|
143
|
+
test('resolves the symbol for a Point feature with symbol properties', () => {
|
|
144
|
+
const { manager, mapProvider, adapter } = setup()
|
|
145
|
+
const olFeature = {}
|
|
146
|
+
manager.add.mockReturnValue(olFeature)
|
|
147
|
+
hasSymbolStyle.mockReturnValue(true)
|
|
148
|
+
const feature = { geometry: { type: 'Point', coordinates: [0, 0] }, properties: { symbol: 'pin' } }
|
|
149
|
+
|
|
150
|
+
const result = adapter.add(feature)
|
|
151
|
+
|
|
152
|
+
expect(manager.add).toHaveBeenCalledWith(feature)
|
|
153
|
+
expect(hasSymbolStyle).toHaveBeenCalledWith({ symbol: 'pin' })
|
|
154
|
+
expect(resolvePointSymbol).toHaveBeenCalledWith({ manager, mapProvider, olFeature })
|
|
155
|
+
expect(result).toBe(olFeature)
|
|
156
|
+
})
|
|
157
|
+
|
|
158
|
+
test('does not attempt resolution for a Point with no symbol properties', () => {
|
|
159
|
+
const { manager, adapter } = setup()
|
|
160
|
+
manager.add.mockReturnValue({})
|
|
161
|
+
hasSymbolStyle.mockReturnValue(false)
|
|
162
|
+
adapter.add({ geometry: { type: 'Point', coordinates: [0, 0] }, properties: {} })
|
|
163
|
+
expect(resolvePointSymbol).not.toHaveBeenCalled()
|
|
164
|
+
})
|
|
165
|
+
|
|
166
|
+
test('does not attempt resolution for a non-Point geometry', () => {
|
|
167
|
+
const { manager, adapter } = setup()
|
|
168
|
+
manager.add.mockReturnValue({})
|
|
169
|
+
adapter.add({ geometry: { type: 'Polygon', coordinates: [[]] }, properties: { symbol: 'pin' } })
|
|
170
|
+
expect(hasSymbolStyle).not.toHaveBeenCalled()
|
|
171
|
+
expect(resolvePointSymbol).not.toHaveBeenCalled()
|
|
172
|
+
})
|
|
173
|
+
|
|
174
|
+
test('does not attempt resolution for a feature with no geometry', () => {
|
|
175
|
+
const { manager, adapter } = setup()
|
|
176
|
+
manager.add.mockReturnValue({})
|
|
177
|
+
adapter.add({ id: 'b' })
|
|
178
|
+
expect(resolvePointSymbol).not.toHaveBeenCalled()
|
|
179
|
+
})
|
|
180
|
+
})
|
|
181
|
+
|
|
182
|
+
describe('setStyle()', () => {
|
|
183
|
+
const fakeOLFeature = (geometryType) => ({
|
|
184
|
+
setProperties: jest.fn(),
|
|
185
|
+
getGeometry: jest.fn(() => ({ getType: () => geometryType })),
|
|
186
|
+
getProperties: jest.fn(() => ({}))
|
|
187
|
+
})
|
|
188
|
+
|
|
189
|
+
test('patches the feature\'s properties (not silently, so VectorSource still redraws)', () => {
|
|
190
|
+
const { manager, adapter } = setup()
|
|
191
|
+
const olFeature = fakeOLFeature('Polygon')
|
|
192
|
+
manager.store.getOL.mockReturnValue(olFeature)
|
|
193
|
+
|
|
194
|
+
adapter.setStyle('a', { stroke: 'blue' })
|
|
195
|
+
|
|
196
|
+
expect(manager.store.getOL).toHaveBeenCalledWith('a')
|
|
197
|
+
expect(olFeature.setProperties).toHaveBeenCalledWith({ stroke: 'blue' })
|
|
198
|
+
})
|
|
199
|
+
|
|
200
|
+
// setStyle re-resolves a Point's icon the same way add() does for a directly-added one.
|
|
201
|
+
test('re-resolves the icon for a Point patched with symbol properties', () => {
|
|
202
|
+
const { manager, mapProvider, adapter } = setup()
|
|
203
|
+
const olFeature = fakeOLFeature('Point')
|
|
204
|
+
manager.store.getOL.mockReturnValue(olFeature)
|
|
205
|
+
hasSymbolStyle.mockReturnValue(true)
|
|
206
|
+
|
|
207
|
+
adapter.setStyle('p1', { symbolBackgroundColor: '#ca3535' })
|
|
208
|
+
|
|
209
|
+
expect(resolvePointSymbol).toHaveBeenCalledWith({ manager, mapProvider, olFeature })
|
|
210
|
+
})
|
|
211
|
+
|
|
212
|
+
test('does not attempt resolution for a non-Point geometry', () => {
|
|
213
|
+
const { manager, adapter } = setup()
|
|
214
|
+
const olFeature = fakeOLFeature('Polygon')
|
|
215
|
+
manager.store.getOL.mockReturnValue(olFeature)
|
|
216
|
+
adapter.setStyle('a', { stroke: 'blue' })
|
|
217
|
+
expect(resolvePointSymbol).not.toHaveBeenCalled()
|
|
218
|
+
})
|
|
219
|
+
|
|
220
|
+
test('does nothing for an id with no existing feature', () => {
|
|
221
|
+
const { manager, adapter } = setup()
|
|
222
|
+
manager.store.getOL.mockReturnValue(null)
|
|
223
|
+
expect(() => adapter.setStyle('missing', { stroke: 'blue' })).not.toThrow()
|
|
224
|
+
expect(resolvePointSymbol).not.toHaveBeenCalled()
|
|
225
|
+
})
|
|
226
|
+
})
|
|
227
|
+
|
|
135
228
|
test('setGeometryValid records validity on the manager for finish gating', () => {
|
|
136
229
|
const { adapter, manager } = setup()
|
|
137
230
|
adapter.setGeometryValid(false)
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import Feature from 'ol/Feature.js'
|
|
2
2
|
import Polygon from 'ol/geom/Polygon.js'
|
|
3
3
|
import LineString from 'ol/geom/LineString.js'
|
|
4
|
+
import Point from 'ol/geom/Point.js'
|
|
4
5
|
import Style from 'ol/style/Style.js'
|
|
5
6
|
import { createUndoStack } from '../../../utils/undoStack.js'
|
|
6
7
|
|
|
@@ -41,6 +42,7 @@ export const createFakeMap = ({ center = [50, 50] } = {}) => {
|
|
|
41
42
|
getCoordinateFromPixel: (p) => [p[0], p[1]],
|
|
42
43
|
getEventPixel: (e) => [e.clientX, e.clientY],
|
|
43
44
|
getView: () => view,
|
|
45
|
+
forEachFeatureAtPixel: jest.fn(() => undefined),
|
|
44
46
|
render: jest.fn()
|
|
45
47
|
}
|
|
46
48
|
}
|
|
@@ -60,6 +62,7 @@ export const createFakeManager = () => {
|
|
|
60
62
|
midpointStyle: new Style({}),
|
|
61
63
|
selectedVertexStyle: new Style({}),
|
|
62
64
|
selectedMidpointStyle: new Style({}),
|
|
65
|
+
selectedPointStyleFor: jest.fn(() => new Style({})),
|
|
63
66
|
createSketchStyle: jest.fn(() => () => [])
|
|
64
67
|
},
|
|
65
68
|
colors: { editVertex: 'rgba(29,112,184,1)' },
|
|
@@ -79,6 +82,12 @@ export const lineFeature = (coords, id = 'f1') => {
|
|
|
79
82
|
return feature
|
|
80
83
|
}
|
|
81
84
|
|
|
85
|
+
export const pointFeature = (coord, id = 'f1') => {
|
|
86
|
+
const feature = new Feature(new Point(coord))
|
|
87
|
+
feature.setId(id)
|
|
88
|
+
return feature
|
|
89
|
+
}
|
|
90
|
+
|
|
82
91
|
export const createContainer = () => {
|
|
83
92
|
const container = document.createElement('div')
|
|
84
93
|
container.tabIndex = 0
|
|
@@ -6,6 +6,9 @@ import { resolveColors } from '../../../utils/resolveColors.js'
|
|
|
6
6
|
import { createSnapManager } from '../snap/snapManager.js'
|
|
7
7
|
import { createDrawMode } from '../draw/DrawMode.js'
|
|
8
8
|
import { createEditMode } from '../edit/EditMode.js'
|
|
9
|
+
import { createEditPointMode } from '../point/editPointMode.js'
|
|
10
|
+
import { createDrawPointMode } from '../point/drawPointMode.js'
|
|
11
|
+
import { resolvePointSymbol } from '../point/pointSymbolImages.js'
|
|
9
12
|
import { TOLERANCES } from '../defaults.js'
|
|
10
13
|
import { ADAPTER_EVENTS } from '../../../adapterEvents.js'
|
|
11
14
|
import { STYLES_CHANGED_EVENT } from './internalEvents.js'
|
|
@@ -31,6 +34,11 @@ export class OLDrawManager {
|
|
|
31
34
|
this.store = createFeatureStore()
|
|
32
35
|
this.undoStack = createUndoStack((length) => this.emit(ADAPTER_EVENTS.UNDO_CHANGE, length))
|
|
33
36
|
|
|
37
|
+
// Tracked (not just derived into colors/styles) so point/pointSymbolImages.js has
|
|
38
|
+
// something to pass to symbolRegistry.rasteriseSymbolImage() when resolving a point's
|
|
39
|
+
// icon on demand, independent of whatever triggered the resolve.
|
|
40
|
+
this.mapStyle = null
|
|
41
|
+
|
|
34
42
|
this.colors = resolveColors(null, pluginConfig)
|
|
35
43
|
this.styles = createStyles(this.colors)
|
|
36
44
|
this.snap = createSnapManager(map, pluginConfig.snapLayers ?? null, this.colors, pluginConfig.snapRadius ?? TOLERANCES.snapRadius)
|
|
@@ -47,6 +55,7 @@ export class OLDrawManager {
|
|
|
47
55
|
// --- Color / style updates ---
|
|
48
56
|
|
|
49
57
|
setMapStyle (mapStyle) {
|
|
58
|
+
this.mapStyle = mapStyle
|
|
50
59
|
this.colors = resolveColors(mapStyle, this._pluginConfig)
|
|
51
60
|
this.styles = createStyles(this.colors)
|
|
52
61
|
this._layer.setStyle(this.styles.createFeatureStyle())
|
|
@@ -84,15 +93,24 @@ export class OLDrawManager {
|
|
|
84
93
|
this._modeInstance = null
|
|
85
94
|
this._mode = modeName
|
|
86
95
|
|
|
87
|
-
const isDrawMode = modeName === 'draw_polygon' || modeName === 'draw_line' || modeName === 'edit_vertex'
|
|
96
|
+
const isDrawMode = modeName === 'draw_polygon' || modeName === 'draw_line' || modeName === 'draw_point' || modeName === 'edit_vertex' || modeName === 'edit_point'
|
|
88
97
|
this.snap?.setIndicatorActive(isDrawMode)
|
|
89
98
|
|
|
90
99
|
const modeOptions = { ...options, snap: this.snap }
|
|
91
100
|
|
|
92
101
|
if (modeName === 'draw_polygon' || modeName === 'draw_line') {
|
|
93
102
|
this._modeInstance = createDrawMode({ map: this._map, manager: this, options: modeOptions })
|
|
103
|
+
} else if (modeName === 'draw_point') {
|
|
104
|
+
// Injected here (rather than imported directly by drawPointMode.js) so the mode only
|
|
105
|
+
// ever calls options.resolvePointSymbol(...) and stays free of a direct dependency on
|
|
106
|
+
// symbolRegistry/mapProvider — mirrors the ML adapter's own state.resolvePointSymbol
|
|
107
|
+
// convention (see MaplibreDrawAdapter.js's changeMode).
|
|
108
|
+
const pointOptions = { ...modeOptions, resolvePointSymbol: (olFeature) => resolvePointSymbol({ manager: this, mapProvider: options.mapProvider, olFeature }) }
|
|
109
|
+
this._modeInstance = createDrawPointMode({ map: this._map, manager: this, options: pointOptions })
|
|
94
110
|
} else if (modeName === 'edit_vertex') {
|
|
95
111
|
this._modeInstance = createEditMode({ map: this._map, manager: this, options: modeOptions })
|
|
112
|
+
} else if (modeName === 'edit_point') {
|
|
113
|
+
this._modeInstance = createEditPointMode({ map: this._map, manager: this, options: modeOptions })
|
|
96
114
|
} else {
|
|
97
115
|
// disabled — no mode instance needed
|
|
98
116
|
}
|
|
@@ -2,6 +2,9 @@ import { OLDrawManager } from './OLDrawManager.js'
|
|
|
2
2
|
import { STYLES_CHANGED_EVENT } from './internalEvents.js'
|
|
3
3
|
import { createDrawMode } from '../draw/DrawMode.js'
|
|
4
4
|
import { createEditMode } from '../edit/EditMode.js'
|
|
5
|
+
import { createEditPointMode } from '../point/editPointMode.js'
|
|
6
|
+
import { createDrawPointMode } from '../point/drawPointMode.js'
|
|
7
|
+
import { resolvePointSymbol } from '../point/pointSymbolImages.js'
|
|
5
8
|
import { createSnapManager } from '../snap/snapManager.js'
|
|
6
9
|
import { ADAPTER_EVENTS } from '../../../adapterEvents.js'
|
|
7
10
|
import { createFakeMap } from '../__helpers__/harness.js'
|
|
@@ -13,6 +16,15 @@ jest.mock('../draw/DrawMode.js', () => ({
|
|
|
13
16
|
jest.mock('../edit/EditMode.js', () => ({
|
|
14
17
|
createEditMode: jest.fn(() => ({ destroy: jest.fn(), done: jest.fn(), cancel: jest.fn(), undo: jest.fn(), deleteVertex: jest.fn(), nudgeSelectedVertex: jest.fn(), setInterfaceType: jest.fn(), setInvalid: jest.fn() }))
|
|
15
18
|
}))
|
|
19
|
+
jest.mock('../point/editPointMode.js', () => ({
|
|
20
|
+
createEditPointMode: jest.fn(() => ({ destroy: jest.fn(), done: jest.fn(), cancel: jest.fn(), undo: jest.fn(), deleteVertex: jest.fn(), nudgeSelectedVertex: jest.fn(), setInterfaceType: jest.fn(), setInvalid: jest.fn() }))
|
|
21
|
+
}))
|
|
22
|
+
jest.mock('../point/drawPointMode.js', () => ({
|
|
23
|
+
createDrawPointMode: jest.fn(() => ({ destroy: jest.fn(), done: jest.fn(), cancel: jest.fn(), undo: jest.fn(), setInterfaceType: jest.fn() }))
|
|
24
|
+
}))
|
|
25
|
+
jest.mock('../point/pointSymbolImages.js', () => ({
|
|
26
|
+
resolvePointSymbol: jest.fn()
|
|
27
|
+
}))
|
|
16
28
|
jest.mock('../snap/snapManager.js', () => ({
|
|
17
29
|
createSnapManager: jest.fn(() => ({ setIndicatorActive: jest.fn(), reattach: jest.fn(), updateColors: jest.fn(), destroy: jest.fn() }))
|
|
18
30
|
}))
|
|
@@ -52,7 +64,8 @@ describe('mode machine', () => {
|
|
|
52
64
|
test.each([
|
|
53
65
|
['draw_polygon', createDrawMode],
|
|
54
66
|
['draw_line', createDrawMode],
|
|
55
|
-
['edit_vertex', createEditMode]
|
|
67
|
+
['edit_vertex', createEditMode],
|
|
68
|
+
['edit_point', createEditPointMode]
|
|
56
69
|
])('%s creates its mode with snap injected, activates the indicator and reattaches snap last', async (name, factory) => {
|
|
57
70
|
const { map, manager } = setup()
|
|
58
71
|
await manager.changeMode(name, { featureId: 'f1' })
|
|
@@ -62,6 +75,26 @@ describe('mode machine', () => {
|
|
|
62
75
|
expect(manager.snap.reattach).toHaveBeenCalled()
|
|
63
76
|
})
|
|
64
77
|
|
|
78
|
+
// draw_point gets an extra options key (resolvePointSymbol) the other modes don't — see
|
|
79
|
+
// OLDrawManager.js's changeMode comment — so it's asserted separately rather than folded
|
|
80
|
+
// into the table above.
|
|
81
|
+
test('draw_point creates its mode with snap and resolvePointSymbol injected, activates the indicator and reattaches snap last', async () => {
|
|
82
|
+
const { map, manager } = setup()
|
|
83
|
+
const mapProvider = { drawScale: 2 }
|
|
84
|
+
await manager.changeMode('draw_point', { featureId: 'f1', mapProvider })
|
|
85
|
+
expect(manager.getMode()).toBe('draw_point')
|
|
86
|
+
expect(createDrawPointMode).toHaveBeenCalledWith({ map, manager, options: { featureId: 'f1', mapProvider, snap: manager.snap, resolvePointSymbol: expect.any(Function) } })
|
|
87
|
+
expect(manager.snap.setIndicatorActive).toHaveBeenCalledWith(true)
|
|
88
|
+
expect(manager.snap.reattach).toHaveBeenCalled()
|
|
89
|
+
|
|
90
|
+
// The injected hook delegates to point/pointSymbolImages.js's resolvePointSymbol with
|
|
91
|
+
// this manager and the mapProvider changeMode was called with.
|
|
92
|
+
const injected = createDrawPointMode.mock.calls.at(-1)[0].options.resolvePointSymbol
|
|
93
|
+
const olFeature = { id: 'point-1' }
|
|
94
|
+
injected(olFeature)
|
|
95
|
+
expect(resolvePointSymbol).toHaveBeenCalledWith({ manager, mapProvider, olFeature })
|
|
96
|
+
})
|
|
97
|
+
|
|
65
98
|
test('disabled destroys the previous mode and deactivates the indicator', async () => {
|
|
66
99
|
const { manager } = setup()
|
|
67
100
|
await manager.changeMode('draw_polygon')
|