@accelint/map-toolkit 1.4.0 → 2.0.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.
Files changed (204) hide show
  1. package/CHANGELOG.md +45 -0
  2. package/catalog-info.yaml +4 -4
  3. package/dist/camera/events.js +1 -1
  4. package/dist/camera/index.d.ts +1 -1
  5. package/dist/camera/index.js +1 -1
  6. package/dist/camera/store.d.ts +1 -1
  7. package/dist/camera/store.js +4 -6
  8. package/dist/camera/store.js.map +1 -1
  9. package/dist/camera/types.d.ts +1 -1
  10. package/dist/camera/types.js +1 -1
  11. package/dist/cursor-coordinates/constants.js +1 -1
  12. package/dist/cursor-coordinates/index.d.ts +1 -1
  13. package/dist/cursor-coordinates/index.js +1 -1
  14. package/dist/cursor-coordinates/store.d.ts +1 -1
  15. package/dist/cursor-coordinates/store.js +1 -1
  16. package/dist/cursor-coordinates/types.d.ts +1 -1
  17. package/dist/cursor-coordinates/types.js +1 -1
  18. package/dist/cursor-coordinates/use-cursor-coordinates.d.ts +1 -1
  19. package/dist/cursor-coordinates/use-cursor-coordinates.js +4 -9
  20. package/dist/cursor-coordinates/use-cursor-coordinates.js.map +1 -1
  21. package/dist/deckgl/base-map/constants.js +1 -1
  22. package/dist/deckgl/base-map/controls.d.ts +1 -1
  23. package/dist/deckgl/base-map/controls.js +1 -1
  24. package/dist/deckgl/base-map/events.js +1 -1
  25. package/dist/deckgl/base-map/index.d.ts +3 -3
  26. package/dist/deckgl/base-map/index.js +15 -7
  27. package/dist/deckgl/base-map/index.js.map +1 -1
  28. package/dist/deckgl/base-map/provider.d.ts +3 -3
  29. package/dist/deckgl/base-map/provider.js +3 -5
  30. package/dist/deckgl/base-map/provider.js.map +1 -1
  31. package/dist/deckgl/base-map/types.d.ts +1 -1
  32. package/dist/deckgl/base-map/types.js +1 -1
  33. package/dist/deckgl/index.d.ts +4 -4
  34. package/dist/deckgl/index.js +4 -4
  35. package/dist/deckgl/saved-viewports/index.d.ts +1 -1
  36. package/dist/deckgl/saved-viewports/index.js +1 -1
  37. package/dist/deckgl/saved-viewports/storage.d.ts +1 -1
  38. package/dist/deckgl/saved-viewports/storage.js +5 -10
  39. package/dist/deckgl/saved-viewports/storage.js.map +1 -1
  40. package/dist/deckgl/shapes/display-shape-layer/constants.js +66 -13
  41. package/dist/deckgl/shapes/display-shape-layer/constants.js.map +1 -1
  42. package/dist/deckgl/shapes/display-shape-layer/fiber.d.ts +1 -1
  43. package/dist/deckgl/shapes/display-shape-layer/fiber.js +1 -1
  44. package/dist/deckgl/shapes/display-shape-layer/index.d.ts +74 -35
  45. package/dist/deckgl/shapes/display-shape-layer/index.js +381 -154
  46. package/dist/deckgl/shapes/display-shape-layer/index.js.map +1 -1
  47. package/dist/deckgl/shapes/display-shape-layer/shape-label-layer.js +1 -1
  48. package/dist/deckgl/shapes/display-shape-layer/store.js +8 -2
  49. package/dist/deckgl/shapes/display-shape-layer/store.js.map +1 -1
  50. package/dist/deckgl/shapes/display-shape-layer/types.d.ts +108 -19
  51. package/dist/deckgl/shapes/display-shape-layer/types.js +1 -1
  52. package/dist/deckgl/shapes/display-shape-layer/use-select-shape.d.ts +1 -1
  53. package/dist/deckgl/shapes/display-shape-layer/use-select-shape.js +1 -1
  54. package/dist/deckgl/shapes/display-shape-layer/utils/display-style.js +66 -36
  55. package/dist/deckgl/shapes/display-shape-layer/utils/display-style.js.map +1 -1
  56. package/dist/deckgl/shapes/display-shape-layer/utils/elevation.js +407 -0
  57. package/dist/deckgl/shapes/display-shape-layer/utils/elevation.js.map +1 -0
  58. package/dist/deckgl/shapes/display-shape-layer/utils/icon-config.js +151 -0
  59. package/dist/deckgl/shapes/display-shape-layer/utils/icon-config.js.map +1 -0
  60. package/dist/deckgl/shapes/display-shape-layer/utils/interaction.js +50 -0
  61. package/dist/deckgl/shapes/display-shape-layer/utils/interaction.js.map +1 -0
  62. package/dist/deckgl/shapes/display-shape-layer/utils/labels.d.ts +1 -1
  63. package/dist/deckgl/shapes/display-shape-layer/utils/labels.js +28 -39
  64. package/dist/deckgl/shapes/display-shape-layer/utils/labels.js.map +1 -1
  65. package/dist/deckgl/shapes/draw-shape-layer/constants.js +1 -1
  66. package/dist/deckgl/shapes/draw-shape-layer/events.d.ts +1 -1
  67. package/dist/deckgl/shapes/draw-shape-layer/events.js +1 -1
  68. package/dist/deckgl/shapes/draw-shape-layer/fiber.js +1 -1
  69. package/dist/deckgl/shapes/draw-shape-layer/index.d.ts +3 -3
  70. package/dist/deckgl/shapes/draw-shape-layer/index.js +7 -17
  71. package/dist/deckgl/shapes/draw-shape-layer/index.js.map +1 -1
  72. package/dist/deckgl/shapes/draw-shape-layer/modes/draw-circle-mode-with-tooltip.js +8 -9
  73. package/dist/deckgl/shapes/draw-shape-layer/modes/draw-circle-mode-with-tooltip.js.map +1 -1
  74. package/dist/deckgl/shapes/draw-shape-layer/modes/draw-ellipse-mode-with-tooltip.js +3 -3
  75. package/dist/deckgl/shapes/draw-shape-layer/modes/draw-line-string-mode-with-tooltip.js +4 -21
  76. package/dist/deckgl/shapes/draw-shape-layer/modes/draw-line-string-mode-with-tooltip.js.map +1 -1
  77. package/dist/deckgl/shapes/draw-shape-layer/modes/draw-polygon-mode-with-tooltip.js +4 -34
  78. package/dist/deckgl/shapes/draw-shape-layer/modes/draw-polygon-mode-with-tooltip.js.map +1 -1
  79. package/dist/deckgl/shapes/draw-shape-layer/modes/draw-rectangle-mode-with-tooltip.js +11 -12
  80. package/dist/deckgl/shapes/draw-shape-layer/modes/draw-rectangle-mode-with-tooltip.js.map +1 -1
  81. package/dist/deckgl/shapes/draw-shape-layer/modes/index.js +2 -32
  82. package/dist/deckgl/shapes/draw-shape-layer/modes/index.js.map +1 -1
  83. package/dist/deckgl/shapes/draw-shape-layer/store.js +38 -4
  84. package/dist/deckgl/shapes/draw-shape-layer/store.js.map +1 -1
  85. package/dist/deckgl/shapes/draw-shape-layer/types.d.ts +1 -1
  86. package/dist/deckgl/shapes/draw-shape-layer/types.js +1 -1
  87. package/dist/deckgl/shapes/draw-shape-layer/use-draw-shape.d.ts +1 -1
  88. package/dist/deckgl/shapes/draw-shape-layer/use-draw-shape.js +2 -2
  89. package/dist/deckgl/shapes/draw-shape-layer/utils/feature-conversion.js +4 -9
  90. package/dist/deckgl/shapes/draw-shape-layer/utils/feature-conversion.js.map +1 -1
  91. package/dist/deckgl/shapes/edit-shape-layer/constants.js +17 -2
  92. package/dist/deckgl/shapes/edit-shape-layer/constants.js.map +1 -1
  93. package/dist/deckgl/shapes/edit-shape-layer/events.d.ts +1 -1
  94. package/dist/deckgl/shapes/edit-shape-layer/events.js +1 -1
  95. package/dist/deckgl/shapes/edit-shape-layer/fiber.d.ts +1 -1
  96. package/dist/deckgl/shapes/edit-shape-layer/fiber.js +1 -1
  97. package/dist/deckgl/shapes/edit-shape-layer/index.d.ts +7 -4
  98. package/dist/deckgl/shapes/edit-shape-layer/index.js +52 -21
  99. package/dist/deckgl/shapes/edit-shape-layer/index.js.map +1 -1
  100. package/dist/deckgl/shapes/edit-shape-layer/modes/base-transform-mode.js +4 -1
  101. package/dist/deckgl/shapes/edit-shape-layer/modes/base-transform-mode.js.map +1 -1
  102. package/dist/deckgl/shapes/edit-shape-layer/modes/bounding-transform-mode.js +2 -2
  103. package/dist/deckgl/shapes/edit-shape-layer/modes/bounding-transform-mode.js.map +1 -1
  104. package/dist/deckgl/shapes/edit-shape-layer/modes/circle-transform-mode.js +7 -7
  105. package/dist/deckgl/shapes/edit-shape-layer/modes/circle-transform-mode.js.map +1 -1
  106. package/dist/deckgl/shapes/edit-shape-layer/modes/index.js +2 -2
  107. package/dist/deckgl/shapes/edit-shape-layer/modes/index.js.map +1 -1
  108. package/dist/deckgl/shapes/edit-shape-layer/modes/point-translate-mode.js +1 -1
  109. package/dist/deckgl/shapes/edit-shape-layer/modes/point-translate-mode.js.map +1 -1
  110. package/dist/deckgl/shapes/edit-shape-layer/modes/rotate-mode-with-snap.js +2 -2
  111. package/dist/deckgl/shapes/edit-shape-layer/modes/rotate-mode-with-snap.js.map +1 -1
  112. package/dist/deckgl/shapes/edit-shape-layer/modes/scale-mode-with-free-transform.js +1 -1
  113. package/dist/deckgl/shapes/edit-shape-layer/modes/scale-mode-with-free-transform.js.map +1 -1
  114. package/dist/deckgl/shapes/edit-shape-layer/modes/vertex-transform-mode.js +1 -1
  115. package/dist/deckgl/shapes/edit-shape-layer/modes/vertex-transform-mode.js.map +1 -1
  116. package/dist/deckgl/shapes/edit-shape-layer/store.js +78 -14
  117. package/dist/deckgl/shapes/edit-shape-layer/store.js.map +1 -1
  118. package/dist/deckgl/shapes/edit-shape-layer/types.d.ts +14 -2
  119. package/dist/deckgl/shapes/edit-shape-layer/types.js +1 -1
  120. package/dist/deckgl/shapes/edit-shape-layer/use-edit-shape.d.ts +1 -1
  121. package/dist/deckgl/shapes/edit-shape-layer/use-edit-shape.js +2 -2
  122. package/dist/deckgl/shapes/index.d.ts +4 -4
  123. package/dist/deckgl/shapes/index.js +5 -5
  124. package/dist/deckgl/shapes/shared/constants.d.ts +4 -3
  125. package/dist/deckgl/shapes/shared/constants.js +55 -15
  126. package/dist/deckgl/shapes/shared/constants.js.map +1 -1
  127. package/dist/deckgl/shapes/shared/events.d.ts +5 -1
  128. package/dist/deckgl/shapes/shared/events.js +1 -1
  129. package/dist/deckgl/shapes/shared/events.js.map +1 -1
  130. package/dist/deckgl/shapes/shared/hooks/use-shift-zoom-disable.js +19 -16
  131. package/dist/deckgl/shapes/shared/hooks/use-shift-zoom-disable.js.map +1 -1
  132. package/dist/deckgl/shapes/shared/types.d.ts +174 -53
  133. package/dist/deckgl/shapes/shared/types.js +155 -2
  134. package/dist/deckgl/shapes/shared/types.js.map +1 -1
  135. package/dist/deckgl/shapes/shared/utils/geometry-measurements.js +29 -24
  136. package/dist/deckgl/shapes/shared/utils/geometry-measurements.js.map +1 -1
  137. package/dist/deckgl/shapes/shared/utils/layer-config.js +9 -6
  138. package/dist/deckgl/shapes/shared/utils/layer-config.js.map +1 -1
  139. package/dist/deckgl/shapes/shared/utils/mode-utils.js +50 -20
  140. package/dist/deckgl/shapes/shared/utils/mode-utils.js.map +1 -1
  141. package/dist/deckgl/shapes/shared/utils/pick-filtering.js +22 -15
  142. package/dist/deckgl/shapes/shared/utils/pick-filtering.js.map +1 -1
  143. package/dist/deckgl/shapes/shared/utils/style-utils.d.ts +38 -14
  144. package/dist/deckgl/shapes/shared/utils/style-utils.js +43 -32
  145. package/dist/deckgl/shapes/shared/utils/style-utils.js.map +1 -1
  146. package/dist/deckgl/symbol-layer/fiber.d.ts +1 -1
  147. package/dist/deckgl/symbol-layer/fiber.js +1 -1
  148. package/dist/deckgl/symbol-layer/index.d.ts +1 -1
  149. package/dist/deckgl/symbol-layer/index.js +1 -1
  150. package/dist/deckgl/text-layer/character-sets.js +1 -1
  151. package/dist/deckgl/text-layer/default-settings.d.ts +1 -1
  152. package/dist/deckgl/text-layer/default-settings.js +1 -1
  153. package/dist/deckgl/text-layer/fiber.d.ts +1 -1
  154. package/dist/deckgl/text-layer/fiber.js +1 -1
  155. package/dist/deckgl/text-layer/index.d.ts +1 -1
  156. package/dist/deckgl/text-layer/index.js +1 -1
  157. package/dist/deckgl/text-settings.d.ts +3 -3
  158. package/dist/deckgl/text-settings.js +1 -1
  159. package/dist/map-cursor/events.js +1 -1
  160. package/dist/map-cursor/index.d.ts +1 -1
  161. package/dist/map-cursor/index.js +1 -1
  162. package/dist/map-cursor/store.d.ts +1 -1
  163. package/dist/map-cursor/store.js +1 -1
  164. package/dist/map-cursor/types.d.ts +1 -1
  165. package/dist/map-cursor/types.js +1 -1
  166. package/dist/map-cursor/use-map-cursor.d.ts +1 -1
  167. package/dist/map-cursor/use-map-cursor.js +1 -1
  168. package/dist/map-mode/events.js +1 -1
  169. package/dist/map-mode/index.d.ts +1 -1
  170. package/dist/map-mode/index.js +1 -1
  171. package/dist/map-mode/store.d.ts +1 -1
  172. package/dist/map-mode/store.js +3 -8
  173. package/dist/map-mode/store.js.map +1 -1
  174. package/dist/map-mode/types.d.ts +1 -1
  175. package/dist/map-mode/types.js +1 -1
  176. package/dist/map-mode/use-map-mode.d.ts +1 -1
  177. package/dist/map-mode/use-map-mode.js +1 -1
  178. package/dist/maplibre/hooks/use-maplibre.d.ts +1 -1
  179. package/dist/maplibre/hooks/use-maplibre.js +1 -1
  180. package/dist/maplibre/index.d.ts +1 -1
  181. package/dist/maplibre/index.js +1 -1
  182. package/dist/shared/cleanup.d.ts +58 -0
  183. package/dist/shared/cleanup.js +93 -0
  184. package/dist/shared/cleanup.js.map +1 -0
  185. package/dist/shared/constants.js +1 -1
  186. package/dist/shared/create-map-store.d.ts +13 -1
  187. package/dist/shared/create-map-store.js +9 -4
  188. package/dist/shared/create-map-store.js.map +1 -1
  189. package/dist/shared/logger.js +31 -0
  190. package/dist/shared/logger.js.map +1 -0
  191. package/dist/shared/units.js +1 -1
  192. package/dist/viewport/index.d.ts +1 -1
  193. package/dist/viewport/index.js +1 -1
  194. package/dist/viewport/store.d.ts +1 -1
  195. package/dist/viewport/store.js +1 -1
  196. package/dist/viewport/types.d.ts +1 -1
  197. package/dist/viewport/types.js +1 -1
  198. package/dist/viewport/utils.d.ts +1 -1
  199. package/dist/viewport/utils.js +1 -1
  200. package/dist/viewport/viewport-size.d.ts +3 -3
  201. package/dist/viewport/viewport-size.js +1 -1
  202. package/package.json +22 -19
  203. package/dist/hotkey-manager/dist/react/use-hotkey.js +0 -39
  204. package/dist/hotkey-manager/dist/react/use-hotkey.js.map +0 -1
