@accelint/map-toolkit 1.2.0 → 1.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +11 -0
- package/catalog-info.yaml +3 -3
- package/dist/camera/events.d.ts +45 -0
- package/dist/camera/events.js +45 -0
- package/dist/camera/events.js.map +1 -1
- package/dist/camera/store.d.ts +47 -0
- package/dist/camera/store.js +81 -0
- package/dist/camera/store.js.map +1 -1
- package/dist/camera/types.d.ts +81 -0
- package/dist/cursor-coordinates/constants.d.ts +8 -0
- package/dist/cursor-coordinates/constants.js +22 -0
- package/dist/cursor-coordinates/constants.js.map +1 -0
- package/dist/cursor-coordinates/store.d.ts +1 -0
- package/dist/cursor-coordinates/store.js +1 -0
- package/dist/cursor-coordinates/store.js.map +1 -1
- package/dist/cursor-coordinates/use-cursor-coordinates.d.ts +5 -0
- package/dist/cursor-coordinates/use-cursor-coordinates.js +23 -8
- package/dist/cursor-coordinates/use-cursor-coordinates.js.map +1 -1
- package/dist/deckgl/base-map/constants.d.ts +12 -0
- package/dist/deckgl/base-map/constants.js +12 -0
- package/dist/deckgl/base-map/constants.js.map +1 -1
- package/dist/deckgl/base-map/controls.d.ts +11 -1
- package/dist/deckgl/base-map/controls.js +5 -0
- package/dist/deckgl/base-map/controls.js.map +1 -1
- package/dist/deckgl/base-map/events.d.ts +30 -0
- package/dist/deckgl/base-map/events.js +30 -0
- package/dist/deckgl/base-map/events.js.map +1 -1
- package/dist/deckgl/base-map/index.d.ts +2 -2
- package/dist/deckgl/base-map/index.js +33 -3
- package/dist/deckgl/base-map/index.js.map +1 -1
- package/dist/deckgl/base-map/provider.d.ts +2 -2
- package/dist/deckgl/index.js +1 -1
- package/dist/deckgl/saved-viewports/index.d.ts +75 -0
- package/dist/deckgl/saved-viewports/index.js +58 -0
- package/dist/deckgl/saved-viewports/index.js.map +1 -1
- package/dist/deckgl/saved-viewports/storage.d.ts +51 -0
- package/dist/deckgl/saved-viewports/storage.js +64 -0
- package/dist/deckgl/saved-viewports/storage.js.map +1 -1
- package/dist/deckgl/shapes/display-shape-layer/constants.js +18 -6
- package/dist/deckgl/shapes/display-shape-layer/constants.js.map +1 -1
- package/dist/deckgl/shapes/display-shape-layer/fiber.d.ts +7 -0
- package/dist/deckgl/shapes/display-shape-layer/fiber.js.map +1 -1
- package/dist/deckgl/shapes/display-shape-layer/utils/display-style.js +61 -4
- package/dist/deckgl/shapes/display-shape-layer/utils/display-style.js.map +1 -1
- package/dist/deckgl/shapes/display-shape-layer/utils/labels.d.ts +22 -8
- package/dist/deckgl/shapes/display-shape-layer/utils/labels.js +75 -4
- package/dist/deckgl/shapes/display-shape-layer/utils/labels.js.map +1 -1
- package/dist/deckgl/shapes/draw-shape-layer/constants.js +30 -0
- package/dist/deckgl/shapes/draw-shape-layer/constants.js.map +1 -1
- package/dist/deckgl/shapes/draw-shape-layer/fiber.js +36 -0
- package/dist/deckgl/shapes/draw-shape-layer/fiber.js.map +1 -1
- package/dist/deckgl/shapes/draw-shape-layer/index.d.ts +2 -2
- package/dist/deckgl/shapes/draw-shape-layer/modes/draw-circle-mode-with-tooltip.js +32 -1
- package/dist/deckgl/shapes/draw-shape-layer/modes/draw-circle-mode-with-tooltip.js.map +1 -1
- package/dist/deckgl/shapes/draw-shape-layer/modes/draw-ellipse-mode-with-tooltip.js +37 -8
- package/dist/deckgl/shapes/draw-shape-layer/modes/draw-ellipse-mode-with-tooltip.js.map +1 -1
- package/dist/deckgl/shapes/draw-shape-layer/modes/draw-line-string-mode-with-tooltip.js +43 -1
- package/dist/deckgl/shapes/draw-shape-layer/modes/draw-line-string-mode-with-tooltip.js.map +1 -1
- package/dist/deckgl/shapes/draw-shape-layer/modes/draw-polygon-mode-with-tooltip.js +44 -1
- package/dist/deckgl/shapes/draw-shape-layer/modes/draw-polygon-mode-with-tooltip.js.map +1 -1
- package/dist/deckgl/shapes/draw-shape-layer/modes/draw-rectangle-mode-with-tooltip.js +46 -3
- package/dist/deckgl/shapes/draw-shape-layer/modes/draw-rectangle-mode-with-tooltip.js.map +1 -1
- package/dist/deckgl/shapes/draw-shape-layer/modes/index.js +37 -1
- package/dist/deckgl/shapes/draw-shape-layer/modes/index.js.map +1 -1
- package/dist/deckgl/shapes/draw-shape-layer/store.js +50 -2
- package/dist/deckgl/shapes/draw-shape-layer/store.js.map +1 -1
- package/dist/deckgl/shapes/draw-shape-layer/utils/feature-conversion.js +138 -17
- package/dist/deckgl/shapes/draw-shape-layer/utils/feature-conversion.js.map +1 -1
- package/dist/deckgl/shapes/edit-shape-layer/events.js +1 -1
- package/dist/deckgl/shapes/edit-shape-layer/events.js.map +1 -1
- package/dist/deckgl/shapes/edit-shape-layer/index.d.ts +2 -2
- package/dist/deckgl/shapes/edit-shape-layer/index.js +14 -0
- package/dist/deckgl/shapes/edit-shape-layer/index.js.map +1 -1
- package/dist/deckgl/shapes/edit-shape-layer/modes/base-transform-mode.js +56 -8
- package/dist/deckgl/shapes/edit-shape-layer/modes/base-transform-mode.js.map +1 -1
- package/dist/deckgl/shapes/edit-shape-layer/modes/bounding-transform-mode.js +26 -4
- package/dist/deckgl/shapes/edit-shape-layer/modes/bounding-transform-mode.js.map +1 -1
- package/dist/deckgl/shapes/edit-shape-layer/modes/circle-transform-mode.js +28 -3
- package/dist/deckgl/shapes/edit-shape-layer/modes/circle-transform-mode.js.map +1 -1
- package/dist/deckgl/shapes/edit-shape-layer/modes/index.js +24 -0
- package/dist/deckgl/shapes/edit-shape-layer/modes/index.js.map +1 -1
- package/dist/deckgl/shapes/edit-shape-layer/modes/rotate-mode-with-snap.js +33 -4
- package/dist/deckgl/shapes/edit-shape-layer/modes/rotate-mode-with-snap.js.map +1 -1
- package/dist/deckgl/shapes/edit-shape-layer/modes/scale-mode-with-free-transform.js +21 -2
- package/dist/deckgl/shapes/edit-shape-layer/modes/scale-mode-with-free-transform.js.map +1 -1
- package/dist/deckgl/shapes/edit-shape-layer/modes/vertex-transform-mode.js +35 -11
- package/dist/deckgl/shapes/edit-shape-layer/modes/vertex-transform-mode.js.map +1 -1
- package/dist/deckgl/shapes/edit-shape-layer/store.js +1 -1
- package/dist/deckgl/shapes/edit-shape-layer/store.js.map +1 -1
- package/dist/deckgl/shapes/shared/hooks/use-shift-zoom-disable.js +12 -0
- package/dist/deckgl/shapes/shared/hooks/use-shift-zoom-disable.js.map +1 -1
- package/dist/deckgl/shapes/shared/types.d.ts +3 -3
- package/dist/deckgl/shapes/shared/types.js +2 -2
- package/dist/deckgl/shapes/shared/types.js.map +1 -1
- package/dist/deckgl/shapes/shared/utils/geometry-measurements.js +3 -3
- package/dist/deckgl/shapes/shared/utils/geometry-measurements.js.map +1 -1
- package/dist/deckgl/shapes/shared/utils/pick-filtering.js +1 -1
- package/dist/deckgl/shapes/shared/utils/pick-filtering.js.map +1 -1
- package/dist/deckgl/symbol-layer/fiber.d.ts +18 -0
- package/dist/deckgl/symbol-layer/fiber.js.map +1 -1
- package/dist/deckgl/symbol-layer/index.d.ts +79 -1
- package/dist/deckgl/symbol-layer/index.js +72 -1
- package/dist/deckgl/symbol-layer/index.js.map +1 -1
- package/dist/deckgl/text-layer/character-sets.d.ts +30 -0
- package/dist/deckgl/text-layer/character-sets.js +26 -0
- package/dist/deckgl/text-layer/character-sets.js.map +1 -1
- package/dist/deckgl/text-layer/default-settings.d.ts +29 -0
- package/dist/deckgl/text-layer/default-settings.js +28 -0
- package/dist/deckgl/text-layer/default-settings.js.map +1 -1
- package/dist/deckgl/text-layer/index.d.ts +65 -0
- package/dist/deckgl/text-layer/index.js +56 -0
- package/dist/deckgl/text-layer/index.js.map +1 -1
- package/dist/map-cursor/events.d.ts +19 -0
- package/dist/map-cursor/events.js +19 -0
- package/dist/map-cursor/events.js.map +1 -1
- package/dist/map-cursor/store.d.ts +34 -2
- package/dist/map-cursor/store.js +44 -3
- package/dist/map-cursor/store.js.map +1 -1
- package/dist/map-mode/store.d.ts +43 -4
- package/dist/map-mode/store.js +56 -6
- package/dist/map-mode/store.js.map +1 -1
- package/dist/shared/create-map-store.d.ts +14 -0
- package/dist/shared/create-map-store.js +26 -2
- package/dist/shared/create-map-store.js.map +1 -1
- package/dist/shared/units.d.ts +24 -0
- package/dist/shared/units.js +24 -0
- package/dist/shared/units.js.map +1 -1
- package/dist/viewport/store.d.ts +1 -0
- package/dist/viewport/store.js +4 -0
- package/dist/viewport/store.js.map +1 -1
- package/package.json +3 -3
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"draw-line-string-mode-with-tooltip.js","names":[],"sources":["../../../../../src/deckgl/shapes/draw-shape-layer/modes/draw-line-string-mode-with-tooltip.ts"],"sourcesContent":["/*\n * Copyright 2026 Hypergiant Galactic Systems Inc. All rights reserved.\n * This file is licensed to you under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License. You may obtain a copy\n * of the License at https://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software distributed under\n * the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS\n * OF ANY KIND, either express or implied. See the License for the specific language\n * governing permissions and limitations under the License.\n */\n\nimport {\n type ClickEvent,\n DrawLineStringMode,\n type FeatureCollection,\n type ModeProps,\n type PointerMoveEvent,\n type Tooltip,\n} from '@deck.gl-community/editable-layers';\nimport { type Coord, distance } from '@turf/turf';\nimport {\n DEFAULT_DISTANCE_UNITS,\n getDistanceUnitAbbreviation,\n} from '@/shared/units';\nimport { formatDistanceTooltip } from '../../shared/constants';\n\n/**\n * Extends DrawLineStringMode to display distance tooltip between points.\n *\n * Shows the distance from the last clicked point to the current cursor position\n * while drawing a line string.\n *\n * Includes a workaround for the double-click to finish issue in @deck.gl-community/editable-layers ~9.1.\n * This will be fixed in a future version (PR #225).\n */\nexport class DrawLineStringModeWithTooltip extends DrawLineStringMode {\n private tooltip: Tooltip | null = null;\n private lastModeProps: ModeProps<FeatureCollection> | null = null;\n\n /**\n * Finish drawing the line string.\n * Extracted to share between double-click workaround and parent class logic.\n */\n private finishDrawing(props: ModeProps<FeatureCollection>): void {\n const clickSequence = this.getClickSequence();\n if (clickSequence.length <= 1) {\n return;\n }\n\n const lineStringToAdd = {\n type: 'LineString' as const,\n coordinates: [...clickSequence],\n };\n\n this.resetClickSequence();\n this.tooltip = null;\n this.lastModeProps = null;\n\n const editAction = this.getAddFeatureAction(lineStringToAdd, props.data);\n if (editAction) {\n props.onEdit(editAction);\n }\n }\n\n /**\n * Handle double-click to finish drawing.\n * This is called externally via a DOM event listener as a workaround for\n * @deck.gl-community/editable-layers ~9.1 which doesn't register 'dblclick' in EVENT_TYPES.\n * @see https://github.com/visgl/deck.gl-community/pull/225\n */\n handleDoubleClick(): void {\n if (this.lastModeProps) {\n this.finishDrawing(this.lastModeProps);\n }\n }\n\n /**\n * Override handleClick to store props for double-click workaround.\n */\n override handleClick(\n event: ClickEvent,\n props: ModeProps<FeatureCollection>,\n ): void {\n // Store props so handleDoubleClick can access them\n this.lastModeProps = props;\n super.handleClick(event, props);\n }\n\n override handlePointerMove(\n event: PointerMoveEvent,\n props: ModeProps<FeatureCollection>,\n ) {\n super.handlePointerMove(event, props);\n\n const clickSequence = this.getClickSequence();\n if (!clickSequence.length) {\n this.tooltip = null;\n return;\n }\n\n const { mapCoords } = event;\n const distanceUnits =\n props.modeConfig?.distanceUnits ?? DEFAULT_DISTANCE_UNITS;\n\n const lastPoint = clickSequence[clickSequence.length - 1] as Coord;\n const currentPoint = mapCoords as Coord;\n\n const dist = distance(lastPoint, currentPoint, { units: distanceUnits });\n const unitAbbrev = getDistanceUnitAbbreviation(distanceUnits);\n\n this.tooltip = {\n position: mapCoords,\n text: formatDistanceTooltip(dist, unitAbbrev),\n };\n }\n\n override getTooltips(): Tooltip[] {\n return this.tooltip ? [this.tooltip] : [];\n }\n}\n"],"mappings":"
|
|
1
|
+
{"version":3,"file":"draw-line-string-mode-with-tooltip.js","names":[],"sources":["../../../../../src/deckgl/shapes/draw-shape-layer/modes/draw-line-string-mode-with-tooltip.ts"],"sourcesContent":["/*\n * Copyright 2026 Hypergiant Galactic Systems Inc. All rights reserved.\n * This file is licensed to you under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License. You may obtain a copy\n * of the License at https://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software distributed under\n * the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS\n * OF ANY KIND, either express or implied. See the License for the specific language\n * governing permissions and limitations under the License.\n */\n\nimport {\n type ClickEvent,\n DrawLineStringMode,\n type FeatureCollection,\n type ModeProps,\n type PointerMoveEvent,\n type Tooltip,\n} from '@deck.gl-community/editable-layers';\nimport { type Coord, distance } from '@turf/turf';\nimport {\n DEFAULT_DISTANCE_UNITS,\n getDistanceUnitAbbreviation,\n} from '@/shared/units';\nimport { formatDistanceTooltip } from '../../shared/constants';\n\n/**\n * Extends DrawLineStringMode to display distance tooltip between points.\n *\n * Shows the distance from the last clicked point to the current cursor position\n * while drawing a line string. The tooltip updates in real-time as the cursor moves.\n *\n * ## Drawing Flow\n * 1. Click to add first point\n * 2. Move cursor (tooltip shows distance from last point)\n * 3. Click to add more points\n * 4. Double-click to finish the line string\n *\n * ## Double-Click Workaround\n * Includes a workaround for the double-click to finish issue in @deck.gl-community/editable-layers ~9.1.\n * This will be fixed in a future version (PR #225).\n *\n * @example\n * ```typescript\n * import { DrawLineStringModeWithTooltip } from '@accelint/map-toolkit/deckgl/shapes/draw-shape-layer/modes';\n *\n * // Used internally by DrawShapeLayer\n * const mode = new DrawLineStringModeWithTooltip();\n * ```\n */\nexport class DrawLineStringModeWithTooltip extends DrawLineStringMode {\n /** Current tooltip state (null when not drawing) */\n private tooltip: Tooltip | null = null;\n /** Cached mode props for double-click workaround */\n private lastModeProps: ModeProps<FeatureCollection> | null = null;\n\n /**\n * Finish drawing the line string.\n *\n * Creates a LineString geometry from the click sequence and emits an edit action.\n * Requires at least 2 points to create a valid line string.\n * Extracted to share between double-click workaround and parent class logic.\n *\n * @param props - Mode properties with onEdit callback\n */\n private finishDrawing(props: ModeProps<FeatureCollection>): void {\n const clickSequence = this.getClickSequence();\n if (clickSequence.length <= 1) {\n return;\n }\n\n const lineStringToAdd = {\n type: 'LineString' as const,\n coordinates: [...clickSequence],\n };\n\n this.resetClickSequence();\n this.tooltip = null;\n this.lastModeProps = null;\n\n const editAction = this.getAddFeatureAction(lineStringToAdd, props.data);\n if (editAction) {\n props.onEdit(editAction);\n }\n }\n\n /**\n * Handle double-click to finish drawing.\n * This is called externally via a DOM event listener as a workaround for\n * @deck.gl-community/editable-layers ~9.1 which doesn't register 'dblclick' in EVENT_TYPES.\n * @see https://github.com/visgl/deck.gl-community/pull/225\n */\n handleDoubleClick(): void {\n if (this.lastModeProps) {\n this.finishDrawing(this.lastModeProps);\n }\n }\n\n /**\n * Override handleClick to store props for double-click workaround.\n *\n * Caches the mode props so that the external double-click handler can\n * access them when finishing the drawing.\n *\n * @param event - Click event with map coordinates\n * @param props - Mode properties including onEdit callback\n */\n override handleClick(\n event: ClickEvent,\n props: ModeProps<FeatureCollection>,\n ): void {\n // Store props so handleDoubleClick can access them\n this.lastModeProps = props;\n super.handleClick(event, props);\n }\n\n /**\n * Handle pointer move events to update the tooltip with distance.\n *\n * Calculates the distance from the last clicked point to the current\n * cursor position and displays it in the configured distance units.\n *\n * @param event - Pointer move event with cursor position\n * @param props - Mode properties including distance units configuration\n */\n override handlePointerMove(\n event: PointerMoveEvent,\n props: ModeProps<FeatureCollection>,\n ) {\n super.handlePointerMove(event, props);\n\n const clickSequence = this.getClickSequence();\n if (!clickSequence.length) {\n this.tooltip = null;\n return;\n }\n\n const { mapCoords } = event;\n const distanceUnits =\n props.modeConfig?.distanceUnits ?? DEFAULT_DISTANCE_UNITS;\n\n const lastPoint = clickSequence[clickSequence.length - 1] as Coord;\n const currentPoint = mapCoords as Coord;\n\n const dist = distance(lastPoint, currentPoint, { units: distanceUnits });\n const unitAbbrev = getDistanceUnitAbbreviation(distanceUnits);\n\n this.tooltip = {\n position: mapCoords,\n text: formatDistanceTooltip(dist, unitAbbrev),\n };\n }\n\n /**\n * Get the current tooltip array for rendering.\n *\n * @returns Array containing the tooltip if one is active, empty array otherwise\n */\n override getTooltips(): Tooltip[] {\n return this.tooltip ? [this.tooltip] : [];\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAmDA,IAAa,gCAAb,cAAmD,mBAAmB;;CAEpE,AAAQ,UAA0B;;CAElC,AAAQ,gBAAqD;;;;;;;;;;CAW7D,AAAQ,cAAc,OAA2C;EAC/D,MAAM,gBAAgB,KAAK,kBAAkB;AAC7C,MAAI,cAAc,UAAU,EAC1B;EAGF,MAAM,kBAAkB;GACtB,MAAM;GACN,aAAa,CAAC,GAAG,cAAc;GAChC;AAED,OAAK,oBAAoB;AACzB,OAAK,UAAU;AACf,OAAK,gBAAgB;EAErB,MAAM,aAAa,KAAK,oBAAoB,iBAAiB,MAAM,KAAK;AACxE,MAAI,WACF,OAAM,OAAO,WAAW;;;;;;;;CAU5B,oBAA0B;AACxB,MAAI,KAAK,cACP,MAAK,cAAc,KAAK,cAAc;;;;;;;;;;;CAa1C,AAAS,YACP,OACA,OACM;AAEN,OAAK,gBAAgB;AACrB,QAAM,YAAY,OAAO,MAAM;;;;;;;;;;;CAYjC,AAAS,kBACP,OACA,OACA;AACA,QAAM,kBAAkB,OAAO,MAAM;EAErC,MAAM,gBAAgB,KAAK,kBAAkB;AAC7C,MAAI,CAAC,cAAc,QAAQ;AACzB,QAAK,UAAU;AACf;;EAGF,MAAM,EAAE,cAAc;EACtB,MAAM,gBACJ,MAAM,YAAY,iBAAiB;EAErC,MAAM,YAAY,cAAc,cAAc,SAAS;AAMvD,OAAK,UAAU;GACb,UAAU;GACV,MAAM,sBALK,SAAS,WAFD,WAE0B,EAAE,OAAO,eAAe,CAAC,EACrD,4BAA4B,cAAc,CAId;GAC9C;;;;;;;CAQH,AAAS,cAAyB;AAChC,SAAO,KAAK,UAAU,CAAC,KAAK,QAAQ,GAAG,EAAE"}
|
|
@@ -21,17 +21,40 @@ import { distance } from "@turf/turf";
|
|
|
21
21
|
* Extends DrawPolygonMode to display distance tooltip between points.
|
|
22
22
|
*
|
|
23
23
|
* Shows the distance from the last clicked point to the current cursor position
|
|
24
|
-
* while drawing a polygon.
|
|
24
|
+
* while drawing a polygon. The tooltip updates in real-time as the cursor moves.
|
|
25
25
|
*
|
|
26
|
+
* ## Drawing Flow
|
|
27
|
+
* 1. Click to add first vertex
|
|
28
|
+
* 2. Move cursor (tooltip shows distance from last vertex)
|
|
29
|
+
* 3. Click to add more vertices
|
|
30
|
+
* 4. Double-click or click the starting point to close the polygon
|
|
31
|
+
*
|
|
32
|
+
* ## Double-Click Workaround
|
|
26
33
|
* Includes a workaround for the double-click to finish issue in @deck.gl-community/editable-layers ~9.1.
|
|
27
34
|
* This will be fixed in a future version (PR #225).
|
|
35
|
+
*
|
|
36
|
+
* @example
|
|
37
|
+
* ```typescript
|
|
38
|
+
* import { DrawPolygonModeWithTooltip } from '@accelint/map-toolkit/deckgl/shapes/draw-shape-layer/modes';
|
|
39
|
+
*
|
|
40
|
+
* // Used internally by DrawShapeLayer
|
|
41
|
+
* const mode = new DrawPolygonModeWithTooltip();
|
|
42
|
+
* ```
|
|
28
43
|
*/
|
|
29
44
|
var DrawPolygonModeWithTooltip = class extends DrawPolygonMode {
|
|
45
|
+
/** Current tooltip state (null when not drawing) */
|
|
30
46
|
tooltip = null;
|
|
47
|
+
/** Cached mode props for double-click workaround */
|
|
31
48
|
lastModeProps = null;
|
|
32
49
|
/**
|
|
33
50
|
* Finish drawing the polygon.
|
|
51
|
+
*
|
|
52
|
+
* Creates a Polygon geometry from the click sequence and emits an edit action.
|
|
53
|
+
* Requires at least 3 points to create a valid polygon. Automatically closes
|
|
54
|
+
* the polygon by adding the first point to the end of the coordinate ring.
|
|
34
55
|
* Extracted to share between double-click workaround and parent class logic.
|
|
56
|
+
*
|
|
57
|
+
* @param props - Mode properties with onEdit callback
|
|
35
58
|
*/
|
|
36
59
|
finishDrawing(props) {
|
|
37
60
|
const clickSequence = this.getClickSequence();
|
|
@@ -58,11 +81,26 @@ var DrawPolygonModeWithTooltip = class extends DrawPolygonMode {
|
|
|
58
81
|
}
|
|
59
82
|
/**
|
|
60
83
|
* Override handleClick to store props for double-click workaround.
|
|
84
|
+
*
|
|
85
|
+
* Caches the mode props so that the external double-click handler can
|
|
86
|
+
* access them when finishing the drawing.
|
|
87
|
+
*
|
|
88
|
+
* @param event - Click event with map coordinates
|
|
89
|
+
* @param props - Mode properties including onEdit callback
|
|
61
90
|
*/
|
|
62
91
|
handleClick(event, props) {
|
|
63
92
|
this.lastModeProps = props;
|
|
64
93
|
super.handleClick(event, props);
|
|
65
94
|
}
|
|
95
|
+
/**
|
|
96
|
+
* Handle pointer move events to update the tooltip with distance.
|
|
97
|
+
*
|
|
98
|
+
* Calculates the distance from the last clicked vertex to the current
|
|
99
|
+
* cursor position and displays it in the configured distance units.
|
|
100
|
+
*
|
|
101
|
+
* @param event - Pointer move event with cursor position
|
|
102
|
+
* @param props - Mode properties including distance units configuration
|
|
103
|
+
*/
|
|
66
104
|
handlePointerMove(event, props) {
|
|
67
105
|
super.handlePointerMove(event, props);
|
|
68
106
|
const clickSequence = this.getClickSequence();
|
|
@@ -78,6 +116,11 @@ var DrawPolygonModeWithTooltip = class extends DrawPolygonMode {
|
|
|
78
116
|
text: formatDistanceTooltip(distance(lastPoint, mapCoords, { units: distanceUnits }), getDistanceUnitAbbreviation(distanceUnits))
|
|
79
117
|
};
|
|
80
118
|
}
|
|
119
|
+
/**
|
|
120
|
+
* Get the current tooltip array for rendering.
|
|
121
|
+
*
|
|
122
|
+
* @returns Array containing the tooltip if one is active, empty array otherwise
|
|
123
|
+
*/
|
|
81
124
|
getTooltips() {
|
|
82
125
|
return this.tooltip ? [this.tooltip] : [];
|
|
83
126
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"draw-polygon-mode-with-tooltip.js","names":[],"sources":["../../../../../src/deckgl/shapes/draw-shape-layer/modes/draw-polygon-mode-with-tooltip.ts"],"sourcesContent":["/*\n * Copyright 2026 Hypergiant Galactic Systems Inc. All rights reserved.\n * This file is licensed to you under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License. You may obtain a copy\n * of the License at https://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software distributed under\n * the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS\n * OF ANY KIND, either express or implied. See the License for the specific language\n * governing permissions and limitations under the License.\n */\n\nimport {\n type ClickEvent,\n DrawPolygonMode,\n type FeatureCollection,\n type ModeProps,\n type PointerMoveEvent,\n type Tooltip,\n} from '@deck.gl-community/editable-layers';\nimport { type Coord, distance } from '@turf/turf';\nimport {\n DEFAULT_DISTANCE_UNITS,\n getDistanceUnitAbbreviation,\n} from '@/shared/units';\nimport { formatDistanceTooltip } from '../../shared/constants';\n\n/**\n * Extends DrawPolygonMode to display distance tooltip between points.\n *\n * Shows the distance from the last clicked point to the current cursor position\n * while drawing a polygon.\n *\n * Includes a workaround for the double-click to finish issue in @deck.gl-community/editable-layers ~9.1.\n * This will be fixed in a future version (PR #225).\n */\nexport class DrawPolygonModeWithTooltip extends DrawPolygonMode {\n private tooltip: Tooltip | null = null;\n private lastModeProps: ModeProps<FeatureCollection> | null = null;\n\n /**\n * Finish drawing the polygon.\n * Extracted to share between double-click workaround and parent class logic.\n */\n private finishDrawing(props: ModeProps<FeatureCollection>): void {\n const clickSequence = this.getClickSequence();\n const firstPoint = clickSequence[0];\n if (clickSequence.length <= 2 || !firstPoint) {\n return;\n }\n\n const polygonToAdd = {\n type: 'Polygon' as const,\n coordinates: [[...clickSequence, firstPoint]],\n };\n\n this.resetClickSequence();\n this.tooltip = null;\n this.lastModeProps = null;\n\n const editAction = this.getAddFeatureOrBooleanPolygonAction(\n polygonToAdd,\n props,\n );\n if (editAction) {\n props.onEdit(editAction);\n }\n }\n\n /**\n * Handle double-click to finish drawing.\n * This is called externally via a DOM event listener as a workaround for\n * @deck.gl-community/editable-layers ~9.1 which doesn't register 'dblclick' in EVENT_TYPES.\n * @see https://github.com/visgl/deck.gl-community/pull/225\n */\n handleDoubleClick(): void {\n if (this.lastModeProps) {\n this.finishDrawing(this.lastModeProps);\n }\n }\n\n /**\n * Override handleClick to store props for double-click workaround.\n */\n override handleClick(\n event: ClickEvent,\n props: ModeProps<FeatureCollection>,\n ): void {\n // Store props so handleDoubleClick can access them\n this.lastModeProps = props;\n super.handleClick(event, props);\n }\n\n override handlePointerMove(\n event: PointerMoveEvent,\n props: ModeProps<FeatureCollection>,\n ) {\n super.handlePointerMove(event, props);\n\n const clickSequence = this.getClickSequence();\n if (!clickSequence.length) {\n this.tooltip = null;\n return;\n }\n\n const { mapCoords } = event;\n const distanceUnits =\n props.modeConfig?.distanceUnits ?? DEFAULT_DISTANCE_UNITS;\n\n const lastPoint = clickSequence[clickSequence.length - 1] as Coord;\n const currentPoint = mapCoords as Coord;\n\n const dist = distance(lastPoint, currentPoint, { units: distanceUnits });\n const unitAbbrev = getDistanceUnitAbbreviation(distanceUnits);\n\n this.tooltip = {\n position: mapCoords,\n text: formatDistanceTooltip(dist, unitAbbrev),\n };\n }\n\n override getTooltips(): Tooltip[] {\n return this.tooltip ? [this.tooltip] : [];\n }\n}\n"],"mappings":"
|
|
1
|
+
{"version":3,"file":"draw-polygon-mode-with-tooltip.js","names":[],"sources":["../../../../../src/deckgl/shapes/draw-shape-layer/modes/draw-polygon-mode-with-tooltip.ts"],"sourcesContent":["/*\n * Copyright 2026 Hypergiant Galactic Systems Inc. All rights reserved.\n * This file is licensed to you under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License. You may obtain a copy\n * of the License at https://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software distributed under\n * the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS\n * OF ANY KIND, either express or implied. See the License for the specific language\n * governing permissions and limitations under the License.\n */\n\nimport {\n type ClickEvent,\n DrawPolygonMode,\n type FeatureCollection,\n type ModeProps,\n type PointerMoveEvent,\n type Tooltip,\n} from '@deck.gl-community/editable-layers';\nimport { type Coord, distance } from '@turf/turf';\nimport {\n DEFAULT_DISTANCE_UNITS,\n getDistanceUnitAbbreviation,\n} from '@/shared/units';\nimport { formatDistanceTooltip } from '../../shared/constants';\n\n/**\n * Extends DrawPolygonMode to display distance tooltip between points.\n *\n * Shows the distance from the last clicked point to the current cursor position\n * while drawing a polygon. The tooltip updates in real-time as the cursor moves.\n *\n * ## Drawing Flow\n * 1. Click to add first vertex\n * 2. Move cursor (tooltip shows distance from last vertex)\n * 3. Click to add more vertices\n * 4. Double-click or click the starting point to close the polygon\n *\n * ## Double-Click Workaround\n * Includes a workaround for the double-click to finish issue in @deck.gl-community/editable-layers ~9.1.\n * This will be fixed in a future version (PR #225).\n *\n * @example\n * ```typescript\n * import { DrawPolygonModeWithTooltip } from '@accelint/map-toolkit/deckgl/shapes/draw-shape-layer/modes';\n *\n * // Used internally by DrawShapeLayer\n * const mode = new DrawPolygonModeWithTooltip();\n * ```\n */\nexport class DrawPolygonModeWithTooltip extends DrawPolygonMode {\n /** Current tooltip state (null when not drawing) */\n private tooltip: Tooltip | null = null;\n /** Cached mode props for double-click workaround */\n private lastModeProps: ModeProps<FeatureCollection> | null = null;\n\n /**\n * Finish drawing the polygon.\n *\n * Creates a Polygon geometry from the click sequence and emits an edit action.\n * Requires at least 3 points to create a valid polygon. Automatically closes\n * the polygon by adding the first point to the end of the coordinate ring.\n * Extracted to share between double-click workaround and parent class logic.\n *\n * @param props - Mode properties with onEdit callback\n */\n private finishDrawing(props: ModeProps<FeatureCollection>): void {\n const clickSequence = this.getClickSequence();\n const firstPoint = clickSequence[0];\n if (clickSequence.length <= 2 || !firstPoint) {\n return;\n }\n\n const polygonToAdd = {\n type: 'Polygon' as const,\n coordinates: [[...clickSequence, firstPoint]],\n };\n\n this.resetClickSequence();\n this.tooltip = null;\n this.lastModeProps = null;\n\n const editAction = this.getAddFeatureOrBooleanPolygonAction(\n polygonToAdd,\n props,\n );\n if (editAction) {\n props.onEdit(editAction);\n }\n }\n\n /**\n * Handle double-click to finish drawing.\n * This is called externally via a DOM event listener as a workaround for\n * @deck.gl-community/editable-layers ~9.1 which doesn't register 'dblclick' in EVENT_TYPES.\n * @see https://github.com/visgl/deck.gl-community/pull/225\n */\n handleDoubleClick(): void {\n if (this.lastModeProps) {\n this.finishDrawing(this.lastModeProps);\n }\n }\n\n /**\n * Override handleClick to store props for double-click workaround.\n *\n * Caches the mode props so that the external double-click handler can\n * access them when finishing the drawing.\n *\n * @param event - Click event with map coordinates\n * @param props - Mode properties including onEdit callback\n */\n override handleClick(\n event: ClickEvent,\n props: ModeProps<FeatureCollection>,\n ): void {\n // Store props so handleDoubleClick can access them\n this.lastModeProps = props;\n super.handleClick(event, props);\n }\n\n /**\n * Handle pointer move events to update the tooltip with distance.\n *\n * Calculates the distance from the last clicked vertex to the current\n * cursor position and displays it in the configured distance units.\n *\n * @param event - Pointer move event with cursor position\n * @param props - Mode properties including distance units configuration\n */\n override handlePointerMove(\n event: PointerMoveEvent,\n props: ModeProps<FeatureCollection>,\n ) {\n super.handlePointerMove(event, props);\n\n const clickSequence = this.getClickSequence();\n if (!clickSequence.length) {\n this.tooltip = null;\n return;\n }\n\n const { mapCoords } = event;\n const distanceUnits =\n props.modeConfig?.distanceUnits ?? DEFAULT_DISTANCE_UNITS;\n\n const lastPoint = clickSequence[clickSequence.length - 1] as Coord;\n const currentPoint = mapCoords as Coord;\n\n const dist = distance(lastPoint, currentPoint, { units: distanceUnits });\n const unitAbbrev = getDistanceUnitAbbreviation(distanceUnits);\n\n this.tooltip = {\n position: mapCoords,\n text: formatDistanceTooltip(dist, unitAbbrev),\n };\n }\n\n /**\n * Get the current tooltip array for rendering.\n *\n * @returns Array containing the tooltip if one is active, empty array otherwise\n */\n override getTooltips(): Tooltip[] {\n return this.tooltip ? [this.tooltip] : [];\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAmDA,IAAa,6BAAb,cAAgD,gBAAgB;;CAE9D,AAAQ,UAA0B;;CAElC,AAAQ,gBAAqD;;;;;;;;;;;CAY7D,AAAQ,cAAc,OAA2C;EAC/D,MAAM,gBAAgB,KAAK,kBAAkB;EAC7C,MAAM,aAAa,cAAc;AACjC,MAAI,cAAc,UAAU,KAAK,CAAC,WAChC;EAGF,MAAM,eAAe;GACnB,MAAM;GACN,aAAa,CAAC,CAAC,GAAG,eAAe,WAAW,CAAC;GAC9C;AAED,OAAK,oBAAoB;AACzB,OAAK,UAAU;AACf,OAAK,gBAAgB;EAErB,MAAM,aAAa,KAAK,oCACtB,cACA,MACD;AACD,MAAI,WACF,OAAM,OAAO,WAAW;;;;;;;;CAU5B,oBAA0B;AACxB,MAAI,KAAK,cACP,MAAK,cAAc,KAAK,cAAc;;;;;;;;;;;CAa1C,AAAS,YACP,OACA,OACM;AAEN,OAAK,gBAAgB;AACrB,QAAM,YAAY,OAAO,MAAM;;;;;;;;;;;CAYjC,AAAS,kBACP,OACA,OACA;AACA,QAAM,kBAAkB,OAAO,MAAM;EAErC,MAAM,gBAAgB,KAAK,kBAAkB;AAC7C,MAAI,CAAC,cAAc,QAAQ;AACzB,QAAK,UAAU;AACf;;EAGF,MAAM,EAAE,cAAc;EACtB,MAAM,gBACJ,MAAM,YAAY,iBAAiB;EAErC,MAAM,YAAY,cAAc,cAAc,SAAS;AAMvD,OAAK,UAAU;GACb,UAAU;GACV,MAAM,sBALK,SAAS,WAFD,WAE0B,EAAE,OAAO,eAAe,CAAC,EACrD,4BAA4B,cAAc,CAId;GAC9C;;;;;;;CAQH,AAAS,cAAyB;AAChC,SAAO,KAAK,UAAU,CAAC,KAAK,QAAQ,GAAG,EAAE"}
|
|
@@ -22,15 +22,43 @@ import { featureCollection, point as point$1 } from "@turf/helpers";
|
|
|
22
22
|
* Extends DrawRectangleMode to display dimensions and area tooltip.
|
|
23
23
|
*
|
|
24
24
|
* Shows the width, height, and total area of the rectangle being drawn.
|
|
25
|
-
*
|
|
25
|
+
* The tooltip updates in real-time as the cursor moves, displaying measurements
|
|
26
|
+
* in the configured distance units.
|
|
27
|
+
*
|
|
28
|
+
* ## Drawing Flow
|
|
29
|
+
* 1. Click to set first corner
|
|
30
|
+
* 2. Move cursor (tooltip shows dimensions and area)
|
|
31
|
+
* 3. Click to set opposite corner and finish the rectangle
|
|
32
|
+
*
|
|
33
|
+
* ## Shift-to-Square Constraint
|
|
34
|
+
* Hold Shift while drawing to constrain the rectangle to a square with equal sides.
|
|
35
|
+
* Uses real-world distances (via Turf.js) to account for lat/lon distortion.
|
|
36
|
+
*
|
|
37
|
+
* @example
|
|
38
|
+
* ```typescript
|
|
39
|
+
* import { DrawRectangleModeWithTooltip } from '@accelint/map-toolkit/deckgl/shapes/draw-shape-layer/modes';
|
|
40
|
+
*
|
|
41
|
+
* // Used internally by DrawShapeLayer
|
|
42
|
+
* const mode = new DrawRectangleModeWithTooltip();
|
|
43
|
+
* ```
|
|
26
44
|
*/
|
|
27
45
|
var DrawRectangleModeWithTooltip = class extends DrawRectangleMode {
|
|
46
|
+
/** Current tooltip state (null when not drawing) */
|
|
28
47
|
tooltip = null;
|
|
48
|
+
/** Tracks whether Shift key is currently pressed for square constraint */
|
|
29
49
|
isShiftPressed = false;
|
|
30
50
|
/**
|
|
31
51
|
* Override getTwoClickPolygon to support Shift-constrained squares.
|
|
32
|
-
*
|
|
33
|
-
*
|
|
52
|
+
*
|
|
53
|
+
* When Shift is held, constrains the rectangle to a square by using the larger
|
|
54
|
+
* of the horizontal or vertical distances as the side length. Uses real-world
|
|
55
|
+
* geographic distances (via Turf.js) to account for lat/lon distortion at different
|
|
56
|
+
* latitudes.
|
|
57
|
+
*
|
|
58
|
+
* @param coord1 - First corner coordinates [lon, lat]
|
|
59
|
+
* @param coord2 - Second corner coordinates [lon, lat]
|
|
60
|
+
* @param modeConfig - Mode configuration options
|
|
61
|
+
* @returns Polygon geometry for the rectangle or square
|
|
34
62
|
*/
|
|
35
63
|
getTwoClickPolygon(coord1, coord2, modeConfig) {
|
|
36
64
|
let finalCoord2 = coord2;
|
|
@@ -48,6 +76,16 @@ var DrawRectangleModeWithTooltip = class extends DrawRectangleMode {
|
|
|
48
76
|
}
|
|
49
77
|
return super.getTwoClickPolygon(coord1, finalCoord2, modeConfig);
|
|
50
78
|
}
|
|
79
|
+
/**
|
|
80
|
+
* Handle pointer move events to update the tooltip with rectangle measurements.
|
|
81
|
+
*
|
|
82
|
+
* Tracks the Shift key state for square constraint and calculates the width,
|
|
83
|
+
* height, and area of the rectangle being drawn. Uses Turf.js for accurate
|
|
84
|
+
* geographic distance and area calculations.
|
|
85
|
+
*
|
|
86
|
+
* @param event - Pointer move event with cursor position and source event
|
|
87
|
+
* @param props - Mode properties including distance units configuration
|
|
88
|
+
*/
|
|
51
89
|
handlePointerMove(event, props) {
|
|
52
90
|
this.isShiftPressed = event.sourceEvent?.shiftKey ?? false;
|
|
53
91
|
super.handlePointerMove(event, props);
|
|
@@ -67,6 +105,11 @@ var DrawRectangleModeWithTooltip = class extends DrawRectangleMode {
|
|
|
67
105
|
text: formatRectangleTooltip(distance(firstClickPoint, cornerPoint, { units: distanceUnits }), distance(currentPoint, cornerPoint, { units: distanceUnits }), convertArea(area(bboxPolygon(bbox(featureCollection([firstClickPoint, currentPoint])))), "meters", distanceUnits), getDistanceUnitAbbreviation(distanceUnits))
|
|
68
106
|
};
|
|
69
107
|
}
|
|
108
|
+
/**
|
|
109
|
+
* Get the current tooltip array for rendering.
|
|
110
|
+
*
|
|
111
|
+
* @returns Array containing the tooltip if one is active, empty array otherwise
|
|
112
|
+
*/
|
|
70
113
|
getTooltips() {
|
|
71
114
|
return this.tooltip ? [this.tooltip] : [];
|
|
72
115
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"draw-rectangle-mode-with-tooltip.js","names":["point"],"sources":["../../../../../src/deckgl/shapes/draw-shape-layer/modes/draw-rectangle-mode-with-tooltip.ts"],"sourcesContent":["/*\n * Copyright 2026 Hypergiant Galactic Systems Inc. All rights reserved.\n * This file is licensed to you under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License. You may obtain a copy\n * of the License at https://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software distributed under\n * the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS\n * OF ANY KIND, either express or implied. See the License for the specific language\n * governing permissions and limitations under the License.\n */\n\nimport {\n DrawRectangleMode,\n type FeatureCollection,\n type ModeProps,\n type PointerMoveEvent,\n type Tooltip,\n} from '@deck.gl-community/editable-layers';\nimport { featureCollection, point } from '@turf/helpers';\nimport {\n area,\n bbox,\n bboxPolygon,\n convertArea,\n destination,\n distance,\n} from '@turf/turf';\nimport {\n DEFAULT_DISTANCE_UNITS,\n getDistanceUnitAbbreviation,\n} from '@/shared/units';\nimport { formatRectangleTooltip } from '../../shared/constants';\nimport type { Position } from 'geojson';\n\n/**\n * Extends DrawRectangleMode to display dimensions and area tooltip.\n *\n * Shows the width, height, and total area of the rectangle being drawn.\n * Hold Shift to constrain to a square.\n */\nexport class DrawRectangleModeWithTooltip extends DrawRectangleMode {\n private tooltip: Tooltip | null = null;\n private isShiftPressed = false;\n\n /**\n * Override getTwoClickPolygon to support Shift-constrained squares.\n * When Shift is held, the rectangle
|
|
1
|
+
{"version":3,"file":"draw-rectangle-mode-with-tooltip.js","names":["point"],"sources":["../../../../../src/deckgl/shapes/draw-shape-layer/modes/draw-rectangle-mode-with-tooltip.ts"],"sourcesContent":["/*\n * Copyright 2026 Hypergiant Galactic Systems Inc. All rights reserved.\n * This file is licensed to you under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License. You may obtain a copy\n * of the License at https://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software distributed under\n * the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS\n * OF ANY KIND, either express or implied. See the License for the specific language\n * governing permissions and limitations under the License.\n */\n\nimport {\n DrawRectangleMode,\n type FeatureCollection,\n type ModeProps,\n type PointerMoveEvent,\n type Tooltip,\n} from '@deck.gl-community/editable-layers';\nimport { featureCollection, point } from '@turf/helpers';\nimport {\n area,\n bbox,\n bboxPolygon,\n convertArea,\n destination,\n distance,\n} from '@turf/turf';\nimport {\n DEFAULT_DISTANCE_UNITS,\n getDistanceUnitAbbreviation,\n} from '@/shared/units';\nimport { formatRectangleTooltip } from '../../shared/constants';\nimport type { Position } from 'geojson';\n\n/**\n * Extends DrawRectangleMode to display dimensions and area tooltip.\n *\n * Shows the width, height, and total area of the rectangle being drawn.\n * The tooltip updates in real-time as the cursor moves, displaying measurements\n * in the configured distance units.\n *\n * ## Drawing Flow\n * 1. Click to set first corner\n * 2. Move cursor (tooltip shows dimensions and area)\n * 3. Click to set opposite corner and finish the rectangle\n *\n * ## Shift-to-Square Constraint\n * Hold Shift while drawing to constrain the rectangle to a square with equal sides.\n * Uses real-world distances (via Turf.js) to account for lat/lon distortion.\n *\n * @example\n * ```typescript\n * import { DrawRectangleModeWithTooltip } from '@accelint/map-toolkit/deckgl/shapes/draw-shape-layer/modes';\n *\n * // Used internally by DrawShapeLayer\n * const mode = new DrawRectangleModeWithTooltip();\n * ```\n */\nexport class DrawRectangleModeWithTooltip extends DrawRectangleMode {\n /** Current tooltip state (null when not drawing) */\n private tooltip: Tooltip | null = null;\n /** Tracks whether Shift key is currently pressed for square constraint */\n private isShiftPressed = false;\n\n /**\n * Override getTwoClickPolygon to support Shift-constrained squares.\n *\n * When Shift is held, constrains the rectangle to a square by using the larger\n * of the horizontal or vertical distances as the side length. Uses real-world\n * geographic distances (via Turf.js) to account for lat/lon distortion at different\n * latitudes.\n *\n * @param coord1 - First corner coordinates [lon, lat]\n * @param coord2 - Second corner coordinates [lon, lat]\n * @param modeConfig - Mode configuration options\n * @returns Polygon geometry for the rectangle or square\n */\n override getTwoClickPolygon(\n coord1: Position,\n coord2: Position,\n modeConfig: ModeProps<FeatureCollection>['modeConfig'],\n ) {\n let finalCoord2 = coord2;\n\n // If Shift is pressed, constrain to a square using real distances\n if (this.isShiftPressed && coord1 && coord2) {\n const lon1 = coord1[0] ?? 0;\n const lat1 = coord1[1] ?? 0;\n const lon2 = coord2[0] ?? 0;\n const lat2 = coord2[1] ?? 0;\n\n // Calculate real-world distances using turf\n // Horizontal distance (along latitude)\n const horizontalDist = distance(\n point([lon1, lat1]),\n point([lon2, lat1]),\n {\n units: 'kilometers',\n },\n );\n // Vertical distance (along longitude)\n const verticalDist = distance(point([lon1, lat1]), point([lon1, lat2]), {\n units: 'kilometers',\n });\n\n // Use the larger distance for the square side\n const maxDist = Math.max(horizontalDist, verticalDist);\n\n // Determine direction signs\n const lonSign = lon2 >= lon1 ? 1 : -1;\n const latSign = lat2 >= lat1 ? 1 : -1;\n\n // Calculate new corner using destination() for accurate geographic positioning\n // Move horizontally from coord1\n const horizontalPoint = destination(\n point([lon1, lat1]),\n maxDist,\n lonSign > 0 ? 90 : 270,\n {\n units: 'kilometers',\n },\n );\n // Move vertically from that point\n const cornerPoint = destination(\n horizontalPoint,\n maxDist,\n latSign > 0 ? 0 : 180,\n {\n units: 'kilometers',\n },\n );\n\n finalCoord2 = cornerPoint.geometry.coordinates;\n }\n\n // Call parent implementation with potentially adjusted coordinates\n return super.getTwoClickPolygon(coord1, finalCoord2, modeConfig);\n }\n\n /**\n * Handle pointer move events to update the tooltip with rectangle measurements.\n *\n * Tracks the Shift key state for square constraint and calculates the width,\n * height, and area of the rectangle being drawn. Uses Turf.js for accurate\n * geographic distance and area calculations.\n *\n * @param event - Pointer move event with cursor position and source event\n * @param props - Mode properties including distance units configuration\n */\n override handlePointerMove(\n event: PointerMoveEvent,\n props: ModeProps<FeatureCollection>,\n ) {\n // Track shift key state from the source event\n const sourceEvent = event.sourceEvent as KeyboardEvent | undefined;\n this.isShiftPressed = sourceEvent?.shiftKey ?? false;\n\n super.handlePointerMove(event, props);\n\n const clickSequence = this.getClickSequence();\n const firstClick = clickSequence[clickSequence.length - 1];\n if (!firstClick) {\n this.tooltip = null;\n return;\n }\n\n const { mapCoords } = event;\n const distanceUnits =\n props.modeConfig?.distanceUnits ?? DEFAULT_DISTANCE_UNITS;\n\n const firstClickPoint = point(firstClick);\n const currentPoint = point(mapCoords);\n\n // Calculate dimensions by finding the corner point\n const cornerPoint = point([\n firstClick[0] as number,\n mapCoords[1] as number,\n ]);\n const dimension1 = distance(firstClickPoint, cornerPoint, {\n units: distanceUnits,\n });\n const dimension2 = distance(currentPoint, cornerPoint, {\n units: distanceUnits,\n });\n\n // Calculate area properly accounting for Earth's curvature\n const points = featureCollection([firstClickPoint, currentPoint]);\n const bboxPoly = bboxPolygon(bbox(points));\n const rectArea = area(bboxPoly);\n const convertedArea = convertArea(rectArea, 'meters', distanceUnits);\n const unitAbbrev = getDistanceUnitAbbreviation(distanceUnits);\n\n this.tooltip = {\n position: mapCoords,\n text: formatRectangleTooltip(\n dimension1,\n dimension2,\n convertedArea,\n unitAbbrev,\n ),\n };\n }\n\n /**\n * Get the current tooltip array for rendering.\n *\n * @returns Array containing the tooltip if one is active, empty array otherwise\n */\n override getTooltips(): Tooltip[] {\n return this.tooltip ? [this.tooltip] : [];\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA2DA,IAAa,+BAAb,cAAkD,kBAAkB;;CAElE,AAAQ,UAA0B;;CAElC,AAAQ,iBAAiB;;;;;;;;;;;;;;CAezB,AAAS,mBACP,QACA,QACA,YACA;EACA,IAAI,cAAc;AAGlB,MAAI,KAAK,kBAAkB,UAAU,QAAQ;GAC3C,MAAM,OAAO,OAAO,MAAM;GAC1B,MAAM,OAAO,OAAO,MAAM;GAC1B,MAAM,OAAO,OAAO,MAAM;GAC1B,MAAM,OAAO,OAAO,MAAM;GAI1B,MAAM,iBAAiB,SACrBA,QAAM,CAAC,MAAM,KAAK,CAAC,EACnBA,QAAM,CAAC,MAAM,KAAK,CAAC,EACnB,EACE,OAAO,cACR,CACF;GAED,MAAM,eAAe,SAASA,QAAM,CAAC,MAAM,KAAK,CAAC,EAAEA,QAAM,CAAC,MAAM,KAAK,CAAC,EAAE,EACtE,OAAO,cACR,CAAC;GAGF,MAAM,UAAU,KAAK,IAAI,gBAAgB,aAAa;GAGtD,MAAM,UAAU,QAAQ,OAAO,IAAI;GACnC,MAAM,UAAU,QAAQ,OAAO,IAAI;AAsBnC,iBAToB,YATI,YACtBA,QAAM,CAAC,MAAM,KAAK,CAAC,EACnB,SACA,UAAU,IAAI,KAAK,KACnB,EACE,OAAO,cACR,CACF,EAIC,SACA,UAAU,IAAI,IAAI,KAClB,EACE,OAAO,cACR,CACF,CAEyB,SAAS;;AAIrC,SAAO,MAAM,mBAAmB,QAAQ,aAAa,WAAW;;;;;;;;;;;;CAalE,AAAS,kBACP,OACA,OACA;AAGA,OAAK,iBADe,MAAM,aACS,YAAY;AAE/C,QAAM,kBAAkB,OAAO,MAAM;EAErC,MAAM,gBAAgB,KAAK,kBAAkB;EAC7C,MAAM,aAAa,cAAc,cAAc,SAAS;AACxD,MAAI,CAAC,YAAY;AACf,QAAK,UAAU;AACf;;EAGF,MAAM,EAAE,cAAc;EACtB,MAAM,gBACJ,MAAM,YAAY,iBAAiB;EAErC,MAAM,kBAAkBA,QAAM,WAAW;EACzC,MAAM,eAAeA,QAAM,UAAU;EAGrC,MAAM,cAAcA,QAAM,CACxB,WAAW,IACX,UAAU,GACX,CAAC;AAeF,OAAK,UAAU;GACb,UAAU;GACV,MAAM,uBAhBW,SAAS,iBAAiB,aAAa,EACxD,OAAO,eACR,CAAC,EACiB,SAAS,cAAc,aAAa,EACrD,OAAO,eACR,CAAC,EAMoB,YADL,KADA,YAAY,KADd,kBAAkB,CAAC,iBAAiB,aAAa,CAAC,CACxB,CAAC,CACX,EACa,UAAU,cAAc,EACjD,4BAA4B,cAAc,CAS1D;GACF;;;;;;;CAQH,AAAS,cAAyB;AAChC,SAAO,KAAK,UAAU,CAAC,KAAK,QAAQ,GAAG,EAAE"}
|
|
@@ -39,20 +39,56 @@ const MODE_INSTANCES = {
|
|
|
39
39
|
/**
|
|
40
40
|
* Get the cached mode instance for a shape type.
|
|
41
41
|
*
|
|
42
|
+
* Returns the pre-instantiated drawing mode for the specified shape type.
|
|
43
|
+
* Modes are cached at module level to prevent deck.gl assertion failures
|
|
44
|
+
* that occur when creating new mode instances on each render.
|
|
45
|
+
*
|
|
42
46
|
* @param shapeType - The shape type to get the mode for
|
|
43
47
|
* @returns The cached mode instance for drawing that shape type
|
|
48
|
+
*
|
|
49
|
+
* @example
|
|
50
|
+
* ```typescript
|
|
51
|
+
* import { getModeInstance } from '@accelint/map-toolkit/deckgl/shapes/draw-shape-layer/modes';
|
|
52
|
+
* import { ShapeFeatureType } from '@accelint/map-toolkit/deckgl/shapes/shared/types';
|
|
53
|
+
*
|
|
54
|
+
* // Get the mode for drawing circles
|
|
55
|
+
* const circleMode = getModeInstance(ShapeFeatureType.Circle);
|
|
56
|
+
*
|
|
57
|
+
* // Use with EditableGeoJsonLayer
|
|
58
|
+
* const layer = new EditableGeoJsonLayer({
|
|
59
|
+
* mode: circleMode,
|
|
60
|
+
* // ... other props
|
|
61
|
+
* });
|
|
62
|
+
* ```
|
|
44
63
|
*/
|
|
45
64
|
function getModeInstance(shapeType) {
|
|
46
65
|
return MODE_INSTANCES[shapeType];
|
|
47
66
|
}
|
|
48
67
|
/**
|
|
49
|
-
* Trigger double-click finish on the active mode.
|
|
68
|
+
* Trigger double-click finish on the active drawing mode.
|
|
69
|
+
*
|
|
50
70
|
* This is a workaround for @deck.gl-community/editable-layers ~9.1 which doesn't
|
|
51
71
|
* register 'dblclick' in EVENT_TYPES. We listen for dblclick at the DOM level
|
|
52
72
|
* and call this function to finish drawing.
|
|
53
73
|
*
|
|
74
|
+
* Only LineString and Polygon modes support double-click to finish. Other shape
|
|
75
|
+
* types are completed with a single click and ignore this call.
|
|
76
|
+
*
|
|
54
77
|
* @param shapeType - The shape type currently being drawn
|
|
55
78
|
* @see https://github.com/visgl/deck.gl-community/pull/225
|
|
79
|
+
*
|
|
80
|
+
* @example
|
|
81
|
+
* ```typescript
|
|
82
|
+
* import { triggerDoubleClickFinish } from '@accelint/map-toolkit/deckgl/shapes/draw-shape-layer/modes';
|
|
83
|
+
* import { ShapeFeatureType } from '@accelint/map-toolkit/deckgl/shapes/shared/types';
|
|
84
|
+
*
|
|
85
|
+
* // Listen for double-click at the DOM level
|
|
86
|
+
* mapContainer.addEventListener('dblclick', () => {
|
|
87
|
+
* if (currentShapeType === ShapeFeatureType.Polygon) {
|
|
88
|
+
* triggerDoubleClickFinish(currentShapeType);
|
|
89
|
+
* }
|
|
90
|
+
* });
|
|
91
|
+
* ```
|
|
56
92
|
*/
|
|
57
93
|
function triggerDoubleClickFinish(shapeType) {
|
|
58
94
|
const mode = MODE_INSTANCES[shapeType];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":[],"sources":["../../../../../src/deckgl/shapes/draw-shape-layer/modes/index.ts"],"sourcesContent":["/*\n * Copyright 2026 Hypergiant Galactic Systems Inc. All rights reserved.\n * This file is licensed to you under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License. You may obtain a copy\n * of the License at https://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software distributed under\n * the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS\n * OF ANY KIND, either express or implied. See the License for the specific language\n * governing permissions and limitations under the License.\n */\n\nimport { DrawPointMode, ViewMode } from '@deck.gl-community/editable-layers';\nimport { ShapeFeatureType } from '../../shared/types';\nimport { DrawCircleModeWithTooltip } from './draw-circle-mode-with-tooltip';\nimport { DrawEllipseModeWithTooltip } from './draw-ellipse-mode-with-tooltip';\nimport { DrawLineStringModeWithTooltip } from './draw-line-string-mode-with-tooltip';\nimport { DrawPolygonModeWithTooltip } from './draw-polygon-mode-with-tooltip';\nimport { DrawRectangleModeWithTooltip } from './draw-rectangle-mode-with-tooltip';\n\nexport { DrawCircleModeWithTooltip } from './draw-circle-mode-with-tooltip';\nexport { DrawEllipseModeWithTooltip } from './draw-ellipse-mode-with-tooltip';\nexport { DrawLineStringModeWithTooltip } from './draw-line-string-mode-with-tooltip';\nexport { DrawPolygonModeWithTooltip } from './draw-polygon-mode-with-tooltip';\nexport { DrawRectangleModeWithTooltip } from './draw-rectangle-mode-with-tooltip';\n\n/**\n * Cached mode instances.\n *\n * CRITICAL: Mode instances must be cached at module level to prevent\n * deck.gl assertion failures. Creating new mode instances on each render\n * causes the EditableGeoJsonLayer to fail with assertion errors.\n */\nconst MODE_INSTANCES = {\n [ShapeFeatureType.Point]: new DrawPointMode(),\n [ShapeFeatureType.LineString]: new DrawLineStringModeWithTooltip(),\n [ShapeFeatureType.Polygon]: new DrawPolygonModeWithTooltip(),\n [ShapeFeatureType.Rectangle]: new DrawRectangleModeWithTooltip(),\n [ShapeFeatureType.Circle]: new DrawCircleModeWithTooltip(),\n [ShapeFeatureType.Ellipse]: new DrawEllipseModeWithTooltip(),\n view: new ViewMode(),\n};\n\n/**\n * Get the cached mode instance for a shape type.\n *\n * @param shapeType - The shape type to get the mode for\n * @returns The cached mode instance for drawing that shape type\n */\nexport function getModeInstance(\n shapeType: ShapeFeatureType,\n): (typeof MODE_INSTANCES)[ShapeFeatureType] {\n return MODE_INSTANCES[shapeType];\n}\n\n/**\n * Get the view mode instance (for when not drawing).\n *\n * @returns The cached ViewMode instance\n */\nexport function getViewModeInstance(): ViewMode {\n return MODE_INSTANCES.view;\n}\n\n/**\n * Trigger double-click finish on the active mode.\n * This is a workaround for @deck.gl-community/editable-layers ~9.1 which doesn't\n * register 'dblclick' in EVENT_TYPES. We listen for dblclick at the DOM level\n * and call this function to finish drawing.\n *\n * @param shapeType - The shape type currently being drawn\n * @see https://github.com/visgl/deck.gl-community/pull/225\n */\nexport function triggerDoubleClickFinish(shapeType: ShapeFeatureType): void {\n const mode = MODE_INSTANCES[shapeType];\n\n // Only Polygon and LineString modes support double-click to finish\n if (\n mode instanceof DrawPolygonModeWithTooltip ||\n mode instanceof DrawLineStringModeWithTooltip\n ) {\n mode.handleDoubleClick();\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAiCA,MAAM,iBAAiB;EACpB,iBAAiB,QAAQ,IAAI,eAAe;EAC5C,iBAAiB,aAAa,IAAI,+BAA+B;EACjE,iBAAiB,UAAU,IAAI,4BAA4B;EAC3D,iBAAiB,YAAY,IAAI,8BAA8B;EAC/D,iBAAiB,SAAS,IAAI,2BAA2B;EACzD,iBAAiB,UAAU,IAAI,4BAA4B;CAC5D,MAAM,IAAI,UAAU;CACrB
|
|
1
|
+
{"version":3,"file":"index.js","names":[],"sources":["../../../../../src/deckgl/shapes/draw-shape-layer/modes/index.ts"],"sourcesContent":["/*\n * Copyright 2026 Hypergiant Galactic Systems Inc. All rights reserved.\n * This file is licensed to you under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License. You may obtain a copy\n * of the License at https://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software distributed under\n * the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS\n * OF ANY KIND, either express or implied. See the License for the specific language\n * governing permissions and limitations under the License.\n */\n\nimport { DrawPointMode, ViewMode } from '@deck.gl-community/editable-layers';\nimport { ShapeFeatureType } from '../../shared/types';\nimport { DrawCircleModeWithTooltip } from './draw-circle-mode-with-tooltip';\nimport { DrawEllipseModeWithTooltip } from './draw-ellipse-mode-with-tooltip';\nimport { DrawLineStringModeWithTooltip } from './draw-line-string-mode-with-tooltip';\nimport { DrawPolygonModeWithTooltip } from './draw-polygon-mode-with-tooltip';\nimport { DrawRectangleModeWithTooltip } from './draw-rectangle-mode-with-tooltip';\n\nexport { DrawCircleModeWithTooltip } from './draw-circle-mode-with-tooltip';\nexport { DrawEllipseModeWithTooltip } from './draw-ellipse-mode-with-tooltip';\nexport { DrawLineStringModeWithTooltip } from './draw-line-string-mode-with-tooltip';\nexport { DrawPolygonModeWithTooltip } from './draw-polygon-mode-with-tooltip';\nexport { DrawRectangleModeWithTooltip } from './draw-rectangle-mode-with-tooltip';\n\n/**\n * Cached mode instances.\n *\n * CRITICAL: Mode instances must be cached at module level to prevent\n * deck.gl assertion failures. Creating new mode instances on each render\n * causes the EditableGeoJsonLayer to fail with assertion errors.\n */\nconst MODE_INSTANCES = {\n [ShapeFeatureType.Point]: new DrawPointMode(),\n [ShapeFeatureType.LineString]: new DrawLineStringModeWithTooltip(),\n [ShapeFeatureType.Polygon]: new DrawPolygonModeWithTooltip(),\n [ShapeFeatureType.Rectangle]: new DrawRectangleModeWithTooltip(),\n [ShapeFeatureType.Circle]: new DrawCircleModeWithTooltip(),\n [ShapeFeatureType.Ellipse]: new DrawEllipseModeWithTooltip(),\n view: new ViewMode(),\n};\n\n/**\n * Get the cached mode instance for a shape type.\n *\n * Returns the pre-instantiated drawing mode for the specified shape type.\n * Modes are cached at module level to prevent deck.gl assertion failures\n * that occur when creating new mode instances on each render.\n *\n * @param shapeType - The shape type to get the mode for\n * @returns The cached mode instance for drawing that shape type\n *\n * @example\n * ```typescript\n * import { getModeInstance } from '@accelint/map-toolkit/deckgl/shapes/draw-shape-layer/modes';\n * import { ShapeFeatureType } from '@accelint/map-toolkit/deckgl/shapes/shared/types';\n *\n * // Get the mode for drawing circles\n * const circleMode = getModeInstance(ShapeFeatureType.Circle);\n *\n * // Use with EditableGeoJsonLayer\n * const layer = new EditableGeoJsonLayer({\n * mode: circleMode,\n * // ... other props\n * });\n * ```\n */\nexport function getModeInstance(\n shapeType: ShapeFeatureType,\n): (typeof MODE_INSTANCES)[ShapeFeatureType] {\n return MODE_INSTANCES[shapeType];\n}\n\n/**\n * Get the view mode instance (for when not drawing).\n *\n * Returns the pre-instantiated ViewMode which is the default mode when\n * no drawing operation is active. This mode allows viewing and interacting\n * with the map without drawing new shapes.\n *\n * @returns The cached ViewMode instance\n *\n * @example\n * ```typescript\n * import { getViewModeInstance } from '@accelint/map-toolkit/deckgl/shapes/draw-shape-layer/modes';\n *\n * // Get the view mode (default when not drawing)\n * const viewMode = getViewModeInstance();\n *\n * // Use with EditableGeoJsonLayer\n * const layer = new EditableGeoJsonLayer({\n * mode: viewMode,\n * // ... other props\n * });\n * ```\n */\nexport function getViewModeInstance(): ViewMode {\n return MODE_INSTANCES.view;\n}\n\n/**\n * Trigger double-click finish on the active drawing mode.\n *\n * This is a workaround for @deck.gl-community/editable-layers ~9.1 which doesn't\n * register 'dblclick' in EVENT_TYPES. We listen for dblclick at the DOM level\n * and call this function to finish drawing.\n *\n * Only LineString and Polygon modes support double-click to finish. Other shape\n * types are completed with a single click and ignore this call.\n *\n * @param shapeType - The shape type currently being drawn\n * @see https://github.com/visgl/deck.gl-community/pull/225\n *\n * @example\n * ```typescript\n * import { triggerDoubleClickFinish } from '@accelint/map-toolkit/deckgl/shapes/draw-shape-layer/modes';\n * import { ShapeFeatureType } from '@accelint/map-toolkit/deckgl/shapes/shared/types';\n *\n * // Listen for double-click at the DOM level\n * mapContainer.addEventListener('dblclick', () => {\n * if (currentShapeType === ShapeFeatureType.Polygon) {\n * triggerDoubleClickFinish(currentShapeType);\n * }\n * });\n * ```\n */\nexport function triggerDoubleClickFinish(shapeType: ShapeFeatureType): void {\n const mode = MODE_INSTANCES[shapeType];\n\n // Only Polygon and LineString modes support double-click to finish\n if (\n mode instanceof DrawPolygonModeWithTooltip ||\n mode instanceof DrawLineStringModeWithTooltip\n ) {\n mode.handleDoubleClick();\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAiCA,MAAM,iBAAiB;EACpB,iBAAiB,QAAQ,IAAI,eAAe;EAC5C,iBAAiB,aAAa,IAAI,+BAA+B;EACjE,iBAAiB,UAAU,IAAI,4BAA4B;EAC3D,iBAAiB,YAAY,IAAI,8BAA8B;EAC/D,iBAAiB,SAAS,IAAI,2BAA2B;EACzD,iBAAiB,UAAU,IAAI,4BAA4B;CAC5D,MAAM,IAAI,UAAU;CACrB;;;;;;;;;;;;;;;;;;;;;;;;;;AA2BD,SAAgB,gBACd,WAC2C;AAC3C,QAAO,eAAe;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAwDxB,SAAgB,yBAAyB,WAAmC;CAC1E,MAAM,OAAO,eAAe;AAG5B,KACE,gBAAgB,8BAChB,gBAAgB,8BAEhB,MAAK,mBAAmB"}
|
|
@@ -158,13 +158,61 @@ const drawStore = createMapStore({
|
|
|
158
158
|
}
|
|
159
159
|
});
|
|
160
160
|
/**
|
|
161
|
-
* Complete drawing with a feature
|
|
161
|
+
* Complete the drawing operation with a GeoJSON feature.
|
|
162
|
+
*
|
|
163
|
+
* Called internally by the DrawShapeLayer component when the user finishes
|
|
164
|
+
* drawing a shape. Converts the raw EditableGeoJsonLayer feature to a Shape
|
|
165
|
+
* object, resets drawing state, releases mode/cursor, and emits the drawn event.
|
|
166
|
+
*
|
|
167
|
+
* ## Internal API
|
|
168
|
+
* This function is exported for use by the DrawShapeLayer component and should
|
|
169
|
+
* not be called directly from application code. Use the `draw` action from
|
|
170
|
+
* `useDrawShape` or `useDrawingState` instead.
|
|
171
|
+
*
|
|
172
|
+
* @param mapId - Unique identifier for the map instance
|
|
173
|
+
* @param feature - The completed GeoJSON feature from EditableGeoJsonLayer
|
|
174
|
+
* @returns The newly created Shape object
|
|
175
|
+
* @throws Error if not currently drawing
|
|
176
|
+
*
|
|
177
|
+
* @example
|
|
178
|
+
* ```typescript
|
|
179
|
+
* // Internal usage in DrawShapeLayer
|
|
180
|
+
* const handleEdit = ({ updatedData, editType }: EditAction) => {
|
|
181
|
+
* if (editType === 'addFeature') {
|
|
182
|
+
* const feature = updatedData.features[updatedData.features.length - 1];
|
|
183
|
+
* if (feature) {
|
|
184
|
+
* completeDrawingFromLayer(mapId, feature);
|
|
185
|
+
* }
|
|
186
|
+
* }
|
|
187
|
+
* };
|
|
188
|
+
* ```
|
|
162
189
|
*/
|
|
163
190
|
function completeDrawingFromLayer(mapId, feature) {
|
|
164
191
|
return completeDrawingInternal(mapId, drawStore.get(mapId), feature, () => {}, (updates) => drawStore.set(mapId, updates));
|
|
165
192
|
}
|
|
166
193
|
/**
|
|
167
|
-
* Cancel drawing
|
|
194
|
+
* Cancel the current drawing operation from the layer.
|
|
195
|
+
*
|
|
196
|
+
* Called internally by the DrawShapeLayer component when the user presses ESC
|
|
197
|
+
* or the drawing is otherwise canceled. Resets drawing state, releases mode/cursor,
|
|
198
|
+
* and emits the canceled event.
|
|
199
|
+
*
|
|
200
|
+
* ## Internal API
|
|
201
|
+
* This function is exported for use by the DrawShapeLayer component and should
|
|
202
|
+
* not be called directly from application code. Use the `cancel` action from
|
|
203
|
+
* `useDrawShape` or `useDrawingState` instead.
|
|
204
|
+
*
|
|
205
|
+
* @param mapId - Unique identifier for the map instance
|
|
206
|
+
*
|
|
207
|
+
* @example
|
|
208
|
+
* ```typescript
|
|
209
|
+
* // Internal usage in DrawShapeLayer
|
|
210
|
+
* const handleEdit = ({ editType }: EditAction) => {
|
|
211
|
+
* if (editType === 'cancelFeature') {
|
|
212
|
+
* cancelDrawingFromLayer(mapId);
|
|
213
|
+
* }
|
|
214
|
+
* };
|
|
215
|
+
* ```
|
|
168
216
|
*/
|
|
169
217
|
function cancelDrawingFromLayer(mapId) {
|
|
170
218
|
drawStore.actions(mapId).cancel();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"store.js","names":["DEFAULT_DRAWING_STATE: DrawingState"],"sources":["../../../../src/deckgl/shapes/draw-shape-layer/store.ts"],"sourcesContent":["/*\n * Copyright 2026 Hypergiant Galactic Systems Inc. All rights reserved.\n * This file is licensed to you under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License. You may obtain a copy\n * of the License at https://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software distributed under\n * the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS\n * OF ANY KIND, either express or implied. See the License for the specific language\n * governing permissions and limitations under the License.\n */\n\n'use client';\n\n/**\n * Draw Shape Store\n *\n * Manages drawing state for shape creation.\n *\n * @example\n * ```tsx\n * import { drawStore } from '@accelint/map-toolkit/deckgl/shapes';\n *\n * function DrawControls({ mapId }) {\n * const { state, draw, cancel } = drawStore.use(mapId);\n *\n * return (\n * <div>\n * <p>Drawing: {state.activeShapeType ?? 'none'}</p>\n * <button onClick={() => draw('Polygon')}>Draw Polygon</button>\n * <button onClick={cancel}>Cancel</button>\n * </div>\n * );\n * }\n * ```\n */\n\nimport { Broadcast } from '@accelint/bus';\nimport { MapModeEvents } from '@/map-mode/events';\nimport { createMapStore } from '@/shared/create-map-store';\nimport {\n releaseModeAndCursor,\n requestModeAndCursor,\n} from '../shared/utils/mode-utils';\nimport {\n DRAW_CURSOR_MAP,\n DRAW_SHAPE_LAYER_ID,\n DRAW_SHAPE_MODE,\n} from './constants';\nimport { DrawShapeEvents } from './events';\nimport { convertFeatureToShape } from './utils/feature-conversion';\nimport type { UniqueId } from '@accelint/core';\nimport type { Feature } from 'geojson';\nimport type { MapModeEventType } from '@/map-mode/types';\nimport type { Shape, ShapeFeatureType } from '../shared/types';\nimport type { DrawShapeEvent, ShapeDrawnEvent } from './events';\nimport type { DrawFunction, DrawingState, DrawShapeOptions } from './types';\n\n/**\n * Typed event bus instances\n */\nconst drawShapeBus = Broadcast.getInstance<DrawShapeEvent>();\nconst mapModeBus = Broadcast.getInstance<MapModeEventType>();\n\n/**\n * Default drawing state\n */\nconst DEFAULT_DRAWING_STATE: DrawingState = {\n activeShapeType: null,\n tentativeFeature: null,\n styleDefaults: null,\n circleDefaults: null,\n};\n\n/**\n * Actions for draw shape store\n */\ntype DrawShapeActions = {\n /** Start drawing a shape of the specified type */\n draw: DrawFunction;\n /** Cancel the current drawing operation */\n cancel: () => void;\n};\n\n/**\n * Start drawing a shape\n */\nfunction startDrawing(\n mapId: UniqueId,\n state: DrawingState,\n shapeType: ShapeFeatureType,\n options: DrawShapeOptions | undefined,\n notify: () => void,\n setState: (updates: Partial<DrawingState>) => void,\n): void {\n // Already drawing - cancel first\n if (state.activeShapeType) {\n cancelDrawingInternal(mapId, state, notify, setState);\n }\n\n // Update state with new object reference\n setState({\n activeShapeType: shapeType,\n tentativeFeature: null,\n styleDefaults: options?.styleDefaults ?? null,\n circleDefaults: options?.circleDefaults ?? null,\n });\n\n // Request map mode and cursor using shared utilities\n const cursor = DRAW_CURSOR_MAP[shapeType];\n requestModeAndCursor(mapId, DRAW_SHAPE_MODE, cursor, DRAW_SHAPE_LAYER_ID);\n\n // Emit drawing started event\n drawShapeBus.emit(DrawShapeEvents.drawing, {\n shapeType,\n mapId,\n });\n\n notify();\n}\n\n/**\n * Complete drawing and create a shape\n */\nfunction completeDrawingInternal(\n mapId: UniqueId,\n state: DrawingState,\n feature: Feature,\n notify: () => void,\n setState: (updates: Partial<DrawingState>) => void,\n): Shape {\n if (!state.activeShapeType) {\n throw new Error('Cannot complete drawing - not currently drawing');\n }\n\n const shapeType = state.activeShapeType;\n const styleDefaults = state.styleDefaults;\n\n // Convert feature to Shape\n const shape = convertFeatureToShape(feature, shapeType, styleDefaults);\n\n // Reset state with new object reference\n setState({\n activeShapeType: null,\n tentativeFeature: null,\n styleDefaults: null,\n circleDefaults: null,\n });\n\n // Release mode and cursor using shared utilities\n releaseModeAndCursor(mapId, DRAW_SHAPE_LAYER_ID);\n\n // Emit shape drawn event\n drawShapeBus.emit(DrawShapeEvents.drawn, {\n shape,\n mapId,\n } as unknown as ShapeDrawnEvent['payload']);\n\n notify();\n\n return shape;\n}\n\n/**\n * Cancel the current drawing operation\n */\nfunction cancelDrawingInternal(\n mapId: UniqueId,\n state: DrawingState,\n notify: () => void,\n setState: (updates: Partial<DrawingState>) => void,\n): void {\n if (!state.activeShapeType) {\n return; // Nothing to cancel\n }\n\n const shapeType = state.activeShapeType;\n\n // Reset state with new object reference\n setState({\n activeShapeType: null,\n tentativeFeature: null,\n styleDefaults: null,\n circleDefaults: null,\n });\n\n // Release mode and cursor using shared utilities\n releaseModeAndCursor(mapId, DRAW_SHAPE_LAYER_ID);\n\n // Emit canceled event\n drawShapeBus.emit(DrawShapeEvents.canceled, {\n shapeType,\n mapId,\n });\n\n notify();\n}\n\n/**\n * Draw shape store\n */\nexport const drawStore = createMapStore<DrawingState, DrawShapeActions>({\n defaultState: { ...DEFAULT_DRAWING_STATE },\n\n actions: (mapId, { get, set, notify }) => ({\n draw: (shapeType: ShapeFeatureType, options?: DrawShapeOptions) => {\n startDrawing(mapId, get(), shapeType, options, notify, set);\n },\n\n cancel: () => {\n cancelDrawingInternal(mapId, get(), notify, set);\n },\n }),\n\n bus: (mapId, { get }) => {\n // Listen for mode authorization requests - REJECT when drawing (protected mode)\n const unsubAuth = mapModeBus.on(\n MapModeEvents.changeAuthorization,\n (event) => {\n const { authId, id } = event.payload;\n\n // Filter: only handle if targeted at this map\n if (id !== mapId) {\n return;\n }\n\n // If we're actively drawing, reject the mode change request\n if (get().activeShapeType) {\n mapModeBus.emit(MapModeEvents.changeDecision, {\n authId,\n approved: false,\n owner: DRAW_SHAPE_LAYER_ID,\n reason: 'Drawing in progress - cancel drawing first',\n id: mapId,\n });\n }\n },\n );\n\n return () => {\n unsubAuth();\n };\n },\n\n onCleanup: (mapId, state) => {\n // Cancel any active drawing before cleanup\n if (state.activeShapeType) {\n // Release mode and cursor using shared utilities\n releaseModeAndCursor(mapId, DRAW_SHAPE_LAYER_ID);\n\n // Emit canceled event\n drawShapeBus.emit(DrawShapeEvents.canceled, {\n shapeType: state.activeShapeType,\n mapId,\n });\n }\n },\n});\n\n// =============================================================================\n// Convenience exports\n// =============================================================================\n\n/**\n * Get the current drawing state for a mapId\n * Returns null if no store instance exists\n */\nexport function getDrawingState(mapId: UniqueId): DrawingState | null {\n if (!drawStore.exists(mapId)) {\n return null;\n }\n return drawStore.get(mapId);\n}\n\n/**\n * Hook for drawing state\n */\nexport function useDrawingState(\n mapId: UniqueId,\n): { state: DrawingState } & DrawShapeActions {\n return drawStore.use(mapId);\n}\n\n/**\n * Manually clear drawing state for a specific mapId.\n */\nexport function clearDrawingState(mapId: UniqueId): void {\n drawStore.clear(mapId);\n}\n\n/**\n * Complete drawing with a feature (called by the layer component)\n */\nexport function completeDrawingFromLayer(\n mapId: UniqueId,\n feature: Feature,\n): Shape {\n const state = drawStore.get(mapId);\n return completeDrawingInternal(\n mapId,\n state,\n feature,\n () => {\n /* notify handled by set */\n },\n (updates) => drawStore.set(mapId, updates),\n );\n}\n\n/**\n * Cancel drawing (called by the layer component)\n */\nexport function cancelDrawingFromLayer(mapId: UniqueId): void {\n drawStore.actions(mapId).cancel();\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA6DA,MAAM,eAAe,UAAU,aAA6B;AAC5D,MAAM,aAAa,UAAU,aAA+B;;;;AAK5D,MAAMA,wBAAsC;CAC1C,iBAAiB;CACjB,kBAAkB;CAClB,eAAe;CACf,gBAAgB;CACjB;;;;AAeD,SAAS,aACP,OACA,OACA,WACA,SACA,QACA,UACM;AAEN,KAAI,MAAM,gBACR,uBAAsB,OAAO,OAAO,QAAQ,SAAS;AAIvD,UAAS;EACP,iBAAiB;EACjB,kBAAkB;EAClB,eAAe,SAAS,iBAAiB;EACzC,gBAAgB,SAAS,kBAAkB;EAC5C,CAAC;CAGF,MAAM,SAAS,gBAAgB;AAC/B,sBAAqB,OAAO,iBAAiB,QAAQ,oBAAoB;AAGzE,cAAa,KAAK,gBAAgB,SAAS;EACzC;EACA;EACD,CAAC;AAEF,SAAQ;;;;;AAMV,SAAS,wBACP,OACA,OACA,SACA,QACA,UACO;AACP,KAAI,CAAC,MAAM,gBACT,OAAM,IAAI,MAAM,kDAAkD;CAGpE,MAAM,YAAY,MAAM;CACxB,MAAM,gBAAgB,MAAM;CAG5B,MAAM,QAAQ,sBAAsB,SAAS,WAAW,cAAc;AAGtE,UAAS;EACP,iBAAiB;EACjB,kBAAkB;EAClB,eAAe;EACf,gBAAgB;EACjB,CAAC;AAGF,sBAAqB,OAAO,oBAAoB;AAGhD,cAAa,KAAK,gBAAgB,OAAO;EACvC;EACA;EACD,CAA0C;AAE3C,SAAQ;AAER,QAAO;;;;;AAMT,SAAS,sBACP,OACA,OACA,QACA,UACM;AACN,KAAI,CAAC,MAAM,gBACT;CAGF,MAAM,YAAY,MAAM;AAGxB,UAAS;EACP,iBAAiB;EACjB,kBAAkB;EAClB,eAAe;EACf,gBAAgB;EACjB,CAAC;AAGF,sBAAqB,OAAO,oBAAoB;AAGhD,cAAa,KAAK,gBAAgB,UAAU;EAC1C;EACA;EACD,CAAC;AAEF,SAAQ;;;;;AAMV,MAAa,YAAY,eAA+C;CACtE,cAAc,EAAE,GAAG,uBAAuB;CAE1C,UAAU,OAAO,EAAE,KAAK,KAAK,cAAc;EACzC,OAAO,WAA6B,YAA+B;AACjE,gBAAa,OAAO,KAAK,EAAE,WAAW,SAAS,QAAQ,IAAI;;EAG7D,cAAc;AACZ,yBAAsB,OAAO,KAAK,EAAE,QAAQ,IAAI;;EAEnD;CAED,MAAM,OAAO,EAAE,UAAU;EAEvB,MAAM,YAAY,WAAW,GAC3B,cAAc,sBACb,UAAU;GACT,MAAM,EAAE,QAAQ,OAAO,MAAM;AAG7B,OAAI,OAAO,MACT;AAIF,OAAI,KAAK,CAAC,gBACR,YAAW,KAAK,cAAc,gBAAgB;IAC5C;IACA,UAAU;IACV,OAAO;IACP,QAAQ;IACR,IAAI;IACL,CAAC;IAGP;AAED,eAAa;AACX,cAAW;;;CAIf,YAAY,OAAO,UAAU;AAE3B,MAAI,MAAM,iBAAiB;AAEzB,wBAAqB,OAAO,oBAAoB;AAGhD,gBAAa,KAAK,gBAAgB,UAAU;IAC1C,WAAW,MAAM;IACjB;IACD,CAAC;;;CAGP,CAAC;;;;AAoCF,SAAgB,yBACd,OACA,SACO;AAEP,QAAO,wBACL,OAFY,UAAU,IAAI,MAAM,EAIhC,eACM,KAGL,YAAY,UAAU,IAAI,OAAO,QAAQ,CAC3C;;;;;AAMH,SAAgB,uBAAuB,OAAuB;AAC5D,WAAU,QAAQ,MAAM,CAAC,QAAQ"}
|
|
1
|
+
{"version":3,"file":"store.js","names":["DEFAULT_DRAWING_STATE: DrawingState"],"sources":["../../../../src/deckgl/shapes/draw-shape-layer/store.ts"],"sourcesContent":["/*\n * Copyright 2026 Hypergiant Galactic Systems Inc. All rights reserved.\n * This file is licensed to you under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License. You may obtain a copy\n * of the License at https://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software distributed under\n * the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS\n * OF ANY KIND, either express or implied. See the License for the specific language\n * governing permissions and limitations under the License.\n */\n\n'use client';\n\n/**\n * Draw Shape Store\n *\n * Manages drawing state for shape creation.\n *\n * @example\n * ```tsx\n * import { drawStore } from '@accelint/map-toolkit/deckgl/shapes';\n *\n * function DrawControls({ mapId }) {\n * const { state, draw, cancel } = drawStore.use(mapId);\n *\n * return (\n * <div>\n * <p>Drawing: {state.activeShapeType ?? 'none'}</p>\n * <button onClick={() => draw('Polygon')}>Draw Polygon</button>\n * <button onClick={cancel}>Cancel</button>\n * </div>\n * );\n * }\n * ```\n */\n\nimport { Broadcast } from '@accelint/bus';\nimport { MapModeEvents } from '@/map-mode/events';\nimport { createMapStore } from '@/shared/create-map-store';\nimport {\n releaseModeAndCursor,\n requestModeAndCursor,\n} from '../shared/utils/mode-utils';\nimport {\n DRAW_CURSOR_MAP,\n DRAW_SHAPE_LAYER_ID,\n DRAW_SHAPE_MODE,\n} from './constants';\nimport { DrawShapeEvents } from './events';\nimport { convertFeatureToShape } from './utils/feature-conversion';\nimport type { UniqueId } from '@accelint/core';\nimport type { Feature } from 'geojson';\nimport type { MapModeEventType } from '@/map-mode/types';\nimport type { Shape, ShapeFeatureType } from '../shared/types';\nimport type { DrawShapeEvent, ShapeDrawnEvent } from './events';\nimport type { DrawFunction, DrawingState, DrawShapeOptions } from './types';\n\n/**\n * Typed event bus instances\n */\nconst drawShapeBus = Broadcast.getInstance<DrawShapeEvent>();\nconst mapModeBus = Broadcast.getInstance<MapModeEventType>();\n\n/**\n * Default drawing state\n */\nconst DEFAULT_DRAWING_STATE: DrawingState = {\n activeShapeType: null,\n tentativeFeature: null,\n styleDefaults: null,\n circleDefaults: null,\n};\n\n/**\n * Actions for draw shape store\n */\ntype DrawShapeActions = {\n /** Start drawing a shape of the specified type */\n draw: DrawFunction;\n /** Cancel the current drawing operation */\n cancel: () => void;\n};\n\n/**\n * Start drawing a shape\n */\nfunction startDrawing(\n mapId: UniqueId,\n state: DrawingState,\n shapeType: ShapeFeatureType,\n options: DrawShapeOptions | undefined,\n notify: () => void,\n setState: (updates: Partial<DrawingState>) => void,\n): void {\n // Already drawing - cancel first\n if (state.activeShapeType) {\n cancelDrawingInternal(mapId, state, notify, setState);\n }\n\n // Update state with new object reference\n setState({\n activeShapeType: shapeType,\n tentativeFeature: null,\n styleDefaults: options?.styleDefaults ?? null,\n circleDefaults: options?.circleDefaults ?? null,\n });\n\n // Request map mode and cursor using shared utilities\n const cursor = DRAW_CURSOR_MAP[shapeType];\n requestModeAndCursor(mapId, DRAW_SHAPE_MODE, cursor, DRAW_SHAPE_LAYER_ID);\n\n // Emit drawing started event\n drawShapeBus.emit(DrawShapeEvents.drawing, {\n shapeType,\n mapId,\n });\n\n notify();\n}\n\n/**\n * Complete drawing and create a shape\n */\nfunction completeDrawingInternal(\n mapId: UniqueId,\n state: DrawingState,\n feature: Feature,\n notify: () => void,\n setState: (updates: Partial<DrawingState>) => void,\n): Shape {\n if (!state.activeShapeType) {\n throw new Error('Cannot complete drawing - not currently drawing');\n }\n\n const shapeType = state.activeShapeType;\n const styleDefaults = state.styleDefaults;\n\n // Convert feature to Shape\n const shape = convertFeatureToShape(feature, shapeType, styleDefaults);\n\n // Reset state with new object reference\n setState({\n activeShapeType: null,\n tentativeFeature: null,\n styleDefaults: null,\n circleDefaults: null,\n });\n\n // Release mode and cursor using shared utilities\n releaseModeAndCursor(mapId, DRAW_SHAPE_LAYER_ID);\n\n // Emit shape drawn event\n drawShapeBus.emit(DrawShapeEvents.drawn, {\n shape,\n mapId,\n } as unknown as ShapeDrawnEvent['payload']);\n\n notify();\n\n return shape;\n}\n\n/**\n * Cancel the current drawing operation\n */\nfunction cancelDrawingInternal(\n mapId: UniqueId,\n state: DrawingState,\n notify: () => void,\n setState: (updates: Partial<DrawingState>) => void,\n): void {\n if (!state.activeShapeType) {\n return; // Nothing to cancel\n }\n\n const shapeType = state.activeShapeType;\n\n // Reset state with new object reference\n setState({\n activeShapeType: null,\n tentativeFeature: null,\n styleDefaults: null,\n circleDefaults: null,\n });\n\n // Release mode and cursor using shared utilities\n releaseModeAndCursor(mapId, DRAW_SHAPE_LAYER_ID);\n\n // Emit canceled event\n drawShapeBus.emit(DrawShapeEvents.canceled, {\n shapeType,\n mapId,\n });\n\n notify();\n}\n\n/**\n * Draw shape store\n */\nexport const drawStore = createMapStore<DrawingState, DrawShapeActions>({\n defaultState: { ...DEFAULT_DRAWING_STATE },\n\n actions: (mapId, { get, set, notify }) => ({\n draw: (shapeType: ShapeFeatureType, options?: DrawShapeOptions) => {\n startDrawing(mapId, get(), shapeType, options, notify, set);\n },\n\n cancel: () => {\n cancelDrawingInternal(mapId, get(), notify, set);\n },\n }),\n\n bus: (mapId, { get }) => {\n // Listen for mode authorization requests - REJECT when drawing (protected mode)\n const unsubAuth = mapModeBus.on(\n MapModeEvents.changeAuthorization,\n (event) => {\n const { authId, id } = event.payload;\n\n // Filter: only handle if targeted at this map\n if (id !== mapId) {\n return;\n }\n\n // If we're actively drawing, reject the mode change request\n if (get().activeShapeType) {\n mapModeBus.emit(MapModeEvents.changeDecision, {\n authId,\n approved: false,\n owner: DRAW_SHAPE_LAYER_ID,\n reason: 'Drawing in progress - cancel drawing first',\n id: mapId,\n });\n }\n },\n );\n\n return () => {\n unsubAuth();\n };\n },\n\n onCleanup: (mapId, state) => {\n // Cancel any active drawing before cleanup\n if (state.activeShapeType) {\n // Release mode and cursor using shared utilities\n releaseModeAndCursor(mapId, DRAW_SHAPE_LAYER_ID);\n\n // Emit canceled event\n drawShapeBus.emit(DrawShapeEvents.canceled, {\n shapeType: state.activeShapeType,\n mapId,\n });\n }\n },\n});\n\n// =============================================================================\n// Convenience exports\n// =============================================================================\n\n/**\n * Get the current drawing state for a map instance.\n *\n * Returns the drawing state (active shape type, style defaults, etc.) for the\n * specified map ID. Returns null if no drawing store instance exists for that map.\n *\n * ## Use Cases\n * - Check if a map is currently in drawing mode\n * - Access drawing state outside of React components\n * - Inspect state for debugging purposes\n *\n * @param mapId - Unique identifier for the map instance\n * @returns The drawing state, or null if no store instance exists\n *\n * @example\n * ```typescript\n * import { getDrawingState } from '@accelint/map-toolkit/deckgl/shapes';\n *\n * const state = getDrawingState('map-1');\n * if (state?.activeShapeType) {\n * console.log(`Currently drawing: ${state.activeShapeType}`);\n * }\n * ```\n */\nexport function getDrawingState(mapId: UniqueId): DrawingState | null {\n if (!drawStore.exists(mapId)) {\n return null;\n }\n return drawStore.get(mapId);\n}\n\n/**\n * React hook for accessing drawing state and actions.\n *\n * Provides access to the drawing store for a specific map instance, including\n * the current state and draw/cancel actions. Uses `useSyncExternalStore` for\n * concurrent-safe React subscriptions.\n *\n * ## Comparison with useDrawShape\n * - `useDrawingState`: Low-level store access without event callbacks\n * - `useDrawShape`: High-level API with onCreate/onCancel callbacks\n *\n * Use `useDrawingState` when you need direct store access without event handling.\n * Use `useDrawShape` (recommended) for most drawing interactions.\n *\n * @param mapId - Unique identifier for the map instance\n * @returns Object containing drawing state and actions (draw, cancel)\n *\n * @example\n * ```tsx\n * import { useDrawingState } from '@accelint/map-toolkit/deckgl/shapes';\n * import { ShapeFeatureType } from '@accelint/map-toolkit/deckgl/shapes/shared/types';\n *\n * function DrawingStatus({ mapId }: { mapId: UniqueId }) {\n * const { state, draw, cancel } = useDrawingState(mapId);\n *\n * return (\n * <div>\n * <p>Status: {state.activeShapeType ?? 'Not drawing'}</p>\n * <button onClick={() => draw(ShapeFeatureType.Polygon)}>\n * Start Drawing\n * </button>\n * {state.activeShapeType && (\n * <button onClick={cancel}>Cancel</button>\n * )}\n * </div>\n * );\n * }\n * ```\n */\nexport function useDrawingState(\n mapId: UniqueId,\n): { state: DrawingState } & DrawShapeActions {\n return drawStore.use(mapId);\n}\n\n/**\n * Manually clear the drawing state for a specific map instance.\n *\n * Removes the drawing store instance for the given map ID, canceling any\n * active drawing operation and releasing mode/cursor ownership. This is\n * typically called automatically during cleanup, but can be used manually\n * when needed.\n *\n * ## When to Use\n * - Cleanup after programmatically managing drawing state\n * - Force-reset drawing state in error conditions\n * - Testing and debugging\n *\n * ## Side Effects\n * - Cancels active drawing (if any)\n * - Releases map mode and cursor\n * - Emits 'shapes:draw-canceled' event\n * - Removes store instance from memory\n *\n * @param mapId - Unique identifier for the map instance\n *\n * @example\n * ```typescript\n * import { clearDrawingState } from '@accelint/map-toolkit/deckgl/shapes';\n *\n * // Clear drawing state when unmounting a map\n * function cleanup(mapId: UniqueId) {\n * clearDrawingState(mapId);\n * }\n * ```\n */\nexport function clearDrawingState(mapId: UniqueId): void {\n drawStore.clear(mapId);\n}\n\n/**\n * Complete the drawing operation with a GeoJSON feature.\n *\n * Called internally by the DrawShapeLayer component when the user finishes\n * drawing a shape. Converts the raw EditableGeoJsonLayer feature to a Shape\n * object, resets drawing state, releases mode/cursor, and emits the drawn event.\n *\n * ## Internal API\n * This function is exported for use by the DrawShapeLayer component and should\n * not be called directly from application code. Use the `draw` action from\n * `useDrawShape` or `useDrawingState` instead.\n *\n * @param mapId - Unique identifier for the map instance\n * @param feature - The completed GeoJSON feature from EditableGeoJsonLayer\n * @returns The newly created Shape object\n * @throws Error if not currently drawing\n *\n * @example\n * ```typescript\n * // Internal usage in DrawShapeLayer\n * const handleEdit = ({ updatedData, editType }: EditAction) => {\n * if (editType === 'addFeature') {\n * const feature = updatedData.features[updatedData.features.length - 1];\n * if (feature) {\n * completeDrawingFromLayer(mapId, feature);\n * }\n * }\n * };\n * ```\n */\nexport function completeDrawingFromLayer(\n mapId: UniqueId,\n feature: Feature,\n): Shape {\n const state = drawStore.get(mapId);\n return completeDrawingInternal(\n mapId,\n state,\n feature,\n () => {\n /* notify handled by set */\n },\n (updates) => drawStore.set(mapId, updates),\n );\n}\n\n/**\n * Cancel the current drawing operation from the layer.\n *\n * Called internally by the DrawShapeLayer component when the user presses ESC\n * or the drawing is otherwise canceled. Resets drawing state, releases mode/cursor,\n * and emits the canceled event.\n *\n * ## Internal API\n * This function is exported for use by the DrawShapeLayer component and should\n * not be called directly from application code. Use the `cancel` action from\n * `useDrawShape` or `useDrawingState` instead.\n *\n * @param mapId - Unique identifier for the map instance\n *\n * @example\n * ```typescript\n * // Internal usage in DrawShapeLayer\n * const handleEdit = ({ editType }: EditAction) => {\n * if (editType === 'cancelFeature') {\n * cancelDrawingFromLayer(mapId);\n * }\n * };\n * ```\n */\nexport function cancelDrawingFromLayer(mapId: UniqueId): void {\n drawStore.actions(mapId).cancel();\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA6DA,MAAM,eAAe,UAAU,aAA6B;AAC5D,MAAM,aAAa,UAAU,aAA+B;;;;AAK5D,MAAMA,wBAAsC;CAC1C,iBAAiB;CACjB,kBAAkB;CAClB,eAAe;CACf,gBAAgB;CACjB;;;;AAeD,SAAS,aACP,OACA,OACA,WACA,SACA,QACA,UACM;AAEN,KAAI,MAAM,gBACR,uBAAsB,OAAO,OAAO,QAAQ,SAAS;AAIvD,UAAS;EACP,iBAAiB;EACjB,kBAAkB;EAClB,eAAe,SAAS,iBAAiB;EACzC,gBAAgB,SAAS,kBAAkB;EAC5C,CAAC;CAGF,MAAM,SAAS,gBAAgB;AAC/B,sBAAqB,OAAO,iBAAiB,QAAQ,oBAAoB;AAGzE,cAAa,KAAK,gBAAgB,SAAS;EACzC;EACA;EACD,CAAC;AAEF,SAAQ;;;;;AAMV,SAAS,wBACP,OACA,OACA,SACA,QACA,UACO;AACP,KAAI,CAAC,MAAM,gBACT,OAAM,IAAI,MAAM,kDAAkD;CAGpE,MAAM,YAAY,MAAM;CACxB,MAAM,gBAAgB,MAAM;CAG5B,MAAM,QAAQ,sBAAsB,SAAS,WAAW,cAAc;AAGtE,UAAS;EACP,iBAAiB;EACjB,kBAAkB;EAClB,eAAe;EACf,gBAAgB;EACjB,CAAC;AAGF,sBAAqB,OAAO,oBAAoB;AAGhD,cAAa,KAAK,gBAAgB,OAAO;EACvC;EACA;EACD,CAA0C;AAE3C,SAAQ;AAER,QAAO;;;;;AAMT,SAAS,sBACP,OACA,OACA,QACA,UACM;AACN,KAAI,CAAC,MAAM,gBACT;CAGF,MAAM,YAAY,MAAM;AAGxB,UAAS;EACP,iBAAiB;EACjB,kBAAkB;EAClB,eAAe;EACf,gBAAgB;EACjB,CAAC;AAGF,sBAAqB,OAAO,oBAAoB;AAGhD,cAAa,KAAK,gBAAgB,UAAU;EAC1C;EACA;EACD,CAAC;AAEF,SAAQ;;;;;AAMV,MAAa,YAAY,eAA+C;CACtE,cAAc,EAAE,GAAG,uBAAuB;CAE1C,UAAU,OAAO,EAAE,KAAK,KAAK,cAAc;EACzC,OAAO,WAA6B,YAA+B;AACjE,gBAAa,OAAO,KAAK,EAAE,WAAW,SAAS,QAAQ,IAAI;;EAG7D,cAAc;AACZ,yBAAsB,OAAO,KAAK,EAAE,QAAQ,IAAI;;EAEnD;CAED,MAAM,OAAO,EAAE,UAAU;EAEvB,MAAM,YAAY,WAAW,GAC3B,cAAc,sBACb,UAAU;GACT,MAAM,EAAE,QAAQ,OAAO,MAAM;AAG7B,OAAI,OAAO,MACT;AAIF,OAAI,KAAK,CAAC,gBACR,YAAW,KAAK,cAAc,gBAAgB;IAC5C;IACA,UAAU;IACV,OAAO;IACP,QAAQ;IACR,IAAI;IACL,CAAC;IAGP;AAED,eAAa;AACX,cAAW;;;CAIf,YAAY,OAAO,UAAU;AAE3B,MAAI,MAAM,iBAAiB;AAEzB,wBAAqB,OAAO,oBAAoB;AAGhD,gBAAa,KAAK,gBAAgB,UAAU;IAC1C,WAAW,MAAM;IACjB;IACD,CAAC;;;CAGP,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAmJF,SAAgB,yBACd,OACA,SACO;AAEP,QAAO,wBACL,OAFY,UAAU,IAAI,MAAM,EAIhC,eACM,KAGL,YAAY,UAAU,IAAI,OAAO,QAAQ,CAC3C;;;;;;;;;;;;;;;;;;;;;;;;;;AA2BH,SAAgB,uBAAuB,OAAuB;AAC5D,WAAU,QAAQ,MAAM,CAAC,QAAQ"}
|