terra-draw 0.0.1-alpha.7 → 0.0.1-alpha.9

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.
@@ -1 +1 @@
1
- {"version":3,"file":"terra-draw.cjs","sources":["../src/geometry/limit-decimal-precision.ts","../src/adapters/google-maps.adapter.ts","../src/adapters/leaflet.adapter.ts","../src/adapters/mapbox-gl.adapter.ts","../src/geometry/measure/haversine-distance.ts","../src/geometry/helpers.ts","../src/geometry/shape/create-circle.ts","../src/util/styling.ts","../src/modes/base.mode.ts","../src/modes/circle/circle.mode.ts","../src/modes/freehand/freehand.mode.ts","../src/geometry/boolean/self-intersects.ts","../src/geometry/measure/pixel-distance.ts","../src/modes/base.behavior.ts","../src/modes/click-bounding-box.behavior.ts","../src/modes/pixel-distance.behavior.ts","../src/modes/snapping.behavior.ts","../src/modes/linestring/linestring.mode.ts","../src/modes/point/point.mode.ts","../src/geometry/coordinates-identical.ts","../src/common.ts","../src/modes/polygon/behaviors/closing-points.behavior.ts","../src/modes/polygon/polygon.mode.ts","../src/util/geoms.ts","../src/modes/render/render.mode.ts","../src/geometry/midpoint-coordinate.ts","../src/geometry/get-midpoints.ts","../src/modes/select/behaviors/midpoint.behavior.ts","../src/modes/select/behaviors/selection-point.behavior.ts","../src/geometry/get-coordinates-as-points.ts","../src/geometry/boolean/point-in-polygon.ts","../src/geometry/measure/pixel-distance-to-line.ts","../src/modes/select/behaviors/features-at-mouse-event.behavior.ts","../src/modes/select/behaviors/drag-feature.behavior.ts","../src/modes/select/behaviors/drag-coordinate.behavior.ts","../src/geometry/centroid.ts","../src/geometry/measure/rhumb-bearing.ts","../src/geometry/measure/rhumb-destination.ts","../src/geometry/measure/rhumb-distance.ts","../src/modes/select/behaviors/rotate-feature.behavior.ts","../src/geometry/transform/rotate.ts","../src/modes/select/behaviors/scale-feature.behavior.ts","../src/geometry/transform/scale.ts","../src/modes/select/select.mode.ts","../src/modes/static/static.mode.ts","../src/util/id.ts","../src/store/spatial-index/quickselect.ts","../src/store/spatial-index/rbush.ts","../src/store/spatial-index/spatial-index.ts","../src/store/store.ts","../src/terra-draw.ts"],"sourcesContent":["export function limitPrecision(num: number, decimalLimit = 9) {\n const decimals = Math.pow(10, decimalLimit);\n return Math.round(num * decimals) / decimals;\n}\n","import {\n TerraDrawCallbacks,\n TerraDrawAdapter,\n TerraDrawModeRegisterConfig,\n TerraDrawAdapterStyling,\n TerraDrawChanges,\n TerraDrawMouseEvent\n} from \"../common\";\nimport { GeoJsonObject } from \"geojson\";\n\nimport { limitPrecision } from \"../geometry/limit-decimal-precision\";\nimport { GeoJSONStoreFeatures } from \"../store/store\";\n\nexport class TerraDrawGoogleMapsAdapter implements TerraDrawAdapter {\n constructor(config: {\n lib: typeof google.maps;\n map: google.maps.Map;\n coordinatePrecision?: number;\n }) {\n this._lib = config.lib;\n this._map = config.map;\n this._coordinatePrecision =\n typeof config.coordinatePrecision === \"number\"\n ? config.coordinatePrecision\n : 9;\n\n this.getMapContainer = () => {\n return this._map.getDiv();\n };\n\n this.project = (lng, lat) => {\n const bounds = this._map.getBounds();\n\n if (bounds === undefined) {\n throw new Error(\"cannot get bounds\");\n }\n\n const northWest = new this._lib.LatLng(\n bounds.getNorthEast().lat(),\n bounds.getSouthWest().lng()\n );\n\n const projection = this._map.getProjection();\n if (projection === undefined) {\n throw new Error(\"cannot get projection\");\n }\n\n const projectedNorthWest = projection.fromLatLngToPoint(northWest);\n if (projectedNorthWest === null) {\n throw new Error(\"cannot get projectedNorthWest\");\n }\n\n const projected = projection.fromLatLngToPoint({ lng, lat });\n if (projected === null) {\n throw new Error(\"cannot get projected lng lat\");\n }\n\n const zoom = this._map.getZoom();\n if (zoom === undefined) {\n throw new Error(\"cannot get zoom\");\n }\n\n const scale = Math.pow(2, zoom);\n return {\n x: Math.floor((projected.x - projectedNorthWest.x) * scale),\n y: Math.floor((projected.y - projectedNorthWest.y) * scale),\n };\n };\n\n this.unproject = (x, y) => {\n const projection = this._map.getProjection();\n if (projection === undefined) {\n throw new Error(\"cannot get projection\");\n }\n\n const bounds = this._map.getBounds();\n if (bounds === undefined) {\n throw new Error(\"cannot get bounds\");\n }\n\n const topRight = projection.fromLatLngToPoint(bounds.getNorthEast());\n if (topRight === null) {\n throw new Error(\"cannot get topRight\");\n }\n\n const bottomLeft = projection.fromLatLngToPoint(bounds.getSouthWest());\n if (bottomLeft === null) {\n throw new Error(\"cannot get bottomLeft\");\n }\n\n const zoom = this._map.getZoom();\n if (zoom === undefined) {\n throw new Error(\"zoom get bounds\");\n }\n\n const scale = Math.pow(2, zoom);\n\n const worldPoint = new google.maps.Point(\n x / scale + bottomLeft.x,\n y / scale + topRight.y\n );\n const lngLat = projection.fromPointToLatLng(worldPoint);\n\n if (lngLat === null) {\n throw new Error(\"zoom get bounds\");\n }\n\n return { lng: lngLat.lng(), lat: lngLat.lat() };\n };\n\n this.setCursor = (cursor) => {\n if (cursor === this._cursor) {\n return;\n }\n\n if (this._cursorStyleSheet) {\n this._cursorStyleSheet.remove();\n this._cursorStyleSheet = undefined;\n }\n\n if (cursor !== \"unset\") {\n // TODO: We could cache these individually per cursor\n\n const div = this.getMapContainer();\n const style = document.createElement(\"style\");\n style.type = \"text/css\";\n const selector = `#${div.id} [aria-label=\"Map\"]`;\n style.innerHTML = `${selector} { cursor: ${cursor} !important; }`;\n document.getElementsByTagName(\"head\")[0].appendChild(style);\n this._cursorStyleSheet = style;\n }\n\n this._cursor = cursor;\n };\n }\n\n private _heldKeys: Set<string> = new Set();\n private _cursor: string | undefined;\n private _cursorStyleSheet: HTMLStyleElement | undefined;\n private _coordinatePrecision: number;\n private _lib: typeof google.maps;\n private _map: google.maps.Map;\n private _onMouseMoveListener: google.maps.MapsEventListener | undefined;\n private _onMouseMoveCallback:\n | ((\n event: google.maps.MapMouseEvent & {\n domEvent: MouseEvent;\n }\n ) => void)\n | undefined;\n private _onClickListener: google.maps.MapsEventListener | undefined;\n private _onRightClickListener: google.maps.MapsEventListener | undefined;\n private _onClickCallback:\n | ((\n event: google.maps.MapMouseEvent & {\n domEvent: MouseEvent;\n }\n ) => void)\n | undefined;\n private _onKeyUpListener: any;\n private _onDragStartListener: ((event: MouseEvent) => void) | undefined;\n private _onDragListener: ((event: MouseEvent) => void) | undefined;\n private _onDragEndListener: ((event: MouseEvent) => void) | undefined;\n private _layers = false;\n\n public getMapContainer: () => HTMLElement;\n\n public unproject: (x: number, y: number) => { lng: number; lat: number };\n public project: TerraDrawModeRegisterConfig[\"project\"];\n public setCursor: TerraDrawModeRegisterConfig[\"setCursor\"];\n\n // https://stackoverflow.com/a/27905268/1363484\n private circlePath(cx: number, cy: number, r: number) {\n return (\n \"M \" +\n cx +\n \" \" +\n cy +\n \" m -\" +\n r +\n \", 0 a \" +\n r +\n \",\" +\n r +\n \" 0 1,0 \" +\n r * 2 +\n \",0 a \" +\n r +\n \",\" +\n r +\n \" 0 1,0 -\" +\n r * 2 +\n \",0\"\n );\n }\n\n register(callbacks: TerraDrawCallbacks) {\n this._onClickCallback = (\n event: google.maps.MapMouseEvent & {\n domEvent: MouseEvent;\n }\n ) => {\n if (!event.latLng) {\n return;\n }\n callbacks.onClick({\n lng: limitPrecision(event.latLng.lng(), this._coordinatePrecision),\n lat: limitPrecision(event.latLng.lat(), this._coordinatePrecision),\n containerX: event.domEvent.clientX - this.getMapContainer().offsetLeft,\n containerY: event.domEvent.clientY - this.getMapContainer().offsetTop,\n button: event.domEvent.button === 0 ? \"left\" : \"right\",\n heldKeys: [...this._heldKeys],\n });\n };\n this._onClickListener = this._map.addListener(\n \"click\",\n this._onClickCallback\n );\n\n this._onRightClickListener = this._map.addListener(\n \"rightclick\",\n this._onClickCallback\n );\n\n this._onMouseMoveCallback = (\n event: google.maps.MapMouseEvent & {\n domEvent: MouseEvent;\n }\n ) => {\n if (!event.latLng) {\n return;\n }\n callbacks.onMouseMove({\n lng: limitPrecision(event.latLng.lng(), this._coordinatePrecision),\n lat: limitPrecision(event.latLng.lat(), this._coordinatePrecision),\n containerX: event.domEvent.clientX - this.getMapContainer().offsetLeft,\n containerY: event.domEvent.clientY - this.getMapContainer().offsetTop,\n button: event.domEvent.button === 0 ? \"left\" : \"right\",\n heldKeys: [...this._heldKeys],\n });\n };\n this._onMouseMoveListener = this._map.addListener(\n \"mousemove\",\n this._onMouseMoveCallback\n );\n\n this._onKeyUpListener = (event: KeyboardEvent) => {\n callbacks.onKeyUp({\n key: event.key,\n });\n };\n\n this.getMapContainer().addEventListener(\"keyup\", this._onKeyUpListener);\n\n let dragState: \"not-dragging\" | \"pre-dragging\" | \"dragging\" =\n \"not-dragging\";\n\n this._onDragStartListener = (event) => {\n dragState = \"pre-dragging\";\n };\n\n const container = this.getMapContainer();\n\n container.addEventListener(\"mousedown\", this._onDragStartListener);\n\n this._onDragListener = (event) => {\n const point = {\n x: event.clientX - container.offsetLeft,\n y: event.clientY - container.offsetTop,\n } as L.Point;\n\n const { lng, lat } = this.unproject(point.x, point.y);\n\n const drawEvent: TerraDrawMouseEvent = {\n lng: limitPrecision(lng, this._coordinatePrecision),\n lat: limitPrecision(lat, this._coordinatePrecision),\n containerX: event.clientX - container.offsetLeft,\n containerY: event.clientY - container.offsetTop,\n button: event.button === 0 ? \"left\" : \"right\",\n heldKeys: [...this._heldKeys],\n };\n\n if (dragState === \"pre-dragging\") {\n dragState = \"dragging\";\n callbacks.onDragStart(drawEvent, (enabled) => {\n this._map.setOptions({ draggable: false });\n });\n } else if (dragState === \"dragging\") {\n callbacks.onDrag(drawEvent);\n }\n };\n\n container.addEventListener(\"mousemove\", this._onDragListener);\n\n this._onDragEndListener = (event) => {\n if (dragState === \"dragging\") {\n const point = {\n x: event.clientX - container.offsetLeft,\n y: event.clientY - container.offsetTop,\n } as L.Point;\n\n const { lng, lat } = this.unproject(point.x, point.y);\n\n callbacks.onDragEnd(\n {\n lng: limitPrecision(lng, this._coordinatePrecision),\n lat: limitPrecision(lat, this._coordinatePrecision),\n containerX: event.clientX - container.offsetLeft,\n containerY: event.clientY - container.offsetTop,\n button: event.button === 0 ? \"left\" : \"right\",\n heldKeys: [...this._heldKeys],\n },\n (enabled) => {\n this._map.setOptions({ draggable: enabled });\n }\n );\n }\n\n dragState = \"not-dragging\";\n };\n\n container.addEventListener(\"mouseup\", this._onDragEndListener);\n }\n\n unregister() {\n if (this._onClickListener) {\n this._onClickCallback = undefined;\n this._onClickListener.remove();\n this._onClickListener = undefined;\n }\n if (this._onRightClickListener) {\n this._onClickCallback = undefined;\n this._onRightClickListener.remove();\n this._onRightClickListener = undefined;\n }\n if (this._onMouseMoveListener) {\n this._onMouseMoveCallback = undefined;\n this._onMouseMoveListener.remove();\n this._onMouseMoveListener = undefined;\n }\n\n if (this._onKeyUpListener) {\n this.getMapContainer().removeEventListener(\n \"keyup\",\n this._onKeyUpListener\n );\n this._onKeyUpListener = undefined;\n }\n }\n\n render(\n changes: TerraDrawChanges,\n styling: { [mode: string]: (feature: GeoJSONStoreFeatures) => TerraDrawAdapterStyling }\n ) {\n if (this._layers) {\n changes.deletedIds.forEach((deletedId) => {\n const featureToDelete = this._map.data.getFeatureById(deletedId);\n featureToDelete && this._map.data.remove(featureToDelete);\n });\n\n changes.updated.forEach((updatedFeature) => {\n if (!updatedFeature || !updatedFeature.id) {\n throw new Error(\"Feature is not valid\");\n }\n\n const featureToUpdate = this._map.data.getFeatureById(\n updatedFeature.id\n );\n\n if (!featureToUpdate) {\n throw new Error(\"Feature could not be found by Google Maps API\");\n }\n\n // Remove all keys\n featureToUpdate.forEachProperty((property, name) => {\n featureToUpdate.setProperty(name, undefined);\n });\n\n // Update all keys\n Object.keys(updatedFeature.properties).forEach((property) => {\n featureToUpdate.setProperty(\n property,\n updatedFeature.properties[property]\n );\n });\n\n switch (updatedFeature.geometry.type) {\n case \"Point\":\n {\n const coordinates = updatedFeature.geometry.coordinates;\n\n featureToUpdate.setGeometry(\n new google.maps.Data.Point(\n new google.maps.LatLng(coordinates[1], coordinates[0])\n )\n );\n }\n break;\n case \"LineString\":\n {\n const coordinates = updatedFeature.geometry.coordinates;\n\n const path = [];\n for (let i = 0; i < coordinates.length; i++) {\n const coordinate = coordinates[i];\n const latLng = new google.maps.LatLng(\n coordinate[1],\n coordinate[0]\n );\n path.push(latLng);\n }\n\n featureToUpdate.setGeometry(\n new google.maps.Data.LineString(path)\n );\n }\n break;\n case \"Polygon\":\n {\n const coordinates = updatedFeature.geometry.coordinates;\n\n const paths = [];\n for (let i = 0; i < coordinates.length; i++) {\n const path = [];\n for (let j = 0; j < coordinates[i].length; j++) {\n const latLng = new google.maps.LatLng(\n coordinates[i][j][1],\n coordinates[i][j][0]\n );\n path.push(latLng);\n }\n paths.push(path);\n }\n\n featureToUpdate.setGeometry(new google.maps.Data.Polygon(paths));\n }\n\n break;\n }\n });\n\n // Create new features\n changes.created.forEach((createdFeature) => {\n this._map.data.addGeoJson(createdFeature);\n });\n } else {\n // Clicking on data geometries triggers\n // swallows the map onclick event,\n // so we need to forward it to the click callback handler\n this._map.data.addListener(\n \"click\",\n (\n event: google.maps.MapMouseEvent & {\n domEvent: MouseEvent;\n }\n ) => {\n this._onClickCallback && this._onClickCallback(event);\n }\n );\n\n this._map.data.addListener(\n \"mousemove\",\n (\n event: google.maps.MapMouseEvent & {\n domEvent: MouseEvent;\n }\n ) => {\n this._onMouseMoveCallback && this._onMouseMoveCallback(event);\n }\n );\n }\n\n const featureCollection = {\n type: \"FeatureCollection\",\n features: [...changes.created],\n } as GeoJsonObject;\n\n this._map.data.addGeoJson(featureCollection);\n\n this._map.data.setStyle((feature) => {\n const mode = feature.getProperty(\"mode\");\n const gmGeometry = feature.getGeometry();\n if (!gmGeometry) {\n throw new Error(\"Google Maps geometry not found\");\n }\n const type = gmGeometry.getType();\n const properties: Record<string, any> = {};\n\n feature.forEachProperty((value, property) => {\n properties[property] = value;\n });\n\n const calculatedStyles = styling[mode]({\n type: \"Feature\",\n geometry: {\n type: type as \"Point\" | \"LineString\" | \"Polygon\",\n coordinates: []\n },\n properties\n });\n\n\n switch (type) {\n case \"Point\":\n\n const path = this.circlePath(\n 0,\n 0,\n calculatedStyles.pointWidth\n );\n\n return {\n clickable: false,\n icon: {\n path,\n fillColor: calculatedStyles.pointColor,\n fillOpacity: 1,\n strokeColor: calculatedStyles.pointOutlineColor,\n strokeWeight: calculatedStyles.pointOutlineWidth,\n rotation: 0,\n scale: 1,\n },\n };\n\n case \"LineString\":\n return {\n strokeColor: calculatedStyles.lineStringColor,\n strokeWeight: calculatedStyles.lineStringWidth,\n };\n case \"Polygon\":\n return {\n strokeColor: calculatedStyles.polygonOutlineColor,\n strokeWeight: calculatedStyles.polygonOutlineWidth,\n fillOpacity: calculatedStyles.polygonFillOpacity,\n fillColor: calculatedStyles.polygonFillColor,\n };\n }\n\n throw Error(\"Unknown feature type\");\n });\n\n this._layers = true;\n }\n}\n","import {\n TerraDrawCallbacks,\n TerraDrawAdapter,\n TerraDrawModeRegisterConfig,\n TerraDrawAdapterStyling,\n TerraDrawChanges,\n TerraDrawMouseEvent\n} from \"../common\";\nimport L from \"leaflet\";\nimport { limitPrecision } from \"../geometry/limit-decimal-precision\";\nimport { GeoJSONStoreFeatures } from \"../store/store\";\n\nexport class TerraDrawLeafletAdapter implements TerraDrawAdapter {\n constructor(config: {\n lib: typeof L;\n map: L.Map;\n coordinatePrecision?: number;\n }) {\n this._lib = config.lib;\n this._map = config.map;\n this._coordinatePrecision =\n typeof config.coordinatePrecision === \"number\"\n ? config.coordinatePrecision\n : 9;\n\n this.getMapContainer = () => {\n return this._map.getContainer();\n };\n\n this.project = (lng: number, lat: number) => {\n const { x, y } = this._map.latLngToContainerPoint({ lng, lat });\n return { x, y };\n };\n\n this.unproject = (x: number, y: number) => {\n const { lng, lat } = this._map.containerPointToLatLng({\n x,\n y,\n } as L.PointExpression);\n return { lng, lat };\n };\n\n this.setCursor = (cursor) => {\n if (cursor === \"unset\") {\n this.getMapContainer().style.removeProperty(\"cursor\");\n } else {\n this.getMapContainer().style.cursor = cursor;\n }\n };\n }\n\n private _heldKeys: Set<string> = new Set();\n private _lib: typeof L;\n private _coordinatePrecision: number;\n private _map: L.Map;\n private _onMouseMoveListener: ((ev: any) => void) | undefined;\n private _onClickListener: ((ev: any) => void) | undefined;\n private _onKeyUpListener: ((ev: any) => void) | undefined;\n private _onKeyDownListener: ((ev: any) => void) | undefined;\n\n private _onDragStartListener: ((event: MouseEvent) => void) | undefined;\n private _onDragListener: ((event: MouseEvent) => void) | undefined;\n private _onDragEndListener: ((event: MouseEvent) => void) | undefined;\n private _layer: L.Layer | undefined;\n private _panes: Record<string, HTMLStyleElement | undefined> = {};\n public project: TerraDrawModeRegisterConfig[\"project\"];\n public unproject: TerraDrawModeRegisterConfig[\"unproject\"];\n public setCursor: TerraDrawModeRegisterConfig[\"setCursor\"];\n\n public getMapContainer: () => HTMLElement;\n\n private createPaneStyleSheet(pane: string, zIndex: number) {\n const style = document.createElement(\"style\");\n style.type = \"text/css\";\n style.innerHTML = `.leaflet-${pane} {z-index: ${zIndex};}`;\n document.getElementsByTagName(\"head\")[0].appendChild(style);\n this._map.createPane(pane);\n return style;\n }\n\n register(callbacks: TerraDrawCallbacks) {\n\n const container = this.getMapContainer();\n\n let dragState:\n | \"not-dragging\"\n | \"pre-dragging\"\n | \"dragging\"\n | \"after-dragging\" = \"not-dragging\";\n\n this._onClickListener = (event: L.LeafletMouseEvent) => {\n if (dragState === \"not-dragging\" || dragState === \"pre-dragging\") {\n callbacks.onClick({\n lng: limitPrecision(event.latlng.lng, this._coordinatePrecision),\n lat: limitPrecision(event.latlng.lat, this._coordinatePrecision),\n containerX:\n event.originalEvent.clientX - this.getMapContainer().offsetLeft,\n containerY:\n event.originalEvent.clientY - this.getMapContainer().offsetTop,\n button: event.originalEvent.button === 0 ? \"left\" : \"right\",\n heldKeys: [...this._heldKeys],\n });\n }\n };\n\n // We can't use 'click' here because it triggers\n // after drag end in Leaflet for some reason\n this._map.on(\"mouseup\", this._onClickListener);\n this._map.on(\"contextmenu\", this._onClickListener);\n\n this._onMouseMoveListener = (event: L.LeafletMouseEvent) => {\n event.originalEvent.preventDefault();\n\n callbacks.onMouseMove({\n lng: limitPrecision(event.latlng.lng, this._coordinatePrecision),\n lat: limitPrecision(event.latlng.lat, this._coordinatePrecision),\n containerX:\n event.originalEvent.clientX - this.getMapContainer().offsetLeft,\n containerY:\n event.originalEvent.clientY - this.getMapContainer().offsetTop,\n button: event.originalEvent.button === 0 ? \"left\" : \"right\",\n heldKeys: [...this._heldKeys],\n });\n };\n this._map.on(\"mousemove\", this._onMouseMoveListener);\n\n this._onDragStartListener = (event) => {\n dragState = \"pre-dragging\";\n };\n container.addEventListener(\"pointerdown\", this._onDragStartListener);\n\n this._onDragListener = (event) => {\n const point = {\n x: event.clientX - container.offsetLeft,\n y: event.clientY - container.offsetTop,\n } as L.Point;\n\n const { lng, lat } = this._map.containerPointToLatLng(point);\n\n const drawEvent: TerraDrawMouseEvent = {\n lng: limitPrecision(lng, this._coordinatePrecision),\n lat: limitPrecision(lat, this._coordinatePrecision),\n containerX: event.clientX - container.offsetLeft,\n containerY: event.clientY - container.offsetTop,\n button: event.button === 0 ? \"left\" : \"right\",\n heldKeys: [...this._heldKeys],\n };\n\n if (dragState === \"pre-dragging\") {\n dragState = \"dragging\";\n\n callbacks.onDragStart(drawEvent, (enabled) => {\n if (enabled) {\n this._map.dragging.enable();\n } else {\n this._map.dragging.disable();\n }\n });\n } else if (dragState === \"dragging\") {\n callbacks.onDrag(drawEvent);\n }\n };\n\n container.addEventListener(\"pointermove\", this._onDragListener);\n\n this._onDragEndListener = (event) => {\n event.preventDefault();\n\n if (dragState === \"dragging\") {\n const point = {\n x: event.clientX - container.offsetLeft,\n y: event.clientY - container.offsetTop,\n } as L.Point;\n\n const { lng, lat } = this._map.containerPointToLatLng(point);\n\n callbacks.onDragEnd(\n {\n lng: limitPrecision(lng, this._coordinatePrecision),\n lat: limitPrecision(lat, this._coordinatePrecision),\n containerX: event.clientX - container.offsetLeft,\n containerY: event.clientY - container.offsetTop,\n button: event.button === 0 ? \"left\" : \"right\",\n heldKeys: [...this._heldKeys],\n },\n (enabled) => {\n if (enabled) {\n this._map.dragging.enable();\n } else {\n this._map.dragging.disable();\n }\n }\n );\n\n // We want to avoid triggering an click\n // event after dragging\n dragState = \"after-dragging\";\n this._map.dragging.enable();\n return;\n }\n\n dragState = \"not-dragging\";\n this._map.dragging.enable();\n };\n\n container.addEventListener(\"pointerup\", this._onDragEndListener);\n\n // map has no keypress event, so we add one to the canvas itself\n this._onKeyUpListener = (event: KeyboardEvent) => {\n event.preventDefault();\n\n this._heldKeys.delete(event.key);\n\n callbacks.onKeyUp({\n key: event.key,\n });\n };\n container.addEventListener(\"keyup\", this._onKeyUpListener);\n\n this._onKeyDownListener = (event: KeyboardEvent) => {\n event.preventDefault();\n\n this._heldKeys.add(event.key);\n\n callbacks.onKeyDown({\n key: event.key,\n });\n };\n container.addEventListener(\"keydown\", this._onKeyDownListener);\n }\n\n unregister() {\n if (this._onClickListener) {\n this._map.off(\"contextmenu\", this._onClickListener);\n this._map.off(\"click\", this._onClickListener);\n this._onClickListener = undefined;\n }\n if (this._onMouseMoveListener) {\n this._map.off(\"click\", this._onClickListener);\n this._onClickListener = undefined;\n }\n\n Object.keys(this._panes).forEach((pane) => {\n const selectedPane = this._map.getPane(pane);\n if (selectedPane) {\n selectedPane.remove();\n }\n });\n }\n\n render(\n changes: TerraDrawChanges,\n styling: { [mode: string]: (feature: GeoJSONStoreFeatures) => TerraDrawAdapterStyling }\n ) {\n const features = [\n ...changes.created,\n ...changes.updated,\n ...changes.unchanged,\n ];\n\n if (this._layer) {\n this._map.removeLayer(this._layer);\n }\n\n const featureCollection = {\n type: \"FeatureCollection\",\n features,\n } as { type: \"FeatureCollection\", features: GeoJSONStoreFeatures[] };\n\n const layer = this._lib.geoJSON(featureCollection, {\n // Style points - convert markers to circle markers\n pointToLayer: (feature: GeoJSONStoreFeatures, latlng: L.LatLngExpression) => {\n if (!feature.properties) {\n throw new Error(\"Feature has no properties\");\n }\n if (typeof feature.properties.mode !== 'string') {\n throw new Error(\"Feature mode is not a string\");\n }\n\n const mode = feature.properties.mode;\n const modeStyle = styling[mode];\n const featureStyles = modeStyle(feature);\n const paneId = String(featureStyles.zIndex);\n const pane = this._panes[paneId];\n\n if (!pane) {\n this._panes[paneId] = this.createPaneStyleSheet(paneId, featureStyles.zIndex);\n }\n\n const styles = {\n radius: featureStyles.pointWidth,\n stroke: featureStyles.pointOutlineWidth || false,\n color: featureStyles.pointOutlineColor,\n weight: featureStyles.pointOutlineWidth,\n fillOpacity: 0.8,\n fillColor: featureStyles.pointColor,\n pane: paneId,\n interactive: false, // Removes mouse hover cursor styles\n } as L.CircleMarkerOptions;\n\n const marker = this._lib.circleMarker(latlng, styles);\n\n return marker;\n },\n\n // Style LineStrings and Polygons\n style: (_feature) => {\n if (!_feature || !_feature.properties) {\n return {};\n }\n\n const feature = _feature as GeoJSONStoreFeatures;\n\n const mode = feature.properties.mode as string;\n const modeStyle = styling[mode];\n const featureStyles = modeStyle(feature);\n\n if (feature.geometry.type === \"LineString\") {\n return {\n interactive: false, // Removes mouse hover cursor styles\n color: featureStyles.lineStringColor,\n weight: featureStyles.lineStringWidth,\n };\n } else if (feature.geometry.type === \"Polygon\") {\n return {\n interactive: false, // Removes mouse hover cursor styles\n fillOpacity: featureStyles.polygonFillOpacity,\n fillColor: featureStyles.polygonFillColor,\n weight: featureStyles.polygonOutlineWidth,\n stroke: true,\n color: featureStyles.polygonFillColor\n };\n }\n\n return {};\n },\n });\n\n this._map.addLayer(layer);\n\n this._layer = layer;\n }\n}\n","import {\n TerraDrawCallbacks,\n TerraDrawAdapter,\n TerraDrawModeRegisterConfig,\n TerraDrawAdapterStyling,\n TerraDrawChanges,\n TerraDrawMouseEvent\n} from \"../common\";\nimport { Feature, LineString, Point, Polygon } from \"geojson\";\nimport { limitPrecision } from \"../geometry/limit-decimal-precision\";\nimport mapboxgl, {\n CircleLayer,\n FillLayer,\n LineLayer,\n PointLike,\n} from \"mapbox-gl\";\nimport { GeoJSONStoreFeatures, GeoJSONStoreGeometries } from \"../store/store\";\n\nexport class TerraDrawMapboxGLAdapter implements TerraDrawAdapter {\n constructor(config: { map: mapboxgl.Map; coordinatePrecision: number }) {\n this._map = config.map;\n this._coordinatePrecision =\n typeof config.coordinatePrecision === \"number\"\n ? config.coordinatePrecision\n : 9;\n\n this.project = (lng: number, lat: number) => {\n const { x, y } = this._map.project({ lng, lat });\n return { x, y };\n };\n\n this.unproject = (x: number, y: number) => {\n const { lng, lat } = this._map.unproject({ x, y } as PointLike);\n return { lng, lat };\n };\n\n this.setCursor = (style) => {\n this._map.getCanvas().style.cursor = style;\n };\n\n this.getMapContainer = () => {\n return this._map.getContainer();\n };\n }\n\n public unproject: TerraDrawModeRegisterConfig[\"unproject\"];\n public project: TerraDrawModeRegisterConfig[\"project\"];\n public setCursor: TerraDrawModeRegisterConfig[\"setCursor\"];\n\n public getMapContainer: () => HTMLElement;\n\n private _heldKeys: Set<string> = new Set();\n private _coordinatePrecision: number;\n private _map: mapboxgl.Map;\n private _onMouseMoveListener:\n | ((event: mapboxgl.MapMouseEvent & mapboxgl.EventData) => void)\n | undefined;\n private _onClickListener:\n | ((event: mapboxgl.MapMouseEvent & mapboxgl.EventData) => void)\n | undefined;\n private _onDragStartListener: ((event: MouseEvent) => void) | undefined;\n private _onDragListener: ((event: MouseEvent) => void) | undefined;\n private _onDragEndListener: ((event: MouseEvent) => void) | undefined;\n private _onKeyDownListener: ((event: KeyboardEvent) => void) | undefined;\n private _onKeyUpListener: ((event: KeyboardEvent) => any) | undefined;\n private _rendered: Record<string, boolean> = {};\n\n private _addGeoJSONSource(id: string, features: Feature[]) {\n this._map.addSource(id, {\n type: \"geojson\",\n data: {\n type: \"FeatureCollection\",\n features: features,\n },\n });\n }\n\n private _addFillLayer(\n id: string,\n mode: string,\n ) {\n return this._map.addLayer({\n id,\n source: id,\n type: \"fill\",\n filter: [\n \"all\",\n [\"match\", [\"geometry-type\"], \"Polygon\", true, false],\n [\"match\", [\"get\", \"mode\"], mode, true, false],\n ],\n paint: {\n \"fill-color\": [\"get\", \"polygonFillColor\"],\n \"fill-opacity\": [\"get\", \"polygonFillOpacity\"]\n },\n } as FillLayer);\n }\n\n private _addFillOutlineLayer(\n id: string,\n mode: string,\n beneath?: string\n ) {\n const layer = this._map.addLayer({\n id: id + \"outline\",\n source: id,\n type: \"line\",\n filter: [\n \"all\",\n [\"match\", [\"geometry-type\"], \"Polygon\", true, false],\n [\"match\", [\"get\", \"mode\"], mode, true, false],\n ],\n paint: {\n \"line-width\": [\"get\", \"polygonOutlineWidth\"],\n \"line-color\": [\"get\", \"polygonOutlineColor\"],\n },\n } as LineLayer);\n\n if (beneath) {\n this._map.moveLayer(id, beneath);\n }\n\n return layer;\n }\n\n private _addLineLayer(\n id: string,\n mode: string,\n beneath?: string\n ) {\n const layer = this._map.addLayer({\n id,\n source: id,\n type: \"line\",\n filter: [\n \"all\",\n [\"match\", [\"geometry-type\"], \"LineString\", true, false],\n [\"match\", [\"get\", \"mode\"], mode, true, false],\n ],\n paint: {\n \"line-width\": [\"get\", \"lineStringWidth\"],\n \"line-color\": [\"get\", \"lineStringColor\"],\n },\n } as LineLayer);\n\n if (beneath) {\n this._map.moveLayer(id, beneath);\n }\n\n return layer;\n }\n\n private _addPointLayer(\n id: string,\n mode: string,\n beneath?: string\n ) {\n const layer = this._map.addLayer({\n id,\n source: id,\n type: \"circle\",\n filter: [\n \"all\",\n [\"match\", [\"geometry-type\"], \"Point\", true, false],\n [\"match\", [\"get\", \"mode\"], mode, true, false],\n ],\n paint: {\n \"circle-stroke-color\": [\"get\", \"pointOutlineColor\"],\n \"circle-stroke-width\": [\"get\", \"pointOutlineWidth\"],\n \"circle-radius\": [\"get\", \"pointWidth\"],\n \"circle-color\": [\"get\", \"pointColor\"],\n },\n } as CircleLayer);\n if (beneath) {\n this._map.moveLayer(id, beneath);\n }\n return layer;\n }\n\n private _addLayer(\n id: string,\n mode: string,\n featureType: \"Point\" | \"LineString\" | \"Polygon\",\n beneath?: string\n ) {\n if (featureType === \"Point\") {\n this._addPointLayer(id, mode, beneath);\n }\n if (featureType === \"LineString\") {\n this._addLineLayer(id, mode, beneath);\n }\n if (featureType === \"Polygon\") {\n this._addFillLayer(id, mode);\n this._addFillOutlineLayer(id, mode, beneath);\n }\n }\n\n private _addGeoJSONLayer<T extends GeoJSONStoreGeometries>(\n mode: string,\n featureType: Feature<T>[\"geometry\"][\"type\"],\n features: Feature<T>[],\n ) {\n const id = `td-${mode}-${featureType.toLowerCase()}`;\n this._addGeoJSONSource(id, features);\n this._addLayer(id, mode, featureType,);\n\n return id;\n }\n\n private _setGeoJSONLayerData<T extends GeoJSONStoreGeometries>(\n mode: string,\n featureType: Feature<T>[\"geometry\"][\"type\"],\n features: Feature<T>[]\n ) {\n const id = `td-${mode}-${featureType.toLowerCase()}`;\n (this._map.getSource(id) as any).setData({\n type: \"FeatureCollection\",\n features: features,\n });\n return id;\n }\n register(callbacks: TerraDrawCallbacks) {\n this._onClickListener = (event) => {\n callbacks.onClick({\n lng: limitPrecision(event.lngLat.lng, this._coordinatePrecision),\n lat: limitPrecision(event.lngLat.lat, this._coordinatePrecision),\n containerX:\n event.originalEvent.clientX - this.getMapContainer().offsetLeft,\n containerY:\n event.originalEvent.clientY - this.getMapContainer().offsetTop,\n button: event.originalEvent.button === 0 ? \"left\" : \"right\",\n heldKeys: [...this._heldKeys],\n });\n };\n this._map.on(\"click\", this._onClickListener);\n this._map.on(\"contextmenu\", this._onClickListener);\n\n this._onMouseMoveListener = (event) => {\n callbacks.onMouseMove({\n lng: limitPrecision(event.lngLat.lng, this._coordinatePrecision),\n lat: limitPrecision(event.lngLat.lat, this._coordinatePrecision),\n containerX:\n event.originalEvent.clientX - this.getMapContainer().offsetLeft,\n containerY:\n event.originalEvent.clientY - this.getMapContainer().offsetTop,\n button: event.originalEvent.button === 0 ? \"left\" : \"right\",\n heldKeys: [...this._heldKeys],\n });\n };\n this._map.on(\"mousemove\", this._onMouseMoveListener);\n\n let dragState: \"not-dragging\" | \"pre-dragging\" | \"dragging\" =\n \"not-dragging\";\n\n this._onDragStartListener = (event) => {\n dragState = \"pre-dragging\";\n };\n\n const container = this.getMapContainer();\n\n container.addEventListener(\"mousedown\", this._onDragStartListener);\n\n this._onDragListener = (event) => {\n const { lng, lat } = this._map.unproject({\n x: event.clientX - container.offsetLeft,\n y: event.clientY - container.offsetTop,\n } as any);\n\n const drawEvent: TerraDrawMouseEvent = {\n lng: limitPrecision(lng, this._coordinatePrecision),\n lat: limitPrecision(lat, this._coordinatePrecision),\n containerX: event.clientX - container.offsetLeft,\n containerY: event.clientY - container.offsetTop,\n button: event.button === 0 ? \"left\" : \"right\",\n heldKeys: [...this._heldKeys],\n };\n\n if (dragState === \"pre-dragging\") {\n dragState = \"dragging\";\n\n callbacks.onDragStart(drawEvent, (enabled) => {\n if (enabled) {\n this._map.dragPan.enable();\n } else {\n this._map.dragPan.disable();\n }\n });\n } else if (dragState === \"dragging\") {\n callbacks.onDrag(drawEvent);\n }\n };\n\n container.addEventListener(\"mousemove\", this._onDragListener);\n\n this._onDragEndListener = (event) => {\n if (dragState === \"dragging\") {\n const point = {\n x: event.clientX - container.offsetLeft,\n y: event.clientY - container.offsetTop,\n } as mapboxgl.Point;\n\n const { lng, lat } = this._map.unproject(point);\n\n callbacks.onDragEnd(\n {\n lng: limitPrecision(lng, this._coordinatePrecision),\n lat: limitPrecision(lat, this._coordinatePrecision),\n containerX: event.clientX - container.offsetLeft,\n containerY: event.clientY - container.offsetTop,\n button: event.button === 0 ? \"left\" : \"right\",\n heldKeys: [...this._heldKeys],\n },\n (enabled) => {\n if (enabled) {\n this._map.dragPan.enable();\n } else {\n this._map.dragPan.disable();\n }\n }\n );\n }\n\n dragState = \"not-dragging\";\n };\n\n container.addEventListener(\"mouseup\", this._onDragEndListener);\n\n // map has no keypress event, so we add one to the canvas itself\n this._onKeyUpListener = (event: KeyboardEvent) => {\n event.preventDefault();\n\n this._heldKeys.delete(event.key);\n\n callbacks.onKeyUp({\n key: event.key,\n });\n };\n container.addEventListener(\"keyup\", this._onKeyUpListener);\n\n this._onKeyDownListener = (event: KeyboardEvent) => {\n event.preventDefault();\n\n this._heldKeys.add(event.key);\n\n callbacks.onKeyDown({\n key: event.key,\n });\n };\n container.addEventListener(\"keydown\", this._onKeyDownListener);\n }\n\n unregister() {\n if (this._onClickListener) {\n this._map.off(\"contextmenue\", this._onClickListener);\n this._map.off(\"click\", this._onClickListener);\n this._onClickListener = undefined;\n }\n\n if (this._onMouseMoveListener) {\n this._map.off(\"mousemove\", this._onMouseMoveListener);\n this._onMouseMoveListener = undefined;\n }\n\n if (this._onKeyUpListener) {\n this._map\n .getCanvas()\n .removeEventListener(\"keypress\", this._onKeyUpListener);\n }\n\n if (this._onDragStartListener) {\n this._map\n .getCanvas()\n .removeEventListener(\"mousedown\", this._onDragStartListener);\n }\n\n if (this._onDragListener) {\n this._map\n .getCanvas()\n .removeEventListener(\"mousemove\", this._onDragListener);\n }\n\n if (this._onDragEndListener) {\n this._map\n .getCanvas()\n .removeEventListener(\"mouseup\", this._onDragEndListener);\n }\n }\n\n render(\n changes: TerraDrawChanges,\n styling: { [mode: string]: (feature: GeoJSONStoreFeatures) => TerraDrawAdapterStyling }\n ) {\n const features = [\n ...changes.created,\n ...changes.updated,\n ...changes.unchanged,\n ];\n\n const modeFeatures: {\n [key: string]: {\n points: GeoJSONStoreFeatures[];\n linestrings: GeoJSONStoreFeatures[];\n polygons: GeoJSONStoreFeatures[];\n };\n } = {};\n\n Object.keys(styling).forEach((mode) => {\n if (!modeFeatures[mode]) {\n modeFeatures[mode] = {\n points: [],\n linestrings: [],\n polygons: [],\n };\n }\n });\n\n for (let i = 0; i < features.length; i++) {\n const feature = features[i];\n\n Object.keys(styling).forEach((mode) => {\n const { properties } = feature;\n\n if (properties.mode !== mode) {\n return;\n }\n\n const styles = styling[mode](feature);\n\n if (feature.geometry.type === \"Point\") {\n properties.pointColor = styles.pointColor;\n properties.pointOutlineColor = styles.pointOutlineColor;\n properties.pointOutlineWidth = styles.pointOutlineWidth;\n properties.pointWidth = styles.pointWidth;\n modeFeatures[mode].points.push(feature);\n } else if (feature.geometry.type === \"LineString\") {\n properties.lineStringColor = styles.lineStringColor;\n properties.lineStringWidth = styles.lineStringWidth;\n modeFeatures[mode].linestrings.push(feature);\n } else if (feature.geometry.type === \"Polygon\") {\n properties.polygonFillColor = styles.polygonFillColor;\n properties.polygonFillOpacity = styles.polygonFillOpacity;\n properties.polygonOutlineColor = styles.polygonOutlineColor;\n properties.polygonOutlineWidth = styles.polygonOutlineWidth;\n modeFeatures[mode].polygons.push(feature);\n }\n });\n }\n\n Object.keys(styling).forEach((mode) => {\n if (!modeFeatures[mode]) {\n return;\n }\n\n const { points, linestrings, polygons } = modeFeatures[mode];\n\n\n if (!this._rendered[mode]) {\n this._addGeoJSONLayer<Point>(\n mode,\n \"Point\",\n points as Feature<Point>[],\n );\n this._addGeoJSONLayer<LineString>(\n mode,\n \"LineString\",\n linestrings as Feature<LineString>[],\n );\n this._addGeoJSONLayer<Polygon>(\n mode,\n \"Polygon\",\n polygons as Feature<Polygon>[],\n );\n this._rendered[mode] = true;\n } else {\n const pointId = this._setGeoJSONLayerData<Point>(\n mode,\n \"Point\",\n points as Feature<Point>[]\n );\n this._setGeoJSONLayerData<LineString>(\n mode,\n \"LineString\",\n linestrings as Feature<LineString>[]\n );\n this._setGeoJSONLayerData<Polygon>(\n mode,\n \"Polygon\",\n polygons as Feature<Polygon>[]\n );\n\n // TODO: This logic could be better - I think this will render the selection points above user\n // defined layers outside of TerraDraw which is perhaps unideal\n\n // Ensure selection/mid points are rendered on top\n this._map.moveLayer(pointId);\n }\n });\n\n if ((this._map as any).style) {\n // cancel the scheduled update\n if ((this._map as any)._frame) {\n (this._map as any)._frame.cancel();\n (this._map as any)._frame = null;\n }\n (this._map as any)._render();\n }\n }\n}\n","import { Position } from \"geojson\";\n\nexport function haversineDistanceKilometers(\n pointOne: Position,\n pointTwo: Position\n) {\n const toRadians = (latOrLng: number) => (latOrLng * Math.PI) / 180;\n\n const phiOne = toRadians(pointOne[1]);\n const lambdaOne = toRadians(pointOne[0]);\n const phiTwo = toRadians(pointTwo[1]);\n const lambdaTwo = toRadians(pointTwo[0]);\n const deltaPhi = phiTwo - phiOne;\n const deltalambda = lambdaTwo - lambdaOne;\n\n const a =\n Math.sin(deltaPhi / 2) * Math.sin(deltaPhi / 2) +\n Math.cos(phiOne) *\n Math.cos(phiTwo) *\n Math.sin(deltalambda / 2) *\n Math.sin(deltalambda / 2);\n const c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));\n\n const radius = 6371e3;\n const distance = radius * c;\n\n return distance / 1000;\n}\n","export const earthRadius = 6371008.8;\n\nexport function degreesToRadians(degrees: number): number {\n const radians = degrees % 360;\n return (radians * Math.PI) / 180;\n}\n\nexport function lengthToRadians(distance: number): number {\n const factor = earthRadius / 1000;\n return distance / factor;\n}\n\nexport function radiansToDegrees(radians: number): number {\n const degrees = radians % (2 * Math.PI);\n return (degrees * 180) / Math.PI;\n}\n","import { Feature, Polygon, Position } from \"geojson\";\nimport {\n degreesToRadians,\n lengthToRadians,\n radiansToDegrees,\n} from \"../helpers\";\n\n// Based on Turf.js Circle module\n// https://github.com/Turfjs/turf/blob/master/packages/turf-circle/index.ts\n\nexport function destination(\n origin: Position,\n distance: number,\n bearing: number\n): Position {\n const longitude1 = degreesToRadians(origin[0]);\n const latitude1 = degreesToRadians(origin[1]);\n const bearingRad = degreesToRadians(bearing);\n const radians = lengthToRadians(distance);\n\n // Main\n const latitude2 = Math.asin(\n Math.sin(latitude1) * Math.cos(radians) +\n Math.cos(latitude1) * Math.sin(radians) * Math.cos(bearingRad)\n );\n const longitude2 =\n longitude1 +\n Math.atan2(\n Math.sin(bearingRad) * Math.sin(radians) * Math.cos(latitude1),\n Math.cos(radians) - Math.sin(latitude1) * Math.sin(latitude2)\n );\n const lng = radiansToDegrees(longitude2);\n const lat = radiansToDegrees(latitude2);\n\n return [lng, lat];\n}\n\nexport function circle(options: {\n center: Position;\n radiusKilometers: number;\n steps?: number;\n}): Feature<Polygon> {\n const { center, radiusKilometers } = options;\n const steps = options.steps ? options.steps : 64;\n\n const coordinates: Position[] = [];\n for (let i = 0; i < steps; i++) {\n coordinates.push(destination(center, radiusKilometers, (i * -360) / steps));\n }\n coordinates.push(coordinates[0]);\n\n return {\n type: \"Feature\",\n geometry: { type: \"Polygon\", coordinates: [coordinates] },\n properties: {},\n };\n}\n","import { TerraDrawAdapterStyling } from \"../common\";\n\nexport const getDefaultStyling = (): TerraDrawAdapterStyling => {\n return {\n polygonFillColor: \"#3f97e0\",\n polygonOutlineColor: \"#3f97e0\",\n polygonOutlineWidth: 4,\n polygonFillOpacity: 0.3,\n pointColor: \"#3f97e0\",\n pointOutlineColor: \"#ffffff\",\n pointOutlineWidth: 0,\n pointWidth: 6,\n lineStringColor: \"#3f97e0\",\n lineStringWidth: 4,\n zIndex: 0\n };\n};\n","import { BehaviorConfig, TerraDrawModeBehavior } from \"./base.behavior\";\nimport {\n TerraDrawAdapterStyling,\n TerraDrawModeRegisterConfig,\n TerraDrawModeState,\n} from \"../common\";\nimport { GeoJSONStore, GeoJSONStoreFeatures } from \"../store/store\";\n\ntype CustomStyling = Record<string, string | number>\n\nexport abstract class TerraDrawBaseDrawMode<T extends CustomStyling> {\n protected _state: TerraDrawModeState;\n get state() {\n return this._state;\n }\n set state(_) {\n throw new Error(\"Please use the modes lifecycle methods\");\n }\n\n protected _styles: Partial<T>;\n\n get styles(): Partial<T> {\n return this._styles;\n }\n set styles(styling: Partial<T>) {\n if (typeof styling !== \"object\") {\n throw new Error(\"Styling must be an object\");\n }\n\n this.onStyleChange([], \"styling\");\n this._styles = styling;\n }\n\n protected behaviors: TerraDrawModeBehavior[] = [];\n protected pointerDistance: number;\n protected coordinatePrecision: number;\n protected onStyleChange: any;\n protected store!: GeoJSONStore;\n protected unproject!: TerraDrawModeRegisterConfig[\"unproject\"];\n protected project!: TerraDrawModeRegisterConfig[\"project\"];\n protected setCursor!: TerraDrawModeRegisterConfig[\"setCursor\"];\n protected registerBehaviors(behaviorConfig: BehaviorConfig): void { }\n\n constructor(options?: {\n styles?: Partial<T>;\n pointerDistance?: number;\n coordinatePrecision?: number;\n }) {\n this._state = \"unregistered\";\n this._styles =\n options && options.styles\n ? { ...options.styles }\n : {} as Partial<T>;\n\n this.pointerDistance = (options && options.pointerDistance) || 40;\n\n this.coordinatePrecision = (options && options.coordinatePrecision) || 9;\n }\n\n protected setStarted() {\n if (this._state === \"stopped\" || this._state === \"registered\") {\n this._state = \"started\";\n } else {\n throw new Error(\"Mode must be unregistered or stopped to start\");\n }\n }\n\n protected setStopped() {\n if (this._state === \"started\") {\n this._state = \"stopped\";\n } else {\n throw new Error(\"Mode must be started to be stopped\");\n }\n }\n\n register(config: TerraDrawModeRegisterConfig) {\n if (this._state === \"unregistered\") {\n this._state = \"registered\";\n this.store = config.store;\n this.store.registerOnChange(config.onChange);\n this.project = config.project;\n this.unproject = config.unproject;\n this.onSelect = config.onSelect;\n this.onDeselect = config.onDeselect;\n this.setCursor = config.setCursor;\n this.onStyleChange = config.onChange;\n\n this.registerBehaviors({\n mode: config.mode,\n store: this.store,\n project: this.project,\n unproject: this.unproject,\n pointerDistance: this.pointerDistance,\n coordinatePrecision: this.coordinatePrecision,\n });\n } else {\n throw new Error(\"Can not register unless mode is unregistered\");\n }\n }\n\n onDeselect(deselectedId: string) { }\n onSelect(selectedId: string) { }\n styleFeature(feature: GeoJSONStoreFeatures) { }\n}\n","import { Position } from \"geojson\";\nimport {\n TerraDrawMouseEvent,\n TerraDrawAdapterStyling,\n TerraDrawKeyboardEvent,\n HexColor,\n} from \"../../common\";\nimport { haversineDistanceKilometers } from \"../../geometry/measure/haversine-distance\";\nimport { circle } from \"../../geometry/shape/create-circle\";\nimport { GeoJSONStoreFeatures } from \"../../store/store\";\nimport { getDefaultStyling } from \"../../util/styling\";\nimport { TerraDrawBaseDrawMode } from \"../base.mode\";\n\ntype TerraDrawCircleModeKeyEvents = {\n cancel: KeyboardEvent[\"key\"];\n};\n\ntype FreehandPolygonStyling = {\n fillColor: HexColor,\n outlineColor: HexColor,\n outlineWidth: number,\n fillOpacity: number,\n}\n\nexport class TerraDrawCircleMode extends TerraDrawBaseDrawMode<FreehandPolygonStyling> {\n\n mode = \"circle\";\n private center: Position | undefined;\n private clickCount = 0;\n private currentCircleId: string | undefined;\n private keyEvents: TerraDrawCircleModeKeyEvents;\n\n constructor(options?: {\n styles?: Partial<FreehandPolygonStyling>;\n keyEvents?: TerraDrawCircleModeKeyEvents;\n }) {\n super(options);\n\n this.keyEvents =\n options && options.keyEvents ? options.keyEvents : { cancel: \"Escape\" };\n }\n\n start() {\n this.setStarted();\n this.setCursor(\"crosshair\");\n }\n\n stop() {\n this.setStopped();\n this.setCursor(\"unset\");\n this.cleanUp();\n }\n\n onClick(event: TerraDrawMouseEvent) {\n if (this.clickCount === 0) {\n this.center = [event.lng, event.lat];\n const startingCircle = circle({\n center: this.center,\n radiusKilometers: 0.00001,\n });\n\n const [createdId] = this.store.create([\n {\n geometry: startingCircle.geometry,\n properties: {\n mode: this.mode,\n },\n },\n ]);\n this.currentCircleId = createdId;\n this.clickCount++;\n } else {\n // Finish drawing\n this.center = undefined;\n this.currentCircleId = undefined;\n this.clickCount = 0;\n }\n }\n onMouseMove(event: TerraDrawMouseEvent) {\n if (this.clickCount === 1 && this.center && this.currentCircleId) {\n const distanceKm = haversineDistanceKilometers(this.center, [\n event.lng,\n event.lat,\n ]);\n\n const updatedCircle = circle({\n center: this.center,\n radiusKilometers: distanceKm,\n });\n\n this.store.updateGeometry([\n { id: this.currentCircleId, geometry: updatedCircle.geometry },\n ]);\n }\n }\n onKeyDown() { }\n onKeyUp(event: TerraDrawKeyboardEvent) {\n if (event.key === this.keyEvents.cancel) {\n this.cleanUp();\n }\n }\n onDragStart() { }\n onDrag() { }\n onDragEnd() { }\n cleanUp() {\n try {\n if (this.currentCircleId) {\n this.store.delete([this.currentCircleId]);\n }\n } catch (error) { }\n this.center = undefined;\n this.currentCircleId = undefined;\n this.clickCount = 0;\n }\n\n styleFeature(\n feature: GeoJSONStoreFeatures\n ): TerraDrawAdapterStyling {\n const styles = { ...getDefaultStyling() };\n\n if (\n feature.type === 'Feature' &&\n feature.geometry.type === 'Polygon' &&\n feature.properties.mode === this.mode\n ) {\n\n if (this.styles.fillColor) {\n styles.polygonFillColor = this.styles.fillColor;\n }\n if (this.styles.outlineColor) {\n styles.polygonOutlineColor = this.styles.outlineColor;\n }\n if (this.styles.outlineWidth) {\n styles.polygonOutlineWidth = this.styles.outlineWidth;\n }\n if (this.styles.fillOpacity) {\n styles.polygonFillOpacity = this.styles.fillOpacity;\n }\n\n return styles;\n }\n\n return styles;\n\n }\n}","import {\n TerraDrawMouseEvent,\n TerraDrawAdapterStyling,\n TerraDrawKeyboardEvent,\n HexColor,\n} from \"../../common\";\nimport { Polygon } from \"geojson\";\n\nimport { TerraDrawBaseDrawMode } from \"../base.mode\";\nimport { getDefaultStyling } from \"../../util/styling\";\nimport { GeoJSONStoreFeatures } from \"../../store/store\";\n\ntype TerraDrawFreehandModeKeyEvents = {\n cancel: KeyboardEvent[\"key\"];\n};\n\ntype FreehandPolygonStyling = {\n fillColor: HexColor,\n outlineColor: HexColor,\n outlineWidth: number,\n fillOpacity: number,\n}\n\nexport class TerraDrawFreehandMode extends TerraDrawBaseDrawMode<FreehandPolygonStyling> {\n mode = \"freehand\";\n\n private startingClick = false;\n private currentId: string | undefined;\n private skip = 0;\n private everyNthMouseEvent: number;\n private keyEvents: TerraDrawFreehandModeKeyEvents;\n\n constructor(options?: {\n styles?: Partial<FreehandPolygonStyling>;\n everyNthMouseEvent?: number;\n keyEvents?: TerraDrawFreehandModeKeyEvents;\n }) {\n super(options);\n\n this.everyNthMouseEvent = (options && options.everyNthMouseEvent) || 10;\n this.keyEvents =\n options && options.keyEvents ? options.keyEvents : { cancel: \"Escape\" };\n }\n\n start() {\n this.setStarted();\n this.setCursor(\"crosshair\");\n }\n stop() {\n this.setStopped();\n this.setCursor(\"unset\");\n this.cleanUp();\n }\n\n onMouseMove(event: TerraDrawMouseEvent) {\n if (!this.currentId || this.startingClick === false) {\n return;\n }\n\n if (this.skip > this.everyNthMouseEvent) {\n this.skip = 0;\n const currentLineGeometry = this.store.getGeometryCopy<Polygon>(\n this.currentId\n );\n\n currentLineGeometry.coordinates[0].pop();\n\n this.store.updateGeometry([\n {\n id: this.currentId,\n geometry: {\n type: \"Polygon\",\n coordinates: [\n [\n ...currentLineGeometry.coordinates[0],\n [event.lng, event.lat],\n currentLineGeometry.coordinates[0][0],\n ],\n ],\n },\n },\n ]);\n }\n\n this.skip++;\n }\n\n onClick(event: TerraDrawMouseEvent) {\n if (this.startingClick === false) {\n const [createdId] = this.store.create([\n {\n geometry: {\n type: \"Polygon\",\n coordinates: [\n [\n [event.lng, event.lat],\n [event.lng, event.lat],\n [event.lng, event.lat],\n [event.lng, event.lat],\n ],\n ],\n },\n properties: { mode: this.mode },\n },\n ]);\n\n this.currentId = createdId;\n this.startingClick = true;\n return;\n }\n\n this.startingClick = false;\n this.currentId = undefined;\n }\n onKeyDown() { }\n onKeyUp(event: TerraDrawKeyboardEvent) {\n if (event.key === this.keyEvents.cancel) {\n this.cleanUp();\n }\n }\n onDragStart() { }\n onDrag() { }\n onDragEnd() { }\n\n cleanUp() {\n try {\n if (this.currentId) {\n this.store.delete([this.currentId]);\n }\n } catch (error) { }\n this.currentId = undefined;\n this.startingClick = false;\n }\n\n styleFeature(\n feature: GeoJSONStoreFeatures\n ): TerraDrawAdapterStyling {\n const styles = { ...getDefaultStyling() };\n\n if (\n feature.type === 'Feature' &&\n feature.geometry.type === 'Polygon' &&\n feature.properties.mode === this.mode\n ) {\n\n if (this.styles.fillColor) {\n styles.polygonFillColor = this.styles.fillColor;\n }\n if (this.styles.outlineColor) {\n styles.polygonOutlineColor = this.styles.outlineColor;\n }\n if (this.styles.outlineWidth) {\n styles.polygonOutlineWidth = this.styles.outlineWidth;\n }\n if (this.styles.fillOpacity) {\n styles.polygonFillOpacity = this.styles.fillOpacity;\n }\n\n return styles;\n }\n\n return styles;\n\n }\n\n}\n","// Based on - https://github.com/mclaeysb/geojson-polygon-self-intersections\n// MIT License\n// Copyright (c) 2016 Manuel Claeys Bouuaert\n\nimport { Feature, LineString, Polygon, Position } from \"geojson\";\n// import * as rbush from \"rbush\";\n\ntype SelfIntersectsOptions = {\n epsilon: number;\n // reportVertexOnVertex: boolean;\n // reportVertexOnEdge: boolean;\n};\n\nexport function selfIntersects(\n feature: Feature<Polygon> | Feature<LineString>\n): boolean {\n const options: SelfIntersectsOptions = {\n epsilon: 0,\n // reportVertexOnVertex: false,\n // reportVertexOnEdge: false,\n };\n\n let coord: number[][][];\n\n if (feature.geometry.type === \"Polygon\") {\n coord = feature.geometry.coordinates;\n } else if (feature.geometry.type === \"LineString\") {\n coord = [feature.geometry.coordinates];\n } else {\n throw new Error(\"Self intersects only accepts Polygons and LineStrings\");\n }\n\n const output: number[][] = [];\n const seen: { [key: string]: boolean } = {};\n\n for (let ring0 = 0; ring0 < coord.length; ring0++) {\n for (let edge0 = 0; edge0 < coord[ring0].length - 1; edge0++) {\n for (let ring1 = 0; ring1 < coord.length; ring1++) {\n for (let edge1 = 0; edge1 < coord[ring1].length - 1; edge1++) {\n // speedup possible if only interested in unique: start last two loops at ring0 and edge0+1\n ifInteresctionAddToOutput(ring0, edge0, ring1, edge1);\n }\n }\n }\n }\n\n return output.length > 0;\n\n // true if frac is (almost) 1.0 or 0.0\n // function isBoundaryCase(frac: number) {\n // const e2 = options.epsilon * options.epsilon;\n // return e2 >= (frac - 1) * (frac - 1) || e2 >= frac * frac;\n // }\n\n function isOutside(frac: number) {\n return frac < 0 - options.epsilon || frac > 1 + options.epsilon;\n }\n // Function to check if two edges intersect and add the intersection to the output\n function ifInteresctionAddToOutput(\n ring0: number,\n edge0: number,\n ring1: number,\n edge1: number\n ) {\n const start0 = coord[ring0][edge0];\n const end0 = coord[ring0][edge0 + 1];\n const start1 = coord[ring1][edge1];\n const end1 = coord[ring1][edge1 + 1];\n\n const intersection = intersect(start0, end0, start1, end1);\n\n if (intersection === null) {\n return; // discard parallels and coincidence\n }\n\n let frac0;\n let frac1;\n\n if (end0[0] !== start0[0]) {\n frac0 = (intersection[0] - start0[0]) / (end0[0] - start0[0]);\n } else {\n frac0 = (intersection[1] - start0[1]) / (end0[1] - start0[1]);\n }\n if (end1[0] !== start1[0]) {\n frac1 = (intersection[0] - start1[0]) / (end1[0] - start1[0]);\n } else {\n frac1 = (intersection[1] - start1[1]) / (end1[1] - start1[1]);\n }\n\n // There are roughly three cases we need to deal with.\n // 1. If at least one of the fracs lies outside [0,1], there is no intersection.\n if (isOutside(frac0) || isOutside(frac1)) {\n return; // require segment intersection\n }\n\n // 2. If both are either exactly 0 or exactly 1, this is not an intersection but just\n // two edge segments sharing a common vertex.\n // if (isBoundaryCase(frac0) && isBoundaryCase(frac1)) {\n // if (!options.reportVertexOnVertex) {\n // return;\n // }\n // }\n\n // // 3. If only one of the fractions is exactly 0 or 1, this is\n // // a vertex-on-edge situation.\n // if (isBoundaryCase(frac0) || isBoundaryCase(frac1)) {\n // if (!options.reportVertexOnEdge) {\n // return;\n // }\n // }\n\n const key = intersection.toString();\n const unique = !seen[key];\n if (unique) {\n seen[key] = true;\n }\n\n output.push(intersection);\n }\n}\n\nfunction equalArrays(array1: Position, array2: Position) {\n return array1[0] === array2[0] && array1[1] === array2[1];\n}\n\n// Function to compute where two lines (not segments) intersect. From https://en.wikipedia.org/wiki/Line%E2%80%93line_intersection\nfunction intersect(\n start0: Position,\n end0: Position,\n start1: Position,\n end1: Position\n) {\n if (\n equalArrays(start0, start1) ||\n equalArrays(start0, end1) ||\n equalArrays(end0, start1) ||\n equalArrays(end1, start1)\n ) {\n return null;\n }\n\n const x0 = start0[0],\n y0 = start0[1],\n x1 = end0[0],\n y1 = end0[1],\n x2 = start1[0],\n y2 = start1[1],\n x3 = end1[0],\n y3 = end1[1];\n\n const denom = (x0 - x1) * (y2 - y3) - (y0 - y1) * (x2 - x3);\n if (denom === 0) {\n return null;\n }\n\n const x4 =\n ((x0 * y1 - y0 * x1) * (x2 - x3) - (x0 - x1) * (x2 * y3 - y2 * x3)) / denom;\n\n const y4 =\n ((x0 * y1 - y0 * x1) * (y2 - y3) - (y0 - y1) * (x2 * y3 - y2 * x3)) / denom;\n\n return [x4, y4];\n}\n","export const pixelDistance = (\n pointOne: { x: number; y: number },\n pointTwo: { x: number; y: number }\n) => {\n const { x: x1, y: y1 } = pointOne;\n const { x: x2, y: y2 } = pointTwo;\n const y = x2 - x1;\n const x = y2 - y1;\n return Math.sqrt(x * x + y * y);\n};\n","import { Project, Unproject } from \"../common\";\nimport { GeoJSONStore } from \"../store/store\";\n\nexport type BehaviorConfig = {\n store: GeoJSONStore;\n mode: string;\n project: Project;\n unproject: Unproject;\n pointerDistance: number;\n coordinatePrecision: number;\n};\n\nexport class TerraDrawModeBehavior {\n protected store: GeoJSONStore;\n protected mode: string;\n protected project: Project;\n protected unproject: Unproject;\n protected pointerDistance: number;\n protected coordinatePrecision: number;\n\n constructor({\n store,\n mode,\n project,\n unproject,\n pointerDistance,\n coordinatePrecision,\n }: BehaviorConfig) {\n this.store = store;\n this.mode = mode;\n this.project = project;\n this.unproject = unproject;\n this.pointerDistance = pointerDistance;\n this.coordinatePrecision = coordinatePrecision;\n }\n}\n","import { Feature, Polygon } from \"geojson\";\nimport { BehaviorConfig, TerraDrawModeBehavior } from \"./base.behavior\";\n\nimport { TerraDrawMouseEvent } from \"../common\";\n\nexport class ClickBoundingBoxBehavior extends TerraDrawModeBehavior {\n constructor(config: BehaviorConfig) {\n super(config);\n }\n\n public create(event: TerraDrawMouseEvent) {\n const { containerX: x, containerY: y } = event;\n const halfDist = this.pointerDistance / 2;\n\n const bbox = {\n type: \"Feature\",\n properties: {},\n geometry: {\n type: \"Polygon\",\n coordinates: [\n [\n this.unproject(x - halfDist, y - halfDist), // TopLeft\n this.unproject(x + halfDist, y - halfDist), // TopRight\n this.unproject(x + halfDist, y + halfDist), // BottomRight\n this.unproject(x - halfDist, y + halfDist), // BottomLeft\n this.unproject(x - halfDist, y - halfDist), // TopLeft\n ].map((c) => [c.lng, c.lat]),\n ],\n },\n } as Feature<Polygon>;\n\n return bbox;\n }\n}\n","import { BehaviorConfig, TerraDrawModeBehavior } from \"./base.behavior\";\nimport { TerraDrawMouseEvent } from \"../common\";\n\nimport { Position } from \"geojson\";\nimport { pixelDistance } from \"../geometry/measure/pixel-distance\";\n\nexport class PixelDistanceBehavior extends TerraDrawModeBehavior {\n constructor(config: BehaviorConfig) {\n super(config);\n }\n public measure(clickEvent: TerraDrawMouseEvent, secondCoordinate: Position) {\n const { x, y } = this.project(secondCoordinate[0], secondCoordinate[1]);\n\n const distance = pixelDistance(\n { x, y },\n { x: clickEvent.containerX, y: clickEvent.containerY }\n );\n\n return distance;\n }\n}\n","import { BehaviorConfig, TerraDrawModeBehavior } from \"./base.behavior\";\nimport { TerraDrawMouseEvent } from \"../common\";\nimport { Feature, Polygon, Position } from \"geojson\";\nimport { ClickBoundingBoxBehavior } from \"./click-bounding-box.behavior\";\nimport { BBoxPolygon } from \"../store/store\";\nimport { PixelDistanceBehavior } from \"./pixel-distance.behavior\";\n\nexport class SnappingBehavior extends TerraDrawModeBehavior {\n constructor(\n readonly config: BehaviorConfig,\n private readonly pixelDistance: PixelDistanceBehavior,\n private readonly clickBoundingBox: ClickBoundingBoxBehavior\n ) {\n super(config);\n }\n\n public getSnappableCoordinate = (\n event: TerraDrawMouseEvent,\n currentFeatureId: string\n ) => {\n return this.getSnappable(event, (feature) => {\n return Boolean(\n feature.properties &&\n feature.properties.mode === this.mode &&\n feature.id !== currentFeatureId\n );\n });\n };\n\n private getSnappable(\n event: TerraDrawMouseEvent,\n filter: (feature: Feature) => boolean\n ) {\n const bbox = this.clickBoundingBox.create(event) as BBoxPolygon;\n\n const features = this.store.search(bbox, filter);\n\n const closest: { coord: undefined | Position; minDist: number } = {\n coord: undefined,\n minDist: Infinity,\n };\n\n features.forEach((feature) => {\n let coordinates: Position[];\n if (feature.geometry.type === \"Polygon\") {\n coordinates = feature.geometry.coordinates[0];\n } else if (feature.geometry.type === \"LineString\") {\n coordinates = feature.geometry.coordinates;\n } else {\n return;\n }\n\n coordinates.forEach((coord) => {\n const dist = this.pixelDistance.measure(event, coord);\n if (dist < closest.minDist && dist < this.pointerDistance) {\n closest.coord = coord;\n }\n });\n });\n\n return closest.coord;\n }\n}\n","import {\n TerraDrawMouseEvent,\n TerraDrawAdapterStyling,\n TerraDrawKeyboardEvent,\n HexColor,\n} from \"../../common\";\nimport { Feature, LineString } from \"geojson\";\nimport { selfIntersects } from \"../../geometry/boolean/self-intersects\";\nimport { TerraDrawBaseDrawMode } from \"../base.mode\";\nimport { pixelDistance } from \"../../geometry/measure/pixel-distance\";\nimport { BehaviorConfig } from \"../base.behavior\";\nimport { ClickBoundingBoxBehavior } from \"../click-bounding-box.behavior\";\nimport { PixelDistanceBehavior } from \"../pixel-distance.behavior\";\nimport { SnappingBehavior } from \"../snapping.behavior\";\nimport { getDefaultStyling } from \"../../util/styling\";\nimport { GeoJSONStoreFeatures } from \"../../store/store\";\n\ntype TerraDrawLineStringModeKeyEvents = {\n cancel: KeyboardEvent[\"key\"];\n};\n\ntype LineStringStyling = {\n lineStringWidth: number,\n lineStringColor: HexColor,\n}\n\n\nexport class TerraDrawLineStringMode extends TerraDrawBaseDrawMode<LineStringStyling> {\n mode = \"linestring\";\n\n private currentCoordinate = 0;\n private currentId: string | undefined;\n private allowSelfIntersections;\n private keyEvents: TerraDrawLineStringModeKeyEvents;\n private snappingEnabled: boolean;\n\n // Behaviors\n private snapping!: SnappingBehavior;\n\n constructor(options?: {\n snapping?: boolean;\n allowSelfIntersections?: boolean;\n pointerDistance?: number;\n styles?: Partial<LineStringStyling>;\n keyEvents?: TerraDrawLineStringModeKeyEvents;\n }) {\n super(options);\n\n this.snappingEnabled =\n options && options.snapping !== undefined ? options.snapping : false;\n\n this.allowSelfIntersections =\n options && options.allowSelfIntersections !== undefined\n ? options.allowSelfIntersections\n : true;\n\n this.keyEvents =\n options && options.keyEvents ? options.keyEvents : { cancel: \"Escape\" };\n }\n\n public registerBehaviors(config: BehaviorConfig) {\n this.snapping = new SnappingBehavior(\n config,\n new PixelDistanceBehavior(config),\n new ClickBoundingBoxBehavior(config)\n );\n }\n\n start() {\n this.setStarted();\n this.setCursor(\"crosshair\");\n }\n stop() {\n this.setStopped();\n this.setCursor(\"unset\");\n this.cleanUp();\n }\n\n onMouseMove(event: TerraDrawMouseEvent) {\n if (!this.currentId || this.currentCoordinate === 0) {\n return;\n }\n const currentLineGeometry = this.store.getGeometryCopy<LineString>(\n this.currentId\n );\n\n // Remove the 'live' point that changes on mouse move\n currentLineGeometry.coordinates.pop();\n\n const snappedCoord =\n this.snappingEnabled &&\n this.snapping.getSnappableCoordinate(event, this.currentId);\n const updatedCoord = snappedCoord ? snappedCoord : [event.lng, event.lat];\n\n // Update the 'live' point\n this.store.updateGeometry([\n {\n id: this.currentId,\n geometry: {\n type: \"LineString\",\n coordinates: [...currentLineGeometry.coordinates, updatedCoord],\n },\n },\n ]);\n }\n\n onClick(event: TerraDrawMouseEvent) {\n const snappedCoord =\n this.currentId &&\n this.snappingEnabled &&\n this.snapping.getSnappableCoordinate(event, this.currentId);\n const updatedCoord = snappedCoord ? snappedCoord : [event.lng, event.lat];\n\n if (this.currentCoordinate === 0) {\n const [createdId] = this.store.create([\n {\n geometry: {\n type: \"LineString\",\n coordinates: [\n updatedCoord,\n updatedCoord, // This is the 'live' point that changes on mouse move\n ],\n },\n properties: { mode: this.mode },\n },\n ]);\n this.currentId = createdId;\n this.currentCoordinate++;\n } else if (this.currentCoordinate === 1 && this.currentId) {\n const currentLineGeometry = this.store.getGeometryCopy<LineString>(\n this.currentId\n );\n\n this.store.updateGeometry([\n {\n id: this.currentId,\n geometry: {\n type: \"LineString\",\n coordinates: [\n currentLineGeometry.coordinates[0],\n updatedCoord,\n updatedCoord,\n ],\n },\n },\n ]);\n\n this.currentCoordinate++;\n } else if (this.currentId) {\n const currentLineGeometry = this.store.getGeometryCopy<LineString>(\n this.currentId\n );\n\n const [previousLng, previousLat] =\n currentLineGeometry.coordinates[\n currentLineGeometry.coordinates.length - 2\n ];\n const { x, y } = this.project(previousLng, previousLat);\n const distance = pixelDistance(\n { x, y },\n { x: event.containerX, y: event.containerY }\n );\n\n const isClosingClick = distance < this.pointerDistance;\n\n if (isClosingClick) {\n // Finish off the drawing\n currentLineGeometry.coordinates.pop();\n this.store.updateGeometry([\n {\n id: this.currentId,\n geometry: {\n type: \"LineString\",\n coordinates: [...currentLineGeometry.coordinates],\n },\n },\n ]);\n\n this.currentCoordinate = 0;\n this.currentId = undefined;\n } else {\n // If not close to the final point, keep adding points\n const newLineString = {\n type: \"LineString\",\n coordinates: [...currentLineGeometry.coordinates, updatedCoord],\n } as LineString;\n\n if (!this.allowSelfIntersections) {\n const hasSelfIntersections = selfIntersects({\n type: \"Feature\",\n geometry: newLineString,\n properties: {},\n });\n\n if (hasSelfIntersections) {\n return;\n }\n }\n\n this.store.updateGeometry([\n { id: this.currentId, geometry: newLineString },\n ]);\n this.currentCoordinate++;\n }\n }\n }\n onKeyDown() { }\n onKeyUp(event: TerraDrawKeyboardEvent) {\n if (event.key === this.keyEvents.cancel) {\n this.cleanUp();\n }\n }\n onDragStart() { }\n onDrag() { }\n onDragEnd() { }\n cleanUp() {\n try {\n if (this.currentId) {\n this.store.delete([this.currentId]);\n }\n } catch (error) { }\n\n this.currentId = undefined;\n this.currentCoordinate = 0;\n }\n\n styleFeature(\n feature: GeoJSONStoreFeatures\n ): TerraDrawAdapterStyling {\n const styles = { ...getDefaultStyling() };\n\n if (\n feature.type === 'Feature' &&\n feature.geometry.type === 'LineString' &&\n feature.properties.mode === this.mode\n ) {\n\n if (this.styles.lineStringColor) {\n styles.lineStringColor = this.styles.lineStringColor;\n }\n if (this.styles.lineStringWidth) {\n styles.lineStringWidth = this.styles.lineStringWidth;\n }\n\n return styles;\n }\n\n return styles;\n }\n}\n","import { Feature, Point } from \"geojson\";\nimport { TerraDrawMouseEvent, TerraDrawAdapterStyling, HexColor } from \"../../common\";\nimport { GeoJSONStoreFeatures } from \"../../store/store\";\nimport { getDefaultStyling } from \"../../util/styling\";\nimport { TerraDrawBaseDrawMode } from \"../base.mode\";\n\ntype PointModeStyling = {\n pointWidth: number,\n pointColor: HexColor,\n pointOutlineColor: HexColor\n}\nexport class TerraDrawPointMode extends TerraDrawBaseDrawMode<PointModeStyling> {\n mode = \"point\";\n\n constructor(options?: { styles?: Partial<PointModeStyling> }) {\n super(options);\n }\n\n start() {\n this.setStarted();\n this.setCursor(\"crosshair\");\n }\n stop() {\n this.setStopped();\n this.setCursor(\"unset\");\n this.cleanUp();\n }\n\n onClick(event: TerraDrawMouseEvent) {\n if (!this.store) {\n throw new Error(\"Mode must be registered first\");\n }\n\n this.store.create([\n {\n geometry: {\n type: \"Point\",\n coordinates: [event.lng, event.lat],\n },\n properties: { mode: this.mode },\n },\n ]);\n }\n onMouseMove() { }\n onKeyDown() { }\n onKeyUp() { }\n cleanUp() { }\n onDragStart() { }\n onDrag() { }\n onDragEnd() { }\n\n styleFeature(\n feature: GeoJSONStoreFeatures\n ): TerraDrawAdapterStyling {\n const styles = { ...getDefaultStyling() };\n\n if (feature.type === 'Feature' && feature.geometry.type === 'Point' && feature.properties.mode === this.mode) {\n\n if (this.styles.pointColor) {\n styles.pointColor = this.styles.pointColor;\n }\n if (this.styles.pointOutlineColor) {\n styles.pointOutlineColor = this.styles.pointOutlineColor;\n }\n if (this.styles.pointWidth) {\n styles.pointWidth = this.styles.pointWidth;\n }\n\n return styles;\n }\n\n return styles;\n }\n}\n","import { Position } from \"geojson\";\n\nexport function coordinatesIdentical(coordinate: Position, coordinateTwo: Position) {\n return coordinate[0] === coordinateTwo[0] && coordinate[1] === coordinateTwo[1];\n}","import {\n StoreChangeHandler,\n GeoJSONStore,\n GeoJSONStoreFeatures,\n} from \"./store/store\";\n\nexport type HexColor = `#${string}`\n\nexport interface TerraDrawAdapterStyling {\n pointColor: HexColor;\n pointWidth: number;\n pointOutlineColor: HexColor;\n pointOutlineWidth: number,\n polygonFillColor: HexColor;\n polygonFillOpacity: number;\n polygonOutlineColor: HexColor;\n polygonOutlineWidth: number;\n lineStringWidth: number;\n lineStringColor: HexColor;\n zIndex: number\n}\n\nexport interface TerraDrawMouseEvent {\n lng: number;\n lat: number;\n containerX: number;\n containerY: number;\n button: \"left\" | \"right\" | \"pointer\";\n heldKeys: string[];\n}\n\nexport interface TerraDrawKeyboardEvent {\n key: string;\n}\n\ntype SetCursor = (cursor: \"unset\" | \"grab\" | \"grabbing\" | \"crosshair\" | \"pointer\") => void;\n\nexport type Project = (lng: number, lat: number) => { x: number; y: number };\nexport type Unproject = (x: number, y: number) => { lat: number; lng: number };\n\nexport interface TerraDrawModeRegisterConfig {\n mode: string;\n store: GeoJSONStore;\n setCursor: SetCursor;\n onChange: StoreChangeHandler;\n onSelect: (selectedId: string) => void;\n onDeselect: (deselectedId: string) => void;\n project: Project;\n unproject: Unproject;\n}\n\nexport type TerraDrawModeState =\n | \"unregistered\"\n | \"registered\"\n | \"started\"\n | \"stopped\";\n\nexport interface TerraDrawMode {\n mode: string;\n styleFeature: (feature: GeoJSONStoreFeatures) => TerraDrawAdapterStyling;\n styles: any;\n state: TerraDrawModeState;\n start: () => void;\n stop: () => void;\n register: (config: TerraDrawModeRegisterConfig) => void;\n\n // cleanUp: () => void;\n onKeyDown: (event: TerraDrawKeyboardEvent) => void;\n onKeyUp: (event: TerraDrawKeyboardEvent) => void;\n onMouseMove: (event: TerraDrawMouseEvent) => void;\n onClick: (event: TerraDrawMouseEvent) => void;\n onDragStart: (\n event: TerraDrawMouseEvent,\n setMapDraggability: (enabled: boolean) => void\n ) => void;\n onDrag: (event: TerraDrawMouseEvent) => void;\n onDragEnd: (\n event: TerraDrawMouseEvent,\n setMapDraggability: (enabled: boolean) => void\n ) => void;\n}\n\nexport interface TerraDrawCallbacks {\n onKeyUp: (event: TerraDrawKeyboardEvent) => void;\n onKeyDown: (event: TerraDrawKeyboardEvent) => void;\n onClick: (event: TerraDrawMouseEvent) => void;\n onMouseMove: (event: TerraDrawMouseEvent) => void;\n onDragStart: (\n event: TerraDrawMouseEvent,\n setMapDraggability: (enabled: boolean) => void\n ) => void;\n onDrag: (event: TerraDrawMouseEvent) => void;\n onDragEnd: (\n event: TerraDrawMouseEvent,\n setMapDraggability: (enabled: boolean) => void\n ) => void;\n}\n\nexport interface TerraDrawChanges {\n created: GeoJSONStoreFeatures[];\n updated: GeoJSONStoreFeatures[];\n unchanged: GeoJSONStoreFeatures[];\n deletedIds: string[];\n}\n\ntype TerraDrawStylingFunction = { [mode: string]: (feature: GeoJSONStoreFeatures) => TerraDrawAdapterStyling }\n\nexport interface TerraDrawAdapter {\n project: Project;\n unproject: Unproject;\n setCursor: SetCursor;\n getMapContainer: () => HTMLElement;\n register(callbacks: TerraDrawCallbacks): void;\n unregister(): void;\n render(\n changes: TerraDrawChanges,\n styling: TerraDrawStylingFunction\n ): void;\n}\n\nexport const SELECT_PROPERTIES = {\n SELECTED: \"selected\",\n MID_POINT: \"midPoint\",\n SELECTION_POINT: \"selectionPoint\",\n} as const;\n\nexport const POLYGON_PROPERTIES = {\n CLOSING_POINT: 'closingPoint'\n};\n","import { Point, Position } from \"geojson\";\nimport { BehaviorConfig, TerraDrawModeBehavior } from \"../../base.behavior\";\nimport { POLYGON_PROPERTIES, TerraDrawMouseEvent } from \"../../../common\";\nimport { PixelDistanceBehavior } from \"../../pixel-distance.behavior\";\n\nexport class ClosingPointsBehavior extends TerraDrawModeBehavior {\n\n constructor(\n readonly config: BehaviorConfig,\n private readonly pixelDistance: PixelDistanceBehavior\n ) {\n super(config);\n }\n\n private _startEndPoints: string[] = [];\n\n get ids() {\n return this._startEndPoints.concat();\n }\n\n set ids(_: string[]) { }\n\n public create(\n selectedCoords: Position[],\n mode: string\n ) {\n if (this.ids.length) {\n throw new Error(\"Opening and closing points already creating\");\n }\n\n if (selectedCoords.length <= 3) {\n throw new Error(\"Requires at least 4 cooridnates\");\n }\n\n this._startEndPoints = this.store.create(\n // Opening coordinate\n [\n {\n geometry: {\n type: \"Point\",\n coordinates: selectedCoords[0]\n } as Point,\n properties: {\n mode,\n [POLYGON_PROPERTIES.CLOSING_POINT]: true\n }\n },\n // Final coordinate\n {\n geometry: {\n type: \"Point\",\n coordinates: selectedCoords[selectedCoords.length - 2]\n } as Point,\n properties: {\n mode,\n [POLYGON_PROPERTIES.CLOSING_POINT]: true\n }\n }\n ]\n );\n }\n\n public delete() {\n if (this.ids.length) {\n this.store.delete(this.ids);\n this._startEndPoints = [];\n }\n }\n\n public update(updatedCoordinates: Position[]) {\n\n if (this.ids.length !== 2) {\n throw new Error(\"No closing points to update\");\n }\n\n this.store.updateGeometry(\n // Opening coordinate\n [\n {\n id: this.ids[0],\n geometry: {\n type: \"Point\",\n coordinates: updatedCoordinates[0]\n } as Point,\n },\n // Final coordinate\n {\n id: this.ids[1],\n geometry: {\n type: \"Point\",\n coordinates: updatedCoordinates[updatedCoordinates.length - 3]\n } as Point,\n\n }\n ]\n );\n }\n\n public isClosingPoint(event: TerraDrawMouseEvent) {\n\n const opening = this.store.getGeometryCopy(this.ids[0]);\n const closing = this.store.getGeometryCopy(this.ids[1]);\n\n const distance = this.pixelDistance.measure(\n event,\n opening.coordinates as Position\n );\n\n const distancePrevious = this.pixelDistance.measure(\n event,\n closing.coordinates as Position\n );\n\n const isClosing = distance < this.pointerDistance;\n const isPreviousClosing = distancePrevious < this.pointerDistance;\n\n return { isClosing, isPreviousClosing };\n }\n\n}\n","import {\n TerraDrawMouseEvent,\n TerraDrawAdapterStyling,\n TerraDrawKeyboardEvent,\n HexColor,\n} from \"../../common\";\nimport { Feature, Point, Polygon } from \"geojson\";\nimport { selfIntersects } from \"../../geometry/boolean/self-intersects\";\nimport { TerraDrawBaseDrawMode } from \"../base.mode\";\nimport { PixelDistanceBehavior } from \"../pixel-distance.behavior\";\nimport { ClickBoundingBoxBehavior } from \"../click-bounding-box.behavior\";\nimport { BehaviorConfig } from \"../base.behavior\";\nimport { createPolygon } from \"../../util/geoms\";\nimport { SnappingBehavior } from \"../snapping.behavior\";\nimport { coordinatesIdentical } from \"../../geometry/coordinates-identical\";\nimport { ClosingPointsBehavior } from \"./behaviors/closing-points.behavior\";\nimport { getDefaultStyling } from \"../../util/styling\";\nimport { GeoJSONStoreFeatures } from \"../../store/store\";\n\ntype TerraDrawPolygonModeKeyEvents = {\n cancel: KeyboardEvent[\"key\"];\n};\n\ntype PolygonStyling = {\n fillColor: HexColor,\n outlineColor: HexColor,\n outlineWidth: number,\n fillOpacity: number,\n closingPointWidth: number,\n closingPointColor: HexColor,\n closingPointOutlineWidth: number,\n closingPointOutlineColor: HexColor\n}\n\nexport class TerraDrawPolygonMode extends TerraDrawBaseDrawMode<PolygonStyling> {\n mode = \"polygon\";\n\n private currentCoordinate = 0;\n private currentId: string | undefined;\n private allowSelfIntersections: boolean;\n private keyEvents: TerraDrawPolygonModeKeyEvents;\n private snappingEnabled: boolean;\n private isClosed = false;\n\n // Behaviors\n private snapping!: SnappingBehavior;\n private pixelDistance!: PixelDistanceBehavior;\n private closingPoints!: ClosingPointsBehavior;\n\n constructor(options?: {\n allowSelfIntersections?: boolean;\n snapping?: boolean;\n pointerDistance?: number;\n styles?: Partial<PolygonStyling>;\n keyEvents?: TerraDrawPolygonModeKeyEvents;\n }) {\n super(options);\n\n this.snappingEnabled =\n options && options.snapping !== undefined ? options.snapping : false;\n\n this.allowSelfIntersections =\n options && options.allowSelfIntersections !== undefined\n ? options.allowSelfIntersections\n : true;\n\n this.keyEvents =\n options && options.keyEvents ? options.keyEvents : { cancel: \"Escape\" };\n }\n\n public registerBehaviors(config: BehaviorConfig) {\n this.pixelDistance = new PixelDistanceBehavior(config);\n this.snapping = new SnappingBehavior(\n config,\n this.pixelDistance,\n new ClickBoundingBoxBehavior(config)\n );\n this.closingPoints = new ClosingPointsBehavior(config, this.pixelDistance);\n }\n\n start() {\n this.setStarted();\n this.setCursor(\"crosshair\");\n }\n stop() {\n this.setStopped();\n this.setCursor(\"unset\");\n this.cleanUp();\n }\n\n onMouseMove(event: TerraDrawMouseEvent) {\n this.setCursor(\"crosshair\");\n\n if (!this.currentId || this.currentCoordinate === 0) {\n return;\n }\n\n const closestCoord = this.snappingEnabled\n ? this.snapping.getSnappableCoordinate(event, this.currentId)\n : undefined;\n\n const currentPolygonCoordinates = this.store.getGeometryCopy<Polygon>(\n this.currentId\n ).coordinates[0];\n\n if (closestCoord) {\n event.lng = closestCoord[0];\n event.lat = closestCoord[1];\n }\n\n let updatedCoordinates;\n\n if (this.currentCoordinate === 1) {\n // We must add a very small epsilon value so that Mapbox GL\n // renders the polygon - There might be a cleaner solution?\n const epsilon = 1 / Math.pow(10, this.coordinatePrecision - 1);\n const offset = Math.max(0.000001, epsilon);\n\n updatedCoordinates = [\n currentPolygonCoordinates[0],\n [event.lng, event.lat],\n [event.lng, event.lat + offset],\n currentPolygonCoordinates[0],\n ];\n } else if (this.currentCoordinate === 2) {\n\n updatedCoordinates = [\n currentPolygonCoordinates[0],\n currentPolygonCoordinates[1],\n [event.lng, event.lat],\n currentPolygonCoordinates[0],\n ];\n } else {\n\n const { isClosing, isPreviousClosing } = this.closingPoints.isClosingPoint(event);\n\n if (isPreviousClosing || isClosing) {\n this.setCursor('pointer');\n updatedCoordinates = [\n ...currentPolygonCoordinates.slice(0, -2),\n currentPolygonCoordinates[0],\n currentPolygonCoordinates[0]\n ];\n\n if (!this.isClosed) {\n this.isClosed = true;\n }\n } else {\n\n if (this.isClosed) {\n this.isClosed = false;\n }\n\n updatedCoordinates = [\n ...currentPolygonCoordinates.slice(0, -2),\n [event.lng, event.lat],\n currentPolygonCoordinates[0],\n ];\n }\n }\n\n this.store.updateGeometry([\n {\n id: this.currentId,\n geometry: {\n type: \"Polygon\",\n coordinates: [updatedCoordinates],\n },\n },\n ]);\n\n if (this.closingPoints.ids.length) {\n this.closingPoints.update(updatedCoordinates);\n }\n }\n\n onClick(event: TerraDrawMouseEvent) {\n const closestCoord =\n this.currentId && this.snappingEnabled\n ? this.snapping.getSnappableCoordinate(event, this.currentId)\n : undefined;\n\n if (this.currentCoordinate === 0) {\n if (closestCoord) {\n event.lng = closestCoord[0];\n event.lat = closestCoord[1];\n }\n\n const [newId] = this.store.create([\n {\n geometry: {\n type: \"Polygon\",\n coordinates: [\n [\n [event.lng, event.lat],\n [event.lng, event.lat],\n [event.lng, event.lat],\n [event.lng, event.lat],\n ],\n ],\n },\n properties: { mode: this.mode },\n },\n ]);\n this.currentId = newId;\n this.currentCoordinate++;\n } else if (this.currentCoordinate === 1 && this.currentId) {\n if (closestCoord) {\n event.lng = closestCoord[0];\n event.lat = closestCoord[1];\n }\n\n const currentPolygonGeometry = this.store.getGeometryCopy<Polygon>(\n this.currentId\n );\n\n const previousCoordinate = currentPolygonGeometry.coordinates[0][0];\n const isIdentical = coordinatesIdentical([event.lng, event.lat], previousCoordinate);\n\n if (isIdentical) {\n return;\n }\n\n this.store.updateGeometry([\n {\n id: this.currentId,\n geometry: {\n type: \"Polygon\",\n coordinates: [\n [\n currentPolygonGeometry.coordinates[0][0],\n [event.lng, event.lat],\n [event.lng, event.lat],\n currentPolygonGeometry.coordinates[0][0],\n ],\n ],\n },\n },\n ]);\n\n this.currentCoordinate++;\n } else if (this.currentCoordinate === 2 && this.currentId) {\n if (closestCoord) {\n event.lng = closestCoord[0];\n event.lat = closestCoord[1];\n }\n\n const currentPolygonCoordinates = this.store.getGeometryCopy<Polygon>(\n this.currentId\n ).coordinates[0];\n\n const previousCoordinate = currentPolygonCoordinates[1];\n const isIdentical = coordinatesIdentical([event.lng, event.lat], previousCoordinate);\n\n if (isIdentical) {\n return;\n }\n\n if (this.currentCoordinate === 2) {\n this.closingPoints.create(currentPolygonCoordinates, 'polygon');\n }\n\n this.store.updateGeometry([\n {\n id: this.currentId,\n geometry: {\n type: \"Polygon\",\n coordinates: [\n [\n currentPolygonCoordinates[0],\n currentPolygonCoordinates[1],\n [event.lng, event.lat],\n [event.lng, event.lat],\n currentPolygonCoordinates[0],\n ],\n ],\n },\n },\n ]);\n\n this.currentCoordinate++;\n } else if (this.currentId) {\n\n\n const currentPolygonCoordinates = this.store.getGeometryCopy<Polygon>(\n this.currentId\n ).coordinates[0];\n\n const { isClosing, isPreviousClosing } = this.closingPoints.isClosingPoint(event);\n\n if (isPreviousClosing || isClosing) {\n\n this.store.updateGeometry([\n {\n id: this.currentId,\n geometry: {\n type: \"Polygon\",\n coordinates: [\n [\n ...currentPolygonCoordinates.slice(0, -2),\n currentPolygonCoordinates[0],\n ],\n ],\n },\n },\n ]);\n\n this.currentCoordinate = 0;\n this.currentId = undefined;\n this.closingPoints.delete();\n } else {\n if (closestCoord) {\n event.lng = closestCoord[0];\n event.lat = closestCoord[1];\n }\n\n const previousCoordinate = currentPolygonCoordinates[this.currentCoordinate - 1];\n const isIdentical = coordinatesIdentical([event.lng, event.lat], previousCoordinate);\n\n if (isIdentical) {\n return;\n }\n\n const updatedPolygon = createPolygon([\n [\n ...currentPolygonCoordinates.slice(0, -1),\n [event.lng, event.lat], // New point that onMouseMove can manipulate\n currentPolygonCoordinates[0],\n ],\n ]);\n\n if (this.currentCoordinate > 2 && !this.allowSelfIntersections) {\n const hasSelfIntersections = selfIntersects(updatedPolygon);\n\n if (hasSelfIntersections) {\n // Don't update the geometry!\n return;\n }\n }\n\n // If not close to the final point, keep adding points\n this.store.updateGeometry([\n { id: this.currentId, geometry: updatedPolygon.geometry },\n ]);\n this.currentCoordinate++;\n }\n }\n }\n\n onKeyUp(event: TerraDrawKeyboardEvent) {\n if (event.key === this.keyEvents.cancel) {\n this.cleanUp();\n }\n }\n\n onKeyDown() { }\n\n onDragStart() {\n // We want to allow the default drag\n // cursor to exist\n this.setCursor(\"unset\");\n }\n onDrag() { }\n onDragEnd() {\n // Set it back to crosshair\n this.setCursor(\"crosshair\");\n }\n\n cleanUp() {\n try {\n if (this.currentId) {\n this.store.delete([this.currentId]);\n }\n if (this.closingPoints.ids.length) {\n this.closingPoints.delete();\n }\n } catch (error) { }\n this.currentId = undefined;\n this.currentCoordinate = 0;\n }\n\n styleFeature(\n feature: GeoJSONStoreFeatures\n ): TerraDrawAdapterStyling {\n\n const styles = { ...getDefaultStyling() };\n\n if (feature.properties.mode === this.mode) {\n if (feature.geometry.type === 'Polygon') {\n styles.polygonFillColor = this.styles.fillColor || styles.polygonFillColor;\n styles.polygonOutlineColor = this.styles.outlineColor || styles.polygonOutlineColor;\n styles.polygonOutlineWidth = this.styles.outlineWidth || styles.polygonOutlineWidth;\n styles.polygonFillColor = this.styles.fillColor || styles.polygonFillColor;\n styles.zIndex = 10;\n return styles;\n }\n\n else if (feature.geometry.type === 'Point') {\n styles.pointWidth = this.styles.closingPointWidth || styles.pointWidth;\n styles.pointColor = this.styles.closingPointColor || styles.pointColor;\n styles.pointOutlineColor = this.styles.closingPointOutlineColor || \"#ffffff\";\n styles.pointOutlineWidth = this.styles.closingPointOutlineWidth || 2;\n styles.zIndex = 30;\n return styles;\n }\n }\n\n return styles;\n }\n}\n","import { Feature, LineString, Polygon, Position } from \"geojson\";\n\nexport function createPolygon(\n coordinates: Position[][] = [\n [\n [0, 0],\n [0, 1],\n [1, 1],\n [1, 0],\n [0, 0],\n ],\n ]\n): Feature<Polygon> {\n return {\n type: \"Feature\",\n geometry: {\n type: \"Polygon\",\n coordinates,\n },\n properties: {},\n };\n}\n\nexport function createLineString(coordinates: Position[]): Feature<LineString> {\n return {\n type: \"Feature\",\n geometry: {\n type: \"LineString\",\n coordinates,\n },\n properties: {},\n };\n}\n","import { TerraDrawAdapterStyling } from \"../../common\";\nimport { TerraDrawBaseDrawMode } from \"../base.mode\";\nimport { BehaviorConfig } from \"../base.behavior\";\nimport { getDefaultStyling } from \"../../util/styling\";\n\n// eslint-disable-next-line @typescript-eslint/ban-types\ntype RenderModeStylingExt<T extends TerraDrawAdapterStyling> = {}\ntype RenderModeStyling = RenderModeStylingExt<TerraDrawAdapterStyling>\n\nexport class TerraDrawRenderMode extends TerraDrawBaseDrawMode<RenderModeStyling> {\n public mode = \"render\"; // This gets changed dynamically\n\n constructor(options: { styles: Partial<TerraDrawAdapterStyling> }) {\n super({ styles: options.styles });\n }\n\n // TODO: this is probably abusing\n // registerBehaviors but it works quite well conceptually\n registerBehaviors(behaviorConfig: BehaviorConfig) {\n // We can set the mode name dynamically\n this.mode = behaviorConfig.mode;\n }\n\n start() {\n this.setStarted();\n }\n stop() {\n this.setStopped();\n }\n onKeyUp() { }\n onKeyDown() { }\n onClick() { }\n onDragStart() { }\n onDrag() { }\n onDragEnd() { }\n onMouseMove() { }\n styleFeature(): TerraDrawAdapterStyling {\n return {\n ...getDefaultStyling(),\n ...this.styles\n };\n }\n}\n","import { Position } from \"geojson\";\nimport { destination } from \"./shape/create-circle\";\nimport { degreesToRadians, radiansToDegrees } from \"./helpers\";\nimport { limitPrecision } from \"./limit-decimal-precision\";\nimport { haversineDistanceKilometers } from \"./measure/haversine-distance\";\n\nfunction bearing(coordinates1: Position, coordinates2: Position) {\n const lon1 = degreesToRadians(coordinates1[0]);\n const lon2 = degreesToRadians(coordinates2[0]);\n const lat1 = degreesToRadians(coordinates1[1]);\n const lat2 = degreesToRadians(coordinates2[1]);\n const a = Math.sin(lon2 - lon1) * Math.cos(lat2);\n const b =\n Math.cos(lat1) * Math.sin(lat2) -\n Math.sin(lat1) * Math.cos(lat2) * Math.cos(lon2 - lon1);\n\n return radiansToDegrees(Math.atan2(a, b));\n}\n\n// Based on turf-midpoint: https://github.com/Turfjs/turf/tree/master/packages/turf-midpoint\n\nexport function midpointCoordinate(\n coordinates1: Position,\n coordinates2: Position,\n precision: number\n) {\n const dist = haversineDistanceKilometers(coordinates1, coordinates2);\n const heading = bearing(coordinates1, coordinates2);\n const midpoint = destination(coordinates1, dist / 2, heading);\n\n return [\n limitPrecision(midpoint[0], precision),\n limitPrecision(midpoint[1], precision),\n ];\n}\n","import { Point, Position } from \"geojson\";\nimport { JSONObject } from \"../store/store\";\nimport { midpointCoordinate } from \"./midpoint-coordinate\";\n\nexport function getMidPointCoordinates(\n featureCoords: Position[],\n precision: number\n) {\n const midPointCoords: Position[] = [];\n for (let i = 0; i < featureCoords.length - 1; i++) {\n const mid = midpointCoordinate(\n featureCoords[i],\n featureCoords[i + 1],\n precision\n );\n midPointCoords.push(mid);\n }\n return midPointCoords;\n}\n\nexport function getMidPoints(\n selectedCoords: Position[],\n properties: (index: number) => JSONObject,\n precision: number\n) {\n return getMidPointCoordinates(selectedCoords, precision).map((coord, i) => ({\n geometry: { type: \"Point\", coordinates: coord } as Point,\n properties: properties(i),\n }));\n}\n","import { LineString, Point, Polygon, Position } from \"geojson\";\nimport { BehaviorConfig, TerraDrawModeBehavior } from \"../../base.behavior\";\nimport {\n getMidPointCoordinates,\n getMidPoints,\n} from \"../../../geometry/get-midpoints\";\nimport { SelectionPointBehavior } from \"./selection-point.behavior\";\nimport { SELECT_PROPERTIES } from \"../../../common\";\n\nexport class MidPointBehavior extends TerraDrawModeBehavior {\n constructor(\n readonly config: BehaviorConfig,\n private readonly selectionPointBehavior: SelectionPointBehavior\n ) {\n super(config);\n }\n\n private _midPoints: string[] = [];\n\n get ids() {\n return this._midPoints.concat();\n }\n\n set ids(_: string[]) {}\n\n public insert(midPointId: string, coordinatePrecision: number) {\n const midPoint = this.store.getGeometryCopy(midPointId);\n const { midPointFeatureId, midPointSegment } =\n this.store.getPropertiesCopy(midPointId);\n const geometry = this.store.getGeometryCopy<Polygon | LineString>(\n midPointFeatureId as string\n );\n\n // Update the coordinates to include inserted midpoint\n const updatedCoordinates =\n geometry.type === \"Polygon\"\n ? geometry.coordinates[0]\n : geometry.coordinates;\n\n updatedCoordinates.splice(\n (midPointSegment as number) + 1,\n 0,\n midPoint.coordinates as Position\n );\n\n // Update geometry coordinates depending\n // on if a polygon or linestring\n geometry.coordinates =\n geometry.type === \"Polygon\" ? [updatedCoordinates] : updatedCoordinates;\n\n // Update the selected features geometry to insert\n // the new midpoint\n this.store.updateGeometry([{ id: midPointFeatureId as string, geometry }]);\n\n // TODO: is there a way of just updating the selection points rather\n // than fully deleting / recreating?\n // Recreate the selection points\n\n this.store.delete([...this._midPoints, ...this.selectionPointBehavior.ids]);\n\n // We don't need to check if flags are correct\n // because selection points are prerequiste for midpoints\n this.create(\n updatedCoordinates,\n midPointFeatureId as string,\n coordinatePrecision\n );\n this.selectionPointBehavior.create(\n updatedCoordinates,\n geometry.type,\n midPointFeatureId as string\n );\n }\n\n public create(\n selectedCoords: Position[],\n featureId: string,\n coordinatePrecision: number\n ) {\n if (!this.store.has(featureId)) {\n throw new Error(\"Store does not have feature with this id\");\n }\n\n this._midPoints = this.store.create(\n getMidPoints(\n selectedCoords,\n (i) => ({\n mode: this.mode,\n [SELECT_PROPERTIES.MID_POINT]: true,\n midPointSegment: i,\n midPointFeatureId: featureId,\n }),\n coordinatePrecision\n )\n );\n }\n\n public delete() {\n if (this._midPoints.length) {\n this.store.delete(this._midPoints);\n this._midPoints = [];\n }\n }\n\n public getUpdated(updatedCoordinates: Position[]) {\n if (this._midPoints.length === 0) {\n return undefined;\n }\n\n return getMidPointCoordinates(\n updatedCoordinates,\n this.coordinatePrecision\n ).map((updatedMidPointCoord, i) => ({\n id: this._midPoints[i] as string,\n geometry: {\n type: \"Point\",\n coordinates: updatedMidPointCoord,\n } as Point,\n }));\n }\n}\n","import { LineString, Point, Polygon, Position } from \"geojson\";\nimport { BehaviorConfig, TerraDrawModeBehavior } from \"../../base.behavior\";\nimport { getCoordinatesAsPoints } from \"../../../geometry/get-coordinates-as-points\";\n\nexport class SelectionPointBehavior extends TerraDrawModeBehavior {\n constructor(config: BehaviorConfig) {\n super(config);\n }\n\n private _selectionPoints: string[] = [];\n\n get ids() {\n return this._selectionPoints.concat();\n }\n\n set ids(_: string[]) {}\n\n public create(\n selectedCoords: Position[],\n type: Polygon[\"type\"] | LineString[\"type\"],\n featureId: string\n ) {\n this._selectionPoints = this.store.create(\n getCoordinatesAsPoints(selectedCoords, type, (i) => ({\n mode: this.mode,\n selectionPoint: true,\n selectionPointFeatureId: featureId,\n index: i,\n }))\n );\n }\n\n public delete() {\n if (this.ids.length) {\n this.store.delete(this.ids);\n this._selectionPoints = [];\n }\n }\n\n public getUpdated(updatedCoordinates: Position[]) {\n if (this._selectionPoints.length === 0) {\n return undefined;\n }\n\n return this._selectionPoints.map((id, i) => {\n return {\n id,\n geometry: {\n type: \"Point\",\n coordinates: updatedCoordinates[i],\n } as Point,\n };\n });\n }\n\n public getOneUpdated(index: number, updatedCoordinate: Position) {\n if (this._selectionPoints[index] === undefined) {\n return undefined;\n }\n\n return {\n id: this._selectionPoints[index] as string,\n geometry: {\n type: \"Point\",\n coordinates: updatedCoordinate,\n } as Point,\n };\n }\n}\n","import { Point, Position } from \"geojson\";\nimport { JSONObject } from \"../store/store\";\n\nexport function getCoordinatesAsPoints(\n selectedCoords: Position[],\n geometryType: \"Polygon\" | \"LineString\",\n properties: (index: number) => JSONObject\n) {\n const selectionPoints = [];\n\n // We can skip the last point for polygons\n // as it's a duplicate of the first\n const length =\n geometryType === \"Polygon\"\n ? selectedCoords.length - 1\n : selectedCoords.length;\n\n for (let i = 0; i < length; i++) {\n selectionPoints.push({\n geometry: {\n type: \"Point\",\n coordinates: selectedCoords[i],\n } as Point,\n properties: properties(i),\n });\n }\n\n return selectionPoints;\n}\n","// Based on which-polygon\n\nimport { Position } from \"geojson\";\n\n// https://github.com/mapbox/which-polygon/blob/2eb5b8a427d018ebd964c05acd3b9166c4558b2c/index.js#L81\nexport function pointInPolygon(point: Position, rings: Position[][]) {\n let inside = false;\n for (let i = 0, len = rings.length; i < len; i++) {\n const ring = rings[i];\n for (let j = 0, len2 = ring.length, k = len2 - 1; j < len2; k = j++) {\n if (rayIntersect(point, ring[j], ring[k])) {\n inside = !inside;\n }\n }\n }\n return inside;\n}\n\nfunction rayIntersect(p: Position, p1: Position, p2: Position) {\n return (\n p1[1] > p[1] !== p2[1] > p[1] &&\n p[0] < ((p2[0] - p1[0]) * (p[1] - p1[1])) / (p2[1] - p1[1]) + p1[0]\n );\n}\n","export const pixelDistanceToLine = (\n point: { x: number; y: number },\n linePointOne: { x: number; y: number },\n linePointTwo: { x: number; y: number }\n) => {\n const square = (x: number) => {\n return x * x;\n };\n const dist2 = (v: { x: number; y: number }, w: { x: number; y: number }) => {\n return square(v.x - w.x) + square(v.y - w.y);\n };\n const distToSegmentSquared = (\n p: { x: number; y: number },\n v: { x: number; y: number },\n w: { x: number; y: number }\n ) => {\n const l2 = dist2(v, w);\n\n if (l2 === 0) {\n return dist2(p, v);\n }\n\n let t = ((p.x - v.x) * (w.x - v.x) + (p.y - v.y) * (w.y - v.y)) / l2;\n t = Math.max(0, Math.min(1, t));\n\n return dist2(p, { x: v.x + t * (w.x - v.x), y: v.y + t * (w.y - v.y) });\n };\n\n return Math.sqrt(distToSegmentSquared(point, linePointOne, linePointTwo));\n};\n","import { SELECT_PROPERTIES, TerraDrawMouseEvent } from \"../../../common\";\nimport { BBoxPolygon, GeoJSONStoreFeatures } from \"../../../store/store\";\n\nimport { BehaviorConfig, TerraDrawModeBehavior } from \"../../base.behavior\";\nimport { ClickBoundingBoxBehavior } from \"../../click-bounding-box.behavior\";\n\nimport { pointInPolygon } from \"../../../geometry/boolean/point-in-polygon\";\nimport { PixelDistanceBehavior } from \"../../pixel-distance.behavior\";\nimport { pixelDistanceToLine } from \"../../../geometry/measure/pixel-distance-to-line\";\n\nexport class FeaturesAtMouseEventBehavior extends TerraDrawModeBehavior {\n constructor(\n readonly config: BehaviorConfig,\n private readonly createClickBoundingBox: ClickBoundingBoxBehavior,\n private readonly pixelDistance: PixelDistanceBehavior\n ) {\n super(config);\n }\n\n public find(event: TerraDrawMouseEvent, hasSelection: boolean) {\n let clickedFeature: GeoJSONStoreFeatures | undefined = undefined;\n let clickedFeatureDistance = Infinity;\n let clickedMidPoint: GeoJSONStoreFeatures | undefined = undefined;\n let clickedMidPointDistance = Infinity;\n\n const bbox = this.createClickBoundingBox.create(event);\n const features = this.store.search(bbox as BBoxPolygon);\n\n for (let i = 0; i < features.length; i++) {\n const feature = features[i];\n const geometry = feature.geometry;\n\n if (geometry.type === \"Point\") {\n // Ignore selection points always, and ignore mid points\n // when nothing is selected\n const isSelectionPoint = feature.properties.selectionPoint;\n const isNonSelectedMidPoint =\n !hasSelection && feature.properties[SELECT_PROPERTIES.MID_POINT];\n\n if (isSelectionPoint || isNonSelectedMidPoint) {\n continue;\n }\n\n const distance = this.pixelDistance.measure(\n event,\n\n geometry.coordinates\n );\n\n // We want to catch both clicked\n // features but also any midpoints\n // in the clicked area\n if (\n feature.properties[SELECT_PROPERTIES.MID_POINT] &&\n distance < this.pointerDistance &&\n distance < clickedMidPointDistance\n ) {\n clickedMidPointDistance = distance;\n clickedMidPoint = feature;\n } else if (\n !feature.properties[SELECT_PROPERTIES.MID_POINT] &&\n distance < this.pointerDistance &&\n distance < clickedFeatureDistance\n ) {\n clickedFeatureDistance = distance;\n clickedFeature = feature;\n }\n } else if (geometry.type === \"LineString\") {\n for (let i = 0; i < geometry.coordinates.length - 1; i++) {\n const coord = geometry.coordinates[i];\n const nextCoord = geometry.coordinates[i + 1];\n const distanceToLine = pixelDistanceToLine(\n { x: event.containerX, y: event.containerY },\n this.project(coord[0], coord[1]),\n this.project(nextCoord[0], nextCoord[1])\n );\n\n if (\n distanceToLine < this.pointerDistance &&\n distanceToLine < clickedFeatureDistance\n ) {\n clickedFeatureDistance = distanceToLine;\n clickedFeature = feature;\n }\n }\n } else if (geometry.type === \"Polygon\") {\n const clickInsidePolygon = pointInPolygon(\n [event.lng, event.lat],\n geometry.coordinates\n );\n\n if (clickInsidePolygon) {\n clickedFeatureDistance = 0;\n clickedFeature = feature;\n }\n }\n }\n\n return { clickedFeature, clickedMidPoint };\n }\n}\n","import { TerraDrawMouseEvent } from \"../../../common\";\nimport { BehaviorConfig, TerraDrawModeBehavior } from \"../../base.behavior\";\nimport { FeaturesAtMouseEventBehavior } from \"./features-at-mouse-event.behavior\";\nimport { Position } from \"geojson\";\nimport { SelectionPointBehavior } from \"./selection-point.behavior\";\nimport { MidPointBehavior } from \"./midpoint.behavior\";\n\nexport class DragFeatureBehavior extends TerraDrawModeBehavior {\n constructor(\n readonly config: BehaviorConfig,\n private readonly featuresAtMouseEvent: FeaturesAtMouseEventBehavior,\n private readonly selectionPoints: SelectionPointBehavior,\n private readonly midPoints: MidPointBehavior\n ) {\n super(config);\n }\n\n private dragPosition: Position | undefined;\n\n get position() {\n return this.dragPosition ? this.dragPosition.concat() : undefined;\n }\n\n set position(newPosition: undefined | Position) {\n if (newPosition === undefined) {\n this.dragPosition = undefined;\n return;\n }\n\n if (\n !Array.isArray(newPosition) ||\n newPosition.length !== 2 ||\n typeof newPosition[0] !== \"number\" ||\n typeof newPosition[1] !== \"number\"\n ) {\n throw new Error(\"Position must be [number, number] array\");\n }\n\n this.dragPosition = newPosition.concat();\n }\n\n drag(event: TerraDrawMouseEvent, selectedId: string) {\n const hasSelection = true;\n const { clickedFeature } = this.featuresAtMouseEvent.find(\n event,\n hasSelection\n );\n\n // If the cursor is not over the selected\n // feature then we don't want to drag\n if (!clickedFeature || clickedFeature.id !== selectedId) {\n return;\n }\n\n const geometry = this.store.getGeometryCopy(selectedId);\n const mouseCoord = [event.lng, event.lat];\n\n // Update the geometry of the dragged feature\n if (geometry.type === \"Polygon\" || geometry.type === \"LineString\") {\n let updatedCoords: Position[] | undefined;\n let upToCoord: number | undefined;\n\n if (geometry.type === \"Polygon\") {\n updatedCoords = geometry.coordinates[0];\n upToCoord = updatedCoords.length - 1;\n } else if (geometry.type === \"LineString\") {\n updatedCoords = geometry.coordinates;\n upToCoord = updatedCoords.length;\n }\n\n if (upToCoord === undefined || !updatedCoords || !this.dragPosition) {\n return false;\n }\n\n for (let i = 0; i < upToCoord; i++) {\n const coordinate = updatedCoords[i];\n const delta = [\n this.dragPosition[0] - mouseCoord[0],\n this.dragPosition[1] - mouseCoord[1],\n ];\n updatedCoords[i] = [coordinate[0] - delta[0], coordinate[1] - delta[1]];\n }\n\n // Set final coordinate identical to first\n // We only want to do this for polygons!\n if (geometry.type === \"Polygon\") {\n updatedCoords[updatedCoords.length - 1] = [\n updatedCoords[0][0],\n updatedCoords[0][1],\n ];\n }\n\n const updatedSelectionPoints =\n this.selectionPoints.getUpdated(updatedCoords) || [];\n\n const updatedMidPoints = this.midPoints.getUpdated(updatedCoords) || [];\n\n // Issue the update to the selected feature\n this.store.updateGeometry([\n { id: selectedId, geometry },\n ...updatedSelectionPoints,\n ...updatedMidPoints,\n ]);\n\n // Update mid point positions\n } else if (geometry.type === \"Point\") {\n // For mouse points we can simply move it\n // to the dragged position\n this.store.updateGeometry([\n {\n id: selectedId,\n geometry: {\n type: \"Point\",\n coordinates: mouseCoord,\n },\n },\n ]);\n }\n }\n}\n","import { TerraDrawMouseEvent } from \"../../../common\";\nimport { BehaviorConfig, TerraDrawModeBehavior } from \"../../base.behavior\";\n\nimport { Position } from \"geojson\";\nimport { PixelDistanceBehavior } from \"../../pixel-distance.behavior\";\nimport { MidPointBehavior } from \"./midpoint.behavior\";\nimport { SelectionPointBehavior } from \"./selection-point.behavior\";\n\nexport class DragCoordinateBehavior extends TerraDrawModeBehavior {\n constructor(\n readonly config: BehaviorConfig,\n private readonly pixelDistance: PixelDistanceBehavior,\n private readonly selectionPoints: SelectionPointBehavior,\n private readonly midPoints: MidPointBehavior\n ) {\n super(config);\n }\n\n public drag(event: TerraDrawMouseEvent, selectedId: string): boolean {\n const geometry = this.store.getGeometryCopy(selectedId);\n\n let geomCoordinates: Position[] | undefined;\n\n if (geometry.type === \"LineString\") {\n geomCoordinates = geometry.coordinates;\n } else if (geometry.type === \"Polygon\") {\n geomCoordinates = geometry.coordinates[0];\n } else {\n // We don't want to handle dragging\n // points here\n return false;\n }\n\n const closestCoordinate = {\n dist: Infinity,\n index: -1,\n isFirstOrLastPolygonCoord: false,\n };\n\n // Look through the selected features coordinates\n // and try to find a coordinate that is draggable\n for (let i = 0; i < geomCoordinates.length; i++) {\n const coord = geomCoordinates[i];\n const distance = this.pixelDistance.measure(event, coord);\n\n if (\n distance < this.pointerDistance &&\n distance < closestCoordinate.dist\n ) {\n // We don't create a point for the final\n // polygon coord, so we must set it to the first\n // coordinate instead\n const isFirstOrLastPolygonCoord =\n geometry.type === \"Polygon\" &&\n (i === geomCoordinates.length - 1 || i === 0);\n\n closestCoordinate.dist = distance;\n closestCoordinate.index = isFirstOrLastPolygonCoord ? 0 : i;\n closestCoordinate.isFirstOrLastPolygonCoord = isFirstOrLastPolygonCoord;\n }\n }\n\n // No coordinate was within the pointer distance\n if (closestCoordinate.index === -1) {\n return false;\n }\n\n // Store the updated coord\n const updatedCoordinate = [event.lng, event.lat];\n\n // We want to update the actual Polygon/LineString itself -\n // for Polygons we want the first and last coordinates to match\n if (closestCoordinate.isFirstOrLastPolygonCoord) {\n const lastCoordIndex = geomCoordinates.length - 1;\n geomCoordinates[0] = updatedCoordinate;\n geomCoordinates[lastCoordIndex] = updatedCoordinate;\n } else {\n geomCoordinates[closestCoordinate.index] = updatedCoordinate;\n }\n\n const updatedSelectionPoint = this.selectionPoints.getOneUpdated(\n closestCoordinate.index,\n updatedCoordinate\n );\n\n const updatedSelectionPoints = updatedSelectionPoint\n ? [updatedSelectionPoint]\n : [];\n\n const updatedMidPoints = this.midPoints.getUpdated(geomCoordinates) || [];\n\n // Apply all the updates\n this.store.updateGeometry([\n // Update feature\n {\n id: selectedId,\n geometry: geometry,\n },\n // Update selection and mid points\n ...updatedSelectionPoints,\n ...updatedMidPoints,\n ]);\n\n return true;\n }\n}\n","import { Feature, LineString, Polygon, Position } from \"geojson\";\n\nexport function centroid(geojson: Feature<Polygon | LineString>): Position {\n let xSum = 0;\n let ySum = 0;\n let len = 0;\n\n const coordinates =\n geojson.geometry.type === \"Polygon\"\n ? geojson.geometry.coordinates[0].slice(0, -1)\n : geojson.geometry.coordinates;\n\n coordinates.forEach((coord: Position) => {\n xSum += coord[0];\n ySum += coord[1];\n len++;\n }, true);\n\n return [xSum / len, ySum / len];\n}\n","import { Position } from \"geojson\";\nimport { degreesToRadians, radiansToDegrees } from \"../helpers\";\n\nexport function rhumbBearing(start: Position, end: Position): number {\n const from = start;\n const to = end;\n\n // φ => phi\n // Δλ => deltaLambda\n // Δψ => deltaPsi\n // θ => theta\n const phi1 = degreesToRadians(from[1]);\n const phi2 = degreesToRadians(to[1]);\n let deltaLambda = degreesToRadians(to[0] - from[0]);\n\n // if deltaLambdaon over 180° take shorter rhumb line across the anti-meridian:\n if (deltaLambda > Math.PI) {\n deltaLambda -= 2 * Math.PI;\n }\n if (deltaLambda < -Math.PI) {\n deltaLambda += 2 * Math.PI;\n }\n\n const deltaPsi = Math.log(\n Math.tan(phi2 / 2 + Math.PI / 4) / Math.tan(phi1 / 2 + Math.PI / 4)\n );\n\n const theta = Math.atan2(deltaLambda, deltaPsi);\n\n const bear360 = (radiansToDegrees(theta) + 360) % 360;\n\n const bear180 = bear360 > 180 ? -(360 - bear360) : bear360;\n\n return bear180;\n}\n","import { Position } from \"geojson\";\nimport { degreesToRadians, radiansToDegrees, earthRadius } from \"../helpers\";\n\nexport function rhumbDestination(\n origin: Position,\n distanceMeters: number,\n bearing: number\n): Position {\n const wasNegativeDistance = distanceMeters < 0;\n let distanceInMeters = distanceMeters;\n\n if (wasNegativeDistance) {\n distanceInMeters = -Math.abs(distanceInMeters);\n }\n\n const delta = distanceMeters / earthRadius; // angular distance in radians\n const lambda1 = (origin[0] * Math.PI) / 180; // to radians, but without normalize to 𝜋\n const phi1 = degreesToRadians(origin[1]);\n const theta = degreesToRadians(bearing);\n\n const DeltaPhi = delta * Math.cos(theta);\n let phi2 = phi1 + DeltaPhi;\n\n // check for going past the pole, normalise latitude if so\n if (Math.abs(phi2) > Math.PI / 2) {\n phi2 = phi2 > 0 ? Math.PI - phi2 : -Math.PI - phi2;\n }\n\n const DeltaPsi = Math.log(\n Math.tan(phi2 / 2 + Math.PI / 4) / Math.tan(phi1 / 2 + Math.PI / 4)\n );\n // E-W course becomes ill-conditioned with 0/0\n const q = Math.abs(DeltaPsi) > 10e-12 ? DeltaPhi / DeltaPsi : Math.cos(phi1);\n\n const DeltaLambda = (delta * Math.sin(theta)) / q;\n const lambda2 = lambda1 + DeltaLambda;\n\n // normalise to −180..+180°\n const destination = [\n (((lambda2 * 180) / Math.PI + 540) % 360) - 180,\n (phi2 * 180) / Math.PI,\n ];\n\n // compensate the crossing of the 180th meridian (https://macwright.org/2016/09/26/the-180th-meridian.html)\n // solution from https://github.com/mapbox/mapbox-gl-js/issues/3250#issuecomment-294887678\n destination[0] +=\n destination[0] - origin[0] > 180\n ? -360\n : origin[0] - destination[0] > 180\n ? 360\n : 0;\n return destination;\n}\n","import { Position } from \"geojson\";\nimport { earthRadius } from \"../helpers\";\n\nexport function rhumbDistance(destination: Position, origin: Position): number {\n // compensate the crossing of the 180th meridian (https://macwright.org/2016/09/26/the-180th-meridian.html)\n // solution from https://github.com/mapbox/mapbox-gl-js/issues/3250#issuecomment-294887678\n destination[0] +=\n destination[0] - origin[0] > 180\n ? -360\n : origin[0] - destination[0] > 180\n ? 360\n : 0;\n\n // see www.edwilliams.org/avform.htm#Rhumb\n\n const R = earthRadius;\n const phi1 = (origin[1] * Math.PI) / 180;\n const phi2 = (destination[1] * Math.PI) / 180;\n const DeltaPhi = phi2 - phi1;\n let DeltaLambda = (Math.abs(destination[0] - origin[0]) * Math.PI) / 180;\n\n // if dLon over 180° take shorter rhumb line across the anti-meridian:\n if (DeltaLambda > Math.PI) {\n DeltaLambda -= 2 * Math.PI;\n }\n\n // on Mercator projection, longitude distances shrink by latitude; q is the 'stretch factor'\n // q becomes ill-conditioned along E-W line (0/0); use empirical tolerance to avoid it\n const DeltaPsi = Math.log(\n Math.tan(phi2 / 2 + Math.PI / 4) / Math.tan(phi1 / 2 + Math.PI / 4)\n );\n const q = Math.abs(DeltaPsi) > 10e-12 ? DeltaPhi / DeltaPsi : Math.cos(phi1);\n\n // distance is pythagoras on 'stretched' Mercator projection\n const delta = Math.sqrt(\n DeltaPhi * DeltaPhi + q * q * DeltaLambda * DeltaLambda\n ); // angular distance in radians\n\n const distanceMeters = delta * R;\n\n return distanceMeters;\n}\n","import { TerraDrawMouseEvent } from \"../../../common\";\nimport { BehaviorConfig, TerraDrawModeBehavior } from \"../../base.behavior\";\nimport { LineString, Polygon, Position } from \"geojson\";\nimport { SelectionPointBehavior } from \"./selection-point.behavior\";\nimport { MidPointBehavior } from \"./midpoint.behavior\";\nimport { transformRotate } from \"../../../geometry/transform/rotate\";\nimport { centroid } from \"../../../geometry/centroid\";\nimport { rhumbBearing } from \"../../../geometry/measure/rhumb-bearing\";\nimport { limitPrecision } from \"../../../geometry/limit-decimal-precision\";\n\nexport class RotateFeatureBehavior extends TerraDrawModeBehavior {\n constructor(\n readonly config: BehaviorConfig,\n private readonly selectionPoints: SelectionPointBehavior,\n private readonly midPoints: MidPointBehavior\n ) {\n super(config);\n }\n\n private lastBearing: number | undefined;\n\n reset() {\n this.lastBearing = undefined;\n }\n\n rotate(event: TerraDrawMouseEvent, selectedId: string) {\n const geometry = this.store.getGeometryCopy<LineString | Polygon>(\n selectedId\n );\n\n // Update the geometry of the dragged feature\n if (geometry.type !== \"Polygon\" && geometry.type !== \"LineString\") {\n return;\n }\n\n const mouseCoord = [event.lng, event.lat];\n\n const bearing = rhumbBearing(\n centroid({ type: \"Feature\", geometry, properties: {} }),\n mouseCoord\n );\n\n // We need an original bearing to compare against\n if (!this.lastBearing) {\n this.lastBearing = bearing + 180;\n return;\n }\n\n const angle = this.lastBearing - (bearing + 180);\n\n transformRotate({ type: \"Feature\", geometry, properties: {} }, -angle);\n\n let updatedCoords: Position[] | undefined;\n\n if (geometry.type === \"Polygon\") {\n updatedCoords = geometry.coordinates[0];\n } else if (geometry.type === \"LineString\") {\n updatedCoords = geometry.coordinates;\n } else {\n return;\n }\n\n // Ensure that coordinate precision is maintained\n updatedCoords.forEach((coordinate) => {\n coordinate[0] = limitPrecision(coordinate[0], this.coordinatePrecision);\n coordinate[1] = limitPrecision(coordinate[1], this.coordinatePrecision);\n });\n\n const updatedMidPoints = this.midPoints.getUpdated(updatedCoords) || [];\n\n const updatedSelectionPoints =\n this.selectionPoints.getUpdated(updatedCoords) || [];\n\n // Issue the update to the selected feature\n this.store.updateGeometry([\n { id: selectedId, geometry },\n ...updatedSelectionPoints,\n ...updatedMidPoints,\n ]);\n\n this.lastBearing = bearing + 180;\n }\n}\n","import { Feature, LineString, Polygon, Position } from \"geojson\";\nimport { centroid } from \"../centroid\";\nimport { rhumbBearing } from \"../measure/rhumb-bearing\";\nimport { rhumbDestination } from \"../measure/rhumb-destination\";\nimport { rhumbDistance } from \"../measure/rhumb-distance\";\n\nexport function transformRotate(\n geojson: Feature<Polygon | LineString>,\n angle: number\n) {\n // Shortcut no-rotation\n if (angle === 0) {\n return geojson;\n }\n\n // Use centroid of GeoJSON if pivot is not provided\n const pivot = centroid(geojson);\n\n const cooordinates =\n geojson.geometry.type === \"Polygon\"\n ? geojson.geometry.coordinates[0]\n : geojson.geometry.coordinates;\n\n cooordinates.forEach((pointCoords: Position) => {\n const initialAngle = rhumbBearing(pivot, pointCoords);\n const finalAngle = initialAngle + angle;\n const distance = rhumbDistance(pivot, pointCoords);\n const newCoords = rhumbDestination(pivot, distance, finalAngle);\n pointCoords[0] = newCoords[0];\n pointCoords[1] = newCoords[1];\n });\n\n return geojson;\n}\n","import { TerraDrawMouseEvent } from \"../../../common\";\nimport { BehaviorConfig, TerraDrawModeBehavior } from \"../../base.behavior\";\nimport { LineString, Polygon, Position } from \"geojson\";\nimport { SelectionPointBehavior } from \"./selection-point.behavior\";\nimport { MidPointBehavior } from \"./midpoint.behavior\";\nimport { centroid } from \"../../../geometry/centroid\";\nimport { haversineDistanceKilometers } from \"../../../geometry/measure/haversine-distance\";\nimport { transformScale } from \"../../../geometry/transform/scale\";\nimport { limitPrecision } from \"../../../geometry/limit-decimal-precision\";\n\nexport class ScaleFeatureBehavior extends TerraDrawModeBehavior {\n constructor(\n readonly config: BehaviorConfig,\n private readonly selectionPoints: SelectionPointBehavior,\n private readonly midPoints: MidPointBehavior\n ) {\n super(config);\n }\n\n private lastDistance: number | undefined;\n\n reset() {\n this.lastDistance = undefined;\n }\n\n scale(event: TerraDrawMouseEvent, selectedId: string) {\n const geometry = this.store.getGeometryCopy<LineString | Polygon>(\n selectedId\n );\n\n // Update the geometry of the dragged feature\n if (geometry.type !== \"Polygon\" && geometry.type !== \"LineString\") {\n return;\n }\n\n const mouseCoord = [event.lng, event.lat];\n\n const distance = haversineDistanceKilometers(\n centroid({ type: \"Feature\", geometry, properties: {} }),\n mouseCoord\n );\n\n // We need an original bearing to compare against\n if (!this.lastDistance) {\n this.lastDistance = distance;\n return;\n }\n\n const scale = 1 - (this.lastDistance - distance) / distance;\n\n transformScale({ type: \"Feature\", geometry, properties: {} }, scale);\n\n let updatedCoords: Position[] | undefined;\n\n if (geometry.type === \"Polygon\") {\n updatedCoords = geometry.coordinates[0];\n } else if (geometry.type === \"LineString\") {\n updatedCoords = geometry.coordinates;\n } else {\n return;\n }\n\n // Ensure that coordinate precision is maintained\n updatedCoords.forEach((coordinate) => {\n coordinate[0] = limitPrecision(coordinate[0], this.coordinatePrecision);\n coordinate[1] = limitPrecision(coordinate[1], this.coordinatePrecision);\n });\n\n const updatedMidPoints = this.midPoints.getUpdated(updatedCoords) || [];\n\n const updatedSelectionPoints =\n this.selectionPoints.getUpdated(updatedCoords) || [];\n\n // Issue the update to the selected feature\n this.store.updateGeometry([\n { id: selectedId, geometry },\n ...updatedSelectionPoints,\n ...updatedMidPoints,\n ]);\n\n this.lastDistance = distance;\n }\n}\n","import { Feature, LineString, Polygon, Position } from \"geojson\";\nimport { centroid } from \"../centroid\";\nimport { rhumbBearing } from \"../measure/rhumb-bearing\";\nimport { rhumbDestination } from \"../measure/rhumb-destination\";\nimport { rhumbDistance } from \"../measure/rhumb-distance\";\n\nexport function transformScale(\n feature: Feature<Polygon | LineString>,\n factor: number\n) {\n // Shortcut no-scaling\n if (factor === 1) {\n return feature;\n }\n\n const origin = centroid(feature);\n\n const cooordinates =\n feature.geometry.type === \"Polygon\"\n ? feature.geometry.coordinates[0]\n : feature.geometry.coordinates;\n\n cooordinates.forEach((pointCoords: Position) => {\n const originalDistance = rhumbDistance(origin, pointCoords);\n const bearing = rhumbBearing(origin, pointCoords);\n const newDistance = originalDistance * factor;\n const newCoord = rhumbDestination(origin, newDistance, bearing);\n pointCoords[0] = newCoord[0];\n pointCoords[1] = newCoord[1];\n });\n\n return feature;\n}\n","import {\n TerraDrawMouseEvent,\n TerraDrawKeyboardEvent,\n SELECT_PROPERTIES,\n HexColor,\n TerraDrawAdapterStyling,\n} from \"../../common\";\nimport { Point, Position } from \"geojson\";\nimport { TerraDrawBaseDrawMode } from \"../base.mode\";\nimport { MidPointBehavior } from \"./behaviors/midpoint.behavior\";\nimport { SelectionPointBehavior } from \"./behaviors/selection-point.behavior\";\nimport { FeaturesAtMouseEventBehavior } from \"./behaviors/features-at-mouse-event.behavior\";\nimport { PixelDistanceBehavior } from \"../pixel-distance.behavior\";\nimport { ClickBoundingBoxBehavior } from \"../click-bounding-box.behavior\";\nimport { DragFeatureBehavior } from \"./behaviors/drag-feature.behavior\";\nimport { DragCoordinateBehavior } from \"./behaviors/drag-coordinate.behavior\";\nimport { BehaviorConfig } from \"../base.behavior\";\nimport { RotateFeatureBehavior } from \"./behaviors/rotate-feature.behavior\";\nimport { ScaleFeatureBehavior } from \"./behaviors/scale-feature.behavior\";\nimport { GeoJSONStoreFeatures } from \"../../store/store\";\nimport { getDefaultStyling } from \"../../util/styling\";\n\ntype TerraDrawSelectModeKeyEvents = {\n deselect: KeyboardEvent[\"key\"];\n delete: KeyboardEvent[\"key\"];\n rotate: KeyboardEvent[\"key\"];\n scale: KeyboardEvent[\"key\"];\n};\n\ntype ModeFlags = {\n feature?: {\n draggable?: boolean;\n rotateable?: boolean;\n scaleable?: boolean;\n coordinates?: {\n midpoints?: boolean;\n draggable?: boolean;\n deletable?: boolean;\n };\n };\n};\n\ntype SelectionStyling = {\n selectedColor: HexColor,\n selectedPointOutlineColor: HexColor,\n selectPointOutlineWidth: number,\n selectionPointWidth: number,\n selectionPointColor: HexColor,\n selectionPointOutlineColor: HexColor,\n selectionPointOutlineWidth: number,\n midPointColor: HexColor,\n midPointOutlineColor: HexColor,\n midPointWidth: number,\n midPointOutlineWidth: number,\n}\n\nexport class TerraDrawSelectMode extends TerraDrawBaseDrawMode<SelectionStyling> {\n mode = \"select\";\n\n private dragEventThrottle = 5;\n private dragEventCount = 0;\n private selected: string[] = [];\n\n private flags: { [mode: string]: ModeFlags };\n private keyEvents: TerraDrawSelectModeKeyEvents;\n\n // Behaviors\n private selectionPoints!: SelectionPointBehavior;\n private midPoints!: MidPointBehavior;\n private featuresAtMouseEvent!: FeaturesAtMouseEventBehavior;\n private pixelDistance!: PixelDistanceBehavior;\n private clickBoundingBox!: ClickBoundingBoxBehavior;\n private dragFeature!: DragFeatureBehavior;\n private dragCoordinate!: DragCoordinateBehavior;\n private rotateFeature!: RotateFeatureBehavior;\n private scaleFeature!: ScaleFeatureBehavior;\n\n constructor(options?: {\n styles?: Partial<SelectionStyling>\n pointerDistance?: number;\n flags?: { [mode: string]: ModeFlags };\n keyEvents?: TerraDrawSelectModeKeyEvents;\n dragEventThrottle?: number;\n }) {\n super(options);\n\n this.flags = options && options.flags ? options.flags : {};\n\n this.keyEvents =\n options && options.keyEvents\n ? options.keyEvents\n : { deselect: \"Escape\", delete: \"Delete\", rotate: \"r\", scale: \"s\" };\n\n this.dragEventThrottle =\n (options &&\n options.dragEventThrottle !== undefined &&\n options.dragEventThrottle) ||\n 5;\n }\n\n public registerBehaviors(config: BehaviorConfig) {\n this.pixelDistance = new PixelDistanceBehavior(config);\n this.clickBoundingBox = new ClickBoundingBoxBehavior(config);\n this.featuresAtMouseEvent = new FeaturesAtMouseEventBehavior(\n config,\n this.clickBoundingBox,\n this.pixelDistance\n );\n\n this.selectionPoints = new SelectionPointBehavior(config);\n this.midPoints = new MidPointBehavior(config, this.selectionPoints);\n\n this.rotateFeature = new RotateFeatureBehavior(\n config,\n this.selectionPoints,\n this.midPoints\n );\n\n this.scaleFeature = new ScaleFeatureBehavior(\n config,\n this.selectionPoints,\n this.midPoints\n );\n\n this.dragFeature = new DragFeatureBehavior(\n config,\n this.featuresAtMouseEvent,\n this.selectionPoints,\n this.midPoints\n );\n this.dragCoordinate = new DragCoordinateBehavior(\n config,\n this.pixelDistance,\n this.selectionPoints,\n this.midPoints\n );\n }\n\n private deselect() {\n this.store.updateProperty(\n this.selected.map((id) => ({\n id,\n property: SELECT_PROPERTIES.SELECTED,\n value: false,\n }))\n );\n\n this.onDeselect(this.selected[0]);\n this.selected = [];\n this.selectionPoints.delete();\n this.midPoints.delete();\n }\n\n private deleteSelected() {\n // Delete all selected features\n // from the store and clear selected\n // We don't need to set selected false\n // as we're going to delete the feature\n\n this.store.delete(this.selected);\n this.selected = [];\n }\n\n private onRightClick(event: TerraDrawMouseEvent) {\n if (!this.selectionPoints.ids.length) {\n return;\n }\n\n let clickedSelectionPointProps:\n | {\n selectionPointFeatureId: string;\n index: number;\n }\n | undefined;\n\n let clickedFeatureDistance = Infinity;\n\n this.selectionPoints.ids.forEach((id: string) => {\n const geometry = this.store.getGeometryCopy<Point>(id);\n const distance = this.pixelDistance.measure(event, geometry.coordinates);\n\n if (\n distance < this.pointerDistance &&\n distance < clickedFeatureDistance\n ) {\n clickedFeatureDistance = distance;\n clickedSelectionPointProps = this.store.getPropertiesCopy(id) as {\n selectionPointFeatureId: string;\n index: number;\n };\n }\n });\n\n if (!clickedSelectionPointProps) {\n return;\n }\n\n const featureId = clickedSelectionPointProps.selectionPointFeatureId;\n const coordinateIndex = clickedSelectionPointProps.index;\n\n // We allow for preventing deleting coordinates via flags\n const properties = this.store.getPropertiesCopy(featureId);\n const modeFlags = this.flags[properties.mode as string];\n\n // Check if we can actually delete the coordinate\n const cannotDelete = !modeFlags ||\n !modeFlags.feature ||\n !modeFlags.feature.coordinates ||\n !modeFlags.feature.coordinates.deletable;\n\n if (cannotDelete) {\n return;\n }\n\n const geometry = this.store.getGeometryCopy(featureId);\n\n let coordinates;\n if (geometry.type === \"Polygon\") {\n coordinates = geometry.coordinates[0];\n\n // Prevent creating an invalid polygon\n if (coordinates.length <= 4) {\n return;\n }\n } else if (geometry.type === \"LineString\") {\n coordinates = geometry.coordinates;\n\n // Prevent creating an invalid linestring\n if (coordinates.length <= 3) {\n return;\n }\n }\n\n // Geometry is not Polygon or LineString\n if (!coordinates) {\n return;\n }\n\n if (\n (geometry.type === \"Polygon\" && coordinateIndex === 0) ||\n coordinateIndex === coordinates.length - 1\n ) {\n // Deleting the final coordinate in a polygon breaks it\n // because GeoJSON expects a duplicate, so we need to fix\n // it by adding the new first coordinate to the end\n coordinates.shift();\n coordinates.pop();\n coordinates.push([coordinates[0][0], coordinates[0][1]]);\n } else {\n // Remove coordinate from array\n coordinates.splice(coordinateIndex, 1);\n }\n\n this.store.delete([...this.midPoints.ids, ...this.selectionPoints.ids]);\n this.store.updateGeometry([\n {\n id: featureId,\n geometry,\n },\n ]);\n\n this.selectionPoints.create(\n coordinates,\n geometry.type as \"Polygon\" | \"LineString\",\n featureId\n );\n\n if (\n modeFlags &&\n modeFlags.feature &&\n modeFlags.feature.coordinates &&\n modeFlags.feature.coordinates.midpoints\n ) {\n this.midPoints.create(coordinates, featureId, this.coordinatePrecision);\n }\n }\n\n private onLeftClick(event: TerraDrawMouseEvent) {\n const { clickedFeature, clickedMidPoint } = this.featuresAtMouseEvent.find(\n event,\n\n this.selected.length > 0\n );\n\n if (this.selected.length && clickedMidPoint) {\n // TODO: We probably want to make sure the midpoint\n // is visible?\n\n this.midPoints.insert(\n clickedMidPoint.id as string,\n this.coordinatePrecision\n );\n\n return;\n }\n\n if (clickedFeature) {\n const { mode } = this.store.getPropertiesCopy(\n clickedFeature.id as string\n );\n\n const previouslySelectedId = this.selected[0];\n\n // If we have something currently selected\n if (previouslySelectedId) {\n // If it matches the current selected feature id, do nothing\n if (previouslySelectedId === clickedFeature.id) {\n return;\n } else {\n // If it's a different feature set selected\n // to false on previously selected feature\n this.deselect();\n }\n }\n\n // This will be undefined for points\n const modeFlags = this.flags[mode as string];\n\n // If feature is not selectable then return\n if (!modeFlags || !modeFlags.feature) {\n return;\n }\n\n // Select feature\n this.selected = [clickedFeature.id as string];\n this.store.updateProperty([\n { id: clickedFeature.id as string, property: \"selected\", value: true },\n ]);\n this.onSelect(clickedFeature.id as string);\n\n // Get the clicked feature\n const { type, coordinates } = this.store.getGeometryCopy(\n clickedFeature.id as string\n );\n\n let selectedCoords: Position[] | undefined;\n if (type === \"LineString\") {\n selectedCoords = coordinates;\n } else if (type === \"Polygon\") {\n selectedCoords = coordinates[0];\n }\n\n if (selectedCoords && modeFlags && modeFlags.feature.coordinates) {\n this.selectionPoints.create(\n selectedCoords,\n type,\n clickedFeature.id as string\n );\n\n if (modeFlags.feature.coordinates.midpoints) {\n this.midPoints.create(\n selectedCoords,\n clickedFeature.id as string,\n this.coordinatePrecision\n );\n }\n }\n } else if (this.selected.length) {\n this.deselect();\n return;\n }\n }\n\n start() {\n this.setStarted();\n }\n stop() {\n this.setStopped();\n this.cleanUp();\n }\n\n onClick(event: TerraDrawMouseEvent) {\n if (event.button === \"right\") {\n this.onRightClick(event);\n return;\n } else if (event.button === \"left\") {\n this.onLeftClick(event);\n }\n }\n onKeyDown() { }\n onKeyUp(event: TerraDrawKeyboardEvent) {\n if (event.key === this.keyEvents.delete) {\n if (!this.selected.length) {\n return;\n }\n\n // We are technically deselecting\n // because the selected feature is deleted\n // and will no longer exist or be selected\n const previouslySelected = this.selected[0];\n this.onDeselect(previouslySelected);\n\n // Delete all selected features\n this.deleteSelected();\n\n // Remove all selection points\n this.selectionPoints.delete();\n this.midPoints.delete();\n } else if (event.key === this.keyEvents.deselect) {\n this.cleanUp();\n }\n }\n cleanUp() {\n if (this.selected.length) {\n this.deselect();\n }\n }\n onDragStart(\n event: TerraDrawMouseEvent,\n setMapDraggability: (enabled: boolean) => void\n ) {\n // We only need to stop the map dragging if\n // we actually have something selected\n if (!this.selected.length) {\n return;\n }\n\n // If the selected feature is not draggable\n // don't do anything\n const properties = this.store.getPropertiesCopy(this.selected[0]);\n const modeFlags = this.flags[properties.mode as string];\n const draggable =\n modeFlags &&\n modeFlags.feature &&\n (modeFlags.feature.draggable ||\n (modeFlags.feature.coordinates &&\n modeFlags.feature.coordinates.draggable));\n\n if (!draggable) {\n return;\n }\n\n this.dragEventCount = 0;\n this.setCursor(\"grabbing\");\n this.dragFeature.position = [event.lng, event.lat];\n\n setMapDraggability(false);\n }\n\n onDrag(event: TerraDrawMouseEvent) {\n const selectedId = this.selected[0];\n\n // If nothing selected or the drag position hasn't been set\n // do nothing\n if (!selectedId || !this.dragFeature.position) {\n return;\n }\n\n const properties = this.store.getPropertiesCopy(selectedId);\n const modeFlags = this.flags[properties.mode as string];\n\n // Ensure drag count is incremented\n this.dragEventCount++;\n\n // Return if we haven't hit the drag throttle limit\n // (i.e. we only want to drag every nth event)\n if (this.dragEventCount % this.dragEventThrottle === 0) {\n return;\n }\n\n // Check if should rotate\n if (\n modeFlags &&\n modeFlags.feature &&\n modeFlags.feature.rotateable &&\n event.heldKeys.includes(\"r\")\n ) {\n this.rotateFeature.rotate(event, selectedId);\n return;\n }\n\n // Check if should scale\n if (\n modeFlags &&\n modeFlags.feature &&\n modeFlags.feature.scaleable &&\n event.heldKeys.includes(\"s\")\n ) {\n this.scaleFeature.scale(event, selectedId);\n return;\n }\n\n // Check if coordinate is draggable and is dragged\n if (\n modeFlags &&\n modeFlags.feature &&\n modeFlags.feature.coordinates &&\n modeFlags.feature.coordinates.draggable\n ) {\n const coordinateWasDragged = this.dragCoordinate.drag(event, selectedId);\n\n if (coordinateWasDragged) {\n return;\n }\n }\n\n // Check if feature is draggable and is dragged\n if (modeFlags && modeFlags.feature && modeFlags.feature.draggable) {\n this.dragFeature.drag(event, selectedId);\n\n this.dragFeature.position = [event.lng, event.lat];\n }\n }\n\n onDragEnd(\n _: TerraDrawMouseEvent,\n setMapDraggability: (enabled: boolean) => void\n ) {\n this.setCursor(\"grab\");\n this.dragFeature.position = undefined;\n this.rotateFeature.reset();\n this.scaleFeature.reset();\n setMapDraggability(true);\n }\n\n onMouseMove(event: TerraDrawMouseEvent) {\n if (!this.selected.length || this.dragFeature.position) {\n return;\n }\n\n let nearbySelectionPoint = false;\n this.midPoints.ids.forEach((id: string) => {\n if (nearbySelectionPoint) {\n return;\n }\n const geometry = this.store.getGeometryCopy<Point>(id);\n const distance = this.pixelDistance.measure(event, geometry.coordinates);\n\n if (distance < this.pointerDistance) {\n nearbySelectionPoint = true;\n }\n });\n\n // TODO: Is there a cleaner way to handle prioritising\n // dragging selection points?\n this.selectionPoints.ids.forEach((id: string) => {\n const geometry = this.store.getGeometryCopy<Point>(id);\n const distance = this.pixelDistance.measure(event, geometry.coordinates);\n if (distance < this.pointerDistance) {\n nearbySelectionPoint = false;\n }\n });\n if (nearbySelectionPoint) {\n this.setCursor(\"crosshair\");\n } else {\n this.setCursor(\"unset\");\n }\n }\n\n styleFeature(\n feature: GeoJSONStoreFeatures\n ): TerraDrawAdapterStyling {\n\n const styles = { ...getDefaultStyling() };\n\n\n if (feature.properties.mode === this.mode) {\n if (feature.geometry.type === 'Polygon') {\n if (this.styles.selectedColor) {\n styles.polygonFillColor = this.styles.selectedColor;\n }\n if (this.styles.selectedColor) {\n styles.polygonOutlineColor = this.styles.selectedColor;\n }\n styles.zIndex = 10;\n return styles;\n }\n\n if (feature.geometry.type === 'Point') {\n if (feature.properties.selectionPoint) {\n styles.pointColor = this.styles.selectionPointColor || styles.pointColor;\n styles.pointOutlineColor = this.styles.selectionPointOutlineColor || styles.pointOutlineColor;\n styles.pointWidth = this.styles.selectionPointWidth || styles.pointWidth;\n styles.pointOutlineWidth = this.styles.midPointOutlineWidth || 2;\n styles.zIndex = 30;\n\n return styles;\n }\n\n if (feature.properties.midPoint) {\n styles.pointColor = this.styles.midPointColor || styles.pointColor;\n styles.pointOutlineColor = this.styles.midPointOutlineColor || styles.pointOutlineColor;\n styles.pointWidth = this.styles.midPointWidth || 4;\n styles.pointOutlineWidth = this.styles.midPointOutlineWidth || 2;\n styles.zIndex = 40;\n\n return styles;\n }\n\n }\n }\n\n\n return styles;\n }\n}\n","import { TerraDrawAdapterStyling } from \"../../common\";\nimport { getDefaultStyling } from \"../../util/styling\";\nimport { TerraDrawBaseDrawMode } from \"../base.mode\";\n\n// eslint-disable-next-line @typescript-eslint/ban-types\ntype StaticModeStylingExt<T extends TerraDrawAdapterStyling> = {}\ntype StaticModeStyling = StaticModeStylingExt<TerraDrawAdapterStyling>\n\nexport class TerraDrawStaticMode extends TerraDrawBaseDrawMode<StaticModeStyling> {\n mode = \"static\";\n start() { }\n stop() { }\n onKeyUp() { }\n onKeyDown() { }\n onClick() { }\n onDragStart() { }\n onDrag() { }\n onDragEnd() { }\n onMouseMove() { }\n styleFeature() {\n return { ...getDefaultStyling() };\n }\n}\n","export const uuid4 = function (): string {\n return \"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx\".replace(/[xy]/g, function (c) {\n const r = (Math.random() * 16) | 0,\n v = c == \"x\" ? r : (r & 0x3) | 0x8;\n return v.toString(16);\n });\n};\n","// ISC License\n// Copyright (c) 2018, Vladimir Agafonkin\n\nexport type CompareFunction<T> = (a: T, b: T) => number;\n\nexport function quickselect<T>(\n arr: T[],\n k: number,\n left: number,\n right: number,\n compare: CompareFunction<T>\n) {\n while (right > left) {\n if (right - left > 600) {\n const n = right - left + 1;\n const m = k - left + 1;\n const z = Math.log(n);\n const s = 0.5 * Math.exp((2 * z) / 3);\n const sd =\n 0.5 * Math.sqrt((z * s * (n - s)) / n) * (m - n / 2 < 0 ? -1 : 1);\n const newLeft = Math.max(left, Math.floor(k - (m * s) / n + sd));\n const newRight = Math.min(right, Math.floor(k + ((n - m) * s) / n + sd));\n quickselect(arr, k, newLeft, newRight, compare);\n }\n\n const t = arr[k];\n let i = left;\n let j = right;\n\n swap(arr, left, k);\n if (compare(arr[right], t) > 0) swap(arr, left, right);\n\n while (i < j) {\n swap(arr, i, j);\n i++;\n j--;\n while (compare(arr[i], t) < 0) i++;\n while (compare(arr[j], t) > 0) j--;\n }\n\n if (compare(arr[left], t) === 0) {\n swap(arr, left, j);\n } else {\n j++;\n swap(arr, j, right);\n }\n\n if (j <= k) left = j + 1;\n if (k <= j) right = j - 1;\n }\n}\n\nfunction swap<T>(arr: T[], i: number, j: number) {\n const tmp = arr[i];\n arr[i] = arr[j];\n arr[j] = tmp;\n}\n","// Base on Rbush - https://github.com/mourner/rbush\n// MIT License\n// Copyright (c) 2016 Vladimir Agafonkin\n\nimport { CompareFunction, quickselect } from \"./quickselect\";\n\nexport type Node = {\n children: Node[];\n height: number;\n leaf: boolean;\n minX: number;\n minY: number;\n maxX: number;\n maxY: number;\n};\n\n// calculate node's bbox from bboxes of its children\nfunction calcBBox(node: Node, toBBox: (node: Node) => any) {\n distBBox(node, 0, node.children.length, toBBox, node);\n}\n\n// min bounding rectangle of node children from k to p-1\nfunction distBBox(\n node: Node,\n k: number,\n p: number,\n toBBox: (node: Node) => Node,\n destNode?: Node\n) {\n if (!destNode) destNode = createNode([]);\n destNode.minX = Infinity;\n destNode.minY = Infinity;\n destNode.maxX = -Infinity;\n destNode.maxY = -Infinity;\n\n for (let i = k; i < p; i++) {\n const child = node.children[i];\n extend(destNode, node.leaf ? toBBox(child) : child);\n }\n\n return destNode;\n}\n\nfunction extend(a: Node, b: Node) {\n a.minX = Math.min(a.minX, b.minX);\n a.minY = Math.min(a.minY, b.minY);\n a.maxX = Math.max(a.maxX, b.maxX);\n a.maxY = Math.max(a.maxY, b.maxY);\n return a;\n}\n\nfunction compareNodeMinX(a: Node, b: Node) {\n return a.minX - b.minX;\n}\nfunction compareNodeMinY(a: Node, b: Node) {\n return a.minY - b.minY;\n}\n\nfunction bboxArea(a: Node) {\n return (a.maxX - a.minX) * (a.maxY - a.minY);\n}\nfunction bboxMargin(a: {\n minX: number;\n minY: number;\n maxX: number;\n maxY: number;\n}) {\n return a.maxX - a.minX + (a.maxY - a.minY);\n}\n\nfunction enlargedArea(a: Node, b: Node) {\n return (\n (Math.max(b.maxX, a.maxX) - Math.min(b.minX, a.minX)) *\n (Math.max(b.maxY, a.maxY) - Math.min(b.minY, a.minY))\n );\n}\n\nfunction intersectionArea(a: Node, b: Node) {\n const minX = Math.max(a.minX, b.minX);\n const minY = Math.max(a.minY, b.minY);\n const maxX = Math.min(a.maxX, b.maxX);\n const maxY = Math.min(a.maxY, b.maxY);\n\n return Math.max(0, maxX - minX) * Math.max(0, maxY - minY);\n}\n\nfunction contains(a: Node, b: Node) {\n return (\n a.minX <= b.minX && a.minY <= b.minY && b.maxX <= a.maxX && b.maxY <= a.maxY\n );\n}\n\nfunction intersects(a: Node, b: Node) {\n return (\n b.minX <= a.maxX && b.minY <= a.maxY && b.maxX >= a.minX && b.maxY >= a.minY\n );\n}\n\nfunction createNode(children: Node[]) {\n return {\n children,\n height: 1,\n leaf: true,\n minX: Infinity,\n minY: Infinity,\n maxX: -Infinity,\n maxY: -Infinity,\n };\n}\n\n// sort an array so that items come in groups of n unsorted items, with groups sorted between each other;\n// combines selection algorithm with binary divide & conquer approach\n\nfunction multiSelect<T>(\n arr: T[],\n left: number,\n right: number,\n n: number,\n compare: CompareFunction<T>\n) {\n const stack = [left, right];\n\n while (stack.length) {\n right = stack.pop() as number;\n left = stack.pop() as number;\n\n if (right - left <= n) continue;\n\n const mid = left + Math.ceil((right - left) / n / 2) * n;\n quickselect(arr, mid, left, right, compare);\n\n stack.push(left, mid, mid, right);\n }\n}\n\nexport class RBush {\n private _maxEntries: number;\n private _minEntries: number;\n private data!: Node;\n\n constructor(maxEntries: number) {\n // max entries in a node is 9 by default; min node fill is 40% for best performance\n this._maxEntries = Math.max(4, maxEntries);\n this._minEntries = Math.max(2, Math.ceil(this._maxEntries * 0.4));\n this.clear();\n }\n\n search(bbox: Node): Node[] {\n let node = this.data;\n const result: Node[] = [];\n\n if (!intersects(bbox, node)) {\n return result;\n }\n\n const toBBox = this.toBBox;\n const nodesToSearch = [];\n\n while (node) {\n for (let i = 0; i < node.children.length; i++) {\n const child = node.children[i];\n const childBBox = node.leaf ? toBBox(child) : child;\n\n if (intersects(bbox, childBBox)) {\n if (node.leaf) result.push(child);\n else if (contains(bbox, childBBox)) this._all(child, result);\n else nodesToSearch.push(child);\n }\n }\n node = nodesToSearch.pop() as Node;\n }\n\n return result;\n }\n\n collides(bbox: Node) {\n let node = this.data;\n\n const intersect = intersects(bbox, node);\n if (intersect) {\n const nodesToSearch = [];\n while (node) {\n for (let i = 0; i < node.children.length; i++) {\n const child = node.children[i];\n const childBBox = node.leaf ? this.toBBox(child) : child;\n\n if (intersects(bbox, childBBox)) {\n if (node.leaf || contains(bbox, childBBox)) {\n return true;\n }\n nodesToSearch.push(child);\n }\n }\n node = nodesToSearch.pop() as Node;\n }\n }\n\n return false;\n }\n\n load(data: Node[]): void {\n if (data.length < this._minEntries) {\n for (let i = 0; i < data.length; i++) {\n this.insert(data[i]);\n }\n return;\n }\n\n // recursively build the tree with the given data from scratch using OMT algorithm\n let node = this._build(data.slice(), 0, data.length - 1, 0);\n\n if (!this.data.children.length) {\n // save as is if tree is empty\n this.data = node;\n } else if (this.data.height === node.height) {\n // split root if trees have the same height\n this._splitRoot(this.data, node);\n } else {\n if (this.data.height < node.height) {\n // swap trees if inserted one is bigger\n const tmpNode = this.data;\n this.data = node;\n node = tmpNode;\n }\n\n // insert the small tree into the large tree at appropriate level\n this._insert(node, this.data.height - node.height - 1, true);\n }\n }\n\n insert(item: Node): void {\n this._insert(item, this.data.height - 1);\n }\n\n clear(): void {\n this.data = createNode([]);\n }\n\n remove(item: Node): void {\n let node: Node | null = this.data;\n const bbox = this.toBBox(item);\n const path = [];\n const indexes: number[] = [];\n let i: number | undefined;\n let parent: Node | undefined;\n let goingUp = false;\n\n // depth-first iterative tree traversal\n while (node || path.length) {\n if (!node) {\n // go up\n node = path.pop() as Node;\n parent = path[path.length - 1];\n i = indexes.pop() as number;\n goingUp = true;\n }\n\n if (node.leaf) {\n // check current node\n\n const index = node.children.indexOf(item);\n\n if (index !== -1) {\n // item found, remove the item and condense tree upwards\n node.children.splice(index, 1);\n path.push(node);\n this._condense(path);\n }\n }\n\n if (!goingUp && !node.leaf && contains(node, bbox)) {\n // go down\n path.push(node);\n indexes.push(i as number);\n i = 0;\n parent = node;\n node = node.children[0];\n } else if (parent) {\n // go right\n (i as number)++;\n node = parent.children[i as number];\n goingUp = false;\n } else {\n node = null; // nothing found\n }\n }\n }\n\n private toBBox<T>(item: T): T {\n return item;\n }\n\n private compareMinX(a: Node, b: Node) {\n return a.minX - b.minX;\n }\n private compareMinY(a: Node, b: Node) {\n return a.minY - b.minY;\n }\n\n private _all(node: Node, result: Node[]) {\n const nodesToSearch = [];\n while (node) {\n if (node.leaf) result.push(...node.children);\n else nodesToSearch.push(...node.children);\n\n node = nodesToSearch.pop() as Node;\n }\n return result;\n }\n\n private _build(items: Node[], left: number, right: number, height: number) {\n const N = right - left + 1;\n let M = this._maxEntries;\n let node;\n\n if (N <= M) {\n // reached leaf level; return leaf\n node = createNode(items.slice(left, right + 1));\n calcBBox(node, this.toBBox);\n return node;\n }\n\n if (!height) {\n // target height of the bulk-loaded tree\n height = Math.ceil(Math.log(N) / Math.log(M));\n\n // target number of root entries to maximize storage utilization\n M = Math.ceil(N / Math.pow(M, height - 1));\n }\n\n node = createNode([]);\n node.leaf = false;\n node.height = height;\n\n // split the items into M mostly square tiles\n\n const N2 = Math.ceil(N / M);\n const N1 = N2 * Math.ceil(Math.sqrt(M));\n\n multiSelect(items, left, right, N1, this.compareMinX);\n\n for (let i = left; i <= right; i += N1) {\n const right2 = Math.min(i + N1 - 1, right);\n\n multiSelect(items, i, right2, N2, this.compareMinY);\n\n for (let j = i; j <= right2; j += N2) {\n const right3 = Math.min(j + N2 - 1, right2);\n\n // pack each entry recursively\n node.children.push(this._build(items, j, right3, height - 1));\n }\n }\n\n calcBBox(node, this.toBBox);\n\n return node;\n }\n\n private _chooseSubtree(bbox: Node, node: Node, level: number, path: Node[]) {\n while (true) {\n path.push(node);\n\n if (node.leaf || path.length - 1 === level) {\n break;\n }\n\n let minArea = Infinity;\n let minEnlargement = Infinity;\n let targetNode;\n\n for (let i = 0; i < node.children.length; i++) {\n const child = node.children[i];\n\n const area = bboxArea(child);\n const enlargement = enlargedArea(bbox, child) - area;\n\n // choose entry with the least area enlargement\n\n if (enlargement < minEnlargement) {\n minEnlargement = enlargement;\n minArea = area < minArea ? area : minArea;\n targetNode = child;\n } else if (enlargement === minEnlargement) {\n // otherwise choose one with the smallest area\n if (area < minArea) {\n minArea = area;\n targetNode = child;\n }\n }\n }\n\n node = targetNode || node.children[0];\n }\n\n return node;\n }\n\n private _insert(item: Node, level: number, isNode?: boolean) {\n const bbox = isNode ? item : this.toBBox(item);\n const insertPath: Node[] = [];\n\n // find the best node for accommodating the item, saving all nodes along the path too\n const node = this._chooseSubtree(bbox, this.data, level, insertPath);\n\n // put the item into the node\n node.children.push(item);\n extend(node, bbox);\n\n // split on node overflow; propagate upwards if necessary\n while (level >= 0) {\n if (insertPath[level].children.length > this._maxEntries) {\n this._split(insertPath, level);\n level--;\n } else break;\n }\n\n // adjust bboxes along the insertion path\n this._adjustParentBBoxes(bbox, insertPath, level);\n }\n\n // split overflowed node into two\n private _split(insertPath: Node[], level: number) {\n const node = insertPath[level];\n const M = node.children.length;\n const m = this._minEntries;\n\n this._chooseSplitAxis(node, m, M);\n\n const splitIndex = this._chooseSplitIndex(node, m, M);\n\n const newNode = createNode(\n node.children.splice(splitIndex, node.children.length - splitIndex)\n );\n newNode.height = node.height;\n newNode.leaf = node.leaf;\n\n calcBBox(node, this.toBBox);\n calcBBox(newNode, this.toBBox);\n\n if (level) insertPath[level - 1].children.push(newNode);\n else this._splitRoot(node, newNode);\n }\n\n private _splitRoot(node: Node, newNode: Node) {\n // split root node\n this.data = createNode([node, newNode]);\n this.data.height = node.height + 1;\n this.data.leaf = false;\n calcBBox(this.data, this.toBBox);\n }\n\n private _chooseSplitIndex(node: Node, m: number, M: number) {\n let index;\n let minOverlap = Infinity;\n let minArea = Infinity;\n\n for (let i = m; i <= M - m; i++) {\n const bbox1 = distBBox(node, 0, i, this.toBBox);\n const bbox2 = distBBox(node, i, M, this.toBBox);\n\n const overlap = intersectionArea(bbox1, bbox2);\n const area = bboxArea(bbox1) + bboxArea(bbox2);\n\n // choose distribution with minimum overlap\n if (overlap < minOverlap) {\n minOverlap = overlap;\n index = i;\n\n minArea = area < minArea ? area : minArea;\n } else if (overlap === minOverlap) {\n // otherwise choose distribution with minimum area\n if (area < minArea) {\n minArea = area;\n index = i;\n }\n }\n }\n\n return index || M - m;\n }\n\n // sorts node children by the best axis for split\n private _chooseSplitAxis(node: Node, m: number, M: number) {\n const compareMinX = node.leaf ? this.compareMinX : compareNodeMinX;\n const compareMinY = node.leaf ? this.compareMinY : compareNodeMinY;\n const xMargin = this._allDistMargin(node, m, M, compareMinX);\n const yMargin = this._allDistMargin(node, m, M, compareMinY);\n\n // if total distributions margin value is minimal for x, sort by minX,\n // otherwise it's already sorted by minY\n if (xMargin < yMargin) {\n node.children.sort(compareMinX);\n }\n }\n\n // total margin of all possible split distributions where each node is at least m full\n private _allDistMargin(\n node: Node,\n m: number,\n M: number,\n compare: CompareFunction<Node>\n ) {\n node.children.sort(compare);\n\n const toBBox = this.toBBox;\n const leftBBox = distBBox(node, 0, m, toBBox);\n const rightBBox = distBBox(node, M - m, M, toBBox);\n let margin = bboxMargin(leftBBox) + bboxMargin(rightBBox);\n\n for (let i = m; i < M - m; i++) {\n const child = node.children[i];\n extend(leftBBox, node.leaf ? toBBox(child) : child);\n margin += bboxMargin(leftBBox);\n }\n\n for (let i = M - m - 1; i >= m; i--) {\n const child = node.children[i];\n extend(rightBBox, node.leaf ? toBBox(child) : child);\n margin += bboxMargin(rightBBox);\n }\n\n return margin;\n }\n\n private _adjustParentBBoxes(bbox: Node, path: Node[], level: number) {\n // adjust bboxes along the given tree path\n for (let i = level; i >= 0; i--) {\n extend(path[i], bbox);\n }\n }\n\n private _condense(path: Node[]) {\n // go through the path, removing empty nodes and updating bboxes\n for (let i = path.length - 1, siblings; i >= 0; i--) {\n if (path[i].children.length === 0) {\n if (i > 0) {\n siblings = path[i - 1].children;\n siblings.splice(siblings.indexOf(path[i]), 1);\n } else this.clear();\n } else {\n calcBBox(path[i], this.toBBox);\n }\n }\n }\n}\n","import { Position } from \"geojson\";\nimport { GeoJSONStoreFeatures } from \"../store\";\nimport { RBush, Node } from \"./rbush\";\n\nexport class SpatialIndex {\n private tree: RBush;\n private idToNode: Map<string, Node>;\n private nodeToId: Map<Node, string>;\n\n constructor(options?: { maxEntries: number }) {\n this.tree = new RBush(\n options && options.maxEntries ? options.maxEntries : 9\n );\n this.idToNode = new Map();\n this.nodeToId = new Map();\n }\n\n private setMaps(feature: GeoJSONStoreFeatures, bbox: Node) {\n this.idToNode.set(String(feature.id), bbox);\n this.nodeToId.set(bbox, String(feature.id));\n }\n\n private toBBox(feature: GeoJSONStoreFeatures) {\n const longitudes: number[] = [];\n const latitudes: number[] = [];\n\n let coordinates: Position[];\n if (feature.geometry.type === \"Polygon\") {\n coordinates = feature.geometry.coordinates[0];\n } else if (feature.geometry.type === \"LineString\") {\n coordinates = feature.geometry.coordinates;\n } else if (feature.geometry.type === \"Point\") {\n coordinates = [feature.geometry.coordinates];\n } else {\n throw new Error(\"Not a valid feature to turn into a bounding box\");\n }\n\n for (let i = 0; i < coordinates.length; i++) {\n latitudes.push(coordinates[i][1]);\n longitudes.push(coordinates[i][0]);\n }\n\n const minLat = Math.min(...latitudes);\n const maxLat = Math.max(...latitudes);\n const minLng = Math.min(...longitudes);\n const maxLng = Math.max(...longitudes);\n\n return {\n minX: minLng,\n minY: minLat,\n maxX: maxLng,\n maxY: maxLat,\n } as Node;\n }\n\n insert(feature: GeoJSONStoreFeatures): void {\n if (this.idToNode.get(String(feature.id))) {\n throw new Error(\"Feature already exists\");\n }\n const bbox = this.toBBox(feature);\n this.setMaps(feature, bbox);\n this.tree.insert(bbox);\n }\n\n load(features: GeoJSONStoreFeatures[]): void {\n const load: Node[] = [];\n const seenIds: Set<string> = new Set();\n features.forEach((feature) => {\n const bbox = this.toBBox(feature);\n this.setMaps(feature, bbox);\n if (seenIds.has(String(feature.id))) {\n throw new Error(`Duplicate feature ID found ${feature.id}`);\n }\n seenIds.add(String(feature.id));\n load.push(bbox);\n });\n this.tree.load(load);\n }\n\n update(feature: GeoJSONStoreFeatures): void {\n this.remove(feature.id as string);\n const bbox = this.toBBox(feature);\n this.setMaps(feature, bbox);\n this.tree.insert(bbox);\n }\n\n remove(featureId: string): void {\n const node = this.idToNode.get(featureId);\n if (!node) {\n throw new Error(`${featureId} not inserted into the spatial index`);\n }\n\n this.tree.remove(node);\n }\n\n clear(): void {\n this.tree.clear();\n }\n\n search(feature: GeoJSONStoreFeatures): string[] {\n const found = this.tree.search(this.toBBox(feature));\n return found.map((node) => {\n return this.nodeToId.get(node) as string;\n });\n }\n\n collides(feature: GeoJSONStoreFeatures): boolean {\n return this.tree.collides(this.toBBox(feature));\n }\n}\n","import { Feature, Point, Polygon, LineString } from \"geojson\";\nimport { uuid4 } from \"../util/id\";\nimport { SpatialIndex } from \"./spatial-index/spatial-index\";\n\ntype JSON = string | number | boolean | null | JSONArray | JSONObject;\n\nexport interface JSONObject {\n [member: string]: JSON;\n}\ntype JSONArray = Array<JSON>;\n\ntype DefinedProperties = Record<string, JSON>;\n\nexport type GeoJSONStoreGeometries = Polygon | LineString | Point;\n\nexport type BBoxPolygon = Feature<Polygon, DefinedProperties>;\n\nexport type GeoJSONStoreFeatures = Feature<\n GeoJSONStoreGeometries,\n DefinedProperties\n>;\n\nexport type StoreChangeEvents = \"delete\" | \"create\" | \"update\";\n\nexport type StoreChangeHandler = (\n ids: string[],\n change: StoreChangeEvents\n) => void;\n\nexport type GeoJSONStoreConfig = {\n data?: GeoJSONStoreFeatures[];\n tracked?: boolean;\n validateFeature?: (feature: unknown, tracked?: boolean) => void;\n};\n\nexport class GeoJSONStore {\n constructor(config?: GeoJSONStoreConfig) {\n this.store = {};\n this.spatialIndex = new SpatialIndex();\n\n // Setting tracked has to happen first\n // because we use it in featureValidation\n this.tracked = config && config.tracked === false ? false : true;\n\n if (config && config.data) {\n this.load(config.data, config.validateFeature);\n }\n }\n\n private tracked: boolean;\n\n private spatialIndex: SpatialIndex;\n\n private store: {\n [key: string]: GeoJSONStoreFeatures;\n };\n\n // Default to no-op\n private _onChange: StoreChangeHandler = () => {};\n\n private getId(): string {\n return uuid4();\n }\n\n private clone<T>(obj: T): T {\n return JSON.parse(JSON.stringify(obj));\n }\n\n has(id: string): boolean {\n return Boolean(this.store[id]);\n }\n\n load(\n data: GeoJSONStoreFeatures[],\n featureValidation?: (feature: unknown, tracked?: boolean) => void\n ) {\n if (data.length === 0) {\n return;\n }\n\n // We don't want to update the original data\n const clonedData = this.clone(data);\n\n // We try to be a bit forgiving here as many users\n // may not set a feature id as UUID or createdAt/updatedAt\n clonedData.forEach((feature) => {\n if (!feature.id) {\n feature.id = uuid4();\n }\n\n if (this.tracked) {\n if (!feature.properties.createdAt) {\n feature.properties.createdAt = +new Date();\n }\n\n if (!feature.properties.updatedAt) {\n feature.properties.updatedAt = +new Date();\n }\n }\n });\n\n const changes: string[] = [];\n clonedData.forEach((feature) => {\n if (featureValidation) {\n featureValidation(feature);\n }\n this.store[feature.id as string] = feature;\n changes.push(feature.id as string);\n });\n this.spatialIndex.load(clonedData);\n this._onChange(changes, \"create\");\n }\n\n search(\n bbox: BBoxPolygon,\n filter?: (feature: GeoJSONStoreFeatures) => boolean\n ) {\n const features = this.spatialIndex.search(bbox).map((id) => this.store[id]);\n if (filter) {\n return this.clone(features.filter(filter));\n } else {\n return this.clone(features);\n }\n }\n\n registerOnChange(onChange: StoreChangeHandler) {\n this._onChange = (ids, change) => {\n onChange(ids, change);\n };\n }\n\n getGeometryCopy<T extends GeoJSONStoreGeometries>(id: string): T {\n const feature = this.store[id];\n if (!feature) {\n throw new Error(\n `No feature with this id (${id}), can not get geometry copy`\n );\n }\n return this.clone(feature.geometry as T);\n }\n\n getPropertiesCopy(id: string) {\n const feature = this.store[id];\n if (!feature) {\n throw new Error(\n `No feature with this id (${id}), can not get properties copy`\n );\n }\n return this.clone(feature.properties);\n }\n\n updateProperty(\n propertiesToUpdate: { id: string; property: string; value: JSON }[]\n ): void {\n const ids: string[] = [];\n propertiesToUpdate.forEach(({ id, property, value }) => {\n const feature = this.store[id];\n\n if (!feature) {\n throw new Error(\n `No feature with this (${id}), can not update geometry`\n );\n }\n\n ids.push(id);\n\n feature.properties[property] = value;\n\n // Update the time the feature was updated\n if (this.tracked) {\n feature.properties.updatedAt = +new Date();\n }\n });\n\n if (this._onChange) {\n this._onChange(ids, \"update\");\n }\n }\n\n updateGeometry(\n geometriesToUpdate: { id: string; geometry: GeoJSONStoreGeometries }[]\n ): void {\n const ids: string[] = [];\n geometriesToUpdate.forEach(({ id, geometry }) => {\n ids.push(id);\n\n const feature = this.store[id];\n\n if (!feature) {\n throw new Error(\n `No feature with this (${id}), can not update geometry`\n );\n }\n\n feature.geometry = this.clone(geometry);\n\n this.spatialIndex.update(feature);\n\n // Update the time the feature was updated\n if (this.tracked) {\n feature.properties.updatedAt = +new Date();\n }\n });\n\n if (this._onChange) {\n this._onChange(ids, \"update\");\n }\n }\n\n create(\n features: {\n geometry: GeoJSONStoreGeometries;\n properties?: JSONObject;\n }[]\n ): string[] {\n const ids: string[] = [];\n features.forEach(({ geometry, properties }) => {\n let createdAt;\n let createdProperties = { ...properties };\n\n if (this.tracked) {\n createdAt = +new Date();\n\n if (properties) {\n createdProperties.createdAt =\n typeof properties.createdAt === \"number\"\n ? properties.createdAt\n : createdAt;\n createdProperties.updatedAt =\n typeof properties.updatedAt === \"number\"\n ? properties.updatedAt\n : createdAt;\n } else {\n createdProperties = { createdAt, updatedAt: createdAt };\n }\n }\n\n const id = this.getId();\n const feature = {\n id,\n type: \"Feature\",\n geometry,\n properties: createdProperties,\n } as GeoJSONStoreFeatures;\n\n this.store[id] = feature;\n this.spatialIndex.insert(feature);\n\n ids.push(id);\n });\n\n if (this._onChange) {\n this._onChange([...ids], \"create\");\n }\n\n return ids;\n }\n\n delete(ids: string[]): void {\n ids.forEach((id) => {\n if (this.store[id]) {\n delete this.store[id];\n this.spatialIndex.remove(id as string);\n } else {\n throw new Error(\"No feature with this id, can not delete\");\n }\n });\n\n if (this._onChange) {\n this._onChange([...ids], \"delete\");\n }\n }\n\n copyAll(): GeoJSONStoreFeatures[] {\n return this.clone(Object.keys(this.store).map((id) => this.store[id]));\n }\n}\n","import { TerraDrawGoogleMapsAdapter } from \"./adapters/google-maps.adapter\";\nimport { TerraDrawLeafletAdapter } from \"./adapters/leaflet.adapter\";\nimport { TerraDrawMapboxGLAdapter } from \"./adapters/mapbox-gl.adapter\";\nimport {\n TerraDrawMode,\n TerraDrawAdapter,\n TerraDrawAdapterStyling,\n} from \"./common\";\nimport { TerraDrawCircleMode } from \"./modes/circle/circle.mode\";\nimport { TerraDrawFreehandMode } from \"./modes/freehand/freehand.mode\";\nimport { TerraDrawLineStringMode } from \"./modes/linestring/linestring.mode\";\nimport { TerraDrawPointMode } from \"./modes/point/point.mode\";\nimport { TerraDrawPolygonMode } from \"./modes/polygon/polygon.mode\";\nimport { TerraDrawRenderMode } from \"./modes/render/render.mode\";\nimport { TerraDrawSelectMode } from \"./modes/select/select.mode\";\nimport { TerraDrawStaticMode } from \"./modes/static/static.mode\";\nimport {\n GeoJSONStore,\n GeoJSONStoreFeatures,\n StoreChangeHandler,\n} from \"./store/store\";\n\ntype ChangeListener = (ids: string[], type: string) => void;\ntype SelectListener = (id: string) => void;\ntype DeselectListener = () => void;\n\ninterface TerraDrawEventListeners {\n change: ChangeListener;\n select: SelectListener;\n deselect: DeselectListener;\n}\n\ntype TerraDrawEvents = keyof TerraDrawEventListeners;\n\nclass TerraDraw {\n private _modes: { [mode: string]: TerraDrawMode };\n private _mode: TerraDrawMode;\n private _adapter: TerraDrawAdapter;\n private _enabled = false;\n private _store: GeoJSONStore;\n private _eventListeners: {\n change: ChangeListener[];\n select: SelectListener[];\n deselect: DeselectListener[];\n };\n\n constructor(options: {\n adapter: TerraDrawAdapter;\n modes: { [mode: string]: TerraDrawMode };\n data?: GeoJSONStoreFeatures[];\n }) {\n this._adapter = options.adapter;\n this._mode = new TerraDrawStaticMode();\n this._modes = { ...options.modes, static: this._mode };\n this._eventListeners = { change: [], select: [], deselect: [] };\n\n if (options.data) {\n this._store = new GeoJSONStore({ data: options.data });\n } else {\n this._store = new GeoJSONStore();\n }\n\n const getChanged = (\n ids: string[]\n ): {\n changed: GeoJSONStoreFeatures[];\n unchanged: GeoJSONStoreFeatures[];\n } => {\n const changed: GeoJSONStoreFeatures[] = [];\n\n const unchanged = this._store.copyAll().filter((f) => {\n if (ids.includes(f.id as string)) {\n changed.push(f);\n return false;\n }\n\n return true;\n });\n\n return { changed, unchanged };\n };\n\n const onChange: StoreChangeHandler = (ids, event) => {\n this._eventListeners.change.forEach((listener) => {\n listener(ids, event);\n });\n\n const { changed, unchanged } = getChanged(ids);\n\n if (event === \"create\") {\n this._adapter.render(\n {\n created: changed,\n deletedIds: [],\n unchanged,\n updated: []\n },\n this.getModeStyles()\n );\n } else if (event === \"update\") {\n this._adapter.render(\n {\n created: [],\n deletedIds: [],\n unchanged,\n updated: changed,\n },\n this.getModeStyles()\n );\n } else if (event === \"delete\") {\n this._adapter.render(\n { created: [], deletedIds: ids, unchanged, updated: [] },\n this.getModeStyles()\n );\n } else if (event === \"styling\") {\n this._adapter.render(\n { created: [], deletedIds: [], unchanged, updated: [] },\n this.getModeStyles()\n );\n }\n };\n\n const onSelect = (selectedId: string) => {\n this._eventListeners.select.forEach((listener) => {\n listener(selectedId);\n });\n\n const { changed, unchanged } = getChanged([selectedId]);\n\n this._adapter.render(\n { created: [], deletedIds: [], unchanged, updated: changed },\n this.getModeStyles()\n );\n };\n\n const onDeselect = (deselectedId: string) => {\n this._eventListeners.deselect.forEach((listener) => {\n listener();\n });\n\n const { changed, unchanged } = getChanged([deselectedId]);\n\n // onDeselect can be called after a delete call which means that\n // you are deselecting a feature that has been deleted. We\n // double check here to ensure that the feature still exists.\n if (changed) {\n this._adapter.render(\n {\n created: [],\n deletedIds: [],\n unchanged,\n updated: changed,\n },\n this.getModeStyles()\n );\n }\n };\n\n // Register stores and callbacks\n Object.keys(this._modes).forEach((modeId) => {\n this._modes[modeId].register({\n mode: modeId,\n store: this._store,\n setCursor: this._adapter.setCursor,\n project: this._adapter.project,\n unproject: this._adapter.unproject,\n onChange: onChange,\n onSelect: onSelect,\n onDeselect: onDeselect,\n });\n });\n\n // If we pass in data, we want to render it on startup\n if (options.data) {\n // Remove all non mode features\n const initialRender = this._store.copyAll().filter((feature) => {\n if (\n feature.properties &&\n !Object.keys(this._modes).includes(feature.properties.mode as string)\n ) {\n this._store.delete([feature.id as string]);\n return false;\n }\n return true;\n });\n\n this._adapter.render(\n {\n created: initialRender,\n deletedIds: [],\n unchanged: [],\n updated: [],\n },\n this.getModeStyles()\n );\n }\n }\n\n private getModeStyles() {\n const modeStyles: { [key: string]: (feature: GeoJSONStoreFeatures) => TerraDrawAdapterStyling } = {};\n Object.keys(this._modes).forEach((mode) => {\n modeStyles[mode] = this._modes[mode].styleFeature.bind(this._modes[mode]);\n });\n return modeStyles;\n }\n\n setModeStyles(mode: string, styles: TerraDrawAdapterStyling) {\n this._modes[mode].styles = styles;\n }\n\n getSnapshot() {\n return this._store.copyAll();\n }\n\n get enabled(): boolean {\n return this._enabled;\n }\n\n set enabled(_) {\n throw new Error(\"Enabled is read only\");\n }\n\n getCurrentMode(): string {\n return this._mode.mode;\n }\n\n changeMode(mode: string) {\n if (this._modes[mode]) {\n // Before we swap modes we want to\n // clean up any state that has been left behind,\n // for example current drawing geometries\n // and mode state\n this._mode.stop();\n\n // Swap the mode to the new mode\n this._mode = this._modes[mode];\n\n // Start the new mode\n this._mode.start();\n } else {\n // If the mode doesn't exist, we throw an error\n throw new Error(\"No mode with this name present\");\n }\n }\n\n start() {\n this._enabled = true;\n this._adapter.register({\n onClick: (event) => {\n this._mode.onClick(event);\n },\n onMouseMove: (event) => {\n this._mode.onMouseMove(event);\n },\n onKeyDown: (event) => {\n this._mode.onKeyDown(event);\n },\n onKeyUp: (event) => {\n this._mode.onKeyUp(event);\n },\n onDragStart: (event, setMapDraggability) => {\n this._mode.onDragStart(event, setMapDraggability);\n },\n onDrag: (event) => {\n this._mode.onDrag(event);\n },\n onDragEnd: (event, setMapDraggability) => {\n this._mode.onDragEnd(event, setMapDraggability);\n },\n });\n }\n\n stop() {\n this._enabled = false;\n this._adapter.unregister();\n }\n\n on<T extends TerraDrawEvents>(\n event: T,\n callback: TerraDrawEventListeners[T]\n ) {\n const listeners = this._eventListeners[\n event\n ] as TerraDrawEventListeners[T][];\n if (!listeners.includes(callback)) {\n listeners.push(callback);\n }\n }\n\n off<T extends TerraDrawEvents>(\n event: TerraDrawEvents,\n callback: TerraDrawEventListeners[T]\n ) {\n const listeners = this._eventListeners[\n event\n ] as TerraDrawEventListeners[T][];\n if (listeners.includes(callback)) {\n listeners.splice(listeners.indexOf(callback), 1);\n }\n }\n}\n\nexport {\n TerraDraw,\n TerraDrawSelectMode,\n TerraDrawPointMode,\n TerraDrawLineStringMode,\n TerraDrawPolygonMode,\n TerraDrawCircleMode,\n TerraDrawFreehandMode,\n TerraDrawRenderMode,\n TerraDrawGoogleMapsAdapter,\n TerraDrawMapboxGLAdapter,\n TerraDrawLeafletAdapter,\n};\n"],"names":["limitPrecision","num","decimalLimit","decimals","Math","pow","round","TerraDrawGoogleMapsAdapter","config","_heldKeys","Set","_cursor","_cursorStyleSheet","_coordinatePrecision","_lib","_map","_onMouseMoveListener","_onMouseMoveCallback","_onClickListener","this","_onRightClickListener","_onClickCallback","_onKeyUpListener","_onDragStartListener","_onDragListener","_onDragEndListener","_layers","getMapContainer","unproject","project","setCursor","lib","map","coordinatePrecision","_this","getDiv","lng","lat","bounds","getBounds","undefined","Error","northWest","LatLng","getNorthEast","getSouthWest","projection","getProjection","projectedNorthWest","fromLatLngToPoint","projected","zoom","getZoom","scale","x","floor","y","topRight","bottomLeft","worldPoint","maps","Point","lngLat","fromPointToLatLng","cursor","remove","div","style","document","createElement","type","innerHTML","id","selector","getElementsByTagName","appendChild","_proto","prototype","circlePath","cx","cy","r","register","callbacks","_this2","event","latLng","onClick","containerX","domEvent","clientX","offsetLeft","containerY","clientY","offsetTop","button","heldKeys","concat","addListener","onMouseMove","onKeyUp","key","addEventListener","dragState","container","point","_this2$unproject","drawEvent","onDragStart","enabled","setOptions","draggable","onDrag","_this2$unproject2","onDragEnd","unregister","removeEventListener","render","changes","styling","_this3","deletedIds","forEach","deletedId","featureToDelete","data","getFeatureById","updated","updatedFeature","featureToUpdate","forEachProperty","property","name","setProperty","Object","keys","properties","geometry","coordinates","setGeometry","google","Data","path","i","length","coordinate","push","LineString","_coordinates2","paths","_i","_path","j","Polygon","created","createdFeature","addGeoJson","featureCollection","features","setStyle","feature","mode","getProperty","gmGeometry","getGeometry","getType","value","calculatedStyles","clickable","icon","pointWidth","fillColor","pointColor","fillOpacity","strokeColor","pointOutlineColor","strokeWeight","pointOutlineWidth","rotation","lineStringColor","lineStringWidth","polygonOutlineColor","polygonOutlineWidth","polygonFillOpacity","polygonFillColor","TerraDrawLeafletAdapter","_onKeyDownListener","_layer","_panes","getContainer","_this$_map$latLngToCo","latLngToContainerPoint","_this$_map$containerP","containerPointToLatLng","removeProperty","createPaneStyleSheet","pane","zIndex","createPane","latlng","originalEvent","on","preventDefault","_this2$_map$container","dragging","enable","disable","_this2$_map$container2","add","onKeyDown","off","selectedPane","getPane","_this4","unchanged","removeLayer","geoJSON","pointToLayer","modeStyle","paneId","String","featureStyles","circleMarker","radius","stroke","color","weight","interactive","_feature","addLayer","layer","TerraDrawMapboxGLAdapter","_rendered","_this$_map$project","getCanvas","_addGeoJSONSource","addSource","_addFillLayer","source","filter","paint","_addFillOutlineLayer","beneath","moveLayer","_addLineLayer","_addPointLayer","_addLayer","featureType","_addGeoJSONLayer","toLowerCase","_setGeoJSONLayerData","getSource","setData","_this2$_map$unproject","dragPan","_this2$_map$unproject2","modeFeatures","points","linestrings","polygons","styles","_loop","_modeFeatures$mode","pointId","_frame","cancel","_render","haversineDistanceKilometers","pointOne","pointTwo","toRadians","latOrLng","PI","phiOne","lambdaOne","phiTwo","deltaPhi","a","sin","cos","deltalambda","atan2","sqrt","degreesToRadians","degrees","radiansToDegrees","radians","origin","distance","bearing","longitude1","latitude1","bearingRad","lengthToRadians","earthRadius","latitude2","asin","circle","options","center","radiusKilometers","steps","destination","registerBehaviors","_state","_styles","behaviors","pointerDistance","onStyleChange","store","behaviorConfig","setStarted","setStopped","registerOnChange","onChange","onSelect","onDeselect","deselectedId","selectedId","styleFeature","set","_","TerraDrawBaseDrawMode","TerraDrawCircleMode","_TerraDrawBaseDrawMod","call","clickCount","currentCircleId","keyEvents","_inheritsLoose","start","stop","cleanUp","_this$store$create","create","startingCircle","distanceKm","updatedCircle","updateGeometry","error","_extends","outlineColor","outlineWidth","TerraDrawFreehandMode","startingClick","currentId","skip","everyNthMouseEvent","currentLineGeometry","getGeometryCopy","pop","getDefaultStyling","selfIntersects","coord","ring0","edge0","ring1","edge1","ifInteresctionAddToOutput","output","frac","frac1","start0","end0","start1","end1","equalArrays","x0","y0","x1","y1","x2","y2","x3","y3","denom","intersect","intersection","isOutside","toString","array1","array2","pixelDistance","TerraDrawModeBehavior","_ref","ClickBoundingBoxBehavior","_TerraDrawModeBehavio","halfDist","c","PixelDistanceBehavior","measure","clickEvent","secondCoordinate","_this$project","SnappingBehavior","clickBoundingBox","getSnappableCoordinate","currentFeatureId","getSnappable","Boolean","bbox","search","closest","minDist","Infinity","dist","TerraDrawLineStringMode","currentCoordinate","allowSelfIntersections","snappingEnabled","snapping","snappedCoord","updatedCoord","_currentLineGeometry","_currentLineGeometry$","previousLat","newLineString","TerraDrawPointMode","coordinatesIdentical","coordinateTwo","ClosingPointsBehavior","_startEndPoints","selectedCoords","ids","POLYGON_PROPERTIES","_properties","_properties2","update","updatedCoordinates","isClosingPoint","opening","closing","isClosing","isPreviousClosing","distancePrevious","_createClass","get","TerraDrawPolygonMode","isClosed","closingPoints","closestCoord","currentPolygonCoordinates","epsilon","max","offset","_this$closingPoints$i","slice","currentPolygonGeometry","_currentPolygonCoordinates","_this$closingPoints$i2","updatedPolygon","closingPointWidth","closingPointColor","closingPointOutlineColor","closingPointOutlineWidth","TerraDrawRenderMode","coordinates1","coordinates2","precision","heading","lon2","lat1","lat2","lon1","b","midpoint","getMidPointCoordinates","featureCoords","midPointCoords","mid","midpointCoordinate","MidPointBehavior","selectionPointBehavior","_midPoints","insert","midPointId","midPoint","getPropertiesCopy","midPointFeatureId","midPointSegment","_this$store$getProper","splice","featureId","has","getMidPoints","getUpdated","updatedMidPointCoord","SelectionPointBehavior","_selectionPoints","geometryType","selectionPoints","getCoordinatesAsPoints","selectionPoint","selectionPointFeatureId","index","getOneUpdated","updatedCoordinate","pointInPolygon","rings","p","p1","p2","inside","len","len2","ring","k","linePointOne","linePointTwo","square","dist2","v","w","l2","t","min","distToSegmentSquared","FeaturesAtMouseEventBehavior","createClickBoundingBox","find","hasSelection","clickedFeature","clickedFeatureDistance","clickedMidPoint","clickedMidPointDistance","nextCoord","distanceToLine","pixelDistanceToLine","DragFeatureBehavior","featuresAtMouseEvent","midPoints","dragPosition","drag","mouseCoord","updatedCoords","upToCoord","delta","updatedSelectionPoints","updatedMidPoints","newPosition","Array","isArray","DragCoordinateBehavior","geomCoordinates","closestCoordinate","isFirstOrLastPolygonCoord","lastCoordIndex","updatedSelectionPoint","centroid","geojson","xSum","ySum","rhumbBearing","end","phi1","from","phi2","to","deltaLambda","deltaPsi","log","tan","bear360","distanceMeters","lambda1","theta","DeltaPhi","abs","DeltaPsi","q","rhumbDistance","DeltaLambda","RotateFeatureBehavior","lastBearing","reset","rotate","transformRotate","angle","pivot","pointCoords","finalAngle","newCoords","rhumbDestination","ScaleFeatureBehavior","lastDistance","transformScale","factor","originalDistance","newCoord","TerraDrawSelectMode","dragEventThrottle","dragEventCount","selected","flags","dragFeature","dragCoordinate","rotateFeature","scaleFeature","deselect","delete","updateProperty","deleteSelected","onRightClick","clickedSelectionPointProps","coordinateIndex","modeFlags","deletable","shift","midpoints","onLeftClick","_this$featuresAtMouse","previouslySelectedId","_this$store$getGeomet","setMapDraggability","position","rotateable","includes","scaleable","nearbySelectionPoint","selectedColor","selectionPointColor","selectionPointOutlineColor","selectionPointWidth","midPointOutlineWidth","midPointColor","midPointOutlineColor","midPointWidth","TerraDrawStaticMode","replace","random","quickselect","arr","left","right","compare","n","m","z","exp","s","sd","swap","tmp","node","toBBox","distBBox","children","destNode","createNode","minX","minY","maxX","maxY","extend","leaf","child","compareNodeMinX","compareNodeMinY","bboxArea","bboxMargin","intersects","height","stack","ceil","RBush","maxEntries","_maxEntries","_minEntries","clear","result","nodesToSearch","childBBox","contains","_all","collides","load","_build","_splitRoot","tmpNode","_insert","item","goingUp","parent","indexes","indexOf","_condense","compareMinX","compareMinY","apply","items","M","N","calcBBox","N2","N1","multiSelect","right2","right3","_chooseSubtree","level","minArea","minEnlargement","targetNode","area","enlargement","isNode","insertPath","_split","_adjustParentBBoxes","_chooseSplitAxis","splitIndex","_chooseSplitIndex","newNode","minOverlap","bbox1","overlap","bbox2","_allDistMargin","sort","margin","leftBBox","rightBBox","_child","siblings","SpatialIndex","tree","idToNode","nodeToId","Map","setMaps","longitudes","latitudes","minLat","maxLat","seenIds","GeoJSONStore","tracked","spatialIndex","_onChange","validateFeature","getId","uuid4","clone","obj","JSON","parse","stringify","featureValidation","clonedData","createdAt","updatedAt","Date","change","propertiesToUpdate","geometriesToUpdate","_ref2","_this5","_ref3","createdProperties","_this6","copyAll","_this7","_modes","_mode","_adapter","_enabled","_store","_eventListeners","adapter","modes","static","select","getChanged","changed","f","listener","_getChanged","getModeStyles","_getChanged2","_getChanged3","modeId","initialRender","modeStyles","bind","setModeStyles","getSnapshot","getCurrentMode","changeMode","callback","listeners","TerraDraw"],"mappings":"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"}
1
+ {"version":3,"file":"terra-draw.cjs","sources":["../src/geometry/limit-decimal-precision.ts","../src/adapters/google-maps.adapter.ts","../src/adapters/leaflet.adapter.ts","../src/adapters/mapbox-gl.adapter.ts","../src/geometry/measure/haversine-distance.ts","../src/geometry/helpers.ts","../src/geometry/shape/create-circle.ts","../src/util/styling.ts","../src/modes/base.mode.ts","../src/modes/circle/circle.mode.ts","../src/geometry/measure/pixel-distance.ts","../src/modes/freehand/freehand.mode.ts","../src/geometry/boolean/self-intersects.ts","../src/modes/base.behavior.ts","../src/modes/click-bounding-box.behavior.ts","../src/modes/pixel-distance.behavior.ts","../src/modes/snapping.behavior.ts","../src/modes/linestring/linestring.mode.ts","../src/modes/point/point.mode.ts","../src/geometry/coordinates-identical.ts","../src/common.ts","../src/modes/polygon/behaviors/closing-points.behavior.ts","../src/modes/polygon/polygon.mode.ts","../src/util/geoms.ts","../src/modes/render/render.mode.ts","../src/geometry/midpoint-coordinate.ts","../src/geometry/get-midpoints.ts","../src/modes/select/behaviors/midpoint.behavior.ts","../src/modes/select/behaviors/selection-point.behavior.ts","../src/geometry/get-coordinates-as-points.ts","../src/geometry/boolean/point-in-polygon.ts","../src/geometry/measure/pixel-distance-to-line.ts","../src/modes/select/behaviors/features-at-mouse-event.behavior.ts","../src/modes/select/behaviors/drag-feature.behavior.ts","../src/modes/select/behaviors/drag-coordinate.behavior.ts","../src/geometry/centroid.ts","../src/geometry/measure/rhumb-bearing.ts","../src/geometry/measure/rhumb-destination.ts","../src/geometry/measure/rhumb-distance.ts","../src/modes/select/behaviors/rotate-feature.behavior.ts","../src/geometry/transform/rotate.ts","../src/modes/select/behaviors/scale-feature.behavior.ts","../src/geometry/transform/scale.ts","../src/modes/select/select.mode.ts","../src/modes/static/static.mode.ts","../src/util/id.ts","../src/store/spatial-index/quickselect.ts","../src/store/spatial-index/rbush.ts","../src/store/spatial-index/spatial-index.ts","../src/store/store.ts","../src/terra-draw.ts"],"sourcesContent":["export function limitPrecision(num: number, decimalLimit = 9) {\n const decimals = Math.pow(10, decimalLimit);\n return Math.round(num * decimals) / decimals;\n}\n","import {\n TerraDrawCallbacks,\n TerraDrawAdapter,\n TerraDrawModeRegisterConfig,\n TerraDrawAdapterStyling,\n TerraDrawChanges,\n TerraDrawMouseEvent\n} from \"../common\";\nimport { GeoJsonObject } from \"geojson\";\n\nimport { limitPrecision } from \"../geometry/limit-decimal-precision\";\nimport { GeoJSONStoreFeatures } from \"../store/store\";\n\nexport class TerraDrawGoogleMapsAdapter implements TerraDrawAdapter {\n constructor(config: {\n lib: typeof google.maps;\n map: google.maps.Map;\n coordinatePrecision?: number;\n }) {\n this._lib = config.lib;\n this._map = config.map;\n this._coordinatePrecision =\n typeof config.coordinatePrecision === \"number\"\n ? config.coordinatePrecision\n : 9;\n\n this.getMapContainer = () => {\n return this._map.getDiv();\n };\n\n this.project = (lng, lat) => {\n const bounds = this._map.getBounds();\n\n if (bounds === undefined) {\n throw new Error(\"cannot get bounds\");\n }\n\n const northWest = new this._lib.LatLng(\n bounds.getNorthEast().lat(),\n bounds.getSouthWest().lng()\n );\n\n const projection = this._map.getProjection();\n if (projection === undefined) {\n throw new Error(\"cannot get projection\");\n }\n\n const projectedNorthWest = projection.fromLatLngToPoint(northWest);\n if (projectedNorthWest === null) {\n throw new Error(\"cannot get projectedNorthWest\");\n }\n\n const projected = projection.fromLatLngToPoint({ lng, lat });\n if (projected === null) {\n throw new Error(\"cannot get projected lng lat\");\n }\n\n const zoom = this._map.getZoom();\n if (zoom === undefined) {\n throw new Error(\"cannot get zoom\");\n }\n\n const scale = Math.pow(2, zoom);\n return {\n x: Math.floor((projected.x - projectedNorthWest.x) * scale),\n y: Math.floor((projected.y - projectedNorthWest.y) * scale),\n };\n };\n\n this.unproject = (x, y) => {\n const projection = this._map.getProjection();\n if (projection === undefined) {\n throw new Error(\"cannot get projection\");\n }\n\n const bounds = this._map.getBounds();\n if (bounds === undefined) {\n throw new Error(\"cannot get bounds\");\n }\n\n const topRight = projection.fromLatLngToPoint(bounds.getNorthEast());\n if (topRight === null) {\n throw new Error(\"cannot get topRight\");\n }\n\n const bottomLeft = projection.fromLatLngToPoint(bounds.getSouthWest());\n if (bottomLeft === null) {\n throw new Error(\"cannot get bottomLeft\");\n }\n\n const zoom = this._map.getZoom();\n if (zoom === undefined) {\n throw new Error(\"zoom get bounds\");\n }\n\n const scale = Math.pow(2, zoom);\n\n const worldPoint = new google.maps.Point(\n x / scale + bottomLeft.x,\n y / scale + topRight.y\n );\n const lngLat = projection.fromPointToLatLng(worldPoint);\n\n if (lngLat === null) {\n throw new Error(\"zoom get bounds\");\n }\n\n return { lng: lngLat.lng(), lat: lngLat.lat() };\n };\n\n this.setCursor = (cursor) => {\n if (cursor === this._cursor) {\n return;\n }\n\n if (this._cursorStyleSheet) {\n this._cursorStyleSheet.remove();\n this._cursorStyleSheet = undefined;\n }\n\n if (cursor !== \"unset\") {\n // TODO: We could cache these individually per cursor\n\n const div = this.getMapContainer();\n const style = document.createElement(\"style\");\n style.type = \"text/css\";\n const selector = `#${div.id} [aria-label=\"Map\"]`;\n style.innerHTML = `${selector} { cursor: ${cursor} !important; }`;\n document.getElementsByTagName(\"head\")[0].appendChild(style);\n this._cursorStyleSheet = style;\n }\n\n this._cursor = cursor;\n };\n }\n\n private _heldKeys: Set<string> = new Set();\n private _cursor: string | undefined;\n private _cursorStyleSheet: HTMLStyleElement | undefined;\n private _coordinatePrecision: number;\n private _lib: typeof google.maps;\n private _map: google.maps.Map;\n private _onMouseMoveListener: google.maps.MapsEventListener | undefined;\n private _onMouseMoveCallback:\n | ((\n event: google.maps.MapMouseEvent & {\n domEvent: MouseEvent;\n }\n ) => void)\n | undefined;\n private _onClickListener: google.maps.MapsEventListener | undefined;\n private _onRightClickListener: google.maps.MapsEventListener | undefined;\n private _onClickCallback:\n | ((\n event: google.maps.MapMouseEvent & {\n domEvent: MouseEvent;\n }\n ) => void)\n | undefined;\n private _onKeyUpListener: any;\n private _onDragStartListener: ((event: MouseEvent) => void) | undefined;\n private _onDragListener: ((event: MouseEvent) => void) | undefined;\n private _onDragEndListener: ((event: MouseEvent) => void) | undefined;\n private _layers = false;\n\n public getMapContainer: () => HTMLElement;\n\n public unproject: (x: number, y: number) => { lng: number; lat: number };\n public project: TerraDrawModeRegisterConfig[\"project\"];\n public setCursor: TerraDrawModeRegisterConfig[\"setCursor\"];\n\n // https://stackoverflow.com/a/27905268/1363484\n private circlePath(cx: number, cy: number, r: number) {\n return (\n \"M \" +\n cx +\n \" \" +\n cy +\n \" m -\" +\n r +\n \", 0 a \" +\n r +\n \",\" +\n r +\n \" 0 1,0 \" +\n r * 2 +\n \",0 a \" +\n r +\n \",\" +\n r +\n \" 0 1,0 -\" +\n r * 2 +\n \",0\"\n );\n }\n\n register(callbacks: TerraDrawCallbacks) {\n this._onClickCallback = (\n event: google.maps.MapMouseEvent & {\n domEvent: MouseEvent;\n }\n ) => {\n if (!event.latLng) {\n return;\n }\n callbacks.onClick({\n lng: limitPrecision(event.latLng.lng(), this._coordinatePrecision),\n lat: limitPrecision(event.latLng.lat(), this._coordinatePrecision),\n containerX: event.domEvent.clientX - this.getMapContainer().offsetLeft,\n containerY: event.domEvent.clientY - this.getMapContainer().offsetTop,\n button: event.domEvent.button === 0 ? \"left\" : \"right\",\n heldKeys: [...this._heldKeys],\n });\n };\n this._onClickListener = this._map.addListener(\n \"click\",\n this._onClickCallback\n );\n\n this._onRightClickListener = this._map.addListener(\n \"rightclick\",\n this._onClickCallback\n );\n\n this._onMouseMoveCallback = (\n event: google.maps.MapMouseEvent & {\n domEvent: MouseEvent;\n }\n ) => {\n if (!event.latLng) {\n return;\n }\n callbacks.onMouseMove({\n lng: limitPrecision(event.latLng.lng(), this._coordinatePrecision),\n lat: limitPrecision(event.latLng.lat(), this._coordinatePrecision),\n containerX: event.domEvent.clientX - this.getMapContainer().offsetLeft,\n containerY: event.domEvent.clientY - this.getMapContainer().offsetTop,\n button: event.domEvent.button === 0 ? \"left\" : \"right\",\n heldKeys: [...this._heldKeys],\n });\n };\n this._onMouseMoveListener = this._map.addListener(\n \"mousemove\",\n this._onMouseMoveCallback\n );\n\n this._onKeyUpListener = (event: KeyboardEvent) => {\n callbacks.onKeyUp({\n key: event.key,\n });\n };\n\n this.getMapContainer().addEventListener(\"keyup\", this._onKeyUpListener);\n\n let dragState: \"not-dragging\" | \"pre-dragging\" | \"dragging\" =\n \"not-dragging\";\n\n this._onDragStartListener = (event) => {\n dragState = \"pre-dragging\";\n };\n\n const container = this.getMapContainer();\n\n container.addEventListener(\"mousedown\", this._onDragStartListener);\n\n this._onDragListener = (event) => {\n const point = {\n x: event.clientX - container.offsetLeft,\n y: event.clientY - container.offsetTop,\n } as L.Point;\n\n const { lng, lat } = this.unproject(point.x, point.y);\n\n const drawEvent: TerraDrawMouseEvent = {\n lng: limitPrecision(lng, this._coordinatePrecision),\n lat: limitPrecision(lat, this._coordinatePrecision),\n containerX: event.clientX - container.offsetLeft,\n containerY: event.clientY - container.offsetTop,\n button: event.button === 0 ? \"left\" : \"right\",\n heldKeys: [...this._heldKeys],\n };\n\n if (dragState === \"pre-dragging\") {\n dragState = \"dragging\";\n callbacks.onDragStart(drawEvent, (enabled) => {\n this._map.setOptions({ draggable: false });\n });\n } else if (dragState === \"dragging\") {\n callbacks.onDrag(drawEvent);\n }\n };\n\n container.addEventListener(\"mousemove\", this._onDragListener);\n\n this._onDragEndListener = (event) => {\n if (dragState === \"dragging\") {\n const point = {\n x: event.clientX - container.offsetLeft,\n y: event.clientY - container.offsetTop,\n } as L.Point;\n\n const { lng, lat } = this.unproject(point.x, point.y);\n\n callbacks.onDragEnd(\n {\n lng: limitPrecision(lng, this._coordinatePrecision),\n lat: limitPrecision(lat, this._coordinatePrecision),\n containerX: event.clientX - container.offsetLeft,\n containerY: event.clientY - container.offsetTop,\n button: event.button === 0 ? \"left\" : \"right\",\n heldKeys: [...this._heldKeys],\n },\n (enabled) => {\n this._map.setOptions({ draggable: enabled });\n }\n );\n }\n\n dragState = \"not-dragging\";\n };\n\n container.addEventListener(\"mouseup\", this._onDragEndListener);\n }\n\n unregister() {\n if (this._onClickListener) {\n this._onClickCallback = undefined;\n this._onClickListener.remove();\n this._onClickListener = undefined;\n }\n if (this._onRightClickListener) {\n this._onClickCallback = undefined;\n this._onRightClickListener.remove();\n this._onRightClickListener = undefined;\n }\n if (this._onMouseMoveListener) {\n this._onMouseMoveCallback = undefined;\n this._onMouseMoveListener.remove();\n this._onMouseMoveListener = undefined;\n }\n\n if (this._onKeyUpListener) {\n this.getMapContainer().removeEventListener(\n \"keyup\",\n this._onKeyUpListener\n );\n this._onKeyUpListener = undefined;\n }\n }\n\n render(\n changes: TerraDrawChanges,\n styling: { [mode: string]: (feature: GeoJSONStoreFeatures) => TerraDrawAdapterStyling }\n ) {\n if (this._layers) {\n changes.deletedIds.forEach((deletedId) => {\n const featureToDelete = this._map.data.getFeatureById(deletedId);\n featureToDelete && this._map.data.remove(featureToDelete);\n });\n\n changes.updated.forEach((updatedFeature) => {\n if (!updatedFeature || !updatedFeature.id) {\n throw new Error(\"Feature is not valid\");\n }\n\n const featureToUpdate = this._map.data.getFeatureById(\n updatedFeature.id\n );\n\n if (!featureToUpdate) {\n throw new Error(\"Feature could not be found by Google Maps API\");\n }\n\n // Remove all keys\n featureToUpdate.forEachProperty((property, name) => {\n featureToUpdate.setProperty(name, undefined);\n });\n\n // Update all keys\n Object.keys(updatedFeature.properties).forEach((property) => {\n featureToUpdate.setProperty(\n property,\n updatedFeature.properties[property]\n );\n });\n\n switch (updatedFeature.geometry.type) {\n case \"Point\":\n {\n const coordinates = updatedFeature.geometry.coordinates;\n\n featureToUpdate.setGeometry(\n new google.maps.Data.Point(\n new google.maps.LatLng(coordinates[1], coordinates[0])\n )\n );\n }\n break;\n case \"LineString\":\n {\n const coordinates = updatedFeature.geometry.coordinates;\n\n const path = [];\n for (let i = 0; i < coordinates.length; i++) {\n const coordinate = coordinates[i];\n const latLng = new google.maps.LatLng(\n coordinate[1],\n coordinate[0]\n );\n path.push(latLng);\n }\n\n featureToUpdate.setGeometry(\n new google.maps.Data.LineString(path)\n );\n }\n break;\n case \"Polygon\":\n {\n const coordinates = updatedFeature.geometry.coordinates;\n\n const paths = [];\n for (let i = 0; i < coordinates.length; i++) {\n const path = [];\n for (let j = 0; j < coordinates[i].length; j++) {\n const latLng = new google.maps.LatLng(\n coordinates[i][j][1],\n coordinates[i][j][0]\n );\n path.push(latLng);\n }\n paths.push(path);\n }\n\n featureToUpdate.setGeometry(new google.maps.Data.Polygon(paths));\n }\n\n break;\n }\n });\n\n // Create new features\n changes.created.forEach((createdFeature) => {\n this._map.data.addGeoJson(createdFeature);\n });\n } else {\n // Clicking on data geometries triggers\n // swallows the map onclick event,\n // so we need to forward it to the click callback handler\n this._map.data.addListener(\n \"click\",\n (\n event: google.maps.MapMouseEvent & {\n domEvent: MouseEvent;\n }\n ) => {\n this._onClickCallback && this._onClickCallback(event);\n }\n );\n\n this._map.data.addListener(\n \"mousemove\",\n (\n event: google.maps.MapMouseEvent & {\n domEvent: MouseEvent;\n }\n ) => {\n this._onMouseMoveCallback && this._onMouseMoveCallback(event);\n }\n );\n }\n\n const featureCollection = {\n type: \"FeatureCollection\",\n features: [...changes.created],\n } as GeoJsonObject;\n\n this._map.data.addGeoJson(featureCollection);\n\n this._map.data.setStyle((feature) => {\n const mode = feature.getProperty(\"mode\");\n const gmGeometry = feature.getGeometry();\n if (!gmGeometry) {\n throw new Error(\"Google Maps geometry not found\");\n }\n const type = gmGeometry.getType();\n const properties: Record<string, any> = {};\n\n feature.forEachProperty((value, property) => {\n properties[property] = value;\n });\n\n const calculatedStyles = styling[mode]({\n type: \"Feature\",\n geometry: {\n type: type as \"Point\" | \"LineString\" | \"Polygon\",\n coordinates: []\n },\n properties\n });\n\n\n switch (type) {\n case \"Point\":\n\n const path = this.circlePath(\n 0,\n 0,\n calculatedStyles.pointWidth\n );\n\n return {\n clickable: false,\n icon: {\n path,\n fillColor: calculatedStyles.pointColor,\n fillOpacity: 1,\n strokeColor: calculatedStyles.pointOutlineColor,\n strokeWeight: calculatedStyles.pointOutlineWidth,\n rotation: 0,\n scale: 1,\n },\n };\n\n case \"LineString\":\n return {\n strokeColor: calculatedStyles.lineStringColor,\n strokeWeight: calculatedStyles.lineStringWidth,\n };\n case \"Polygon\":\n return {\n strokeColor: calculatedStyles.polygonOutlineColor,\n strokeWeight: calculatedStyles.polygonOutlineWidth,\n fillOpacity: calculatedStyles.polygonFillOpacity,\n fillColor: calculatedStyles.polygonFillColor,\n };\n }\n\n throw Error(\"Unknown feature type\");\n });\n\n this._layers = true;\n }\n}\n","import {\n TerraDrawCallbacks,\n TerraDrawAdapter,\n TerraDrawModeRegisterConfig,\n TerraDrawAdapterStyling,\n TerraDrawChanges,\n TerraDrawMouseEvent\n} from \"../common\";\nimport L from \"leaflet\";\nimport { limitPrecision } from \"../geometry/limit-decimal-precision\";\nimport { GeoJSONStoreFeatures } from \"../store/store\";\n\nexport class TerraDrawLeafletAdapter implements TerraDrawAdapter {\n constructor(config: {\n lib: typeof L;\n map: L.Map;\n coordinatePrecision?: number;\n }) {\n this._lib = config.lib;\n this._map = config.map;\n this._coordinatePrecision =\n typeof config.coordinatePrecision === \"number\"\n ? config.coordinatePrecision\n : 9;\n\n this.getMapContainer = () => {\n return this._map.getContainer();\n };\n\n this.project = (lng: number, lat: number) => {\n const { x, y } = this._map.latLngToContainerPoint({ lng, lat });\n return { x, y };\n };\n\n this.unproject = (x: number, y: number) => {\n const { lng, lat } = this._map.containerPointToLatLng({\n x,\n y,\n } as L.PointExpression);\n return { lng, lat };\n };\n\n this.setCursor = (cursor) => {\n if (cursor === \"unset\") {\n this.getMapContainer().style.removeProperty(\"cursor\");\n } else {\n this.getMapContainer().style.cursor = cursor;\n }\n };\n }\n\n private _heldKeys: Set<string> = new Set();\n private _lib: typeof L;\n private _coordinatePrecision: number;\n private _map: L.Map;\n private _onMouseMoveListener: ((ev: any) => void) | undefined;\n private _onClickListener: ((ev: any) => void) | undefined;\n private _onKeyUpListener: ((ev: any) => void) | undefined;\n private _onKeyDownListener: ((ev: any) => void) | undefined;\n\n private _onDragStartListener: ((event: MouseEvent) => void) | undefined;\n private _onDragListener: ((event: MouseEvent) => void) | undefined;\n private _onDragEndListener: ((event: MouseEvent) => void) | undefined;\n private _layer: L.Layer | undefined;\n private _panes: Record<string, HTMLStyleElement | undefined> = {};\n public project: TerraDrawModeRegisterConfig[\"project\"];\n public unproject: TerraDrawModeRegisterConfig[\"unproject\"];\n public setCursor: TerraDrawModeRegisterConfig[\"setCursor\"];\n\n public getMapContainer: () => HTMLElement;\n\n private createPaneStyleSheet(pane: string, zIndex: number) {\n const style = document.createElement(\"style\");\n style.type = \"text/css\";\n style.innerHTML = `.leaflet-${pane} {z-index: ${zIndex};}`;\n document.getElementsByTagName(\"head\")[0].appendChild(style);\n this._map.createPane(pane);\n return style;\n }\n\n register(callbacks: TerraDrawCallbacks) {\n\n const container = this.getMapContainer();\n\n let dragState:\n | \"not-dragging\"\n | \"pre-dragging\"\n | \"dragging\"\n | \"after-dragging\" = \"not-dragging\";\n\n this._onClickListener = (event: L.LeafletMouseEvent) => {\n if (dragState === \"not-dragging\" || dragState === \"pre-dragging\") {\n callbacks.onClick({\n lng: limitPrecision(event.latlng.lng, this._coordinatePrecision),\n lat: limitPrecision(event.latlng.lat, this._coordinatePrecision),\n containerX:\n event.originalEvent.clientX - this.getMapContainer().offsetLeft,\n containerY:\n event.originalEvent.clientY - this.getMapContainer().offsetTop,\n button: event.originalEvent.button === 0 ? \"left\" : \"right\",\n heldKeys: [...this._heldKeys],\n });\n }\n };\n\n // We can't use 'click' here because it triggers\n // after drag end in Leaflet for some reason\n this._map.on(\"mouseup\", this._onClickListener);\n this._map.on(\"contextmenu\", this._onClickListener);\n\n this._onMouseMoveListener = (event: L.LeafletMouseEvent) => {\n event.originalEvent.preventDefault();\n\n callbacks.onMouseMove({\n lng: limitPrecision(event.latlng.lng, this._coordinatePrecision),\n lat: limitPrecision(event.latlng.lat, this._coordinatePrecision),\n containerX:\n event.originalEvent.clientX - this.getMapContainer().offsetLeft,\n containerY:\n event.originalEvent.clientY - this.getMapContainer().offsetTop,\n button: event.originalEvent.button === 0 ? \"left\" : \"right\",\n heldKeys: [...this._heldKeys],\n });\n };\n this._map.on(\"mousemove\", this._onMouseMoveListener);\n\n this._onDragStartListener = (event) => {\n dragState = \"pre-dragging\";\n };\n container.addEventListener(\"pointerdown\", this._onDragStartListener);\n\n this._onDragListener = (event) => {\n const point = {\n x: event.clientX - container.offsetLeft,\n y: event.clientY - container.offsetTop,\n } as L.Point;\n\n const { lng, lat } = this._map.containerPointToLatLng(point);\n\n const drawEvent: TerraDrawMouseEvent = {\n lng: limitPrecision(lng, this._coordinatePrecision),\n lat: limitPrecision(lat, this._coordinatePrecision),\n containerX: event.clientX - container.offsetLeft,\n containerY: event.clientY - container.offsetTop,\n button: event.button === 0 ? \"left\" : \"right\",\n heldKeys: [...this._heldKeys],\n };\n\n if (dragState === \"pre-dragging\") {\n dragState = \"dragging\";\n\n callbacks.onDragStart(drawEvent, (enabled) => {\n if (enabled) {\n this._map.dragging.enable();\n } else {\n this._map.dragging.disable();\n }\n });\n } else if (dragState === \"dragging\") {\n callbacks.onDrag(drawEvent);\n }\n };\n\n container.addEventListener(\"pointermove\", this._onDragListener);\n\n this._onDragEndListener = (event) => {\n event.preventDefault();\n\n if (dragState === \"dragging\") {\n const point = {\n x: event.clientX - container.offsetLeft,\n y: event.clientY - container.offsetTop,\n } as L.Point;\n\n const { lng, lat } = this._map.containerPointToLatLng(point);\n\n callbacks.onDragEnd(\n {\n lng: limitPrecision(lng, this._coordinatePrecision),\n lat: limitPrecision(lat, this._coordinatePrecision),\n containerX: event.clientX - container.offsetLeft,\n containerY: event.clientY - container.offsetTop,\n button: event.button === 0 ? \"left\" : \"right\",\n heldKeys: [...this._heldKeys],\n },\n (enabled) => {\n if (enabled) {\n this._map.dragging.enable();\n } else {\n this._map.dragging.disable();\n }\n }\n );\n\n // We want to avoid triggering an click\n // event after dragging\n dragState = \"after-dragging\";\n this._map.dragging.enable();\n return;\n }\n\n dragState = \"not-dragging\";\n this._map.dragging.enable();\n };\n\n container.addEventListener(\"pointerup\", this._onDragEndListener);\n\n // map has no keypress event, so we add one to the canvas itself\n this._onKeyUpListener = (event: KeyboardEvent) => {\n event.preventDefault();\n\n this._heldKeys.delete(event.key);\n\n callbacks.onKeyUp({\n key: event.key,\n });\n };\n container.addEventListener(\"keyup\", this._onKeyUpListener);\n\n this._onKeyDownListener = (event: KeyboardEvent) => {\n event.preventDefault();\n\n this._heldKeys.add(event.key);\n\n callbacks.onKeyDown({\n key: event.key,\n });\n };\n container.addEventListener(\"keydown\", this._onKeyDownListener);\n }\n\n unregister() {\n if (this._onClickListener) {\n this._map.off(\"contextmenu\", this._onClickListener);\n this._map.off(\"click\", this._onClickListener);\n this._onClickListener = undefined;\n }\n if (this._onMouseMoveListener) {\n this._map.off(\"click\", this._onClickListener);\n this._onClickListener = undefined;\n }\n\n Object.keys(this._panes).forEach((pane) => {\n const selectedPane = this._map.getPane(pane);\n if (selectedPane) {\n selectedPane.remove();\n }\n });\n }\n\n render(\n changes: TerraDrawChanges,\n styling: { [mode: string]: (feature: GeoJSONStoreFeatures) => TerraDrawAdapterStyling }\n ) {\n const features = [\n ...changes.created,\n ...changes.updated,\n ...changes.unchanged,\n ];\n\n if (this._layer) {\n this._map.removeLayer(this._layer);\n }\n\n const featureCollection = {\n type: \"FeatureCollection\",\n features,\n } as { type: \"FeatureCollection\", features: GeoJSONStoreFeatures[] };\n\n const layer = this._lib.geoJSON(featureCollection, {\n // Style points - convert markers to circle markers\n pointToLayer: (feature: GeoJSONStoreFeatures, latlng: L.LatLngExpression) => {\n if (!feature.properties) {\n throw new Error(\"Feature has no properties\");\n }\n if (typeof feature.properties.mode !== 'string') {\n throw new Error(\"Feature mode is not a string\");\n }\n\n const mode = feature.properties.mode;\n const modeStyle = styling[mode];\n const featureStyles = modeStyle(feature);\n const paneId = String(featureStyles.zIndex);\n const pane = this._panes[paneId];\n\n if (!pane) {\n this._panes[paneId] = this.createPaneStyleSheet(paneId, featureStyles.zIndex);\n }\n\n const styles = {\n radius: featureStyles.pointWidth,\n stroke: featureStyles.pointOutlineWidth || false,\n color: featureStyles.pointOutlineColor,\n weight: featureStyles.pointOutlineWidth,\n fillOpacity: 0.8,\n fillColor: featureStyles.pointColor,\n pane: paneId,\n interactive: false, // Removes mouse hover cursor styles\n } as L.CircleMarkerOptions;\n\n const marker = this._lib.circleMarker(latlng, styles);\n\n return marker;\n },\n\n // Style LineStrings and Polygons\n style: (_feature) => {\n if (!_feature || !_feature.properties) {\n return {};\n }\n\n const feature = _feature as GeoJSONStoreFeatures;\n\n const mode = feature.properties.mode as string;\n const modeStyle = styling[mode];\n const featureStyles = modeStyle(feature);\n\n if (feature.geometry.type === \"LineString\") {\n return {\n interactive: false, // Removes mouse hover cursor styles\n color: featureStyles.lineStringColor,\n weight: featureStyles.lineStringWidth,\n };\n } else if (feature.geometry.type === \"Polygon\") {\n return {\n interactive: false, // Removes mouse hover cursor styles\n fillOpacity: featureStyles.polygonFillOpacity,\n fillColor: featureStyles.polygonFillColor,\n weight: featureStyles.polygonOutlineWidth,\n stroke: true,\n color: featureStyles.polygonFillColor\n };\n }\n\n return {};\n },\n });\n\n this._map.addLayer(layer);\n\n this._layer = layer;\n }\n}\n","import {\n TerraDrawCallbacks,\n TerraDrawAdapter,\n TerraDrawModeRegisterConfig,\n TerraDrawAdapterStyling,\n TerraDrawChanges,\n TerraDrawMouseEvent\n} from \"../common\";\nimport { Feature, LineString, Point, Polygon } from \"geojson\";\nimport { limitPrecision } from \"../geometry/limit-decimal-precision\";\nimport mapboxgl, {\n CircleLayer,\n FillLayer,\n LineLayer,\n PointLike,\n} from \"mapbox-gl\";\nimport { GeoJSONStoreFeatures, GeoJSONStoreGeometries } from \"../store/store\";\n\nexport class TerraDrawMapboxGLAdapter implements TerraDrawAdapter {\n constructor(config: { map: mapboxgl.Map; coordinatePrecision: number }) {\n this._map = config.map;\n this._coordinatePrecision =\n typeof config.coordinatePrecision === \"number\"\n ? config.coordinatePrecision\n : 9;\n\n this.project = (lng: number, lat: number) => {\n const { x, y } = this._map.project({ lng, lat });\n return { x, y };\n };\n\n this.unproject = (x: number, y: number) => {\n const { lng, lat } = this._map.unproject({ x, y } as PointLike);\n return { lng, lat };\n };\n\n this.setCursor = (style) => {\n this._map.getCanvas().style.cursor = style;\n };\n\n this.getMapContainer = () => {\n return this._map.getContainer();\n };\n }\n\n public unproject: TerraDrawModeRegisterConfig[\"unproject\"];\n public project: TerraDrawModeRegisterConfig[\"project\"];\n public setCursor: TerraDrawModeRegisterConfig[\"setCursor\"];\n\n public getMapContainer: () => HTMLElement;\n\n private _heldKeys: Set<string> = new Set();\n private _coordinatePrecision: number;\n private _map: mapboxgl.Map;\n private _onMouseMoveListener:\n | ((event: mapboxgl.MapMouseEvent & mapboxgl.EventData) => void)\n | undefined;\n private _onClickListener:\n | ((event: mapboxgl.MapMouseEvent & mapboxgl.EventData) => void)\n | undefined;\n private _onDragStartListener: ((event: MouseEvent) => void) | undefined;\n private _onDragListener: ((event: MouseEvent) => void) | undefined;\n private _onDragEndListener: ((event: MouseEvent) => void) | undefined;\n private _onKeyDownListener: ((event: KeyboardEvent) => void) | undefined;\n private _onKeyUpListener: ((event: KeyboardEvent) => any) | undefined;\n private _rendered: Record<string, boolean> = {};\n\n private _addGeoJSONSource(id: string, features: Feature[]) {\n this._map.addSource(id, {\n type: \"geojson\",\n data: {\n type: \"FeatureCollection\",\n features: features,\n },\n });\n }\n\n private _addFillLayer(\n id: string,\n mode: string,\n ) {\n return this._map.addLayer({\n id,\n source: id,\n type: \"fill\",\n filter: [\n \"all\",\n [\"match\", [\"geometry-type\"], \"Polygon\", true, false],\n [\"match\", [\"get\", \"mode\"], mode, true, false],\n ],\n paint: {\n \"fill-color\": [\"get\", \"polygonFillColor\"],\n \"fill-opacity\": [\"get\", \"polygonFillOpacity\"]\n },\n } as FillLayer);\n }\n\n private _addFillOutlineLayer(\n id: string,\n mode: string,\n beneath?: string\n ) {\n const layer = this._map.addLayer({\n id: id + \"outline\",\n source: id,\n type: \"line\",\n filter: [\n \"all\",\n [\"match\", [\"geometry-type\"], \"Polygon\", true, false],\n [\"match\", [\"get\", \"mode\"], mode, true, false],\n ],\n paint: {\n \"line-width\": [\"get\", \"polygonOutlineWidth\"],\n \"line-color\": [\"get\", \"polygonOutlineColor\"],\n },\n } as LineLayer);\n\n if (beneath) {\n this._map.moveLayer(id, beneath);\n }\n\n return layer;\n }\n\n private _addLineLayer(\n id: string,\n mode: string,\n beneath?: string\n ) {\n const layer = this._map.addLayer({\n id,\n source: id,\n type: \"line\",\n filter: [\n \"all\",\n [\"match\", [\"geometry-type\"], \"LineString\", true, false],\n [\"match\", [\"get\", \"mode\"], mode, true, false],\n ],\n paint: {\n \"line-width\": [\"get\", \"lineStringWidth\"],\n \"line-color\": [\"get\", \"lineStringColor\"],\n },\n } as LineLayer);\n\n if (beneath) {\n this._map.moveLayer(id, beneath);\n }\n\n return layer;\n }\n\n private _addPointLayer(\n id: string,\n mode: string,\n beneath?: string\n ) {\n const layer = this._map.addLayer({\n id,\n source: id,\n type: \"circle\",\n filter: [\n \"all\",\n [\"match\", [\"geometry-type\"], \"Point\", true, false],\n [\"match\", [\"get\", \"mode\"], mode, true, false],\n ],\n paint: {\n \"circle-stroke-color\": [\"get\", \"pointOutlineColor\"],\n \"circle-stroke-width\": [\"get\", \"pointOutlineWidth\"],\n \"circle-radius\": [\"get\", \"pointWidth\"],\n \"circle-color\": [\"get\", \"pointColor\"],\n },\n } as CircleLayer);\n if (beneath) {\n this._map.moveLayer(id, beneath);\n }\n return layer;\n }\n\n private _addLayer(\n id: string,\n mode: string,\n featureType: \"Point\" | \"LineString\" | \"Polygon\",\n beneath?: string\n ) {\n if (featureType === \"Point\") {\n this._addPointLayer(id, mode, beneath);\n }\n if (featureType === \"LineString\") {\n this._addLineLayer(id, mode, beneath);\n }\n if (featureType === \"Polygon\") {\n this._addFillLayer(id, mode);\n this._addFillOutlineLayer(id, mode, beneath);\n }\n }\n\n private _addGeoJSONLayer<T extends GeoJSONStoreGeometries>(\n mode: string,\n featureType: Feature<T>[\"geometry\"][\"type\"],\n features: Feature<T>[],\n ) {\n const id = `td-${mode}-${featureType.toLowerCase()}`;\n this._addGeoJSONSource(id, features);\n this._addLayer(id, mode, featureType,);\n\n return id;\n }\n\n private _setGeoJSONLayerData<T extends GeoJSONStoreGeometries>(\n mode: string,\n featureType: Feature<T>[\"geometry\"][\"type\"],\n features: Feature<T>[]\n ) {\n const id = `td-${mode}-${featureType.toLowerCase()}`;\n (this._map.getSource(id) as any).setData({\n type: \"FeatureCollection\",\n features: features,\n });\n return id;\n }\n register(callbacks: TerraDrawCallbacks) {\n this._onClickListener = (event) => {\n callbacks.onClick({\n lng: limitPrecision(event.lngLat.lng, this._coordinatePrecision),\n lat: limitPrecision(event.lngLat.lat, this._coordinatePrecision),\n containerX:\n event.originalEvent.clientX - this.getMapContainer().offsetLeft,\n containerY:\n event.originalEvent.clientY - this.getMapContainer().offsetTop,\n button: event.originalEvent.button === 0 ? \"left\" : \"right\",\n heldKeys: [...this._heldKeys],\n });\n };\n this._map.on(\"click\", this._onClickListener);\n this._map.on(\"contextmenu\", this._onClickListener);\n\n this._onMouseMoveListener = (event) => {\n callbacks.onMouseMove({\n lng: limitPrecision(event.lngLat.lng, this._coordinatePrecision),\n lat: limitPrecision(event.lngLat.lat, this._coordinatePrecision),\n containerX:\n event.originalEvent.clientX - this.getMapContainer().offsetLeft,\n containerY:\n event.originalEvent.clientY - this.getMapContainer().offsetTop,\n button: event.originalEvent.button === 0 ? \"left\" : \"right\",\n heldKeys: [...this._heldKeys],\n });\n };\n this._map.on(\"mousemove\", this._onMouseMoveListener);\n\n let dragState: \"not-dragging\" | \"pre-dragging\" | \"dragging\" =\n \"not-dragging\";\n\n this._onDragStartListener = (event) => {\n dragState = \"pre-dragging\";\n };\n\n const container = this.getMapContainer();\n\n container.addEventListener(\"mousedown\", this._onDragStartListener);\n\n this._onDragListener = (event) => {\n const { lng, lat } = this._map.unproject({\n x: event.clientX - container.offsetLeft,\n y: event.clientY - container.offsetTop,\n } as any);\n\n const drawEvent: TerraDrawMouseEvent = {\n lng: limitPrecision(lng, this._coordinatePrecision),\n lat: limitPrecision(lat, this._coordinatePrecision),\n containerX: event.clientX - container.offsetLeft,\n containerY: event.clientY - container.offsetTop,\n button: event.button === 0 ? \"left\" : \"right\",\n heldKeys: [...this._heldKeys],\n };\n\n if (dragState === \"pre-dragging\") {\n dragState = \"dragging\";\n\n callbacks.onDragStart(drawEvent, (enabled) => {\n if (enabled) {\n this._map.dragPan.enable();\n } else {\n this._map.dragPan.disable();\n }\n });\n } else if (dragState === \"dragging\") {\n callbacks.onDrag(drawEvent);\n }\n };\n\n container.addEventListener(\"mousemove\", this._onDragListener);\n\n this._onDragEndListener = (event) => {\n if (dragState === \"dragging\") {\n const point = {\n x: event.clientX - container.offsetLeft,\n y: event.clientY - container.offsetTop,\n } as mapboxgl.Point;\n\n const { lng, lat } = this._map.unproject(point);\n\n callbacks.onDragEnd(\n {\n lng: limitPrecision(lng, this._coordinatePrecision),\n lat: limitPrecision(lat, this._coordinatePrecision),\n containerX: event.clientX - container.offsetLeft,\n containerY: event.clientY - container.offsetTop,\n button: event.button === 0 ? \"left\" : \"right\",\n heldKeys: [...this._heldKeys],\n },\n (enabled) => {\n if (enabled) {\n this._map.dragPan.enable();\n } else {\n this._map.dragPan.disable();\n }\n }\n );\n }\n\n dragState = \"not-dragging\";\n };\n\n container.addEventListener(\"mouseup\", this._onDragEndListener);\n\n // map has no keypress event, so we add one to the canvas itself\n this._onKeyUpListener = (event: KeyboardEvent) => {\n event.preventDefault();\n\n this._heldKeys.delete(event.key);\n\n callbacks.onKeyUp({\n key: event.key,\n });\n };\n container.addEventListener(\"keyup\", this._onKeyUpListener);\n\n this._onKeyDownListener = (event: KeyboardEvent) => {\n event.preventDefault();\n\n this._heldKeys.add(event.key);\n\n callbacks.onKeyDown({\n key: event.key,\n });\n };\n container.addEventListener(\"keydown\", this._onKeyDownListener);\n }\n\n unregister() {\n if (this._onClickListener) {\n this._map.off(\"contextmenue\", this._onClickListener);\n this._map.off(\"click\", this._onClickListener);\n this._onClickListener = undefined;\n }\n\n if (this._onMouseMoveListener) {\n this._map.off(\"mousemove\", this._onMouseMoveListener);\n this._onMouseMoveListener = undefined;\n }\n\n if (this._onKeyUpListener) {\n this._map\n .getCanvas()\n .removeEventListener(\"keypress\", this._onKeyUpListener);\n }\n\n if (this._onDragStartListener) {\n this._map\n .getCanvas()\n .removeEventListener(\"mousedown\", this._onDragStartListener);\n }\n\n if (this._onDragListener) {\n this._map\n .getCanvas()\n .removeEventListener(\"mousemove\", this._onDragListener);\n }\n\n if (this._onDragEndListener) {\n this._map\n .getCanvas()\n .removeEventListener(\"mouseup\", this._onDragEndListener);\n }\n }\n\n render(\n changes: TerraDrawChanges,\n styling: { [mode: string]: (feature: GeoJSONStoreFeatures) => TerraDrawAdapterStyling }\n ) {\n const features = [\n ...changes.created,\n ...changes.updated,\n ...changes.unchanged,\n ];\n\n const modeFeatures: {\n [key: string]: {\n points: GeoJSONStoreFeatures[];\n linestrings: GeoJSONStoreFeatures[];\n polygons: GeoJSONStoreFeatures[];\n };\n } = {};\n\n Object.keys(styling).forEach((mode) => {\n if (!modeFeatures[mode]) {\n modeFeatures[mode] = {\n points: [],\n linestrings: [],\n polygons: [],\n };\n }\n });\n\n for (let i = 0; i < features.length; i++) {\n const feature = features[i];\n\n Object.keys(styling).forEach((mode) => {\n const { properties } = feature;\n\n if (properties.mode !== mode) {\n return;\n }\n\n const styles = styling[mode](feature);\n\n if (feature.geometry.type === \"Point\") {\n properties.pointColor = styles.pointColor;\n properties.pointOutlineColor = styles.pointOutlineColor;\n properties.pointOutlineWidth = styles.pointOutlineWidth;\n properties.pointWidth = styles.pointWidth;\n modeFeatures[mode].points.push(feature);\n } else if (feature.geometry.type === \"LineString\") {\n properties.lineStringColor = styles.lineStringColor;\n properties.lineStringWidth = styles.lineStringWidth;\n modeFeatures[mode].linestrings.push(feature);\n } else if (feature.geometry.type === \"Polygon\") {\n properties.polygonFillColor = styles.polygonFillColor;\n properties.polygonFillOpacity = styles.polygonFillOpacity;\n properties.polygonOutlineColor = styles.polygonOutlineColor;\n properties.polygonOutlineWidth = styles.polygonOutlineWidth;\n modeFeatures[mode].polygons.push(feature);\n }\n });\n }\n\n Object.keys(styling).forEach((mode) => {\n if (!modeFeatures[mode]) {\n return;\n }\n\n const { points, linestrings, polygons } = modeFeatures[mode];\n\n\n if (!this._rendered[mode]) {\n this._addGeoJSONLayer<Point>(\n mode,\n \"Point\",\n points as Feature<Point>[],\n );\n this._addGeoJSONLayer<LineString>(\n mode,\n \"LineString\",\n linestrings as Feature<LineString>[],\n );\n this._addGeoJSONLayer<Polygon>(\n mode,\n \"Polygon\",\n polygons as Feature<Polygon>[],\n );\n this._rendered[mode] = true;\n } else {\n const pointId = this._setGeoJSONLayerData<Point>(\n mode,\n \"Point\",\n points as Feature<Point>[]\n );\n this._setGeoJSONLayerData<LineString>(\n mode,\n \"LineString\",\n linestrings as Feature<LineString>[]\n );\n this._setGeoJSONLayerData<Polygon>(\n mode,\n \"Polygon\",\n polygons as Feature<Polygon>[]\n );\n\n // TODO: This logic could be better - I think this will render the selection points above user\n // defined layers outside of TerraDraw which is perhaps unideal\n\n // Ensure selection/mid points are rendered on top\n this._map.moveLayer(pointId);\n }\n });\n\n if ((this._map as any).style) {\n // cancel the scheduled update\n if ((this._map as any)._frame) {\n (this._map as any)._frame.cancel();\n (this._map as any)._frame = null;\n }\n (this._map as any)._render();\n }\n }\n}\n","import { Position } from \"geojson\";\n\nexport function haversineDistanceKilometers(\n pointOne: Position,\n pointTwo: Position\n) {\n const toRadians = (latOrLng: number) => (latOrLng * Math.PI) / 180;\n\n const phiOne = toRadians(pointOne[1]);\n const lambdaOne = toRadians(pointOne[0]);\n const phiTwo = toRadians(pointTwo[1]);\n const lambdaTwo = toRadians(pointTwo[0]);\n const deltaPhi = phiTwo - phiOne;\n const deltalambda = lambdaTwo - lambdaOne;\n\n const a =\n Math.sin(deltaPhi / 2) * Math.sin(deltaPhi / 2) +\n Math.cos(phiOne) *\n Math.cos(phiTwo) *\n Math.sin(deltalambda / 2) *\n Math.sin(deltalambda / 2);\n const c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));\n\n const radius = 6371e3;\n const distance = radius * c;\n\n return distance / 1000;\n}\n","export const earthRadius = 6371008.8;\n\nexport function degreesToRadians(degrees: number): number {\n const radians = degrees % 360;\n return (radians * Math.PI) / 180;\n}\n\nexport function lengthToRadians(distance: number): number {\n const factor = earthRadius / 1000;\n return distance / factor;\n}\n\nexport function radiansToDegrees(radians: number): number {\n const degrees = radians % (2 * Math.PI);\n return (degrees * 180) / Math.PI;\n}\n","import { Feature, Polygon, Position } from \"geojson\";\nimport {\n degreesToRadians,\n lengthToRadians,\n radiansToDegrees,\n} from \"../helpers\";\n\n// Based on Turf.js Circle module\n// https://github.com/Turfjs/turf/blob/master/packages/turf-circle/index.ts\n\nexport function destination(\n origin: Position,\n distance: number,\n bearing: number\n): Position {\n const longitude1 = degreesToRadians(origin[0]);\n const latitude1 = degreesToRadians(origin[1]);\n const bearingRad = degreesToRadians(bearing);\n const radians = lengthToRadians(distance);\n\n // Main\n const latitude2 = Math.asin(\n Math.sin(latitude1) * Math.cos(radians) +\n Math.cos(latitude1) * Math.sin(radians) * Math.cos(bearingRad)\n );\n const longitude2 =\n longitude1 +\n Math.atan2(\n Math.sin(bearingRad) * Math.sin(radians) * Math.cos(latitude1),\n Math.cos(radians) - Math.sin(latitude1) * Math.sin(latitude2)\n );\n const lng = radiansToDegrees(longitude2);\n const lat = radiansToDegrees(latitude2);\n\n return [lng, lat];\n}\n\nexport function circle(options: {\n center: Position;\n radiusKilometers: number;\n steps?: number;\n}): Feature<Polygon> {\n const { center, radiusKilometers } = options;\n const steps = options.steps ? options.steps : 64;\n\n const coordinates: Position[] = [];\n for (let i = 0; i < steps; i++) {\n coordinates.push(destination(center, radiusKilometers, (i * -360) / steps));\n }\n coordinates.push(coordinates[0]);\n\n return {\n type: \"Feature\",\n geometry: { type: \"Polygon\", coordinates: [coordinates] },\n properties: {},\n };\n}\n","import { TerraDrawAdapterStyling } from \"../common\";\n\nexport const getDefaultStyling = (): TerraDrawAdapterStyling => {\n return {\n polygonFillColor: \"#3f97e0\",\n polygonOutlineColor: \"#3f97e0\",\n polygonOutlineWidth: 4,\n polygonFillOpacity: 0.3,\n pointColor: \"#3f97e0\",\n pointOutlineColor: \"#ffffff\",\n pointOutlineWidth: 0,\n pointWidth: 6,\n lineStringColor: \"#3f97e0\",\n lineStringWidth: 4,\n zIndex: 0\n };\n};\n","import { BehaviorConfig, TerraDrawModeBehavior } from \"./base.behavior\";\nimport {\n TerraDrawAdapterStyling,\n TerraDrawModeRegisterConfig,\n TerraDrawModeState,\n} from \"../common\";\nimport { GeoJSONStore, GeoJSONStoreFeatures } from \"../store/store\";\n\ntype CustomStyling = Record<string, string | number>\n\nexport abstract class TerraDrawBaseDrawMode<T extends CustomStyling> {\n protected _state: TerraDrawModeState;\n get state() {\n return this._state;\n }\n set state(_) {\n throw new Error(\"Please use the modes lifecycle methods\");\n }\n\n protected _styles: Partial<T>;\n\n get styles(): Partial<T> {\n return this._styles;\n }\n set styles(styling: Partial<T>) {\n if (typeof styling !== \"object\") {\n throw new Error(\"Styling must be an object\");\n }\n\n this.onStyleChange([], \"styling\");\n this._styles = styling;\n }\n\n protected behaviors: TerraDrawModeBehavior[] = [];\n protected pointerDistance: number;\n protected coordinatePrecision: number;\n protected onStyleChange: any;\n protected store!: GeoJSONStore;\n protected unproject!: TerraDrawModeRegisterConfig[\"unproject\"];\n protected project!: TerraDrawModeRegisterConfig[\"project\"];\n protected setCursor!: TerraDrawModeRegisterConfig[\"setCursor\"];\n protected registerBehaviors(behaviorConfig: BehaviorConfig): void { }\n\n constructor(options?: {\n styles?: Partial<T>;\n pointerDistance?: number;\n coordinatePrecision?: number;\n }) {\n this._state = \"unregistered\";\n this._styles =\n options && options.styles\n ? { ...options.styles }\n : {} as Partial<T>;\n\n this.pointerDistance = (options && options.pointerDistance) || 40;\n\n this.coordinatePrecision = (options && options.coordinatePrecision) || 9;\n }\n\n protected setStarted() {\n if (this._state === \"stopped\" || this._state === \"registered\") {\n this._state = \"started\";\n } else {\n throw new Error(\"Mode must be unregistered or stopped to start\");\n }\n }\n\n protected setStopped() {\n if (this._state === \"started\") {\n this._state = \"stopped\";\n } else {\n throw new Error(\"Mode must be started to be stopped\");\n }\n }\n\n register(config: TerraDrawModeRegisterConfig) {\n if (this._state === \"unregistered\") {\n this._state = \"registered\";\n this.store = config.store;\n this.store.registerOnChange(config.onChange);\n this.project = config.project;\n this.unproject = config.unproject;\n this.onSelect = config.onSelect;\n this.onDeselect = config.onDeselect;\n this.setCursor = config.setCursor;\n this.onStyleChange = config.onChange;\n\n this.registerBehaviors({\n mode: config.mode,\n store: this.store,\n project: this.project,\n unproject: this.unproject,\n pointerDistance: this.pointerDistance,\n coordinatePrecision: this.coordinatePrecision,\n });\n } else {\n throw new Error(\"Can not register unless mode is unregistered\");\n }\n }\n\n onDeselect(deselectedId: string) { }\n onSelect(selectedId: string) { }\n styleFeature(feature: GeoJSONStoreFeatures) { }\n}\n","import { Position } from \"geojson\";\nimport {\n TerraDrawMouseEvent,\n TerraDrawAdapterStyling,\n TerraDrawKeyboardEvent,\n HexColor,\n} from \"../../common\";\nimport { haversineDistanceKilometers } from \"../../geometry/measure/haversine-distance\";\nimport { circle } from \"../../geometry/shape/create-circle\";\nimport { GeoJSONStoreFeatures } from \"../../store/store\";\nimport { getDefaultStyling } from \"../../util/styling\";\nimport { TerraDrawBaseDrawMode } from \"../base.mode\";\n\ntype TerraDrawCircleModeKeyEvents = {\n cancel: KeyboardEvent[\"key\"];\n finish: KeyboardEvent[\"key\"];\n};\n\ntype FreehandPolygonStyling = {\n fillColor: HexColor,\n outlineColor: HexColor,\n outlineWidth: number,\n fillOpacity: number,\n}\n\nexport class TerraDrawCircleMode extends TerraDrawBaseDrawMode<FreehandPolygonStyling> {\n\n mode = \"circle\";\n private center: Position | undefined;\n private clickCount = 0;\n private currentCircleId: string | undefined;\n private keyEvents: TerraDrawCircleModeKeyEvents;\n\n constructor(options?: {\n styles?: Partial<FreehandPolygonStyling>;\n keyEvents?: TerraDrawCircleModeKeyEvents;\n }) {\n super(options);\n\n this.keyEvents =\n options && options.keyEvents ? options.keyEvents : { cancel: \"Escape\", finish: 'Enter' };\n }\n\n private close() {\n this.center = undefined;\n this.currentCircleId = undefined;\n this.clickCount = 0;\n }\n\n start() {\n this.setStarted();\n this.setCursor(\"crosshair\");\n }\n\n stop() {\n this.setStopped();\n this.setCursor(\"unset\");\n this.cleanUp();\n }\n\n onClick(event: TerraDrawMouseEvent) {\n if (this.clickCount === 0) {\n this.center = [event.lng, event.lat];\n const startingCircle = circle({\n center: this.center,\n radiusKilometers: 0.00001,\n });\n\n const [createdId] = this.store.create([\n {\n geometry: startingCircle.geometry,\n properties: {\n mode: this.mode,\n },\n },\n ]);\n this.currentCircleId = createdId;\n this.clickCount++;\n } else {\n // Finish drawing\n this.close();\n }\n }\n onMouseMove(event: TerraDrawMouseEvent) {\n if (this.clickCount === 1 && this.center && this.currentCircleId) {\n const distanceKm = haversineDistanceKilometers(this.center, [\n event.lng,\n event.lat,\n ]);\n\n const updatedCircle = circle({\n center: this.center,\n radiusKilometers: distanceKm,\n });\n\n this.store.updateGeometry([\n { id: this.currentCircleId, geometry: updatedCircle.geometry },\n ]);\n }\n }\n onKeyDown() { }\n onKeyUp(event: TerraDrawKeyboardEvent) {\n if (event.key === this.keyEvents.cancel) {\n this.cleanUp();\n } else if (event.key === this.keyEvents.finish) {\n this.close();\n }\n }\n onDragStart() { }\n onDrag() { }\n onDragEnd() { }\n cleanUp() {\n try {\n if (this.currentCircleId) {\n this.store.delete([this.currentCircleId]);\n }\n } catch (error) { }\n this.center = undefined;\n this.currentCircleId = undefined;\n this.clickCount = 0;\n }\n\n styleFeature(\n feature: GeoJSONStoreFeatures\n ): TerraDrawAdapterStyling {\n const styles = { ...getDefaultStyling() };\n\n if (\n feature.type === 'Feature' &&\n feature.geometry.type === 'Polygon' &&\n feature.properties.mode === this.mode\n ) {\n\n if (this.styles.fillColor) {\n styles.polygonFillColor = this.styles.fillColor;\n }\n if (this.styles.outlineColor) {\n styles.polygonOutlineColor = this.styles.outlineColor;\n }\n if (this.styles.outlineWidth) {\n styles.polygonOutlineWidth = this.styles.outlineWidth;\n }\n if (this.styles.fillOpacity) {\n styles.polygonFillOpacity = this.styles.fillOpacity;\n }\n\n return styles;\n }\n\n return styles;\n\n }\n}","export const pixelDistance = (\n pointOne: { x: number; y: number },\n pointTwo: { x: number; y: number }\n) => {\n const { x: x1, y: y1 } = pointOne;\n const { x: x2, y: y2 } = pointTwo;\n const y = x2 - x1;\n const x = y2 - y1;\n return Math.sqrt(x * x + y * y);\n};\n","import {\n TerraDrawMouseEvent,\n TerraDrawAdapterStyling,\n TerraDrawKeyboardEvent,\n HexColor,\n} from \"../../common\";\nimport { Polygon } from \"geojson\";\n\nimport { TerraDrawBaseDrawMode } from \"../base.mode\";\nimport { getDefaultStyling } from \"../../util/styling\";\nimport { GeoJSONStoreFeatures } from \"../../store/store\";\nimport { pixelDistance } from \"../../geometry/measure/pixel-distance\";\n\ntype TerraDrawFreehandModeKeyEvents = {\n cancel: KeyboardEvent[\"key\"];\n finish: KeyboardEvent[\"key\"];\n};\n\ntype FreehandPolygonStyling = {\n fillColor: HexColor,\n outlineColor: HexColor,\n outlineWidth: number,\n fillOpacity: number,\n closingPointColor: HexColor,\n closingPointWidth: number,\n closingPointOutlineColor: HexColor,\n closingPointOutlineWidth: number\n}\n\nexport class TerraDrawFreehandMode extends TerraDrawBaseDrawMode<FreehandPolygonStyling> {\n mode = \"freehand\";\n\n private startingClick = false;\n private currentId: string | undefined;\n private closingPointId: string | undefined;\n private minDistance: number;\n private keyEvents: TerraDrawFreehandModeKeyEvents;\n\n constructor(options?: {\n styles?: Partial<FreehandPolygonStyling>;\n minDistance?: number;\n keyEvents?: TerraDrawFreehandModeKeyEvents;\n }) {\n super(options);\n\n this.minDistance = (options && options.minDistance) || 20;\n this.keyEvents =\n options && options.keyEvents ? options.keyEvents : { cancel: \"Escape\", finish: 'Enter' };\n }\n\n private close() {\n this.closingPointId && this.store.delete([this.closingPointId]);\n this.startingClick = false;\n this.currentId = undefined;\n this.closingPointId = undefined;\n }\n\n start() {\n this.setStarted();\n this.setCursor(\"crosshair\");\n }\n stop() {\n this.setStopped();\n this.setCursor(\"unset\");\n this.cleanUp();\n }\n\n onMouseMove(event: TerraDrawMouseEvent) {\n if (!this.currentId || this.startingClick === false) {\n return;\n }\n\n const currentLineGeometry = this.store.getGeometryCopy<Polygon>(\n this.currentId\n );\n\n const [previousLng, previousLat] =\n currentLineGeometry.coordinates[0][\n currentLineGeometry.coordinates[0].length - 2\n ];\n const { x, y } = this.project(previousLng, previousLat);\n const distance = pixelDistance(\n { x, y },\n { x: event.containerX, y: event.containerY }\n );\n\n const [closingLng, closingLat] = currentLineGeometry.coordinates[0][0];\n const { x: closingX, y: closingY } = this.project(closingLng, closingLat);\n const closingDistance = pixelDistance(\n { x: closingX, y: closingY },\n { x: event.containerX, y: event.containerY }\n );\n\n if (closingDistance < this.pointerDistance) {\n this.setCursor('pointer');\n } else {\n this.setCursor('crosshair');\n }\n\n // The cusor must have moved a minimum distance\n // before we add another coordinate\n if (distance < this.minDistance) {\n return;\n }\n\n currentLineGeometry.coordinates[0].pop();\n\n this.store.updateGeometry([\n {\n id: this.currentId,\n geometry: {\n type: \"Polygon\",\n coordinates: [\n [\n ...currentLineGeometry.coordinates[0],\n [event.lng, event.lat],\n currentLineGeometry.coordinates[0][0],\n ],\n ],\n },\n },\n ]);\n }\n\n onClick(event: TerraDrawMouseEvent) {\n if (this.startingClick === false) {\n const [createdId, closingPointId] = this.store.create([\n {\n geometry: {\n type: \"Polygon\",\n coordinates: [\n [\n [event.lng, event.lat],\n [event.lng, event.lat],\n [event.lng, event.lat],\n [event.lng, event.lat],\n ],\n ],\n },\n properties: { mode: this.mode },\n },\n {\n geometry: {\n type: \"Point\",\n coordinates: [event.lng, event.lat],\n },\n properties: { mode: this.mode },\n },\n ]);\n\n this.currentId = createdId;\n this.closingPointId = closingPointId;\n this.startingClick = true;\n return;\n }\n\n this.close();\n }\n onKeyDown() { }\n onKeyUp(event: TerraDrawKeyboardEvent) {\n if (event.key === this.keyEvents.cancel) {\n this.cleanUp();\n } else if (event.key === this.keyEvents.finish) {\n this.close();\n }\n }\n onDragStart() { }\n onDrag() { }\n onDragEnd() { }\n\n cleanUp() {\n try {\n if (this.currentId) {\n this.store.delete([this.currentId]);\n }\n if (this.closingPointId) {\n this.store.delete([this.closingPointId]);\n }\n } catch (error) { }\n this.closingPointId = undefined;\n this.currentId = undefined;\n this.startingClick = false;\n }\n\n styleFeature(\n feature: GeoJSONStoreFeatures\n ): TerraDrawAdapterStyling {\n const styles = { ...getDefaultStyling() };\n\n if (\n feature.type === 'Feature' &&\n feature.geometry.type === 'Polygon' &&\n feature.properties.mode === this.mode\n ) {\n\n if (this.styles.fillColor) {\n styles.polygonFillColor = this.styles.fillColor;\n }\n if (this.styles.outlineColor) {\n styles.polygonOutlineColor = this.styles.outlineColor;\n }\n if (this.styles.outlineWidth) {\n styles.polygonOutlineWidth = this.styles.outlineWidth;\n }\n if (this.styles.fillOpacity) {\n styles.polygonFillOpacity = this.styles.fillOpacity;\n }\n\n return styles;\n } else if (\n feature.type === 'Feature' &&\n feature.geometry.type === 'Point' &&\n feature.properties.mode === this.mode\n ) {\n\n if (this.styles.closingPointColor) {\n styles.pointColor = this.styles.closingPointColor;\n }\n if (this.styles.closingPointWidth) {\n styles.pointWidth = this.styles.closingPointWidth;\n }\n\n styles.pointOutlineColor = this.styles.closingPointOutlineColor !== undefined ?\n this.styles.closingPointOutlineColor : '#ffffff';\n styles.pointOutlineWidth = this.styles.closingPointOutlineWidth !== undefined ?\n this.styles.closingPointOutlineWidth : 2;\n\n return styles;\n }\n\n return styles;\n\n }\n\n}\n","// Based on - https://github.com/mclaeysb/geojson-polygon-self-intersections\n// MIT License - Copyright (c) 2016 Manuel Claeys Bouuaert\n\nimport { Feature, LineString, Polygon, Position } from \"geojson\";\n// import * as rbush from \"rbush\";\n\ntype SelfIntersectsOptions = {\n epsilon: number;\n // reportVertexOnVertex: boolean;\n // reportVertexOnEdge: boolean;\n};\n\nexport function selfIntersects(\n feature: Feature<Polygon> | Feature<LineString>\n): boolean {\n const options: SelfIntersectsOptions = {\n epsilon: 0,\n // reportVertexOnVertex: false,\n // reportVertexOnEdge: false,\n };\n\n let coord: number[][][];\n\n if (feature.geometry.type === \"Polygon\") {\n coord = feature.geometry.coordinates;\n } else if (feature.geometry.type === \"LineString\") {\n coord = [feature.geometry.coordinates];\n } else {\n throw new Error(\"Self intersects only accepts Polygons and LineStrings\");\n }\n\n const output: number[][] = [];\n const seen: { [key: string]: boolean } = {};\n\n for (let ring0 = 0; ring0 < coord.length; ring0++) {\n for (let edge0 = 0; edge0 < coord[ring0].length - 1; edge0++) {\n for (let ring1 = 0; ring1 < coord.length; ring1++) {\n for (let edge1 = 0; edge1 < coord[ring1].length - 1; edge1++) {\n // speedup possible if only interested in unique: start last two loops at ring0 and edge0+1\n ifInteresctionAddToOutput(ring0, edge0, ring1, edge1);\n }\n }\n }\n }\n\n return output.length > 0;\n\n // true if frac is (almost) 1.0 or 0.0\n // function isBoundaryCase(frac: number) {\n // const e2 = options.epsilon * options.epsilon;\n // return e2 >= (frac - 1) * (frac - 1) || e2 >= frac * frac;\n // }\n\n function isOutside(frac: number) {\n return frac < 0 - options.epsilon || frac > 1 + options.epsilon;\n }\n // Function to check if two edges intersect and add the intersection to the output\n function ifInteresctionAddToOutput(\n ring0: number,\n edge0: number,\n ring1: number,\n edge1: number\n ) {\n const start0 = coord[ring0][edge0];\n const end0 = coord[ring0][edge0 + 1];\n const start1 = coord[ring1][edge1];\n const end1 = coord[ring1][edge1 + 1];\n\n const intersection = intersect(start0, end0, start1, end1);\n\n if (intersection === null) {\n return; // discard parallels and coincidence\n }\n\n let frac0;\n let frac1;\n\n if (end0[0] !== start0[0]) {\n frac0 = (intersection[0] - start0[0]) / (end0[0] - start0[0]);\n } else {\n frac0 = (intersection[1] - start0[1]) / (end0[1] - start0[1]);\n }\n if (end1[0] !== start1[0]) {\n frac1 = (intersection[0] - start1[0]) / (end1[0] - start1[0]);\n } else {\n frac1 = (intersection[1] - start1[1]) / (end1[1] - start1[1]);\n }\n\n // There are roughly three cases we need to deal with.\n // 1. If at least one of the fracs lies outside [0,1], there is no intersection.\n if (isOutside(frac0) || isOutside(frac1)) {\n return; // require segment intersection\n }\n\n // 2. If both are either exactly 0 or exactly 1, this is not an intersection but just\n // two edge segments sharing a common vertex.\n // if (isBoundaryCase(frac0) && isBoundaryCase(frac1)) {\n // if (!options.reportVertexOnVertex) {\n // return;\n // }\n // }\n\n // // 3. If only one of the fractions is exactly 0 or 1, this is\n // // a vertex-on-edge situation.\n // if (isBoundaryCase(frac0) || isBoundaryCase(frac1)) {\n // if (!options.reportVertexOnEdge) {\n // return;\n // }\n // }\n\n const key = intersection.toString();\n const unique = !seen[key];\n if (unique) {\n seen[key] = true;\n }\n\n output.push(intersection);\n }\n}\n\nfunction equalArrays(array1: Position, array2: Position) {\n return array1[0] === array2[0] && array1[1] === array2[1];\n}\n\n// Function to compute where two lines (not segments) intersect. From https://en.wikipedia.org/wiki/Line%E2%80%93line_intersection\nfunction intersect(\n start0: Position,\n end0: Position,\n start1: Position,\n end1: Position\n) {\n if (\n equalArrays(start0, start1) ||\n equalArrays(start0, end1) ||\n equalArrays(end0, start1) ||\n equalArrays(end1, start1)\n ) {\n return null;\n }\n\n const x0 = start0[0],\n y0 = start0[1],\n x1 = end0[0],\n y1 = end0[1],\n x2 = start1[0],\n y2 = start1[1],\n x3 = end1[0],\n y3 = end1[1];\n\n const denom = (x0 - x1) * (y2 - y3) - (y0 - y1) * (x2 - x3);\n if (denom === 0) {\n return null;\n }\n\n const x4 =\n ((x0 * y1 - y0 * x1) * (x2 - x3) - (x0 - x1) * (x2 * y3 - y2 * x3)) / denom;\n\n const y4 =\n ((x0 * y1 - y0 * x1) * (y2 - y3) - (y0 - y1) * (x2 * y3 - y2 * x3)) / denom;\n\n return [x4, y4];\n}\n","import { Project, Unproject } from \"../common\";\nimport { GeoJSONStore } from \"../store/store\";\n\nexport type BehaviorConfig = {\n store: GeoJSONStore;\n mode: string;\n project: Project;\n unproject: Unproject;\n pointerDistance: number;\n coordinatePrecision: number;\n};\n\nexport class TerraDrawModeBehavior {\n protected store: GeoJSONStore;\n protected mode: string;\n protected project: Project;\n protected unproject: Unproject;\n protected pointerDistance: number;\n protected coordinatePrecision: number;\n\n constructor({\n store,\n mode,\n project,\n unproject,\n pointerDistance,\n coordinatePrecision,\n }: BehaviorConfig) {\n this.store = store;\n this.mode = mode;\n this.project = project;\n this.unproject = unproject;\n this.pointerDistance = pointerDistance;\n this.coordinatePrecision = coordinatePrecision;\n }\n}\n","import { Feature, Polygon } from \"geojson\";\nimport { BehaviorConfig, TerraDrawModeBehavior } from \"./base.behavior\";\n\nimport { TerraDrawMouseEvent } from \"../common\";\n\nexport class ClickBoundingBoxBehavior extends TerraDrawModeBehavior {\n constructor(config: BehaviorConfig) {\n super(config);\n }\n\n public create(event: TerraDrawMouseEvent) {\n const { containerX: x, containerY: y } = event;\n const halfDist = this.pointerDistance / 2;\n\n const bbox = {\n type: \"Feature\",\n properties: {},\n geometry: {\n type: \"Polygon\",\n coordinates: [\n [\n this.unproject(x - halfDist, y - halfDist), // TopLeft\n this.unproject(x + halfDist, y - halfDist), // TopRight\n this.unproject(x + halfDist, y + halfDist), // BottomRight\n this.unproject(x - halfDist, y + halfDist), // BottomLeft\n this.unproject(x - halfDist, y - halfDist), // TopLeft\n ].map((c) => [c.lng, c.lat]),\n ],\n },\n } as Feature<Polygon>;\n\n return bbox;\n }\n}\n","import { BehaviorConfig, TerraDrawModeBehavior } from \"./base.behavior\";\nimport { TerraDrawMouseEvent } from \"../common\";\n\nimport { Position } from \"geojson\";\nimport { pixelDistance } from \"../geometry/measure/pixel-distance\";\n\nexport class PixelDistanceBehavior extends TerraDrawModeBehavior {\n constructor(config: BehaviorConfig) {\n super(config);\n }\n public measure(clickEvent: TerraDrawMouseEvent, secondCoordinate: Position) {\n const { x, y } = this.project(secondCoordinate[0], secondCoordinate[1]);\n\n const distance = pixelDistance(\n { x, y },\n { x: clickEvent.containerX, y: clickEvent.containerY }\n );\n\n return distance;\n }\n}\n","import { BehaviorConfig, TerraDrawModeBehavior } from \"./base.behavior\";\nimport { TerraDrawMouseEvent } from \"../common\";\nimport { Feature, Polygon, Position } from \"geojson\";\nimport { ClickBoundingBoxBehavior } from \"./click-bounding-box.behavior\";\nimport { BBoxPolygon } from \"../store/store\";\nimport { PixelDistanceBehavior } from \"./pixel-distance.behavior\";\n\nexport class SnappingBehavior extends TerraDrawModeBehavior {\n constructor(\n readonly config: BehaviorConfig,\n private readonly pixelDistance: PixelDistanceBehavior,\n private readonly clickBoundingBox: ClickBoundingBoxBehavior\n ) {\n super(config);\n }\n\n public getSnappableCoordinate = (\n event: TerraDrawMouseEvent,\n currentFeatureId: string\n ) => {\n return this.getSnappable(event, (feature) => {\n return Boolean(\n feature.properties &&\n feature.properties.mode === this.mode &&\n feature.id !== currentFeatureId\n );\n });\n };\n\n private getSnappable(\n event: TerraDrawMouseEvent,\n filter: (feature: Feature) => boolean\n ) {\n const bbox = this.clickBoundingBox.create(event) as BBoxPolygon;\n\n const features = this.store.search(bbox, filter);\n\n const closest: { coord: undefined | Position; minDist: number } = {\n coord: undefined,\n minDist: Infinity,\n };\n\n features.forEach((feature) => {\n let coordinates: Position[];\n if (feature.geometry.type === \"Polygon\") {\n coordinates = feature.geometry.coordinates[0];\n } else if (feature.geometry.type === \"LineString\") {\n coordinates = feature.geometry.coordinates;\n } else {\n return;\n }\n\n coordinates.forEach((coord) => {\n const dist = this.pixelDistance.measure(event, coord);\n if (dist < closest.minDist && dist < this.pointerDistance) {\n closest.coord = coord;\n }\n });\n });\n\n return closest.coord;\n }\n}\n","import {\n TerraDrawMouseEvent,\n TerraDrawAdapterStyling,\n TerraDrawKeyboardEvent,\n HexColor,\n} from \"../../common\";\nimport { LineString } from \"geojson\";\nimport { selfIntersects } from \"../../geometry/boolean/self-intersects\";\nimport { TerraDrawBaseDrawMode } from \"../base.mode\";\nimport { pixelDistance } from \"../../geometry/measure/pixel-distance\";\nimport { BehaviorConfig } from \"../base.behavior\";\nimport { ClickBoundingBoxBehavior } from \"../click-bounding-box.behavior\";\nimport { PixelDistanceBehavior } from \"../pixel-distance.behavior\";\nimport { SnappingBehavior } from \"../snapping.behavior\";\nimport { getDefaultStyling } from \"../../util/styling\";\nimport { GeoJSONStoreFeatures } from \"../../store/store\";\nimport { createSourceMapSource } from \"typescript\";\n\ntype TerraDrawLineStringModeKeyEvents = {\n cancel: KeyboardEvent[\"key\"];\n finish: KeyboardEvent[\"key\"]\n};\n\ntype LineStringStyling = {\n lineStringWidth: number,\n lineStringColor: HexColor,\n closingPointColor: HexColor,\n closingPointWidth: number,\n closingPointOutlineColor: HexColor,\n closingPointOutlineWidth: number\n}\n\n\nexport class TerraDrawLineStringMode extends TerraDrawBaseDrawMode<LineStringStyling> {\n mode = \"linestring\";\n\n private currentCoordinate = 0;\n private currentId: string | undefined;\n private closingPointId: string | undefined;\n private allowSelfIntersections;\n private keyEvents: TerraDrawLineStringModeKeyEvents;\n private snappingEnabled: boolean;\n\n // Behaviors\n private snapping!: SnappingBehavior;\n\n constructor(options?: {\n snapping?: boolean;\n allowSelfIntersections?: boolean;\n pointerDistance?: number;\n styles?: Partial<LineStringStyling>;\n keyEvents?: TerraDrawLineStringModeKeyEvents;\n }) {\n super(options);\n\n this.snappingEnabled =\n options && options.snapping !== undefined ? options.snapping : false;\n\n this.allowSelfIntersections =\n options && options.allowSelfIntersections !== undefined\n ? options.allowSelfIntersections\n : true;\n\n this.keyEvents =\n options && options.keyEvents ? options.keyEvents : { cancel: \"Escape\", finish: \"Enter\" };\n }\n\n private close() {\n if (!this.currentId) {\n return;\n }\n\n const currentLineGeometry = this.store.getGeometryCopy<LineString>(\n this.currentId\n );\n\n // Finish off the drawing\n currentLineGeometry.coordinates.pop();\n this.store.updateGeometry([\n {\n id: this.currentId,\n geometry: {\n type: \"LineString\",\n coordinates: [...currentLineGeometry.coordinates],\n },\n },\n ]);\n\n // Reset the state back to starting state\n this.closingPointId && this.store.delete([this.closingPointId]);\n this.currentCoordinate = 0;\n this.currentId = undefined;\n this.closingPointId = undefined;\n }\n\n registerBehaviors(config: BehaviorConfig) {\n this.snapping = new SnappingBehavior(\n config,\n new PixelDistanceBehavior(config),\n new ClickBoundingBoxBehavior(config)\n );\n }\n\n start() {\n this.setStarted();\n this.setCursor(\"crosshair\");\n }\n stop() {\n this.setStopped();\n this.setCursor(\"unset\");\n this.cleanUp();\n }\n\n onMouseMove(event: TerraDrawMouseEvent) {\n this.setCursor(\"crosshair\");\n\n if (!this.currentId || this.currentCoordinate === 0) {\n return;\n }\n const currentLineGeometry = this.store.getGeometryCopy<LineString>(\n this.currentId\n );\n\n // Remove the 'live' point that changes on mouse move\n currentLineGeometry.coordinates.pop();\n\n const snappedCoord =\n this.snappingEnabled &&\n this.snapping.getSnappableCoordinate(event, this.currentId);\n const updatedCoord = snappedCoord ? snappedCoord : [event.lng, event.lat];\n\n\n // We want to ensure that when we are hovering over\n // the losign point that the pointer cursor is shown\n if (this.closingPointId) {\n const [previousLng, previousLat] =\n currentLineGeometry.coordinates[\n currentLineGeometry.coordinates.length - 1\n ];\n const { x, y } = this.project(previousLng, previousLat);\n const distance = pixelDistance(\n { x, y },\n { x: event.containerX, y: event.containerY }\n );\n\n const isClosingClick = distance < this.pointerDistance;\n\n if (isClosingClick) {\n this.setCursor('pointer');\n }\n }\n\n\n // Update the 'live' point\n this.store.updateGeometry([\n {\n id: this.currentId,\n geometry: {\n type: \"LineString\",\n coordinates: [...currentLineGeometry.coordinates, updatedCoord],\n },\n },\n ]);\n }\n\n onClick(event: TerraDrawMouseEvent) {\n const snappedCoord =\n this.currentId &&\n this.snappingEnabled &&\n this.snapping.getSnappableCoordinate(event, this.currentId);\n const updatedCoord = snappedCoord ? snappedCoord : [event.lng, event.lat];\n\n if (this.currentCoordinate === 0) {\n const [createdId] = this.store.create([\n {\n geometry: {\n type: \"LineString\",\n coordinates: [\n updatedCoord,\n updatedCoord, // This is the 'live' point that changes on mouse move\n ],\n },\n properties: { mode: this.mode },\n },\n ]);\n this.currentId = createdId;\n this.currentCoordinate++;\n } else if (this.currentCoordinate === 1 && this.currentId) {\n const currentLineGeometry = this.store.getGeometryCopy<LineString>(\n this.currentId\n );\n\n const [pointId] = this.store.create([\n {\n geometry: {\n type: \"Point\",\n coordinates: [...updatedCoord],\n },\n properties: { mode: this.mode },\n },\n ]);\n this.closingPointId = pointId;\n\n // We are creating the point so we immediately want\n // to set the point cursor to show it can be closed\n this.setCursor('pointer');\n\n this.store.updateGeometry([\n {\n id: this.currentId,\n geometry: {\n type: \"LineString\",\n coordinates: [\n currentLineGeometry.coordinates[0],\n updatedCoord,\n updatedCoord,\n ],\n },\n },\n ]);\n\n\n\n this.currentCoordinate++;\n } else if (this.currentId) {\n const currentLineGeometry = this.store.getGeometryCopy<LineString>(\n this.currentId\n );\n\n const [previousLng, previousLat] =\n currentLineGeometry.coordinates[\n currentLineGeometry.coordinates.length - 2\n ];\n const { x, y } = this.project(previousLng, previousLat);\n const distance = pixelDistance(\n { x, y },\n { x: event.containerX, y: event.containerY }\n );\n\n const isClosingClick = distance < this.pointerDistance;\n\n if (isClosingClick) {\n this.close();\n } else {\n // If not close to the final point, keep adding points\n const newLineString = {\n type: \"LineString\",\n coordinates: [...currentLineGeometry.coordinates, updatedCoord],\n } as LineString;\n\n if (!this.allowSelfIntersections) {\n const hasSelfIntersections = selfIntersects({\n type: \"Feature\",\n geometry: newLineString,\n properties: {},\n });\n\n if (hasSelfIntersections) {\n return;\n }\n }\n\n if (this.closingPointId) {\n this.setCursor('pointer');\n\n this.store.updateGeometry([\n { id: this.currentId, geometry: newLineString },\n {\n id: this.closingPointId,\n geometry: {\n type: \"Point\",\n coordinates: currentLineGeometry.coordinates[currentLineGeometry.coordinates.length - 1]\n }\n }\n ]);\n this.currentCoordinate++;\n }\n }\n }\n }\n onKeyDown() { }\n onKeyUp(event: TerraDrawKeyboardEvent) {\n if (event.key === this.keyEvents.cancel) {\n this.cleanUp();\n }\n\n if (event.key === this.keyEvents.finish) {\n this.close();\n }\n }\n onDragStart() { }\n onDrag() { }\n onDragEnd() { }\n cleanUp() {\n try {\n if (this.currentId) {\n this.store.delete([this.currentId]);\n }\n if (this.closingPointId) {\n this.store.delete([this.closingPointId]);\n }\n } catch (error) { }\n\n this.closingPointId = undefined;\n this.currentId = undefined;\n this.currentCoordinate = 0;\n }\n\n styleFeature(\n feature: GeoJSONStoreFeatures\n ): TerraDrawAdapterStyling {\n const styles = { ...getDefaultStyling() };\n\n if (\n feature.type === 'Feature' &&\n feature.geometry.type === 'LineString' &&\n feature.properties.mode === this.mode\n ) {\n\n if (this.styles.lineStringColor) {\n styles.lineStringColor = this.styles.lineStringColor;\n }\n if (this.styles.lineStringWidth) {\n styles.lineStringWidth = this.styles.lineStringWidth;\n }\n\n return styles;\n } else if (\n feature.type === 'Feature' &&\n feature.geometry.type === 'Point' &&\n feature.properties.mode === this.mode\n ) {\n\n if (this.styles.closingPointColor) {\n styles.pointColor = this.styles.closingPointColor;\n }\n if (this.styles.closingPointWidth) {\n styles.pointWidth = this.styles.closingPointWidth;\n }\n\n styles.pointOutlineColor = this.styles.closingPointOutlineColor !== undefined ?\n this.styles.closingPointOutlineColor : '#ffffff';\n styles.pointOutlineWidth = this.styles.closingPointOutlineWidth !== undefined ?\n this.styles.closingPointOutlineWidth : 2;\n\n return styles;\n }\n\n return styles;\n }\n}\n","import { Feature, Point } from \"geojson\";\nimport { TerraDrawMouseEvent, TerraDrawAdapterStyling, HexColor } from \"../../common\";\nimport { GeoJSONStoreFeatures } from \"../../store/store\";\nimport { getDefaultStyling } from \"../../util/styling\";\nimport { TerraDrawBaseDrawMode } from \"../base.mode\";\n\ntype PointModeStyling = {\n pointWidth: number,\n pointColor: HexColor,\n pointOutlineColor: HexColor\n}\nexport class TerraDrawPointMode extends TerraDrawBaseDrawMode<PointModeStyling> {\n mode = \"point\";\n\n constructor(options?: { styles?: Partial<PointModeStyling> }) {\n super(options);\n }\n\n start() {\n this.setStarted();\n this.setCursor(\"crosshair\");\n }\n stop() {\n this.setStopped();\n this.setCursor(\"unset\");\n this.cleanUp();\n }\n\n onClick(event: TerraDrawMouseEvent) {\n if (!this.store) {\n throw new Error(\"Mode must be registered first\");\n }\n\n this.store.create([\n {\n geometry: {\n type: \"Point\",\n coordinates: [event.lng, event.lat],\n },\n properties: { mode: this.mode },\n },\n ]);\n }\n onMouseMove() { }\n onKeyDown() { }\n onKeyUp() { }\n cleanUp() { }\n onDragStart() { }\n onDrag() { }\n onDragEnd() { }\n\n styleFeature(\n feature: GeoJSONStoreFeatures\n ): TerraDrawAdapterStyling {\n const styles = { ...getDefaultStyling() };\n\n if (feature.type === 'Feature' && feature.geometry.type === 'Point' && feature.properties.mode === this.mode) {\n\n if (this.styles.pointColor) {\n styles.pointColor = this.styles.pointColor;\n }\n if (this.styles.pointOutlineColor) {\n styles.pointOutlineColor = this.styles.pointOutlineColor;\n }\n if (this.styles.pointWidth) {\n styles.pointWidth = this.styles.pointWidth;\n }\n\n return styles;\n }\n\n return styles;\n }\n}\n","import { Position } from \"geojson\";\n\nexport function coordinatesIdentical(coordinate: Position, coordinateTwo: Position) {\n return coordinate[0] === coordinateTwo[0] && coordinate[1] === coordinateTwo[1];\n}","import {\n StoreChangeHandler,\n GeoJSONStore,\n GeoJSONStoreFeatures,\n} from \"./store/store\";\n\nexport type HexColor = `#${string}`\n\nexport interface TerraDrawAdapterStyling {\n pointColor: HexColor;\n pointWidth: number;\n pointOutlineColor: HexColor;\n pointOutlineWidth: number,\n polygonFillColor: HexColor;\n polygonFillOpacity: number;\n polygonOutlineColor: HexColor;\n polygonOutlineWidth: number;\n lineStringWidth: number;\n lineStringColor: HexColor;\n zIndex: number\n}\n\nexport interface TerraDrawMouseEvent {\n lng: number;\n lat: number;\n containerX: number;\n containerY: number;\n button: \"left\" | \"right\" | \"pointer\";\n heldKeys: string[];\n}\n\nexport interface TerraDrawKeyboardEvent {\n key: string;\n}\n\ntype SetCursor = (cursor: \"unset\" | \"grab\" | \"grabbing\" | \"crosshair\" | \"pointer\") => void;\n\nexport type Project = (lng: number, lat: number) => { x: number; y: number };\nexport type Unproject = (x: number, y: number) => { lat: number; lng: number };\n\nexport interface TerraDrawModeRegisterConfig {\n mode: string;\n store: GeoJSONStore;\n setCursor: SetCursor;\n onChange: StoreChangeHandler;\n onSelect: (selectedId: string) => void;\n onDeselect: (deselectedId: string) => void;\n project: Project;\n unproject: Unproject;\n}\n\nexport type TerraDrawModeState =\n | \"unregistered\"\n | \"registered\"\n | \"started\"\n | \"stopped\";\n\nexport interface TerraDrawMode {\n mode: string;\n styleFeature: (feature: GeoJSONStoreFeatures) => TerraDrawAdapterStyling;\n styles: any;\n state: TerraDrawModeState;\n start: () => void;\n stop: () => void;\n register: (config: TerraDrawModeRegisterConfig) => void;\n\n // cleanUp: () => void;\n onKeyDown: (event: TerraDrawKeyboardEvent) => void;\n onKeyUp: (event: TerraDrawKeyboardEvent) => void;\n onMouseMove: (event: TerraDrawMouseEvent) => void;\n onClick: (event: TerraDrawMouseEvent) => void;\n onDragStart: (\n event: TerraDrawMouseEvent,\n setMapDraggability: (enabled: boolean) => void\n ) => void;\n onDrag: (event: TerraDrawMouseEvent) => void;\n onDragEnd: (\n event: TerraDrawMouseEvent,\n setMapDraggability: (enabled: boolean) => void\n ) => void;\n}\n\nexport interface TerraDrawCallbacks {\n onKeyUp: (event: TerraDrawKeyboardEvent) => void;\n onKeyDown: (event: TerraDrawKeyboardEvent) => void;\n onClick: (event: TerraDrawMouseEvent) => void;\n onMouseMove: (event: TerraDrawMouseEvent) => void;\n onDragStart: (\n event: TerraDrawMouseEvent,\n setMapDraggability: (enabled: boolean) => void\n ) => void;\n onDrag: (event: TerraDrawMouseEvent) => void;\n onDragEnd: (\n event: TerraDrawMouseEvent,\n setMapDraggability: (enabled: boolean) => void\n ) => void;\n}\n\nexport interface TerraDrawChanges {\n created: GeoJSONStoreFeatures[];\n updated: GeoJSONStoreFeatures[];\n unchanged: GeoJSONStoreFeatures[];\n deletedIds: string[];\n}\n\ntype TerraDrawStylingFunction = { [mode: string]: (feature: GeoJSONStoreFeatures) => TerraDrawAdapterStyling }\n\nexport interface TerraDrawAdapter {\n project: Project;\n unproject: Unproject;\n setCursor: SetCursor;\n getMapContainer: () => HTMLElement;\n register(callbacks: TerraDrawCallbacks): void;\n unregister(): void;\n render(\n changes: TerraDrawChanges,\n styling: TerraDrawStylingFunction\n ): void;\n}\n\nexport const SELECT_PROPERTIES = {\n SELECTED: \"selected\",\n MID_POINT: \"midPoint\",\n SELECTION_POINT: \"selectionPoint\",\n} as const;\n\nexport const POLYGON_PROPERTIES = {\n CLOSING_POINT: 'closingPoint'\n};\n","import { Point, Position } from \"geojson\";\nimport { BehaviorConfig, TerraDrawModeBehavior } from \"../../base.behavior\";\nimport { POLYGON_PROPERTIES, TerraDrawMouseEvent } from \"../../../common\";\nimport { PixelDistanceBehavior } from \"../../pixel-distance.behavior\";\n\nexport class ClosingPointsBehavior extends TerraDrawModeBehavior {\n\n constructor(\n readonly config: BehaviorConfig,\n private readonly pixelDistance: PixelDistanceBehavior\n ) {\n super(config);\n }\n\n private _startEndPoints: string[] = [];\n\n get ids() {\n return this._startEndPoints.concat();\n }\n\n set ids(_: string[]) { }\n\n public create(\n selectedCoords: Position[],\n mode: string\n ) {\n if (this.ids.length) {\n throw new Error(\"Opening and closing points already creating\");\n }\n\n if (selectedCoords.length <= 3) {\n throw new Error(\"Requires at least 4 cooridnates\");\n }\n\n this._startEndPoints = this.store.create(\n // Opening coordinate\n [\n {\n geometry: {\n type: \"Point\",\n coordinates: selectedCoords[0]\n } as Point,\n properties: {\n mode,\n [POLYGON_PROPERTIES.CLOSING_POINT]: true\n }\n },\n // Final coordinate\n {\n geometry: {\n type: \"Point\",\n coordinates: selectedCoords[selectedCoords.length - 2]\n } as Point,\n properties: {\n mode,\n [POLYGON_PROPERTIES.CLOSING_POINT]: true\n }\n }\n ]\n );\n }\n\n public delete() {\n if (this.ids.length) {\n this.store.delete(this.ids);\n this._startEndPoints = [];\n }\n }\n\n public update(updatedCoordinates: Position[]) {\n\n if (this.ids.length !== 2) {\n throw new Error(\"No closing points to update\");\n }\n\n this.store.updateGeometry(\n // Opening coordinate\n [\n {\n id: this.ids[0],\n geometry: {\n type: \"Point\",\n coordinates: updatedCoordinates[0]\n } as Point,\n },\n // Final coordinate\n {\n id: this.ids[1],\n geometry: {\n type: \"Point\",\n coordinates: updatedCoordinates[updatedCoordinates.length - 3]\n } as Point,\n\n }\n ]\n );\n }\n\n public isClosingPoint(event: TerraDrawMouseEvent) {\n\n const opening = this.store.getGeometryCopy(this.ids[0]);\n const closing = this.store.getGeometryCopy(this.ids[1]);\n\n const distance = this.pixelDistance.measure(\n event,\n opening.coordinates as Position\n );\n\n const distancePrevious = this.pixelDistance.measure(\n event,\n closing.coordinates as Position\n );\n\n const isClosing = distance < this.pointerDistance;\n const isPreviousClosing = distancePrevious < this.pointerDistance;\n\n return { isClosing, isPreviousClosing };\n }\n\n}\n","import {\n TerraDrawMouseEvent,\n TerraDrawAdapterStyling,\n TerraDrawKeyboardEvent,\n HexColor,\n} from \"../../common\";\nimport { Feature, Point, Polygon } from \"geojson\";\nimport { selfIntersects } from \"../../geometry/boolean/self-intersects\";\nimport { TerraDrawBaseDrawMode } from \"../base.mode\";\nimport { PixelDistanceBehavior } from \"../pixel-distance.behavior\";\nimport { ClickBoundingBoxBehavior } from \"../click-bounding-box.behavior\";\nimport { BehaviorConfig } from \"../base.behavior\";\nimport { createPolygon } from \"../../util/geoms\";\nimport { SnappingBehavior } from \"../snapping.behavior\";\nimport { coordinatesIdentical } from \"../../geometry/coordinates-identical\";\nimport { ClosingPointsBehavior } from \"./behaviors/closing-points.behavior\";\nimport { getDefaultStyling } from \"../../util/styling\";\nimport { GeoJSONStoreFeatures } from \"../../store/store\";\n\ntype TerraDrawPolygonModeKeyEvents = {\n cancel: KeyboardEvent[\"key\"];\n finish: KeyboardEvent[\"key\"]\n};\n\ntype PolygonStyling = {\n fillColor: HexColor,\n outlineColor: HexColor,\n outlineWidth: number,\n fillOpacity: number,\n closingPointWidth: number,\n closingPointColor: HexColor,\n closingPointOutlineWidth: number,\n closingPointOutlineColor: HexColor\n}\n\nexport class TerraDrawPolygonMode extends TerraDrawBaseDrawMode<PolygonStyling> {\n mode = \"polygon\";\n\n private currentCoordinate = 0;\n private currentId: string | undefined;\n private allowSelfIntersections: boolean;\n private keyEvents: TerraDrawPolygonModeKeyEvents;\n private snappingEnabled: boolean;\n private isClosed = false;\n\n // Behaviors\n private snapping!: SnappingBehavior;\n private pixelDistance!: PixelDistanceBehavior;\n private closingPoints!: ClosingPointsBehavior;\n\n constructor(options?: {\n allowSelfIntersections?: boolean;\n snapping?: boolean;\n pointerDistance?: number;\n styles?: Partial<PolygonStyling>;\n keyEvents?: TerraDrawPolygonModeKeyEvents;\n }) {\n super(options);\n\n this.snappingEnabled =\n options && options.snapping !== undefined ? options.snapping : false;\n\n this.allowSelfIntersections =\n options && options.allowSelfIntersections !== undefined\n ? options.allowSelfIntersections\n : true;\n\n this.keyEvents =\n options && options.keyEvents ? options.keyEvents : { cancel: \"Escape\", finish: 'Enter' };\n }\n\n private close() {\n if (!this.currentId) {\n return;\n }\n\n const currentPolygonCoordinates = this.store.getGeometryCopy<Polygon>(\n this.currentId\n ).coordinates[0];\n\n // We don't want to allow closing if there is not enough \n // coordinates. We have extra because we insert them on mouse\n // move\n if (currentPolygonCoordinates.length < 5) {\n return;\n }\n\n this.store.updateGeometry([\n {\n id: this.currentId,\n geometry: {\n type: \"Polygon\",\n coordinates: [\n [\n ...currentPolygonCoordinates.slice(0, -2),\n currentPolygonCoordinates[0],\n ],\n ],\n },\n },\n ]);\n\n this.currentCoordinate = 0;\n this.currentId = undefined;\n this.closingPoints.delete();\n }\n\n registerBehaviors(config: BehaviorConfig) {\n this.pixelDistance = new PixelDistanceBehavior(config);\n this.snapping = new SnappingBehavior(\n config,\n this.pixelDistance,\n new ClickBoundingBoxBehavior(config)\n );\n this.closingPoints = new ClosingPointsBehavior(config, this.pixelDistance);\n }\n\n start() {\n this.setStarted();\n this.setCursor(\"crosshair\");\n }\n stop() {\n this.setStopped();\n this.setCursor(\"unset\");\n this.cleanUp();\n }\n\n onMouseMove(event: TerraDrawMouseEvent) {\n this.setCursor(\"crosshair\");\n\n if (!this.currentId || this.currentCoordinate === 0) {\n return;\n }\n\n const closestCoord = this.snappingEnabled\n ? this.snapping.getSnappableCoordinate(event, this.currentId)\n : undefined;\n\n const currentPolygonCoordinates = this.store.getGeometryCopy<Polygon>(\n this.currentId\n ).coordinates[0];\n\n if (closestCoord) {\n event.lng = closestCoord[0];\n event.lat = closestCoord[1];\n }\n\n let updatedCoordinates;\n\n if (this.currentCoordinate === 1) {\n // We must add a very small epsilon value so that Mapbox GL\n // renders the polygon - There might be a cleaner solution?\n const epsilon = 1 / Math.pow(10, this.coordinatePrecision - 1);\n const offset = Math.max(0.000001, epsilon);\n\n updatedCoordinates = [\n currentPolygonCoordinates[0],\n [event.lng, event.lat],\n [event.lng, event.lat + offset],\n currentPolygonCoordinates[0],\n ];\n } else if (this.currentCoordinate === 2) {\n\n updatedCoordinates = [\n currentPolygonCoordinates[0],\n currentPolygonCoordinates[1],\n [event.lng, event.lat],\n currentPolygonCoordinates[0],\n ];\n } else {\n\n const { isClosing, isPreviousClosing } = this.closingPoints.isClosingPoint(event);\n\n if (isPreviousClosing || isClosing) {\n this.setCursor('pointer');\n updatedCoordinates = [\n ...currentPolygonCoordinates.slice(0, -2),\n currentPolygonCoordinates[0],\n currentPolygonCoordinates[0]\n ];\n\n if (!this.isClosed) {\n this.isClosed = true;\n }\n } else {\n\n if (this.isClosed) {\n this.isClosed = false;\n }\n\n updatedCoordinates = [\n ...currentPolygonCoordinates.slice(0, -2),\n [event.lng, event.lat],\n currentPolygonCoordinates[0],\n ];\n }\n }\n\n this.store.updateGeometry([\n {\n id: this.currentId,\n geometry: {\n type: \"Polygon\",\n coordinates: [updatedCoordinates],\n },\n },\n ]);\n\n if (this.closingPoints.ids.length) {\n this.closingPoints.update(updatedCoordinates);\n }\n }\n\n onClick(event: TerraDrawMouseEvent) {\n const closestCoord =\n this.currentId && this.snappingEnabled\n ? this.snapping.getSnappableCoordinate(event, this.currentId)\n : undefined;\n\n if (this.currentCoordinate === 0) {\n if (closestCoord) {\n event.lng = closestCoord[0];\n event.lat = closestCoord[1];\n }\n\n const [newId] = this.store.create([\n {\n geometry: {\n type: \"Polygon\",\n coordinates: [\n [\n [event.lng, event.lat],\n [event.lng, event.lat],\n [event.lng, event.lat],\n [event.lng, event.lat],\n ],\n ],\n },\n properties: { mode: this.mode },\n },\n ]);\n this.currentId = newId;\n this.currentCoordinate++;\n } else if (this.currentCoordinate === 1 && this.currentId) {\n if (closestCoord) {\n event.lng = closestCoord[0];\n event.lat = closestCoord[1];\n }\n\n const currentPolygonGeometry = this.store.getGeometryCopy<Polygon>(\n this.currentId\n );\n\n const previousCoordinate = currentPolygonGeometry.coordinates[0][0];\n const isIdentical = coordinatesIdentical([event.lng, event.lat], previousCoordinate);\n\n if (isIdentical) {\n return;\n }\n\n this.store.updateGeometry([\n {\n id: this.currentId,\n geometry: {\n type: \"Polygon\",\n coordinates: [\n [\n currentPolygonGeometry.coordinates[0][0],\n [event.lng, event.lat],\n [event.lng, event.lat],\n currentPolygonGeometry.coordinates[0][0],\n ],\n ],\n },\n },\n ]);\n\n this.currentCoordinate++;\n } else if (this.currentCoordinate === 2 && this.currentId) {\n if (closestCoord) {\n event.lng = closestCoord[0];\n event.lat = closestCoord[1];\n }\n\n const currentPolygonCoordinates = this.store.getGeometryCopy<Polygon>(\n this.currentId\n ).coordinates[0];\n\n const previousCoordinate = currentPolygonCoordinates[1];\n const isIdentical = coordinatesIdentical([event.lng, event.lat], previousCoordinate);\n\n if (isIdentical) {\n return;\n }\n\n if (this.currentCoordinate === 2) {\n this.closingPoints.create(currentPolygonCoordinates, 'polygon');\n }\n\n this.store.updateGeometry([\n {\n id: this.currentId,\n geometry: {\n type: \"Polygon\",\n coordinates: [\n [\n currentPolygonCoordinates[0],\n currentPolygonCoordinates[1],\n [event.lng, event.lat],\n [event.lng, event.lat],\n currentPolygonCoordinates[0],\n ],\n ],\n },\n },\n ]);\n\n this.currentCoordinate++;\n } else if (this.currentId) {\n\n\n const currentPolygonCoordinates = this.store.getGeometryCopy<Polygon>(\n this.currentId\n ).coordinates[0];\n\n const { isClosing, isPreviousClosing } = this.closingPoints.isClosingPoint(event);\n\n if (isPreviousClosing || isClosing) {\n this.close();\n } else {\n if (closestCoord) {\n event.lng = closestCoord[0];\n event.lat = closestCoord[1];\n }\n\n const previousCoordinate = currentPolygonCoordinates[this.currentCoordinate - 1];\n const isIdentical = coordinatesIdentical([event.lng, event.lat], previousCoordinate);\n\n if (isIdentical) {\n return;\n }\n\n const updatedPolygon = createPolygon([\n [\n ...currentPolygonCoordinates.slice(0, -1),\n [event.lng, event.lat], // New point that onMouseMove can manipulate\n currentPolygonCoordinates[0],\n ],\n ]);\n\n if (this.currentCoordinate > 2 && !this.allowSelfIntersections) {\n const hasSelfIntersections = selfIntersects(updatedPolygon);\n\n if (hasSelfIntersections) {\n // Don't update the geometry!\n return;\n }\n }\n\n // If not close to the final point, keep adding points\n this.store.updateGeometry([\n { id: this.currentId, geometry: updatedPolygon.geometry },\n ]);\n this.currentCoordinate++;\n }\n }\n }\n\n onKeyUp(event: TerraDrawKeyboardEvent) {\n if (event.key === this.keyEvents.cancel) {\n this.cleanUp();\n } else if (event.key === this.keyEvents.finish) {\n this.close();\n }\n }\n\n onKeyDown() { }\n\n onDragStart() {\n // We want to allow the default drag\n // cursor to exist\n this.setCursor(\"unset\");\n }\n onDrag() { }\n onDragEnd() {\n // Set it back to crosshair\n this.setCursor(\"crosshair\");\n }\n\n cleanUp() {\n try {\n if (this.currentId) {\n this.store.delete([this.currentId]);\n }\n if (this.closingPoints.ids.length) {\n this.closingPoints.delete();\n }\n } catch (error) { }\n this.currentId = undefined;\n this.currentCoordinate = 0;\n }\n\n styleFeature(\n feature: GeoJSONStoreFeatures\n ): TerraDrawAdapterStyling {\n\n const styles = { ...getDefaultStyling() };\n\n if (feature.properties.mode === this.mode) {\n if (feature.geometry.type === 'Polygon') {\n styles.polygonFillColor = this.styles.fillColor || styles.polygonFillColor;\n styles.polygonOutlineColor = this.styles.outlineColor || styles.polygonOutlineColor;\n styles.polygonOutlineWidth = this.styles.outlineWidth || styles.polygonOutlineWidth;\n styles.polygonFillColor = this.styles.fillColor || styles.polygonFillColor;\n styles.zIndex = 10;\n return styles;\n }\n\n else if (feature.geometry.type === 'Point') {\n styles.pointWidth = this.styles.closingPointWidth || styles.pointWidth;\n styles.pointColor = this.styles.closingPointColor || styles.pointColor;\n styles.pointOutlineColor = this.styles.closingPointOutlineColor || \"#ffffff\";\n styles.pointOutlineWidth = this.styles.closingPointOutlineWidth || 2;\n styles.zIndex = 30;\n return styles;\n }\n }\n\n return styles;\n }\n}\n","import { Feature, LineString, Polygon, Position } from \"geojson\";\n\nexport function createPolygon(\n coordinates: Position[][] = [\n [\n [0, 0],\n [0, 1],\n [1, 1],\n [1, 0],\n [0, 0],\n ],\n ]\n): Feature<Polygon> {\n return {\n type: \"Feature\",\n geometry: {\n type: \"Polygon\",\n coordinates,\n },\n properties: {},\n };\n}\n\nexport function createLineString(coordinates: Position[]): Feature<LineString> {\n return {\n type: \"Feature\",\n geometry: {\n type: \"LineString\",\n coordinates,\n },\n properties: {},\n };\n}\n","import { TerraDrawAdapterStyling } from \"../../common\";\nimport { TerraDrawBaseDrawMode } from \"../base.mode\";\nimport { BehaviorConfig } from \"../base.behavior\";\nimport { getDefaultStyling } from \"../../util/styling\";\n\n// eslint-disable-next-line @typescript-eslint/ban-types\ntype RenderModeStylingExt<T extends TerraDrawAdapterStyling> = {}\ntype RenderModeStyling = RenderModeStylingExt<TerraDrawAdapterStyling>\n\nexport class TerraDrawRenderMode extends TerraDrawBaseDrawMode<RenderModeStyling> {\n public mode = \"render\"; // This gets changed dynamically\n\n constructor(options: { styles: Partial<TerraDrawAdapterStyling> }) {\n super({ styles: options.styles });\n }\n\n // TODO: this is probably abusing\n // registerBehaviors but it works quite well conceptually\n registerBehaviors(behaviorConfig: BehaviorConfig) {\n // We can set the mode name dynamically\n this.mode = behaviorConfig.mode;\n }\n\n start() {\n this.setStarted();\n }\n stop() {\n this.setStopped();\n }\n onKeyUp() { }\n onKeyDown() { }\n onClick() { }\n onDragStart() { }\n onDrag() { }\n onDragEnd() { }\n onMouseMove() { }\n styleFeature(): TerraDrawAdapterStyling {\n return {\n ...getDefaultStyling(),\n ...this.styles\n };\n }\n}\n","import { Position } from \"geojson\";\nimport { destination } from \"./shape/create-circle\";\nimport { degreesToRadians, radiansToDegrees } from \"./helpers\";\nimport { limitPrecision } from \"./limit-decimal-precision\";\nimport { haversineDistanceKilometers } from \"./measure/haversine-distance\";\n\n// Based on turf-bearing: https://github.com/Turfjs/turf/tree/master/packages/turf-bearing\n\nfunction bearing(coordinates1: Position, coordinates2: Position) {\n const lon1 = degreesToRadians(coordinates1[0]);\n const lon2 = degreesToRadians(coordinates2[0]);\n const lat1 = degreesToRadians(coordinates1[1]);\n const lat2 = degreesToRadians(coordinates2[1]);\n const a = Math.sin(lon2 - lon1) * Math.cos(lat2);\n const b =\n Math.cos(lat1) * Math.sin(lat2) -\n Math.sin(lat1) * Math.cos(lat2) * Math.cos(lon2 - lon1);\n\n return radiansToDegrees(Math.atan2(a, b));\n}\n\n// Based on turf-midpoint: https://github.com/Turfjs/turf/tree/master/packages/turf-midpoint\n\nexport function midpointCoordinate(\n coordinates1: Position,\n coordinates2: Position,\n precision: number\n) {\n const dist = haversineDistanceKilometers(coordinates1, coordinates2);\n const heading = bearing(coordinates1, coordinates2);\n const midpoint = destination(coordinates1, dist / 2, heading);\n\n return [\n limitPrecision(midpoint[0], precision),\n limitPrecision(midpoint[1], precision),\n ];\n}\n","import { Point, Position } from \"geojson\";\nimport { JSONObject } from \"../store/store\";\nimport { midpointCoordinate } from \"./midpoint-coordinate\";\n\nexport function getMidPointCoordinates(\n featureCoords: Position[],\n precision: number\n) {\n const midPointCoords: Position[] = [];\n for (let i = 0; i < featureCoords.length - 1; i++) {\n const mid = midpointCoordinate(\n featureCoords[i],\n featureCoords[i + 1],\n precision\n );\n midPointCoords.push(mid);\n }\n return midPointCoords;\n}\n\nexport function getMidPoints(\n selectedCoords: Position[],\n properties: (index: number) => JSONObject,\n precision: number\n) {\n return getMidPointCoordinates(selectedCoords, precision).map((coord, i) => ({\n geometry: { type: \"Point\", coordinates: coord } as Point,\n properties: properties(i),\n }));\n}\n","import { LineString, Point, Polygon, Position } from \"geojson\";\nimport { BehaviorConfig, TerraDrawModeBehavior } from \"../../base.behavior\";\nimport {\n getMidPointCoordinates,\n getMidPoints,\n} from \"../../../geometry/get-midpoints\";\nimport { SelectionPointBehavior } from \"./selection-point.behavior\";\nimport { SELECT_PROPERTIES } from \"../../../common\";\n\nexport class MidPointBehavior extends TerraDrawModeBehavior {\n constructor(\n readonly config: BehaviorConfig,\n private readonly selectionPointBehavior: SelectionPointBehavior\n ) {\n super(config);\n }\n\n private _midPoints: string[] = [];\n\n get ids() {\n return this._midPoints.concat();\n }\n\n set ids(_: string[]) {}\n\n public insert(midPointId: string, coordinatePrecision: number) {\n const midPoint = this.store.getGeometryCopy(midPointId);\n const { midPointFeatureId, midPointSegment } =\n this.store.getPropertiesCopy(midPointId);\n const geometry = this.store.getGeometryCopy<Polygon | LineString>(\n midPointFeatureId as string\n );\n\n // Update the coordinates to include inserted midpoint\n const updatedCoordinates =\n geometry.type === \"Polygon\"\n ? geometry.coordinates[0]\n : geometry.coordinates;\n\n updatedCoordinates.splice(\n (midPointSegment as number) + 1,\n 0,\n midPoint.coordinates as Position\n );\n\n // Update geometry coordinates depending\n // on if a polygon or linestring\n geometry.coordinates =\n geometry.type === \"Polygon\" ? [updatedCoordinates] : updatedCoordinates;\n\n // Update the selected features geometry to insert\n // the new midpoint\n this.store.updateGeometry([{ id: midPointFeatureId as string, geometry }]);\n\n // TODO: is there a way of just updating the selection points rather\n // than fully deleting / recreating?\n // Recreate the selection points\n\n this.store.delete([...this._midPoints, ...this.selectionPointBehavior.ids]);\n\n // We don't need to check if flags are correct\n // because selection points are prerequiste for midpoints\n this.create(\n updatedCoordinates,\n midPointFeatureId as string,\n coordinatePrecision\n );\n this.selectionPointBehavior.create(\n updatedCoordinates,\n geometry.type,\n midPointFeatureId as string\n );\n }\n\n public create(\n selectedCoords: Position[],\n featureId: string,\n coordinatePrecision: number\n ) {\n if (!this.store.has(featureId)) {\n throw new Error(\"Store does not have feature with this id\");\n }\n\n this._midPoints = this.store.create(\n getMidPoints(\n selectedCoords,\n (i) => ({\n mode: this.mode,\n [SELECT_PROPERTIES.MID_POINT]: true,\n midPointSegment: i,\n midPointFeatureId: featureId,\n }),\n coordinatePrecision\n )\n );\n }\n\n public delete() {\n if (this._midPoints.length) {\n this.store.delete(this._midPoints);\n this._midPoints = [];\n }\n }\n\n public getUpdated(updatedCoordinates: Position[]) {\n if (this._midPoints.length === 0) {\n return undefined;\n }\n\n return getMidPointCoordinates(\n updatedCoordinates,\n this.coordinatePrecision\n ).map((updatedMidPointCoord, i) => ({\n id: this._midPoints[i] as string,\n geometry: {\n type: \"Point\",\n coordinates: updatedMidPointCoord,\n } as Point,\n }));\n }\n}\n","import { LineString, Point, Polygon, Position } from \"geojson\";\nimport { BehaviorConfig, TerraDrawModeBehavior } from \"../../base.behavior\";\nimport { getCoordinatesAsPoints } from \"../../../geometry/get-coordinates-as-points\";\n\nexport class SelectionPointBehavior extends TerraDrawModeBehavior {\n constructor(config: BehaviorConfig) {\n super(config);\n }\n\n private _selectionPoints: string[] = [];\n\n get ids() {\n return this._selectionPoints.concat();\n }\n\n set ids(_: string[]) {}\n\n public create(\n selectedCoords: Position[],\n type: Polygon[\"type\"] | LineString[\"type\"],\n featureId: string\n ) {\n this._selectionPoints = this.store.create(\n getCoordinatesAsPoints(selectedCoords, type, (i) => ({\n mode: this.mode,\n selectionPoint: true,\n selectionPointFeatureId: featureId,\n index: i,\n }))\n );\n }\n\n public delete() {\n if (this.ids.length) {\n this.store.delete(this.ids);\n this._selectionPoints = [];\n }\n }\n\n public getUpdated(updatedCoordinates: Position[]) {\n if (this._selectionPoints.length === 0) {\n return undefined;\n }\n\n return this._selectionPoints.map((id, i) => {\n return {\n id,\n geometry: {\n type: \"Point\",\n coordinates: updatedCoordinates[i],\n } as Point,\n };\n });\n }\n\n public getOneUpdated(index: number, updatedCoordinate: Position) {\n if (this._selectionPoints[index] === undefined) {\n return undefined;\n }\n\n return {\n id: this._selectionPoints[index] as string,\n geometry: {\n type: \"Point\",\n coordinates: updatedCoordinate,\n } as Point,\n };\n }\n}\n","import { Point, Position } from \"geojson\";\nimport { JSONObject } from \"../store/store\";\n\nexport function getCoordinatesAsPoints(\n selectedCoords: Position[],\n geometryType: \"Polygon\" | \"LineString\",\n properties: (index: number) => JSONObject\n) {\n const selectionPoints = [];\n\n // We can skip the last point for polygons\n // as it's a duplicate of the first\n const length =\n geometryType === \"Polygon\"\n ? selectedCoords.length - 1\n : selectedCoords.length;\n\n for (let i = 0; i < length; i++) {\n selectionPoints.push({\n geometry: {\n type: \"Point\",\n coordinates: selectedCoords[i],\n } as Point,\n properties: properties(i),\n });\n }\n\n return selectionPoints;\n}\n","import { Position } from \"geojson\";\n\n// Based on which-polygon (Mapbox)\n// https://github.com/mapbox/which-polygon/blob/2eb5b8a427d018ebd964c05acd3b9166c4558b2c/index.js#L81\n// ISC License - Copyright (c) 2017, Mapbox\n\nexport function pointInPolygon(point: Position, rings: Position[][]) {\n let inside = false;\n for (let i = 0, len = rings.length; i < len; i++) {\n const ring = rings[i];\n for (let j = 0, len2 = ring.length, k = len2 - 1; j < len2; k = j++) {\n if (rayIntersect(point, ring[j], ring[k])) {\n inside = !inside;\n }\n }\n }\n return inside;\n}\n\nfunction rayIntersect(p: Position, p1: Position, p2: Position) {\n return (\n p1[1] > p[1] !== p2[1] > p[1] &&\n p[0] < ((p2[0] - p1[0]) * (p[1] - p1[1])) / (p2[1] - p1[1]) + p1[0]\n );\n}\n","export const pixelDistanceToLine = (\n point: { x: number; y: number },\n linePointOne: { x: number; y: number },\n linePointTwo: { x: number; y: number }\n) => {\n const square = (x: number) => {\n return x * x;\n };\n const dist2 = (v: { x: number; y: number }, w: { x: number; y: number }) => {\n return square(v.x - w.x) + square(v.y - w.y);\n };\n const distToSegmentSquared = (\n p: { x: number; y: number },\n v: { x: number; y: number },\n w: { x: number; y: number }\n ) => {\n const l2 = dist2(v, w);\n\n if (l2 === 0) {\n return dist2(p, v);\n }\n\n let t = ((p.x - v.x) * (w.x - v.x) + (p.y - v.y) * (w.y - v.y)) / l2;\n t = Math.max(0, Math.min(1, t));\n\n return dist2(p, { x: v.x + t * (w.x - v.x), y: v.y + t * (w.y - v.y) });\n };\n\n return Math.sqrt(distToSegmentSquared(point, linePointOne, linePointTwo));\n};\n","import { SELECT_PROPERTIES, TerraDrawMouseEvent } from \"../../../common\";\nimport { BBoxPolygon, GeoJSONStoreFeatures } from \"../../../store/store\";\n\nimport { BehaviorConfig, TerraDrawModeBehavior } from \"../../base.behavior\";\nimport { ClickBoundingBoxBehavior } from \"../../click-bounding-box.behavior\";\n\nimport { pointInPolygon } from \"../../../geometry/boolean/point-in-polygon\";\nimport { PixelDistanceBehavior } from \"../../pixel-distance.behavior\";\nimport { pixelDistanceToLine } from \"../../../geometry/measure/pixel-distance-to-line\";\n\nexport class FeaturesAtMouseEventBehavior extends TerraDrawModeBehavior {\n constructor(\n readonly config: BehaviorConfig,\n private readonly createClickBoundingBox: ClickBoundingBoxBehavior,\n private readonly pixelDistance: PixelDistanceBehavior\n ) {\n super(config);\n }\n\n public find(event: TerraDrawMouseEvent, hasSelection: boolean) {\n let clickedFeature: GeoJSONStoreFeatures | undefined = undefined;\n let clickedFeatureDistance = Infinity;\n let clickedMidPoint: GeoJSONStoreFeatures | undefined = undefined;\n let clickedMidPointDistance = Infinity;\n\n const bbox = this.createClickBoundingBox.create(event);\n const features = this.store.search(bbox as BBoxPolygon);\n\n for (let i = 0; i < features.length; i++) {\n const feature = features[i];\n const geometry = feature.geometry;\n\n if (geometry.type === \"Point\") {\n // Ignore selection points always, and ignore mid points\n // when nothing is selected\n const isSelectionPoint = feature.properties.selectionPoint;\n const isNonSelectedMidPoint =\n !hasSelection && feature.properties[SELECT_PROPERTIES.MID_POINT];\n\n if (isSelectionPoint || isNonSelectedMidPoint) {\n continue;\n }\n\n const distance = this.pixelDistance.measure(\n event,\n\n geometry.coordinates\n );\n\n // We want to catch both clicked\n // features but also any midpoints\n // in the clicked area\n if (\n feature.properties[SELECT_PROPERTIES.MID_POINT] &&\n distance < this.pointerDistance &&\n distance < clickedMidPointDistance\n ) {\n clickedMidPointDistance = distance;\n clickedMidPoint = feature;\n } else if (\n !feature.properties[SELECT_PROPERTIES.MID_POINT] &&\n distance < this.pointerDistance &&\n distance < clickedFeatureDistance\n ) {\n clickedFeatureDistance = distance;\n clickedFeature = feature;\n }\n } else if (geometry.type === \"LineString\") {\n for (let i = 0; i < geometry.coordinates.length - 1; i++) {\n const coord = geometry.coordinates[i];\n const nextCoord = geometry.coordinates[i + 1];\n const distanceToLine = pixelDistanceToLine(\n { x: event.containerX, y: event.containerY },\n this.project(coord[0], coord[1]),\n this.project(nextCoord[0], nextCoord[1])\n );\n\n if (\n distanceToLine < this.pointerDistance &&\n distanceToLine < clickedFeatureDistance\n ) {\n clickedFeatureDistance = distanceToLine;\n clickedFeature = feature;\n }\n }\n } else if (geometry.type === \"Polygon\") {\n const clickInsidePolygon = pointInPolygon(\n [event.lng, event.lat],\n geometry.coordinates\n );\n\n if (clickInsidePolygon) {\n clickedFeatureDistance = 0;\n clickedFeature = feature;\n }\n }\n }\n\n return { clickedFeature, clickedMidPoint };\n }\n}\n","import { TerraDrawMouseEvent } from \"../../../common\";\nimport { BehaviorConfig, TerraDrawModeBehavior } from \"../../base.behavior\";\nimport { FeaturesAtMouseEventBehavior } from \"./features-at-mouse-event.behavior\";\nimport { Position } from \"geojson\";\nimport { SelectionPointBehavior } from \"./selection-point.behavior\";\nimport { MidPointBehavior } from \"./midpoint.behavior\";\n\nexport class DragFeatureBehavior extends TerraDrawModeBehavior {\n constructor(\n readonly config: BehaviorConfig,\n private readonly featuresAtMouseEvent: FeaturesAtMouseEventBehavior,\n private readonly selectionPoints: SelectionPointBehavior,\n private readonly midPoints: MidPointBehavior\n ) {\n super(config);\n }\n\n private dragPosition: Position | undefined;\n\n get position() {\n return this.dragPosition ? this.dragPosition.concat() : undefined;\n }\n\n set position(newPosition: undefined | Position) {\n if (newPosition === undefined) {\n this.dragPosition = undefined;\n return;\n }\n\n if (\n !Array.isArray(newPosition) ||\n newPosition.length !== 2 ||\n typeof newPosition[0] !== \"number\" ||\n typeof newPosition[1] !== \"number\"\n ) {\n throw new Error(\"Position must be [number, number] array\");\n }\n\n this.dragPosition = newPosition.concat();\n }\n\n drag(event: TerraDrawMouseEvent, selectedId: string) {\n const hasSelection = true;\n const { clickedFeature } = this.featuresAtMouseEvent.find(\n event,\n hasSelection\n );\n\n // If the cursor is not over the selected\n // feature then we don't want to drag\n if (!clickedFeature || clickedFeature.id !== selectedId) {\n return;\n }\n\n const geometry = this.store.getGeometryCopy(selectedId);\n const mouseCoord = [event.lng, event.lat];\n\n // Update the geometry of the dragged feature\n if (geometry.type === \"Polygon\" || geometry.type === \"LineString\") {\n let updatedCoords: Position[] | undefined;\n let upToCoord: number | undefined;\n\n if (geometry.type === \"Polygon\") {\n updatedCoords = geometry.coordinates[0];\n upToCoord = updatedCoords.length - 1;\n } else if (geometry.type === \"LineString\") {\n updatedCoords = geometry.coordinates;\n upToCoord = updatedCoords.length;\n }\n\n if (upToCoord === undefined || !updatedCoords || !this.dragPosition) {\n return false;\n }\n\n for (let i = 0; i < upToCoord; i++) {\n const coordinate = updatedCoords[i];\n const delta = [\n this.dragPosition[0] - mouseCoord[0],\n this.dragPosition[1] - mouseCoord[1],\n ];\n updatedCoords[i] = [coordinate[0] - delta[0], coordinate[1] - delta[1]];\n }\n\n // Set final coordinate identical to first\n // We only want to do this for polygons!\n if (geometry.type === \"Polygon\") {\n updatedCoords[updatedCoords.length - 1] = [\n updatedCoords[0][0],\n updatedCoords[0][1],\n ];\n }\n\n const updatedSelectionPoints =\n this.selectionPoints.getUpdated(updatedCoords) || [];\n\n const updatedMidPoints = this.midPoints.getUpdated(updatedCoords) || [];\n\n // Issue the update to the selected feature\n this.store.updateGeometry([\n { id: selectedId, geometry },\n ...updatedSelectionPoints,\n ...updatedMidPoints,\n ]);\n\n // Update mid point positions\n } else if (geometry.type === \"Point\") {\n // For mouse points we can simply move it\n // to the dragged position\n this.store.updateGeometry([\n {\n id: selectedId,\n geometry: {\n type: \"Point\",\n coordinates: mouseCoord,\n },\n },\n ]);\n }\n }\n}\n","import { TerraDrawMouseEvent } from \"../../../common\";\nimport { BehaviorConfig, TerraDrawModeBehavior } from \"../../base.behavior\";\n\nimport { Position } from \"geojson\";\nimport { PixelDistanceBehavior } from \"../../pixel-distance.behavior\";\nimport { MidPointBehavior } from \"./midpoint.behavior\";\nimport { SelectionPointBehavior } from \"./selection-point.behavior\";\n\nexport class DragCoordinateBehavior extends TerraDrawModeBehavior {\n constructor(\n readonly config: BehaviorConfig,\n private readonly pixelDistance: PixelDistanceBehavior,\n private readonly selectionPoints: SelectionPointBehavior,\n private readonly midPoints: MidPointBehavior\n ) {\n super(config);\n }\n\n public drag(event: TerraDrawMouseEvent, selectedId: string): boolean {\n const geometry = this.store.getGeometryCopy(selectedId);\n\n let geomCoordinates: Position[] | undefined;\n\n if (geometry.type === \"LineString\") {\n geomCoordinates = geometry.coordinates;\n } else if (geometry.type === \"Polygon\") {\n geomCoordinates = geometry.coordinates[0];\n } else {\n // We don't want to handle dragging\n // points here\n return false;\n }\n\n const closestCoordinate = {\n dist: Infinity,\n index: -1,\n isFirstOrLastPolygonCoord: false,\n };\n\n // Look through the selected features coordinates\n // and try to find a coordinate that is draggable\n for (let i = 0; i < geomCoordinates.length; i++) {\n const coord = geomCoordinates[i];\n const distance = this.pixelDistance.measure(event, coord);\n\n if (\n distance < this.pointerDistance &&\n distance < closestCoordinate.dist\n ) {\n // We don't create a point for the final\n // polygon coord, so we must set it to the first\n // coordinate instead\n const isFirstOrLastPolygonCoord =\n geometry.type === \"Polygon\" &&\n (i === geomCoordinates.length - 1 || i === 0);\n\n closestCoordinate.dist = distance;\n closestCoordinate.index = isFirstOrLastPolygonCoord ? 0 : i;\n closestCoordinate.isFirstOrLastPolygonCoord = isFirstOrLastPolygonCoord;\n }\n }\n\n // No coordinate was within the pointer distance\n if (closestCoordinate.index === -1) {\n return false;\n }\n\n // Store the updated coord\n const updatedCoordinate = [event.lng, event.lat];\n\n // We want to update the actual Polygon/LineString itself -\n // for Polygons we want the first and last coordinates to match\n if (closestCoordinate.isFirstOrLastPolygonCoord) {\n const lastCoordIndex = geomCoordinates.length - 1;\n geomCoordinates[0] = updatedCoordinate;\n geomCoordinates[lastCoordIndex] = updatedCoordinate;\n } else {\n geomCoordinates[closestCoordinate.index] = updatedCoordinate;\n }\n\n const updatedSelectionPoint = this.selectionPoints.getOneUpdated(\n closestCoordinate.index,\n updatedCoordinate\n );\n\n const updatedSelectionPoints = updatedSelectionPoint\n ? [updatedSelectionPoint]\n : [];\n\n const updatedMidPoints = this.midPoints.getUpdated(geomCoordinates) || [];\n\n // Apply all the updates\n this.store.updateGeometry([\n // Update feature\n {\n id: selectedId,\n geometry: geometry,\n },\n // Update selection and mid points\n ...updatedSelectionPoints,\n ...updatedMidPoints,\n ]);\n\n return true;\n }\n}\n","import { Feature, LineString, Polygon, Position } from \"geojson\";\n\n// Based on turf-bearing: https://github.com/Turfjs/turf/tree/master/packages/turf-centroid\n\nexport function centroid(geojson: Feature<Polygon | LineString>): Position {\n let xSum = 0;\n let ySum = 0;\n let len = 0;\n\n const coordinates =\n geojson.geometry.type === \"Polygon\"\n ? geojson.geometry.coordinates[0].slice(0, -1)\n : geojson.geometry.coordinates;\n\n coordinates.forEach((coord: Position) => {\n xSum += coord[0];\n ySum += coord[1];\n len++;\n }, true);\n\n return [xSum / len, ySum / len];\n}\n","import { Position } from \"geojson\";\nimport { degreesToRadians, radiansToDegrees } from \"../helpers\";\n\n// Based on Turf.js Rhumb Bearing module\n// https://github.com/Turfjs/turf/blob/master/packages/turf-rhumb-bearing/index.ts\n\nexport function rhumbBearing(start: Position, end: Position): number {\n const from = start;\n const to = end;\n\n // φ => phi\n // Δλ => deltaLambda\n // Δψ => deltaPsi\n // θ => theta\n const phi1 = degreesToRadians(from[1]);\n const phi2 = degreesToRadians(to[1]);\n let deltaLambda = degreesToRadians(to[0] - from[0]);\n\n // if deltaLambdaon over 180° take shorter rhumb line across the anti-meridian:\n if (deltaLambda > Math.PI) {\n deltaLambda -= 2 * Math.PI;\n }\n if (deltaLambda < -Math.PI) {\n deltaLambda += 2 * Math.PI;\n }\n\n const deltaPsi = Math.log(\n Math.tan(phi2 / 2 + Math.PI / 4) / Math.tan(phi1 / 2 + Math.PI / 4)\n );\n\n const theta = Math.atan2(deltaLambda, deltaPsi);\n\n const bear360 = (radiansToDegrees(theta) + 360) % 360;\n\n const bear180 = bear360 > 180 ? -(360 - bear360) : bear360;\n\n return bear180;\n}\n","import { Position } from \"geojson\";\nimport { degreesToRadians, earthRadius } from \"../helpers\";\n\n// Based on Turf.js Rhumb Destination module\n// https://github.com/Turfjs/turf/blob/master/packages/turf-rhumb-destination/index.ts\n\nexport function rhumbDestination(\n origin: Position,\n distanceMeters: number,\n bearing: number\n): Position {\n const wasNegativeDistance = distanceMeters < 0;\n let distanceInMeters = distanceMeters;\n\n if (wasNegativeDistance) {\n distanceInMeters = -Math.abs(distanceInMeters);\n }\n\n const delta = distanceMeters / earthRadius; // angular distance in radians\n const lambda1 = (origin[0] * Math.PI) / 180; // to radians, but without normalize to 𝜋\n const phi1 = degreesToRadians(origin[1]);\n const theta = degreesToRadians(bearing);\n\n const DeltaPhi = delta * Math.cos(theta);\n let phi2 = phi1 + DeltaPhi;\n\n // check for going past the pole, normalise latitude if so\n if (Math.abs(phi2) > Math.PI / 2) {\n phi2 = phi2 > 0 ? Math.PI - phi2 : -Math.PI - phi2;\n }\n\n const DeltaPsi = Math.log(\n Math.tan(phi2 / 2 + Math.PI / 4) / Math.tan(phi1 / 2 + Math.PI / 4)\n );\n // E-W course becomes ill-conditioned with 0/0\n const q = Math.abs(DeltaPsi) > 10e-12 ? DeltaPhi / DeltaPsi : Math.cos(phi1);\n\n const DeltaLambda = (delta * Math.sin(theta)) / q;\n const lambda2 = lambda1 + DeltaLambda;\n\n // normalise to −180..+180°\n const destination = [\n (((lambda2 * 180) / Math.PI + 540) % 360) - 180,\n (phi2 * 180) / Math.PI,\n ];\n\n // compensate the crossing of the 180th meridian (https://macwright.org/2016/09/26/the-180th-meridian.html)\n // solution from https://github.com/mapbox/mapbox-gl-js/issues/3250#issuecomment-294887678\n destination[0] +=\n destination[0] - origin[0] > 180\n ? -360\n : origin[0] - destination[0] > 180\n ? 360\n : 0;\n return destination;\n}\n","import { Position } from \"geojson\";\nimport { earthRadius } from \"../helpers\";\n\n// Based on Turf.js Rhumb Distance module\n// https://github.com/Turfjs/turf/blob/master/packages/turf-rhumb-distance/index.ts\n\nexport function rhumbDistance(destination: Position, origin: Position): number {\n // compensate the crossing of the 180th meridian (https://macwright.org/2016/09/26/the-180th-meridian.html)\n // solution from https://github.com/mapbox/mapbox-gl-js/issues/3250#issuecomment-294887678\n destination[0] +=\n destination[0] - origin[0] > 180\n ? -360\n : origin[0] - destination[0] > 180\n ? 360\n : 0;\n\n // see www.edwilliams.org/avform.htm#Rhumb\n\n const R = earthRadius;\n const phi1 = (origin[1] * Math.PI) / 180;\n const phi2 = (destination[1] * Math.PI) / 180;\n const DeltaPhi = phi2 - phi1;\n let DeltaLambda = (Math.abs(destination[0] - origin[0]) * Math.PI) / 180;\n\n // if dLon over 180° take shorter rhumb line across the anti-meridian:\n if (DeltaLambda > Math.PI) {\n DeltaLambda -= 2 * Math.PI;\n }\n\n // on Mercator projection, longitude distances shrink by latitude; q is the 'stretch factor'\n // q becomes ill-conditioned along E-W line (0/0); use empirical tolerance to avoid it\n const DeltaPsi = Math.log(\n Math.tan(phi2 / 2 + Math.PI / 4) / Math.tan(phi1 / 2 + Math.PI / 4)\n );\n const q = Math.abs(DeltaPsi) > 10e-12 ? DeltaPhi / DeltaPsi : Math.cos(phi1);\n\n // distance is pythagoras on 'stretched' Mercator projection\n const delta = Math.sqrt(\n DeltaPhi * DeltaPhi + q * q * DeltaLambda * DeltaLambda\n ); // angular distance in radians\n\n const distanceMeters = delta * R;\n\n return distanceMeters;\n}\n","import { TerraDrawMouseEvent } from \"../../../common\";\nimport { BehaviorConfig, TerraDrawModeBehavior } from \"../../base.behavior\";\nimport { LineString, Polygon, Position } from \"geojson\";\nimport { SelectionPointBehavior } from \"./selection-point.behavior\";\nimport { MidPointBehavior } from \"./midpoint.behavior\";\nimport { transformRotate } from \"../../../geometry/transform/rotate\";\nimport { centroid } from \"../../../geometry/centroid\";\nimport { rhumbBearing } from \"../../../geometry/measure/rhumb-bearing\";\nimport { limitPrecision } from \"../../../geometry/limit-decimal-precision\";\n\nexport class RotateFeatureBehavior extends TerraDrawModeBehavior {\n constructor(\n readonly config: BehaviorConfig,\n private readonly selectionPoints: SelectionPointBehavior,\n private readonly midPoints: MidPointBehavior\n ) {\n super(config);\n }\n\n private lastBearing: number | undefined;\n\n reset() {\n this.lastBearing = undefined;\n }\n\n rotate(event: TerraDrawMouseEvent, selectedId: string) {\n const geometry = this.store.getGeometryCopy<LineString | Polygon>(\n selectedId\n );\n\n // Update the geometry of the dragged feature\n if (geometry.type !== \"Polygon\" && geometry.type !== \"LineString\") {\n return;\n }\n\n const mouseCoord = [event.lng, event.lat];\n\n const bearing = rhumbBearing(\n centroid({ type: \"Feature\", geometry, properties: {} }),\n mouseCoord\n );\n\n // We need an original bearing to compare against\n if (!this.lastBearing) {\n this.lastBearing = bearing + 180;\n return;\n }\n\n const angle = this.lastBearing - (bearing + 180);\n\n transformRotate({ type: \"Feature\", geometry, properties: {} }, -angle);\n\n let updatedCoords: Position[] | undefined;\n\n if (geometry.type === \"Polygon\") {\n updatedCoords = geometry.coordinates[0];\n } else if (geometry.type === \"LineString\") {\n updatedCoords = geometry.coordinates;\n } else {\n return;\n }\n\n // Ensure that coordinate precision is maintained\n updatedCoords.forEach((coordinate) => {\n coordinate[0] = limitPrecision(coordinate[0], this.coordinatePrecision);\n coordinate[1] = limitPrecision(coordinate[1], this.coordinatePrecision);\n });\n\n const updatedMidPoints = this.midPoints.getUpdated(updatedCoords) || [];\n\n const updatedSelectionPoints =\n this.selectionPoints.getUpdated(updatedCoords) || [];\n\n // Issue the update to the selected feature\n this.store.updateGeometry([\n { id: selectedId, geometry },\n ...updatedSelectionPoints,\n ...updatedMidPoints,\n ]);\n\n this.lastBearing = bearing + 180;\n }\n}\n","import { Feature, LineString, Polygon, Position } from \"geojson\";\nimport { centroid } from \"../centroid\";\nimport { rhumbBearing } from \"../measure/rhumb-bearing\";\nimport { rhumbDestination } from \"../measure/rhumb-destination\";\nimport { rhumbDistance } from \"../measure/rhumb-distance\";\n\n// Based on turf-transform-rotate: https://github.com/Turfjs/turf/tree/master/packages/turf-transform-rotate\n\nexport function transformRotate(\n geojson: Feature<Polygon | LineString>,\n angle: number\n) {\n // Shortcut no-rotation\n if (angle === 0) {\n return geojson;\n }\n\n // Use centroid of GeoJSON if pivot is not provided\n const pivot = centroid(geojson);\n\n const cooordinates =\n geojson.geometry.type === \"Polygon\"\n ? geojson.geometry.coordinates[0]\n : geojson.geometry.coordinates;\n\n cooordinates.forEach((pointCoords: Position) => {\n const initialAngle = rhumbBearing(pivot, pointCoords);\n const finalAngle = initialAngle + angle;\n const distance = rhumbDistance(pivot, pointCoords);\n const newCoords = rhumbDestination(pivot, distance, finalAngle);\n pointCoords[0] = newCoords[0];\n pointCoords[1] = newCoords[1];\n });\n\n return geojson;\n}\n","import { TerraDrawMouseEvent } from \"../../../common\";\nimport { BehaviorConfig, TerraDrawModeBehavior } from \"../../base.behavior\";\nimport { LineString, Polygon, Position } from \"geojson\";\nimport { SelectionPointBehavior } from \"./selection-point.behavior\";\nimport { MidPointBehavior } from \"./midpoint.behavior\";\nimport { centroid } from \"../../../geometry/centroid\";\nimport { haversineDistanceKilometers } from \"../../../geometry/measure/haversine-distance\";\nimport { transformScale } from \"../../../geometry/transform/scale\";\nimport { limitPrecision } from \"../../../geometry/limit-decimal-precision\";\n\nexport class ScaleFeatureBehavior extends TerraDrawModeBehavior {\n constructor(\n readonly config: BehaviorConfig,\n private readonly selectionPoints: SelectionPointBehavior,\n private readonly midPoints: MidPointBehavior\n ) {\n super(config);\n }\n\n private lastDistance: number | undefined;\n\n reset() {\n this.lastDistance = undefined;\n }\n\n scale(event: TerraDrawMouseEvent, selectedId: string) {\n const geometry = this.store.getGeometryCopy<LineString | Polygon>(\n selectedId\n );\n\n // Update the geometry of the dragged feature\n if (geometry.type !== \"Polygon\" && geometry.type !== \"LineString\") {\n return;\n }\n\n const mouseCoord = [event.lng, event.lat];\n\n const distance = haversineDistanceKilometers(\n centroid({ type: \"Feature\", geometry, properties: {} }),\n mouseCoord\n );\n\n // We need an original bearing to compare against\n if (!this.lastDistance) {\n this.lastDistance = distance;\n return;\n }\n\n const scale = 1 - (this.lastDistance - distance) / distance;\n\n transformScale({ type: \"Feature\", geometry, properties: {} }, scale);\n\n let updatedCoords: Position[] | undefined;\n\n if (geometry.type === \"Polygon\") {\n updatedCoords = geometry.coordinates[0];\n } else if (geometry.type === \"LineString\") {\n updatedCoords = geometry.coordinates;\n } else {\n return;\n }\n\n // Ensure that coordinate precision is maintained\n updatedCoords.forEach((coordinate) => {\n coordinate[0] = limitPrecision(coordinate[0], this.coordinatePrecision);\n coordinate[1] = limitPrecision(coordinate[1], this.coordinatePrecision);\n });\n\n const updatedMidPoints = this.midPoints.getUpdated(updatedCoords) || [];\n\n const updatedSelectionPoints =\n this.selectionPoints.getUpdated(updatedCoords) || [];\n\n // Issue the update to the selected feature\n this.store.updateGeometry([\n { id: selectedId, geometry },\n ...updatedSelectionPoints,\n ...updatedMidPoints,\n ]);\n\n this.lastDistance = distance;\n }\n}\n","import { Feature, LineString, Polygon, Position } from \"geojson\";\nimport { centroid } from \"../centroid\";\nimport { rhumbBearing } from \"../measure/rhumb-bearing\";\nimport { rhumbDestination } from \"../measure/rhumb-destination\";\nimport { rhumbDistance } from \"../measure/rhumb-distance\";\n\n// Based on turf-transform-scale: https://github.com/Turfjs/turf/tree/master/packages/turf-transform-scale\n\nexport function transformScale(\n feature: Feature<Polygon | LineString>,\n factor: number\n) {\n // Shortcut no-scaling\n if (factor === 1) {\n return feature;\n }\n\n const origin = centroid(feature);\n\n const cooordinates =\n feature.geometry.type === \"Polygon\"\n ? feature.geometry.coordinates[0]\n : feature.geometry.coordinates;\n\n cooordinates.forEach((pointCoords: Position) => {\n const originalDistance = rhumbDistance(origin, pointCoords);\n const bearing = rhumbBearing(origin, pointCoords);\n const newDistance = originalDistance * factor;\n const newCoord = rhumbDestination(origin, newDistance, bearing);\n pointCoords[0] = newCoord[0];\n pointCoords[1] = newCoord[1];\n });\n\n return feature;\n}\n","import {\n TerraDrawMouseEvent,\n TerraDrawKeyboardEvent,\n SELECT_PROPERTIES,\n HexColor,\n TerraDrawAdapterStyling,\n} from \"../../common\";\nimport { Point, Position } from \"geojson\";\nimport { TerraDrawBaseDrawMode } from \"../base.mode\";\nimport { MidPointBehavior } from \"./behaviors/midpoint.behavior\";\nimport { SelectionPointBehavior } from \"./behaviors/selection-point.behavior\";\nimport { FeaturesAtMouseEventBehavior } from \"./behaviors/features-at-mouse-event.behavior\";\nimport { PixelDistanceBehavior } from \"../pixel-distance.behavior\";\nimport { ClickBoundingBoxBehavior } from \"../click-bounding-box.behavior\";\nimport { DragFeatureBehavior } from \"./behaviors/drag-feature.behavior\";\nimport { DragCoordinateBehavior } from \"./behaviors/drag-coordinate.behavior\";\nimport { BehaviorConfig } from \"../base.behavior\";\nimport { RotateFeatureBehavior } from \"./behaviors/rotate-feature.behavior\";\nimport { ScaleFeatureBehavior } from \"./behaviors/scale-feature.behavior\";\nimport { GeoJSONStoreFeatures } from \"../../store/store\";\nimport { getDefaultStyling } from \"../../util/styling\";\n\ntype TerraDrawSelectModeKeyEvents = {\n deselect: KeyboardEvent[\"key\"];\n delete: KeyboardEvent[\"key\"];\n rotate: KeyboardEvent[\"key\"];\n scale: KeyboardEvent[\"key\"];\n};\n\ntype ModeFlags = {\n feature?: {\n draggable?: boolean;\n rotateable?: boolean;\n scaleable?: boolean;\n coordinates?: {\n midpoints?: boolean;\n draggable?: boolean;\n deletable?: boolean;\n };\n };\n};\n\ntype SelectionStyling = {\n selectedColor: HexColor,\n selectedPointOutlineColor: HexColor,\n selectPointOutlineWidth: number,\n selectionPointWidth: number,\n selectionPointColor: HexColor,\n selectionPointOutlineColor: HexColor,\n selectionPointOutlineWidth: number,\n midPointColor: HexColor,\n midPointOutlineColor: HexColor,\n midPointWidth: number,\n midPointOutlineWidth: number,\n}\n\nexport class TerraDrawSelectMode extends TerraDrawBaseDrawMode<SelectionStyling> {\n mode = \"select\";\n\n private dragEventThrottle = 5;\n private dragEventCount = 0;\n private selected: string[] = [];\n\n private flags: { [mode: string]: ModeFlags };\n private keyEvents: TerraDrawSelectModeKeyEvents;\n\n // Behaviors\n private selectionPoints!: SelectionPointBehavior;\n private midPoints!: MidPointBehavior;\n private featuresAtMouseEvent!: FeaturesAtMouseEventBehavior;\n private pixelDistance!: PixelDistanceBehavior;\n private clickBoundingBox!: ClickBoundingBoxBehavior;\n private dragFeature!: DragFeatureBehavior;\n private dragCoordinate!: DragCoordinateBehavior;\n private rotateFeature!: RotateFeatureBehavior;\n private scaleFeature!: ScaleFeatureBehavior;\n\n constructor(options?: {\n styles?: Partial<SelectionStyling>\n pointerDistance?: number;\n flags?: { [mode: string]: ModeFlags };\n keyEvents?: TerraDrawSelectModeKeyEvents;\n dragEventThrottle?: number;\n }) {\n super(options);\n\n this.flags = options && options.flags ? options.flags : {};\n\n this.keyEvents =\n options && options.keyEvents\n ? options.keyEvents\n : { deselect: \"Escape\", delete: \"Delete\", rotate: \"r\", scale: \"s\" };\n\n this.dragEventThrottle =\n (options &&\n options.dragEventThrottle !== undefined &&\n options.dragEventThrottle) ||\n 5;\n }\n\n registerBehaviors(config: BehaviorConfig) {\n this.pixelDistance = new PixelDistanceBehavior(config);\n this.clickBoundingBox = new ClickBoundingBoxBehavior(config);\n this.featuresAtMouseEvent = new FeaturesAtMouseEventBehavior(\n config,\n this.clickBoundingBox,\n this.pixelDistance\n );\n\n this.selectionPoints = new SelectionPointBehavior(config);\n this.midPoints = new MidPointBehavior(config, this.selectionPoints);\n\n this.rotateFeature = new RotateFeatureBehavior(\n config,\n this.selectionPoints,\n this.midPoints\n );\n\n this.scaleFeature = new ScaleFeatureBehavior(\n config,\n this.selectionPoints,\n this.midPoints\n );\n\n this.dragFeature = new DragFeatureBehavior(\n config,\n this.featuresAtMouseEvent,\n this.selectionPoints,\n this.midPoints\n );\n this.dragCoordinate = new DragCoordinateBehavior(\n config,\n this.pixelDistance,\n this.selectionPoints,\n this.midPoints\n );\n }\n\n private deselect() {\n this.store.updateProperty(\n this.selected.map((id) => ({\n id,\n property: SELECT_PROPERTIES.SELECTED,\n value: false,\n }))\n );\n\n this.onDeselect(this.selected[0]);\n this.selected = [];\n this.selectionPoints.delete();\n this.midPoints.delete();\n }\n\n private deleteSelected() {\n // Delete all selected features\n // from the store and clear selected\n // We don't need to set selected false\n // as we're going to delete the feature\n\n this.store.delete(this.selected);\n this.selected = [];\n }\n\n private onRightClick(event: TerraDrawMouseEvent) {\n if (!this.selectionPoints.ids.length) {\n return;\n }\n\n let clickedSelectionPointProps:\n | {\n selectionPointFeatureId: string;\n index: number;\n }\n | undefined;\n\n let clickedFeatureDistance = Infinity;\n\n this.selectionPoints.ids.forEach((id: string) => {\n const geometry = this.store.getGeometryCopy<Point>(id);\n const distance = this.pixelDistance.measure(event, geometry.coordinates);\n\n if (\n distance < this.pointerDistance &&\n distance < clickedFeatureDistance\n ) {\n clickedFeatureDistance = distance;\n clickedSelectionPointProps = this.store.getPropertiesCopy(id) as {\n selectionPointFeatureId: string;\n index: number;\n };\n }\n });\n\n if (!clickedSelectionPointProps) {\n return;\n }\n\n const featureId = clickedSelectionPointProps.selectionPointFeatureId;\n const coordinateIndex = clickedSelectionPointProps.index;\n\n // We allow for preventing deleting coordinates via flags\n const properties = this.store.getPropertiesCopy(featureId);\n const modeFlags = this.flags[properties.mode as string];\n\n // Check if we can actually delete the coordinate\n const cannotDelete = !modeFlags ||\n !modeFlags.feature ||\n !modeFlags.feature.coordinates ||\n !modeFlags.feature.coordinates.deletable;\n\n if (cannotDelete) {\n return;\n }\n\n const geometry = this.store.getGeometryCopy(featureId);\n\n let coordinates;\n if (geometry.type === \"Polygon\") {\n coordinates = geometry.coordinates[0];\n\n // Prevent creating an invalid polygon\n if (coordinates.length <= 4) {\n return;\n }\n } else if (geometry.type === \"LineString\") {\n coordinates = geometry.coordinates;\n\n // Prevent creating an invalid linestring\n if (coordinates.length <= 3) {\n return;\n }\n }\n\n // Geometry is not Polygon or LineString\n if (!coordinates) {\n return;\n }\n\n if (\n (geometry.type === \"Polygon\" && coordinateIndex === 0) ||\n coordinateIndex === coordinates.length - 1\n ) {\n // Deleting the final coordinate in a polygon breaks it\n // because GeoJSON expects a duplicate, so we need to fix\n // it by adding the new first coordinate to the end\n coordinates.shift();\n coordinates.pop();\n coordinates.push([coordinates[0][0], coordinates[0][1]]);\n } else {\n // Remove coordinate from array\n coordinates.splice(coordinateIndex, 1);\n }\n\n this.store.delete([...this.midPoints.ids, ...this.selectionPoints.ids]);\n this.store.updateGeometry([\n {\n id: featureId,\n geometry,\n },\n ]);\n\n this.selectionPoints.create(\n coordinates,\n geometry.type as \"Polygon\" | \"LineString\",\n featureId\n );\n\n if (\n modeFlags &&\n modeFlags.feature &&\n modeFlags.feature.coordinates &&\n modeFlags.feature.coordinates.midpoints\n ) {\n this.midPoints.create(coordinates, featureId, this.coordinatePrecision);\n }\n }\n\n private onLeftClick(event: TerraDrawMouseEvent) {\n const { clickedFeature, clickedMidPoint } = this.featuresAtMouseEvent.find(\n event,\n\n this.selected.length > 0\n );\n\n if (this.selected.length && clickedMidPoint) {\n // TODO: We probably want to make sure the midpoint\n // is visible?\n\n this.midPoints.insert(\n clickedMidPoint.id as string,\n this.coordinatePrecision\n );\n\n return;\n }\n\n if (clickedFeature) {\n const { mode } = this.store.getPropertiesCopy(\n clickedFeature.id as string\n );\n\n const previouslySelectedId = this.selected[0];\n\n // If we have something currently selected\n if (previouslySelectedId) {\n // If it matches the current selected feature id, do nothing\n if (previouslySelectedId === clickedFeature.id) {\n return;\n } else {\n // If it's a different feature set selected\n // to false on previously selected feature\n this.deselect();\n }\n }\n\n // This will be undefined for points\n const modeFlags = this.flags[mode as string];\n\n // If feature is not selectable then return\n if (!modeFlags || !modeFlags.feature) {\n return;\n }\n\n // Select feature\n this.selected = [clickedFeature.id as string];\n this.store.updateProperty([\n { id: clickedFeature.id as string, property: \"selected\", value: true },\n ]);\n this.onSelect(clickedFeature.id as string);\n\n // Get the clicked feature\n const { type, coordinates } = this.store.getGeometryCopy(\n clickedFeature.id as string\n );\n\n let selectedCoords: Position[] | undefined;\n if (type === \"LineString\") {\n selectedCoords = coordinates;\n } else if (type === \"Polygon\") {\n selectedCoords = coordinates[0];\n }\n\n if (selectedCoords && modeFlags && modeFlags.feature.coordinates) {\n this.selectionPoints.create(\n selectedCoords,\n type,\n clickedFeature.id as string\n );\n\n if (modeFlags.feature.coordinates.midpoints) {\n this.midPoints.create(\n selectedCoords,\n clickedFeature.id as string,\n this.coordinatePrecision\n );\n }\n }\n } else if (this.selected.length) {\n this.deselect();\n return;\n }\n }\n\n start() {\n this.setStarted();\n }\n stop() {\n this.setStopped();\n this.cleanUp();\n }\n\n onClick(event: TerraDrawMouseEvent) {\n if (event.button === \"right\") {\n this.onRightClick(event);\n return;\n } else if (event.button === \"left\") {\n this.onLeftClick(event);\n }\n }\n onKeyDown() { }\n onKeyUp(event: TerraDrawKeyboardEvent) {\n if (event.key === this.keyEvents.delete) {\n if (!this.selected.length) {\n return;\n }\n\n // We are technically deselecting\n // because the selected feature is deleted\n // and will no longer exist or be selected\n const previouslySelected = this.selected[0];\n this.onDeselect(previouslySelected);\n\n // Delete all selected features\n this.deleteSelected();\n\n // Remove all selection points\n this.selectionPoints.delete();\n this.midPoints.delete();\n } else if (event.key === this.keyEvents.deselect) {\n this.cleanUp();\n }\n }\n cleanUp() {\n if (this.selected.length) {\n this.deselect();\n }\n }\n onDragStart(\n event: TerraDrawMouseEvent,\n setMapDraggability: (enabled: boolean) => void\n ) {\n // We only need to stop the map dragging if\n // we actually have something selected\n if (!this.selected.length) {\n return;\n }\n\n // If the selected feature is not draggable\n // don't do anything\n const properties = this.store.getPropertiesCopy(this.selected[0]);\n const modeFlags = this.flags[properties.mode as string];\n const draggable =\n modeFlags &&\n modeFlags.feature &&\n (modeFlags.feature.draggable ||\n (modeFlags.feature.coordinates &&\n modeFlags.feature.coordinates.draggable));\n\n if (!draggable) {\n return;\n }\n\n this.dragEventCount = 0;\n this.setCursor(\"grabbing\");\n this.dragFeature.position = [event.lng, event.lat];\n\n setMapDraggability(false);\n }\n\n onDrag(event: TerraDrawMouseEvent) {\n const selectedId = this.selected[0];\n\n // If nothing selected or the drag position hasn't been set\n // do nothing\n if (!selectedId || !this.dragFeature.position) {\n return;\n }\n\n const properties = this.store.getPropertiesCopy(selectedId);\n const modeFlags = this.flags[properties.mode as string];\n\n // Ensure drag count is incremented\n this.dragEventCount++;\n\n // Return if we haven't hit the drag throttle limit\n // (i.e. we only want to drag every nth event)\n if (this.dragEventCount % this.dragEventThrottle === 0) {\n return;\n }\n\n // Check if should rotate\n if (\n modeFlags &&\n modeFlags.feature &&\n modeFlags.feature.rotateable &&\n event.heldKeys.includes(\"r\")\n ) {\n this.rotateFeature.rotate(event, selectedId);\n return;\n }\n\n // Check if should scale\n if (\n modeFlags &&\n modeFlags.feature &&\n modeFlags.feature.scaleable &&\n event.heldKeys.includes(\"s\")\n ) {\n this.scaleFeature.scale(event, selectedId);\n return;\n }\n\n // Check if coordinate is draggable and is dragged\n if (\n modeFlags &&\n modeFlags.feature &&\n modeFlags.feature.coordinates &&\n modeFlags.feature.coordinates.draggable\n ) {\n const coordinateWasDragged = this.dragCoordinate.drag(event, selectedId);\n\n if (coordinateWasDragged) {\n return;\n }\n }\n\n // Check if feature is draggable and is dragged\n if (modeFlags && modeFlags.feature && modeFlags.feature.draggable) {\n this.dragFeature.drag(event, selectedId);\n\n this.dragFeature.position = [event.lng, event.lat];\n }\n }\n\n onDragEnd(\n _: TerraDrawMouseEvent,\n setMapDraggability: (enabled: boolean) => void\n ) {\n this.setCursor(\"grab\");\n this.dragFeature.position = undefined;\n this.rotateFeature.reset();\n this.scaleFeature.reset();\n setMapDraggability(true);\n }\n\n onMouseMove(event: TerraDrawMouseEvent) {\n if (!this.selected.length || this.dragFeature.position) {\n return;\n }\n\n let nearbySelectionPoint = false;\n this.midPoints.ids.forEach((id: string) => {\n if (nearbySelectionPoint) {\n return;\n }\n const geometry = this.store.getGeometryCopy<Point>(id);\n const distance = this.pixelDistance.measure(event, geometry.coordinates);\n\n if (distance < this.pointerDistance) {\n nearbySelectionPoint = true;\n }\n });\n\n // TODO: Is there a cleaner way to handle prioritising\n // dragging selection points?\n this.selectionPoints.ids.forEach((id: string) => {\n const geometry = this.store.getGeometryCopy<Point>(id);\n const distance = this.pixelDistance.measure(event, geometry.coordinates);\n if (distance < this.pointerDistance) {\n nearbySelectionPoint = false;\n }\n });\n if (nearbySelectionPoint) {\n this.setCursor(\"crosshair\");\n } else {\n this.setCursor(\"unset\");\n }\n }\n\n styleFeature(\n feature: GeoJSONStoreFeatures\n ): TerraDrawAdapterStyling {\n\n const styles = { ...getDefaultStyling() };\n\n\n if (feature.properties.mode === this.mode) {\n if (feature.geometry.type === 'Polygon') {\n if (this.styles.selectedColor) {\n styles.polygonFillColor = this.styles.selectedColor;\n }\n if (this.styles.selectedColor) {\n styles.polygonOutlineColor = this.styles.selectedColor;\n }\n styles.zIndex = 10;\n return styles;\n }\n\n if (feature.geometry.type === 'Point') {\n if (feature.properties.selectionPoint) {\n styles.pointColor = this.styles.selectionPointColor || styles.pointColor;\n styles.pointOutlineColor = this.styles.selectionPointOutlineColor || styles.pointOutlineColor;\n styles.pointWidth = this.styles.selectionPointWidth || styles.pointWidth;\n styles.pointOutlineWidth = this.styles.midPointOutlineWidth || 2;\n styles.zIndex = 30;\n\n return styles;\n }\n\n if (feature.properties.midPoint) {\n styles.pointColor = this.styles.midPointColor || styles.pointColor;\n styles.pointOutlineColor = this.styles.midPointOutlineColor || styles.pointOutlineColor;\n styles.pointWidth = this.styles.midPointWidth || 4;\n styles.pointOutlineWidth = this.styles.midPointOutlineWidth || 2;\n styles.zIndex = 40;\n\n return styles;\n }\n\n }\n }\n\n\n return styles;\n }\n}\n","import { TerraDrawAdapterStyling } from \"../../common\";\nimport { getDefaultStyling } from \"../../util/styling\";\nimport { TerraDrawBaseDrawMode } from \"../base.mode\";\n\n// eslint-disable-next-line @typescript-eslint/ban-types\ntype StaticModeStylingExt<T extends TerraDrawAdapterStyling> = {}\ntype StaticModeStyling = StaticModeStylingExt<TerraDrawAdapterStyling>\n\nexport class TerraDrawStaticMode extends TerraDrawBaseDrawMode<StaticModeStyling> {\n mode = \"static\";\n start() { }\n stop() { }\n onKeyUp() { }\n onKeyDown() { }\n onClick() { }\n onDragStart() { }\n onDrag() { }\n onDragEnd() { }\n onMouseMove() { }\n styleFeature() {\n return { ...getDefaultStyling() };\n }\n}\n","export const uuid4 = function (): string {\n return \"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx\".replace(/[xy]/g, function (c) {\n const r = (Math.random() * 16) | 0,\n v = c == \"x\" ? r : (r & 0x3) | 0x8;\n return v.toString(16);\n });\n};\n","// ISC License\n// Copyright (c) 2018, Vladimir Agafonkin\n\nexport type CompareFunction<T> = (a: T, b: T) => number;\n\nexport function quickselect<T>(\n arr: T[],\n k: number,\n left: number,\n right: number,\n compare: CompareFunction<T>\n) {\n while (right > left) {\n if (right - left > 600) {\n const n = right - left + 1;\n const m = k - left + 1;\n const z = Math.log(n);\n const s = 0.5 * Math.exp((2 * z) / 3);\n const sd =\n 0.5 * Math.sqrt((z * s * (n - s)) / n) * (m - n / 2 < 0 ? -1 : 1);\n const newLeft = Math.max(left, Math.floor(k - (m * s) / n + sd));\n const newRight = Math.min(right, Math.floor(k + ((n - m) * s) / n + sd));\n quickselect(arr, k, newLeft, newRight, compare);\n }\n\n const t = arr[k];\n let i = left;\n let j = right;\n\n swap(arr, left, k);\n if (compare(arr[right], t) > 0) swap(arr, left, right);\n\n while (i < j) {\n swap(arr, i, j);\n i++;\n j--;\n while (compare(arr[i], t) < 0) i++;\n while (compare(arr[j], t) > 0) j--;\n }\n\n if (compare(arr[left], t) === 0) {\n swap(arr, left, j);\n } else {\n j++;\n swap(arr, j, right);\n }\n\n if (j <= k) left = j + 1;\n if (k <= j) right = j - 1;\n }\n}\n\nfunction swap<T>(arr: T[], i: number, j: number) {\n const tmp = arr[i];\n arr[i] = arr[j];\n arr[j] = tmp;\n}\n","// Base on Rbush - https://github.com/mourner/rbush\n// MIT License\n// Copyright (c) 2016 Vladimir Agafonkin\n\nimport { CompareFunction, quickselect } from \"./quickselect\";\n\nexport type Node = {\n children: Node[];\n height: number;\n leaf: boolean;\n minX: number;\n minY: number;\n maxX: number;\n maxY: number;\n};\n\n// calculate node's bbox from bboxes of its children\nfunction calcBBox(node: Node, toBBox: (node: Node) => any) {\n distBBox(node, 0, node.children.length, toBBox, node);\n}\n\n// min bounding rectangle of node children from k to p-1\nfunction distBBox(\n node: Node,\n k: number,\n p: number,\n toBBox: (node: Node) => Node,\n destNode?: Node\n) {\n if (!destNode) destNode = createNode([]);\n destNode.minX = Infinity;\n destNode.minY = Infinity;\n destNode.maxX = -Infinity;\n destNode.maxY = -Infinity;\n\n for (let i = k; i < p; i++) {\n const child = node.children[i];\n extend(destNode, node.leaf ? toBBox(child) : child);\n }\n\n return destNode;\n}\n\nfunction extend(a: Node, b: Node) {\n a.minX = Math.min(a.minX, b.minX);\n a.minY = Math.min(a.minY, b.minY);\n a.maxX = Math.max(a.maxX, b.maxX);\n a.maxY = Math.max(a.maxY, b.maxY);\n return a;\n}\n\nfunction compareNodeMinX(a: Node, b: Node) {\n return a.minX - b.minX;\n}\nfunction compareNodeMinY(a: Node, b: Node) {\n return a.minY - b.minY;\n}\n\nfunction bboxArea(a: Node) {\n return (a.maxX - a.minX) * (a.maxY - a.minY);\n}\nfunction bboxMargin(a: {\n minX: number;\n minY: number;\n maxX: number;\n maxY: number;\n}) {\n return a.maxX - a.minX + (a.maxY - a.minY);\n}\n\nfunction enlargedArea(a: Node, b: Node) {\n return (\n (Math.max(b.maxX, a.maxX) - Math.min(b.minX, a.minX)) *\n (Math.max(b.maxY, a.maxY) - Math.min(b.minY, a.minY))\n );\n}\n\nfunction intersectionArea(a: Node, b: Node) {\n const minX = Math.max(a.minX, b.minX);\n const minY = Math.max(a.minY, b.minY);\n const maxX = Math.min(a.maxX, b.maxX);\n const maxY = Math.min(a.maxY, b.maxY);\n\n return Math.max(0, maxX - minX) * Math.max(0, maxY - minY);\n}\n\nfunction contains(a: Node, b: Node) {\n return (\n a.minX <= b.minX && a.minY <= b.minY && b.maxX <= a.maxX && b.maxY <= a.maxY\n );\n}\n\nfunction intersects(a: Node, b: Node) {\n return (\n b.minX <= a.maxX && b.minY <= a.maxY && b.maxX >= a.minX && b.maxY >= a.minY\n );\n}\n\nfunction createNode(children: Node[]) {\n return {\n children,\n height: 1,\n leaf: true,\n minX: Infinity,\n minY: Infinity,\n maxX: -Infinity,\n maxY: -Infinity,\n };\n}\n\n// sort an array so that items come in groups of n unsorted items, with groups sorted between each other;\n// combines selection algorithm with binary divide & conquer approach\n\nfunction multiSelect<T>(\n arr: T[],\n left: number,\n right: number,\n n: number,\n compare: CompareFunction<T>\n) {\n const stack = [left, right];\n\n while (stack.length) {\n right = stack.pop() as number;\n left = stack.pop() as number;\n\n if (right - left <= n) continue;\n\n const mid = left + Math.ceil((right - left) / n / 2) * n;\n quickselect(arr, mid, left, right, compare);\n\n stack.push(left, mid, mid, right);\n }\n}\n\nexport class RBush {\n private _maxEntries: number;\n private _minEntries: number;\n private data!: Node;\n\n constructor(maxEntries: number) {\n // max entries in a node is 9 by default; min node fill is 40% for best performance\n this._maxEntries = Math.max(4, maxEntries);\n this._minEntries = Math.max(2, Math.ceil(this._maxEntries * 0.4));\n this.clear();\n }\n\n search(bbox: Node): Node[] {\n let node = this.data;\n const result: Node[] = [];\n\n if (!intersects(bbox, node)) {\n return result;\n }\n\n const toBBox = this.toBBox;\n const nodesToSearch = [];\n\n while (node) {\n for (let i = 0; i < node.children.length; i++) {\n const child = node.children[i];\n const childBBox = node.leaf ? toBBox(child) : child;\n\n if (intersects(bbox, childBBox)) {\n if (node.leaf) result.push(child);\n else if (contains(bbox, childBBox)) this._all(child, result);\n else nodesToSearch.push(child);\n }\n }\n node = nodesToSearch.pop() as Node;\n }\n\n return result;\n }\n\n collides(bbox: Node) {\n let node = this.data;\n\n const intersect = intersects(bbox, node);\n if (intersect) {\n const nodesToSearch = [];\n while (node) {\n for (let i = 0; i < node.children.length; i++) {\n const child = node.children[i];\n const childBBox = node.leaf ? this.toBBox(child) : child;\n\n if (intersects(bbox, childBBox)) {\n if (node.leaf || contains(bbox, childBBox)) {\n return true;\n }\n nodesToSearch.push(child);\n }\n }\n node = nodesToSearch.pop() as Node;\n }\n }\n\n return false;\n }\n\n load(data: Node[]): void {\n if (data.length < this._minEntries) {\n for (let i = 0; i < data.length; i++) {\n this.insert(data[i]);\n }\n return;\n }\n\n // recursively build the tree with the given data from scratch using OMT algorithm\n let node = this._build(data.slice(), 0, data.length - 1, 0);\n\n if (!this.data.children.length) {\n // save as is if tree is empty\n this.data = node;\n } else if (this.data.height === node.height) {\n // split root if trees have the same height\n this._splitRoot(this.data, node);\n } else {\n if (this.data.height < node.height) {\n // swap trees if inserted one is bigger\n const tmpNode = this.data;\n this.data = node;\n node = tmpNode;\n }\n\n // insert the small tree into the large tree at appropriate level\n this._insert(node, this.data.height - node.height - 1, true);\n }\n }\n\n insert(item: Node): void {\n this._insert(item, this.data.height - 1);\n }\n\n clear(): void {\n this.data = createNode([]);\n }\n\n remove(item: Node): void {\n let node: Node | null = this.data;\n const bbox = this.toBBox(item);\n const path = [];\n const indexes: number[] = [];\n let i: number | undefined;\n let parent: Node | undefined;\n let goingUp = false;\n\n // depth-first iterative tree traversal\n while (node || path.length) {\n if (!node) {\n // go up\n node = path.pop() as Node;\n parent = path[path.length - 1];\n i = indexes.pop() as number;\n goingUp = true;\n }\n\n if (node.leaf) {\n // check current node\n\n const index = node.children.indexOf(item);\n\n if (index !== -1) {\n // item found, remove the item and condense tree upwards\n node.children.splice(index, 1);\n path.push(node);\n this._condense(path);\n }\n }\n\n if (!goingUp && !node.leaf && contains(node, bbox)) {\n // go down\n path.push(node);\n indexes.push(i as number);\n i = 0;\n parent = node;\n node = node.children[0];\n } else if (parent) {\n // go right\n (i as number)++;\n node = parent.children[i as number];\n goingUp = false;\n } else {\n node = null; // nothing found\n }\n }\n }\n\n private toBBox<T>(item: T): T {\n return item;\n }\n\n private compareMinX(a: Node, b: Node) {\n return a.minX - b.minX;\n }\n private compareMinY(a: Node, b: Node) {\n return a.minY - b.minY;\n }\n\n private _all(node: Node, result: Node[]) {\n const nodesToSearch = [];\n while (node) {\n if (node.leaf) result.push(...node.children);\n else nodesToSearch.push(...node.children);\n\n node = nodesToSearch.pop() as Node;\n }\n return result;\n }\n\n private _build(items: Node[], left: number, right: number, height: number) {\n const N = right - left + 1;\n let M = this._maxEntries;\n let node;\n\n if (N <= M) {\n // reached leaf level; return leaf\n node = createNode(items.slice(left, right + 1));\n calcBBox(node, this.toBBox);\n return node;\n }\n\n if (!height) {\n // target height of the bulk-loaded tree\n height = Math.ceil(Math.log(N) / Math.log(M));\n\n // target number of root entries to maximize storage utilization\n M = Math.ceil(N / Math.pow(M, height - 1));\n }\n\n node = createNode([]);\n node.leaf = false;\n node.height = height;\n\n // split the items into M mostly square tiles\n\n const N2 = Math.ceil(N / M);\n const N1 = N2 * Math.ceil(Math.sqrt(M));\n\n multiSelect(items, left, right, N1, this.compareMinX);\n\n for (let i = left; i <= right; i += N1) {\n const right2 = Math.min(i + N1 - 1, right);\n\n multiSelect(items, i, right2, N2, this.compareMinY);\n\n for (let j = i; j <= right2; j += N2) {\n const right3 = Math.min(j + N2 - 1, right2);\n\n // pack each entry recursively\n node.children.push(this._build(items, j, right3, height - 1));\n }\n }\n\n calcBBox(node, this.toBBox);\n\n return node;\n }\n\n private _chooseSubtree(bbox: Node, node: Node, level: number, path: Node[]) {\n while (true) {\n path.push(node);\n\n if (node.leaf || path.length - 1 === level) {\n break;\n }\n\n let minArea = Infinity;\n let minEnlargement = Infinity;\n let targetNode;\n\n for (let i = 0; i < node.children.length; i++) {\n const child = node.children[i];\n\n const area = bboxArea(child);\n const enlargement = enlargedArea(bbox, child) - area;\n\n // choose entry with the least area enlargement\n\n if (enlargement < minEnlargement) {\n minEnlargement = enlargement;\n minArea = area < minArea ? area : minArea;\n targetNode = child;\n } else if (enlargement === minEnlargement) {\n // otherwise choose one with the smallest area\n if (area < minArea) {\n minArea = area;\n targetNode = child;\n }\n }\n }\n\n node = targetNode || node.children[0];\n }\n\n return node;\n }\n\n private _insert(item: Node, level: number, isNode?: boolean) {\n const bbox = isNode ? item : this.toBBox(item);\n const insertPath: Node[] = [];\n\n // find the best node for accommodating the item, saving all nodes along the path too\n const node = this._chooseSubtree(bbox, this.data, level, insertPath);\n\n // put the item into the node\n node.children.push(item);\n extend(node, bbox);\n\n // split on node overflow; propagate upwards if necessary\n while (level >= 0) {\n if (insertPath[level].children.length > this._maxEntries) {\n this._split(insertPath, level);\n level--;\n } else break;\n }\n\n // adjust bboxes along the insertion path\n this._adjustParentBBoxes(bbox, insertPath, level);\n }\n\n // split overflowed node into two\n private _split(insertPath: Node[], level: number) {\n const node = insertPath[level];\n const M = node.children.length;\n const m = this._minEntries;\n\n this._chooseSplitAxis(node, m, M);\n\n const splitIndex = this._chooseSplitIndex(node, m, M);\n\n const newNode = createNode(\n node.children.splice(splitIndex, node.children.length - splitIndex)\n );\n newNode.height = node.height;\n newNode.leaf = node.leaf;\n\n calcBBox(node, this.toBBox);\n calcBBox(newNode, this.toBBox);\n\n if (level) insertPath[level - 1].children.push(newNode);\n else this._splitRoot(node, newNode);\n }\n\n private _splitRoot(node: Node, newNode: Node) {\n // split root node\n this.data = createNode([node, newNode]);\n this.data.height = node.height + 1;\n this.data.leaf = false;\n calcBBox(this.data, this.toBBox);\n }\n\n private _chooseSplitIndex(node: Node, m: number, M: number) {\n let index;\n let minOverlap = Infinity;\n let minArea = Infinity;\n\n for (let i = m; i <= M - m; i++) {\n const bbox1 = distBBox(node, 0, i, this.toBBox);\n const bbox2 = distBBox(node, i, M, this.toBBox);\n\n const overlap = intersectionArea(bbox1, bbox2);\n const area = bboxArea(bbox1) + bboxArea(bbox2);\n\n // choose distribution with minimum overlap\n if (overlap < minOverlap) {\n minOverlap = overlap;\n index = i;\n\n minArea = area < minArea ? area : minArea;\n } else if (overlap === minOverlap) {\n // otherwise choose distribution with minimum area\n if (area < minArea) {\n minArea = area;\n index = i;\n }\n }\n }\n\n return index || M - m;\n }\n\n // sorts node children by the best axis for split\n private _chooseSplitAxis(node: Node, m: number, M: number) {\n const compareMinX = node.leaf ? this.compareMinX : compareNodeMinX;\n const compareMinY = node.leaf ? this.compareMinY : compareNodeMinY;\n const xMargin = this._allDistMargin(node, m, M, compareMinX);\n const yMargin = this._allDistMargin(node, m, M, compareMinY);\n\n // if total distributions margin value is minimal for x, sort by minX,\n // otherwise it's already sorted by minY\n if (xMargin < yMargin) {\n node.children.sort(compareMinX);\n }\n }\n\n // total margin of all possible split distributions where each node is at least m full\n private _allDistMargin(\n node: Node,\n m: number,\n M: number,\n compare: CompareFunction<Node>\n ) {\n node.children.sort(compare);\n\n const toBBox = this.toBBox;\n const leftBBox = distBBox(node, 0, m, toBBox);\n const rightBBox = distBBox(node, M - m, M, toBBox);\n let margin = bboxMargin(leftBBox) + bboxMargin(rightBBox);\n\n for (let i = m; i < M - m; i++) {\n const child = node.children[i];\n extend(leftBBox, node.leaf ? toBBox(child) : child);\n margin += bboxMargin(leftBBox);\n }\n\n for (let i = M - m - 1; i >= m; i--) {\n const child = node.children[i];\n extend(rightBBox, node.leaf ? toBBox(child) : child);\n margin += bboxMargin(rightBBox);\n }\n\n return margin;\n }\n\n private _adjustParentBBoxes(bbox: Node, path: Node[], level: number) {\n // adjust bboxes along the given tree path\n for (let i = level; i >= 0; i--) {\n extend(path[i], bbox);\n }\n }\n\n private _condense(path: Node[]) {\n // go through the path, removing empty nodes and updating bboxes\n for (let i = path.length - 1, siblings; i >= 0; i--) {\n if (path[i].children.length === 0) {\n if (i > 0) {\n siblings = path[i - 1].children;\n siblings.splice(siblings.indexOf(path[i]), 1);\n } else this.clear();\n } else {\n calcBBox(path[i], this.toBBox);\n }\n }\n }\n}\n","import { Position } from \"geojson\";\nimport { GeoJSONStoreFeatures } from \"../store\";\nimport { RBush, Node } from \"./rbush\";\n\nexport class SpatialIndex {\n private tree: RBush;\n private idToNode: Map<string, Node>;\n private nodeToId: Map<Node, string>;\n\n constructor(options?: { maxEntries: number }) {\n this.tree = new RBush(\n options && options.maxEntries ? options.maxEntries : 9\n );\n this.idToNode = new Map();\n this.nodeToId = new Map();\n }\n\n private setMaps(feature: GeoJSONStoreFeatures, bbox: Node) {\n this.idToNode.set(String(feature.id), bbox);\n this.nodeToId.set(bbox, String(feature.id));\n }\n\n private toBBox(feature: GeoJSONStoreFeatures) {\n const longitudes: number[] = [];\n const latitudes: number[] = [];\n\n let coordinates: Position[];\n if (feature.geometry.type === \"Polygon\") {\n coordinates = feature.geometry.coordinates[0];\n } else if (feature.geometry.type === \"LineString\") {\n coordinates = feature.geometry.coordinates;\n } else if (feature.geometry.type === \"Point\") {\n coordinates = [feature.geometry.coordinates];\n } else {\n throw new Error(\"Not a valid feature to turn into a bounding box\");\n }\n\n for (let i = 0; i < coordinates.length; i++) {\n latitudes.push(coordinates[i][1]);\n longitudes.push(coordinates[i][0]);\n }\n\n const minLat = Math.min(...latitudes);\n const maxLat = Math.max(...latitudes);\n const minLng = Math.min(...longitudes);\n const maxLng = Math.max(...longitudes);\n\n return {\n minX: minLng,\n minY: minLat,\n maxX: maxLng,\n maxY: maxLat,\n } as Node;\n }\n\n insert(feature: GeoJSONStoreFeatures): void {\n if (this.idToNode.get(String(feature.id))) {\n throw new Error(\"Feature already exists\");\n }\n const bbox = this.toBBox(feature);\n this.setMaps(feature, bbox);\n this.tree.insert(bbox);\n }\n\n load(features: GeoJSONStoreFeatures[]): void {\n const load: Node[] = [];\n const seenIds: Set<string> = new Set();\n features.forEach((feature) => {\n const bbox = this.toBBox(feature);\n this.setMaps(feature, bbox);\n if (seenIds.has(String(feature.id))) {\n throw new Error(`Duplicate feature ID found ${feature.id}`);\n }\n seenIds.add(String(feature.id));\n load.push(bbox);\n });\n this.tree.load(load);\n }\n\n update(feature: GeoJSONStoreFeatures): void {\n this.remove(feature.id as string);\n const bbox = this.toBBox(feature);\n this.setMaps(feature, bbox);\n this.tree.insert(bbox);\n }\n\n remove(featureId: string): void {\n const node = this.idToNode.get(featureId);\n if (!node) {\n throw new Error(`${featureId} not inserted into the spatial index`);\n }\n\n this.tree.remove(node);\n }\n\n clear(): void {\n this.tree.clear();\n }\n\n search(feature: GeoJSONStoreFeatures): string[] {\n const found = this.tree.search(this.toBBox(feature));\n return found.map((node) => {\n return this.nodeToId.get(node) as string;\n });\n }\n\n collides(feature: GeoJSONStoreFeatures): boolean {\n return this.tree.collides(this.toBBox(feature));\n }\n}\n","import { Feature, Point, Polygon, LineString } from \"geojson\";\nimport { uuid4 } from \"../util/id\";\nimport { SpatialIndex } from \"./spatial-index/spatial-index\";\n\ntype JSON = string | number | boolean | null | JSONArray | JSONObject;\n\nexport interface JSONObject {\n [member: string]: JSON;\n}\ntype JSONArray = Array<JSON>;\n\ntype DefinedProperties = Record<string, JSON>;\n\nexport type GeoJSONStoreGeometries = Polygon | LineString | Point;\n\nexport type BBoxPolygon = Feature<Polygon, DefinedProperties>;\n\nexport type GeoJSONStoreFeatures = Feature<\n GeoJSONStoreGeometries,\n DefinedProperties\n>;\n\nexport type StoreChangeEvents = \"delete\" | \"create\" | \"update\";\n\nexport type StoreChangeHandler = (\n ids: string[],\n change: StoreChangeEvents\n) => void;\n\nexport type GeoJSONStoreConfig = {\n data?: GeoJSONStoreFeatures[];\n tracked?: boolean;\n validateFeature?: (feature: unknown, tracked?: boolean) => void;\n};\n\nexport class GeoJSONStore {\n constructor(config?: GeoJSONStoreConfig) {\n this.store = {};\n this.spatialIndex = new SpatialIndex();\n\n // Setting tracked has to happen first\n // because we use it in featureValidation\n this.tracked = config && config.tracked === false ? false : true;\n\n if (config && config.data) {\n this.load(config.data, config.validateFeature);\n }\n }\n\n private tracked: boolean;\n\n private spatialIndex: SpatialIndex;\n\n private store: {\n [key: string]: GeoJSONStoreFeatures;\n };\n\n // Default to no-op\n private _onChange: StoreChangeHandler = () => {};\n\n private getId(): string {\n return uuid4();\n }\n\n private clone<T>(obj: T): T {\n return JSON.parse(JSON.stringify(obj));\n }\n\n has(id: string): boolean {\n return Boolean(this.store[id]);\n }\n\n load(\n data: GeoJSONStoreFeatures[],\n featureValidation?: (feature: unknown, tracked?: boolean) => void\n ) {\n if (data.length === 0) {\n return;\n }\n\n // We don't want to update the original data\n const clonedData = this.clone(data);\n\n // We try to be a bit forgiving here as many users\n // may not set a feature id as UUID or createdAt/updatedAt\n clonedData.forEach((feature) => {\n if (!feature.id) {\n feature.id = uuid4();\n }\n\n if (this.tracked) {\n if (!feature.properties.createdAt) {\n feature.properties.createdAt = +new Date();\n }\n\n if (!feature.properties.updatedAt) {\n feature.properties.updatedAt = +new Date();\n }\n }\n });\n\n const changes: string[] = [];\n clonedData.forEach((feature) => {\n if (featureValidation) {\n featureValidation(feature);\n }\n this.store[feature.id as string] = feature;\n changes.push(feature.id as string);\n });\n this.spatialIndex.load(clonedData);\n this._onChange(changes, \"create\");\n }\n\n search(\n bbox: BBoxPolygon,\n filter?: (feature: GeoJSONStoreFeatures) => boolean\n ) {\n const features = this.spatialIndex.search(bbox).map((id) => this.store[id]);\n if (filter) {\n return this.clone(features.filter(filter));\n } else {\n return this.clone(features);\n }\n }\n\n registerOnChange(onChange: StoreChangeHandler) {\n this._onChange = (ids, change) => {\n onChange(ids, change);\n };\n }\n\n getGeometryCopy<T extends GeoJSONStoreGeometries>(id: string): T {\n const feature = this.store[id];\n if (!feature) {\n throw new Error(\n `No feature with this id (${id}), can not get geometry copy`\n );\n }\n return this.clone(feature.geometry as T);\n }\n\n getPropertiesCopy(id: string) {\n const feature = this.store[id];\n if (!feature) {\n throw new Error(\n `No feature with this id (${id}), can not get properties copy`\n );\n }\n return this.clone(feature.properties);\n }\n\n updateProperty(\n propertiesToUpdate: { id: string; property: string; value: JSON }[]\n ): void {\n const ids: string[] = [];\n propertiesToUpdate.forEach(({ id, property, value }) => {\n const feature = this.store[id];\n\n if (!feature) {\n throw new Error(\n `No feature with this (${id}), can not update geometry`\n );\n }\n\n ids.push(id);\n\n feature.properties[property] = value;\n\n // Update the time the feature was updated\n if (this.tracked) {\n feature.properties.updatedAt = +new Date();\n }\n });\n\n if (this._onChange) {\n this._onChange(ids, \"update\");\n }\n }\n\n updateGeometry(\n geometriesToUpdate: { id: string; geometry: GeoJSONStoreGeometries }[]\n ): void {\n const ids: string[] = [];\n geometriesToUpdate.forEach(({ id, geometry }) => {\n ids.push(id);\n\n const feature = this.store[id];\n\n if (!feature) {\n throw new Error(\n `No feature with this (${id}), can not update geometry`\n );\n }\n\n feature.geometry = this.clone(geometry);\n\n this.spatialIndex.update(feature);\n\n // Update the time the feature was updated\n if (this.tracked) {\n feature.properties.updatedAt = +new Date();\n }\n });\n\n if (this._onChange) {\n this._onChange(ids, \"update\");\n }\n }\n\n create(\n features: {\n geometry: GeoJSONStoreGeometries;\n properties?: JSONObject;\n }[]\n ): string[] {\n const ids: string[] = [];\n features.forEach(({ geometry, properties }) => {\n let createdAt;\n let createdProperties = { ...properties };\n\n if (this.tracked) {\n createdAt = +new Date();\n\n if (properties) {\n createdProperties.createdAt =\n typeof properties.createdAt === \"number\"\n ? properties.createdAt\n : createdAt;\n createdProperties.updatedAt =\n typeof properties.updatedAt === \"number\"\n ? properties.updatedAt\n : createdAt;\n } else {\n createdProperties = { createdAt, updatedAt: createdAt };\n }\n }\n\n const id = this.getId();\n const feature = {\n id,\n type: \"Feature\",\n geometry,\n properties: createdProperties,\n } as GeoJSONStoreFeatures;\n\n this.store[id] = feature;\n this.spatialIndex.insert(feature);\n\n ids.push(id);\n });\n\n if (this._onChange) {\n this._onChange([...ids], \"create\");\n }\n\n return ids;\n }\n\n delete(ids: string[]): void {\n ids.forEach((id) => {\n if (this.store[id]) {\n delete this.store[id];\n this.spatialIndex.remove(id as string);\n } else {\n throw new Error(\"No feature with this id, can not delete\");\n }\n });\n\n if (this._onChange) {\n this._onChange([...ids], \"delete\");\n }\n }\n\n copyAll(): GeoJSONStoreFeatures[] {\n return this.clone(Object.keys(this.store).map((id) => this.store[id]));\n }\n}\n","import { TerraDrawGoogleMapsAdapter } from \"./adapters/google-maps.adapter\";\nimport { TerraDrawLeafletAdapter } from \"./adapters/leaflet.adapter\";\nimport { TerraDrawMapboxGLAdapter } from \"./adapters/mapbox-gl.adapter\";\nimport {\n TerraDrawMode,\n TerraDrawAdapter,\n TerraDrawAdapterStyling,\n} from \"./common\";\nimport { TerraDrawCircleMode } from \"./modes/circle/circle.mode\";\nimport { TerraDrawFreehandMode } from \"./modes/freehand/freehand.mode\";\nimport { TerraDrawLineStringMode } from \"./modes/linestring/linestring.mode\";\nimport { TerraDrawPointMode } from \"./modes/point/point.mode\";\nimport { TerraDrawPolygonMode } from \"./modes/polygon/polygon.mode\";\nimport { TerraDrawRenderMode } from \"./modes/render/render.mode\";\nimport { TerraDrawSelectMode } from \"./modes/select/select.mode\";\nimport { TerraDrawStaticMode } from \"./modes/static/static.mode\";\nimport {\n GeoJSONStore,\n GeoJSONStoreFeatures,\n StoreChangeHandler,\n} from \"./store/store\";\n\ntype ChangeListener = (ids: string[], type: string) => void;\ntype SelectListener = (id: string) => void;\ntype DeselectListener = () => void;\n\ninterface TerraDrawEventListeners {\n change: ChangeListener;\n select: SelectListener;\n deselect: DeselectListener;\n}\n\ntype TerraDrawEvents = keyof TerraDrawEventListeners;\n\nclass TerraDraw {\n private _modes: { [mode: string]: TerraDrawMode };\n private _mode: TerraDrawMode;\n private _adapter: TerraDrawAdapter;\n private _enabled = false;\n private _store: GeoJSONStore;\n private _eventListeners: {\n change: ChangeListener[];\n select: SelectListener[];\n deselect: DeselectListener[];\n };\n\n constructor(options: {\n adapter: TerraDrawAdapter;\n modes: { [mode: string]: TerraDrawMode };\n data?: GeoJSONStoreFeatures[];\n }) {\n this._adapter = options.adapter;\n this._mode = new TerraDrawStaticMode();\n this._modes = { ...options.modes, static: this._mode };\n this._eventListeners = { change: [], select: [], deselect: [] };\n\n if (options.data) {\n this._store = new GeoJSONStore({ data: options.data });\n } else {\n this._store = new GeoJSONStore();\n }\n\n const getChanged = (\n ids: string[]\n ): {\n changed: GeoJSONStoreFeatures[];\n unchanged: GeoJSONStoreFeatures[];\n } => {\n const changed: GeoJSONStoreFeatures[] = [];\n\n const unchanged = this._store.copyAll().filter((f) => {\n if (ids.includes(f.id as string)) {\n changed.push(f);\n return false;\n }\n\n return true;\n });\n\n return { changed, unchanged };\n };\n\n const onChange: StoreChangeHandler = (ids, event) => {\n this._eventListeners.change.forEach((listener) => {\n listener(ids, event);\n });\n\n const { changed, unchanged } = getChanged(ids);\n\n if (event === \"create\") {\n this._adapter.render(\n {\n created: changed,\n deletedIds: [],\n unchanged,\n updated: []\n },\n this.getModeStyles()\n );\n } else if (event === \"update\") {\n this._adapter.render(\n {\n created: [],\n deletedIds: [],\n unchanged,\n updated: changed,\n },\n this.getModeStyles()\n );\n } else if (event === \"delete\") {\n this._adapter.render(\n { created: [], deletedIds: ids, unchanged, updated: [] },\n this.getModeStyles()\n );\n } else if (event === \"styling\") {\n this._adapter.render(\n { created: [], deletedIds: [], unchanged, updated: [] },\n this.getModeStyles()\n );\n }\n };\n\n const onSelect = (selectedId: string) => {\n this._eventListeners.select.forEach((listener) => {\n listener(selectedId);\n });\n\n const { changed, unchanged } = getChanged([selectedId]);\n\n this._adapter.render(\n { created: [], deletedIds: [], unchanged, updated: changed },\n this.getModeStyles()\n );\n };\n\n const onDeselect = (deselectedId: string) => {\n this._eventListeners.deselect.forEach((listener) => {\n listener();\n });\n\n const { changed, unchanged } = getChanged([deselectedId]);\n\n // onDeselect can be called after a delete call which means that\n // you are deselecting a feature that has been deleted. We\n // double check here to ensure that the feature still exists.\n if (changed) {\n this._adapter.render(\n {\n created: [],\n deletedIds: [],\n unchanged,\n updated: changed,\n },\n this.getModeStyles()\n );\n }\n };\n\n // Register stores and callbacks\n Object.keys(this._modes).forEach((modeId) => {\n this._modes[modeId].register({\n mode: modeId,\n store: this._store,\n setCursor: this._adapter.setCursor,\n project: this._adapter.project,\n unproject: this._adapter.unproject,\n onChange: onChange,\n onSelect: onSelect,\n onDeselect: onDeselect,\n });\n });\n\n // If we pass in data, we want to render it on startup\n if (options.data) {\n // Remove all non mode features\n const initialRender = this._store.copyAll().filter((feature) => {\n if (\n feature.properties &&\n !Object.keys(this._modes).includes(feature.properties.mode as string)\n ) {\n this._store.delete([feature.id as string]);\n return false;\n }\n return true;\n });\n\n this._adapter.render(\n {\n created: initialRender,\n deletedIds: [],\n unchanged: [],\n updated: [],\n },\n this.getModeStyles()\n );\n }\n }\n\n private getModeStyles() {\n const modeStyles: { [key: string]: (feature: GeoJSONStoreFeatures) => TerraDrawAdapterStyling } = {};\n Object.keys(this._modes).forEach((mode) => {\n modeStyles[mode] = this._modes[mode].styleFeature.bind(this._modes[mode]);\n });\n return modeStyles;\n }\n\n setModeStyles(mode: string, styles: TerraDrawAdapterStyling) {\n this._modes[mode].styles = styles;\n }\n\n getSnapshot() {\n return this._store.copyAll();\n }\n\n get enabled(): boolean {\n return this._enabled;\n }\n\n set enabled(_) {\n throw new Error(\"Enabled is read only\");\n }\n\n getCurrentMode(): string {\n return this._mode.mode;\n }\n\n changeMode(mode: string) {\n if (this._modes[mode]) {\n // Before we swap modes we want to\n // clean up any state that has been left behind,\n // for example current drawing geometries\n // and mode state\n this._mode.stop();\n\n // Swap the mode to the new mode\n this._mode = this._modes[mode];\n\n // Start the new mode\n this._mode.start();\n } else {\n // If the mode doesn't exist, we throw an error\n throw new Error(\"No mode with this name present\");\n }\n }\n\n start() {\n this._enabled = true;\n this._adapter.register({\n onClick: (event) => {\n this._mode.onClick(event);\n },\n onMouseMove: (event) => {\n this._mode.onMouseMove(event);\n },\n onKeyDown: (event) => {\n this._mode.onKeyDown(event);\n },\n onKeyUp: (event) => {\n this._mode.onKeyUp(event);\n },\n onDragStart: (event, setMapDraggability) => {\n this._mode.onDragStart(event, setMapDraggability);\n },\n onDrag: (event) => {\n this._mode.onDrag(event);\n },\n onDragEnd: (event, setMapDraggability) => {\n this._mode.onDragEnd(event, setMapDraggability);\n },\n });\n }\n\n stop() {\n this._enabled = false;\n this._adapter.unregister();\n }\n\n on<T extends TerraDrawEvents>(\n event: T,\n callback: TerraDrawEventListeners[T]\n ) {\n const listeners = this._eventListeners[\n event\n ] as TerraDrawEventListeners[T][];\n if (!listeners.includes(callback)) {\n listeners.push(callback);\n }\n }\n\n off<T extends TerraDrawEvents>(\n event: TerraDrawEvents,\n callback: TerraDrawEventListeners[T]\n ) {\n const listeners = this._eventListeners[\n event\n ] as TerraDrawEventListeners[T][];\n if (listeners.includes(callback)) {\n listeners.splice(listeners.indexOf(callback), 1);\n }\n }\n}\n\nexport {\n TerraDraw,\n TerraDrawSelectMode,\n TerraDrawPointMode,\n TerraDrawLineStringMode,\n TerraDrawPolygonMode,\n TerraDrawCircleMode,\n TerraDrawFreehandMode,\n TerraDrawRenderMode,\n TerraDrawGoogleMapsAdapter,\n TerraDrawMapboxGLAdapter,\n TerraDrawLeafletAdapter,\n};\n"],"names":["limitPrecision","num","decimalLimit","decimals","Math","pow","round","TerraDrawGoogleMapsAdapter","config","_heldKeys","Set","_cursor","_cursorStyleSheet","_coordinatePrecision","_lib","_map","_onMouseMoveListener","_onMouseMoveCallback","_onClickListener","this","_onRightClickListener","_onClickCallback","_onKeyUpListener","_onDragStartListener","_onDragListener","_onDragEndListener","_layers","getMapContainer","unproject","project","setCursor","lib","map","coordinatePrecision","_this","getDiv","lng","lat","bounds","getBounds","undefined","Error","northWest","LatLng","getNorthEast","getSouthWest","projection","getProjection","projectedNorthWest","fromLatLngToPoint","projected","zoom","getZoom","scale","x","floor","y","topRight","bottomLeft","worldPoint","maps","Point","lngLat","fromPointToLatLng","cursor","remove","div","style","document","createElement","type","innerHTML","id","selector","getElementsByTagName","appendChild","_proto","prototype","circlePath","cx","cy","r","register","callbacks","_this2","event","latLng","onClick","containerX","domEvent","clientX","offsetLeft","containerY","clientY","offsetTop","button","heldKeys","concat","addListener","onMouseMove","onKeyUp","key","addEventListener","dragState","container","point","_this2$unproject","drawEvent","onDragStart","enabled","setOptions","draggable","onDrag","_this2$unproject2","onDragEnd","unregister","removeEventListener","render","changes","styling","_this3","deletedIds","forEach","deletedId","featureToDelete","data","getFeatureById","updated","updatedFeature","featureToUpdate","forEachProperty","property","name","setProperty","Object","keys","properties","geometry","coordinates","setGeometry","google","Data","path","i","length","coordinate","push","LineString","_coordinates2","paths","_i","_path","j","Polygon","created","createdFeature","addGeoJson","featureCollection","features","setStyle","feature","mode","getProperty","gmGeometry","getGeometry","getType","value","calculatedStyles","clickable","icon","pointWidth","fillColor","pointColor","fillOpacity","strokeColor","pointOutlineColor","strokeWeight","pointOutlineWidth","rotation","lineStringColor","lineStringWidth","polygonOutlineColor","polygonOutlineWidth","polygonFillOpacity","polygonFillColor","TerraDrawLeafletAdapter","_onKeyDownListener","_layer","_panes","getContainer","_this$_map$latLngToCo","latLngToContainerPoint","_this$_map$containerP","containerPointToLatLng","removeProperty","createPaneStyleSheet","pane","zIndex","createPane","latlng","originalEvent","on","preventDefault","_this2$_map$container","dragging","enable","disable","_this2$_map$container2","add","onKeyDown","off","selectedPane","getPane","_this4","unchanged","removeLayer","geoJSON","pointToLayer","modeStyle","paneId","String","featureStyles","circleMarker","radius","stroke","color","weight","interactive","_feature","addLayer","layer","TerraDrawMapboxGLAdapter","_rendered","_this$_map$project","getCanvas","_addGeoJSONSource","addSource","_addFillLayer","source","filter","paint","_addFillOutlineLayer","beneath","moveLayer","_addLineLayer","_addPointLayer","_addLayer","featureType","_addGeoJSONLayer","toLowerCase","_setGeoJSONLayerData","getSource","setData","_this2$_map$unproject","dragPan","_this2$_map$unproject2","modeFeatures","points","linestrings","polygons","styles","_loop","_modeFeatures$mode","pointId","_frame","cancel","_render","haversineDistanceKilometers","pointOne","pointTwo","toRadians","latOrLng","PI","phiOne","lambdaOne","phiTwo","deltaPhi","a","sin","cos","deltalambda","atan2","sqrt","degreesToRadians","degrees","radiansToDegrees","radians","origin","distance","bearing","longitude1","latitude1","bearingRad","lengthToRadians","earthRadius","latitude2","asin","circle","options","center","radiusKilometers","steps","destination","registerBehaviors","_state","_styles","behaviors","pointerDistance","onStyleChange","store","behaviorConfig","setStarted","setStopped","registerOnChange","onChange","onSelect","onDeselect","deselectedId","selectedId","styleFeature","set","_","TerraDrawBaseDrawMode","TerraDrawCircleMode","_TerraDrawBaseDrawMod","call","clickCount","currentCircleId","keyEvents","finish","_inheritsLoose","close","start","stop","cleanUp","startingCircle","_this$store$create","create","distanceKm","updatedCircle","updateGeometry","error","_extends","outlineColor","outlineWidth","pixelDistance","TerraDrawFreehandMode","startingClick","currentId","closingPointId","minDistance","currentLineGeometry","getGeometryCopy","_currentLineGeometry$","_this$project","previousLat","_this$project2","closingLat","closingDistance","pop","closingPointColor","closingPointWidth","closingPointOutlineColor","closingPointOutlineWidth","selfIntersects","coord","ring0","edge0","ring1","edge1","ifInteresctionAddToOutput","output","frac","frac1","start0","end0","start1","end1","equalArrays","x0","y0","x1","y1","x2","y2","x3","y3","denom","intersect","intersection","isOutside","toString","array1","array2","TerraDrawModeBehavior","_ref","ClickBoundingBoxBehavior","_TerraDrawModeBehavio","halfDist","c","PixelDistanceBehavior","measure","clickEvent","secondCoordinate","SnappingBehavior","clickBoundingBox","getSnappableCoordinate","currentFeatureId","getSnappable","Boolean","bbox","search","closest","minDist","Infinity","dist","TerraDrawLineStringMode","currentCoordinate","allowSelfIntersections","snappingEnabled","snapping","updatedCoord","_this$store$create2","_currentLineGeometry","_currentLineGeometry$2","newLineString","getDefaultStyling","TerraDrawPointMode","coordinatesIdentical","coordinateTwo","ClosingPointsBehavior","_startEndPoints","selectedCoords","ids","POLYGON_PROPERTIES","_properties","_properties2","update","updatedCoordinates","isClosingPoint","opening","closing","isClosing","isPreviousClosing","distancePrevious","_createClass","get","TerraDrawPolygonMode","isClosed","closingPoints","currentPolygonCoordinates","slice","closestCoord","epsilon","offset","max","_this$closingPoints$i","currentPolygonGeometry","_this$closingPoints$i2","updatedPolygon","TerraDrawRenderMode","coordinates1","coordinates2","precision","heading","lon2","lat1","lat2","lon1","b","midpoint","getMidPointCoordinates","featureCoords","midPointCoords","mid","midpointCoordinate","MidPointBehavior","selectionPointBehavior","_midPoints","insert","midPointId","midPoint","getPropertiesCopy","midPointFeatureId","midPointSegment","_this$store$getProper","splice","featureId","has","getMidPoints","getUpdated","updatedMidPointCoord","SelectionPointBehavior","_selectionPoints","geometryType","selectionPoints","getCoordinatesAsPoints","selectionPoint","selectionPointFeatureId","index","getOneUpdated","updatedCoordinate","pointInPolygon","rings","p","p1","p2","inside","len","len2","ring","k","linePointOne","linePointTwo","square","dist2","v","w","l2","t","min","distToSegmentSquared","FeaturesAtMouseEventBehavior","createClickBoundingBox","find","hasSelection","clickedFeature","clickedFeatureDistance","clickedMidPoint","clickedMidPointDistance","nextCoord","distanceToLine","pixelDistanceToLine","DragFeatureBehavior","featuresAtMouseEvent","midPoints","dragPosition","drag","mouseCoord","updatedCoords","upToCoord","delta","updatedSelectionPoints","updatedMidPoints","newPosition","Array","isArray","DragCoordinateBehavior","geomCoordinates","closestCoordinate","isFirstOrLastPolygonCoord","lastCoordIndex","updatedSelectionPoint","centroid","geojson","xSum","ySum","rhumbBearing","end","phi1","from","phi2","to","deltaLambda","deltaPsi","log","tan","bear360","distanceMeters","lambda1","theta","DeltaPhi","abs","DeltaPsi","q","rhumbDistance","DeltaLambda","RotateFeatureBehavior","lastBearing","reset","rotate","transformRotate","angle","pivot","pointCoords","finalAngle","newCoords","rhumbDestination","ScaleFeatureBehavior","lastDistance","transformScale","factor","originalDistance","newCoord","TerraDrawSelectMode","dragEventThrottle","dragEventCount","selected","flags","dragFeature","dragCoordinate","rotateFeature","scaleFeature","deselect","delete","updateProperty","deleteSelected","onRightClick","clickedSelectionPointProps","coordinateIndex","modeFlags","deletable","shift","midpoints","onLeftClick","_this$featuresAtMouse","previouslySelectedId","_this$store$getGeomet","setMapDraggability","position","rotateable","includes","scaleable","nearbySelectionPoint","selectedColor","selectionPointColor","selectionPointOutlineColor","selectionPointWidth","midPointOutlineWidth","midPointColor","midPointOutlineColor","midPointWidth","TerraDrawStaticMode","replace","random","quickselect","arr","left","right","compare","n","m","z","exp","s","sd","swap","tmp","node","toBBox","distBBox","children","destNode","createNode","minX","minY","maxX","maxY","extend","leaf","child","compareNodeMinX","compareNodeMinY","bboxArea","bboxMargin","intersects","height","stack","ceil","RBush","maxEntries","_maxEntries","_minEntries","clear","result","nodesToSearch","childBBox","contains","_all","collides","load","_build","_splitRoot","tmpNode","_insert","item","goingUp","parent","indexes","indexOf","_condense","compareMinX","compareMinY","apply","items","M","N","calcBBox","N2","N1","multiSelect","right2","right3","_chooseSubtree","level","minArea","minEnlargement","targetNode","area","enlargement","isNode","insertPath","_split","_adjustParentBBoxes","_chooseSplitAxis","splitIndex","_chooseSplitIndex","newNode","minOverlap","bbox1","overlap","bbox2","_allDistMargin","sort","margin","leftBBox","rightBBox","_child","siblings","SpatialIndex","tree","idToNode","nodeToId","Map","setMaps","longitudes","latitudes","minLat","maxLat","seenIds","GeoJSONStore","tracked","spatialIndex","_onChange","validateFeature","getId","uuid4","clone","obj","JSON","parse","stringify","featureValidation","clonedData","createdAt","updatedAt","Date","change","propertiesToUpdate","geometriesToUpdate","_ref2","_this5","_ref3","createdProperties","_this6","copyAll","_this7","_modes","_mode","_adapter","_enabled","_store","_eventListeners","adapter","modes","static","select","getChanged","changed","f","listener","_getChanged","getModeStyles","_getChanged2","_getChanged3","modeId","initialRender","modeStyles","bind","setModeStyles","getSnapshot","getCurrentMode","changeMode","callback","listeners","TerraDraw"],"mappings":"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"}