@@ -1,5 +1,5 @@
1
1
  /*
2
- * Copyright 2025 Hypergiant Galactic Systems Inc. All rights reserved.
2
+ * Copyright 2026 Hypergiant Galactic Systems Inc. All rights reserved.
3
3
  * This file is licensed to you under the Apache License, Version 2.0 (the "License");
4
4
  * you may not use this file except in compliance with the License. You may obtain a copy
5
5
  * of the License at https://www.apache.org/licenses/LICENSE-2.0
@@ -11,18 +11,16 @@
11
11
  */
12
12
 
13
13
 
14
- 'use client';
15
-
16
- import { distance, point } from "@turf/turf";
14
+ import { distance } from "@turf/turf";
17
15
 
18
16
  //#region src/deckgl/shapes/shared/utils/geometry-measurements.ts
19
17
  /**
20
18
  * Compute circle measurements from center and edge point.
21
19
  *
22
- * @param center - Center point as [longitude, latitude]
23
- * @param edgePoint - Point on the circle's edge as [longitude, latitude]
24
- * @param units - Distance units for the measurements
25
- * @returns Circle measurements including radius, diameter, and area
20
+ * @param center - Center point as [longitude, latitude].
21
+ * @param edgePoint - Point on the circle's edge as [longitude, latitude].
22
+ * @param units - Distance units for the measurements.
23
+ * @returns Circle measurements including radius, diameter, and area.
26
24
  *
27
25
  * @example
28
26
  * ```typescript
@@ -49,11 +47,11 @@ function computeCircleMeasurements(center, edgePoint, units) {
49
47
  * - corner0 to corner1 defines one edge (width)
50
48
  * - corner1 to corner2 defines the adjacent edge (height)
51
49
  *
52
- * @param corner0 - First corner as [longitude, latitude]
53
- * @param corner1 - Adjacent corner as [longitude, latitude]
54
- * @param corner2 - Corner adjacent to corner1 as [longitude, latitude]
55
- * @param units - Distance units for the measurements
56
- * @returns Rectangle measurements including width, height, and area
50
+ * @param corner0 - First corner as [longitude, latitude].
51
+ * @param corner1 - Adjacent corner as [longitude, latitude].
52
+ * @param corner2 - Corner adjacent to corner1 as [longitude, latitude].
53
+ * @param units - Distance units for the measurements.
54
+ * @returns Rectangle measurements including width, height, and area.
57
55
  *
58
56
  * @example
59
57
  * ```typescript
@@ -67,8 +65,9 @@ function computeCircleMeasurements(center, edgePoint, units) {
67
65
  * ```
68
66
  */
