@defra/interactive-map 0.0.37-alpha → 0.0.39-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.
Files changed (247) hide show
  1. package/assets/templates/draw-tools.njk +4 -3
  2. package/dist/css/index.css +1 -1
  3. package/dist/esm/im-core.js +1 -1
  4. package/dist/esm/im-shell.js +1 -1
  5. package/dist/umd/im-core.js +1 -1
  6. package/dist/umd/index.js +1 -1
  7. package/docs/api.md +32 -0
  8. package/docs/examples/draw-tools.mdx +0 -4
  9. package/docs/plugins/draw.md +482 -0
  10. package/docs/plugins.md +2 -6
  11. package/govuk-prototype-kit.config.json +3 -2
  12. package/package.json +2 -4
  13. package/plugins/beta/draw-es/dist/esm/im-draw-es-plugin.js +1 -1
  14. package/plugins/beta/draw-ml/dist/esm/im-draw-ml-plugin.js +1 -1
  15. package/plugins/beta/draw-ml/dist/umd/im-draw-ml-plugin.js +1 -1
  16. package/plugins/beta/draw-ol/dist/esm/im-draw-ol-plugin.js +1 -1
  17. package/plugins/beta/map-styles/dist/css/index.css +1 -97
  18. package/plugins/datasets/dist/esm/im-datasets-plugin.js +1 -1
  19. package/plugins/datasets/dist/umd/im-datasets-plugin.js +1 -1
  20. package/plugins/datasets/src/registry/dataset.js +3 -1
  21. package/plugins/datasets/src/registry/datasetRegistry.js +30 -24
  22. package/plugins/datasets/src/registry/datasetRegistry.test.js +25 -18
  23. package/plugins/draw/dist/esm/im-draw-ml-adapter.js +1 -0
  24. package/plugins/draw/dist/esm/im-draw-ol-adapter.js +1 -0
  25. package/plugins/draw/dist/esm/im-draw-plugin.js +1 -0
  26. package/plugins/draw/dist/esm/index.js +1 -0
  27. package/plugins/draw/dist/umd/im-draw-ml-adapter.js +1 -0
  28. package/plugins/draw/dist/umd/im-draw-ol-adapter.js +2 -0
  29. package/plugins/draw/dist/umd/im-draw-ol-adapter.js.LICENSE.txt +1 -0
  30. package/plugins/draw/dist/umd/im-draw-plugin.js +2 -0
  31. package/plugins/draw/dist/umd/im-draw-plugin.js.LICENSE.txt +1 -0
  32. package/plugins/draw/dist/umd/index.js +2 -0
  33. package/plugins/draw/dist/umd/index.js.LICENSE.txt +1 -0
  34. package/plugins/draw/src/DrawInit.jsx +89 -0
  35. package/plugins/draw/src/DrawInit.test.jsx +184 -0
  36. package/plugins/draw/src/adapterEvents.js +127 -0
  37. package/plugins/draw/src/adapterEvents.test.js +20 -0
  38. package/plugins/draw/src/adapters/adapterContract.test.js +48 -0
  39. package/plugins/draw/src/adapters/loadDrawAdapter.js +14 -0
  40. package/plugins/draw/src/adapters/loadDrawAdapter.test.js +53 -0
  41. package/plugins/draw/src/adapters/maplibre/MaplibreDrawAdapter.js +367 -0
  42. package/plugins/draw/src/adapters/maplibre/MaplibreDrawAdapter.test.js +799 -0
  43. package/plugins/draw/src/adapters/maplibre/defaults.js +1 -0
  44. package/plugins/draw/src/adapters/maplibre/drawEvents.js +35 -0
  45. package/plugins/draw/src/adapters/maplibre/mapboxDraw.js +126 -0
  46. package/plugins/draw/src/adapters/maplibre/mapboxDraw.test.js +268 -0
  47. package/plugins/draw/src/adapters/maplibre/mapboxSnap.js +39 -0
  48. package/plugins/draw/src/adapters/maplibre/mapboxSnap.test.js +91 -0
  49. package/plugins/draw/src/adapters/maplibre/modes/createDrawMode.js +58 -0
  50. package/plugins/draw/src/adapters/maplibre/modes/createDrawMode.test.js +53 -0
  51. package/plugins/draw/src/adapters/maplibre/modes/disabledMode.js +23 -0
  52. package/plugins/draw/src/adapters/maplibre/modes/disabledMode.test.js +21 -0
  53. package/plugins/draw/src/adapters/maplibre/modes/drawLineMode.js +15 -0
  54. package/plugins/draw/src/adapters/maplibre/modes/drawLineMode.test.js +37 -0
  55. package/plugins/draw/src/adapters/maplibre/modes/drawMode/__helpers__/harness.js +115 -0
  56. package/plugins/draw/src/adapters/maplibre/modes/drawMode/clickHandlers.js +193 -0
  57. package/plugins/draw/src/adapters/maplibre/modes/drawMode/clickHandlers.test.js +241 -0
  58. package/plugins/draw/src/adapters/maplibre/modes/drawMode/keyboardHandlers.js +78 -0
  59. package/plugins/draw/src/adapters/maplibre/modes/drawMode/keyboardHandlers.test.js +75 -0
  60. package/plugins/draw/src/adapters/maplibre/modes/drawMode/lifecycle.js +78 -0
  61. package/plugins/draw/src/adapters/maplibre/modes/drawMode/lifecycle.test.js +48 -0
  62. package/plugins/draw/src/adapters/maplibre/modes/drawMode/pointerHandlers.js +103 -0
  63. package/plugins/draw/src/adapters/maplibre/modes/drawMode/pointerHandlers.test.js +127 -0
  64. package/plugins/draw/src/adapters/maplibre/modes/drawMode/renderHelpers.js +59 -0
  65. package/plugins/draw/src/adapters/maplibre/modes/drawMode/renderHelpers.test.js +34 -0
  66. package/plugins/draw/src/adapters/maplibre/modes/drawMode/undoHandlers.js +193 -0
  67. package/plugins/draw/src/adapters/maplibre/modes/drawMode/undoHandlers.test.js +195 -0
  68. package/plugins/draw/src/adapters/maplibre/modes/drawPolygonMode.js +16 -0
  69. package/plugins/draw/src/adapters/maplibre/modes/drawPolygonMode.test.js +27 -0
  70. package/plugins/draw/src/adapters/maplibre/modes/editVertexMode/__helpers__/harness.js +107 -0
  71. package/plugins/draw/src/adapters/maplibre/modes/editVertexMode/geometryHelpers.js +139 -0
  72. package/plugins/draw/src/adapters/maplibre/modes/editVertexMode/geometryHelpers.test.js +46 -0
  73. package/plugins/draw/src/adapters/maplibre/modes/editVertexMode/helpers.js +2 -0
  74. package/plugins/draw/src/adapters/maplibre/modes/editVertexMode/helpers.test.js +17 -0
  75. package/plugins/draw/src/adapters/maplibre/modes/editVertexMode/keyboardHandlers.js +151 -0
  76. package/plugins/draw/src/adapters/maplibre/modes/editVertexMode/keyboardHandlers.test.js +123 -0
  77. package/plugins/draw/src/adapters/maplibre/modes/editVertexMode/pointerHandlers.js +161 -0
  78. package/plugins/draw/src/adapters/maplibre/modes/editVertexMode/pointerHandlers.test.js +98 -0
  79. package/plugins/draw/src/adapters/maplibre/modes/editVertexMode/touchHandlers.js +133 -0
  80. package/plugins/draw/src/adapters/maplibre/modes/editVertexMode/touchHandlers.test.js +105 -0
  81. package/plugins/draw/src/adapters/maplibre/modes/editVertexMode/undoHandlers.js +166 -0
  82. package/plugins/draw/src/adapters/maplibre/modes/editVertexMode/undoHandlers.test.js +133 -0
  83. package/plugins/draw/src/adapters/maplibre/modes/editVertexMode/vertexOperations.js +210 -0
  84. package/plugins/draw/src/adapters/maplibre/modes/editVertexMode/vertexOperations.test.js +167 -0
  85. package/plugins/draw/src/adapters/maplibre/modes/editVertexMode/vertexQueries.js +121 -0
  86. package/plugins/draw/src/adapters/maplibre/modes/editVertexMode/vertexQueries.test.js +73 -0
  87. package/plugins/draw/src/adapters/maplibre/modes/editVertexMode.js +249 -0
  88. package/plugins/draw/src/adapters/maplibre/modes/editVertexMode.test.js +153 -0
  89. package/plugins/draw/src/adapters/maplibre/snap/constants.js +2 -0
  90. package/plugins/draw/src/adapters/maplibre/snap/mapHandlers.js +39 -0
  91. package/plugins/draw/src/adapters/maplibre/snap/mapHandlers.test.js +106 -0
  92. package/plugins/draw/src/adapters/maplibre/snap/prototypePatches.js +148 -0
  93. package/plugins/draw/src/adapters/maplibre/snap/prototypePatches.test.js +238 -0
  94. package/plugins/draw/src/adapters/maplibre/snap/snapInstance.js +115 -0
  95. package/plugins/draw/src/adapters/maplibre/snap/snapInstance.test.js +151 -0
  96. package/plugins/draw/src/adapters/maplibre/snap/sourceData.js +34 -0
  97. package/plugins/draw/src/adapters/maplibre/snap/sourceData.test.js +62 -0
  98. package/plugins/draw/src/adapters/maplibre/styles.js +207 -0
  99. package/plugins/draw/src/adapters/maplibre/styles.test.js +155 -0
  100. package/plugins/draw/src/adapters/maplibre/utils/snapHelpers.js +202 -0
  101. package/plugins/draw/src/adapters/maplibre/utils/snapHelpers.test.js +253 -0
  102. package/plugins/draw/src/adapters/maplibre/utils/touchClickWorkaround.js +57 -0
  103. package/plugins/draw/src/adapters/maplibre/utils/touchClickWorkaround.test.js +106 -0
  104. package/plugins/draw/src/adapters/openlayers/OLDrawAdapter.js +117 -0
  105. package/plugins/draw/src/adapters/openlayers/OLDrawAdapter.test.js +159 -0
  106. package/plugins/draw/src/adapters/openlayers/__helpers__/harness.js +90 -0
  107. package/plugins/draw/src/adapters/openlayers/core/OLDrawManager.js +178 -0
  108. package/plugins/draw/src/adapters/openlayers/core/OLDrawManager.test.js +153 -0
  109. package/plugins/draw/src/adapters/openlayers/core/featureStore.js +69 -0
  110. package/plugins/draw/src/adapters/openlayers/core/featureStore.test.js +58 -0
  111. package/plugins/draw/src/adapters/openlayers/core/internalEvents.js +8 -0
  112. package/plugins/draw/src/adapters/openlayers/core/styles.js +155 -0
  113. package/plugins/draw/src/adapters/openlayers/core/styles.test.js +143 -0
  114. package/plugins/draw/src/adapters/openlayers/defaults.js +1 -0
  115. package/plugins/draw/src/adapters/openlayers/draw/DrawMode.js +272 -0
  116. package/plugins/draw/src/adapters/openlayers/draw/DrawMode.test.js +431 -0
  117. package/plugins/draw/src/adapters/openlayers/draw/drawInput.js +139 -0
  118. package/plugins/draw/src/adapters/openlayers/draw/drawInput.test.js +140 -0
  119. package/plugins/draw/src/adapters/openlayers/draw/vertexPlacement.js +144 -0
  120. package/plugins/draw/src/adapters/openlayers/draw/vertexPlacement.test.js +196 -0
  121. package/plugins/draw/src/adapters/openlayers/edit/EditMode.js +385 -0
  122. package/plugins/draw/src/adapters/openlayers/edit/EditMode.test.js +303 -0
  123. package/plugins/draw/src/adapters/openlayers/edit/activeVertexLayer.js +55 -0
  124. package/plugins/draw/src/adapters/openlayers/edit/activeVertexLayer.test.js +53 -0
  125. package/plugins/draw/src/adapters/openlayers/edit/keyboardHandler.js +157 -0
  126. package/plugins/draw/src/adapters/openlayers/edit/keyboardHandler.test.js +195 -0
  127. package/plugins/draw/src/adapters/openlayers/edit/midpointLayer.js +57 -0
  128. package/plugins/draw/src/adapters/openlayers/edit/midpointLayer.test.js +42 -0
  129. package/plugins/draw/src/adapters/openlayers/edit/modifyInteraction.js +83 -0
  130. package/plugins/draw/src/adapters/openlayers/edit/modifyInteraction.test.js +80 -0
  131. package/plugins/draw/src/adapters/openlayers/edit/nudge.js +118 -0
  132. package/plugins/draw/src/adapters/openlayers/edit/nudge.test.js +165 -0
  133. package/plugins/draw/src/adapters/openlayers/edit/pointerHandlers.js +79 -0
  134. package/plugins/draw/src/adapters/openlayers/edit/pointerHandlers.test.js +78 -0
  135. package/plugins/draw/src/adapters/openlayers/edit/selectionState.js +116 -0
  136. package/plugins/draw/src/adapters/openlayers/edit/selectionState.test.js +109 -0
  137. package/plugins/draw/src/adapters/openlayers/edit/touchHandler.js +184 -0
  138. package/plugins/draw/src/adapters/openlayers/edit/touchHandler.test.js +133 -0
  139. package/plugins/draw/src/adapters/openlayers/edit/undoOps.js +94 -0
  140. package/plugins/draw/src/adapters/openlayers/edit/undoOps.test.js +64 -0
  141. package/plugins/draw/src/adapters/openlayers/edit/vertexHitTest.js +74 -0
  142. package/plugins/draw/src/adapters/openlayers/edit/vertexHitTest.test.js +28 -0
  143. package/plugins/draw/src/adapters/openlayers/edit/vertexLayer.js +49 -0
  144. package/plugins/draw/src/adapters/openlayers/edit/vertexLayer.test.js +42 -0
  145. package/plugins/draw/src/adapters/openlayers/edit/vertexOps.js +100 -0
  146. package/plugins/draw/src/adapters/openlayers/edit/vertexOps.test.js +80 -0
  147. package/plugins/draw/src/adapters/openlayers/olDraw.js +40 -0
  148. package/plugins/draw/src/adapters/openlayers/olDraw.test.js +70 -0
  149. package/plugins/draw/src/adapters/openlayers/snap/snapEngine.js +220 -0
  150. package/plugins/draw/src/adapters/openlayers/snap/snapEngine.test.js +232 -0
  151. package/plugins/draw/src/adapters/openlayers/snap/snapGeometry.js +198 -0
  152. package/plugins/draw/src/adapters/openlayers/snap/snapGeometry.test.js +136 -0
  153. package/plugins/draw/src/adapters/openlayers/snap/snapIndicator.js +81 -0
  154. package/plugins/draw/src/adapters/openlayers/snap/snapIndicator.test.js +72 -0
  155. package/plugins/draw/src/adapters/openlayers/snap/snapInteraction.js +57 -0
  156. package/plugins/draw/src/adapters/openlayers/snap/snapInteraction.test.js +68 -0
  157. package/plugins/draw/src/adapters/openlayers/snap/snapManager.js +99 -0
  158. package/plugins/draw/src/adapters/openlayers/snap/snapManager.test.js +101 -0
  159. package/plugins/draw/src/adapters/openlayers/utils/geometryHelpers.js +103 -0
  160. package/plugins/draw/src/adapters/openlayers/utils/geometryHelpers.test.js +76 -0
  161. package/plugins/draw/src/adapters/openlayers/utils/olCoords.js +35 -0
  162. package/plugins/draw/src/adapters/openlayers/utils/olCoords.test.js +22 -0
  163. package/plugins/draw/src/adapters/openlayers/utils/sketchHelpers.js +22 -0
  164. package/plugins/draw/src/adapters/openlayers/utils/sketchHelpers.test.js +18 -0
  165. package/plugins/draw/src/adapters/openlayers/utils/touchTarget.js +8 -0
  166. package/plugins/draw/src/api/addFeature.js +22 -0
  167. package/plugins/draw/src/api/addFeature.test.js +41 -0
  168. package/plugins/draw/src/api/deleteFeature.js +11 -0
  169. package/plugins/draw/src/api/deleteFeature.test.js +24 -0
  170. package/plugins/draw/src/api/editFeature.js +54 -0
  171. package/plugins/draw/src/api/editFeature.test.js +134 -0
  172. package/plugins/draw/src/api/merge.js +30 -0
  173. package/plugins/draw/src/api/merge.test.js +57 -0
  174. package/plugins/draw/src/api/newLine.js +41 -0
  175. package/plugins/draw/src/api/newLine.test.js +93 -0
  176. package/plugins/draw/src/api/newPolygon.js +41 -0
  177. package/plugins/draw/src/api/newPolygon.test.js +93 -0
  178. package/plugins/draw/src/api/split.js +117 -0
  179. package/plugins/draw/src/api/split.test.js +204 -0
  180. package/plugins/draw/src/defaults.js +52 -0
  181. package/plugins/draw/src/defaults.test.js +18 -0
  182. package/plugins/draw/src/draw.scss +43 -0
  183. package/plugins/draw/src/events.js +237 -0
  184. package/plugins/draw/src/events.test.js +369 -0
  185. package/plugins/draw/src/index.js +10 -0
  186. package/plugins/draw/src/index.test.js +24 -0
  187. package/plugins/draw/src/manifest.js +170 -0
  188. package/plugins/draw/src/manifest.test.js +147 -0
  189. package/plugins/draw/src/reducer.js +69 -0
  190. package/plugins/draw/src/reducer.test.js +85 -0
  191. package/plugins/draw/src/utils/debounce.js +16 -0
  192. package/plugins/draw/src/utils/debounce.test.js +40 -0
  193. package/plugins/draw/src/utils/eventBus.js +36 -0
  194. package/plugins/draw/src/utils/eventBus.test.js +47 -0
  195. package/plugins/draw/src/utils/flattenStyleProperties.js +25 -0
  196. package/plugins/draw/src/utils/flattenStyleProperties.test.js +33 -0
  197. package/plugins/draw/src/utils/getValueForStyle.js +33 -0
  198. package/plugins/draw/src/utils/getValueForStyle.test.js +32 -0
  199. package/plugins/draw/src/utils/resolveColors.js +39 -0
  200. package/plugins/draw/src/utils/resolveColors.test.js +34 -0
  201. package/plugins/draw/src/utils/spatial.js +243 -0
  202. package/plugins/draw/src/utils/spatial.test.js +243 -0
  203. package/plugins/draw/src/utils/touchTarget.js +95 -0
  204. package/plugins/draw/src/utils/touchTarget.test.js +107 -0
  205. package/plugins/draw/src/utils/undoStack.js +31 -0
  206. package/plugins/draw/src/utils/undoStack.test.js +49 -0
  207. package/plugins/draw/src/validation/liveDrawChecks.js +120 -0
  208. package/plugins/draw/src/validation/liveDrawChecks.test.js +159 -0
  209. package/plugins/draw/src/validation/liveStroke.js +85 -0
  210. package/plugins/draw/src/validation/liveStroke.test.js +150 -0
  211. package/plugins/draw/src/validation/rules.areaError.test.js +12 -0
  212. package/plugins/draw/src/validation/rules.js +186 -0
  213. package/plugins/draw/src/validation/rules.test.js +120 -0
  214. package/plugins/draw/src/validation/validateGeometry.js +119 -0
  215. package/plugins/draw/src/validation/validateGeometry.test.js +200 -0
  216. package/plugins/interact/dist/esm/im-interact-plugin.js +1 -1
  217. package/plugins/interact/dist/umd/im-interact-plugin.js +1 -1
  218. package/plugins/interact/src/hooks/useInteractionHandlers.js +1 -1
  219. package/plugins/interact/src/hooks/useInteractionHandlers.test.js +1 -1
  220. package/plugins/interact/src/utils/buildStylesMap.js +1 -0
  221. package/plugins/search/dist/css/index.css +1 -317
  222. package/rollup.esm.mjs +35 -28
  223. package/sonar-project.properties +2 -2
  224. package/src/App/components/Attributions/Attributions.module.scss +1 -0
  225. package/src/App/components/Hints/Hints.module.scss +5 -4
  226. package/src/App/components/KeyboardHelp/KeyboardHelp.jsx +1 -1
  227. package/src/App/components/KeyboardHelp/KeyboardHelp.test.jsx +11 -0
  228. package/src/App/components/MoveControl/MoveControl.jsx +73 -9
  229. package/src/App/components/MoveControl/MoveControl.module.scss +12 -2
  230. package/src/App/components/MoveControl/MoveControl.test.jsx +136 -0
  231. package/src/App/hooks/useHintsAPI.js +67 -0
  232. package/src/App/hooks/useHintsAPI.test.js +145 -0
  233. package/src/App/renderer/PluginInits.jsx +4 -0
  234. package/src/App/renderer/PluginInits.test.jsx +7 -1
  235. package/src/InteractiveMap/InteractiveMap.js +20 -0
  236. package/src/InteractiveMap/InteractiveMap.test.js +7 -0
  237. package/src/config/events.js +4 -0
  238. package/src/scss/settings/_dimensions.scss +3 -0
  239. package/src/services/announcer.js +38 -3
  240. package/src/services/announcer.test.js +133 -1
  241. package/src/services/hints.js +3 -0
  242. package/src/services/hints.test.js +19 -0
  243. package/src/types.js +12 -0
  244. package/src/utils/detectInterfaceType.js +5 -1
  245. package/src/utils/isMac.js +15 -0
  246. package/src/utils/isMac.test.js +37 -0
  247. package/webpack.umd.mjs +1 -0
