@defra/interactive-map 0.0.4-alpha → 0.0.5-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/index.js +1 -1
- package/dist/umd/im-core.js +1 -1
- package/dist/umd/index.js +1 -1
- package/docs/api.md +8 -0
- package/package.json +3 -2
- package/plugins/beta/datasets/dist/esm/im-datasets-plugin.js +2 -1
- package/plugins/beta/datasets/dist/esm/im-datasets-plugin.js.LICENSE.txt +1 -0
- package/plugins/beta/datasets/dist/umd/im-datasets-plugin.js +2 -1
- package/plugins/beta/datasets/dist/umd/im-datasets-plugin.js.LICENSE.txt +1 -0
- package/plugins/beta/datasets/dist/umd/index.js +1 -1
- package/plugins/beta/datasets/src/datasets.js +55 -2
- package/plugins/beta/datasets/src/fetch/createDynamicSource.js +206 -0
- package/plugins/beta/datasets/src/fetch/fetchGeoJSON.js +38 -0
- package/plugins/beta/datasets/src/handleSetMapStyle.js +8 -1
- package/plugins/beta/datasets/src/mapLayers.js +41 -3
- package/plugins/beta/datasets/src/utils/bbox.js +113 -2
- package/plugins/beta/draw-ml/dist/css/index.css +1 -1
- package/plugins/beta/draw-ml/dist/esm/im-draw-ml-plugin.js +1 -1
- package/plugins/beta/draw-ml/dist/umd/im-draw-ml-plugin.js +1 -1
- package/plugins/beta/draw-ml/dist/umd/index.js +1 -1
- package/plugins/beta/draw-ml/src/api/addFeature.js +15 -3
- package/plugins/beta/draw-ml/src/api/editFeature.js +16 -5
- package/plugins/beta/draw-ml/src/api/newLine.js +32 -7
- package/plugins/beta/draw-ml/src/api/newPolygon.js +33 -8
- package/plugins/beta/draw-ml/src/defaults.js +1 -0
- package/plugins/beta/draw-ml/src/draw.scss +23 -0
- package/plugins/beta/draw-ml/src/events.js +55 -113
- package/plugins/beta/draw-ml/src/manifest.js +64 -38
- package/plugins/beta/draw-ml/src/mapboxSnap.js +16 -12
- package/plugins/beta/draw-ml/src/modes/createDrawMode.js +4 -3
- package/plugins/beta/draw-ml/src/modes/editVertex/geometryHelpers.js +135 -0
- package/plugins/beta/draw-ml/src/modes/editVertex/helpers.js +2 -0
- package/plugins/beta/draw-ml/src/modes/editVertex/touchHandlers.js +134 -0
- package/plugins/beta/draw-ml/src/modes/editVertex/undoHandlers.js +133 -0
- package/plugins/beta/draw-ml/src/modes/editVertex/vertexOperations.js +141 -0
- package/plugins/beta/draw-ml/src/modes/editVertex/vertexQueries.js +121 -0
- package/plugins/beta/draw-ml/src/modes/editVertexMode.js +51 -406
- package/plugins/beta/draw-ml/src/utils/flattenStyleProperties.js +49 -0
- package/plugins/beta/frame/dist/esm/im-frame-plugin.js +1 -1
- package/plugins/beta/frame/dist/umd/im-frame-plugin.js +1 -1
- package/plugins/beta/frame/src/Frame.jsx +1 -1
- package/plugins/beta/map-styles/dist/css/index.css +1 -1
- package/plugins/beta/map-styles/dist/esm/index.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/beta/map-styles/src/mapStyles.scss +4 -1
- package/plugins/interact/dist/css/index.css +1 -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/InteractInit.jsx +1 -1
- package/plugins/interact/src/defaults.js +1 -0
- package/plugins/interact/src/events.js +37 -52
- package/plugins/interact/src/events.test.js +35 -0
- package/plugins/interact/src/hooks/useHighlightSync.js +1 -1
- package/plugins/interact/src/hooks/useInteractionHandlers.js +80 -48
- package/plugins/interact/src/hooks/useInteractionHandlers.test.js +64 -8
- package/plugins/interact/src/interact.scss +6 -0
- package/plugins/interact/src/reducer.js +25 -27
- package/plugins/interact/src/reducer.test.js +19 -6
- package/plugins/interact/src/utils/featureQueries.js +2 -2
- package/plugins/interact/src/utils/spatial.js +95 -0
- package/plugins/interact/src/utils/spatial.test.js +93 -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/umd/im-search-plugin.js +1 -1
- package/plugins/search/dist/umd/index.js +1 -1
- package/plugins/search/src/Search.jsx +2 -2
- package/plugins/search/src/components/Form/Form.jsx +1 -1
- package/plugins/search/src/components/Suggestions/Suggestions.jsx +5 -5
- package/plugins/search/src/datasets.js +1 -1
- package/plugins/search/src/defaults.js +3 -0
- package/plugins/search/src/events/fetchSuggestions.js +48 -53
- package/plugins/search/src/events/formHandlers.js +3 -2
- package/plugins/search/src/events/index.js +1 -1
- package/plugins/search/src/events/inputHandlers.js +3 -1
- package/plugins/search/src/events/suggestionHandlers.js +12 -3
- package/plugins/search/src/search.scss +4 -1
- package/plugins/search/src/utils/parseOsNamesResults.js +12 -12
- package/providers/beta/esri/src/esriProvider.js +1 -1
- package/providers/beta/esri/src/index.js +1 -1
- package/providers/maplibre/dist/esm/im-maplibre-provider.js +1 -1
- package/providers/maplibre/dist/esm/index.js +1 -1
- package/providers/maplibre/dist/umd/im-maplibre-framework.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/defaults.js +3 -2
- package/providers/maplibre/src/index.js +22 -19
- package/providers/maplibre/src/maplibreProvider.js +13 -11
- package/providers/maplibre/src/utils/detectWebgl.js +1 -2
- package/providers/maplibre/src/utils/highlightFeatures.js +78 -67
- package/providers/maplibre/src/utils/labels.js +174 -120
- package/providers/maplibre/src/utils/maplibreFixes.js +2 -2
- package/providers/maplibre/src/utils/queryFeatures.js +146 -0
- package/providers/maplibre/src/utils/spatial.js +14 -17
- package/sonar-project.properties +39 -2
- package/src/App/components/Actions/Actions.jsx +2 -2
- package/src/App/components/Actions/Actions.module.scss +2 -2
- package/src/App/components/KeyboardHelp/KeyboardHelp.jsx +3 -1
- package/src/App/components/KeyboardHelp/KeyboardHelp.test.jsx +9 -0
- package/src/App/components/Logo/Logo.jsx +1 -1
- package/src/App/components/MapButton/MapButton.jsx +217 -41
- package/src/App/components/MapButton/MapButton.module.scss +32 -21
- package/src/App/components/MapButton/MapButton.test.jsx +128 -84
- package/src/App/components/Markers/Markers.jsx +1 -1
- package/src/App/components/Markers/Markers.module.scss +0 -5
- package/src/App/components/Panel/Panel.jsx +75 -45
- package/src/App/components/Panel/Panel.module.scss +18 -24
- package/src/App/components/Panel/Panel.test.jsx +18 -0
- package/src/App/components/PopupMenu/PopupMenu.jsx +246 -0
- package/src/App/components/PopupMenu/PopupMenu.module.scss +70 -0
- package/src/App/components/PopupMenu/PopupMenu.test.jsx +304 -0
- package/src/App/components/Tooltip/Tooltip.jsx +4 -2
- package/src/App/components/Tooltip/getTooltipPosition.js +1 -1
- package/src/App/components/Viewport/MapController.jsx +1 -1
- package/src/App/components/Viewport/MapStatus.jsx +1 -1
- package/src/App/components/Viewport/Viewport.jsx +2 -2
- package/src/App/components/Viewport/Viewport.module.scss +2 -2
- package/src/App/controls/keyboardActions.js +3 -2
- package/src/App/controls/keyboardShortcuts.js +4 -2
- package/src/App/hooks/useButtonStateEvaluator.js +58 -45
- package/src/App/hooks/useButtonStateEvaluator.test.js +36 -3
- package/src/App/hooks/useCrossHairAPI.js +49 -47
- package/src/App/hooks/useFocusVisible.js +2 -2
- package/src/App/hooks/useInterfaceAPI.js +16 -4
- package/src/App/hooks/useKeyboardHint.js +1 -1
- package/src/App/hooks/useKeyboardShortcuts.js +4 -2
- package/src/App/hooks/useMapAnnouncements.js +34 -32
- package/src/App/hooks/useMapEvents.js +12 -1
- package/src/App/hooks/useMapProviderOverrides.js +3 -3
- package/src/App/hooks/useMapStateSync.js +7 -1
- package/src/App/hooks/useMapURLSync.js +6 -1
- package/src/App/hooks/useMarkersAPI.js +88 -50
- package/src/App/hooks/useMediaQueryDispatch.test.js +48 -0
- package/src/App/hooks/useModalPanelBehaviour.js +46 -40
- package/src/App/hooks/useResizeObserver.js +2 -2
- package/src/App/initialiseApp.js +45 -38
- package/src/App/layout/Layout.jsx +6 -4
- package/src/App/layout/layout.module.scss +13 -17
- package/src/App/registry/keyboardShortcutRegistry.js +12 -2
- package/src/App/registry/keyboardShortcutRegistry.test.js +28 -0
- package/src/App/registry/mergeManifests.js +1 -1
- package/src/App/registry/panelRegistry.js +1 -1
- package/src/App/registry/panelRegistry.test.js +30 -1
- package/src/App/registry/pluginRegistry.js +14 -51
- package/src/App/registry/pluginRegistry.test.js +54 -6
- package/src/App/renderer/HtmlElementHost.jsx +186 -0
- package/src/App/renderer/HtmlElementHost.test.jsx +231 -0
- package/src/App/renderer/mapButtons.js +11 -8
- package/src/App/renderer/mapButtons.test.js +6 -4
- package/src/App/renderer/mapControls.js +6 -0
- package/src/App/renderer/mapControls.test.js +10 -2
- package/src/App/renderer/mapPanels.js +39 -26
- package/src/App/renderer/mapPanels.test.js +29 -0
- package/src/App/renderer/pluginWrapper.test.js +28 -0
- package/src/App/renderer/slotHelpers.js +60 -0
- package/src/App/renderer/slotHelpers.test.js +82 -0
- package/src/App/store/AppProvider.jsx +3 -0
- package/src/App/store/AppProvider.test.jsx +40 -0
- package/src/App/store/PluginProvider.jsx +7 -5
- package/src/App/store/appActionsMap.js +25 -1
- package/src/App/store/appActionsMap.test.js +21 -0
- package/src/App/store/appReducer.js +1 -0
- package/src/App/store/mapActionsMap.js +12 -24
- package/src/App/store/mapReducer.js +1 -1
- package/src/InteractiveMap/InteractiveMap.js +79 -6
- package/src/InteractiveMap/InteractiveMap.test.js +164 -2
- package/src/InteractiveMap/behaviourController.js +12 -2
- package/src/InteractiveMap/behaviourController.test.js +82 -1
- package/src/InteractiveMap/deviceChecker.js +1 -1
- package/src/InteractiveMap/deviceChecker.test.js +2 -2
- package/src/InteractiveMap/historyManager.js +41 -5
- package/src/InteractiveMap/historyManager.test.js +37 -6
- package/src/InteractiveMap/polyfills.js +39 -0
- package/src/InteractiveMap/polyfills.test.js +127 -0
- package/src/config/appConfig.js +5 -5
- package/src/config/appConfig.test.js +107 -42
- package/src/config/defaults.js +1 -0
- package/src/index.umd.js +1 -1
- package/src/scss/main.scss +1 -0
- package/src/scss/settings/_dimensions.scss +6 -2
- package/src/services/eventBus.test.js +24 -1
- package/src/test-utils.js +1 -0
- package/src/types.js +5 -0
- package/src/utils/detectBreakpoint.js +78 -77
- package/src/utils/detectBreakpoint.test.js +50 -4
- package/src/utils/detectInterfaceType.js +4 -4
- package/src/utils/getIsFullscreen.js +3 -1
- package/src/utils/getSafeZoneInset.js +23 -7
- package/src/utils/getSafeZoneInset.test.js +18 -0
- package/src/utils/mapStateSync.js +3 -3
- package/src/utils/queryString.js +1 -1
- package/src/utils/stringToKebab.js +1 -1
- package/src/utils/toggleInertElements.js +37 -12
- package/webpack.dev.mjs +3 -4
- package/plugins/interact/src/utils/turfHelpers.js +0 -30
- package/plugins/interact/src/utils/turfHelpers.test.js +0 -30
- package/plugins/search/src/utils/fetchDataset.js +0 -23
- package/providers/maplibre/dist/esm/im-maplibre-legacy-framework.js +0 -1
- package/providers/maplibre/dist/umd/im-maplibre-legacy-framework.js +0 -1
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
/*! For license information please see index.js.LICENSE.txt */
|
|
2
|
-
!function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t():"function"==typeof define&&define.amd?define("defra",[],t):"object"==typeof exports?exports.defra=t():(e.defra=e.defra||{},e.defra.drawMLPlugin=t())}(this,()=>(()=>{"use strict";var e,t,r={738(e){e.exports=preactCompat}},n={};function o(e){var t=n[e];if(void 0!==t)return t.exports;var i=n[e]={exports:{}};return r[e].call(i.exports,i,i.exports,o),i.exports}o.m=r,o.d=(e,t)=>{for(var r in t)o.o(t,r)&&!o.o(e,r)&&Object.defineProperty(e,r,{enumerable:!0,get:t[r]})},o.f={},o.e=e=>Promise.all(Object.keys(o.f).reduce((t,r)=>(o.f[r](e,t),t),[])),o.u=e=>"im-draw-ml-plugin.js",o.miniCssF=e=>{},o.g=function(){if("object"==typeof globalThis)return globalThis;try{return this||new Function("return this")()}catch(e){if("object"==typeof window)return window}}(),o.o=(e,t)=>Object.prototype.hasOwnProperty.call(e,t),e={},t="defra.drawMLPlugin:",o.l=(r,n,i,a)=>{if(e[r])e[r].push(n);else{var u,c;if(void 0!==i)for(var f=document.getElementsByTagName("script"),p=0;p<f.length;p++){var l=f[p];if(l.getAttribute("src")==r||l.getAttribute("data-webpack")==t+i){u=l;break}}u||(c=!0,(u=document.createElement("script")).charset="utf-8",o.nc&&u.setAttribute("nonce",o.nc),u.setAttribute("data-webpack",t+i),u.src=r),e[r]=[n];var s=(t,n)=>{u.onerror=u.onload=null,clearTimeout(d);var o=e[r];if(delete e[r],u.parentNode&&u.parentNode.removeChild(u),o&&o.forEach(e=>e(n)),t)return t(n)},d=setTimeout(s.bind(null,void 0,{type:"timeout",target:u}),12e4);u.onerror=s.bind(null,u.onerror),u.onload=s.bind(null,u.onload),c&&document.head.appendChild(u)}},o.r=e=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},(()=>{var e;o.g.importScripts&&(e=o.g.location+"");var t=o.g.document;if(!e&&t&&(t.currentScript&&"SCRIPT"===t.currentScript.tagName.toUpperCase()&&(e=t.currentScript.src),!e)){var r=t.getElementsByTagName("script");if(r.length)for(var n=r.length-1;n>-1&&(!e||!/^http(s?):/.test(e));)e=r[n--].src}if(!e)throw new Error("Automatic publicPath is not supported in this browser");e=e.replace(/^blob:/,"").replace(/#.*$/,"").replace(/\?.*$/,"").replace(/\/[^\/]+$/,"/"),o.p=e})(),(()=>{var e={57:0};o.f.j=(t,r)=>{var n=o.o(e,t)?e[t]:void 0;if(0!==n)if(n)r.push(n[2]);else{var i=new Promise((r,o)=>n=e[t]=[r,o]);r.push(n[2]=i);var a=o.p+o.u(t),u=new Error;o.l(a,r=>{if(o.o(e,t)&&(0!==(n=e[t])&&(e[t]=void 0),n)){var i=r&&("load"===r.type?"missing":r.type),a=r&&r.target&&r.target.src;u.message="Loading chunk "+t+" failed.\n("+i+": "+a+")",u.name="ChunkLoadError",u.type=i,u.request=a,n[1](u)}},"chunk-"+t,t)}};var t=(t,r)=>{var n,i,[a,u,c]=r,f=0;if(a.some(t=>0!==e[t])){for(n in u)o.o(u,n)&&(o.m[n]=u[n]);c&&c(o)}for(t&&t(r);f<a.length;f++)i=a[f],o.o(e,i)&&e[i]&&e[i][0](),e[i]=0},r=this.webpackChunkdefra_DefraMap=this.webpackChunkdefra_DefraMap||[];r.forEach(t.bind(null,0)),r.push=t.bind(null,r.push.bind(r))})();var i={};function a(e){return a="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},a(e)}function u(){var e,t,r="function"==typeof Symbol?Symbol:{},n=r.iterator||"@@iterator",o=r.toStringTag||"@@toStringTag";function i(r,n,o,i){var u=n&&n.prototype instanceof f?n:f,p=Object.create(u.prototype);return c(p,"_invoke",function(r,n,o){var i,u,c,f=0,p=o||[],l=!1,s={p:0,n:0,v:e,a:d,f:d.bind(e,4),d:function(t,r){return i=t,u=0,c=e,s.n=r,a}};function d(r,n){for(u=r,c=n,t=0;!l&&f&&!o&&t<p.length;t++){var o,i=p[t],d=s.p,b=i[2];r>3?(o=b===n)&&(c=i[(u=i[4])?5:(u=3,3)],i[4]=i[5]=e):i[0]<=d&&((o=r<2&&d<i[1])?(u=0,s.v=n,s.n=i[1]):d<b&&(o=r<3||i[0]>n||n>b)&&(i[4]=r,i[5]=n,s.n=b,u=0))}if(o||r>1)return a;throw l=!0,n}return function(o,p,b){if(f>1)throw TypeError("Generator is already running");for(l&&1===p&&d(p,b),u=p,c=b;(t=u<2?e:c)||!l;){i||(u?u<3?(u>1&&(s.n=-1),d(u,c)):s.n=c:s.v=c);try{if(f=2,i){if(u||(o="next"),t=i[o]){if(!(t=t.call(i,c)))throw TypeError("iterator result is not an object");if(!t.done)return t;c=t.value,u<2&&(u=0)}else 1===u&&(t=i.return)&&t.call(i),u<2&&(c=TypeError("The iterator does not provide a '"+o+"' method"),u=1);i=e}else if((t=(l=s.n<0)?c:r.call(n,s))!==a)break}catch(t){i=e,u=1,c=t}finally{f=1}}return{value:t,done:l}}}(r,o,i),!0),p}var a={};function f(){}function p(){}function l(){}t=Object.getPrototypeOf;var s=[][n]?t(t([][n]())):(c(t={},n,function(){return this}),t),d=l.prototype=f.prototype=Object.create(s);function b(e){return Object.setPrototypeOf?Object.setPrototypeOf(e,l):(e.__proto__=l,c(e,o,"GeneratorFunction")),e.prototype=Object.create(d),e}return p.prototype=l,c(d,"constructor",l),c(l,"constructor",p),p.displayName="GeneratorFunction",c(l,o,"GeneratorFunction"),c(d),c(d,o,"Generator"),c(d,n,function(){return this}),c(d,"toString",function(){return"[object Generator]"}),(u=function(){return{w:i,m:b}})()}function c(e,t,r,n){var o=Object.defineProperty;try{o({},"",{})}catch(e){o=0}c=function(e,t,r,n){function i(t,r){c(e,t,function(e){return this._invoke(t,r,e)})}t?o?o(e,t,{value:r,enumerable:!n,configurable:!n,writable:!n}):e[t]=r:(i("next",0),i("throw",1),i("return",2))},c(e,t,r,n)}function f(e,t,r,n,o,i,a){try{var u=e[i](a),c=u.value}catch(e){return void r(e)}u.done?t(c):Promise.resolve(c).then(n,o)}function p(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter(function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable})),r.push.apply(r,n)}return r}function l(e){for(var t=1;t<arguments.length;t++){var r=null!=arguments[t]?arguments[t]:{};t%2?p(Object(r),!0).forEach(function(t){s(e,t,r[t])}):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(r)):p(Object(r)).forEach(function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(r,t))})}return e}function s(e,t,r){return(t=function(e){var t=function(e){if("object"!=a(e)||!e)return e;var t=e[Symbol.toPrimitive];if(void 0!==t){var r=t.call(e,"string");if("object"!=a(r))return r;throw new TypeError("@@toPrimitive must return a primitive value.")}return String(e)}(e);return"symbol"==a(t)?t:t+""}(t))in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function d(){var e,t;return l(l({},arguments.length>0&&void 0!==arguments[0]?arguments[0]:{}),{},{id:"draw",load:(e=u().m(function e(){var t;return u().w(function(e){for(;;)switch(e.n){case 0:return e.n=1,o.e(966).then(o.bind(o,
|
|
2
|
+
!function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t():"function"==typeof define&&define.amd?define("defra",[],t):"object"==typeof exports?exports.defra=t():(e.defra=e.defra||{},e.defra.drawMLPlugin=t())}(this,()=>(()=>{"use strict";var e,t,r={738(e){e.exports=preactCompat}},n={};function o(e){var t=n[e];if(void 0!==t)return t.exports;var i=n[e]={exports:{}};return r[e].call(i.exports,i,i.exports,o),i.exports}o.m=r,o.d=(e,t)=>{for(var r in t)o.o(t,r)&&!o.o(e,r)&&Object.defineProperty(e,r,{enumerable:!0,get:t[r]})},o.f={},o.e=e=>Promise.all(Object.keys(o.f).reduce((t,r)=>(o.f[r](e,t),t),[])),o.u=e=>"im-draw-ml-plugin.js",o.miniCssF=e=>{},o.g=function(){if("object"==typeof globalThis)return globalThis;try{return this||new Function("return this")()}catch(e){if("object"==typeof window)return window}}(),o.o=(e,t)=>Object.prototype.hasOwnProperty.call(e,t),e={},t="defra.drawMLPlugin:",o.l=(r,n,i,a)=>{if(e[r])e[r].push(n);else{var u,c;if(void 0!==i)for(var f=document.getElementsByTagName("script"),p=0;p<f.length;p++){var l=f[p];if(l.getAttribute("src")==r||l.getAttribute("data-webpack")==t+i){u=l;break}}u||(c=!0,(u=document.createElement("script")).charset="utf-8",o.nc&&u.setAttribute("nonce",o.nc),u.setAttribute("data-webpack",t+i),u.src=r),e[r]=[n];var s=(t,n)=>{u.onerror=u.onload=null,clearTimeout(d);var o=e[r];if(delete e[r],u.parentNode&&u.parentNode.removeChild(u),o&&o.forEach(e=>e(n)),t)return t(n)},d=setTimeout(s.bind(null,void 0,{type:"timeout",target:u}),12e4);u.onerror=s.bind(null,u.onerror),u.onload=s.bind(null,u.onload),c&&document.head.appendChild(u)}},o.r=e=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},(()=>{var e;o.g.importScripts&&(e=o.g.location+"");var t=o.g.document;if(!e&&t&&(t.currentScript&&"SCRIPT"===t.currentScript.tagName.toUpperCase()&&(e=t.currentScript.src),!e)){var r=t.getElementsByTagName("script");if(r.length)for(var n=r.length-1;n>-1&&(!e||!/^http(s?):/.test(e));)e=r[n--].src}if(!e)throw new Error("Automatic publicPath is not supported in this browser");e=e.replace(/^blob:/,"").replace(/#.*$/,"").replace(/\?.*$/,"").replace(/\/[^\/]+$/,"/"),o.p=e})(),(()=>{var e={57:0};o.f.j=(t,r)=>{var n=o.o(e,t)?e[t]:void 0;if(0!==n)if(n)r.push(n[2]);else{var i=new Promise((r,o)=>n=e[t]=[r,o]);r.push(n[2]=i);var a=o.p+o.u(t),u=new Error;o.l(a,r=>{if(o.o(e,t)&&(0!==(n=e[t])&&(e[t]=void 0),n)){var i=r&&("load"===r.type?"missing":r.type),a=r&&r.target&&r.target.src;u.message="Loading chunk "+t+" failed.\n("+i+": "+a+")",u.name="ChunkLoadError",u.type=i,u.request=a,n[1](u)}},"chunk-"+t,t)}};var t=(t,r)=>{var n,i,[a,u,c]=r,f=0;if(a.some(t=>0!==e[t])){for(n in u)o.o(u,n)&&(o.m[n]=u[n]);c&&c(o)}for(t&&t(r);f<a.length;f++)i=a[f],o.o(e,i)&&e[i]&&e[i][0](),e[i]=0},r=this.webpackChunkdefra_DefraMap=this.webpackChunkdefra_DefraMap||[];r.forEach(t.bind(null,0)),r.push=t.bind(null,r.push.bind(r))})();var i={};function a(e){return a="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},a(e)}function u(){var e,t,r="function"==typeof Symbol?Symbol:{},n=r.iterator||"@@iterator",o=r.toStringTag||"@@toStringTag";function i(r,n,o,i){var u=n&&n.prototype instanceof f?n:f,p=Object.create(u.prototype);return c(p,"_invoke",function(r,n,o){var i,u,c,f=0,p=o||[],l=!1,s={p:0,n:0,v:e,a:d,f:d.bind(e,4),d:function(t,r){return i=t,u=0,c=e,s.n=r,a}};function d(r,n){for(u=r,c=n,t=0;!l&&f&&!o&&t<p.length;t++){var o,i=p[t],d=s.p,b=i[2];r>3?(o=b===n)&&(c=i[(u=i[4])?5:(u=3,3)],i[4]=i[5]=e):i[0]<=d&&((o=r<2&&d<i[1])?(u=0,s.v=n,s.n=i[1]):d<b&&(o=r<3||i[0]>n||n>b)&&(i[4]=r,i[5]=n,s.n=b,u=0))}if(o||r>1)return a;throw l=!0,n}return function(o,p,b){if(f>1)throw TypeError("Generator is already running");for(l&&1===p&&d(p,b),u=p,c=b;(t=u<2?e:c)||!l;){i||(u?u<3?(u>1&&(s.n=-1),d(u,c)):s.n=c:s.v=c);try{if(f=2,i){if(u||(o="next"),t=i[o]){if(!(t=t.call(i,c)))throw TypeError("iterator result is not an object");if(!t.done)return t;c=t.value,u<2&&(u=0)}else 1===u&&(t=i.return)&&t.call(i),u<2&&(c=TypeError("The iterator does not provide a '"+o+"' method"),u=1);i=e}else if((t=(l=s.n<0)?c:r.call(n,s))!==a)break}catch(t){i=e,u=1,c=t}finally{f=1}}return{value:t,done:l}}}(r,o,i),!0),p}var a={};function f(){}function p(){}function l(){}t=Object.getPrototypeOf;var s=[][n]?t(t([][n]())):(c(t={},n,function(){return this}),t),d=l.prototype=f.prototype=Object.create(s);function b(e){return Object.setPrototypeOf?Object.setPrototypeOf(e,l):(e.__proto__=l,c(e,o,"GeneratorFunction")),e.prototype=Object.create(d),e}return p.prototype=l,c(d,"constructor",l),c(l,"constructor",p),p.displayName="GeneratorFunction",c(l,o,"GeneratorFunction"),c(d),c(d,o,"Generator"),c(d,n,function(){return this}),c(d,"toString",function(){return"[object Generator]"}),(u=function(){return{w:i,m:b}})()}function c(e,t,r,n){var o=Object.defineProperty;try{o({},"",{})}catch(e){o=0}c=function(e,t,r,n){function i(t,r){c(e,t,function(e){return this._invoke(t,r,e)})}t?o?o(e,t,{value:r,enumerable:!n,configurable:!n,writable:!n}):e[t]=r:(i("next",0),i("throw",1),i("return",2))},c(e,t,r,n)}function f(e,t,r,n,o,i,a){try{var u=e[i](a),c=u.value}catch(e){return void r(e)}u.done?t(c):Promise.resolve(c).then(n,o)}function p(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter(function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable})),r.push.apply(r,n)}return r}function l(e){for(var t=1;t<arguments.length;t++){var r=null!=arguments[t]?arguments[t]:{};t%2?p(Object(r),!0).forEach(function(t){s(e,t,r[t])}):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(r)):p(Object(r)).forEach(function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(r,t))})}return e}function s(e,t,r){return(t=function(e){var t=function(e){if("object"!=a(e)||!e)return e;var t=e[Symbol.toPrimitive];if(void 0!==t){var r=t.call(e,"string");if("object"!=a(r))return r;throw new TypeError("@@toPrimitive must return a primitive value.")}return String(e)}(e);return"symbol"==a(t)?t:t+""}(t))in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function d(){var e,t;return l(l({},arguments.length>0&&void 0!==arguments[0]?arguments[0]:{}),{},{id:"draw",load:(e=u().m(function e(){var t;return u().w(function(e){for(;;)switch(e.n){case 0:return e.n=1,o.e(966).then(o.bind(o,133));case 1:return t=e.v.manifest,e.a(2,t)}},e)}),t=function(){var t=this,r=arguments;return new Promise(function(n,o){var i=e.apply(t,r);function a(e){f(i,n,o,a,u,"next",e)}function u(e){f(i,n,o,a,u,"throw",e)}a(void 0)})},function(){return t.apply(this,arguments)})})}return o.d(i,{default:()=>d}),i.default})());
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { flattenStyleProperties } from '../utils/flattenStyleProperties.js'
|
|
2
|
+
|
|
1
3
|
export const addFeature = ({ mapProvider, services }, feature) => {
|
|
2
4
|
const { draw } = mapProvider
|
|
3
5
|
const { eventBus } = services
|
|
@@ -6,10 +8,20 @@ export const addFeature = ({ mapProvider, services }, feature) => {
|
|
|
6
8
|
return
|
|
7
9
|
}
|
|
8
10
|
|
|
11
|
+
// Extract style props from top level, flatten variants, merge with custom properties
|
|
12
|
+
const { stroke, fill, strokeWidth, properties, ...rest } = feature
|
|
13
|
+
const flatFeature = {
|
|
14
|
+
...rest,
|
|
15
|
+
properties: {
|
|
16
|
+
...properties,
|
|
17
|
+
...flattenStyleProperties({ stroke, fill, strokeWidth })
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
|
|
9
21
|
// --- Add feature to draw instance
|
|
10
|
-
draw.add(
|
|
22
|
+
draw.add(flatFeature, {
|
|
11
23
|
userProperties: true
|
|
12
24
|
})
|
|
13
25
|
|
|
14
|
-
eventBus.emit('draw:add',
|
|
15
|
-
}
|
|
26
|
+
eventBus.emit('draw:add', flatFeature)
|
|
27
|
+
}
|
|
@@ -6,7 +6,7 @@ import { getSnapInstance } from '../utils/snapHelpers.js'
|
|
|
6
6
|
* @param {string} featureId - ID of the feature to edit
|
|
7
7
|
* @param {object} options - Options including snapLayers
|
|
8
8
|
*/
|
|
9
|
-
export const editFeature = ({ appState, appConfig, mapState, pluginState, mapProvider }, featureId, options = {}) => {
|
|
9
|
+
export const editFeature = ({ appState, appConfig, mapState, pluginConfig, pluginState, mapProvider }, featureId, options = {}) => {
|
|
10
10
|
const { dispatch } = pluginState
|
|
11
11
|
const { draw, map } = mapProvider
|
|
12
12
|
|
|
@@ -14,24 +14,35 @@ export const editFeature = ({ appState, appConfig, mapState, pluginState, mapPro
|
|
|
14
14
|
return
|
|
15
15
|
}
|
|
16
16
|
|
|
17
|
+
// Determin snapLayers from pluginConfig or runtime config
|
|
18
|
+
let snapLayers = null
|
|
19
|
+
if (options.snapLayers !== undefined) {
|
|
20
|
+
snapLayers = options.snapLayers
|
|
21
|
+
} else if (pluginConfig.snapLayers !== undefined) {
|
|
22
|
+
snapLayers = pluginConfig.snapLayers
|
|
23
|
+
} else {
|
|
24
|
+
snapLayers = null
|
|
25
|
+
}
|
|
26
|
+
|
|
17
27
|
// Set per-call snap layers if provided
|
|
18
28
|
const snap = getSnapInstance(map)
|
|
19
29
|
if (snap?.setSnapLayers) {
|
|
20
|
-
snap.setSnapLayers(
|
|
21
|
-
} else if (
|
|
30
|
+
snap.setSnapLayers(snapLayers)
|
|
31
|
+
} else if (snapLayers) {
|
|
22
32
|
// Snap instance not ready yet - store for later
|
|
23
|
-
map._pendingSnapLayers =
|
|
33
|
+
map._pendingSnapLayers = snapLayers
|
|
24
34
|
} else {
|
|
25
35
|
// No action
|
|
26
36
|
}
|
|
27
37
|
|
|
28
38
|
// Update state so UI can react to snap layer availability
|
|
29
|
-
dispatch({ type: 'SET_HAS_SNAP_LAYERS', payload:
|
|
39
|
+
dispatch({ type: 'SET_HAS_SNAP_LAYERS', payload: snapLayers?.length > 0 })
|
|
30
40
|
|
|
31
41
|
// Change mode to edit_vertex
|
|
32
42
|
draw.changeMode('edit_vertex', {
|
|
33
43
|
container: appState.layoutRefs.viewportRef.current,
|
|
34
44
|
deleteVertexButtonId: `${appConfig.id}-draw-delete-point`,
|
|
45
|
+
undoButtonId: `${appConfig.id}-draw-undo`,
|
|
35
46
|
isPanEnabled: appState.interfaceType !== 'keyboard',
|
|
36
47
|
interfaceType: appState.interfaceType,
|
|
37
48
|
scale: { small: 1, medium: 1.5, large: 2 }[mapState.mapSize],
|
|
@@ -1,32 +1,55 @@
|
|
|
1
1
|
import { getSnapInstance } from '../utils/snapHelpers.js'
|
|
2
|
+
import { flattenStyleProperties } from '../utils/flattenStyleProperties.js'
|
|
3
|
+
import { DEFAULTS } from '../defaults.js'
|
|
2
4
|
|
|
3
5
|
/**
|
|
4
6
|
* Programmatically create a new line
|
|
5
7
|
* @param {object} context - plugin context
|
|
6
8
|
* @param {string} featureId - ID for the new feature
|
|
7
|
-
* @param {object} options - Options including snapLayers.
|
|
9
|
+
* @param {object} options - Options including snapLayers, stroke, fill, strokeWidth, properties.
|
|
8
10
|
*/
|
|
9
|
-
export const newLine = ({ appState, appConfig, pluginState, mapProvider }, featureId, options = {}) => {
|
|
11
|
+
export const newLine = ({ appState, appConfig, pluginConfig, pluginState, mapProvider, services }, featureId, options = {}) => {
|
|
10
12
|
const { dispatch } = pluginState
|
|
11
13
|
const { draw, map } = mapProvider
|
|
14
|
+
const { eventBus } = services
|
|
12
15
|
|
|
13
16
|
if (!draw) {
|
|
14
17
|
return
|
|
15
18
|
}
|
|
16
19
|
|
|
20
|
+
// Emit draw:start
|
|
21
|
+
eventBus.emit('draw:start', { mode: 'draw_line' })
|
|
22
|
+
|
|
23
|
+
// Determin snapLayers from pluginConfig or runtime config
|
|
24
|
+
let snapLayers = null
|
|
25
|
+
if (options.snapLayers !== undefined) {
|
|
26
|
+
snapLayers = options.snapLayers
|
|
27
|
+
} else if (pluginConfig.snapLayers !== undefined) {
|
|
28
|
+
snapLayers = pluginConfig.snapLayers
|
|
29
|
+
} else {
|
|
30
|
+
snapLayers = null
|
|
31
|
+
}
|
|
32
|
+
|
|
17
33
|
// Set per-call snap layers if provided
|
|
18
34
|
const snap = getSnapInstance(map)
|
|
19
35
|
if (snap?.setSnapLayers) {
|
|
20
|
-
snap.setSnapLayers(
|
|
21
|
-
} else if (
|
|
36
|
+
snap.setSnapLayers(snapLayers)
|
|
37
|
+
} else if (snapLayers) {
|
|
22
38
|
// Snap instance not ready yet - store for later
|
|
23
|
-
map._pendingSnapLayers =
|
|
39
|
+
map._pendingSnapLayers = snapLayers
|
|
24
40
|
} else {
|
|
25
41
|
// No action
|
|
26
42
|
}
|
|
27
43
|
|
|
28
44
|
// Update state so UI can react to snap layer availability
|
|
29
|
-
dispatch({ type: 'SET_HAS_SNAP_LAYERS', payload:
|
|
45
|
+
dispatch({ type: 'SET_HAS_SNAP_LAYERS', payload: snapLayers?.length > 0 })
|
|
46
|
+
|
|
47
|
+
// Extract style props and flatten variants into properties
|
|
48
|
+
const { stroke, fill, strokeWidth, properties: customProperties, ...modeOptions } = options
|
|
49
|
+
const properties = {
|
|
50
|
+
...customProperties,
|
|
51
|
+
...flattenStyleProperties({ stroke, fill, strokeWidth })
|
|
52
|
+
}
|
|
30
53
|
|
|
31
54
|
// Change mode to draw_line
|
|
32
55
|
draw.changeMode('draw_line', {
|
|
@@ -35,7 +58,9 @@ export const newLine = ({ appState, appConfig, pluginState, mapProvider }, featu
|
|
|
35
58
|
addVertexButtonId: `${appConfig.id}-draw-add-point`,
|
|
36
59
|
interfaceType: appState.interfaceType,
|
|
37
60
|
getSnapEnabled: () => mapProvider.snapEnabled === true,
|
|
38
|
-
featureId
|
|
61
|
+
featureId,
|
|
62
|
+
...modeOptions,
|
|
63
|
+
properties
|
|
39
64
|
})
|
|
40
65
|
|
|
41
66
|
// Set mode to draw_line
|
|
@@ -1,32 +1,55 @@
|
|
|
1
1
|
import { getSnapInstance } from '../utils/snapHelpers.js'
|
|
2
|
+
import { flattenStyleProperties } from '../utils/flattenStyleProperties.js'
|
|
3
|
+
import { DEFAULTS } from '../defaults.js'
|
|
2
4
|
|
|
3
5
|
/**
|
|
4
6
|
* Programmatically create a new polygon
|
|
5
7
|
* @param {object} context - plugin context
|
|
6
8
|
* @param {string} featureId - ID for the new feature
|
|
7
|
-
* @param {object} options - Options including snapLayers.
|
|
9
|
+
* @param {object} options - Options including snapLayers, stroke, fill, strokeWidth, properties.
|
|
8
10
|
*/
|
|
9
|
-
export const newPolygon = ({ appState, appConfig, pluginState, mapProvider }, featureId, options = {}) => {
|
|
11
|
+
export const newPolygon = ({ appState, appConfig, pluginConfig, pluginState, mapProvider, services }, featureId, options = {}) => {
|
|
10
12
|
const { dispatch } = pluginState
|
|
11
13
|
const { draw, map } = mapProvider
|
|
14
|
+
const { eventBus } = services
|
|
12
15
|
|
|
13
16
|
if (!draw) {
|
|
14
17
|
return
|
|
15
18
|
}
|
|
16
19
|
|
|
20
|
+
// Emit draw:start
|
|
21
|
+
eventBus.emit('draw:start', { mode: 'draw_polygon' })
|
|
22
|
+
|
|
23
|
+
// Determin snapLayers from pluginConfig or runtime config
|
|
24
|
+
let snapLayers = null
|
|
25
|
+
if (options.snapLayers !== undefined) {
|
|
26
|
+
snapLayers = options.snapLayers
|
|
27
|
+
} else if (pluginConfig.snapLayers !== undefined) {
|
|
28
|
+
snapLayers = pluginConfig.snapLayers
|
|
29
|
+
} else {
|
|
30
|
+
snapLayers = null
|
|
31
|
+
}
|
|
32
|
+
|
|
17
33
|
// Set per-call snap layers if provided
|
|
18
34
|
const snap = getSnapInstance(map)
|
|
19
35
|
if (snap?.setSnapLayers) {
|
|
20
|
-
snap.setSnapLayers(
|
|
21
|
-
} else if (
|
|
36
|
+
snap.setSnapLayers(snapLayers)
|
|
37
|
+
} else if (snapLayers) {
|
|
22
38
|
// Snap instance not ready yet - store for later
|
|
23
|
-
map._pendingSnapLayers =
|
|
39
|
+
map._pendingSnapLayers = snapLayers
|
|
24
40
|
} else {
|
|
25
41
|
// No action
|
|
26
42
|
}
|
|
27
43
|
|
|
28
44
|
// Update state so UI can react to snap layer availability
|
|
29
|
-
dispatch({ type: 'SET_HAS_SNAP_LAYERS', payload:
|
|
45
|
+
dispatch({ type: 'SET_HAS_SNAP_LAYERS', payload: snapLayers?.length > 0 })
|
|
46
|
+
|
|
47
|
+
// Extract style props and flatten variants into properties
|
|
48
|
+
const { stroke, fill, strokeWidth, properties: customProperties, ...modeOptions } = options
|
|
49
|
+
const properties = {
|
|
50
|
+
...customProperties,
|
|
51
|
+
...flattenStyleProperties({ stroke, fill, strokeWidth })
|
|
52
|
+
}
|
|
30
53
|
|
|
31
54
|
// Change mode to draw_polygon
|
|
32
55
|
draw.changeMode('draw_polygon', {
|
|
@@ -35,9 +58,11 @@ export const newPolygon = ({ appState, appConfig, pluginState, mapProvider }, fe
|
|
|
35
58
|
addVertexButtonId: `${appConfig.id}-draw-add-point`,
|
|
36
59
|
interfaceType: appState.interfaceType,
|
|
37
60
|
getSnapEnabled: () => mapProvider.snapEnabled === true,
|
|
38
|
-
featureId
|
|
61
|
+
featureId,
|
|
62
|
+
...modeOptions,
|
|
63
|
+
properties
|
|
39
64
|
})
|
|
40
65
|
|
|
41
66
|
// Set mode to draw_polygon
|
|
42
67
|
dispatch({ type: 'SET_MODE', payload: 'draw_polygon' })
|
|
43
|
-
}
|
|
68
|
+
}
|
|
@@ -6,4 +6,27 @@
|
|
|
6
6
|
path {
|
|
7
7
|
fill: var(--map-overlay-halo-color);
|
|
8
8
|
}
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
// Ensure action buttons take up same width
|
|
12
|
+
.im-c-actions {
|
|
13
|
+
.im-c-button-wrapper--draw-done,
|
|
14
|
+
.im-c-button-wrapper--draw-menu,
|
|
15
|
+
.im-c-button-wrapper--draw-cancel {
|
|
16
|
+
width: 33.33%;
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
.im-o-app--tablet .im-c-actions,
|
|
20
|
+
.im-o-app--desktop .im-c-actions {
|
|
21
|
+
.im-c-button-wrapper--draw-done,
|
|
22
|
+
.im-c-button-wrapper--draw-menu,
|
|
23
|
+
.im-c-button-wrapper--draw-cancel {
|
|
24
|
+
width: 100px;
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
// Position touch add point button
|
|
29
|
+
.im-c-button-wrapper--draw-add-point {
|
|
30
|
+
position: absolute;
|
|
31
|
+
bottom: calc(100% + var(--primary-gap));
|
|
9
32
|
}
|
|
@@ -1,20 +1,11 @@
|
|
|
1
1
|
import { clearSnapState, getSnapInstance } from './utils/snapHelpers.js'
|
|
2
2
|
|
|
3
|
-
export function attachEvents
|
|
4
|
-
const {
|
|
5
|
-
drawDone,
|
|
6
|
-
drawAddPoint,
|
|
7
|
-
drawUndo,
|
|
8
|
-
drawFinish,
|
|
9
|
-
drawDeletePoint,
|
|
10
|
-
drawSnap,
|
|
11
|
-
drawCancel
|
|
12
|
-
} = buttonConfig
|
|
13
|
-
|
|
3
|
+
export function attachEvents({ pluginState, mapProvider, buttonConfig, eventBus }) {
|
|
4
|
+
const { drawDone, drawAddPoint, drawUndo, drawDeletePoint, drawSnap, drawCancel } = buttonConfig
|
|
14
5
|
const { map, draw } = mapProvider
|
|
15
6
|
const { dispatch, feature, tempFeature } = pluginState
|
|
16
7
|
|
|
17
|
-
// Helper to disable snap
|
|
8
|
+
// --- Helper to disable snap
|
|
18
9
|
const disableSnap = () => {
|
|
19
10
|
mapProvider.snapEnabled = false
|
|
20
11
|
dispatch({ type: 'SET_SNAP', payload: false })
|
|
@@ -28,100 +19,72 @@ export function attachEvents ({ appState, appConfig, mapState, pluginState, mapP
|
|
|
28
19
|
}
|
|
29
20
|
}
|
|
30
21
|
|
|
31
|
-
// ---
|
|
32
|
-
const
|
|
33
|
-
disableSnap()
|
|
22
|
+
// --- Helper to reset draw mode and feature (without touching snap)
|
|
23
|
+
const resetDrawModeAndFeature = () => {
|
|
34
24
|
mapProvider.undoStack?.clear()
|
|
35
|
-
draw.changeMode('disabled')
|
|
36
25
|
dispatch({ type: 'SET_MODE', payload: null })
|
|
37
26
|
dispatch({ type: 'SET_FEATURE', payload: { feature: null, tempFeature: null }})
|
|
38
|
-
eventBus.emit('draw:done', { newFeature: tempFeature })
|
|
39
27
|
}
|
|
40
|
-
drawDone.onClick = handleDone
|
|
41
28
|
|
|
42
|
-
// ---
|
|
43
|
-
const
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
29
|
+
// --- Button handlers
|
|
30
|
+
const handleDone = () => {
|
|
31
|
+
const mode = draw.getMode()
|
|
32
|
+
const features = draw.getAll().features
|
|
33
|
+
const feature = features?.[0]
|
|
47
34
|
|
|
48
|
-
// Reinstate initial feature
|
|
49
|
-
if (feature) {
|
|
50
|
-
draw.add(feature)
|
|
51
|
-
}
|
|
52
35
|
disableSnap()
|
|
53
36
|
mapProvider.undoStack?.clear()
|
|
54
|
-
draw.changeMode('disabled')
|
|
55
37
|
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
eventBus.emit('draw:cancel', { originalFeature: feature })
|
|
59
|
-
}
|
|
60
|
-
drawCancel.onClick = handleCancel
|
|
61
|
-
|
|
62
|
-
// --- Finish shape (programmatically complete the drawing)
|
|
63
|
-
const handleFinish = () => {
|
|
64
|
-
const mode = draw.getMode()
|
|
65
|
-
if (!['draw_polygon', 'draw_line'].includes(mode)) {
|
|
38
|
+
if (mode === 'edit_vertex') {
|
|
39
|
+
map.fire('draw.editfinish', { features: [feature] })
|
|
66
40
|
return
|
|
67
41
|
}
|
|
68
42
|
|
|
69
|
-
|
|
70
|
-
if (features.length === 0) {
|
|
43
|
+
if (!['draw_polygon', 'draw_line'].includes(mode) || features.length === 0) {
|
|
71
44
|
return
|
|
72
45
|
}
|
|
73
46
|
|
|
74
|
-
const feature = features[0]
|
|
75
47
|
const geom = feature.geometry
|
|
76
|
-
|
|
77
|
-
// Remove the rubber band point (last coordinate that follows cursor)
|
|
78
48
|
if (geom.type === 'Polygon') {
|
|
79
|
-
// Polygon coords: [v1, v2, v3, ..., rubberBand, v1(closing)]
|
|
80
|
-
// Remove rubber band (second to last) and keep the ring closed
|
|
81
49
|
const ring = geom.coordinates[0]
|
|
82
50
|
geom.coordinates[0] = [...ring.slice(0, -2), ring[0]]
|
|
83
51
|
} else {
|
|
84
|
-
// Line coords: [v1, v2, v3, ..., rubberBand]
|
|
85
|
-
// Remove the rubber band (last point)
|
|
86
52
|
geom.coordinates = geom.coordinates.slice(0, -1)
|
|
87
53
|
}
|
|
88
54
|
|
|
89
|
-
// Fire draw.create to trigger the standard completion flow
|
|
90
55
|
map.fire('draw.create', { features: [feature] })
|
|
56
|
+
}
|
|
91
57
|
|
|
92
|
-
|
|
93
|
-
|
|
58
|
+
const handleCancel = () => {
|
|
59
|
+
if (tempFeature?.id) {
|
|
60
|
+
draw.delete(tempFeature.id)
|
|
61
|
+
}
|
|
62
|
+
if (feature) {
|
|
63
|
+
draw.add(feature)
|
|
64
|
+
}
|
|
65
|
+
disableSnap()
|
|
66
|
+
draw.changeMode('disabled')
|
|
67
|
+
resetDrawModeAndFeature()
|
|
68
|
+
eventBus.emit('draw:cancel', { originalFeature: feature })
|
|
94
69
|
}
|
|
95
|
-
drawFinish.onClick = handleFinish
|
|
96
70
|
|
|
97
|
-
// --- Undo last action (only for draw modes - edit_vertex handles its own undo)
|
|
98
71
|
const handleUndo = () => {
|
|
99
|
-
// edit_vertex mode handles its own undo via button click listener
|
|
100
72
|
if (draw.getMode() === 'edit_vertex') {
|
|
101
73
|
return
|
|
102
74
|
}
|
|
103
|
-
|
|
104
75
|
const undoStack = mapProvider.undoStack
|
|
105
|
-
if (!undoStack
|
|
76
|
+
if (!undoStack?.length) {
|
|
106
77
|
return
|
|
107
78
|
}
|
|
108
|
-
|
|
109
79
|
const operation = undoStack.pop()
|
|
110
|
-
|
|
111
|
-
// Set flag to prevent button click from also adding a vertex
|
|
112
80
|
map._undoInProgress = true
|
|
113
81
|
setTimeout(() => { map._undoInProgress = false }, 100)
|
|
114
|
-
|
|
115
|
-
// Fire event for the current mode to handle
|
|
116
82
|
map.fire('draw.undo', { operation })
|
|
117
83
|
}
|
|
118
|
-
drawUndo.onClick = handleUndo
|
|
119
84
|
|
|
120
|
-
// --- Snap toggle with throttle to prevent Safari slowdown
|
|
121
85
|
let lastToggleTime = 0
|
|
122
86
|
const THROTTLE_MS = 300
|
|
123
87
|
const handleSnap = () => {
|
|
124
|
-
// Strict throttle - ignore clicks within throttle window
|
|
125
88
|
const now = Date.now()
|
|
126
89
|
if (now - lastToggleTime < THROTTLE_MS) {
|
|
127
90
|
return
|
|
@@ -137,90 +100,69 @@ export function attachEvents ({ appState, appConfig, mapState, pluginState, mapP
|
|
|
137
100
|
snap.setSnapStatus(newSnapState)
|
|
138
101
|
}
|
|
139
102
|
|
|
140
|
-
// Clear all snap state when disabling - prevents accumulation
|
|
141
103
|
if (!newSnapState && snap) {
|
|
142
104
|
clearSnapState(snap)
|
|
143
|
-
// Hide indicator immediately when disabling (single call, not in RAF)
|
|
144
105
|
if (map.getLayer('snap-helper-circle')) {
|
|
145
106
|
map.setLayoutProperty('snap-helper-circle', 'visibility', 'none')
|
|
146
107
|
}
|
|
147
108
|
}
|
|
148
|
-
// When enabling, the indicator will show automatically via setMapData patch
|
|
149
109
|
}
|
|
150
|
-
drawSnap.onClick = handleSnap
|
|
151
110
|
|
|
152
|
-
// --- Map style
|
|
111
|
+
// --- Map style update
|
|
153
112
|
const handleStyleData = () => {
|
|
154
113
|
const layers = map.getStyle().layers || []
|
|
155
|
-
if (layers.length
|
|
114
|
+
if (!layers.length || layers[layers.length - 1].source?.startsWith('mapbox-gl-draw')) {
|
|
156
115
|
return
|
|
157
116
|
}
|
|
158
117
|
layers.filter(l => l.source?.startsWith('mapbox-gl-draw')).forEach(l => map.moveLayer(l.id))
|
|
159
118
|
}
|
|
160
|
-
map.on('styledata', () => handleStyleData())
|
|
161
119
|
|
|
162
|
-
// ---
|
|
163
|
-
const
|
|
120
|
+
// --- Draw completion handlers (create / edit)
|
|
121
|
+
const handleDrawCompletion = (eventName) => (e) => {
|
|
164
122
|
const newFeature = e.features[0]
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
// Clear draw mode undo stack - editing starts fresh
|
|
169
|
-
mapProvider.undoStack?.clear()
|
|
170
|
-
|
|
171
|
-
// Switch straight to edit vertex mode
|
|
172
|
-
dispatch({ type: 'SET_MODE', payload: 'edit_vertex'})
|
|
173
|
-
|
|
174
|
-
setTimeout(() => {
|
|
175
|
-
draw.changeMode('edit_vertex', {
|
|
176
|
-
container: appState.layoutRefs.viewportRef.current,
|
|
177
|
-
deleteVertexButtonId: `${appConfig.id}-draw-delete-point`,
|
|
178
|
-
undoButtonId: `${appConfig.id}-draw-undo`,
|
|
179
|
-
isPanEnabled: appState.interfaceType !== 'keyboard',
|
|
180
|
-
interfaceType: appState.interfaceType,
|
|
181
|
-
scale: { small: 1, medium: 1.5, large: 2 }[mapState.mapSize],
|
|
182
|
-
featureId: newFeature.id,
|
|
183
|
-
getSnapEnabled: () => mapProvider.snapEnabled === true
|
|
184
|
-
})
|
|
185
|
-
}, 0)
|
|
123
|
+
resetDrawModeAndFeature()
|
|
124
|
+
setTimeout(() => draw.changeMode('disabled'), 0)
|
|
125
|
+
eventBus.emit(eventName, { newFeature })
|
|
186
126
|
}
|
|
187
|
-
map.on('draw.create', onCreate)
|
|
188
127
|
|
|
189
|
-
|
|
190
|
-
const
|
|
191
|
-
eventBus.emit('draw:update', e)
|
|
192
|
-
}
|
|
193
|
-
map.on('draw.update', onUpdate)
|
|
128
|
+
const onCreate = handleDrawCompletion('draw:create')
|
|
129
|
+
const onEditFinish = handleDrawCompletion('draw:edit')
|
|
194
130
|
|
|
195
|
-
// ---
|
|
131
|
+
// --- Other map events
|
|
132
|
+
const onUpdate = (e) => eventBus.emit('draw:update', e)
|
|
196
133
|
const onVertexSelection = (e) => {
|
|
197
134
|
dispatch({ type: 'SET_SELECTED_VERTEX_INDEX', payload: e })
|
|
198
135
|
eventBus.emit('draw:vertexselection', e)
|
|
199
136
|
}
|
|
200
|
-
map.on('draw.vertexselection', onVertexSelection)
|
|
201
|
-
|
|
202
|
-
// --- Vertex count changes during drawing
|
|
203
137
|
const onVertexChange = (e) => {
|
|
204
138
|
dispatch({ type: 'SET_SELECTED_VERTEX_INDEX', payload: { index: -1, numVertecies: e.numVertecies } })
|
|
205
139
|
}
|
|
206
|
-
map.on('draw.vertexchange', onVertexChange)
|
|
207
|
-
|
|
208
|
-
// --- Undo stack changes
|
|
209
140
|
const onUndoChange = (e) => {
|
|
210
141
|
dispatch({ type: 'SET_UNDO_STACK_LENGTH', payload: e.length })
|
|
211
142
|
}
|
|
143
|
+
|
|
144
|
+
// --- Register events
|
|
145
|
+
drawDone.onClick = handleDone
|
|
146
|
+
drawCancel.onClick = handleCancel
|
|
147
|
+
drawUndo.onClick = handleUndo
|
|
148
|
+
drawSnap.onClick = handleSnap
|
|
149
|
+
|
|
150
|
+
map.on('styledata', handleStyleData)
|
|
151
|
+
map.on('draw.create', onCreate)
|
|
152
|
+
map.on('draw.editfinish', onEditFinish)
|
|
153
|
+
map.on('draw.update', onUpdate)
|
|
154
|
+
map.on('draw.vertexselection', onVertexSelection)
|
|
155
|
+
map.on('draw.vertexchange', onVertexChange)
|
|
212
156
|
map.on('draw.undochange', onUndoChange)
|
|
213
157
|
|
|
158
|
+
// --- Cleanup
|
|
214
159
|
return () => {
|
|
215
|
-
drawDone.
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
drawFinish.onClick = null
|
|
219
|
-
drawDeletePoint.onClick = null
|
|
220
|
-
drawSnap.onClick = null
|
|
221
|
-
drawCancel.onClick = null
|
|
160
|
+
[drawDone, drawAddPoint, drawUndo, drawDeletePoint, drawSnap, drawCancel].forEach(btn => { if (btn) {
|
|
161
|
+
btn.onClick = null
|
|
162
|
+
}})
|
|
222
163
|
map.off('styledata', handleStyleData)
|
|
223
164
|
map.off('draw.create', onCreate)
|
|
165
|
+
map.off('draw.editfinish', onEditFinish)
|
|
224
166
|
map.off('draw.update', onUpdate)
|
|
225
167
|
map.off('draw.vertexselection', onVertexSelection)
|
|
226
168
|
map.off('draw.vertexchange', onVertexChange)
|