69
67
  function computeRectangleMeasurementsFromCorners(corner0, corner1, corner2, units) {
70
- const width = distance(point(corner0), point(corner1), { units });
71
- const height = distance(point(corner1), point(corner2), { units });
68
+ const options = { units };
69
+ const width = distance(corner0, corner1, options);
70
+ const height = distance(corner1, corner2, options);
72
71
  return {
73
72
  width,
74
73
  height,
@@ -81,9 +80,9 @@ function computeRectangleMeasurementsFromCorners(corner0, corner1, corner2, unit
81
80
  * For an ellipse approximated as a polygon, calculates the major and minor axes
82
81
  * by measuring distances between opposite points on the perimeter.
83
82
  *
84
- * @param coordinates - Polygon ring coordinates as [[lon, lat], ...]
85
- * @param units - Distance units for the measurements
86
- * @returns Ellipse measurements including axes and area
83
+ * @param coordinates - Polygon ring coordinates as [[lon, lat], ...].
84
+ * @param units - Distance units for the measurements.
85
+ * @returns Ellipse measurements including axes and area.
87
86
  *
88
87
  * @example
89
88
  * ```typescript
@@ -95,20 +94,24 @@ function computeRectangleMeasurementsFromCorners(corner0, corner1, corner2, unit
95
94
  * ```
96
95
  */
97
96
  function computeEllipseMeasurementsFromPolygon(coordinates, units) {
98
- const points = coordinates[0]?.[0] === coordinates[coordinates.length - 1]?.[0] && coordinates[0]?.[1] === coordinates[coordinates.length - 1]?.[1] ? coordinates.slice(0, -1) : coordinates;
99
- if (points.length < 4) return {
97
+ const len = coordinates.length;
98
+ const pointCount = len > 0 && coordinates[0]?.[0] === coordinates[len - 1]?.[0] && coordinates[0]?.[1] === coordinates[len - 1]?.[1] ? len - 1 : len;
99
+ if (pointCount < 4) return {
100
+ xSemiAxis: 0,
101
+ ySemiAxis: 0,
100
102
  majorAxis: 0,
101
103
  minorAxis: 0,
102
104
  area: 0
103
105
  };
104
- const halfLen = Math.floor(points.length / 2);
106
+ const halfLen = Math.floor(pointCount / 2);
107
+ const options = { units };
105
108
  let maxDist = 0;
106
109
  let minDist = Number.POSITIVE_INFINITY;
107
110
  for (let i = 0; i < halfLen; i++) {
108
- const p1 = points[i];
109
- const p2 = points[i + halfLen];
111
+ const p1 = coordinates[i];
112
+ const p2 = coordinates[i + halfLen];
110
113
  if (!(p1 && p2)) continue;
111
- const dist = distance([p1[0], p1[1]], [p2[0], p2[1]], { units });
114
+ const dist = distance(p1, p2, options);
112
115
  if (dist > maxDist) maxDist = dist;
113
116
  if (dist < minDist) minDist = dist;
114
117
  }
@@ -117,6 +120,8 @@ function computeEllipseMeasurementsFromPolygon(coordinates, units) {
117
120
  const semiMajor = majorAxis / 2;
118
121
  const semiMinor = minorAxis / 2;
119
122
  return {
123
+ xSemiAxis: semiMajor,
124
+ ySemiAxis: semiMinor,
120
125
  majorAxis,
121
126
  minorAxis,
122
127
  area: Math.PI * semiMajor * semiMinor
@@ -1 +1 @@
1
- {"version":3,"file":"geometry-measurements.js","names":[],"sources":["../../../../../src/deckgl/shapes/shared/utils/geometry-measurements.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\nimport { distance, point } from '@turf/turf';\nimport type { DistanceUnit } from '@/shared/units';\n\n/**\n * Circle measurement result containing radius, diameter, and area.\n */\nexport interface CircleMeasurements {\n /** Radius in the specified units */\n radius: number;\n /** Diameter (radius * 2) in the specified units */\n diameter: number;\n /** Area (π * radius²) in the specified units squared */\n area: number;\n}\n\n/**\n * Ellipse measurement result containing semi-axes and area.\n */\nexport interface EllipseMeasurements {\n /** X semi-axis (horizontal radius) in the specified units */\n xSemiAxis: number;\n /** Y semi-axis (vertical radius) in the specified units */\n ySemiAxis: number;\n /** Major axis (full length of longer axis) in the specified units */\n majorAxis: number;\n /** Minor axis (full length of shorter axis) in the specified units */\n minorAxis: number;\n /** Area (π * xSemiAxis * ySemiAxis) in the specified units squared */\n area: number;\n}\n\n/**\n * Rectangle measurement result containing width, height, and area.\n */\nexport interface RectangleMeasurements {\n /** Width in the specified units */\n width: number;\n /** Height in the specified units */\n height: number;\n /** Area (width * height) in the specified units squared */\n area: number;\n}\n\n/**\n * Compute circle measurements from center and edge point.\n *\n * @param center - Center point as [longitude, latitude]\n * @param edgePoint - Point on the circle's edge as [longitude, latitude]\n * @param units - Distance units for the measurements\n * @returns Circle measurements including radius, diameter, and area\n *\n * @example\n * ```typescript\n * const { radius, diameter, area } = computeCircleMeasurements(\n * [-122.4, 37.8],\n * [-122.3, 37.8],\n * 'kilometers'\n * );\n * ```\n */\nexport function computeCircleMeasurements(\n center: [number, number],\n edgePoint: [number, number],\n units: DistanceUnit,\n): CircleMeasurements {\n const radius = distance(center, edgePoint, { units });\n const diameter = radius * 2;\n const area = Math.PI * radius ** 2;\n\n return { radius, diameter, area };\n}\n\n/**\n * Compute ellipse measurements from center and semi-axis lengths.\n *\n * @param xSemiAxis - X semi-axis (horizontal radius) in the specified units\n * @param ySemiAxis - Y semi-axis (vertical radius) in the specified units\n * @returns Ellipse measurements including axes and area\n *\n * @example\n * ```typescript\n * const { majorAxis, minorAxis, area } = computeEllipseMeasurementsFromAxes(100, 50);\n * ```\n */\nexport function computeEllipseMeasurementsFromAxes(\n xSemiAxis: number,\n ySemiAxis: number,\n): EllipseMeasurements {\n const majorAxis = Math.max(xSemiAxis, ySemiAxis) * 2;\n const minorAxis = Math.min(xSemiAxis, ySemiAxis) * 2;\n const area = Math.PI * xSemiAxis * ySemiAxis;\n\n return { xSemiAxis, ySemiAxis, majorAxis, minorAxis, area };\n}\n\n/**\n * Compute rectangle measurements from adjacent corner points.\n *\n * Uses geodesic distance calculations for accurate measurements on Earth's surface.\n * Corners should be provided in order: corner0 -> corner1 -> corner2 where:\n * - corner0 to corner1 defines one edge (width)\n * - corner1 to corner2 defines the adjacent edge (height)\n *\n * @param corner0 - First corner as [longitude, latitude]\n * @param corner1 - Adjacent corner as [longitude, latitude]\n * @param corner2 - Corner adjacent to corner1 as [longitude, latitude]\n * @param units - Distance units for the measurements\n * @returns Rectangle measurements including width, height, and area\n *\n * @example\n * ```typescript\n * const coords = polygon.geometry.coordinates[0];\n * const { width, height, area } = computeRectangleMeasurementsFromCorners(\n * coords[0] as [number, number],\n * coords[1] as [number, number],\n * coords[2] as [number, number],\n * 'kilometers'\n * );\n * ```\n */\nexport function computeRectangleMeasurementsFromCorners(\n corner0: [number, number],\n corner1: [number, number],\n corner2: [number, number],\n units: DistanceUnit,\n): RectangleMeasurements {\n const width = distance(point(corner0), point(corner1), { units });\n const height = distance(point(corner1), point(corner2), { units });\n const area = width * height;\n\n return { width, height, area };\n}\n\n/**\n * Compute ellipse measurements from polygon coordinates.\n *\n * For an ellipse approximated as a polygon, calculates the major and minor axes\n * by measuring distances between opposite points on the perimeter.\n *\n * @param coordinates - Polygon ring coordinates as [[lon, lat], ...]\n * @param units - Distance units for the measurements\n * @returns Ellipse measurements including axes and area\n *\n * @example\n * ```typescript\n * const coords = polygon.geometry.coordinates[0];\n * const { majorAxis, minorAxis, area } = computeEllipseMeasurementsFromPolygon(\n * coords as [number, number][],\n * 'kilometers'\n * );\n * ```\n */\nexport function computeEllipseMeasurementsFromPolygon(\n coordinates: [number, number][],\n units: DistanceUnit,\n): { majorAxis: number; minorAxis: number; area: number } {\n // Remove the closing point if it duplicates the first\n const points =\n coordinates[0]?.[0] === coordinates[coordinates.length - 1]?.[0] &&\n coordinates[0]?.[1] === coordinates[coordinates.length - 1]?.[1]\n ? coordinates.slice(0, -1)\n : coordinates;\n\n if (points.length < 4) {\n return { majorAxis: 0, minorAxis: 0, area: 0 };\n }\n\n // For an ellipse polygon, opposite points are at index i and i + n/2\n const halfLen = Math.floor(points.length / 2);\n let maxDist = 0;\n let minDist = Number.POSITIVE_INFINITY;\n\n // Sample several diameter measurements\n for (let i = 0; i < halfLen; i++) {\n const p1 = points[i];\n const p2 = points[i + halfLen];\n if (!(p1 && p2)) {\n continue;\n }\n\n const dist = distance(\n [p1[0] as number, p1[1] as number],\n [p2[0] as number, p2[1] as number],\n { units },\n );\n\n if (dist > maxDist) {\n maxDist = dist;\n }\n if (dist < minDist) {\n minDist = dist;\n }\n }\n\n const majorAxis = maxDist;\n const minorAxis = minDist === Number.POSITIVE_INFINITY ? maxDist : minDist;\n\n // Ellipse area = π × a × b (where a and b are semi-axes)\n const semiMajor = majorAxis / 2;\n const semiMinor = minorAxis / 2;\n const ellipseArea = Math.PI * semiMajor * semiMinor;\n\n return { majorAxis, minorAxis, area: ellipseArea };\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA0EA,SAAgB,0BACd,QACA,WACA,OACoB;CACpB,MAAM,SAAS,SAAS,QAAQ,WAAW,EAAE,OAAO,CAAC;AAIrD,QAAO;EAAE;EAAQ,UAHA,SAAS;EAGC,MAFd,KAAK,KAAK,UAAU;EAEA;;;;;;;;;;;;;;;;;;;;;;;;;;;AAmDnC,SAAgB,wCACd,SACA,SACA,SACA,OACuB;CACvB,MAAM,QAAQ,SAAS,MAAM,QAAQ,EAAE,MAAM,QAAQ,EAAE,EAAE,OAAO,CAAC;CACjE,MAAM,SAAS,SAAS,MAAM,QAAQ,EAAE,MAAM,QAAQ,EAAE,EAAE,OAAO,CAAC;AAGlE,QAAO;EAAE;EAAO;EAAQ,MAFX,QAAQ;EAES;;;;;;;;;;;;;;;;;;;;;AAsBhC,SAAgB,sCACd,aACA,OACwD;CAExD,MAAM,SACJ,YAAY,KAAK,OAAO,YAAY,YAAY,SAAS,KAAK,MAC9D,YAAY,KAAK,OAAO,YAAY,YAAY,SAAS,KAAK,KAC1D,YAAY,MAAM,GAAG,GAAG,GACxB;AAEN,KAAI,OAAO,SAAS,EAClB,QAAO;EAAE,WAAW;EAAG,WAAW;EAAG,MAAM;EAAG;CAIhD,MAAM,UAAU,KAAK,MAAM,OAAO,SAAS,EAAE;CAC7C,IAAI,UAAU;CACd,IAAI,UAAU,OAAO;AAGrB,MAAK,IAAI,IAAI,GAAG,IAAI,SAAS,KAAK;EAChC,MAAM,KAAK,OAAO;EAClB,MAAM,KAAK,OAAO,IAAI;AACtB,MAAI,EAAE,MAAM,IACV;EAGF,MAAM,OAAO,SACX,CAAC,GAAG,IAAc,GAAG,GAAa,EAClC,CAAC,GAAG,IAAc,GAAG,GAAa,EAClC,EAAE,OAAO,CACV;AAED,MAAI,OAAO,QACT,WAAU;AAEZ,MAAI,OAAO,QACT,WAAU;;CAId,MAAM,YAAY;CAClB,MAAM,YAAY,YAAY,OAAO,oBAAoB,UAAU;CAGnE,MAAM,YAAY,YAAY;CAC9B,MAAM,YAAY,YAAY;AAG9B,QAAO;EAAE;EAAW;EAAW,MAFX,KAAK,KAAK,YAAY;EAEQ"}
1
+ {"version":3,"file":"geometry-measurements.js","names":[],"sources":["../../../../../src/deckgl/shapes/shared/utils/geometry-measurements.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 { distance } from '@turf/turf';\nimport type { DistanceUnit } from '@/shared/units';\n\n/**\n * Circle measurement result containing radius, diameter, and area.\n */\nexport type CircleMeasurements = {\n /** Radius in the specified units. */\n radius: number;\n /** Diameter (radius * 2) in the specified units. */\n diameter: number;\n /** Area (π * radius²) in the specified units squared. */\n area: number;\n};\n\n/**\n * Ellipse measurement result containing semi-axes and area.\n */\nexport type EllipseMeasurements = {\n /** X semi-axis (horizontal radius) in the specified units. */\n xSemiAxis: number;\n /** Y semi-axis (vertical radius) in the specified units. */\n ySemiAxis: number;\n /** Major axis (full length of longer axis) in the specified units. */\n majorAxis: number;\n /** Minor axis (full length of shorter axis) in the specified units. */\n minorAxis: number;\n /** Area (π * xSemiAxis * ySemiAxis) in the specified units squared. */\n area: number;\n};\n\n/**\n * Rectangle measurement result containing width, height, and area.\n */\nexport type RectangleMeasurements = {\n /** Width in the specified units. */\n width: number;\n /** Height in the specified units. */\n height: number;\n /** Area (width * height) in the specified units squared. */\n area: number;\n};\n\n/**\n * Compute circle measurements from center and edge point.\n *\n * @param center - Center point as [longitude, latitude].\n * @param edgePoint - Point on the circle's edge as [longitude, latitude].\n * @param units - Distance units for the measurements.\n * @returns Circle measurements including radius, diameter, and area.\n *\n * @example\n * ```typescript\n * const { radius, diameter, area } = computeCircleMeasurements(\n * [-122.4, 37.8],\n * [-122.3, 37.8],\n * 'kilometers'\n * );\n * ```\n */\nexport function computeCircleMeasurements(\n center: [number, number],\n edgePoint: [number, number],\n units: DistanceUnit,\n): CircleMeasurements {\n const radius = distance(center, edgePoint, { units });\n const diameter = radius * 2;\n const area = Math.PI * radius ** 2;\n\n return { radius, diameter, area };\n}\n\n/**\n * Compute ellipse measurements from semi-axis lengths.\n *\n * @param xSemiAxis - X semi-axis (horizontal radius) in the specified units.\n * @param ySemiAxis - Y semi-axis (vertical radius) in the specified units.\n * @returns Ellipse measurements including axes and area.\n *\n * @example\n * ```typescript\n * const { majorAxis, minorAxis, area } = computeEllipseMeasurementsFromAxes(100, 50);\n * ```\n */\nexport function computeEllipseMeasurementsFromAxes(\n xSemiAxis: number,\n ySemiAxis: number,\n): EllipseMeasurements {\n const majorAxis = Math.max(xSemiAxis, ySemiAxis) * 2;\n const minorAxis = Math.min(xSemiAxis, ySemiAxis) * 2;\n const area = Math.PI * xSemiAxis * ySemiAxis;\n\n return { xSemiAxis, ySemiAxis, majorAxis, minorAxis, area };\n}\n\n/**\n * Compute rectangle measurements from adjacent corner points.\n *\n * Uses geodesic distance calculations for accurate measurements on Earth's surface.\n * Corners should be provided in order: corner0 -> corner1 -> corner2 where:\n * - corner0 to corner1 defines one edge (width)\n * - corner1 to corner2 defines the adjacent edge (height)\n *\n * @param corner0 - First corner as [longitude, latitude].\n * @param corner1 - Adjacent corner as [longitude, latitude].\n * @param corner2 - Corner adjacent to corner1 as [longitude, latitude].\n * @param units - Distance units for the measurements.\n * @returns Rectangle measurements including width, height, and area.\n *\n * @example\n * ```typescript\n * const coords = polygon.geometry.coordinates[0];\n * const { width, height, area } = computeRectangleMeasurementsFromCorners(\n * coords[0] as [number, number],\n * coords[1] as [number, number],\n * coords[2] as [number, number],\n * 'kilometers'\n * );\n * ```\n */\nexport function computeRectangleMeasurementsFromCorners(\n corner0: [number, number],\n corner1: [number, number],\n corner2: [number, number],\n units: DistanceUnit,\n): RectangleMeasurements {\n const options = { units };\n const width = distance(corner0, corner1, options);\n const height = distance(corner1, corner2, options);\n const area = width * height;\n\n return { width, height, area };\n}\n\n/**\n * Compute ellipse measurements from polygon coordinates.\n *\n * For an ellipse approximated as a polygon, calculates the major and minor axes\n * by measuring distances between opposite points on the perimeter.\n *\n * @param coordinates - Polygon ring coordinates as [[lon, lat], ...].\n * @param units - Distance units for the measurements.\n * @returns Ellipse measurements including axes and area.\n *\n * @example\n * ```typescript\n * const coords = polygon.geometry.coordinates[0];\n * const { majorAxis, minorAxis, area } = computeEllipseMeasurementsFromPolygon(\n * coords as [number, number][],\n * 'kilometers'\n * );\n * ```\n */\nexport function computeEllipseMeasurementsFromPolygon(\n coordinates: [number, number][],\n units: DistanceUnit,\n): EllipseMeasurements {\n // Determine effective point count without allocating a new array\n const len = coordinates.length;\n const isClosed =\n len > 0 &&\n coordinates[0]?.[0] === coordinates[len - 1]?.[0] &&\n coordinates[0]?.[1] === coordinates[len - 1]?.[1];\n const pointCount = isClosed ? len - 1 : len;\n\n if (pointCount < 4) {\n return { xSemiAxis: 0, ySemiAxis: 0, majorAxis: 0, minorAxis: 0, area: 0 };\n }\n\n // For an ellipse polygon, opposite points are at index i and i + n/2\n const halfLen = Math.floor(pointCount / 2);\n const options = { units };\n let maxDist = 0;\n let minDist = Number.POSITIVE_INFINITY;\n\n // Sample several diameter measurements\n for (let i = 0; i < halfLen; i++) {\n const p1 = coordinates[i];\n const p2 = coordinates[i + halfLen];\n if (!(p1 && p2)) {\n continue;\n }\n\n const dist = distance(p1, p2, options);\n\n if (dist > maxDist) {\n maxDist = dist;\n }\n if (dist < minDist) {\n minDist = dist;\n }\n }\n\n const majorAxis = maxDist;\n const minorAxis = minDist === Number.POSITIVE_INFINITY ? maxDist : minDist;\n\n // Ellipse area = π × a × b (where a and b are semi-axes)\n const semiMajor = majorAxis / 2;\n const semiMinor = minorAxis / 2;\n const area = Math.PI * semiMajor * semiMinor;\n\n return {\n xSemiAxis: semiMajor,\n ySemiAxis: semiMinor,\n majorAxis,\n minorAxis,\n area,\n };\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAwEA,SAAgB,0BACd,QACA,WACA,OACoB;CACpB,MAAM,SAAS,SAAS,QAAQ,WAAW,EAAE,OAAO,CAAC;AAIrD,QAAO;EAAE;EAAQ,UAHA,SAAS;EAGC,MAFd,KAAK,KAAK,UAAU;EAEA;;;;;;;;;;;;;;;;;;;;;;;;;;;AAmDnC,SAAgB,wCACd,SACA,SACA,SACA,OACuB;CACvB,MAAM,UAAU,EAAE,OAAO;CACzB,MAAM,QAAQ,SAAS,SAAS,SAAS,QAAQ;CACjD,MAAM,SAAS,SAAS,SAAS,SAAS,QAAQ;AAGlD,QAAO;EAAE;EAAO;EAAQ,MAFX,QAAQ;EAES;;;;;;;;;;;;;;;;;;;;;AAsBhC,SAAgB,sCACd,aACA,OACqB;CAErB,MAAM,MAAM,YAAY;CAKxB,MAAM,aAHJ,MAAM,KACN,YAAY,KAAK,OAAO,YAAY,MAAM,KAAK,MAC/C,YAAY,KAAK,OAAO,YAAY,MAAM,KAAK,KACnB,MAAM,IAAI;AAExC,KAAI,aAAa,EACf,QAAO;EAAE,WAAW;EAAG,WAAW;EAAG,WAAW;EAAG,WAAW;EAAG,MAAM;EAAG;CAI5E,MAAM,UAAU,KAAK,MAAM,aAAa,EAAE;CAC1C,MAAM,UAAU,EAAE,OAAO;CACzB,IAAI,UAAU;CACd,IAAI,UAAU,OAAO;AAGrB,MAAK,IAAI,IAAI,GAAG,IAAI,SAAS,KAAK;EAChC,MAAM,KAAK,YAAY;EACvB,MAAM,KAAK,YAAY,IAAI;AAC3B,MAAI,EAAE,MAAM,IACV;EAGF,MAAM,OAAO,SAAS,IAAI,IAAI,QAAQ;AAEtC,MAAI,OAAO,QACT,WAAU;AAEZ,MAAI,OAAO,QACT,WAAU;;CAId,MAAM,YAAY;CAClB,MAAM,YAAY,YAAY,OAAO,oBAAoB,UAAU;CAGnE,MAAM,YAAY,YAAY;CAC9B,MAAM,YAAY,YAAY;AAG9B,QAAO;EACL,WAAW;EACX,WAAW;EACX;EACA;EACA,MAPW,KAAK,KAAK,YAAY;EAQlC"}
@@ -1,5 +1,5 @@
1
1
  /*
2
- * Copyright 2025 Hypergiant Galactic Systems Inc. All rights reserved.
2
+ * Copyright 2026 Hypergiant Galactic Systems Inc. All rights reserved.
3
3
  * This file is licensed to you under the Apache License, Version 2.0 (the "License");
4
4
  * you may not use this file except in compliance with the License. You may obtain a copy
5
5
  * of the License at https://www.apache.org/licenses/LICENSE-2.0
@@ -11,12 +11,12 @@
11
11
  */
12
12
 
13
13
 
14
- 'use client';
15
-
16
- import { DEFAULT_EDIT_HANDLE_COLOR, EDITABLE_LAYER_SUBLAYER_PROPS } from "../constants.js";
17
14
  import { DEFAULT_DISTANCE_UNITS, getDistanceUnitFromAbbreviation } from "../../../../shared/units.js";
15
+ import { DEFAULT_EDIT_HANDLE_COLOR, EDITABLE_LAYER_SUBLAYER_PROPS } from "../constants.js";
18
16
 
19
17
  //#region src/deckgl/shapes/shared/utils/layer-config.ts
18
+ let cachedAbbrev = null;
19
+ let cachedProps;
20
20
  /**
21
21
  * Returns default props for EditableGeoJsonLayer configuration.
22
22
  *
@@ -26,7 +26,7 @@ import { DEFAULT_DISTANCE_UNITS, getDistanceUnitFromAbbreviation } from "../../.
26
26
  * - Sublayer props for tooltips and handles
27
27
  *
28
28
  * @param unitAbbrev - Optional unit abbreviation (e.g., 'km', 'mi'). Defaults to DEFAULT_DISTANCE_UNITS.
29
- * @returns Default props to spread onto EditableGeoJsonLayer
29
+ * @returns Default props to spread onto EditableGeoJsonLayer.
30
30
  *
31
31
  * @example
32
32
  * ```tsx
@@ -37,12 +37,15 @@ import { DEFAULT_DISTANCE_UNITS, getDistanceUnitFromAbbreviation } from "../../.
37
37
  * ```
38
38
  */
39
39
  function getDefaultEditableLayerProps(unitAbbrev) {
40
- return {
40
+ if (cachedAbbrev !== null && cachedAbbrev === unitAbbrev && cachedProps) return cachedProps;
41
+ cachedAbbrev = unitAbbrev;
42
+ cachedProps = {
41
43
  getEditHandlePointColor: DEFAULT_EDIT_HANDLE_COLOR,
42
44
  getEditHandlePointOutlineColor: DEFAULT_EDIT_HANDLE_COLOR,
43
45
  modeConfig: { distanceUnits: unitAbbrev ? getDistanceUnitFromAbbreviation(unitAbbrev) ?? DEFAULT_DISTANCE_UNITS : DEFAULT_DISTANCE_UNITS },
44
46
  _subLayerProps: EDITABLE_LAYER_SUBLAYER_PROPS
45
47
  };
48
+ return cachedProps;
46
49
  }
47
50
 
48
51
  //#endregion
@@ -1 +1 @@
1
- {"version":3,"file":"layer-config.js","names":[],"sources":["../../../../../src/deckgl/shapes/shared/utils/layer-config.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\nimport {\n DEFAULT_DISTANCE_UNITS,\n getDistanceUnitFromAbbreviation,\n} from '@/shared/units';\nimport {\n DEFAULT_EDIT_HANDLE_COLOR,\n EDITABLE_LAYER_SUBLAYER_PROPS,\n} from '../constants';\nimport type { Color } from '@deck.gl/core';\nimport type { DistanceUnit } from '@/shared/units';\n\n/**\n * Props returned by getDefaultEditableLayerProps.\n * These are common configuration props shared between DrawShapeLayer and EditShapeLayer.\n */\nexport interface EditableLayerDefaultProps {\n /** Edit handle point color */\n getEditHandlePointColor: Color;\n /** Edit handle point outline color */\n getEditHandlePointOutlineColor: Color;\n /** Mode configuration with distance units */\n modeConfig: {\n distanceUnits: DistanceUnit;\n };\n /** Sublayer props for tooltips and edit handles */\n _subLayerProps: typeof EDITABLE_LAYER_SUBLAYER_PROPS;\n}\n\n/**\n * Returns default props for EditableGeoJsonLayer configuration.\n *\n * This consolidates the common configuration shared between DrawShapeLayer and EditShapeLayer:\n * - Edit handle colors\n * - Mode configuration with distance units\n * - Sublayer props for tooltips and handles\n *\n * @param unitAbbrev - Optional unit abbreviation (e.g., 'km', 'mi'). Defaults to DEFAULT_DISTANCE_UNITS.\n * @returns Default props to spread onto EditableGeoJsonLayer\n *\n * @example\n * ```tsx\n * <editableGeoJsonLayer\n * {...getDefaultEditableLayerProps(unit)}\n * // other props\n * />\n * ```\n */\nexport function getDefaultEditableLayerProps(\n unitAbbrev?: string,\n): EditableLayerDefaultProps {\n return {\n getEditHandlePointColor: DEFAULT_EDIT_HANDLE_COLOR,\n getEditHandlePointOutlineColor: DEFAULT_EDIT_HANDLE_COLOR,\n modeConfig: {\n distanceUnits: unitAbbrev\n ? (getDistanceUnitFromAbbreviation(unitAbbrev) ??\n DEFAULT_DISTANCE_UNITS)\n : DEFAULT_DISTANCE_UNITS,\n },\n // biome-ignore lint/style/useNamingConvention: deck.gl API convention\n _subLayerProps: EDITABLE_LAYER_SUBLAYER_PROPS,\n };\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA6DA,SAAgB,6BACd,YAC2B;AAC3B,QAAO;EACL,yBAAyB;EACzB,gCAAgC;EAChC,YAAY,EACV,eAAe,aACV,gCAAgC,WAAW,IAC5C,yBACA,wBACL;EAED,gBAAgB;EACjB"}
1
+ {"version":3,"file":"layer-config.js","names":["cachedAbbrev: DistanceUnitAbbreviation | undefined | null","cachedProps: EditableLayerDefaultProps | undefined"],"sources":["../../../../../src/deckgl/shapes/shared/utils/layer-config.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 DEFAULT_DISTANCE_UNITS,\n type DistanceUnit,\n type DistanceUnitAbbreviation,\n getDistanceUnitFromAbbreviation,\n} from '@/shared/units';\nimport {\n DEFAULT_EDIT_HANDLE_COLOR,\n EDITABLE_LAYER_SUBLAYER_PROPS,\n} from '../constants';\nimport type { Color } from '@deck.gl/core';\n\n/**\n * Props returned by getDefaultEditableLayerProps.\n * These are common configuration props shared between DrawShapeLayer and EditShapeLayer.\n */\nexport type EditableLayerDefaultProps = {\n /** Edit handle point color. */\n getEditHandlePointColor: Color;\n /** Edit handle point outline color. */\n getEditHandlePointOutlineColor: Color;\n /** Mode configuration with distance units. */\n modeConfig: {\n distanceUnits: DistanceUnit;\n };\n /** Sublayer props for tooltips and edit handles. */\n _subLayerProps: typeof EDITABLE_LAYER_SUBLAYER_PROPS;\n};\n\nlet cachedAbbrev: DistanceUnitAbbreviation | undefined | null = null;\nlet cachedProps: EditableLayerDefaultProps | undefined;\n\n/**\n * Returns default props for EditableGeoJsonLayer configuration.\n *\n * This consolidates the common configuration shared between DrawShapeLayer and EditShapeLayer:\n * - Edit handle colors\n * - Mode configuration with distance units\n * - Sublayer props for tooltips and handles\n *\n * @param unitAbbrev - Optional unit abbreviation (e.g., 'km', 'mi'). Defaults to DEFAULT_DISTANCE_UNITS.\n * @returns Default props to spread onto EditableGeoJsonLayer.\n *\n * @example\n * ```tsx\n * <editableGeoJsonLayer\n * {...getDefaultEditableLayerProps(unit)}\n * // other props\n * />\n * ```\n */\nexport function getDefaultEditableLayerProps(\n unitAbbrev?: DistanceUnitAbbreviation,\n): EditableLayerDefaultProps {\n if (cachedAbbrev !== null && cachedAbbrev === unitAbbrev && cachedProps) {\n return cachedProps;\n }\n\n cachedAbbrev = unitAbbrev;\n cachedProps = {\n getEditHandlePointColor: DEFAULT_EDIT_HANDLE_COLOR,\n getEditHandlePointOutlineColor: DEFAULT_EDIT_HANDLE_COLOR,\n modeConfig: {\n distanceUnits: unitAbbrev\n ? (getDistanceUnitFromAbbreviation(unitAbbrev) ??\n DEFAULT_DISTANCE_UNITS)\n : DEFAULT_DISTANCE_UNITS,\n },\n // biome-ignore lint/style/useNamingConvention: deck.gl API convention\n _subLayerProps: EDITABLE_LAYER_SUBLAYER_PROPS,\n };\n\n return cachedProps;\n}\n"],"mappings":";;;;;;;;;;;;;;;;;AAyCA,IAAIA,eAA4D;AAChE,IAAIC;;;;;;;;;;;;;;;;;;;;AAqBJ,SAAgB,6BACd,YAC2B;AAC3B,KAAI,iBAAiB,QAAQ,iBAAiB,cAAc,YAC1D,QAAO;AAGT,gBAAe;AACf,eAAc;EACZ,yBAAyB;EACzB,gCAAgC;EAChC,YAAY,EACV,eAAe,aACV,gCAAgC,WAAW,IAC5C,yBACA,wBACL;EAED,gBAAgB;EACjB;AAED,QAAO"}
@@ -1,5 +1,5 @@
1
1
  /*
2
- * Copyright 2025 Hypergiant Galactic Systems Inc. All rights reserved.
2
+ * Copyright 2026 Hypergiant Galactic Systems Inc. All rights reserved.
3
3
  * This file is licensed to you under the Apache License, Version 2.0 (the "License");
4
4
  * you may not use this file except in compliance with the License. You may obtain a copy
5
5
  * of the License at https://www.apache.org/licenses/LICENSE-2.0
@@ -11,8 +11,6 @@
11
11
  */
12
12
 
13
13
 
14
- 'use client';
15
-
16
14
  import { MapModeEvents } from "../../../../map-mode/events.js";
17
15
  import { MapCursorEvents } from "../../../../map-cursor/events.js";
18
16
  import { cursorStore } from "../../../../map-cursor/store.js";
@@ -24,15 +22,22 @@ import { Broadcast } from "@accelint/bus";
24
22
  */
25
23
  const mapModeBus = Broadcast.getInstance();
26
24
  const mapCursorBus = Broadcast.getInstance();
25
+ /** The idle mode name used when releasing ownership. */
26
+ const DEFAULT_MODE = "default";
27
27
  /**
28
28
  * Request a map mode change.
29
29
  *
30
30
  * Emits a mode change request through the event bus. The mode store will
31
31
  * handle authorization and apply the change if approved.
32
32
  *
33
- * @param mapId - The map instance ID
34
- * @param desiredMode - The mode to switch to
35
- * @param owner - The identifier of the component requesting the change
33
+ * @param mapId - The map instance ID.
34
+ * @param desiredMode - The mode to switch to.
35
+ * @param owner - The identifier of the component requesting the change.
36
+ *
37
+ * @example
38
+ * ```typescript
39
+ * requestModeChange(mapId, 'draw', 'draw-shape-layer');
40
+ * ```
36
41
  */
37
42
  function requestModeChange(mapId, desiredMode, owner) {
38
43
  mapModeBus.emit(MapModeEvents.changeRequest, {
@@ -46,20 +51,30 @@ function requestModeChange(mapId, desiredMode, owner) {
46
51
  *
47
52
  * Convenience function to request a mode change back to 'default'.
48
53
  *
49
- * @param mapId - The map instance ID
50
- * @param owner - The identifier of the component releasing the mode
54
+ * @param mapId - The map instance ID.
55
+ * @param owner - The identifier of the component releasing the mode.
56
+ *
57
+ * @example
58
+ * ```typescript
59
+ * releaseMode(mapId, 'draw-shape-layer');
60
+ * ```
51
61
  */
52
62
  function releaseMode(mapId, owner) {
53
- requestModeChange(mapId, "default", owner);
63
+ requestModeChange(mapId, DEFAULT_MODE, owner);
54
64
  }
55
65
  /**
56
66
  * Request a cursor change.
57
67
  *
58
68
  * Emits a cursor change request through the event bus.
59
69
  *
60
- * @param mapId - The map instance ID
61
- * @param cursor - The CSS cursor type to set
62
- * @param owner - The identifier of the component requesting the change
70
+ * @param mapId - The map instance ID.
71
+ * @param cursor - The CSS cursor type to set.
72
+ * @param owner - The identifier of the component requesting the change.
73
+ *
74
+ * @example
75
+ * ```typescript
76
+ * requestCursorChange(mapId, 'crosshair', 'draw-shape-layer');
77
+ * ```
63
78
  */
64
79
  function requestCursorChange(mapId, cursor, owner) {
65
80
  mapCursorBus.emit(MapCursorEvents.changeRequest, {
@@ -73,8 +88,13 @@ function requestCursorChange(mapId, cursor, owner) {
73
88
  *
74
89
  * Uses the cursor store's clear function to release the cursor.
75
90
  *
76
- * @param mapId - The map instance ID
77
- * @param owner - The identifier of the component releasing the cursor
91
+ * @param mapId - The map instance ID.
92
+ * @param owner - The identifier of the component releasing the cursor.
93
+ *
94
+ * @example
95
+ * ```typescript
96
+ * releaseCursor(mapId, 'draw-shape-layer');
97
+ * ```
78
98
  */
79
99
  function releaseCursor(mapId, owner) {
80
100
  cursorStore.actions(mapId).clearCursor(owner);
@@ -86,10 +106,15 @@ function releaseCursor(mapId, owner) {
86
106
  * requires authorization. When the mode change is approved, the cursor
87
107
  * will be automatically applied via getEffectiveCursor.
88
108
  *
89
- * @param mapId - The map instance ID
90
- * @param desiredMode - The mode to switch to
91
- * @param cursor - The CSS cursor type to set
92
- * @param owner - The identifier of the component requesting the changes
109
+ * @param mapId - The map instance ID.
110
+ * @param desiredMode - The mode to switch to.
111
+ * @param cursor - The CSS cursor type to set.
112
+ * @param owner - The identifier of the component requesting the changes.
113
+ *
114
+ * @example
115
+ * ```typescript
116
+ * requestModeAndCursor(mapId, 'draw', 'crosshair', 'draw-shape-layer');
117
+ * ```
93
118
  */
94
119
  function requestModeAndCursor(mapId, desiredMode, cursor, owner) {
95
120
  requestModeChange(mapId, desiredMode, owner);
@@ -100,8 +125,13 @@ function requestModeAndCursor(mapId, desiredMode, cursor, owner) {
100
125
  *
101
126
  * Common pattern when ending an operation.
102
127
  *
103
- * @param mapId - The map instance ID
104
- * @param owner - The identifier of the component releasing mode and cursor
128
+ * @param mapId - The map instance ID.
129
+ * @param owner - The identifier of the component releasing mode and cursor.
130
+ *
131
+ * @example
132
+ * ```typescript
133
+ * releaseModeAndCursor(mapId, 'draw-shape-layer');
134
+ * ```
105
135
  */
106
136
  function releaseModeAndCursor(mapId, owner) {
107
137
  releaseMode(mapId, owner);
@@ -1 +1 @@
1
- {"version":3,"file":"mode-utils.js","names":[],"sources":["../../../../../src/deckgl/shapes/shared/utils/mode-utils.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\nimport { Broadcast } from '@accelint/bus';\nimport { MapCursorEvents } from '@/map-cursor/events';\nimport { cursorStore } from '@/map-cursor/store';\nimport { MapModeEvents } from '@/map-mode/events';\nimport type { UniqueId } from '@accelint/core';\nimport type { CSSCursorType, MapCursorEventType } from '@/map-cursor/types';\nimport type { MapModeEventType } from '@/map-mode/types';\n\n/**\n * Typed event bus instances for mode and cursor communication.\n */\nconst mapModeBus = Broadcast.getInstance<MapModeEventType>();\nconst mapCursorBus = Broadcast.getInstance<MapCursorEventType>();\n\n/**\n * Request a map mode change.\n *\n * Emits a mode change request through the event bus. The mode store will\n * handle authorization and apply the change if approved.\n *\n * @param mapId - The map instance ID\n * @param desiredMode - The mode to switch to\n * @param owner - The identifier of the component requesting the change\n */\nexport function requestModeChange(\n mapId: UniqueId,\n desiredMode: string,\n owner: string,\n): void {\n mapModeBus.emit(MapModeEvents.changeRequest, {\n desiredMode,\n owner,\n id: mapId,\n });\n}\n\n/**\n * Release mode back to default.\n *\n * Convenience function to request a mode change back to 'default'.\n *\n * @param mapId - The map instance ID\n * @param owner - The identifier of the component releasing the mode\n */\nexport function releaseMode(mapId: UniqueId, owner: string): void {\n requestModeChange(mapId, 'default', owner);\n}\n\n/**\n * Request a cursor change.\n *\n * Emits a cursor change request through the event bus.\n *\n * @param mapId - The map instance ID\n * @param cursor - The CSS cursor type to set\n * @param owner - The identifier of the component requesting the change\n */\nexport function requestCursorChange(\n mapId: UniqueId,\n cursor: CSSCursorType,\n owner: string,\n): void {\n mapCursorBus.emit(MapCursorEvents.changeRequest, {\n cursor,\n owner,\n id: mapId,\n });\n}\n\n/**\n * Release cursor back to default.\n *\n * Uses the cursor store's clear function to release the cursor.\n *\n * @param mapId - The map instance ID\n * @param owner - The identifier of the component releasing the cursor\n */\nexport function releaseCursor(mapId: UniqueId, owner: string): void {\n cursorStore.actions(mapId).clearCursor(owner);\n}\n\n/**\n * Request both mode and cursor changes together.\n *\n * The cursor is stored for registered mode owners even if the mode change\n * requires authorization. When the mode change is approved, the cursor\n * will be automatically applied via getEffectiveCursor.\n *\n * @param mapId - The map instance ID\n * @param desiredMode - The mode to switch to\n * @param cursor - The CSS cursor type to set\n * @param owner - The identifier of the component requesting the changes\n */\nexport function requestModeAndCursor(\n mapId: UniqueId,\n desiredMode: string,\n cursor: CSSCursorType,\n owner: string,\n): void {\n requestModeChange(mapId, desiredMode, owner);\n requestCursorChange(mapId, cursor, owner);\n}\n\n/**\n * Release both mode and cursor back to defaults.\n *\n * Common pattern when ending an operation.\n *\n * @param mapId - The map instance ID\n * @param owner - The identifier of the component releasing mode and cursor\n */\nexport function releaseModeAndCursor(mapId: UniqueId, owner: string): void {\n releaseMode(mapId, owner);\n releaseCursor(mapId, owner);\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;AAyBA,MAAM,aAAa,UAAU,aAA+B;AAC5D,MAAM,eAAe,UAAU,aAAiC;;;;;;;;;;;AAYhE,SAAgB,kBACd,OACA,aACA,OACM;AACN,YAAW,KAAK,cAAc,eAAe;EAC3C;EACA;EACA,IAAI;EACL,CAAC;;;;;;;;;;AAWJ,SAAgB,YAAY,OAAiB,OAAqB;AAChE,mBAAkB,OAAO,WAAW,MAAM;;;;;;;;;;;AAY5C,SAAgB,oBACd,OACA,QACA,OACM;AACN,cAAa,KAAK,gBAAgB,eAAe;EAC/C;EACA;EACA,IAAI;EACL,CAAC;;;;;;;;;;AAWJ,SAAgB,cAAc,OAAiB,OAAqB;AAClE,aAAY,QAAQ,MAAM,CAAC,YAAY,MAAM;;;;;;;;;;;;;;AAe/C,SAAgB,qBACd,OACA,aACA,QACA,OACM;AACN,mBAAkB,OAAO,aAAa,MAAM;AAC5C,qBAAoB,OAAO,QAAQ,MAAM;;;;;;;;;;AAW3C,SAAgB,qBAAqB,OAAiB,OAAqB;AACzE,aAAY,OAAO,MAAM;AACzB,eAAc,OAAO,MAAM"}
1
+ {"version":3,"file":"mode-utils.js","names":[],"sources":["../../../../../src/deckgl/shapes/shared/utils/mode-utils.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 { Broadcast } from '@accelint/bus';\nimport { MapCursorEvents } from '@/map-cursor/events';\nimport { cursorStore } from '@/map-cursor/store';\nimport { MapModeEvents } from '@/map-mode/events';\nimport type { UniqueId } from '@accelint/core';\nimport type { CSSCursorType, MapCursorEventType } from '@/map-cursor/types';\nimport type { MapModeEventType } from '@/map-mode/types';\n\n/**\n * Typed event bus instances for mode and cursor communication.\n */\nconst mapModeBus = Broadcast.getInstance<MapModeEventType>();\nconst mapCursorBus = Broadcast.getInstance<MapCursorEventType>();\n\n/** The idle mode name used when releasing ownership. */\nconst DEFAULT_MODE = 'default';\n\n/**\n * Request a map mode change.\n *\n * Emits a mode change request through the event bus. The mode store will\n * handle authorization and apply the change if approved.\n *\n * @param mapId - The map instance ID.\n * @param desiredMode - The mode to switch to.\n * @param owner - The identifier of the component requesting the change.\n *\n * @example\n * ```typescript\n * requestModeChange(mapId, 'draw', 'draw-shape-layer');\n * ```\n */\nexport function requestModeChange(\n mapId: UniqueId,\n desiredMode: string,\n owner: string,\n): void {\n mapModeBus.emit(MapModeEvents.changeRequest, {\n desiredMode,\n owner,\n id: mapId,\n });\n}\n\n/**\n * Release mode back to default.\n *\n * Convenience function to request a mode change back to 'default'.\n *\n * @param mapId - The map instance ID.\n * @param owner - The identifier of the component releasing the mode.\n *\n * @example\n * ```typescript\n * releaseMode(mapId, 'draw-shape-layer');\n * ```\n */\nexport function releaseMode(mapId: UniqueId, owner: string): void {\n requestModeChange(mapId, DEFAULT_MODE, owner);\n}\n\n/**\n * Request a cursor change.\n *\n * Emits a cursor change request through the event bus.\n *\n * @param mapId - The map instance ID.\n * @param cursor - The CSS cursor type to set.\n * @param owner - The identifier of the component requesting the change.\n *\n * @example\n * ```typescript\n * requestCursorChange(mapId, 'crosshair', 'draw-shape-layer');\n * ```\n */\nexport function requestCursorChange(\n mapId: UniqueId,\n cursor: CSSCursorType,\n owner: string,\n): void {\n mapCursorBus.emit(MapCursorEvents.changeRequest, {\n cursor,\n owner,\n id: mapId,\n });\n}\n\n/**\n * Release cursor back to default.\n *\n * Uses the cursor store's clear function to release the cursor.\n *\n * @param mapId - The map instance ID.\n * @param owner - The identifier of the component releasing the cursor.\n *\n * @example\n * ```typescript\n * releaseCursor(mapId, 'draw-shape-layer');\n * ```\n */\nexport function releaseCursor(mapId: UniqueId, owner: string): void {\n cursorStore.actions(mapId).clearCursor(owner);\n}\n\n/**\n * Request both mode and cursor changes together.\n *\n * The cursor is stored for registered mode owners even if the mode change\n * requires authorization. When the mode change is approved, the cursor\n * will be automatically applied via getEffectiveCursor.\n *\n * @param mapId - The map instance ID.\n * @param desiredMode - The mode to switch to.\n * @param cursor - The CSS cursor type to set.\n * @param owner - The identifier of the component requesting the changes.\n *\n * @example\n * ```typescript\n * requestModeAndCursor(mapId, 'draw', 'crosshair', 'draw-shape-layer');\n * ```\n */\nexport function requestModeAndCursor(\n mapId: UniqueId,\n desiredMode: string,\n cursor: CSSCursorType,\n owner: string,\n): void {\n requestModeChange(mapId, desiredMode, owner);\n requestCursorChange(mapId, cursor, owner);\n}\n\n/**\n * Release both mode and cursor back to defaults.\n *\n * Common pattern when ending an operation.\n *\n * @param mapId - The map instance ID.\n * @param owner - The identifier of the component releasing mode and cursor.\n *\n * @example\n * ```typescript\n * releaseModeAndCursor(mapId, 'draw-shape-layer');\n * ```\n */\nexport function releaseModeAndCursor(mapId: UniqueId, owner: string): void {\n releaseMode(mapId, owner);\n releaseCursor(mapId, owner);\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;AAuBA,MAAM,aAAa,UAAU,aAA+B;AAC5D,MAAM,eAAe,UAAU,aAAiC;;AAGhE,MAAM,eAAe;;;;;;;;;;;;;;;;AAiBrB,SAAgB,kBACd,OACA,aACA,OACM;AACN,YAAW,KAAK,cAAc,eAAe;EAC3C;EACA;EACA,IAAI;EACL,CAAC;;;;;;;;;;;;;;;AAgBJ,SAAgB,YAAY,OAAiB,OAAqB;AAChE,mBAAkB,OAAO,cAAc,MAAM;;;;;;;;;;;;;;;;AAiB/C,SAAgB,oBACd,OACA,QACA,OACM;AACN,cAAa,KAAK,gBAAgB,eAAe;EAC/C;EACA;EACA,IAAI;EACL,CAAC;;;;;;;;;;;;;;;AAgBJ,SAAgB,cAAc,OAAiB,OAAqB;AAClE,aAAY,QAAQ,MAAM,CAAC,YAAY,MAAM;;;;;;;;;;;;;;;;;;;AAoB/C,SAAgB,qBACd,OACA,aACA,QACA,OACM;AACN,mBAAkB,OAAO,aAAa,MAAM;AAC5C,qBAAoB,OAAO,QAAQ,MAAM;;;;;;;;;;;;;;;AAgB3C,SAAgB,qBAAqB,OAAiB,OAAqB;AACzE,aAAY,OAAO,MAAM;AACzB,eAAc,OAAO,MAAM"}
@@ -1,5 +1,5 @@
1
1
  /*
2
- * Copyright 2025 Hypergiant Galactic Systems Inc. All rights reserved.
2
+ * Copyright 2026 Hypergiant Galactic Systems Inc. All rights reserved.
3
3
  * This file is licensed to you under the Apache License, Version 2.0 (the "License");
4
4
  * you may not use this file except in compliance with the License. You may obtain a copy
5
5
  * of the License at https://www.apache.org/licenses/LICENSE-2.0
@@ -11,8 +11,6 @@
11
11
  */
12
12
 
13
13
 
14
- 'use client';
15
-
16
14
  //#region src/deckgl/shapes/shared/utils/pick-filtering.ts
17
15
  /**
18
16
  * Filters picks to only include valid geometry elements.
@@ -21,11 +19,12 @@
21
19
  * when modes try to access pick.object.geometry.type. Only picks that are
22
20
  * either guide features (pick.isGuide) or have valid geometry are included.
23
21
  *
24
- * Uses a single-pass algorithm for efficiency - filters and tracks changes
25
- * in one loop iteration.
22
+ * On the common path where all picks are valid, returns the original array
23
+ * with zero allocations.
26
24
  *
27
- * @param picks - The picks array from a pointer event
28
- * @returns Object containing filtered picks and whether filtering occurred
25
+ * @template T - The pick type, constrained to PickLike.
26
+ * @param picks - The picks array from a pointer event.
27
+ * @returns Object containing filtered picks and whether filtering occurred.
29
28
  *
30
29
  * @example
31
30
  * ```typescript
@@ -39,16 +38,24 @@
39
38
  * ```
40
39
  */
41
40
  function filterGeometryAwarePicks(picks) {
42
- const filteredPicks = [];
43
- let didFilter = false;
44
- for (const pick of picks) {
45
- const pickObj = pick;
46
- if (pickObj.isGuide || pickObj.object?.geometry?.type !== void 0) filteredPicks.push(pick);
47
- else didFilter = true;
41
+ const len = picks.length;
42
+ for (let i = 0; i < len; i++) {
43
+ const pick = picks[i];
44
+ if (!pick?.isGuide && pick?.object?.geometry?.type === void 0) {
45
+ const filteredPicks = picks.slice(0, i);
46
+ for (let j = i + 1; j < len; j++) {
47
+ const p = picks[j];
48
+ if (p?.isGuide || p?.object?.geometry?.type !== void 0) filteredPicks.push(p);
49
+ }
50
+ return {
51
+ filteredPicks,
52
+ didFilter: true
53
+ };
54
+ }
48
55
  }
49
56
  return {
50
- filteredPicks,
51
- didFilter
57
+ filteredPicks: picks,
58
+ didFilter: false
52
59
  };
53
60
  }
54
61
 
@@ -1 +1 @@
1
- {"version":3,"file":"pick-filtering.js","names":["filteredPicks: T[]"],"sources":["../../../../../src/deckgl/shapes/shared/utils/pick-filtering.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 * Result of filtering picks for geometry-aware processing.\n * Generic to support both deck.gl/core PickingInfo and editable-layers Pick types.\n */\nexport interface FilteredPicksResult<T> {\n /** The filtered picks array (only valid geometry picks) */\n filteredPicks: T[];\n /** Whether any picks were removed during filtering */\n didFilter: boolean;\n}\n\n/**\n * Filters picks to only include valid geometry elements.\n *\n * This prevents TypeError from sublayer elements that don't have geometry\n * when modes try to access pick.object.geometry.type. Only picks that are\n * either guide features (pick.isGuide) or have valid geometry are included.\n *\n * Uses a single-pass algorithm for efficiency - filters and tracks changes\n * in one loop iteration.\n *\n * @param picks - The picks array from a pointer event\n * @returns Object containing filtered picks and whether filtering occurred\n *\n * @example\n * ```typescript\n * const picks = props.lastPointerMoveEvent?.picks;\n * if (picks && picks.length > 0) {\n * const { filteredPicks, didFilter } = filterGeometryAwarePicks(picks);\n * if (didFilter) {\n * // Use filteredPicks in modified props\n * }\n * }\n * ```\n */\nexport function filterGeometryAwarePicks<T>(\n picks: T[],\n): FilteredPicksResult<T> {\n const filteredPicks: T[] = [];\n let didFilter = false;\n\n for (const pick of picks) {\n // Keep picks that are guides or have valid geometry\n // biome-ignore lint/suspicious/noExplicitAny: deck.gl picks have dynamic object structure\n const pickObj = pick as any;\n if (pickObj.isGuide || pickObj.object?.geometry?.type !== undefined) {\n filteredPicks.push(pick);\n } else {\n didFilter = true;\n }\n }\n\n return { filteredPicks, didFilter };\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAiDA,SAAgB,yBACd,OACwB;CACxB,MAAMA,gBAAqB,EAAE;CAC7B,IAAI,YAAY;AAEhB,MAAK,MAAM,QAAQ,OAAO;EAGxB,MAAM,UAAU;AAChB,MAAI,QAAQ,WAAW,QAAQ,QAAQ,UAAU,SAAS,OACxD,eAAc,KAAK,KAAK;MAExB,aAAY;;AAIhB,QAAO;EAAE;EAAe;EAAW"}
1
+ {"version":3,"file":"pick-filtering.js","names":["filteredPicks: T[]"],"sources":["../../../../../src/deckgl/shapes/shared/utils/pick-filtering.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/**\n * Minimal shape required for pick filtering.\n * Satisfied by both deck.gl/core PickingInfo and editable-layers Pick types.\n */\ntype PickLike = {\n isGuide?: boolean;\n object?: {\n geometry?: {\n type?: string;\n };\n };\n};\n\n/**\n * Result of filtering picks for geometry-aware processing.\n * Generic to support both deck.gl/core PickingInfo and editable-layers Pick types.\n *\n * @template T - The pick type, must satisfy PickLike shape.\n */\nexport type FilteredPicksResult<T> = {\n /** The filtered picks array (only valid geometry picks). */\n filteredPicks: T[];\n /** Whether any picks were removed during filtering. */\n didFilter: boolean;\n};\n\n/**\n * Filters picks to only include valid geometry elements.\n *\n * This prevents TypeError from sublayer elements that don't have geometry\n * when modes try to access pick.object.geometry.type. Only picks that are\n * either guide features (pick.isGuide) or have valid geometry are included.\n *\n * On the common path where all picks are valid, returns the original array\n * with zero allocations.\n *\n * @template T - The pick type, constrained to PickLike.\n * @param picks - The picks array from a pointer event.\n * @returns Object containing filtered picks and whether filtering occurred.\n *\n * @example\n * ```typescript\n * const picks = props.lastPointerMoveEvent?.picks;\n * if (picks && picks.length > 0) {\n * const { filteredPicks, didFilter } = filterGeometryAwarePicks(picks);\n * if (didFilter) {\n * // Use filteredPicks in modified props\n * }\n * }\n * ```\n */\nexport function filterGeometryAwarePicks<T extends PickLike>(\n picks: T[],\n): FilteredPicksResult<T> {\n const len = picks.length;\n\n for (let i = 0; i < len; i++) {\n const pick = picks[i];\n if (!pick?.isGuide && pick?.object?.geometry?.type === undefined) {\n // Found a pick that needs filtering build filtered array from here\n const filteredPicks: T[] = picks.slice(0, i);\n for (let j = i + 1; j < len; j++) {\n const p = picks[j];\n if (p?.isGuide || p?.object?.geometry?.type !== undefined) {\n filteredPicks.push(p);\n }\n }\n return { filteredPicks, didFilter: true };\n }\n }\n\n return { filteredPicks: picks, didFilter: false };\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA+DA,SAAgB,yBACd,OACwB;CACxB,MAAM,MAAM,MAAM;AAElB,MAAK,IAAI,IAAI,GAAG,IAAI,KAAK,KAAK;EAC5B,MAAM,OAAO,MAAM;AACnB,MAAI,CAAC,MAAM,WAAW,MAAM,QAAQ,UAAU,SAAS,QAAW;GAEhE,MAAMA,gBAAqB,MAAM,MAAM,GAAG,EAAE;AAC5C,QAAK,IAAI,IAAI,IAAI,GAAG,IAAI,KAAK,KAAK;IAChC,MAAM,IAAI,MAAM;AAChB,QAAI,GAAG,WAAW,GAAG,QAAQ,UAAU,SAAS,OAC9C,eAAc,KAAK,EAAE;;AAGzB,UAAO;IAAE;IAAe,WAAW;IAAM;;;AAI7C,QAAO;EAAE,eAAe;EAAO,WAAW;EAAO"}
@@ -1,5 +1,5 @@
1
1
  /*
2
- * Copyright 2025 Hypergiant Galactic Systems Inc. All rights reserved.
2
+ * Copyright 2026 Hypergiant Galactic Systems Inc. All rights reserved.
3
3
  * This file is licensed to you under the Apache License, Version 2.0 (the "License");
4
4
  * you may not use this file except in compliance with the License. You may obtain a copy
5
5
  * of the License at https://www.apache.org/licenses/LICENSE-2.0
@@ -18,19 +18,29 @@ import { Color } from "@deck.gl/core";
18
18
  * Normalize a Color to a 4-element RGBA array.
19
19
  * Handles RGB arrays (adds alpha 255), RGBA arrays, and typed arrays.
20
20
  *
21
- * @param color - The color to normalize
22
- * @returns 4-element RGBA array [r, g, b, a]
21
+ * @param color - The color to normalize.
22
+ * @returns 4-element RGBA array [r, g, b, a].
23
+ * @example
24
+ * ```typescript
25
+ * normalizeColor([255, 128, 0]); // → [255, 128, 0, 255]
26
+ * normalizeColor([255, 128, 0, 200]); // → [255, 128, 0, 200]
27
+ * ```
23
28
  */
24
29
  declare function normalizeColor(color: Color): [number, number, number, number];
25
30
  /**
26
31
  * Get fill color for a feature.
27
32
  * Colors are passed through as-is unless applyBaseOpacity is true.
28
33
  *
29
- * @param feature - The styled feature
30
- * @param applyBaseOpacity - When true, multiplies alpha by BASE_FILL_OPACITY (0.2)
31
- * @returns RGBA color array
34
+ * @param feature - The styled feature.
35
+ * @param applyBaseOpacity - When true, multiplies alpha by BASE_FILL_OPACITY (0.2).
36
+ * @returns RGBA color array.
37
+ * @example
38
+ * ```typescript
39
+ * getFillColor(feature); // → [255, 255, 255, 255] (full opacity)
40
+ * getFillColor(feature, true); // → [255, 255, 255, 51] (255 × 0.2)
41
+ * ```
32
42
  */
33
- declare function getFillColor(feature: StyledFeature, applyBaseOpacity?: boolean): Color;
43
+ declare function getFillColor(feature: StyledFeature, applyBaseOpacity?: boolean): [number, number, number, number];
34
44
  /**
35
45
  * Get border/outline color for a feature.
36
46
  * Outlines are always rendered at their literal alpha value.
@@ -38,25 +48,39 @@ declare function getFillColor(feature: StyledFeature, applyBaseOpacity?: boolean
38
48
  * Named to match deck.gl's `getLineColor` accessor convention.
39
49
  * Reads from `lineColor` in the feature's style properties.
40
50
  *
41
- * @param feature - The styled feature
42
- * @returns RGBA color array
51
+ * @param feature - The styled feature.
52
+ * @returns RGBA color array.
53
+ * @example
54
+ * ```typescript
55
+ * getLineColor(feature); // → [136, 138, 143, 255] (default line color)
56
+ * ```
43
57
  */
44
- declare function getLineColor(feature: StyledFeature): Color;
58
+ declare function getLineColor(feature: StyledFeature): [number, number, number, number];
45
59
  /**
46
60
  * Get border/outline width for a feature.
47
61
  *
48
62
  * Named to match deck.gl's `getLineWidth` accessor convention.
49
63
  * Reads from `lineWidth` in the feature's style properties.
50
64
  *
51
- * @param feature - The styled feature
52
- * @returns Border/outline width in pixels
65
+ * @param feature - The styled feature.
66
+ * @returns Border/outline width in pixels.
67
+ * @example
68
+ * ```typescript
69
+ * getLineWidth(feature); // → 2 (default width)
70
+ * ```
53
71
  */
54
72
  declare function getLineWidth(feature: StyledFeature): number;
55
73
  /**
56
74
  * Get dash array for border/outline pattern.
57
75
  *
58
- * @param feature - The styled feature
59
- * @returns Dash array [dash, gap] or null for solid outlines
76
+ * @param feature - The styled feature.
77
+ * @returns Dash array [dash, gap] or null for solid outlines.
78
+ * @example
79
+ * ```typescript
80
+ * getDashArray(solidFeature); // → null
81
+ * getDashArray(dashedFeature); // → [8, 4]
82
+ * getDashArray(dottedFeature); // → [2, 4]
83
+ * ```
60
84
  */
61
85
  declare function getDashArray(feature: StyledFeature): [number, number] | null;
62
86
  //#endregion