@@ -0,0 +1,482 @@
1
+ # Draw Plugin
2
+
3
+ The draw plugin lets users draw and edit polygon and line features on the map — placing vertices by click, tap, or keyboard, snapping to existing map layers, and validating geometry as it's built. Polygons can also be split and merged. It works identically with both the MapLibre and OpenLayers map providers, determining the correct adapter to use from the `mapProvider` passed to `InteractiveMap` — there's nothing to configure.
4
+
5
+ ## ESM usage
6
+
7
+ ```js
8
+ import createDrawPlugin from '@defra/interactive-map/plugins/draw'
9
+
10
+ const drawPlugin = createDrawPlugin()
11
+
12
+ const interactiveMap = new InteractiveMap('map', {
13
+ plugins: [drawPlugin]
14
+ })
15
+
16
+ interactiveMap.on('map:ready', () => {
17
+ interactiveMap.addButton('drawPolygon', {
18
+ label: 'Draw polygon',
19
+ onClick: () => drawPlugin.newPolygon(crypto.randomUUID())
20
+ })
21
+ })
22
+ ```
23
+
24
+ ## UMD usage
25
+
26
+ Copy the entire `plugins/draw/dist/umd/` directory to `/your-assets-path/plugins/draw/umd/`. The plugin uses dynamic imports to load MapLibre or OpenLayers support on demand, so all files in the directory must be served from the same location. Then add the script tag:
27
+
28
+ ```html
29
+ <script defer src="/your-assets-path/plugins/draw/umd/index.js"></script>
30
+ ```
31
+
32
+ ```js
33
+ const drawPlugin = defra.drawPlugin()
34
+
35
+ const interactiveMap = new defra.InteractiveMap('map', {
36
+ mapProvider: defra.maplibreProvider(),
37
+ plugins: [drawPlugin]
38
+ })
39
+ ```
40
+
41
+ > [!NOTE]
42
+ > **GOV.UK Prototype Kit** — skip the copy step. All files are served automatically. Use this path instead:
43
+ > ```html
44
+ > <script defer src="/plugin-assets/%40defra%2Finteractive-map/plugins/draw/dist/umd/index.js"></script>
45
+ > ```
46
+
47
+ ## Options
48
+
49
+ Options are passed to the factory function when creating the plugin.
50
+
51
+ ---
52
+
53
+ ### `snapLayers`
54
+
55
+ **Type:** `string[]`
56
+
57
+ Vector tile source-layer names to snap new and edited vertices against. Can be overridden per call — see `newPolygon`, `newLine`, `editFeature`, and `split` below.
58
+
59
+ The layer names available depend entirely on your basemap style — there's no universal default, so check your style's vector tile source(s) for the source-layer names to use. The example below (`'OS/TopographicArea_1/Agricultural Land'`) is specific to an Ordnance Survey basemap style.
60
+
61
+ When set (globally or per call), a "Snap to feature" toggle appears in the draw menu, letting the user turn snapping on and off during a session.
62
+
63
+ ```js
64
+ createDrawPlugin({
65
+ snapLayers: ['OS/TopographicArea_1/Agricultural Land', 'OS/TopographicLine/Building Outline']
66
+ })
67
+ ```
68
+
69
+ ---
70
+
71
+ ### `onGeometryChange`
72
+
73
+ **Type:** `Function`
74
+
75
+ Plugin-level validation callback, called throughout the draw/edit lifecycle so you can enforce your own rules (e.g. "shapes must stay inside a boundary") alongside the built-in ones. Can be overridden per call — see [Validation](#validation) below for the full contract, and `newPolygon`, `newLine`, `editFeature` for the per-call override.
76
+
77
+ ---
78
+
79
+ ### `includeModes`
80
+
81
+ **Type:** `string[]`
82
+
83
+ When set, the plugin only initialises when the app is in one of the specified modes.
84
+
85
+ ---
86
+
87
+ ### `excludeModes`
88
+
89
+ **Type:** `string[]`
90
+
91
+ When set, the plugin does not initialise when the app is in one of the specified modes.
92
+
93
+ ---
94
+
95
+ ### Colour and size overrides
96
+
97
+ > [!NOTE]
98
+ > Each colour accepts a plain colour string or a style-keyed object (e.g. `{ light: '#1d70b8', dark: '#ffffff' }`).
99
+
100
+ | Property | Type | Description |
101
+ |----------|------|-------------|
102
+ | `shapeStroke` | `string \| Record<string, string>` | Default stroke colour for an inactive (not being drawn/edited) shape, when the feature sets no `stroke` of its own |
103
+ | `shapeFill` | `string \| Record<string, string>` | Default fill colour for an inactive shape, when the feature sets no `fill` of its own |
104
+ | `strokeWidth` | `number` | Default stroke width in pixels. **Default:** `2` |
105
+ | `editStroke` | `string \| Record<string, string>` | Stroke colour of the shape currently being drawn or edited |
106
+ | `editFill` | `string \| Record<string, string>` | Fill colour of the shape currently being drawn or edited |
107
+ | `editVertex` | `string \| Record<string, string>` | Colour of placed, unselected vertex handles |
108
+ | `editMidpoint` | `string \| Record<string, string>` | Colour of the midpoint handles used to insert a new vertex on an edge |
109
+ | `editActive` | `string \| Record<string, string>` | Colour of the currently selected/active vertex handle |
110
+ | `editHalo` | `string \| Record<string, string>` | Colour of the halo drawn behind vertex/midpoint handles for contrast |
111
+ | `invalidStroke` | `string \| Record<string, string>` | Stroke colour of the dashed outline shown while the shape fails validation |
112
+ | `splitValid` | `string \| Record<string, string>` | Colour of the split line while it would produce a valid split |
113
+ | `splitInvalid` | `string \| Record<string, string>` | Colour of the split line while it would not produce a valid split |
114
+ | `snapVertex` | `string \| Record<string, string>` | Colour of the snap indicator shown over a vertex |
115
+ | `snapEdge` | `string \| Record<string, string>` | Colour of the snap indicator shown over an edge |
116
+ | `snapRadius` | `number` | Snap tolerance in pixels. **Default:** `12` |
117
+
118
+ ```js
119
+ createDrawPlugin({
120
+ shapeStroke: { light: '#1d70b8', dark: '#5694ca' },
121
+ editStroke: '#0b0c0c',
122
+ strokeWidth: 3,
123
+ snapRadius: 16
124
+ })
125
+ ```
126
+
127
+ ## Validation
128
+
129
+ Every geometry change — placing a vertex, dragging one, finishing a shape — is checked against a set of built-in rules before it's accepted, plus your own `onGeometryChange` callback if you provide one.
130
+
131
+ ### Built-in rules
132
+
133
+ | Rule | Applies to | Behaviour |
134
+ |------|-----------|-----------|
135
+ | Minimum vertices | Polygon (3), Line (2) | Gates the Done button — a shape below the minimum can't be finished |
136
+ | Self-intersection | Polygon | Gates the Done button — a self-crossing shape can't be finished |
137
+ | Self-intersection (placement) | Polygon | Rejects a vertex placement outright if it would make the drawn path cross itself — the vertex never appears |
138
+ | Non-zero area | Polygon | Gates the Done button — a collinear/degenerate ring can't be finished |
139
+
140
+ Rule failures gate the Done button (the shape can pass through interim invalid states while being built or reshaped, shown with a dashed outline) except the placement-time self-intersection check, which is a hard veto — that specific vertex is rejected and never placed.
141
+
142
+ ### `onGeometryChange` callback
143
+
144
+ Set at the plugin level (`createDrawPlugin({ onGeometryChange })`) or per call (`newPolygon`/`newLine`/`editFeature`'s `options.onGeometryChange`, which takes precedence when given). Not used by `split` (which validates that the line actually bisects the shape) or `merge`/`addFeature` (no validation).
145
+
146
+ **Signature:** `onGeometryChange(event) => boolean | { valid: boolean, reason?: string } | undefined`
147
+
148
+ | Return value | Meaning |
149
+ |---|---|
150
+ | `true` / `undefined` | Valid |
151
+ | `false` | Invalid, no reason shown |
152
+ | `{ valid, reason }` | Valid or invalid, with an optional reason surfaced as a hint toast (except for placement, which never toasts — see `phase` below) |
153
+
154
+ **Event payload:**
155
+
156
+ | Property | Type | Description |
157
+ |----------|------|-------------|
158
+ | `feature` | `GeoJSON.Feature` | The shape at this point — the in-progress feature during `'preview'`, the committed/candidate feature at every other phase |
159
+ | `phase` | `string` | See table below |
160
+ | `mode` | `'draw_polygon' \| 'draw_line' \| 'edit_vertex'` | The active draw mode |
161
+ | `vertexIndex` | `number` | Index of the vertex being placed/added/moved/inserted/deleted. Present on `'place'` and every `'commit-*'` phase |
162
+ | `numVertices` | `number` | Count of already-committed vertices, excluding any in-progress cursor point. Present on every `'preview'` call |
163
+
164
+ **Phases:**
165
+
166
+ | Phase | When | Can veto? |
167
+ |-------|------|-----------|
168
+ | `'preview'` | Live feedback on every rubber-band move while drawing/dragging, throttled to once per frame. Drives both the dashed-outline check and the Add-point button | No — display only |
169
+ | `'place'` | A real click/tap/Add-point press, evaluated once, synchronously | Yes — a hard rule or your callback returning invalid rejects the vertex outright; it never appears |
170
+ | `'create'` | A whole new feature just finished being drawn | Gates whether it's accepted as-is or reopened in edit mode |
171
+ | `'edit-start'` | An existing feature was just loaded into an edit session — the baseline check before anything has changed | Gates the initial Done state |
172
+ | `'commit-add'` | A vertex was added while drawing | Gates Done |
173
+ | `'commit-move'` | A vertex was dragged/nudged while editing | Gates Done |
174
+ | `'commit-insert'` | A vertex was inserted at a midpoint while editing | Gates Done |
175
+ | `'commit-delete'` | A vertex was removed while editing | Gates Done |
176
+
177
+ ```js
178
+ createDrawPlugin({
179
+ onGeometryChange: (event) => ({
180
+ valid: isEastOfWalesBorder(event.feature.geometry),
181
+ reason: 'Points must be placed east of the England/Wales border'
182
+ })
183
+ })
184
+ ```
185
+
186
+ ## Methods
187
+
188
+ Methods are called on the plugin instance. `newPolygon`, `newLine`, `editFeature`, `addFeature`, `deleteFeature`, `split`, and `merge` all need `mapProvider.draw` to be ready — call them after [`draw:ready`](#drawready).
189
+
190
+ ---
191
+
192
+ ### `newPolygon(featureId, options?)`
193
+
194
+ Start drawing a new polygon.
195
+
196
+ | Argument | Type | Description |
197
+ |----------|------|-------------|
198
+ | `featureId` | `string` | **Required.** ID to assign the finished feature |
199
+ | `options.snapLayers` | `string[]` | Overrides the plugin-level `snapLayers` for this session |
200
+ | `options.onGeometryChange` | `Function` | Overrides the plugin-level `onGeometryChange` for this session — see [Validation](#validation) |
201
+ | `options.stroke` | `string \| Record<string, string>` | Stroke colour for this shape |
202
+ | `options.fill` | `string \| Record<string, string>` | Fill colour for this shape |
203
+ | `options.strokeWidth` | `number` | Stroke width in pixels for this shape |
204
+ | `options.properties` | `Object` | Custom GeoJSON properties to set on the finished feature |
205
+
206
+ ```js
207
+ drawPlugin.newPolygon(crypto.randomUUID(), {
208
+ stroke: '#e6c700',
209
+ fill: 'rgba(255, 221, 0, 0.1)'
210
+ })
211
+ ```
212
+
213
+ ---
214
+
215
+ ### `newLine(featureId, options?)`
216
+
217
+ Start drawing a new line. Same options as `newPolygon`.
218
+
219
+ ```js
220
+ drawPlugin.newLine(crypto.randomUUID(), {
221
+ stroke: { outdoor: '#99704a', dark: '#ffffff' },
222
+ strokeWidth: 6
223
+ })
224
+ ```
225
+
226
+ ---
227
+
228
+ ### `editFeature(featureId, options?)`
229
+
230
+ Open an existing feature in vertex-edit mode. Returns `false` (without doing anything) if the feature doesn't exist or the plugin isn't ready yet — check the return value before assuming the edit session started.
231
+
232
+ | Argument | Type | Description |
233
+ |----------|------|-------------|
234
+ | `featureId` | `string` | **Required.** ID of the feature to edit |
235
+ | `options.snapLayers` | `string[]` | Overrides the plugin-level `snapLayers` for this session |
236
+ | `options.onGeometryChange` | `Function` | Overrides the plugin-level `onGeometryChange` for this session |
237
+
238
+ ```js
239
+ const editSuccess = drawPlugin.editFeature(selectedFeatureId)
240
+ if (!editSuccess) {
241
+ return
242
+ }
243
+ ```
244
+
245
+ ---
246
+
247
+ ### `addFeature(feature)`
248
+
249
+ Add a feature directly to the map without a draw session — e.g. loading in existing shapes on `draw:ready`.
250
+
251
+ | Argument | Type | Description |
252
+ |----------|------|-------------|
253
+ | `feature.id` | `string` | **Required.** Feature ID |
254
+ | `feature.geometry` | `GeoJSON.Geometry` | **Required.** `Polygon` or `LineString` geometry |
255
+ | `feature.stroke` | `string \| Record<string, string>` | Stroke colour |
256
+ | `feature.fill` | `string \| Record<string, string>` | Fill colour |
257
+ | `feature.strokeWidth` | `number` | Stroke width in pixels |
258
+ | `feature.properties` | `Object` | Custom GeoJSON properties |
259
+
260
+ ```js
261
+ interactiveMap.on('draw:ready', () => {
262
+ drawPlugin.addFeature({
263
+ id: 'test1234',
264
+ type: 'Feature',
265
+ geometry: { type: 'Polygon', coordinates: [[[-2.879, 54.709], [-2.877, 54.708], [-2.875, 54.708], [-2.879, 54.709]]] },
266
+ stroke: 'rgba(0,112,60,1)',
267
+ fill: 'rgba(0,112,60,0.2)',
268
+ strokeWidth: 2
269
+ })
270
+ })
271
+ ```
272
+
273
+ ---
274
+
275
+ ### `deleteFeature(featureIds)`
276
+
277
+ Remove one or more features from the map.
278
+
279
+ | Argument | Type | Description |
280
+ |----------|------|-------------|
281
+ | `featureIds` | `string[]` | IDs of the features to remove |
282
+
283
+ ```js
284
+ drawPlugin.deleteFeature(['test1234'])
285
+ ```
286
+
287
+ ---
288
+
289
+ ### `split(featureId, options?)`
290
+
291
+ Start drawing a line across a polygon to split it in two. Splitting is a pure computation — it does not remove the original feature or add the results itself. Listen for [`draw:split`](#drawsplit) and call `deleteFeature`/`addFeature` yourself.
292
+
293
+ Always snaps to the polygon's own outline, in addition to any layers in `snapLayers`.
294
+
295
+ | Argument | Type | Description |
296
+ |----------|------|-------------|
297
+ | `featureId` | `string` | **Required.** ID of the polygon to split |
298
+ | `options.snapLayers` | `string[]` | Additional layers to snap against, on top of the polygon's own outline |
299
+
300
+ ```js
301
+ drawPlugin.split(selectedFeatureId)
302
+
303
+ interactiveMap.on('draw:split', (e) => {
304
+ drawPlugin.deleteFeature([e.originalFeatureId])
305
+ e.featureCollection.features.forEach((feature, index) => {
306
+ drawPlugin.addFeature({
307
+ id: `${e.originalFeatureId}-${index === 0 ? 'a' : 'b'}`,
308
+ type: feature.type,
309
+ geometry: feature.geometry,
310
+ properties: feature.properties
311
+ })
312
+ })
313
+ })
314
+ ```
315
+
316
+ ---
317
+
318
+ ### `merge(featureIds)`
319
+
320
+ Merge multiple contiguous polygons into one. Like `split`, this is a pure computation — it does not touch the map. Listen for the return value or [`draw:merge`](#drawmerge) and call `deleteFeature`/`addFeature` yourself.
321
+
322
+ | Argument | Type | Description |
323
+ |----------|------|-------------|
324
+ | `featureIds` | `string[]` | IDs of the polygons to merge |
325
+
326
+ **Returns:** the merged GeoJSON feature, or `null` if the merge failed (e.g. the polygons aren't actually contiguous).
327
+
328
+ ```js
329
+ drawPlugin.merge(selectedFeatureIds)
330
+
331
+ interactiveMap.on('draw:merge', (e) => {
332
+ drawPlugin.deleteFeature(e.originalFeatureIds)
333
+ drawPlugin.addFeature({
334
+ id: e.originalFeatureIds[0],
335
+ type: e.feature.type,
336
+ geometry: e.feature.geometry,
337
+ properties: e.feature.properties
338
+ })
339
+ })
340
+ ```
341
+
342
+ ## Buttons and keyboard shortcuts
343
+
344
+ The plugin registers its own toolbar buttons automatically — Cancel, Add point (touch only), Done, and a Draw actions menu (Undo, Snap to feature, Delete point) — which show and enable themselves based on the current draw/edit state. You don't need to render these yourself; augment them with your own trigger buttons (e.g. "Draw polygon", "Draw line") the way the [Draw tools example](../examples/draw-tools.mdx) does.
345
+
346
+ | Shortcut | Action |
347
+ |----------|--------|
348
+ | <kbd>Enter</kbd> | Add point (draw) |
349
+ | <kbd>Spacebar</kbd> | Select nearest point (edit) |
350
+ | <kbd>Alt</kbd> + <kbd>↑</kbd>/<kbd>↓</kbd>/<kbd>←</kbd>/<kbd>→</kbd> | Select adjacent point (edit) |
351
+ | <kbd>↑</kbd>/<kbd>↓</kbd>/<kbd>←</kbd>/<kbd>→</kbd> | Move point (edit) |
352
+ | <kbd>Shift</kbd> + <kbd>↑</kbd>/<kbd>↓</kbd>/<kbd>←</kbd>/<kbd>→</kbd> | Nudge point, fine step (edit) |
353
+ | <kbd>Delete</kbd> | Delete point (edit) |
354
+ | <kbd>Command</kbd>/<kbd>Ctrl</kbd> + <kbd>Z</kbd> | Undo |
355
+
356
+ A selected edit vertex also claims the map's [`enableMoveControl`](../api.md#enablemovecontrol) D-pad, if enabled, so it can be nudged with the on-screen directional buttons as well as the keyboard.
357
+
358
+ ## Events
359
+
360
+ Subscribe to events using `interactiveMap.on()`.
361
+
362
+ ---
363
+
364
+ ### `draw:ready`
365
+
366
+ Emitted once the draw plugin has initialised. Safe to call API methods from here.
367
+
368
+ **Payload:** None
369
+
370
+ ---
371
+
372
+ ### `draw:started`
373
+
374
+ Emitted when `newPolygon` or `newLine` starts a new draw session.
375
+
376
+ **Payload:** `{ mode: 'draw_polygon' | 'draw_line' }`
377
+
378
+ ---
379
+
380
+ ### `draw:editstart`
381
+
382
+ Emitted when `editFeature` opens an existing feature for editing.
383
+
384
+ **Payload:** `{ mode: 'edit_polygon' | 'edit_line' }`
385
+
386
+ ---
387
+
388
+ ### `draw:created`
389
+
390
+ Emitted when a new shape finishes drawing and passes validation. Also fires for a shape that finished invalid, was automatically reopened in edit mode, and was then fixed and finished — from the caller's perspective it's still a creation, not an edit.
391
+
392
+ **Payload:** the finished `GeoJSON.Feature`
393
+
394
+ ---
395
+
396
+ ### `draw:edited`
397
+
398
+ Emitted when an existing feature finishes an edit session (via `editFeature`).
399
+
400
+ **Payload:** the edited `GeoJSON.Feature`
401
+
402
+ ---
403
+
404
+ ### `draw:cancelled`
405
+
406
+ Emitted when the Cancel button is pressed during a draw or edit session.
407
+
408
+ **Payload:** the feature being drawn/edited at the time of cancellation
409
+
410
+ ---
411
+
412
+ ### `draw:updated`
413
+
414
+ Emitted after a committed vertex operation (add/move/insert/delete) while editing.
415
+
416
+ **Payload:** the updated `GeoJSON.Feature`
417
+
418
+ ---
419
+
420
+ ### `draw:vertexselection`
421
+
422
+ Emitted when the selected vertex changes in edit mode.
423
+
424
+ **Payload:** `{ index: number, numVertices: number }` — `index` is `-1` when nothing is selected
425
+
426
+ ---
427
+
428
+ ### `draw:interfacetypechange`
429
+
430
+ Emitted when the input device changes mid-session (e.g. switching from mouse to touch and panning via the Move control) — sync your own `interfaceType` state from this if you're tracking it independently.
431
+
432
+ **Payload:** `{ interfaceType: 'mouse' | 'touch' | 'keyboard' }`
433
+
434
+ ---
435
+
436
+ ### `draw:geometryinvalid`
437
+
438
+ Emitted whenever a validation check — a built-in rule or your `onGeometryChange` callback — fails, alongside the same hint toast shown to the user (skipped only for an in-progress shape that simply hasn't reached its minimum vertex count yet). See [Validation](#validation).
439
+
440
+ **Payload:** `{ feature, reason, phase, mode, vertexIndex? }`
441
+
442
+ ---
443
+
444
+ ### `draw:add`
445
+
446
+ Emitted after `addFeature` adds a feature to the map.
447
+
448
+ **Payload:** the added `GeoJSON.Feature`
449
+
450
+ ---
451
+
452
+ ### `draw:delete`
453
+
454
+ Emitted after `deleteFeature` removes a feature.
455
+
456
+ **Payload:** `{ featureId: string }`
457
+
458
+ ---
459
+
460
+ ### `draw:split`
461
+
462
+ Emitted when `split` computes a successful split.
463
+
464
+ **Payload:** `{ originalFeatureId: string, featureCollection: GeoJSON.FeatureCollection }` — the two resulting polygons
465
+
466
+ ---
467
+
468
+ ### `draw:merge`
469
+
470
+ Emitted when `merge` computes a successful merge.
471
+
472
+ **Payload:** `{ originalFeatureIds: string[], feature: GeoJSON.Feature }` — the single merged polygon
473
+
474
+ ```js
475
+ interactiveMap.on('draw:created', (feature) => {
476
+ console.log('New feature drawn:', feature.id)
477
+ })
478
+
479
+ interactiveMap.on('draw:geometryinvalid', ({ reason }) => {
480
+ console.log('Validation failed:', reason)
481
+ })
482
+ ```
package/docs/plugins.md CHANGED
@@ -32,13 +32,9 @@ The following plugins are in early development. APIs and features may change.
32
32
 
33
33
  Add datasets to your map, configure the display, layer toggling and render a key of symbology.
34
34
 
35
- ### Draw for MapLibre
35
+ ### [Draw](./plugins/draw.md)
36
36
 
37
- Draw lines, polygons and place points using the MapLibre map provider. Includes geometry actions such as split and merge.
38
-
39
- ### Draw for ESRI SDK
40
-
41
- Draw polygons using the Esri map provider.
37
+ Draw and edit polygon and line features, with snapping and validation; polygons can also be split and merged. Works with both the MapLibre and OpenLayers map providers.
42
38
 
43
39
  ### Frame
44
40
 
@@ -61,12 +61,13 @@
61
61
  "/dist/css/",
62
62
  "/dist/umd/",
63
63
  "/providers/maplibre/dist",
64
+ "/plugins/interact/dist",
65
+ "/plugins/search/dist",
66
+ "/plugins/draw/dist",
64
67
  "/providers/beta/open-names/dist",
65
68
  "/plugins/datasets/dist",
66
- "/plugins/interact/dist",
67
69
  "/plugins/beta/map-styles/dist",
68
70
  "/plugins/beta/scale-bar/dist",
69
- "/plugins/search/dist",
70
71
  "/plugins/beta/use-location/dist",
71
72
  "/plugins/beta/draw-ml/dist",
72
73
  "/plugins/beta/frame/dist"
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@defra/interactive-map",
3
- "version": "0.0.37-alpha",
3
+ "version": "0.0.39-alpha",
4
4
  "description": "An accessible map component",
5
5
  "repository": {
6
6
  "type": "git",
@@ -230,9 +230,7 @@
230
230
  "@turf/boolean-valid": "^7.2.0",
231
231
  "@turf/destination": "^7.3.3",
232
232
  "@turf/helpers": "^7.2.0",
233
- "@turf/line-intersect": "^7.3.3",
234
- "@turf/point-to-line-distance": "^7.3.3",
235
- "@turf/polygon-to-line": "^7.3.3",
233
+ "@turf/union": "^7.3.5",
236
234
  "accessible-autocomplete": "^3.0.1",
237
235
  "govuk-frontend": "^5.13.0",
238
236
  "maplibre-gl": "^5.23.0",
@@ -1 +1 @@
1
- import e from"@babel/runtime/helpers/defineProperty";import{useEffect as t}from"preact/compat";import r from"@arcgis/core/widgets/Sketch/SketchViewModel.js";import 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-stop"===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
+ 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_SHOW_HINT:"app:showhint",APP_DISMISS_HINT:"app:dismisshint",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 h(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 g(t){for(var r=1;r<arguments.length;r++){var a=null!=arguments[r]?arguments[r]:{};r%2?h(Object(a),!0).forEach(function(r){e(t,r,a[r])}):Object.getOwnPropertyDescriptors?Object.defineProperties(t,Object.getOwnPropertyDescriptors(a)):h(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:h,mapProvider:g,buttonConfig:P}=e,{eventBus:_}=h,{mapColorScheme:A}=d.mapStyle||{},S=null===(i=null===(p=m.includeModes)||void 0===p?void 0:p.includes(u.mode))||void 0===i||i,O=null!==(l=null===(s=m.excludeModes)||void 0===s?void 0:s.includes(u.mode))&&void 0!==l&&l,b=d.isMapReady&&S&&!O;t(()=>{if(b&&!g.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:g});return g.sketchViewModel=e,g.sketchLayer=t,g.emptySketchLayer=o,_.emit("draw:ready"),()=>{g.sketchViewModel=null,g.sketchLayer=null,g.emptySketchLayer=null}}},[d.isMapReady,u.mode]),t(()=>{if(b&&g.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:h,mode:g,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)},S=()=>_(),O=e=>{if(e){var t=E(e);i.emit("draw:updated",t),h({type:"SET_FEATURE",payload:{tempFeature:t}})}},b=function(){var e=o(function*(){g&&((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&&O(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];O(r)});return function(t){return e.apply(this,arguments)}}();i.on(a.MAP_STYLE_CHANGE,S);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-stop"===r&&(n.isSimple(a.geometry)&&1===a.geometry.rings.length||s.undo()),"reshape-stop"!==r&&"vertex-remove"!==r||O(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,h({type:"SET_MODE",payload:null}),h({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,h({type:"SET_MODE",payload:null}),i.emit("draw:cancelled")},()=>{i.off(a.MAP_STYLE_CHANGE,S),M.remove(),k.remove(),D.remove(),L.remove(),m.onClick=C,y.onClick=j}}({pluginState:y,mapProvider:g,events:c,eventBus:_,buttonConfig:P,mapColorScheme:A});return()=>{e()}}},[b,A,y])},buttons:[g({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),g({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};