UNPKG

terra-draw

Version:

Frictionless map drawing across mapping provider

1 lines 138 kB
function t(){return t=Object.assign?Object.assign.bind():function(t){for(var e=1;e<arguments.length;e++){var i=arguments[e];for(var o in i)({}).hasOwnProperty.call(i,o)&&(t[o]=i[o])}return t},t.apply(null,arguments)}var e;!function(t){t.Commit="commit",t.Provisional="provisional",t.Finish="finish"}(e||(e={}));const i={SELECTED:"selected",MID_POINT:"midPoint",SELECTION_POINT_FEATURE_ID:"selectionPointFeatureId",SELECTION_POINT:"selectionPoint"},o="edited",s="closingPoint",n="snappingPoint",r="coordinatePoint",a="coordinatePointFeatureId",d="coordinatePointIds",h=10;function l(t){return Boolean(t&&"object"==typeof t&&null!==t&&!Array.isArray(t))}function c(t){return Boolean(t&&"object"==typeof t&&"properties"in t&&"object"==typeof t.properties&&null!==t.properties&&"mode"in t.properties)}function u(t){return!!function(t){return"number"==typeof t&&!isNaN(new Date(t).valueOf())}(t)}const p="Feature is not a Polygon",g="Feature mode property does not match the mode being added to";var y;!function(t){t.Drawing="drawing",t.Select="select",t.Static="static",t.Render="render"}(y||(y={}));const f={rightClick:!0,contextMenu:!1,leftClick:!0,onDragStart:!0,onDrag:!0,onDragEnd:!0};class m{get state(){return this._state}set state(t){throw new Error("Please use the modes lifecycle methods")}get styles(){return this._styles}set styles(t){if("object"!=typeof t)throw new Error("Styling must be an object");this.onStyleChange&&this.onStyleChange([],"styling"),this._styles=t}registerBehaviors(t){}constructor(t,e=!1){this._state="unregistered",this._styles={},this.pointerEvents=f,this.behaviors=[],this.validate=void 0,this.pointerDistance=40,this.coordinatePrecision=void 0,this.onStyleChange=void 0,this.store=void 0,this.projection="web-mercator",this.setDoubleClickToZoom=void 0,this.unproject=void 0,this.project=void 0,this.setCursor=void 0,this.type=y.Drawing,this.mode="base",e||this.updateOptions(t)}updateOptions(e){null!=e&&e.styles&&(this.styles=t({},this._styles,e.styles)),null!=e&&e.pointerDistance&&(this.pointerDistance=e.pointerDistance),null!=e&&e.validation&&(this.validate=e&&e.validation),null!=e&&e.projection&&(this.projection=e.projection),void 0!==(null==e?void 0:e.pointerEvents)&&(this.pointerEvents=e.pointerEvents)}allowPointerEvent(t,e){return"boolean"==typeof t?t:"function"!=typeof t||t(e)}setDrawing(){if("started"!==this._state)throw new Error("Mode must be unregistered or stopped to start");this._state="drawing"}setStarted(){if("stopped"!==this._state&&"registered"!==this._state&&"drawing"!==this._state&&"selecting"!==this._state)throw new Error("Mode must be unregistered or stopped to start");this._state="started",this.setDoubleClickToZoom(!1)}setStopped(){if("started"!==this._state)throw new Error("Mode must be started to be stopped");this._state="stopped",this.setDoubleClickToZoom(!0)}register(t){if("unregistered"!==this._state)throw new Error("Can not register unless mode is unregistered");this._state="registered",this.store=t.store,this.store.registerOnChange(t.onChange),this.setDoubleClickToZoom=t.setDoubleClickToZoom,this.project=t.project,this.unproject=t.unproject,this.onSelect=t.onSelect,this.onDeselect=t.onDeselect,this.setCursor=t.setCursor,this.onStyleChange=t.onChange,this.onFinish=t.onFinish,this.coordinatePrecision=t.coordinatePrecision,this.registerBehaviors({mode:t.mode,store:this.store,project:this.project,unproject:this.unproject,pointerDistance:this.pointerDistance,coordinatePrecision:t.coordinatePrecision,projection:this.projection})}validateFeature(t){return this.performFeatureValidation(t)}afterFeatureAdded(t){}performFeatureValidation(t){if("unregistered"===this._state)throw new Error("Mode must be registered");const i=function(t,e){let i;if(l(t))if(null==t.id)i="Feature has no id";else if("string"!=typeof t.id&&"number"!=typeof t.id)i="Feature must be string or number as per GeoJSON spec";else if(e(t.id))if(l(t.geometry))if(l(t.properties))if("string"==typeof t.geometry.type&&["Polygon","LineString","Point"].includes(t.geometry.type))if(Array.isArray(t.geometry.coordinates)){if(!t.properties.mode||"string"!=typeof t.properties.mode)return{valid:!1,reason:"Feature does not have a valid mode property"}}else i="Feature coordinates is not an array";else i="Feature is not Point, LineString or Polygon";else i="Feature has no properties";else i="Feature has no geometry";else i="Feature must match the id strategy (default is UUID4)";else i="Feature is not object";return i?{valid:!1,reason:i}:{valid:!0}}(t,this.store.idStrategy.isValidId);if(this.validate){const o=this.validate(t,{project:this.project,unproject:this.unproject,coordinatePrecision:this.coordinatePrecision,updateType:e.Provisional});return{valid:i.valid&&o.valid,reason:o.reason}}return{valid:i.valid,reason:i.reason}}validateModeFeature(t,e){const i=this.performFeatureValidation(t);return i.valid?t.properties.mode!==this.mode?{valid:!1,reason:g}:e(t):{valid:!1,reason:i.reason}}onFinish(t,e){}onDeselect(t){}onSelect(t){}onKeyDown(t){}onKeyUp(t){}onMouseMove(t){}onClick(t){}onDragStart(t,e){}onDrag(t,e){}onDragEnd(t,e){}getHexColorStylingValue(t,e,i){return this.getStylingValue(t,e,i)}getNumericStylingValue(t,e,i){return this.getStylingValue(t,e,i)}getStylingValue(t,e,i){return void 0===t?e:"function"==typeof t?t(i):t}}class v extends m{constructor(...t){super(...t),this.type=y.Select}}function C(t,e){const i=t=>t*Math.PI/180,o=i(t[1]),s=i(t[0]),n=i(e[1]),r=n-o,a=i(e[0])-s,d=Math.sin(r/2)*Math.sin(r/2)+Math.cos(o)*Math.cos(n)*Math.sin(a/2)*Math.sin(a/2);return 2*Math.atan2(Math.sqrt(d),Math.sqrt(1-d))*6371e3/1e3}const P=6371008.8;function I(t){return t%360*Math.PI/180}function x(t){return t/6371.0088}function M(t){return t%(2*Math.PI)*180/Math.PI}function S(t,e=9){const i=Math.pow(10,e);return Math.round(t*i)/i}const E=57.29577951308232,F=.017453292519943295,w=6378137,D=(t,e)=>({x:0===t?0:t*F*w,y:0===e?0:Math.log(Math.tan(Math.PI/4+e*F/2))*w}),b=(t,e)=>({lng:0===t?0:E*(t/w),lat:0===e?0:(2*Math.atan(Math.exp(e/w))-Math.PI/2)*E});function k(t,e,i){const o=I(t[0]),s=I(t[1]),n=I(i),r=x(e),a=Math.asin(Math.sin(s)*Math.cos(r)+Math.cos(s)*Math.sin(r)*Math.cos(n));return[M(o+Math.atan2(Math.sin(n)*Math.sin(r)*Math.cos(s),Math.cos(r)-Math.sin(s)*Math.sin(a))),M(a)]}function O(t){const{center:e,radiusKilometers:i,coordinatePrecision:o}=t,s=t.steps?t.steps:64,n=[];for(let t=0;t<s;t++){const r=k(e,i,-360*t/s);n.push([S(r[0],o),S(r[1],o)])}return n.push(n[0]),{type:"Feature",geometry:{type:"Polygon",coordinates:[n]},properties:{}}}function _(t){let e;if("Polygon"===t.geometry.type)e=t.geometry.coordinates;else{if("LineString"!==t.geometry.type)throw new Error("Self intersects only accepts Polygons and LineStrings");e=[t.geometry.coordinates]}const i=[];for(let t=0;t<e.length;t++)for(let i=0;i<e[t].length-1;i++)for(let o=0;o<e.length;o++)for(let n=0;n<e[o].length-1;n++)s(t,i,o,n);return i.length>0;function o(t){return t<0||t>1}function s(t,s,n,r){const a=e[t][s],d=e[t][s+1],h=e[n][r],l=e[n][r+1],c=function(t,e,i,o){if(j(t,i)||j(t,o)||j(e,i)||j(o,i))return null;const s=t[0],n=t[1],r=e[0],a=e[1],d=i[0],h=i[1],l=o[0],c=o[1],u=(s-r)*(h-c)-(n-a)*(d-l);return 0===u?null:[((s*a-n*r)*(d-l)-(s-r)*(d*c-h*l))/u,((s*a-n*r)*(h-c)-(n-a)*(d*c-h*l))/u]}(a,d,h,l);if(null===c)return;let u,p;u=d[0]!==a[0]?(c[0]-a[0])/(d[0]-a[0]):(c[1]-a[1])/(d[1]-a[1]),p=l[0]!==h[0]?(c[0]-h[0])/(l[0]-h[0]):(c[1]-h[1])/(l[1]-h[1]),o(u)||o(p)||(c.toString(),i.push(c))}}function j(t,e){return t[0]===e[0]&&t[1]===e[1]}function B(t,e){return G(t[0])<=e&&G(t[1])<=e}function W(t){return 2===t.length&&"number"==typeof t[0]&&"number"==typeof t[1]&&Infinity!==t[0]&&Infinity!==t[1]&&(i=t[0])>=-180&&i<=180&&(e=t[1])>=-90&&e<=90;var e,i}function G(t){let e=1,i=0;for(;Math.round(t*e)/e!==t;)e*=10,i++;return i}const N="Feature has holes",L="Feature has less than 4 coordinates",T="Feature has invalid coordinates",V="Feature coordinates are not closed";function U(t,e){if("Polygon"!==t.geometry.type)return{valid:!1,reason:"Feature is not a Polygon"};if(1!==t.geometry.coordinates.length)return{valid:!1,reason:N};if(t.geometry.coordinates[0].length<4)return{valid:!1,reason:L};for(let i=0;i<t.geometry.coordinates[0].length;i++){if(!W(t.geometry.coordinates[0][i]))return{valid:!1,reason:T};if(!B(t.geometry.coordinates[0][i],e))return{valid:!1,reason:"Feature has coordinates with excessive precision"}}return(i=t.geometry.coordinates[0][0])[0]!==(o=t.geometry.coordinates[0][t.geometry.coordinates[0].length-1])[0]||i[1]!==o[1]?{valid:!1,reason:V}:{valid:!0};var i,o}function A(t,e){const i=U(t,e);return i.valid?_(t)?{valid:!1,reason:"Feature intersects itself"}:{valid:!0}:i}const R={cancel:"Escape",finish:"Enter"},K={start:"crosshair"};class z extends m{constructor(t){super(t,!0),this.mode="circle",this.center=void 0,this.clickCount=0,this.currentCircleId=void 0,this.keyEvents=R,this.cursors=K,this.startingRadiusKilometers=1e-5,this.cursorMovedAfterInitialCursorDown=!1,this.updateOptions(t)}updateOptions(e){super.updateOptions(e),null!=e&&e.cursors&&(this.cursors=t({},this.cursors,e.cursors)),null===(null==e?void 0:e.keyEvents)?this.keyEvents={cancel:null,finish:null}:null!=e&&e.keyEvents&&(this.keyEvents=t({},this.keyEvents,e.keyEvents)),null!=e&&e.startingRadiusKilometers&&(this.startingRadiusKilometers=e.startingRadiusKilometers)}close(){if(void 0===this.currentCircleId)return;const t=this.currentCircleId;if(this.validate&&t){const i=this.store.getGeometryCopy(t);if(!this.validate({type:"Feature",id:t,geometry:i,properties:{}},{project:this.project,unproject:this.unproject,coordinatePrecision:this.coordinatePrecision,updateType:e.Finish}).valid)return}this.cursorMovedAfterInitialCursorDown=!1,this.center=void 0,this.currentCircleId=void 0,this.clickCount=0,"drawing"===this.state&&this.setStarted(),this.onFinish(t,{mode:this.mode,action:"draw"})}start(){this.setStarted(),this.setCursor(this.cursors.start)}stop(){this.cleanUp(),this.setStopped(),this.setCursor("unset")}onClick(t){if("right"===t.button&&this.allowPointerEvent(this.pointerEvents.rightClick,t)||"left"===t.button&&this.allowPointerEvent(this.pointerEvents.leftClick,t)||t.isContextMenu&&this.allowPointerEvent(this.pointerEvents.contextMenu,t))if(0===this.clickCount){this.center=[t.lng,t.lat];const e=O({center:this.center,radiusKilometers:this.startingRadiusKilometers,coordinatePrecision:this.coordinatePrecision}),[i]=this.store.create([{geometry:e.geometry,properties:{mode:this.mode,radiusKilometers:this.startingRadiusKilometers}}]);this.currentCircleId=i,this.clickCount++,this.cursorMovedAfterInitialCursorDown=!1,this.setDrawing()}else 1===this.clickCount&&this.center&&void 0!==this.currentCircleId&&this.cursorMovedAfterInitialCursorDown&&this.updateCircle(t),this.close()}onMouseMove(t){this.cursorMovedAfterInitialCursorDown=!0,this.updateCircle(t)}onKeyDown(){}onKeyUp(t){t.key===this.keyEvents.cancel?this.cleanUp():t.key===this.keyEvents.finish&&this.close()}onDragStart(){}onDrag(){}onDragEnd(){}cleanUp(){const t=this.currentCircleId;this.center=void 0,this.currentCircleId=void 0,this.clickCount=0,"drawing"===this.state&&this.setStarted();try{void 0!==t&&this.store.delete([t])}catch(t){}}styleFeature(e){const i=t({},{polygonFillColor:"#3f97e0",polygonOutlineColor:"#3f97e0",polygonOutlineWidth:4,polygonFillOpacity:.3,pointColor:"#3f97e0",pointOutlineColor:"#ffffff",pointOutlineWidth:0,pointWidth:6,lineStringColor:"#3f97e0",lineStringWidth:4,zIndex:0});return"Feature"===e.type&&"Polygon"===e.geometry.type&&e.properties.mode===this.mode?(i.polygonFillColor=this.getHexColorStylingValue(this.styles.fillColor,i.polygonFillColor,e),i.polygonOutlineColor=this.getHexColorStylingValue(this.styles.outlineColor,i.polygonOutlineColor,e),i.polygonOutlineWidth=this.getNumericStylingValue(this.styles.outlineWidth,i.polygonOutlineWidth,e),i.polygonFillOpacity=this.getNumericStylingValue(this.styles.fillOpacity,i.polygonFillOpacity,e),i.zIndex=h,i):i}validateFeature(t){return this.validateModeFeature(t,t=>A(t,this.coordinatePrecision))}updateCircle(t){if(1===this.clickCount&&this.center&&this.currentCircleId){const i=C(this.center,[t.lng,t.lat]);let o;if("web-mercator"===this.projection){const e=function(t,e){const i=1e3*C(t,e);if(0===i)return 1;const{x:o,y:s}=D(t[0],t[1]),{x:n,y:r}=D(e[0],e[1]);return Math.sqrt(Math.pow(n-o,2)+Math.pow(r-s,2))/i}(this.center,[t.lng,t.lat]);o=function(t){const{center:e,radiusKilometers:i,coordinatePrecision:o}=t,s=t.steps?t.steps:64,n=1e3*i,[r,a]=e,{x:d,y:h}=D(r,a),l=[];for(let t=0;t<s;t++){const e=360*t/s*Math.PI/180,i=n*Math.cos(e),r=n*Math.sin(e),[a,c]=[d+i,h+r],{lng:u,lat:p}=b(a,c);l.push([S(u,o),S(p,o)])}return l.push(l[0]),{type:"Feature",geometry:{type:"Polygon",coordinates:[l]},properties:{}}}({center:this.center,radiusKilometers:i*e,coordinatePrecision:this.coordinatePrecision})}else{if("globe"!==this.projection)throw new Error("Invalid projection");o=O({center:this.center,radiusKilometers:i,coordinatePrecision:this.coordinatePrecision})}if(this.validate&&!this.validate({type:"Feature",id:this.currentCircleId,geometry:o.geometry,properties:{radiusKilometers:i}},{project:this.project,unproject:this.unproject,coordinatePrecision:this.coordinatePrecision,updateType:e.Provisional}).valid)return;this.store.updateGeometry([{id:this.currentCircleId,geometry:o.geometry}]),this.store.updateProperty([{id:this.currentCircleId,property:"radiusKilometers",value:i}])}}}const X=(t,e)=>{const{x:i,y:o}=t,{x:s,y:n}=e,r=s-i,a=n-o;return Math.sqrt(a*a+r*r)};function Y(t){const e=function(t){const e=t.coordinates[0];let i=0;for(let t=0;t<e.length-1;t++){const[o,s]=e[t],[n,r]=e[t+1];i+=(n-o)*(r+s)}return i<0}(t);if(!e)return{type:"Polygon",coordinates:[t.coordinates[0].reverse()]}}const H={cancel:"Escape",finish:"Enter"},q={start:"crosshair",close:"pointer"};class $ extends m{constructor(t){super(t,!0),this.mode="freehand",this.startingClick=!1,this.currentId=void 0,this.closingPointId=void 0,this.minDistance=20,this.keyEvents=H,this.cursors=q,this.preventPointsNearClose=!0,this.autoClose=!1,this.autoCloseTimeout=500,this.hasLeftStartingPoint=!1,this.preventNewFeature=!1,this.updateOptions(t)}updateOptions(e){super.updateOptions(e),null!=e&&e.minDistance&&(this.minDistance=e.minDistance),void 0!==(null==e?void 0:e.preventPointsNearClose)&&(this.preventPointsNearClose=e.preventPointsNearClose),void 0!==(null==e?void 0:e.autoClose)&&(this.autoClose=e.autoClose),null!=e&&e.autoCloseTimeout&&(this.autoCloseTimeout=e.autoCloseTimeout),null===(null==e?void 0:e.keyEvents)?this.keyEvents={cancel:null,finish:null}:null!=e&&e.keyEvents&&(this.keyEvents=t({},this.keyEvents,e.keyEvents)),null!=e&&e.cursors&&(this.cursors=t({},this.cursors,e.cursors))}close(){if(void 0===this.currentId)return;if(this.currentId){const t=Y(this.store.getGeometryCopy(this.currentId));t&&this.store.updateGeometry([{id:this.currentId,geometry:t}])}const t=this.currentId;if(this.validate&&t){const i=this.store.getGeometryCopy(t);if(!this.validate({type:"Feature",id:t,geometry:i,properties:{}},{project:this.project,unproject:this.unproject,coordinatePrecision:this.coordinatePrecision,updateType:e.Finish}).valid)return}this.closingPointId&&this.store.delete([this.closingPointId]),this.startingClick=!1,this.currentId=void 0,this.closingPointId=void 0,this.hasLeftStartingPoint=!1,"drawing"===this.state&&this.setStarted(),this.onFinish(t,{mode:this.mode,action:"draw"})}start(){this.setStarted(),this.setCursor(this.cursors.start)}stop(){this.cleanUp(),this.setStopped(),this.setCursor("unset")}onMouseMove(t){if(void 0===this.currentId||!1===this.startingClick)return;const i=this.store.getGeometryCopy(this.currentId),o=i.coordinates[0].length-2,[s,n]=i.coordinates[0][o],{x:r,y:a}=this.project(s,n),d=X({x:r,y:a},{x:t.containerX,y:t.containerY}),[h,l]=i.coordinates[0][0],{x:c,y:u}=this.project(h,l);if(X({x:c,y:u},{x:t.containerX,y:t.containerY})<this.pointerDistance){if(this.autoClose&&this.hasLeftStartingPoint&&(this.preventNewFeature=!0,setTimeout(()=>{this.preventNewFeature=!1},this.autoCloseTimeout),this.close()),this.setCursor(this.cursors.close),this.preventPointsNearClose)return}else this.hasLeftStartingPoint=!0,this.setCursor(this.cursors.start);if(d<this.minDistance)return;i.coordinates[0].pop();const p={type:"Polygon",coordinates:[[...i.coordinates[0],[t.lng,t.lat],i.coordinates[0][0]]]};this.validate&&!this.validate({type:"Feature",id:this.currentId,geometry:p,properties:{}},{project:this.project,unproject:this.unproject,coordinatePrecision:this.coordinatePrecision,updateType:e.Provisional}).valid||this.store.updateGeometry([{id:this.currentId,geometry:p}])}onClick(t){if("right"===t.button&&this.allowPointerEvent(this.pointerEvents.rightClick,t)||"left"===t.button&&this.allowPointerEvent(this.pointerEvents.leftClick,t)||t.isContextMenu&&this.allowPointerEvent(this.pointerEvents.contextMenu,t)){if(this.preventNewFeature)return;if(!1===this.startingClick){const[e,i]=this.store.create([{geometry:{type:"Polygon",coordinates:[[[t.lng,t.lat],[t.lng,t.lat],[t.lng,t.lat],[t.lng,t.lat]]]},properties:{mode:this.mode}},{geometry:{type:"Point",coordinates:[t.lng,t.lat]},properties:{mode:this.mode,[s]:!0}}]);return this.currentId=e,this.closingPointId=i,this.startingClick=!0,void this.setDrawing()}this.close()}}onKeyDown(){}onKeyUp(t){t.key===this.keyEvents.cancel?this.cleanUp():t.key===this.keyEvents.finish&&!0===this.startingClick&&this.close()}onDragStart(){}onDrag(){}onDragEnd(){}cleanUp(){const t=this.currentId,e=this.closingPointId;this.closingPointId=void 0,this.currentId=void 0,this.startingClick=!1,"drawing"===this.state&&this.setStarted();try{void 0!==t&&this.store.delete([t]),void 0!==e&&this.store.delete([e])}catch(t){}}styleFeature(e){const i=t({},{polygonFillColor:"#3f97e0",polygonOutlineColor:"#3f97e0",polygonOutlineWidth:4,polygonFillOpacity:.3,pointColor:"#3f97e0",pointOutlineColor:"#ffffff",pointOutlineWidth:0,pointWidth:6,lineStringColor:"#3f97e0",lineStringWidth:4,zIndex:0});return"Feature"===e.type&&"Polygon"===e.geometry.type&&e.properties.mode===this.mode?(i.polygonFillColor=this.getHexColorStylingValue(this.styles.fillColor,i.polygonFillColor,e),i.polygonOutlineColor=this.getHexColorStylingValue(this.styles.outlineColor,i.polygonOutlineColor,e),i.polygonOutlineWidth=this.getNumericStylingValue(this.styles.outlineWidth,i.polygonOutlineWidth,e),i.polygonFillOpacity=this.getNumericStylingValue(this.styles.fillOpacity,i.polygonFillOpacity,e),i.zIndex=h,i):"Feature"===e.type&&"Point"===e.geometry.type&&e.properties.mode===this.mode?(i.pointWidth=this.getNumericStylingValue(this.styles.closingPointWidth,i.pointWidth,e),i.pointColor=this.getHexColorStylingValue(this.styles.closingPointColor,i.pointColor,e),i.pointOutlineColor=this.getHexColorStylingValue(this.styles.closingPointOutlineColor,i.pointOutlineColor,e),i.pointOutlineWidth=this.getNumericStylingValue(this.styles.closingPointOutlineWidth,2,e),i.zIndex=50,i):i}validateFeature(t){return this.validateModeFeature(t,t=>U(t,this.coordinatePrecision))}}class Z{constructor({store:t,mode:e,project:i,unproject:o,pointerDistance:s,coordinatePrecision:n,projection:r}){this.store=void 0,this.mode=void 0,this.project=void 0,this.unproject=void 0,this.pointerDistance=void 0,this.coordinatePrecision=void 0,this.projection=void 0,this.store=t,this.mode=e,this.project=i,this.unproject=o,this.pointerDistance=s,this.coordinatePrecision=n,this.projection=r}}function J({unproject:t,point:e,pointerDistance:i}){const o=i/2,{x:s,y:n}=e;return{type:"Feature",properties:{},geometry:{type:"Polygon",coordinates:[[t(s-o,n-o),t(s+o,n-o),t(s+o,n+o),t(s-o,n+o),t(s-o,n-o)].map(t=>[t.lng,t.lat])]}}}class Q extends Z{constructor(t){super(t)}create(t){const{containerX:e,containerY:i}=t;return J({unproject:this.unproject,point:{x:e,y:i},pointerDistance:this.pointerDistance})}}class tt extends Z{constructor(t){super(t)}measure(t,e){const{x:i,y:o}=this.project(e[0],e[1]);return X({x:i,y:o},{x:t.containerX,y:t.containerY})}}class et extends Z{constructor(t,e,i){super(t),this.config=void 0,this.pixelDistance=void 0,this.clickBoundingBox=void 0,this.getSnappableCoordinateFirstClick=t=>this.getSnappable(t,t=>Boolean(t.properties&&t.properties.mode===this.mode)).coordinate,this.getSnappableCoordinate=(t,e)=>this.getSnappable(t,t=>Boolean(t.properties&&t.properties.mode===this.mode&&t.id!==e)).coordinate,this.config=t,this.pixelDistance=e,this.clickBoundingBox=i}getSnappable(t,e){const i=this.clickBoundingBox.create(t),o=this.store.search(i,e),s={featureId:void 0,featureCoordinateIndex:void 0,coordinate:void 0,minDist:Infinity};return o.forEach(e=>{let i;if("Polygon"===e.geometry.type)i=e.geometry.coordinates[0];else{if("LineString"!==e.geometry.type)return;i=e.geometry.coordinates}i.forEach((i,o)=>{const n=this.pixelDistance.measure(t,i);n<s.minDist&&n<this.pointerDistance&&(s.coordinate=i,s.minDist=n,s.featureId=e.id,s.featureCoordinateIndex=o)})}),s}}function it(t,e,i){const o=I(t[0]),s=I(t[1]),n=I(i),r=x(e),a=Math.asin(Math.sin(s)*Math.cos(r)+Math.cos(s)*Math.sin(r)*Math.cos(n));return[M(o+Math.atan2(Math.sin(n)*Math.sin(r)*Math.cos(s),Math.cos(r)-Math.sin(s)*Math.sin(a))),M(a)]}function ot({x:t,y:e},i,o){const s=I(o);return{x:t+i*Math.cos(s),y:e+i*Math.sin(s)}}function st(t,e){const i=I(t[0]),o=I(e[0]),s=I(t[1]),n=I(e[1]),r=Math.sin(o-i)*Math.cos(n),a=Math.cos(s)*Math.sin(n)-Math.sin(s)*Math.cos(n)*Math.cos(o-i);return M(Math.atan2(r,a))}function nt({x:t,y:e},{x:i,y:o}){const s=i-t,n=o-e;if(0===s&&0===n)return 0;let r=Math.atan2(n,s);return r*=180/Math.PI,r>180?r-=360:r<-180&&(r+=360),r}function rt(t){return(t+360)%360}function at(t,e,i){const o=[],s=t.length;let n,r,a,d=0;for(let s=0;s<t.length&&!(e>=d&&s===t.length-1);s++){if(d>e&&0===o.length){if(n=e-d,!n)return o.push(t[s]),o;r=st(t[s],t[s-1])-180,a=it(t[s],n,r),o.push(a)}if(d>=i)return n=i-d,n?(r=st(t[s],t[s-1])-180,a=it(t[s],n,r),o.push(a),o):(o.push(t[s]),o);if(d>=e&&o.push(t[s]),s===t.length-1)return o;d+=C(t[s],t[s+1])}if(d<e&&t.length===s)throw new Error("Start position is beyond line");const h=t[t.length-1];return[h,h]}function dt(t){return t*(Math.PI/180)}function ht(t){return t*(180/Math.PI)}class lt extends Z{constructor(t){super(t),this.config=void 0,this.config=t}generateInsertionCoordinates(t,e,i){const o=[t,e];let s=0;for(let t=0;t<o.length-1;t++)s+=C(o[0],o[1]);if(s<=i)return o;let n=s/i-1;Number.isInteger(n)||(n=Math.floor(n)+1);const r=[];for(let t=0;t<n;t++){const e=at(o,i*t,i*(t+1));r.push(e)}const a=[];for(let t=0;t<r.length;t++)a.push(r[t][1]);return this.limitCoordinates(a)}generateInsertionGeodesicCoordinates(t,e,i){const o=C(t,e),s=function(t,e,i){const o=[],s=dt(t[1]),n=dt(t[0]),r=dt(e[1]),a=dt(e[0]);i+=1;const d=2*Math.asin(Math.sqrt(Math.sin((r-s)/2)**2+Math.cos(s)*Math.cos(r)*Math.sin((a-n)/2)**2));if(0===d||isNaN(d))return o;for(let t=0;t<=i;t++){const e=t/i,h=Math.sin((1-e)*d)/Math.sin(d),l=Math.sin(e*d)/Math.sin(d),c=h*Math.cos(s)*Math.cos(n)+l*Math.cos(r)*Math.cos(a),u=h*Math.cos(s)*Math.sin(n)+l*Math.cos(r)*Math.sin(a),p=h*Math.sin(s)+l*Math.sin(r);if(isNaN(c)||isNaN(u)||isNaN(p))continue;const g=Math.atan2(p,Math.sqrt(c**2+u**2)),y=Math.atan2(u,c);isNaN(g)||isNaN(y)||o.push([ht(y),ht(g)])}return o.slice(1,-1)}(t,e,Math.floor(o/i));return this.limitCoordinates(s)}limitCoordinates(t){return t.map(t=>[S(t[0],this.config.coordinatePrecision),S(t[1],this.config.coordinatePrecision)])}}function ct(t,e){return t[0]===e[0]&&t[1]===e[1]}function ut(t,e){if("LineString"!==t.geometry.type)return{valid:!1,reason:"Feature is not a LineString"};if(t.geometry.coordinates.length<2)return{valid:!1,reason:"Feature has less than 2 coordinates"};for(let i=0;i<t.geometry.coordinates.length;i++){if(!W(t.geometry.coordinates[i]))return{valid:!1,reason:"Feature has invalid coordinates"};if(!B(t.geometry.coordinates[i],e))return{valid:!1,reason:"Feature has coordinates with excessive precision"}}return{valid:!0}}function pt(t){return Math.sqrt(Math.pow(t[0],2)+Math.pow(t[1],2)+Math.pow(t[2],2))}function gt(t,e){const i=function(t,e){const[i,o,s]=t,[n,r,a]=e;return i*n+o*r+s*a}(t,e)/(pt(t)*pt(e));return Math.acos(Math.min(Math.max(i,-1),1))}function yt(t){const e=I(t[1]),i=I(t[0]);return[Math.cos(e)*Math.cos(i),Math.cos(e)*Math.sin(i),Math.sin(e)]}function ft(t){const[e,i,o]=t,s=M(Math.asin(o));return[M(Math.atan2(i,e)),s]}function mt(t,e,i){const o=yt(t),s=yt(e),n=yt(i),[r,a,d]=n,[h,l,c]=function(t,e){const[i,o,s]=t,[n,r,a]=e;return[o*a-s*r,s*n-i*a,i*r-o*n]}(o,s),u=l*d-c*a,p=c*r-h*d,g=h*a-l*r,y=g*l-p*c,f=u*c-g*h,m=p*h-u*l,v=1/Math.sqrt(Math.pow(y,2)+Math.pow(f,2)+Math.pow(m,2)),P=[y*v,f*v,m*v],I=[-1*y*v,-1*f*v,-1*m*v],x=gt(o,s),M=gt(o,P),S=gt(s,P),E=gt(o,I),F=gt(s,I);let w;return w=M<E&&M<F||S<E&&S<F?P:I,gt(o,w)>x||gt(s,w)>x?C(ft(w),ft(o))<=C(ft(w),ft(s))?[ft(o),!0,!1]:[ft(s),!1,!0]:[ft(w),!1,!1]}function vt(t,e,i){const o=e.x-t.x,s=e.y-t.y,n=Math.max(0,Math.min(1,((i.x-t.x)*o+(i.y-t.y)*s)/(o*o+s*s)));return{x:t.x+n*o,y:t.y+n*s}}class Ct extends Z{constructor(t,e,i){super(t),this.config=void 0,this.pixelDistance=void 0,this.clickBoundingBox=void 0,this.getSnappableCoordinateFirstClick=t=>this.getSnappable(t,t=>Boolean(t.properties&&t.properties.mode===this.mode)).coordinate,this.getSnappableCoordinate=(t,e)=>this.getSnappable(t,t=>Boolean(t.properties&&t.properties.mode===this.mode&&t.id!==e)).coordinate,this.config=t,this.pixelDistance=e,this.clickBoundingBox=i}getSnappable(t,e){const i=this.clickBoundingBox.create(t),o=this.store.search(i,e),s={featureId:void 0,featureCoordinateIndex:void 0,coordinate:void 0,minDistance:Infinity};return o.forEach(e=>{let i;if("Polygon"===e.geometry.type)i=e.geometry.coordinates[0];else{if("LineString"!==e.geometry.type)return;i=e.geometry.coordinates}const o=[];for(let t=0;t<i.length-1;t++)o.push([i[t],i[t+1]]);let n;const r=[t.lng,t.lat];if("web-mercator"===this.config.projection?n=function(t,e){let i=[Infinity,Infinity],o=Infinity,s=0;for(let n of e){const r=n[0],a=n[1];let d,h=Infinity;const l=D(r[0],r[1]),c=D(a[0],a[1]),u=D(t[0],t[1]);if(r[0]===t[0]&&r[1]===t[1])d=r;else if(a[0]===t[0]&&a[1]===t[1])d=a;else{const{x:t,y:e}=vt(l,c,u),{lng:i,lat:o}=b(t,e);d=[i,o]}d&&(h=X(u,D(d[0],d[1])),h<o&&(i=d,o=h,s=e.indexOf(n)))}return Infinity===o?void 0:{coordinate:i,lineIndex:s,distance:o}}(r,o):"globe"===this.config.projection&&(n=function(t,e){let i=[Infinity,Infinity],o=Infinity,s=0;for(let n of e){const r=n[0],a=n[1];let d,h=Infinity;r[0]===t[0]&&r[1]===t[1]?d=r:a[0]===t[0]&&a[1]===t[1]?d=a:[d]=mt(r,a,t),d&&(h=C(t,d),h<o&&(i=d,o=h,s=e.indexOf(n)))}return Infinity===o?void 0:{coordinate:i,distance:o,lineIndex:s}}(r,o)),!n)return;const a=this.pixelDistance.measure(t,n.coordinate);a<s.minDistance&&a<this.pointerDistance&&(s.featureId=e.id,s.coordinate=n.coordinate,s.featureCoordinateIndex=n.lineIndex,s.minDistance=a)}),s}}const Pt={cancel:"Escape",finish:"Enter"},It={start:"crosshair",close:"pointer",dragStart:"grabbing",dragEnd:"crosshair"};class xt extends m{constructor(t){super(t,!0),this.mode="linestring",this.currentCoordinate=0,this.currentId=void 0,this.closingPointId=void 0,this.keyEvents=Pt,this.snapping=void 0,this.cursors=It,this.mouseMove=!1,this.insertCoordinates=void 0,this.lastCommitedCoordinates=void 0,this.snappedPointId=void 0,this.editable=!1,this.editedFeatureId=void 0,this.editedFeatureCoordinateIndex=void 0,this.editedSnapType=void 0,this.editedInsertIndex=void 0,this.editedPointId=void 0,this.coordinateSnapping=void 0,this.insertPoint=void 0,this.lineSnapping=void 0,this.pixelDistance=void 0,this.clickBoundingBox=void 0,this.updateOptions(t)}updateOptions(e){super.updateOptions(e),null!=e&&e.cursors&&(this.cursors=t({},this.cursors,e.cursors)),null!=e&&e.snapping&&(this.snapping=e.snapping),null===(null==e?void 0:e.keyEvents)?this.keyEvents={cancel:null,finish:null}:null!=e&&e.keyEvents&&(this.keyEvents=t({},this.keyEvents,e.keyEvents)),null!=e&&e.insertCoordinates&&(this.insertCoordinates=e.insertCoordinates),e&&e.editable&&(this.editable=e.editable)}close(){if(void 0===this.currentId)return;const t=this.store.getGeometryCopy(this.currentId);t.coordinates.pop(),this.updateGeometries([...t.coordinates],void 0,e.Commit);const i=this.currentId;this.closingPointId&&this.store.delete([this.closingPointId]),this.snappedPointId&&this.store.delete([this.snappedPointId]),this.currentCoordinate=0,this.currentId=void 0,this.closingPointId=void 0,this.snappedPointId=void 0,this.lastCommitedCoordinates=void 0,"drawing"===this.state&&this.setStarted(),this.onFinish(i,{mode:this.mode,action:"draw"})}updateGeometries(t,e,i){if(!this.currentId)return;const o={type:"LineString",coordinates:t};if(this.validate&&!this.validate({type:"Feature",geometry:o},{project:this.project,unproject:this.unproject,coordinatePrecision:this.coordinatePrecision,updateType:i}).valid)return;const s=[{id:this.currentId,geometry:o}];this.closingPointId&&e&&s.push({id:this.closingPointId,geometry:{type:"Point",coordinates:e}}),"commit"===i&&(this.lastCommitedCoordinates=o.coordinates),this.store.updateGeometry(s)}generateInsertCoordinates(t,e){if(!this.insertCoordinates||!this.lastCommitedCoordinates)throw new Error("Not able to insert coordinates");if("amount"!==this.insertCoordinates.strategy)throw new Error("Strategy does not exist");const i=C(t,e)/(this.insertCoordinates.value+1);let o=[];return"globe"===this.projection?o=this.insertPoint.generateInsertionGeodesicCoordinates(t,e,i):"web-mercator"===this.projection&&(o=this.insertPoint.generateInsertionCoordinates(t,e,i)),o}createLine(t){const[e]=this.store.create([{geometry:{type:"LineString",coordinates:[t,t]},properties:{mode:this.mode}}]);this.lastCommitedCoordinates=[t,t],this.currentId=e,this.currentCoordinate++,this.setDrawing()}firstUpdateToLine(t){if(!this.currentId)return;const i=this.store.getGeometryCopy(this.currentId).coordinates,[o]=this.store.create([{geometry:{type:"Point",coordinates:[...t]},properties:{mode:this.mode}}]);this.closingPointId=o,this.setCursor(this.cursors.close);const s=[...i,t];this.updateGeometries(s,void 0,e.Commit),this.currentCoordinate++}updateToLine(t,i){if(!this.currentId)return;const o=this.store.getGeometryCopy(this.currentId).coordinates,[s,n]=this.lastCommitedCoordinates?this.lastCommitedCoordinates[this.lastCommitedCoordinates.length-1]:o[o.length-2],{x:r,y:a}=this.project(s,n);if(X({x:r,y:a},{x:i.x,y:i.y})<this.pointerDistance)return void this.close();this.setCursor(this.cursors.close);const d=[...o,t];this.updateGeometries(d,o[o.length-1],e.Commit),this.currentCoordinate++}registerBehaviors(t){this.coordinateSnapping=new et(t,new tt(t),new Q(t)),this.insertPoint=new lt(t),this.clickBoundingBox=new Q(t),this.pixelDistance=new tt(t),this.lineSnapping=new Ct(t,this.pixelDistance,this.clickBoundingBox),this.coordinateSnapping=new et(t,this.pixelDistance,this.clickBoundingBox)}start(){this.setStarted(),this.setCursor(this.cursors.start)}stop(){this.cleanUp(),this.setStopped(),this.setCursor("unset")}onMouseMove(t){this.mouseMove=!0,this.setCursor(this.cursors.start);const i=this.snapCoordinate(t);if(i){if(this.snappedPointId)this.store.updateGeometry([{id:this.snappedPointId,geometry:{type:"Point",coordinates:i}}]);else{const[t]=this.store.create([{geometry:{type:"Point",coordinates:i},properties:{mode:this.mode,[n]:!0}}]);this.snappedPointId=t}t.lng=i[0],t.lat=i[1]}else this.snappedPointId&&(this.store.delete([this.snappedPointId]),this.snappedPointId=void 0);const o=i||[t.lng,t.lat];if(void 0===this.currentId||0===this.currentCoordinate)return;const s=this.store.getGeometryCopy(this.currentId).coordinates;if(s.pop(),this.closingPointId){const[e,i]=s[s.length-1],{x:o,y:n}=this.project(e,i);X({x:o,y:n},{x:t.containerX,y:t.containerY})<this.pointerDistance&&this.setCursor(this.cursors.close)}let r=[...s,o];if(this.insertCoordinates&&this.currentId&&this.lastCommitedCoordinates){const t=this.lastCommitedCoordinates[this.lastCommitedCoordinates.length-1],e=o;if(!ct(t,e)){const i=this.generateInsertCoordinates(t,e);r=[...this.lastCommitedCoordinates.slice(0,-1),...i,o]}}this.updateGeometries(r,void 0,e.Provisional)}onRightClick(t){if(!this.editable||"started"!==this.state)return;const{featureId:i,featureCoordinateIndex:o}=this.coordinateSnapping.getSnappable(t,t=>this.lineStringFilter(t));if(!i||void 0===o)return;const s=this.store.getGeometryCopy(i);let n;if("LineString"===s.type&&(n=s.coordinates,!(n.length<=2))){if(n.splice(o,1),this.validate&&!this.validate({id:i,type:"Feature",geometry:s,properties:{}},{project:this.project,unproject:this.unproject,coordinatePrecision:this.coordinatePrecision,updateType:e.Commit}).valid)return;this.snappedPointId&&(this.store.delete([this.snappedPointId]),this.snappedPointId=void 0),this.store.updateGeometry([{id:i,geometry:s}]),this.onFinish(i,{mode:this.mode,action:"edit"})}}onLeftClick(t){this.snappedPointId&&(this.store.delete([this.snappedPointId]),this.snappedPointId=void 0);const e=this.snapCoordinate(t)||[t.lng,t.lat];0===this.currentCoordinate?this.createLine(e):1===this.currentCoordinate&&this.currentId?this.firstUpdateToLine(e):this.currentId&&this.updateToLine(e,{x:t.containerX,y:t.containerY})}onClick(t){("right"===t.button&&this.allowPointerEvent(this.pointerEvents.rightClick,t)||"left"===t.button&&this.allowPointerEvent(this.pointerEvents.leftClick,t)||t.isContextMenu&&this.allowPointerEvent(this.pointerEvents.contextMenu,t))&&(this.currentCoordinate>0&&!this.mouseMove&&this.onMouseMove(t),this.mouseMove=!1,"right"===t.button?this.onRightClick(t):"left"===t.button&&this.onLeftClick(t))}onKeyDown(){}onKeyUp(t){t.key===this.keyEvents.cancel&&this.cleanUp(),t.key===this.keyEvents.finish&&this.close()}onDragStart(t,e){if(!this.allowPointerEvent(this.pointerEvents.onDragStart,t))return;if(!this.editable)return;let i;if("started"===this.state){const e=this.lineSnapping.getSnappable(t,t=>this.lineStringFilter(t));e.coordinate&&(this.editedSnapType="line",this.editedFeatureCoordinateIndex=e.featureCoordinateIndex,this.editedFeatureId=e.featureId,i=e.coordinate);const o=this.coordinateSnapping.getSnappable(t,t=>this.lineStringFilter(t));o.coordinate&&(this.editedSnapType="coordinate",this.editedFeatureCoordinateIndex=o.featureCoordinateIndex,this.editedFeatureId=o.featureId,i=o.coordinate)}if(this.editedFeatureId&&i){if(!this.editedPointId){const[t]=this.store.create([{geometry:{type:"Point",coordinates:i},properties:{mode:this.mode,[o]:!0}}]);this.editedPointId=t}this.setCursor(this.cursors.dragStart),e(!1)}}onDrag(t,i){if(!this.allowPointerEvent(this.pointerEvents.onDrag,t))return;if(void 0===this.editedFeatureId||void 0===this.editedFeatureCoordinateIndex)return;const s=this.store.getGeometryCopy(this.editedFeatureId);"coordinate"===this.editedSnapType||"line"===this.editedSnapType&&void 0!==this.editedInsertIndex?s.coordinates[this.editedFeatureCoordinateIndex]=[t.lng,t.lat]:"line"===this.editedSnapType&&void 0===this.editedInsertIndex&&(this.editedInsertIndex=this.editedFeatureCoordinateIndex+1,s.coordinates.splice(this.editedInsertIndex,0,[t.lng,t.lat]),this.editedFeatureCoordinateIndex++);const n={type:"LineString",coordinates:s.coordinates};this.validate&&!this.validate({type:"Feature",geometry:n,properties:this.store.getPropertiesCopy(this.editedFeatureId)},{project:this.project,unproject:this.unproject,coordinatePrecision:this.coordinatePrecision,updateType:e.Provisional}).valid||(this.snapping&&this.snappedPointId&&(this.store.delete([this.snappedPointId]),this.snappedPointId=void 0),this.store.updateGeometry([{id:this.editedFeatureId,geometry:n}]),this.editedPointId&&this.store.updateGeometry([{id:this.editedPointId,geometry:{type:"Point",coordinates:[t.lng,t.lat]}}]),this.store.updateProperty([{id:this.editedFeatureId,property:o,value:!0}]))}onDragEnd(t,e){this.allowPointerEvent(this.pointerEvents.onDragEnd,t)&&void 0!==this.editedFeatureId&&(this.setCursor(this.cursors.dragEnd),this.editedPointId&&(this.store.delete([this.editedPointId]),this.editedPointId=void 0),this.store.updateProperty([{id:this.editedFeatureId,property:o,value:!1}]),this.onFinish(this.editedFeatureId,{mode:this.mode,action:"edit"}),this.editedFeatureId=void 0,this.editedFeatureCoordinateIndex=void 0,this.editedInsertIndex=void 0,this.editedSnapType=void 0,e(!0))}cleanUp(){const t=this.currentId,e=this.closingPointId,i=this.snappedPointId;this.closingPointId=void 0,this.snappedPointId=void 0,this.currentId=void 0,this.currentCoordinate=0,"drawing"===this.state&&this.setStarted();try{void 0!==t&&this.store.delete([t]),void 0!==i&&this.store.delete([i]),void 0!==e&&this.store.delete([e])}catch(t){}}styleFeature(e){const i=t({},{polygonFillColor:"#3f97e0",polygonOutlineColor:"#3f97e0",polygonOutlineWidth:4,polygonFillOpacity:.3,pointColor:"#3f97e0",pointOutlineColor:"#ffffff",pointOutlineWidth:0,pointWidth:6,lineStringColor:"#3f97e0",lineStringWidth:4,zIndex:0});if("Feature"===e.type&&"LineString"===e.geometry.type&&e.properties.mode===this.mode)return i.lineStringColor=this.getHexColorStylingValue(this.styles.lineStringColor,i.lineStringColor,e),i.lineStringWidth=this.getNumericStylingValue(this.styles.lineStringWidth,i.lineStringWidth,e),i.zIndex=h,i;if("Feature"===e.type&&"Point"===e.geometry.type&&e.properties.mode===this.mode){const t=e.properties[s];return i.pointColor=this.getHexColorStylingValue(t?this.styles.closingPointColor:this.styles.snappingPointColor,i.pointColor,e),i.pointWidth=this.getNumericStylingValue(t?this.styles.closingPointWidth:this.styles.snappingPointWidth,i.pointWidth,e),i.pointOutlineColor=this.getHexColorStylingValue(t?this.styles.closingPointOutlineColor:this.styles.snappingPointOutlineColor,"#ffffff",e),i.pointOutlineWidth=this.getNumericStylingValue(t?this.styles.closingPointOutlineWidth:this.styles.snappingPointOutlineWidth,2,e),i.zIndex=50,i}return i}validateFeature(t){return this.validateModeFeature(t,t=>ut(t,this.coordinatePrecision))}lineStringFilter(t){return Boolean("LineString"===t.geometry.type&&t.properties&&t.properties.mode===this.mode)}snapCoordinate(t){var e,i,o;let s;if(null!=(e=this.snapping)&&e.toLine){let e;e=this.currentId?this.lineSnapping.getSnappableCoordinate(t,this.currentId):this.lineSnapping.getSnappableCoordinateFirstClick(t),e&&(s=e)}return null!=(i=this.snapping)&&i.toCoordinate&&(s=this.currentId?this.coordinateSnapping.getSnappableCoordinate(t,this.currentId):this.coordinateSnapping.getSnappableCoordinateFirstClick(t)),null!=(o=this.snapping)&&o.toCustom&&(s=this.snapping.toCustom(t,{currentCoordinate:this.currentCoordinate,currentId:this.currentId,getCurrentGeometrySnapshot:this.currentId?()=>this.store.getGeometryCopy(this.currentId):()=>null,project:this.project,unproject:this.unproject})),s}}const Mt="Feature is not a Point",St="Feature has invalid coordinates",Et="Feature has coordinates with excessive precision";function Ft(t,e){return"Point"!==t.geometry.type?{valid:!1,reason:Mt}:W(t.geometry.coordinates)?B(t.geometry.coordinates,e)?{valid:!0}:{valid:!1,reason:Et}:{valid:!1,reason:St}}const wt={create:"crosshair",dragStart:"grabbing",dragEnd:"crosshair"};class Dt extends m{constructor(t){super(t,!0),this.mode="point",this.cursors=wt,this.editable=!1,this.editedFeatureId=void 0,this.pixelDistance=void 0,this.clickBoundingBox=void 0,this.updateOptions(t)}updateOptions(e){super.updateOptions(e),null!=e&&e.cursors&&(this.cursors=t({},this.cursors,e.cursors)),null!=e&&e.editable&&(this.editable=e.editable)}start(){this.setStarted(),this.setCursor(this.cursors.create)}stop(){this.cleanUp(),this.setStopped(),this.setCursor("unset")}onClick(t){"right"===t.button&&this.allowPointerEvent(this.pointerEvents.rightClick,t)||t.isContextMenu&&this.allowPointerEvent(this.pointerEvents.contextMenu,t)?this.onRightClick(t):"left"===t.button&&this.allowPointerEvent(this.pointerEvents.leftClick,t)&&this.onLeftClick(t)}onMouseMove(){}onKeyDown(){}onKeyUp(){}cleanUp(){this.editedFeatureId=void 0}onDragStart(t,e){if(this.allowPointerEvent(this.pointerEvents.onDragStart,t)){if(this.editable){const e=this.getNearestPointFeature(t);this.editedFeatureId=null==e?void 0:e.id}this.editedFeatureId&&(this.setCursor(this.cursors.dragStart),e(!1))}}onDrag(t,i){this.allowPointerEvent(this.pointerEvents.onDrag,t)&&void 0!==this.editedFeatureId&&(this.validate&&!this.validate({type:"Feature",geometry:{type:"Point",coordinates:[t.lng,t.lat]},properties:this.store.getPropertiesCopy(this.editedFeatureId)},{project:this.project,unproject:this.unproject,coordinatePrecision:this.coordinatePrecision,updateType:e.Finish}).valid||(this.store.updateGeometry([{id:this.editedFeatureId,geometry:{type:"Point",coordinates:[t.lng,t.lat]}}]),this.store.updateProperty([{id:this.editedFeatureId,property:o,value:!0}])))}onDragEnd(t,e){this.allowPointerEvent(this.pointerEvents.onDragEnd,t)&&void 0!==this.editedFeatureId&&(this.onFinish(this.editedFeatureId,{mode:this.mode,action:"edit"}),this.setCursor(this.cursors.dragEnd),this.store.updateProperty([{id:this.editedFeatureId,property:o,value:!1}]),this.editedFeatureId=void 0,e(!0))}registerBehaviors(t){this.pixelDistance=new tt(t),this.clickBoundingBox=new Q(t)}styleFeature(e){const i=t({},{polygonFillColor:"#3f97e0",polygonOutlineColor:"#3f97e0",polygonOutlineWidth:4,polygonFillOpacity:.3,pointColor:"#3f97e0",pointOutlineColor:"#ffffff",pointOutlineWidth:0,pointWidth:6,lineStringColor:"#3f97e0",lineStringWidth:4,zIndex:0});if("Feature"===e.type&&"Point"===e.geometry.type&&e.properties.mode===this.mode){const t=Boolean(e.id&&this.editedFeatureId===e.id);i.pointWidth=this.getNumericStylingValue(t?this.styles.editedPointWidth:this.styles.pointWidth,i.pointWidth,e),i.pointColor=this.getHexColorStylingValue(t?this.styles.editedPointColor:this.styles.pointColor,i.pointColor,e),i.pointOutlineColor=this.getHexColorStylingValue(t?this.styles.editedPointOutlineColor:this.styles.pointOutlineColor,i.pointOutlineColor,e),i.pointOutlineWidth=this.getNumericStylingValue(t?this.styles.editedPointOutlineWidth:this.styles.pointOutlineWidth,2,e),i.zIndex=30}return i}validateFeature(t){return this.validateModeFeature(t,t=>Ft(t,this.coordinatePrecision))}onLeftClick(t){const i={type:"Point",coordinates:[t.lng,t.lat]},o={mode:this.mode};if(this.validate&&!this.validate({type:"Feature",geometry:i,properties:o},{project:this.project,unproject:this.unproject,coordinatePrecision:this.coordinatePrecision,updateType:e.Finish}).valid)return;const[s]=this.store.create([{geometry:i,properties:o}]);this.onFinish(s,{mode:this.mode,action:"draw"})}onRightClick(t){if(!this.editable)return;const e=this.getNearestPointFeature(t);e&&this.store.delete([e.id])}getNearestPointFeature(t){const e=this.clickBoundingBox.create(t),i=this.store.search(e);let o,s=Infinity;for(let e=0;e<i.length;e++){const n=i[e];if("Point"!==n.geometry.type||n.properties.mode!==this.mode)continue;const r=this.pixelDistance.measure(t,n.geometry.coordinates);r>s||r>this.pointerDistance||(s=r,o=n)}return o}}class bt extends Z{constructor(t,e){super(t),this.config=void 0,this.pixelDistance=void 0,this._startEndPoints=[],this.config=t,this.pixelDistance=e}get ids(){return this._startEndPoints.concat()}set ids(t){}create(t,e){if(this.ids.length)throw new Error("Opening and closing points already created");if(t.length<=3)throw new Error("Requires at least 4 coordinates");this._startEndPoints=this.store.create([{geometry:{type:"Point",coordinates:t[0]},properties:{mode:e,[s]:!0}},{geometry:{type:"Point",coordinates:t[t.length-2]},properties:{mode:e,[s]:!0}}])}delete(){this.ids.length&&(this.store.delete(this.ids),this._startEndPoints=[])}update(t){if(2!==this.ids.length)throw new Error("No closing points to update");this.store.updateGeometry([{id:this.ids[0],geometry:{type:"Point",coordinates:t[0]}},{id:this.ids[1],geometry:{type:"Point",coordinates:t[t.length-3]}}])}isClosingPoint(t){const e=this.store.getGeometryCopy(this.ids[0]),i=this.store.getGeometryCopy(this.ids[1]),o=this.pixelDistance.measure(t,e.coordinates),s=this.pixelDistance.measure(t,i.coordinates);return{isClosing:o<this.pointerDistance,isPreviousClosing:s<this.pointerDistance}}}class kt extends Z{constructor(t){super(t)}createOrUpdate(t){const e=this.store.getGeometryCopy(t),i=this.store.getPropertiesCopy(t);let o;if("Polygon"===e.type)o=e.coordinates[0].slice(0,-1);else{if("LineString"!==e.type)return;o=e.coordinates}const s=this.store.getPropertiesCopy(t),n=s.coordinatePointIds;if(n)if(n&&n.every(t=>this.store.has(t))){const e=s.coordinatePointIds,n=e.map(t=>this.store.getGeometryCopy(t).coordinates);if(e.length!==o.length){this.deleteCoordinatePoints(e);const s=this.createPoints(o,i.mode,t);this.setFeatureCoordinatePoints(t,s)}else o.forEach((t,i)=>{t[0]===n[i][0]&&t[1]===n[i][1]||this.store.updateGeometry([{id:e[i],geometry:{type:"Point",coordinates:t}}])})}else{const e=n.filter(t=>this.store.has(t));e.length&&this.deleteCoordinatePoints(e);const s=this.createPoints(o,i.mode,t);this.setFeatureCoordinatePoints(t,s)}else{const e=this.createPoints(o,i.mode,t);this.setFeatureCoordinatePoints(t,e)}}deletePointsByFeatureIds(t){for(const e of t)this.deleteIfPresent(e)}getUpdated(e,i){const o=this.store.getPropertiesCopy(e);if(o.coordinatePointIds)return o.coordinatePointIds.map((e,o)=>({id:e,geometry:t({},this.store.getGeometryCopy(e),{coordinates:i[o]})}))}createPoints(t,e,i){return this.store.create(t.map((t,o)=>({geometry:{type:"Point",coordinates:t},properties:{mode:e,[r]:!0,[a]:i,index:o}})))}setFeatureCoordinatePoints(t,e){this.store.updateProperty([{id:t,property:d,value:e}])}deleteCoordinatePoints(t){const e=t.filter(t=>this.store.has(t));this.store.delete(e)}deleteIfPresent(t){const e=this.store.getPropertiesCopy(t).coordinatePointIds;e&&(this.deleteCoordinatePoints(e),this.setFeatureCoordinatePoints(t,null))}}const Ot={cancel:"Escape",finish:"Enter"},_t={start:"crosshair",close:"pointer",dragStart:"grabbing",dragEnd:"crosshair"};class jt extends m{constructor(t){super(t,!0),this.mode="polygon",this.currentCoordinate=0,this.currentId=void 0,this.keyEvents=Ot,this.cursors=_t,this.mouseMove=!1,this.showCoordinatePoints=!1,this.snapping=void 0,this.snappedPointId=void 0,this.editable=!1,this.editedFeatureId=void 0,this.editedFeatureCoordinateIndex=void 0,this.editedSnapType=void 0,this.editedInsertIndex=void 0,this.editedPointId=void 0,this.coordinatePoints=void 0,this.lineSnapping=void 0,this.coordinateSnapping=void 0,this.pixelDistance=void 0,this.closingPoints=void 0,this.clickBoundingBox=void 0,this.updateOptions(t)}updateOptions(e){if(super.updateOptions(e),null!=e&&e.cursors&&(this.cursors=t({},this.cursors,e.cursors)),null===(null==e?void 0:e.keyEvents)?this.keyEvents={cancel:null,finish:null}:null!=e&&e.keyEvents&&(this.keyEvents=t({},this.keyEvents,e.keyEvents)),null!=e&&e.snapping&&(this.snapping=e.snapping),void 0!==(null==e?void 0:e.editable)&&(this.editable=e.editable),void 0!==(null==e?void 0:e.pointerEvents)&&(this.pointerEvents=e.pointerEvents),void 0!==(null==e?void 0:e.showCoordinatePoints))if(this.showCoordinatePoints=e.showCoordinatePoints,this.coordinatePoints&&!0===e.showCoordinatePoints)this.store.copyAllWhere(t=>t.mode===this.mode).map(t=>t.id).forEach(t=>{this.coordinatePoints.createOrUpdate(t)});else if(this.coordinatePoints&&!1===this.showCoordinatePoints){const t=this.store.copyAllWhere(t=>t.mode===this.mode&&Boolean(t[d]));this.coordinatePoints.deletePointsByFeatureIds(t.map(t=>t.id))}}close(){if(void 0===this.currentId)return;const t=this.store.getGeometryCopy(this.currentId).coordinates[0];if(t.length<5)return;if(!this.updatePolygonGeometry([...t.slice(0,-2),t[0]],e.Finish))return;const i=this.currentId;if(this.currentId){const t=Y(this.store.getGeometryCopy(this.currentId));t&&this.store.updateGeometry([{id:this.currentId,geometry:t}])}this.snappedPointId&&this.store.delete([this.snappedPointId]),this.currentCoordinate=0,this.currentId=void 0,this.snappedPointId=void 0,this.closingPoints.delete(),"drawing"===this.state&&this.setStarted(),this.onFinish(i,{mode:this.mode,action:"draw"})}registerBehaviors(t){this.clickBoundingBox=new Q(t),this.pixelDistance=new tt(t),this.lineSnapping=new Ct(t,this.pixelDistance,this.clickBoundingBox),this.coordinateSnapping=new et(t,this.pixelDistance,this.clickBoundingBox),this.closingPoints=new bt(t,this.pixelDistance),this.coordinatePoints=new kt(t)}start(){this.setStarted(),this.setCursor(this.cursors.start)}stop(){this.cleanUp(),this.setStopped(),this.setCursor("unset")}onMouseMove(t){this.mouseMove=!0,this.setCursor(this.cursors.start);const i=this.snapCoordinate(t);if(i){if(this.snappedPointId)this.store.updateGeometry([{id:this.snappedPointId,geometry:{type:"Point",coordinates:i}}]);else{const[t]=this.store.create([{geometry:{type:"Point",coordinates:i},properties:{mode:this.mode,[n]:!0}}]);this.snappedPointId=t}t.lng=i[0],t.lat=i[1]}else this.snappedPointId&&(this.store.delete([this.snappedPointId]),this.snappedPointId=void 0);if(void 0===this.currentId||0===this.currentCoordinate)return;const o=this.store.getGeometryCopy(this.currentId).coordinates[0];let s;if(1===this.currentCoordinate){const e=1/Math.pow(10,this.coordinatePrecision-1),i=Math.max(1e-6,e);s=[o[0],[t.lng,t.lat],[t.lng,t.lat-i],o[0]]}else if(2===this.currentCoordinate)s=[o[0],o[1],[t.lng,t.lat],o[0]];else{const{isClosing:e,isPreviousClosing:i}=this.closingPoints.isClosingPoint(t);i||e?(this.snappedPointId&&(this.store.delete([this.snappedPointId]),this.snappedPointId=void 0),this.setCursor(this.cursors.close),s=[...o.slice(0,-2),o[0],o[0]]):s=[...o.slice(0,-2),[t.lng,t.lat],o[0]]}this.updatePolygonGeometry(s,e.Provisional)}updatePolygonGeometry(t,e){if(!this.currentId)return!1;const i={type:"Polygon",coordinates:[t]};return!(this.validate&&!this.validate({type:"Feature",geometry:i},{project:this.project,unproject:this.unproject,coordinatePrecision:this.coordinatePrecision,updateType:e}).valid||(this.store.updateGeometry([{id:this.currentId,geometry:i}]),this.showCoordinatePoints&&this.coordinatePoints.createOrUpdate(this.currentId),0))}snapCoordinate(t){var e,i,o;let s;if(null!=