@accelint/map-toolkit 0.6.0 → 1.1.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 +81 -0
- package/catalog-info.yaml +7 -6
- package/dist/camera/events.js.map +1 -1
- package/dist/camera/index.d.ts +2 -2
- package/dist/camera/index.js +2 -2
- package/dist/camera/store.d.ts +120 -0
- package/dist/camera/store.js +279 -0
- package/dist/camera/store.js.map +1 -0
- package/dist/cursor-coordinates/index.d.ts +4 -2
- package/dist/cursor-coordinates/index.js +3 -2
- package/dist/cursor-coordinates/store.d.ts +48 -0
- package/dist/cursor-coordinates/store.js +92 -0
- package/dist/cursor-coordinates/store.js.map +1 -0
- package/dist/cursor-coordinates/types.d.ts +87 -0
- package/dist/cursor-coordinates/types.js +12 -0
- package/dist/cursor-coordinates/use-cursor-coordinates.d.ts +41 -37
- package/dist/cursor-coordinates/use-cursor-coordinates.js +131 -202
- package/dist/cursor-coordinates/use-cursor-coordinates.js.map +1 -1
- package/dist/deckgl/base-map/constants.d.ts +1 -6
- package/dist/deckgl/base-map/constants.js +1 -6
- package/dist/deckgl/base-map/constants.js.map +1 -1
- package/dist/deckgl/base-map/controls.js +2 -0
- package/dist/deckgl/base-map/controls.js.map +1 -1
- 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 +10 -11
- package/dist/deckgl/base-map/index.js.map +1 -1
- package/dist/deckgl/base-map/provider.d.ts +2 -2
- package/dist/deckgl/base-map/provider.js +1 -1
- package/dist/deckgl/base-map/provider.js.map +1 -1
- package/dist/deckgl/index.d.ts +4 -4
- package/dist/deckgl/index.js +4 -4
- package/dist/deckgl/saved-viewports/index.js.map +1 -1
- package/dist/deckgl/saved-viewports/storage.js +10 -2
- package/dist/deckgl/saved-viewports/storage.js.map +1 -1
- package/dist/deckgl/shapes/display-shape-layer/constants.js +5 -8
- package/dist/deckgl/shapes/display-shape-layer/constants.js.map +1 -1
- package/dist/deckgl/shapes/display-shape-layer/fiber.js.map +1 -1
- package/dist/deckgl/shapes/display-shape-layer/index.d.ts +18 -14
- package/dist/deckgl/shapes/display-shape-layer/index.js +63 -30
- package/dist/deckgl/shapes/display-shape-layer/index.js.map +1 -1
- package/dist/deckgl/shapes/display-shape-layer/shape-label-layer.js +2 -16
- package/dist/deckgl/shapes/display-shape-layer/shape-label-layer.js.map +1 -1
- package/dist/deckgl/shapes/display-shape-layer/store.js +58 -272
- package/dist/deckgl/shapes/display-shape-layer/store.js.map +1 -1
- package/dist/deckgl/shapes/display-shape-layer/types.d.ts +22 -11
- package/dist/deckgl/shapes/display-shape-layer/{use-shape-selection.d.ts → use-select-shape.d.ts} +9 -9
- package/dist/deckgl/shapes/display-shape-layer/{use-shape-selection.js → use-select-shape.js} +12 -12
- package/dist/deckgl/shapes/display-shape-layer/use-select-shape.js.map +1 -0
- package/dist/deckgl/shapes/display-shape-layer/utils/display-style.js +5 -66
- 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 +2 -65
- package/dist/deckgl/shapes/display-shape-layer/utils/labels.js +3 -121
- package/dist/deckgl/shapes/display-shape-layer/utils/labels.js.map +1 -1
- package/dist/deckgl/shapes/draw-shape-layer/constants.js +46 -0
- package/dist/deckgl/shapes/draw-shape-layer/constants.js.map +1 -0
- package/dist/deckgl/shapes/draw-shape-layer/events.d.ts +92 -0
- package/dist/deckgl/shapes/draw-shape-layer/events.js +56 -0
- package/dist/deckgl/shapes/draw-shape-layer/events.js.map +1 -0
- package/dist/deckgl/shapes/draw-shape-layer/fiber.d.ts +11 -0
- package/dist/{maplibre/constants.js → deckgl/shapes/draw-shape-layer/fiber.js} +6 -12
- package/dist/deckgl/shapes/draw-shape-layer/fiber.js.map +1 -0
- package/dist/deckgl/shapes/draw-shape-layer/index.d.ts +53 -0
- package/dist/deckgl/shapes/draw-shape-layer/index.js +95 -0
- package/dist/deckgl/shapes/draw-shape-layer/index.js.map +1 -0
- package/dist/deckgl/shapes/draw-shape-layer/modes/draw-circle-mode-with-tooltip.js +51 -0
- package/dist/deckgl/shapes/draw-shape-layer/modes/draw-circle-mode-with-tooltip.js.map +1 -0
- package/dist/deckgl/shapes/draw-shape-layer/modes/draw-ellipse-mode-with-tooltip.js +73 -0
- package/dist/deckgl/shapes/draw-shape-layer/modes/draw-ellipse-mode-with-tooltip.js.map +1 -0
- package/dist/deckgl/shapes/draw-shape-layer/modes/draw-line-string-mode-with-tooltip.js +87 -0
- package/dist/deckgl/shapes/draw-shape-layer/modes/draw-line-string-mode-with-tooltip.js.map +1 -0
- package/dist/deckgl/shapes/draw-shape-layer/modes/draw-polygon-mode-with-tooltip.js +88 -0
- package/dist/deckgl/shapes/draw-shape-layer/modes/draw-polygon-mode-with-tooltip.js.map +1 -0
- package/dist/deckgl/shapes/draw-shape-layer/modes/draw-rectangle-mode-with-tooltip.js +77 -0
- package/dist/deckgl/shapes/draw-shape-layer/modes/draw-rectangle-mode-with-tooltip.js.map +1 -0
- package/dist/deckgl/shapes/draw-shape-layer/modes/index.js +64 -0
- package/dist/deckgl/shapes/draw-shape-layer/modes/index.js.map +1 -0
- package/dist/deckgl/shapes/draw-shape-layer/store.js +175 -0
- package/dist/deckgl/shapes/draw-shape-layer/store.js.map +1 -0
- package/dist/deckgl/shapes/draw-shape-layer/types.d.ts +86 -0
- package/dist/{viewport/constants.js → deckgl/shapes/draw-shape-layer/types.js} +1 -12
- package/dist/deckgl/shapes/draw-shape-layer/use-draw-shape.d.ts +82 -0
- package/dist/deckgl/shapes/draw-shape-layer/use-draw-shape.js +112 -0
- package/dist/deckgl/shapes/draw-shape-layer/use-draw-shape.js.map +1 -0
- package/dist/deckgl/shapes/draw-shape-layer/utils/feature-conversion.js +147 -0
- package/dist/deckgl/shapes/draw-shape-layer/utils/feature-conversion.js.map +1 -0
- package/dist/deckgl/shapes/edit-shape-layer/constants.js +41 -0
- package/dist/deckgl/shapes/edit-shape-layer/constants.js.map +1 -0
- package/dist/deckgl/shapes/edit-shape-layer/events.d.ts +92 -0
- package/dist/deckgl/shapes/edit-shape-layer/events.js +56 -0
- package/dist/deckgl/shapes/edit-shape-layer/events.js.map +1 -0
- package/dist/deckgl/shapes/edit-shape-layer/fiber.d.ts +13 -0
- package/dist/deckgl/shapes/edit-shape-layer/fiber.js +14 -0
- package/dist/deckgl/shapes/edit-shape-layer/index.d.ts +63 -0
- package/dist/deckgl/shapes/edit-shape-layer/index.js +162 -0
- package/dist/deckgl/shapes/edit-shape-layer/index.js.map +1 -0
- package/dist/deckgl/shapes/edit-shape-layer/modes/base-transform-mode.js +154 -0
- package/dist/deckgl/shapes/edit-shape-layer/modes/base-transform-mode.js.map +1 -0
- package/dist/deckgl/shapes/edit-shape-layer/modes/bounding-transform-mode.js +147 -0
- package/dist/deckgl/shapes/edit-shape-layer/modes/bounding-transform-mode.js.map +1 -0
- package/dist/deckgl/shapes/edit-shape-layer/modes/circle-transform-mode.js +87 -0
- package/dist/deckgl/shapes/edit-shape-layer/modes/circle-transform-mode.js.map +1 -0
- package/dist/deckgl/shapes/edit-shape-layer/modes/index.js +61 -0
- package/dist/deckgl/shapes/edit-shape-layer/modes/index.js.map +1 -0
- package/dist/deckgl/shapes/edit-shape-layer/modes/rotate-mode-with-snap.js +109 -0
- package/dist/deckgl/shapes/edit-shape-layer/modes/rotate-mode-with-snap.js.map +1 -0
- package/dist/deckgl/shapes/edit-shape-layer/modes/scale-mode-with-free-transform.js +289 -0
- package/dist/deckgl/shapes/edit-shape-layer/modes/scale-mode-with-free-transform.js.map +1 -0
- package/dist/deckgl/shapes/edit-shape-layer/modes/vertex-transform-mode.js +121 -0
- package/dist/deckgl/shapes/edit-shape-layer/modes/vertex-transform-mode.js.map +1 -0
- package/dist/deckgl/shapes/edit-shape-layer/store.js +194 -0
- package/dist/deckgl/shapes/edit-shape-layer/store.js.map +1 -0
- package/dist/deckgl/shapes/edit-shape-layer/types.d.ts +93 -0
- package/dist/deckgl/shapes/edit-shape-layer/types.js +14 -0
- package/dist/deckgl/shapes/edit-shape-layer/use-edit-shape.d.ts +82 -0
- package/dist/deckgl/shapes/edit-shape-layer/use-edit-shape.js +114 -0
- package/dist/deckgl/shapes/edit-shape-layer/use-edit-shape.js.map +1 -0
- package/dist/deckgl/shapes/index.d.ts +15 -6
- package/dist/deckgl/shapes/index.js +12 -5
- package/dist/deckgl/shapes/shared/constants.d.ts +27 -32
- package/dist/deckgl/shapes/shared/constants.js +189 -25
- package/dist/deckgl/shapes/shared/constants.js.map +1 -1
- package/dist/deckgl/shapes/shared/events.d.ts +1 -20
- package/dist/deckgl/shapes/shared/events.js +1 -31
- package/dist/deckgl/shapes/shared/events.js.map +1 -1
- package/dist/deckgl/shapes/shared/hooks/use-shift-zoom-disable.js +84 -0
- package/dist/deckgl/shapes/shared/hooks/use-shift-zoom-disable.js.map +1 -0
- package/dist/deckgl/shapes/shared/types.d.ts +187 -28
- package/dist/deckgl/shapes/shared/types.js +55 -1
- package/dist/deckgl/shapes/shared/types.js.map +1 -1
- package/dist/deckgl/shapes/shared/utils/geometry-measurements.js +128 -0
- package/dist/deckgl/shapes/shared/utils/geometry-measurements.js.map +1 -0
- package/dist/deckgl/shapes/shared/utils/layer-config.js +50 -0
- package/dist/deckgl/shapes/shared/utils/layer-config.js.map +1 -0
- package/dist/deckgl/shapes/shared/utils/mode-utils.js +113 -0
- package/dist/deckgl/shapes/shared/utils/mode-utils.js.map +1 -0
- package/dist/deckgl/shapes/shared/utils/pick-filtering.js +57 -0
- package/dist/deckgl/shapes/shared/utils/pick-filtering.js.map +1 -0
- package/dist/deckgl/shapes/shared/utils/style-utils.d.ts +64 -0
- package/dist/deckgl/shapes/shared/utils/style-utils.js +101 -0
- package/dist/deckgl/shapes/shared/utils/style-utils.js.map +1 -0
- package/dist/deckgl/symbol-layer/fiber.js.map +1 -1
- package/dist/deckgl/symbol-layer/index.js.map +1 -1
- package/dist/deckgl/text-layer/character-sets.js.map +1 -1
- package/dist/deckgl/text-layer/default-settings.js +4 -24
- package/dist/deckgl/text-layer/default-settings.js.map +1 -1
- package/dist/deckgl/text-layer/fiber.js.map +1 -1
- package/dist/deckgl/text-layer/index.js.map +1 -1
- package/dist/deckgl/text-settings.d.ts +77 -0
- package/dist/deckgl/text-settings.js +83 -0
- package/dist/deckgl/text-settings.js.map +1 -0
- package/dist/map-cursor/events.js.map +1 -1
- package/dist/map-cursor/index.d.ts +2 -2
- package/dist/map-cursor/index.js +2 -2
- package/dist/map-cursor/store.d.ts +32 -61
- package/dist/map-cursor/store.js +165 -294
- package/dist/map-cursor/store.js.map +1 -1
- package/dist/map-cursor/use-map-cursor.d.ts +5 -2
- package/dist/map-cursor/use-map-cursor.js +33 -15
- package/dist/map-cursor/use-map-cursor.js.map +1 -1
- package/dist/map-mode/events.js.map +1 -1
- package/dist/map-mode/index.d.ts +2 -2
- package/dist/map-mode/index.js +2 -2
- package/dist/map-mode/store.d.ts +36 -37
- package/dist/map-mode/store.js +131 -237
- package/dist/map-mode/store.js.map +1 -1
- package/dist/map-mode/use-map-mode.js +6 -5
- package/dist/map-mode/use-map-mode.js.map +1 -1
- package/dist/maplibre/hooks/use-maplibre.js.map +1 -1
- package/dist/maplibre/index.d.ts +2 -2
- package/dist/maplibre/index.js +2 -2
- package/dist/shared/constants.d.ts +19 -0
- package/dist/shared/constants.js +33 -0
- package/dist/shared/constants.js.map +1 -0
- package/dist/shared/create-map-store.d.ts +202 -0
- package/dist/shared/create-map-store.js +223 -0
- package/dist/shared/create-map-store.js.map +1 -0
- package/dist/shared/units.d.ts +39 -0
- package/dist/shared/units.js +49 -0
- package/dist/shared/units.js.map +1 -0
- package/dist/viewport/index.d.ts +3 -3
- package/dist/viewport/index.js +3 -3
- package/dist/viewport/store.d.ts +69 -0
- package/dist/viewport/store.js +125 -0
- package/dist/viewport/store.js.map +1 -0
- package/dist/viewport/types.d.ts +2 -2
- package/dist/viewport/utils.js +2 -2
- package/dist/viewport/utils.js.map +1 -1
- package/dist/viewport/viewport-size.d.ts +2 -2
- package/dist/viewport/viewport-size.js +2 -2
- package/dist/viewport/viewport-size.js.map +1 -1
- package/package.json +39 -19
- package/dist/camera/use-camera-state.d.ts +0 -153
- package/dist/camera/use-camera-state.js +0 -418
- package/dist/camera/use-camera-state.js.map +0 -1
- package/dist/deckgl/shapes/display-shape-layer/constants.d.ts +0 -44
- package/dist/deckgl/shapes/display-shape-layer/shape-label-layer.d.ts +0 -66
- package/dist/deckgl/shapes/display-shape-layer/store.d.ts +0 -87
- package/dist/deckgl/shapes/display-shape-layer/use-shape-selection.js.map +0 -1
- package/dist/deckgl/shapes/display-shape-layer/utils/display-style.d.ts +0 -61
- package/dist/maplibre/constants.d.ts +0 -13
- package/dist/maplibre/constants.js.map +0 -1
- package/dist/viewport/constants.d.ts +0 -11
- package/dist/viewport/constants.js.map +0 -1
- package/dist/viewport/use-viewport-state.d.ts +0 -100
- package/dist/viewport/use-viewport-state.js +0 -222
- package/dist/viewport/use-viewport-state.js.map +0 -1
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright 2025 Hypergiant Galactic Systems Inc. All rights reserved.
|
|
3
|
+
* This file is licensed to you under the Apache License, Version 2.0 (the "License");
|
|
4
|
+
* you may not use this file except in compliance with the License. You may obtain a copy
|
|
5
|
+
* of the License at https://www.apache.org/licenses/LICENSE-2.0
|
|
6
|
+
*
|
|
7
|
+
* Unless required by applicable law or agreed to in writing, software distributed under
|
|
8
|
+
* the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
|
|
9
|
+
* OF ANY KIND, either express or implied. See the License for the specific language
|
|
10
|
+
* governing permissions and limitations under the License.
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
import { formatDistanceTooltip, formatEllipseTooltip } from "../../shared/constants.js";
|
|
15
|
+
import { DEFAULT_DISTANCE_UNITS, getDistanceUnitAbbreviation } from "../../../../shared/units.js";
|
|
16
|
+
import { DrawEllipseUsingThreePointsMode } from "@deck.gl-community/editable-layers";
|
|
17
|
+
import { distance } from "@turf/turf";
|
|
18
|
+
|
|
19
|
+
//#region src/deckgl/shapes/draw-shape-layer/modes/draw-ellipse-mode-with-tooltip.ts
|
|
20
|
+
/**
|
|
21
|
+
* Extends DrawEllipseUsingThreePointsMode to display contextual tooltips.
|
|
22
|
+
*
|
|
23
|
+
* Drawing process (3 clicks):
|
|
24
|
+
* 1. First click: Sets the first endpoint of the major axis
|
|
25
|
+
* 2. Second click: Sets the second endpoint of the major axis
|
|
26
|
+
* - While moving to second click, shows distance tooltip (like line/polygon)
|
|
27
|
+
* 3. Third click: Sets the minor axis radius
|
|
28
|
+
* - While moving to third click, shows area tooltip (like circle)
|
|
29
|
+
*
|
|
30
|
+
* The ellipse center is the midpoint between the first two clicks.
|
|
31
|
+
* The Y semi-axis is half the distance between clicks 1 and 2.
|
|
32
|
+
* The X semi-axis is the distance from center to click 3.
|
|
33
|
+
*/
|
|
34
|
+
var DrawEllipseModeWithTooltip = class extends DrawEllipseUsingThreePointsMode {
|
|
35
|
+
tooltip = null;
|
|
36
|
+
handlePointerMove(event, props) {
|
|
37
|
+
super.handlePointerMove(event, props);
|
|
38
|
+
const clickSequence = this.getClickSequence();
|
|
39
|
+
if (!clickSequence.length) {
|
|
40
|
+
this.tooltip = null;
|
|
41
|
+
return;
|
|
42
|
+
}
|
|
43
|
+
const { mapCoords } = event;
|
|
44
|
+
const distanceUnits = props.modeConfig?.distanceUnits ?? DEFAULT_DISTANCE_UNITS;
|
|
45
|
+
const unitAbbrev = getDistanceUnitAbbreviation(distanceUnits);
|
|
46
|
+
const tooltipPosition = mapCoords;
|
|
47
|
+
if (clickSequence.length === 1) {
|
|
48
|
+
const firstPoint = clickSequence[0];
|
|
49
|
+
this.tooltip = {
|
|
50
|
+
position: tooltipPosition,
|
|
51
|
+
text: formatDistanceTooltip(distance(firstPoint, mapCoords, { units: distanceUnits }), unitAbbrev)
|
|
52
|
+
};
|
|
53
|
+
} else if (clickSequence.length === 2) {
|
|
54
|
+
const click1 = clickSequence[0];
|
|
55
|
+
const click2 = clickSequence[1];
|
|
56
|
+
const cursorPos = mapCoords;
|
|
57
|
+
const center = [(click1[0] + click2[0]) / 2, (click1[1] + click2[1]) / 2];
|
|
58
|
+
const ySemiAxis = distance(click1, click2, { units: distanceUnits }) / 2;
|
|
59
|
+
const xSemiAxis = distance(center, cursorPos, { units: distanceUnits });
|
|
60
|
+
this.tooltip = {
|
|
61
|
+
position: tooltipPosition,
|
|
62
|
+
text: formatEllipseTooltip(Math.max(xSemiAxis, ySemiAxis) * 2, Math.min(xSemiAxis, ySemiAxis) * 2, Math.PI * xSemiAxis * ySemiAxis, unitAbbrev)
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
getTooltips() {
|
|
67
|
+
return this.tooltip ? [this.tooltip] : [];
|
|
68
|
+
}
|
|
69
|
+
};
|
|
70
|
+
|
|
71
|
+
//#endregion
|
|
72
|
+
export { DrawEllipseModeWithTooltip };
|
|
73
|
+
//# sourceMappingURL=draw-ellipse-mode-with-tooltip.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"draw-ellipse-mode-with-tooltip.js","names":["center: [number, number]"],"sources":["../../../../../src/deckgl/shapes/draw-shape-layer/modes/draw-ellipse-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 DrawEllipseUsingThreePointsMode,\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 {\n formatDistanceTooltip,\n formatEllipseTooltip,\n} from '../../shared/constants';\n\n/**\n * Extends DrawEllipseUsingThreePointsMode to display contextual tooltips.\n *\n * Drawing process (3 clicks):\n * 1. First click: Sets the first endpoint of the major axis\n * 2. Second click: Sets the second endpoint of the major axis\n * - While moving to second click, shows distance tooltip (like line/polygon)\n * 3. Third click: Sets the minor axis radius\n * - While moving to third click, shows area tooltip (like circle)\n *\n * The ellipse center is the midpoint between the first two clicks.\n * The Y semi-axis is half the distance between clicks 1 and 2.\n * The X semi-axis is the distance from center to click 3.\n */\nexport class DrawEllipseModeWithTooltip extends DrawEllipseUsingThreePointsMode {\n private tooltip: Tooltip | null = null;\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 const unitAbbrev = getDistanceUnitAbbreviation(distanceUnits);\n const tooltipPosition = mapCoords;\n\n if (clickSequence.length === 1) {\n // First segment: show distance from first click to cursor (like line/polygon)\n const firstPoint = clickSequence[0] as Coord;\n const currentPoint = mapCoords as Coord;\n\n const dist = distance(firstPoint, currentPoint, { units: distanceUnits });\n\n this.tooltip = {\n position: tooltipPosition,\n text: formatDistanceTooltip(dist, unitAbbrev),\n };\n } else if (clickSequence.length === 2) {\n // Second segment: show dimensions and area (like rectangle)\n // The ellipse will have:\n // - center at midpoint of click1 and click2\n // - ySemiAxis = distance(click1, click2) / 2\n // - xSemiAxis = distance(center, cursor)\n const click1 = clickSequence[0] as [number, number];\n const click2 = clickSequence[1] as [number, number];\n const cursorPos = mapCoords as [number, number];\n\n // Calculate center (midpoint)\n const center: [number, number] = [\n (click1[0] + click2[0]) / 2,\n (click1[1] + click2[1]) / 2,\n ];\n\n // Calculate semi-axes\n const ySemiAxis = distance(click1, click2, { units: distanceUnits }) / 2;\n const xSemiAxis = distance(center, cursorPos, { units: distanceUnits });\n\n // Full axes (diameter equivalent)\n const majorAxis = Math.max(xSemiAxis, ySemiAxis) * 2;\n const minorAxis = Math.min(xSemiAxis, ySemiAxis) * 2;\n\n // Ellipse area = π × a × b\n const ellipseArea = Math.PI * xSemiAxis * ySemiAxis;\n\n this.tooltip = {\n position: tooltipPosition,\n text: formatEllipseTooltip(\n majorAxis,\n minorAxis,\n ellipseArea,\n unitAbbrev,\n ),\n };\n }\n }\n\n override getTooltips(): Tooltip[] {\n return this.tooltip ? [this.tooltip] : [];\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA2CA,IAAa,6BAAb,cAAgD,gCAAgC;CAC9E,AAAQ,UAA0B;CAElC,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;EACrC,MAAM,aAAa,4BAA4B,cAAc;EAC7D,MAAM,kBAAkB;AAExB,MAAI,cAAc,WAAW,GAAG;GAE9B,MAAM,aAAa,cAAc;AAKjC,QAAK,UAAU;IACb,UAAU;IACV,MAAM,sBAJK,SAAS,YAFD,WAE2B,EAAE,OAAO,eAAe,CAAC,EAIrC,WAAW;IAC9C;aACQ,cAAc,WAAW,GAAG;GAMrC,MAAM,SAAS,cAAc;GAC7B,MAAM,SAAS,cAAc;GAC7B,MAAM,YAAY;GAGlB,MAAMA,SAA2B,EAC9B,OAAO,KAAK,OAAO,MAAM,IACzB,OAAO,KAAK,OAAO,MAAM,EAC3B;GAGD,MAAM,YAAY,SAAS,QAAQ,QAAQ,EAAE,OAAO,eAAe,CAAC,GAAG;GACvE,MAAM,YAAY,SAAS,QAAQ,WAAW,EAAE,OAAO,eAAe,CAAC;AASvE,QAAK,UAAU;IACb,UAAU;IACV,MAAM,qBARU,KAAK,IAAI,WAAW,UAAU,GAAG,GACjC,KAAK,IAAI,WAAW,UAAU,GAAG,GAG/B,KAAK,KAAK,YAAY,WAQtC,WACD;IACF;;;CAIL,AAAS,cAAyB;AAChC,SAAO,KAAK,UAAU,CAAC,KAAK,QAAQ,GAAG,EAAE"}
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright 2025 Hypergiant Galactic Systems Inc. All rights reserved.
|
|
3
|
+
* This file is licensed to you under the Apache License, Version 2.0 (the "License");
|
|
4
|
+
* you may not use this file except in compliance with the License. You may obtain a copy
|
|
5
|
+
* of the License at https://www.apache.org/licenses/LICENSE-2.0
|
|
6
|
+
*
|
|
7
|
+
* Unless required by applicable law or agreed to in writing, software distributed under
|
|
8
|
+
* the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
|
|
9
|
+
* OF ANY KIND, either express or implied. See the License for the specific language
|
|
10
|
+
* governing permissions and limitations under the License.
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
import { formatDistanceTooltip } from "../../shared/constants.js";
|
|
15
|
+
import { DEFAULT_DISTANCE_UNITS, getDistanceUnitAbbreviation } from "../../../../shared/units.js";
|
|
16
|
+
import { DrawLineStringMode } from "@deck.gl-community/editable-layers";
|
|
17
|
+
import { distance } from "@turf/turf";
|
|
18
|
+
|
|
19
|
+
//#region src/deckgl/shapes/draw-shape-layer/modes/draw-line-string-mode-with-tooltip.ts
|
|
20
|
+
/**
|
|
21
|
+
* Extends DrawLineStringMode to display distance tooltip between points.
|
|
22
|
+
*
|
|
23
|
+
* Shows the distance from the last clicked point to the current cursor position
|
|
24
|
+
* while drawing a line string.
|
|
25
|
+
*
|
|
26
|
+
* Includes a workaround for the double-click to finish issue in @deck.gl-community/editable-layers ~9.1.
|
|
27
|
+
* This will be fixed in a future version (PR #225).
|
|
28
|
+
*/
|
|
29
|
+
var DrawLineStringModeWithTooltip = class extends DrawLineStringMode {
|
|
30
|
+
tooltip = null;
|
|
31
|
+
lastModeProps = null;
|
|
32
|
+
/**
|
|
33
|
+
* Finish drawing the line string.
|
|
34
|
+
* Extracted to share between double-click workaround and parent class logic.
|
|
35
|
+
*/
|
|
36
|
+
finishDrawing(props) {
|
|
37
|
+
const clickSequence = this.getClickSequence();
|
|
38
|
+
if (clickSequence.length <= 1) return;
|
|
39
|
+
const lineStringToAdd = {
|
|
40
|
+
type: "LineString",
|
|
41
|
+
coordinates: [...clickSequence]
|
|
42
|
+
};
|
|
43
|
+
this.resetClickSequence();
|
|
44
|
+
this.tooltip = null;
|
|
45
|
+
this.lastModeProps = null;
|
|
46
|
+
const editAction = this.getAddFeatureAction(lineStringToAdd, props.data);
|
|
47
|
+
if (editAction) props.onEdit(editAction);
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Handle double-click to finish drawing.
|
|
51
|
+
* This is called externally via a DOM event listener as a workaround for
|
|
52
|
+
* @deck.gl-community/editable-layers ~9.1 which doesn't register 'dblclick' in EVENT_TYPES.
|
|
53
|
+
* @see https://github.com/visgl/deck.gl-community/pull/225
|
|
54
|
+
*/
|
|
55
|
+
handleDoubleClick() {
|
|
56
|
+
if (this.lastModeProps) this.finishDrawing(this.lastModeProps);
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Override handleClick to store props for double-click workaround.
|
|
60
|
+
*/
|
|
61
|
+
handleClick(event, props) {
|
|
62
|
+
this.lastModeProps = props;
|
|
63
|
+
super.handleClick(event, props);
|
|
64
|
+
}
|
|
65
|
+
handlePointerMove(event, props) {
|
|
66
|
+
super.handlePointerMove(event, props);
|
|
67
|
+
const clickSequence = this.getClickSequence();
|
|
68
|
+
if (!clickSequence.length) {
|
|
69
|
+
this.tooltip = null;
|
|
70
|
+
return;
|
|
71
|
+
}
|
|
72
|
+
const { mapCoords } = event;
|
|
73
|
+
const distanceUnits = props.modeConfig?.distanceUnits ?? DEFAULT_DISTANCE_UNITS;
|
|
74
|
+
const lastPoint = clickSequence[clickSequence.length - 1];
|
|
75
|
+
this.tooltip = {
|
|
76
|
+
position: mapCoords,
|
|
77
|
+
text: formatDistanceTooltip(distance(lastPoint, mapCoords, { units: distanceUnits }), getDistanceUnitAbbreviation(distanceUnits))
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
getTooltips() {
|
|
81
|
+
return this.tooltip ? [this.tooltip] : [];
|
|
82
|
+
}
|
|
83
|
+
};
|
|
84
|
+
|
|
85
|
+
//#endregion
|
|
86
|
+
export { DrawLineStringModeWithTooltip };
|
|
87
|
+
//# sourceMappingURL=draw-line-string-mode-with-tooltip.js.map
|
|
@@ -0,0 +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":";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAoCA,IAAa,gCAAb,cAAmD,mBAAmB;CACpE,AAAQ,UAA0B;CAClC,AAAQ,gBAAqD;;;;;CAM7D,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;;;;;CAO1C,AAAS,YACP,OACA,OACM;AAEN,OAAK,gBAAgB;AACrB,QAAM,YAAY,OAAO,MAAM;;CAGjC,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;;CAGH,AAAS,cAAyB;AAChC,SAAO,KAAK,UAAU,CAAC,KAAK,QAAQ,GAAG,EAAE"}
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright 2025 Hypergiant Galactic Systems Inc. All rights reserved.
|
|
3
|
+
* This file is licensed to you under the Apache License, Version 2.0 (the "License");
|
|
4
|
+
* you may not use this file except in compliance with the License. You may obtain a copy
|
|
5
|
+
* of the License at https://www.apache.org/licenses/LICENSE-2.0
|
|
6
|
+
*
|
|
7
|
+
* Unless required by applicable law or agreed to in writing, software distributed under
|
|
8
|
+
* the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
|
|
9
|
+
* OF ANY KIND, either express or implied. See the License for the specific language
|
|
10
|
+
* governing permissions and limitations under the License.
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
import { formatDistanceTooltip } from "../../shared/constants.js";
|
|
15
|
+
import { DEFAULT_DISTANCE_UNITS, getDistanceUnitAbbreviation } from "../../../../shared/units.js";
|
|
16
|
+
import { DrawPolygonMode } from "@deck.gl-community/editable-layers";
|
|
17
|
+
import { distance } from "@turf/turf";
|
|
18
|
+
|
|
19
|
+
//#region src/deckgl/shapes/draw-shape-layer/modes/draw-polygon-mode-with-tooltip.ts
|
|
20
|
+
/**
|
|
21
|
+
* Extends DrawPolygonMode to display distance tooltip between points.
|
|
22
|
+
*
|
|
23
|
+
* Shows the distance from the last clicked point to the current cursor position
|
|
24
|
+
* while drawing a polygon.
|
|
25
|
+
*
|
|
26
|
+
* Includes a workaround for the double-click to finish issue in @deck.gl-community/editable-layers ~9.1.
|
|
27
|
+
* This will be fixed in a future version (PR #225).
|
|
28
|
+
*/
|
|
29
|
+
var DrawPolygonModeWithTooltip = class extends DrawPolygonMode {
|
|
30
|
+
tooltip = null;
|
|
31
|
+
lastModeProps = null;
|
|
32
|
+
/**
|
|
33
|
+
* Finish drawing the polygon.
|
|
34
|
+
* Extracted to share between double-click workaround and parent class logic.
|
|
35
|
+
*/
|
|
36
|
+
finishDrawing(props) {
|
|
37
|
+
const clickSequence = this.getClickSequence();
|
|
38
|
+
const firstPoint = clickSequence[0];
|
|
39
|
+
if (clickSequence.length <= 2 || !firstPoint) return;
|
|
40
|
+
const polygonToAdd = {
|
|
41
|
+
type: "Polygon",
|
|
42
|
+
coordinates: [[...clickSequence, firstPoint]]
|
|
43
|
+
};
|
|
44
|
+
this.resetClickSequence();
|
|
45
|
+
this.tooltip = null;
|
|
46
|
+
this.lastModeProps = null;
|
|
47
|
+
const editAction = this.getAddFeatureOrBooleanPolygonAction(polygonToAdd, props);
|
|
48
|
+
if (editAction) props.onEdit(editAction);
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Handle double-click to finish drawing.
|
|
52
|
+
* This is called externally via a DOM event listener as a workaround for
|
|
53
|
+
* @deck.gl-community/editable-layers ~9.1 which doesn't register 'dblclick' in EVENT_TYPES.
|
|
54
|
+
* @see https://github.com/visgl/deck.gl-community/pull/225
|
|
55
|
+
*/
|
|
56
|
+
handleDoubleClick() {
|
|
57
|
+
if (this.lastModeProps) this.finishDrawing(this.lastModeProps);
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Override handleClick to store props for double-click workaround.
|
|
61
|
+
*/
|
|
62
|
+
handleClick(event, props) {
|
|
63
|
+
this.lastModeProps = props;
|
|
64
|
+
super.handleClick(event, props);
|
|
65
|
+
}
|
|
66
|
+
handlePointerMove(event, props) {
|
|
67
|
+
super.handlePointerMove(event, props);
|
|
68
|
+
const clickSequence = this.getClickSequence();
|
|
69
|
+
if (!clickSequence.length) {
|
|
70
|
+
this.tooltip = null;
|
|
71
|
+
return;
|
|
72
|
+
}
|
|
73
|
+
const { mapCoords } = event;
|
|
74
|
+
const distanceUnits = props.modeConfig?.distanceUnits ?? DEFAULT_DISTANCE_UNITS;
|
|
75
|
+
const lastPoint = clickSequence[clickSequence.length - 1];
|
|
76
|
+
this.tooltip = {
|
|
77
|
+
position: mapCoords,
|
|
78
|
+
text: formatDistanceTooltip(distance(lastPoint, mapCoords, { units: distanceUnits }), getDistanceUnitAbbreviation(distanceUnits))
|
|
79
|
+
};
|
|
80
|
+
}
|
|
81
|
+
getTooltips() {
|
|
82
|
+
return this.tooltip ? [this.tooltip] : [];
|
|
83
|
+
}
|
|
84
|
+
};
|
|
85
|
+
|
|
86
|
+
//#endregion
|
|
87
|
+
export { DrawPolygonModeWithTooltip };
|
|
88
|
+
//# sourceMappingURL=draw-polygon-mode-with-tooltip.js.map
|
|
@@ -0,0 +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":";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAoCA,IAAa,6BAAb,cAAgD,gBAAgB;CAC9D,AAAQ,UAA0B;CAClC,AAAQ,gBAAqD;;;;;CAM7D,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;;;;;CAO1C,AAAS,YACP,OACA,OACM;AAEN,OAAK,gBAAgB;AACrB,QAAM,YAAY,OAAO,MAAM;;CAGjC,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;;CAGH,AAAS,cAAyB;AAChC,SAAO,KAAK,UAAU,CAAC,KAAK,QAAQ,GAAG,EAAE"}
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright 2025 Hypergiant Galactic Systems Inc. All rights reserved.
|
|
3
|
+
* This file is licensed to you under the Apache License, Version 2.0 (the "License");
|
|
4
|
+
* you may not use this file except in compliance with the License. You may obtain a copy
|
|
5
|
+
* of the License at https://www.apache.org/licenses/LICENSE-2.0
|
|
6
|
+
*
|
|
7
|
+
* Unless required by applicable law or agreed to in writing, software distributed under
|
|
8
|
+
* the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
|
|
9
|
+
* OF ANY KIND, either express or implied. See the License for the specific language
|
|
10
|
+
* governing permissions and limitations under the License.
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
import { formatRectangleTooltip } from "../../shared/constants.js";
|
|
15
|
+
import { DEFAULT_DISTANCE_UNITS, getDistanceUnitAbbreviation } from "../../../../shared/units.js";
|
|
16
|
+
import { DrawRectangleMode } from "@deck.gl-community/editable-layers";
|
|
17
|
+
import { area, bbox, bboxPolygon, convertArea, destination, distance } from "@turf/turf";
|
|
18
|
+
import { featureCollection, point as point$1 } from "@turf/helpers";
|
|
19
|
+
|
|
20
|
+
//#region src/deckgl/shapes/draw-shape-layer/modes/draw-rectangle-mode-with-tooltip.ts
|
|
21
|
+
/**
|
|
22
|
+
* Extends DrawRectangleMode to display dimensions and area tooltip.
|
|
23
|
+
*
|
|
24
|
+
* Shows the width, height, and total area of the rectangle being drawn.
|
|
25
|
+
* Hold Shift to constrain to a square.
|
|
26
|
+
*/
|
|
27
|
+
var DrawRectangleModeWithTooltip = class extends DrawRectangleMode {
|
|
28
|
+
tooltip = null;
|
|
29
|
+
isShiftPressed = false;
|
|
30
|
+
/**
|
|
31
|
+
* Override getTwoClickPolygon to support Shift-constrained squares.
|
|
32
|
+
* When Shift is held, the rectangle is constrained to a square using
|
|
33
|
+
* real-world distances to account for lat/lon distortion.
|
|
34
|
+
*/
|
|
35
|
+
getTwoClickPolygon(coord1, coord2, modeConfig) {
|
|
36
|
+
let finalCoord2 = coord2;
|
|
37
|
+
if (this.isShiftPressed && coord1 && coord2) {
|
|
38
|
+
const lon1 = coord1[0] ?? 0;
|
|
39
|
+
const lat1 = coord1[1] ?? 0;
|
|
40
|
+
const lon2 = coord2[0] ?? 0;
|
|
41
|
+
const lat2 = coord2[1] ?? 0;
|
|
42
|
+
const horizontalDist = distance(point$1([lon1, lat1]), point$1([lon2, lat1]), { units: "kilometers" });
|
|
43
|
+
const verticalDist = distance(point$1([lon1, lat1]), point$1([lon1, lat2]), { units: "kilometers" });
|
|
44
|
+
const maxDist = Math.max(horizontalDist, verticalDist);
|
|
45
|
+
const lonSign = lon2 >= lon1 ? 1 : -1;
|
|
46
|
+
const latSign = lat2 >= lat1 ? 1 : -1;
|
|
47
|
+
finalCoord2 = destination(destination(point$1([lon1, lat1]), maxDist, lonSign > 0 ? 90 : 270, { units: "kilometers" }), maxDist, latSign > 0 ? 0 : 180, { units: "kilometers" }).geometry.coordinates;
|
|
48
|
+
}
|
|
49
|
+
return super.getTwoClickPolygon(coord1, finalCoord2, modeConfig);
|
|
50
|
+
}
|
|
51
|
+
handlePointerMove(event, props) {
|
|
52
|
+
this.isShiftPressed = event.sourceEvent?.shiftKey ?? false;
|
|
53
|
+
super.handlePointerMove(event, props);
|
|
54
|
+
const clickSequence = this.getClickSequence();
|
|
55
|
+
const firstClick = clickSequence[clickSequence.length - 1];
|
|
56
|
+
if (!firstClick) {
|
|
57
|
+
this.tooltip = null;
|
|
58
|
+
return;
|
|
59
|
+
}
|
|
60
|
+
const { mapCoords } = event;
|
|
61
|
+
const distanceUnits = props.modeConfig?.distanceUnits ?? DEFAULT_DISTANCE_UNITS;
|
|
62
|
+
const firstClickPoint = point$1(firstClick);
|
|
63
|
+
const currentPoint = point$1(mapCoords);
|
|
64
|
+
const cornerPoint = point$1([firstClick[0], mapCoords[1]]);
|
|
65
|
+
this.tooltip = {
|
|
66
|
+
position: mapCoords,
|
|
67
|
+
text: formatRectangleTooltip(distance(firstClickPoint, cornerPoint, { units: distanceUnits }), distance(currentPoint, cornerPoint, { units: distanceUnits }), convertArea(area(bboxPolygon(bbox(featureCollection([firstClickPoint, currentPoint])))), "meters", distanceUnits), getDistanceUnitAbbreviation(distanceUnits))
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
getTooltips() {
|
|
71
|
+
return this.tooltip ? [this.tooltip] : [];
|
|
72
|
+
}
|
|
73
|
+
};
|
|
74
|
+
|
|
75
|
+
//#endregion
|
|
76
|
+
export { DrawRectangleModeWithTooltip };
|
|
77
|
+
//# sourceMappingURL=draw-rectangle-mode-with-tooltip.js.map
|
|
@@ -0,0 +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 is constrained to a square using\n * real-world distances to account for lat/lon distortion.\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 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 override getTooltips(): Tooltip[] {\n return this.tooltip ? [this.tooltip] : [];\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;AAyCA,IAAa,+BAAb,cAAkD,kBAAkB;CAClE,AAAQ,UAA0B;CAClC,AAAQ,iBAAiB;;;;;;CAOzB,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;;CAGlE,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;;CAGH,AAAS,cAAyB;AAChC,SAAO,KAAK,UAAU,CAAC,KAAK,QAAQ,GAAG,EAAE"}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright 2025 Hypergiant Galactic Systems Inc. All rights reserved.
|
|
3
|
+
* This file is licensed to you under the Apache License, Version 2.0 (the "License");
|
|
4
|
+
* you may not use this file except in compliance with the License. You may obtain a copy
|
|
5
|
+
* of the License at https://www.apache.org/licenses/LICENSE-2.0
|
|
6
|
+
*
|
|
7
|
+
* Unless required by applicable law or agreed to in writing, software distributed under
|
|
8
|
+
* the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
|
|
9
|
+
* OF ANY KIND, either express or implied. See the License for the specific language
|
|
10
|
+
* governing permissions and limitations under the License.
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
import { ShapeFeatureType } from "../../shared/types.js";
|
|
15
|
+
import { DrawCircleModeWithTooltip } from "./draw-circle-mode-with-tooltip.js";
|
|
16
|
+
import { DrawEllipseModeWithTooltip } from "./draw-ellipse-mode-with-tooltip.js";
|
|
17
|
+
import { DrawLineStringModeWithTooltip } from "./draw-line-string-mode-with-tooltip.js";
|
|
18
|
+
import { DrawPolygonModeWithTooltip } from "./draw-polygon-mode-with-tooltip.js";
|
|
19
|
+
import { DrawRectangleModeWithTooltip } from "./draw-rectangle-mode-with-tooltip.js";
|
|
20
|
+
import { DrawPointMode, ViewMode } from "@deck.gl-community/editable-layers";
|
|
21
|
+
|
|
22
|
+
//#region src/deckgl/shapes/draw-shape-layer/modes/index.ts
|
|
23
|
+
/**
|
|
24
|
+
* Cached mode instances.
|
|
25
|
+
*
|
|
26
|
+
* CRITICAL: Mode instances must be cached at module level to prevent
|
|
27
|
+
* deck.gl assertion failures. Creating new mode instances on each render
|
|
28
|
+
* causes the EditableGeoJsonLayer to fail with assertion errors.
|
|
29
|
+
*/
|
|
30
|
+
const MODE_INSTANCES = {
|
|
31
|
+
[ShapeFeatureType.Point]: new DrawPointMode(),
|
|
32
|
+
[ShapeFeatureType.LineString]: new DrawLineStringModeWithTooltip(),
|
|
33
|
+
[ShapeFeatureType.Polygon]: new DrawPolygonModeWithTooltip(),
|
|
34
|
+
[ShapeFeatureType.Rectangle]: new DrawRectangleModeWithTooltip(),
|
|
35
|
+
[ShapeFeatureType.Circle]: new DrawCircleModeWithTooltip(),
|
|
36
|
+
[ShapeFeatureType.Ellipse]: new DrawEllipseModeWithTooltip(),
|
|
37
|
+
view: new ViewMode()
|
|
38
|
+
};
|
|
39
|
+
/**
|
|
40
|
+
* Get the cached mode instance for a shape type.
|
|
41
|
+
*
|
|
42
|
+
* @param shapeType - The shape type to get the mode for
|
|
43
|
+
* @returns The cached mode instance for drawing that shape type
|
|
44
|
+
*/
|
|
45
|
+
function getModeInstance(shapeType) {
|
|
46
|
+
return MODE_INSTANCES[shapeType];
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Trigger double-click finish on the active mode.
|
|
50
|
+
* This is a workaround for @deck.gl-community/editable-layers ~9.1 which doesn't
|
|
51
|
+
* register 'dblclick' in EVENT_TYPES. We listen for dblclick at the DOM level
|
|
52
|
+
* and call this function to finish drawing.
|
|
53
|
+
*
|
|
54
|
+
* @param shapeType - The shape type currently being drawn
|
|
55
|
+
* @see https://github.com/visgl/deck.gl-community/pull/225
|
|
56
|
+
*/
|
|
57
|
+
function triggerDoubleClickFinish(shapeType) {
|
|
58
|
+
const mode = MODE_INSTANCES[shapeType];
|
|
59
|
+
if (mode instanceof DrawPolygonModeWithTooltip || mode instanceof DrawLineStringModeWithTooltip) mode.handleDoubleClick();
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
//#endregion
|
|
63
|
+
export { getModeInstance, triggerDoubleClickFinish };
|
|
64
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +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;;;;;;;AAQD,SAAgB,gBACd,WAC2C;AAC3C,QAAO,eAAe;;;;;;;;;;;AAqBxB,SAAgB,yBAAyB,WAAmC;CAC1E,MAAM,OAAO,eAAe;AAG5B,KACE,gBAAgB,8BAChB,gBAAgB,8BAEhB,MAAK,mBAAmB"}
|
|
@@ -0,0 +1,175 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright 2025 Hypergiant Galactic Systems Inc. All rights reserved.
|
|
3
|
+
* This file is licensed to you under the Apache License, Version 2.0 (the "License");
|
|
4
|
+
* you may not use this file except in compliance with the License. You may obtain a copy
|
|
5
|
+
* of the License at https://www.apache.org/licenses/LICENSE-2.0
|
|
6
|
+
*
|
|
7
|
+
* Unless required by applicable law or agreed to in writing, software distributed under
|
|
8
|
+
* the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
|
|
9
|
+
* OF ANY KIND, either express or implied. See the License for the specific language
|
|
10
|
+
* governing permissions and limitations under the License.
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
'use client';
|
|
15
|
+
|
|
16
|
+
import { createMapStore } from "../../../shared/create-map-store.js";
|
|
17
|
+
import { MapModeEvents } from "../../../map-mode/events.js";
|
|
18
|
+
import { DrawShapeEvents } from "./events.js";
|
|
19
|
+
import { DRAW_CURSOR_MAP, DRAW_SHAPE_LAYER_ID, DRAW_SHAPE_MODE } from "./constants.js";
|
|
20
|
+
import { releaseModeAndCursor, requestModeAndCursor } from "../shared/utils/mode-utils.js";
|
|
21
|
+
import { convertFeatureToShape } from "./utils/feature-conversion.js";
|
|
22
|
+
import { Broadcast } from "@accelint/bus";
|
|
23
|
+
|
|
24
|
+
//#region src/deckgl/shapes/draw-shape-layer/store.ts
|
|
25
|
+
/**
|
|
26
|
+
* Draw Shape Store
|
|
27
|
+
*
|
|
28
|
+
* Manages drawing state for shape creation.
|
|
29
|
+
*
|
|
30
|
+
* @example
|
|
31
|
+
* ```tsx
|
|
32
|
+
* import { drawStore } from '@accelint/map-toolkit/deckgl/shapes';
|
|
33
|
+
*
|
|
34
|
+
* function DrawControls({ mapId }) {
|
|
35
|
+
* const { state, draw, cancel } = drawStore.use(mapId);
|
|
36
|
+
*
|
|
37
|
+
* return (
|
|
38
|
+
* <div>
|
|
39
|
+
* <p>Drawing: {state.activeShapeType ?? 'none'}</p>
|
|
40
|
+
* <button onClick={() => draw('Polygon')}>Draw Polygon</button>
|
|
41
|
+
* <button onClick={cancel}>Cancel</button>
|
|
42
|
+
* </div>
|
|
43
|
+
* );
|
|
44
|
+
* }
|
|
45
|
+
* ```
|
|
46
|
+
*/
|
|
47
|
+
/**
|
|
48
|
+
* Typed event bus instances
|
|
49
|
+
*/
|
|
50
|
+
const drawShapeBus = Broadcast.getInstance();
|
|
51
|
+
const mapModeBus = Broadcast.getInstance();
|
|
52
|
+
/**
|
|
53
|
+
* Default drawing state
|
|
54
|
+
*/
|
|
55
|
+
const DEFAULT_DRAWING_STATE = {
|
|
56
|
+
activeShapeType: null,
|
|
57
|
+
tentativeFeature: null,
|
|
58
|
+
styleDefaults: null,
|
|
59
|
+
circleDefaults: null
|
|
60
|
+
};
|
|
61
|
+
/**
|
|
62
|
+
* Start drawing a shape
|
|
63
|
+
*/
|
|
64
|
+
function startDrawing(mapId, state, shapeType, options, notify, setState) {
|
|
65
|
+
if (state.activeShapeType) cancelDrawingInternal(mapId, state, notify, setState);
|
|
66
|
+
setState({
|
|
67
|
+
activeShapeType: shapeType,
|
|
68
|
+
tentativeFeature: null,
|
|
69
|
+
styleDefaults: options?.styleDefaults ?? null,
|
|
70
|
+
circleDefaults: options?.circleDefaults ?? null
|
|
71
|
+
});
|
|
72
|
+
const cursor = DRAW_CURSOR_MAP[shapeType];
|
|
73
|
+
requestModeAndCursor(mapId, DRAW_SHAPE_MODE, cursor, DRAW_SHAPE_LAYER_ID);
|
|
74
|
+
drawShapeBus.emit(DrawShapeEvents.drawing, {
|
|
75
|
+
shapeType,
|
|
76
|
+
mapId
|
|
77
|
+
});
|
|
78
|
+
notify();
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Complete drawing and create a shape
|
|
82
|
+
*/
|
|
83
|
+
function completeDrawingInternal(mapId, state, feature, notify, setState) {
|
|
84
|
+
if (!state.activeShapeType) throw new Error("Cannot complete drawing - not currently drawing");
|
|
85
|
+
const shapeType = state.activeShapeType;
|
|
86
|
+
const styleDefaults = state.styleDefaults;
|
|
87
|
+
const shape = convertFeatureToShape(feature, shapeType, styleDefaults);
|
|
88
|
+
setState({
|
|
89
|
+
activeShapeType: null,
|
|
90
|
+
tentativeFeature: null,
|
|
91
|
+
styleDefaults: null,
|
|
92
|
+
circleDefaults: null
|
|
93
|
+
});
|
|
94
|
+
releaseModeAndCursor(mapId, DRAW_SHAPE_LAYER_ID);
|
|
95
|
+
drawShapeBus.emit(DrawShapeEvents.drawn, {
|
|
96
|
+
shape,
|
|
97
|
+
mapId
|
|
98
|
+
});
|
|
99
|
+
notify();
|
|
100
|
+
return shape;
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* Cancel the current drawing operation
|
|
104
|
+
*/
|
|
105
|
+
function cancelDrawingInternal(mapId, state, notify, setState) {
|
|
106
|
+
if (!state.activeShapeType) return;
|
|
107
|
+
const shapeType = state.activeShapeType;
|
|
108
|
+
setState({
|
|
109
|
+
activeShapeType: null,
|
|
110
|
+
tentativeFeature: null,
|
|
111
|
+
styleDefaults: null,
|
|
112
|
+
circleDefaults: null
|
|
113
|
+
});
|
|
114
|
+
releaseModeAndCursor(mapId, DRAW_SHAPE_LAYER_ID);
|
|
115
|
+
drawShapeBus.emit(DrawShapeEvents.canceled, {
|
|
116
|
+
shapeType,
|
|
117
|
+
mapId
|
|
118
|
+
});
|
|
119
|
+
notify();
|
|
120
|
+
}
|
|
121
|
+
/**
|
|
122
|
+
* Draw shape store
|
|
123
|
+
*/
|
|
124
|
+
const drawStore = createMapStore({
|
|
125
|
+
defaultState: { ...DEFAULT_DRAWING_STATE },
|
|
126
|
+
actions: (mapId, { get, set, notify }) => ({
|
|
127
|
+
draw: (shapeType, options) => {
|
|
128
|
+
startDrawing(mapId, get(), shapeType, options, notify, set);
|
|
129
|
+
},
|
|
130
|
+
cancel: () => {
|
|
131
|
+
cancelDrawingInternal(mapId, get(), notify, set);
|
|
132
|
+
}
|
|
133
|
+
}),
|
|
134
|
+
bus: (mapId, { get }) => {
|
|
135
|
+
const unsubAuth = mapModeBus.on(MapModeEvents.changeAuthorization, (event) => {
|
|
136
|
+
const { authId, id } = event.payload;
|
|
137
|
+
if (id !== mapId) return;
|
|
138
|
+
if (get().activeShapeType) mapModeBus.emit(MapModeEvents.changeDecision, {
|
|
139
|
+
authId,
|
|
140
|
+
approved: false,
|
|
141
|
+
owner: DRAW_SHAPE_LAYER_ID,
|
|
142
|
+
reason: "Drawing in progress - cancel drawing first",
|
|
143
|
+
id: mapId
|
|
144
|
+
});
|
|
145
|
+
});
|
|
146
|
+
return () => {
|
|
147
|
+
unsubAuth();
|
|
148
|
+
};
|
|
149
|
+
},
|
|
150
|
+
onCleanup: (mapId, state) => {
|
|
151
|
+
if (state.activeShapeType) {
|
|
152
|
+
releaseModeAndCursor(mapId, DRAW_SHAPE_LAYER_ID);
|
|
153
|
+
drawShapeBus.emit(DrawShapeEvents.canceled, {
|
|
154
|
+
shapeType: state.activeShapeType,
|
|
155
|
+
mapId
|
|
156
|
+
});
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
});
|
|
160
|
+
/**
|
|
161
|
+
* Complete drawing with a feature (called by the layer component)
|
|
162
|
+
*/
|
|
163
|
+
function completeDrawingFromLayer(mapId, feature) {
|
|
164
|
+
return completeDrawingInternal(mapId, drawStore.get(mapId), feature, () => {}, (updates) => drawStore.set(mapId, updates));
|
|
165
|
+
}
|
|
166
|
+
/**
|
|
167
|
+
* Cancel drawing (called by the layer component)
|
|
168
|
+
*/
|
|
169
|
+
function cancelDrawingFromLayer(mapId) {
|
|
170
|
+
drawStore.actions(mapId).cancel();
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
//#endregion
|
|
174
|
+
export { cancelDrawingFromLayer, completeDrawingFromLayer, drawStore };
|
|
175
|
+
//# sourceMappingURL=store.js.map
|