@accelint/map-toolkit 0.6.0 → 1.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 (183) hide show
  1. package/CHANGELOG.md +68 -0
  2. package/catalog-info.yaml +5 -4
  3. package/dist/camera/index.d.ts +2 -2
  4. package/dist/camera/index.js +2 -2
  5. package/dist/camera/store.d.ts +120 -0
  6. package/dist/camera/store.js +279 -0
  7. package/dist/camera/store.js.map +1 -0
  8. package/dist/deckgl/base-map/constants.d.ts +1 -6
  9. package/dist/deckgl/base-map/constants.js +1 -6
  10. package/dist/deckgl/base-map/constants.js.map +1 -1
  11. package/dist/deckgl/base-map/controls.js +2 -0
  12. package/dist/deckgl/base-map/controls.js.map +1 -1
  13. package/dist/deckgl/base-map/index.d.ts +2 -2
  14. package/dist/deckgl/base-map/index.js +10 -11
  15. package/dist/deckgl/base-map/index.js.map +1 -1
  16. package/dist/deckgl/base-map/provider.js +1 -1
  17. package/dist/deckgl/index.d.ts +4 -4
  18. package/dist/deckgl/index.js +4 -4
  19. package/dist/deckgl/saved-viewports/storage.js +10 -2
  20. package/dist/deckgl/saved-viewports/storage.js.map +1 -1
  21. package/dist/deckgl/shapes/display-shape-layer/constants.js +5 -8
  22. package/dist/deckgl/shapes/display-shape-layer/constants.js.map +1 -1
  23. package/dist/deckgl/shapes/display-shape-layer/index.d.ts +18 -14
  24. package/dist/deckgl/shapes/display-shape-layer/index.js +63 -30
  25. package/dist/deckgl/shapes/display-shape-layer/index.js.map +1 -1
  26. package/dist/deckgl/shapes/display-shape-layer/shape-label-layer.js +2 -16
  27. package/dist/deckgl/shapes/display-shape-layer/shape-label-layer.js.map +1 -1
  28. package/dist/deckgl/shapes/display-shape-layer/store.js +58 -272
  29. package/dist/deckgl/shapes/display-shape-layer/store.js.map +1 -1
  30. package/dist/deckgl/shapes/display-shape-layer/types.d.ts +22 -11
  31. package/dist/deckgl/shapes/display-shape-layer/{use-shape-selection.d.ts → use-select-shape.d.ts} +9 -9
  32. package/dist/deckgl/shapes/display-shape-layer/{use-shape-selection.js → use-select-shape.js} +12 -12
  33. package/dist/deckgl/shapes/display-shape-layer/use-select-shape.js.map +1 -0
  34. package/dist/deckgl/shapes/display-shape-layer/utils/display-style.js +5 -66
  35. package/dist/deckgl/shapes/display-shape-layer/utils/display-style.js.map +1 -1
  36. package/dist/deckgl/shapes/display-shape-layer/utils/labels.d.ts +2 -65
  37. package/dist/deckgl/shapes/display-shape-layer/utils/labels.js +3 -121
  38. package/dist/deckgl/shapes/display-shape-layer/utils/labels.js.map +1 -1
  39. package/dist/deckgl/shapes/draw-shape-layer/constants.js +46 -0
  40. package/dist/deckgl/shapes/draw-shape-layer/constants.js.map +1 -0
  41. package/dist/deckgl/shapes/draw-shape-layer/events.d.ts +92 -0
  42. package/dist/deckgl/shapes/draw-shape-layer/events.js +56 -0
  43. package/dist/deckgl/shapes/draw-shape-layer/events.js.map +1 -0
  44. package/dist/deckgl/shapes/draw-shape-layer/fiber.d.ts +11 -0
  45. package/dist/{maplibre/constants.js → deckgl/shapes/draw-shape-layer/fiber.js} +6 -12
  46. package/dist/deckgl/shapes/draw-shape-layer/fiber.js.map +1 -0
  47. package/dist/deckgl/shapes/draw-shape-layer/index.d.ts +53 -0
  48. package/dist/deckgl/shapes/draw-shape-layer/index.js +95 -0
  49. package/dist/deckgl/shapes/draw-shape-layer/index.js.map +1 -0
  50. package/dist/deckgl/shapes/draw-shape-layer/modes/draw-circle-mode-with-tooltip.js +51 -0
  51. package/dist/deckgl/shapes/draw-shape-layer/modes/draw-circle-mode-with-tooltip.js.map +1 -0
  52. package/dist/deckgl/shapes/draw-shape-layer/modes/draw-ellipse-mode-with-tooltip.js +73 -0
  53. package/dist/deckgl/shapes/draw-shape-layer/modes/draw-ellipse-mode-with-tooltip.js.map +1 -0
  54. package/dist/deckgl/shapes/draw-shape-layer/modes/draw-line-string-mode-with-tooltip.js +87 -0
  55. package/dist/deckgl/shapes/draw-shape-layer/modes/draw-line-string-mode-with-tooltip.js.map +1 -0
  56. package/dist/deckgl/shapes/draw-shape-layer/modes/draw-polygon-mode-with-tooltip.js +88 -0
  57. package/dist/deckgl/shapes/draw-shape-layer/modes/draw-polygon-mode-with-tooltip.js.map +1 -0
  58. package/dist/deckgl/shapes/draw-shape-layer/modes/draw-rectangle-mode-with-tooltip.js +77 -0
  59. package/dist/deckgl/shapes/draw-shape-layer/modes/draw-rectangle-mode-with-tooltip.js.map +1 -0
  60. package/dist/deckgl/shapes/draw-shape-layer/modes/index.js +64 -0
  61. package/dist/deckgl/shapes/draw-shape-layer/modes/index.js.map +1 -0
  62. package/dist/deckgl/shapes/draw-shape-layer/store.js +175 -0
  63. package/dist/deckgl/shapes/draw-shape-layer/store.js.map +1 -0
  64. package/dist/deckgl/shapes/draw-shape-layer/types.d.ts +86 -0
  65. package/dist/{viewport/constants.js → deckgl/shapes/draw-shape-layer/types.js} +1 -12
  66. package/dist/deckgl/shapes/draw-shape-layer/use-draw-shape.d.ts +82 -0
  67. package/dist/deckgl/shapes/draw-shape-layer/use-draw-shape.js +112 -0
  68. package/dist/deckgl/shapes/draw-shape-layer/use-draw-shape.js.map +1 -0
  69. package/dist/deckgl/shapes/draw-shape-layer/utils/feature-conversion.js +147 -0
  70. package/dist/deckgl/shapes/draw-shape-layer/utils/feature-conversion.js.map +1 -0
  71. package/dist/deckgl/shapes/edit-shape-layer/constants.js +41 -0
  72. package/dist/deckgl/shapes/edit-shape-layer/constants.js.map +1 -0
  73. package/dist/deckgl/shapes/edit-shape-layer/events.d.ts +92 -0
  74. package/dist/deckgl/shapes/edit-shape-layer/events.js +56 -0
  75. package/dist/deckgl/shapes/edit-shape-layer/events.js.map +1 -0
  76. package/dist/deckgl/shapes/edit-shape-layer/fiber.d.ts +13 -0
  77. package/dist/deckgl/shapes/edit-shape-layer/fiber.js +14 -0
  78. package/dist/deckgl/shapes/edit-shape-layer/index.d.ts +63 -0
  79. package/dist/deckgl/shapes/edit-shape-layer/index.js +162 -0
  80. package/dist/deckgl/shapes/edit-shape-layer/index.js.map +1 -0
  81. package/dist/deckgl/shapes/edit-shape-layer/modes/base-transform-mode.js +154 -0
  82. package/dist/deckgl/shapes/edit-shape-layer/modes/base-transform-mode.js.map +1 -0
  83. package/dist/deckgl/shapes/edit-shape-layer/modes/bounding-transform-mode.js +147 -0
  84. package/dist/deckgl/shapes/edit-shape-layer/modes/bounding-transform-mode.js.map +1 -0
  85. package/dist/deckgl/shapes/edit-shape-layer/modes/circle-transform-mode.js +87 -0
  86. package/dist/deckgl/shapes/edit-shape-layer/modes/circle-transform-mode.js.map +1 -0
  87. package/dist/deckgl/shapes/edit-shape-layer/modes/index.js +61 -0
  88. package/dist/deckgl/shapes/edit-shape-layer/modes/index.js.map +1 -0
  89. package/dist/deckgl/shapes/edit-shape-layer/modes/rotate-mode-with-snap.js +109 -0
  90. package/dist/deckgl/shapes/edit-shape-layer/modes/rotate-mode-with-snap.js.map +1 -0
  91. package/dist/deckgl/shapes/edit-shape-layer/modes/scale-mode-with-free-transform.js +289 -0
  92. package/dist/deckgl/shapes/edit-shape-layer/modes/scale-mode-with-free-transform.js.map +1 -0
  93. package/dist/deckgl/shapes/edit-shape-layer/modes/vertex-transform-mode.js +121 -0
  94. package/dist/deckgl/shapes/edit-shape-layer/modes/vertex-transform-mode.js.map +1 -0
  95. package/dist/deckgl/shapes/edit-shape-layer/store.js +194 -0
  96. package/dist/deckgl/shapes/edit-shape-layer/store.js.map +1 -0
  97. package/dist/deckgl/shapes/edit-shape-layer/types.d.ts +93 -0
  98. package/dist/deckgl/shapes/edit-shape-layer/types.js +14 -0
  99. package/dist/deckgl/shapes/edit-shape-layer/use-edit-shape.d.ts +82 -0
  100. package/dist/deckgl/shapes/edit-shape-layer/use-edit-shape.js +114 -0
  101. package/dist/deckgl/shapes/edit-shape-layer/use-edit-shape.js.map +1 -0
  102. package/dist/deckgl/shapes/index.d.ts +15 -6
  103. package/dist/deckgl/shapes/index.js +12 -5
  104. package/dist/deckgl/shapes/shared/constants.d.ts +27 -32
  105. package/dist/deckgl/shapes/shared/constants.js +189 -25
  106. package/dist/deckgl/shapes/shared/constants.js.map +1 -1
  107. package/dist/deckgl/shapes/shared/events.d.ts +1 -20
  108. package/dist/deckgl/shapes/shared/events.js +1 -31
  109. package/dist/deckgl/shapes/shared/events.js.map +1 -1
  110. package/dist/deckgl/shapes/shared/hooks/use-shift-zoom-disable.js +84 -0
  111. package/dist/deckgl/shapes/shared/hooks/use-shift-zoom-disable.js.map +1 -0
  112. package/dist/deckgl/shapes/shared/types.d.ts +187 -28
  113. package/dist/deckgl/shapes/shared/types.js +55 -1
  114. package/dist/deckgl/shapes/shared/types.js.map +1 -1
  115. package/dist/deckgl/shapes/shared/utils/geometry-measurements.js +128 -0
  116. package/dist/deckgl/shapes/shared/utils/geometry-measurements.js.map +1 -0
  117. package/dist/deckgl/shapes/shared/utils/layer-config.js +50 -0
  118. package/dist/deckgl/shapes/shared/utils/layer-config.js.map +1 -0
  119. package/dist/deckgl/shapes/shared/utils/mode-utils.js +113 -0
  120. package/dist/deckgl/shapes/shared/utils/mode-utils.js.map +1 -0
  121. package/dist/deckgl/shapes/shared/utils/pick-filtering.js +57 -0
  122. package/dist/deckgl/shapes/shared/utils/pick-filtering.js.map +1 -0
  123. package/dist/deckgl/shapes/shared/utils/style-utils.d.ts +64 -0
  124. package/dist/deckgl/shapes/shared/utils/style-utils.js +101 -0
  125. package/dist/deckgl/shapes/shared/utils/style-utils.js.map +1 -0
  126. package/dist/deckgl/text-layer/default-settings.js +4 -24
  127. package/dist/deckgl/text-layer/default-settings.js.map +1 -1
  128. package/dist/deckgl/text-settings.d.ts +77 -0
  129. package/dist/deckgl/text-settings.js +83 -0
  130. package/dist/deckgl/text-settings.js.map +1 -0
  131. package/dist/map-cursor/index.d.ts +2 -2
  132. package/dist/map-cursor/index.js +2 -2
  133. package/dist/map-cursor/store.d.ts +32 -61
  134. package/dist/map-cursor/store.js +165 -294
  135. package/dist/map-cursor/store.js.map +1 -1
  136. package/dist/map-cursor/use-map-cursor.d.ts +5 -2
  137. package/dist/map-cursor/use-map-cursor.js +33 -15
  138. package/dist/map-cursor/use-map-cursor.js.map +1 -1
  139. package/dist/map-mode/index.d.ts +2 -2
  140. package/dist/map-mode/index.js +2 -2
  141. package/dist/map-mode/store.d.ts +36 -37
  142. package/dist/map-mode/store.js +131 -237
  143. package/dist/map-mode/store.js.map +1 -1
  144. package/dist/map-mode/use-map-mode.js +6 -5
  145. package/dist/map-mode/use-map-mode.js.map +1 -1
  146. package/dist/maplibre/index.d.ts +2 -2
  147. package/dist/maplibre/index.js +2 -2
  148. package/dist/shared/constants.d.ts +19 -0
  149. package/dist/shared/constants.js +33 -0
  150. package/dist/shared/constants.js.map +1 -0
  151. package/dist/shared/create-map-store.d.ts +202 -0
  152. package/dist/shared/create-map-store.js +223 -0
  153. package/dist/shared/create-map-store.js.map +1 -0
  154. package/dist/shared/units.d.ts +39 -0
  155. package/dist/shared/units.js +49 -0
  156. package/dist/shared/units.js.map +1 -0
  157. package/dist/viewport/index.d.ts +3 -3
  158. package/dist/viewport/index.js +3 -3
  159. package/dist/viewport/store.d.ts +69 -0
  160. package/dist/viewport/store.js +125 -0
  161. package/dist/viewport/store.js.map +1 -0
  162. package/dist/viewport/types.d.ts +2 -2
  163. package/dist/viewport/utils.js +2 -2
  164. package/dist/viewport/utils.js.map +1 -1
  165. package/dist/viewport/viewport-size.d.ts +2 -2
  166. package/dist/viewport/viewport-size.js +2 -2
  167. package/dist/viewport/viewport-size.js.map +1 -1
  168. package/package.json +36 -18
  169. package/dist/camera/use-camera-state.d.ts +0 -153
  170. package/dist/camera/use-camera-state.js +0 -418
  171. package/dist/camera/use-camera-state.js.map +0 -1
  172. package/dist/deckgl/shapes/display-shape-layer/constants.d.ts +0 -44
  173. package/dist/deckgl/shapes/display-shape-layer/shape-label-layer.d.ts +0 -66
  174. package/dist/deckgl/shapes/display-shape-layer/store.d.ts +0 -87
  175. package/dist/deckgl/shapes/display-shape-layer/use-shape-selection.js.map +0 -1
  176. package/dist/deckgl/shapes/display-shape-layer/utils/display-style.d.ts +0 -61
  177. package/dist/maplibre/constants.d.ts +0 -13
  178. package/dist/maplibre/constants.js.map +0 -1
  179. package/dist/viewport/constants.d.ts +0 -11
  180. package/dist/viewport/constants.js.map +0 -1
  181. package/dist/viewport/use-viewport-state.d.ts +0 -100
  182. package/dist/viewport/use-viewport-state.js +0 -222
  183. package/dist/viewport/use-viewport-state.js.map +0 -1
@@ -10,6 +10,7 @@
10
10
  * governing permissions and limitations under the License.
11
11
  */
12
12
 
13
+ import { DistanceUnit } from "../../../shared/units.js";
13
14
  import { UniqueId } from "@accelint/core";
14
15
  import { Color } from "@deck.gl/core";
15
16
  import { Feature, LineString, Point, Polygon } from "geojson";
@@ -20,7 +21,9 @@ import { Feature, LineString, Point, Polygon } from "geojson";
20
21
  */
21
22
  declare const ShapeFeatureType: {
22
23
  readonly Circle: "Circle";
24
+ readonly Ellipse: "Ellipse";
23
25
  readonly Polygon: "Polygon";
26
+ readonly Rectangle: "Rectangle";
24
27
  readonly LineString: "LineString";
25
28
  readonly Point: "Point";
26
29
  };
@@ -30,25 +33,27 @@ type ShapeFeatureType = (typeof ShapeFeatureType)[keyof typeof ShapeFeatureType]
30
33
  */
31
34
  type ShapeId = UniqueId;
32
35
  /**
33
- * Stroke width options (in pixels)
36
+ * Border/outline width options (in pixels).
37
+ * Controls the width of shape outlines.
34
38
  */
35
- type StrokeWidth = 1 | 2 | 4 | 8;
39
+ type LineWidth = 1 | 2 | 4 | 8;
36
40
  /**
37
- * Stroke pattern options
41
+ * Border/outline pattern options.
42
+ * Controls how shape outlines are rendered.
38
43
  */
39
- type StrokePattern = 'solid' | 'dashed' | 'dotted';
44
+ type LinePattern = 'solid' | 'dashed' | 'dotted';
40
45
  /**
41
46
  * Style properties for rendering shapes
42
47
  */
43
48
  interface StyleProperties {
44
49
  /** Fill color as RGBA array [r, g, b, a] where each value is 0-255 */
45
50
  fillColor: Color;
46
- /** Stroke color as RGBA array [r, g, b, a] where each value is 0-255 */
47
- strokeColor: Color;
48
- /** Stroke width in pixels */
49
- strokeWidth: StrokeWidth;
50
- /** Stroke pattern */
51
- strokePattern: StrokePattern;
51
+ /** Border/outline color as RGBA array [r, g, b, a] where each value is 0-255 */
52
+ lineColor: Color;
53
+ /** Border/outline width in pixels */
54
+ lineWidth: LineWidth;
55
+ /** Border/outline pattern (solid, dashed, or dotted) */
56
+ linePattern: LinePattern;
52
57
  /** Optional icon properties for Point geometries */
53
58
  icon?: {
54
59
  /** Icon atlas URL or data */
@@ -86,31 +91,81 @@ interface CircleProperties {
86
91
  radius: {
87
92
  /** Radius value */
88
93
  value: number;
89
- /** Units (hardcoded to kilometers for v1) */
90
- units: 'kilometers';
94
+ /** Units for the radius measurement */
95
+ units: DistanceUnit;
91
96
  };
92
97
  }
98
+ /**
99
+ * Ellipse-specific properties for precise rendering
100
+ * Stored alongside the polygon approximation
101
+ */
102
+ interface EllipseProperties {
103
+ /** Center point as [longitude, latitude] */
104
+ center: [number, number];
105
+ /** X semi-axis (horizontal radius) with value and units */
106
+ xSemiAxis: {
107
+ /** X semi-axis value */
108
+ value: number;
109
+ /** Units for the measurement */
110
+ units: DistanceUnit;
111
+ };
112
+ /** Y semi-axis (vertical radius) with value and units */
113
+ ySemiAxis: {
114
+ /** Y semi-axis value */
115
+ value: number;
116
+ /** Units for the measurement */
117
+ units: DistanceUnit;
118
+ };
119
+ /** Rotation angle in degrees */
120
+ angle: number;
121
+ }
93
122
  /**
94
123
  * Custom geometry types supported
95
124
  */
96
125
  type CustomGeometry = Point | LineString | Polygon;
126
+ /**
127
+ * Properties for styled features.
128
+ *
129
+ * Note: circleProperties and ellipseProperties are optional at the type level
130
+ * but are guaranteed to be present for their respective shape types.
131
+ * Use the type guards (isCircleShape, isEllipseShape) for type narrowing.
132
+ */
133
+ interface StyledFeatureProperties {
134
+ /** Style properties for rendering */
135
+ styleProperties: StyleProperties;
136
+ /** Shape ID for correlation */
137
+ shapeId?: ShapeId;
138
+ /** Circle properties (present for Circle shapes) */
139
+ circleProperties?: CircleProperties;
140
+ /** Ellipse properties (present for Ellipse shapes) */
141
+ ellipseProperties?: EllipseProperties;
142
+ }
143
+ /**
144
+ * Feature properties for Circle shapes (circleProperties required).
145
+ * Used by CircleShape for better type narrowing.
146
+ */
147
+ interface CircleFeatureProperties extends StyledFeatureProperties {
148
+ /** Circle properties (required for Circle shapes) */
149
+ circleProperties: CircleProperties;
150
+ }
151
+ /**
152
+ * Feature properties for Ellipse shapes (ellipseProperties required).
153
+ * Used by EllipseShape for better type narrowing.
154
+ */
155
+ interface EllipseFeatureProperties extends StyledFeatureProperties {
156
+ /** Ellipse properties (required for Ellipse shapes) */
157
+ ellipseProperties: EllipseProperties;
158
+ }
97
159
  /**
98
160
  * GeoJSON Feature with style properties
99
161
  */
100
162
  interface StyledFeature extends Feature {
101
- properties: {
102
- /** Style properties for rendering */
103
- styleProperties: StyleProperties;
104
- /** Circle properties (only for Circle type shapes) */
105
- circleProperties?: CircleProperties;
106
- /** Shape ID for correlation */
107
- shapeId?: ShapeId;
108
- };
163
+ properties: StyledFeatureProperties;
109
164
  }
110
165
  /**
111
- * Shape data structure for DisplayShapeLayer
166
+ * Base shape properties shared by all shapes
112
167
  */
113
- interface DisplayShape {
168
+ interface BaseShape {
114
169
  /** Unique identifier */
115
170
  id: ShapeId;
116
171
  /** Full shape name used internally and in UI */
@@ -121,18 +176,77 @@ interface DisplayShape {
121
176
  * Useful for showing abbreviated text on the map (e.g., "NYC" vs "New York City Office")
122
177
  */
123
178
  label?: string;
124
- /** Shape type */
125
- shapeType: ShapeFeatureTypeValues;
126
179
  /** GeoJSON feature with geometry and style properties */
127
180
  feature: ShapeFeature;
128
181
  /** UTC timestamp (only set when saved) */
129
182
  lastUpdated?: number;
183
+ /**
184
+ * Whether the shape is locked for editing
185
+ * Locked shapes cannot be modified due to data restrictions or user preference
186
+ */
187
+ locked?: boolean;
188
+ }
189
+ /**
190
+ * Circle shape with required circleProperties
191
+ */
192
+ interface CircleShape extends BaseShape {
193
+ shape: typeof ShapeFeatureType.Circle;
194
+ feature: StyledFeature & {
195
+ properties: CircleFeatureProperties;
196
+ };
197
+ }
198
+ /**
199
+ * Ellipse shape with required ellipseProperties
200
+ */
201
+ interface EllipseShape extends BaseShape {
202
+ shape: typeof ShapeFeatureType.Ellipse;
203
+ feature: StyledFeature & {
204
+ properties: EllipseFeatureProperties;
205
+ };
206
+ }
207
+ /**
208
+ * Polygon shape
209
+ */
210
+ interface PolygonShape extends BaseShape {
211
+ shape: typeof ShapeFeatureType.Polygon;
212
+ feature: StyledFeature;
130
213
  }
131
214
  /**
132
- * Alias for backward compatibility
133
- * @deprecated Use DisplayShape instead
215
+ * Rectangle shape
134
216
  */
135
- type EditableShape = DisplayShape;
217
+ interface RectangleShape extends BaseShape {
218
+ shape: typeof ShapeFeatureType.Rectangle;
219
+ feature: StyledFeature;
220
+ }
221
+ /**
222
+ * LineString shape
223
+ */
224
+ interface LineStringShape extends BaseShape {
225
+ shape: typeof ShapeFeatureType.LineString;
226
+ feature: StyledFeature;
227
+ }
228
+ /**
229
+ * Point shape
230
+ */
231
+ interface PointShape extends BaseShape {
232
+ shape: typeof ShapeFeatureType.Point;
233
+ feature: StyledFeature;
234
+ }
235
+ /**
236
+ * Discriminated union of all shape types.
237
+ *
238
+ * Use this for type narrowing based on shape:
239
+ * @example
240
+ * ```ts
241
+ * function handleShape(shape: Shape) {
242
+ * if (shape.shape === 'Circle') {
243
+ * // TypeScript knows shape.feature.properties.circleProperties exists
244
+ * const { center, radius } = shape.feature.properties.circleProperties;
245
+ * }
246
+ * }
247
+ * ```
248
+ */
249
+ type Shape = CircleShape | EllipseShape | PolygonShape | RectangleShape | LineStringShape | PointShape;
136
250
  /**
137
251
  * Alias for ShapeFeatureType values
138
252
  */
@@ -153,6 +267,51 @@ type CircleRadius = CircleProperties['radius'];
153
267
  * Coordinate as [longitude, latitude]
154
268
  */
155
269
  type Coordinate = [number, number];
270
+ /**
271
+ * Function type for subscription (useSyncExternalStore pattern).
272
+ * Used by draw-shape-layer and edit-shape-layer stores.
273
+ */
274
+ type Subscription = (onStoreChange: () => void) => () => void;
275
+ /**
276
+ * Type guard for Circle shapes.
277
+ *
278
+ * @example
279
+ * ```ts
280
+ * if (isCircleShape(shape)) {
281
+ * // shape.feature.properties.circleProperties is available
282
+ * const { center, radius } = shape.feature.properties.circleProperties;
283
+ * }
284
+ * ```
285
+ */
286
+ declare function isCircleShape(shape: Shape): shape is CircleShape;
287
+ /**
288
+ * Type guard for Ellipse shapes.
289
+ *
290
+ * @example
291
+ * ```ts
292
+ * if (isEllipseShape(shape)) {
293
+ * // shape.feature.properties.ellipseProperties is available
294
+ * const { center, xSemiAxis, ySemiAxis } = shape.feature.properties.ellipseProperties;
295
+ * }
296
+ * ```
297
+ */
298
+ declare function isEllipseShape(shape: Shape): shape is EllipseShape;
299
+ /**
300
+ * Type guard for Polygon shapes.
301
+ */
302
+ declare function isPolygonShape(shape: Shape): shape is PolygonShape;
303
+ /**
304
+ * Type guard for Rectangle shapes.
305
+ */
306
+ declare function isRectangleShape(shape: Shape): shape is RectangleShape;
307
+ /**
308
+ * Type guard for LineString shapes.
309
+ */
310
+ declare function isLineStringShape(shape: Shape): shape is LineStringShape;
311
+ /**
312
+ * Type guard for Point shapes.
313
+ */
314
+ declare function isPointShape(shape: Shape): shape is PointShape;
156
315
  //#endregion
157
- export { CircleProperties, CircleRadius, Coordinate, CustomGeometry, DisplayShape, EditableShape, ShapeFeature, ShapeFeatureProperties, ShapeFeatureType, ShapeFeatureTypeValues, ShapeId, StrokePattern, StrokeWidth, StyleProperties, StyledFeature };
316
+ export { CircleFeatureProperties, CircleProperties, CircleRadius, CircleShape, Coordinate, CustomGeometry, EllipseFeatureProperties, EllipseProperties, EllipseShape, LinePattern, LineStringShape, LineWidth, PointShape, PolygonShape, RectangleShape, Shape, ShapeFeature, ShapeFeatureProperties, ShapeFeatureType, ShapeFeatureTypeValues, ShapeId, StyleProperties, StyledFeature, StyledFeatureProperties, Subscription, isCircleShape, isEllipseShape, isLineStringShape, isPointShape, isPolygonShape, isRectangleShape };
158
317
  //# sourceMappingURL=types.d.ts.map
@@ -19,11 +19,65 @@
19
19
  */
20
20
  const ShapeFeatureType = {
21
21
  Circle: "Circle",
22
+ Ellipse: "Ellipse",
22
23
  Polygon: "Polygon",
24
+ Rectangle: "Rectangle",
23
25
  LineString: "LineString",
24
26
  Point: "Point"
25
27
  };
28
+ /**
29
+ * Type guard for Circle shapes.
30
+ *
31
+ * @example
32
+ * ```ts
33
+ * if (isCircleShape(shape)) {
34
+ * // shape.feature.properties.circleProperties is available
35
+ * const { center, radius } = shape.feature.properties.circleProperties;
36
+ * }
37
+ * ```
38
+ */
39
+ function isCircleShape(shape) {
40
+ return shape.shape === ShapeFeatureType.Circle;
41
+ }
42
+ /**
43
+ * Type guard for Ellipse shapes.
44
+ *
45
+ * @example
46
+ * ```ts
47
+ * if (isEllipseShape(shape)) {
48
+ * // shape.feature.properties.ellipseProperties is available
49
+ * const { center, xSemiAxis, ySemiAxis } = shape.feature.properties.ellipseProperties;
50
+ * }
51
+ * ```
52
+ */
53
+ function isEllipseShape(shape) {
54
+ return shape.shape === ShapeFeatureType.Ellipse;
55
+ }
56
+ /**
57
+ * Type guard for Polygon shapes.
58
+ */
59
+ function isPolygonShape(shape) {
60
+ return shape.shape === ShapeFeatureType.Polygon;
61
+ }
62
+ /**
63
+ * Type guard for Rectangle shapes.
64
+ */
65
+ function isRectangleShape(shape) {
66
+ return shape.shape === ShapeFeatureType.Rectangle;
67
+ }
68
+ /**
69
+ * Type guard for LineString shapes.
70
+ */
71
+ function isLineStringShape(shape) {
72
+ return shape.shape === ShapeFeatureType.LineString;
73
+ }
74
+ /**
75
+ * Type guard for Point shapes.
76
+ */
77
+ function isPointShape(shape) {
78
+ return shape.shape === ShapeFeatureType.Point;
79
+ }
26
80
 
27
81
  //#endregion
28
- export { ShapeFeatureType };
82
+ export { ShapeFeatureType, isCircleShape, isEllipseShape, isLineStringShape, isPointShape, isPolygonShape, isRectangleShape };
29
83
  //# sourceMappingURL=types.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"types.js","names":[],"sources":["../../../../src/deckgl/shapes/shared/types.ts"],"sourcesContent":["/*\n * Copyright 2025 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 type { UniqueId } from '@accelint/core';\nimport type { Color } from '@deck.gl/core';\nimport type { Feature, LineString, Point, Polygon } from 'geojson';\n\n/**\n * Supported shape types\n */\nexport const ShapeFeatureType = {\n Circle: 'Circle',\n Polygon: 'Polygon',\n LineString: 'LineString',\n Point: 'Point',\n} as const;\n\nexport type ShapeFeatureType =\n (typeof ShapeFeatureType)[keyof typeof ShapeFeatureType];\n\n/**\n * Shape ID type - uses UniqueId from core\n */\nexport type ShapeId = UniqueId;\n\n/**\n * Stroke width options (in pixels)\n */\nexport type StrokeWidth = 1 | 2 | 4 | 8;\n\n/**\n * Stroke pattern options\n */\nexport type StrokePattern = 'solid' | 'dashed' | 'dotted';\n\n/**\n * Style properties for rendering shapes\n */\nexport interface StyleProperties {\n /** Fill color as RGBA array [r, g, b, a] where each value is 0-255 */\n fillColor: Color;\n /** Stroke color as RGBA array [r, g, b, a] where each value is 0-255 */\n strokeColor: Color;\n /** Stroke width in pixels */\n strokeWidth: StrokeWidth;\n /** Stroke pattern */\n strokePattern: StrokePattern;\n /** Optional icon properties for Point geometries */\n icon?: {\n /** Icon atlas URL or data */\n atlas?: string;\n /** Icon mapping (name to position in atlas) */\n mapping?: Record<\n string,\n { x: number; y: number; width: number; height: number; mask?: boolean }\n >;\n /** Icon name to use from mapping */\n name?: string;\n /** Icon size in pixels */\n size?: number;\n };\n /** Optional custom label pixel offset [x, y] */\n labelOffset?: [number, number];\n /** Optional custom label vertical anchor */\n labelVerticalAnchor?: 'top' | 'middle' | 'bottom';\n /** Optional custom label horizontal anchor */\n labelHorizontalAnchor?: 'left' | 'center' | 'right';\n /** Optional custom label coordinate anchor (position along geometry) */\n labelCoordinateAnchor?:\n | 'center'\n | 'start'\n | 'middle'\n | 'end'\n | 'top'\n | 'right'\n | 'bottom'\n | 'left';\n}\n\n/**\n * Circle-specific properties for precise rendering\n * Stored alongside the polygon approximation\n */\nexport interface CircleProperties {\n /** Center point as [longitude, latitude] */\n center: [number, number];\n /** Radius with value and units */\n radius: {\n /** Radius value */\n value: number;\n /** Units (hardcoded to kilometers for v1) */\n units: 'kilometers';\n };\n}\n\n/**\n * Custom geometry types supported\n */\nexport type CustomGeometry = Point | LineString | Polygon;\n\n/**\n * GeoJSON Feature with style properties\n */\nexport interface StyledFeature extends Feature {\n properties: {\n /** Style properties for rendering */\n styleProperties: StyleProperties;\n /** Circle properties (only for Circle type shapes) */\n circleProperties?: CircleProperties;\n /** Shape ID for correlation */\n shapeId?: ShapeId;\n };\n}\n\n/**\n * Shape data structure for DisplayShapeLayer\n */\nexport interface DisplayShape {\n /** Unique identifier */\n id: ShapeId;\n /** Full shape name used internally and in UI */\n name: string;\n /**\n * Optional short display label shown on the map\n * If not provided, the `name` property will be used instead\n * Useful for showing abbreviated text on the map (e.g., \"NYC\" vs \"New York City Office\")\n */\n label?: string;\n /** Shape type */\n shapeType: ShapeFeatureTypeValues;\n /** GeoJSON feature with geometry and style properties */\n feature: ShapeFeature;\n /** UTC timestamp (only set when saved) */\n lastUpdated?: number;\n}\n\n/**\n * Alias for backward compatibility\n * @deprecated Use DisplayShape instead\n */\nexport type EditableShape = DisplayShape;\n\n/**\n * Alias for ShapeFeatureType values\n */\nexport type ShapeFeatureTypeValues = ShapeFeatureType;\n\n/**\n * Alias for StyledFeature (shape feature)\n */\nexport type ShapeFeature = StyledFeature;\n\n/**\n * Alias for StyledFeature properties\n */\nexport type ShapeFeatureProperties = StyledFeature['properties'];\n\n/**\n * Circle radius type\n */\nexport type CircleRadius = CircleProperties['radius'];\n\n/**\n * Coordinate as [longitude, latitude]\n */\nexport type Coordinate = [number, number];\n"],"mappings":";;;;;;;;;;;;;;;;;;;AAqBA,MAAa,mBAAmB;CAC9B,QAAQ;CACR,SAAS;CACT,YAAY;CACZ,OAAO;CACR"}
1
+ {"version":3,"file":"types.js","names":[],"sources":["../../../../src/deckgl/shapes/shared/types.ts"],"sourcesContent":["/*\n * Copyright 2025 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 type { UniqueId } from '@accelint/core';\nimport type { Color } from '@deck.gl/core';\nimport type { Feature, LineString, Point, Polygon } from 'geojson';\nimport type { DistanceUnit } from '@/shared/units';\n\n/**\n * Supported shape types\n */\nexport const ShapeFeatureType = {\n Circle: 'Circle',\n Ellipse: 'Ellipse',\n Polygon: 'Polygon',\n Rectangle: 'Rectangle',\n LineString: 'LineString',\n Point: 'Point',\n} as const;\n\nexport type ShapeFeatureType =\n (typeof ShapeFeatureType)[keyof typeof ShapeFeatureType];\n\n/**\n * Shape ID type - uses UniqueId from core\n */\nexport type ShapeId = UniqueId;\n\n/**\n * Border/outline width options (in pixels).\n * Controls the width of shape outlines.\n */\nexport type LineWidth = 1 | 2 | 4 | 8;\n\n/**\n * Border/outline pattern options.\n * Controls how shape outlines are rendered.\n */\nexport type LinePattern = 'solid' | 'dashed' | 'dotted';\n\n/**\n * Style properties for rendering shapes\n */\nexport interface StyleProperties {\n /** Fill color as RGBA array [r, g, b, a] where each value is 0-255 */\n fillColor: Color;\n /** Border/outline color as RGBA array [r, g, b, a] where each value is 0-255 */\n lineColor: Color;\n /** Border/outline width in pixels */\n lineWidth: LineWidth;\n /** Border/outline pattern (solid, dashed, or dotted) */\n linePattern: LinePattern;\n /** Optional icon properties for Point geometries */\n icon?: {\n /** Icon atlas URL or data */\n atlas?: string;\n /** Icon mapping (name to position in atlas) */\n mapping?: Record<\n string,\n { x: number; y: number; width: number; height: number; mask?: boolean }\n >;\n /** Icon name to use from mapping */\n name?: string;\n /** Icon size in pixels */\n size?: number;\n };\n /** Optional custom label pixel offset [x, y] */\n labelOffset?: [number, number];\n /** Optional custom label vertical anchor */\n labelVerticalAnchor?: 'top' | 'middle' | 'bottom';\n /** Optional custom label horizontal anchor */\n labelHorizontalAnchor?: 'left' | 'center' | 'right';\n /** Optional custom label coordinate anchor (position along geometry) */\n labelCoordinateAnchor?:\n | 'center'\n | 'start'\n | 'middle'\n | 'end'\n | 'top'\n | 'right'\n | 'bottom'\n | 'left';\n}\n\n/**\n * Circle-specific properties for precise rendering\n * Stored alongside the polygon approximation\n */\nexport interface CircleProperties {\n /** Center point as [longitude, latitude] */\n center: [number, number];\n /** Radius with value and units */\n radius: {\n /** Radius value */\n value: number;\n /** Units for the radius measurement */\n units: DistanceUnit;\n };\n}\n\n/**\n * Ellipse-specific properties for precise rendering\n * Stored alongside the polygon approximation\n */\nexport interface EllipseProperties {\n /** Center point as [longitude, latitude] */\n center: [number, number];\n /** X semi-axis (horizontal radius) with value and units */\n xSemiAxis: {\n /** X semi-axis value */\n value: number;\n /** Units for the measurement */\n units: DistanceUnit;\n };\n /** Y semi-axis (vertical radius) with value and units */\n ySemiAxis: {\n /** Y semi-axis value */\n value: number;\n /** Units for the measurement */\n units: DistanceUnit;\n };\n /** Rotation angle in degrees */\n angle: number;\n}\n\n/**\n * Custom geometry types supported\n */\nexport type CustomGeometry = Point | LineString | Polygon;\n\n/**\n * Properties for styled features.\n *\n * Note: circleProperties and ellipseProperties are optional at the type level\n * but are guaranteed to be present for their respective shape types.\n * Use the type guards (isCircleShape, isEllipseShape) for type narrowing.\n */\nexport interface StyledFeatureProperties {\n /** Style properties for rendering */\n styleProperties: StyleProperties;\n /** Shape ID for correlation */\n shapeId?: ShapeId;\n /** Circle properties (present for Circle shapes) */\n circleProperties?: CircleProperties;\n /** Ellipse properties (present for Ellipse shapes) */\n ellipseProperties?: EllipseProperties;\n}\n\n/**\n * Feature properties for Circle shapes (circleProperties required).\n * Used by CircleShape for better type narrowing.\n */\nexport interface CircleFeatureProperties extends StyledFeatureProperties {\n /** Circle properties (required for Circle shapes) */\n circleProperties: CircleProperties;\n}\n\n/**\n * Feature properties for Ellipse shapes (ellipseProperties required).\n * Used by EllipseShape for better type narrowing.\n */\nexport interface EllipseFeatureProperties extends StyledFeatureProperties {\n /** Ellipse properties (required for Ellipse shapes) */\n ellipseProperties: EllipseProperties;\n}\n\n/**\n * GeoJSON Feature with style properties\n */\nexport interface StyledFeature extends Feature {\n properties: StyledFeatureProperties;\n}\n\n/**\n * Base shape properties shared by all shapes\n */\ninterface BaseShape {\n /** Unique identifier */\n id: ShapeId;\n /** Full shape name used internally and in UI */\n name: string;\n /**\n * Optional short display label shown on the map\n * If not provided, the `name` property will be used instead\n * Useful for showing abbreviated text on the map (e.g., \"NYC\" vs \"New York City Office\")\n */\n label?: string;\n /** GeoJSON feature with geometry and style properties */\n feature: ShapeFeature;\n /** UTC timestamp (only set when saved) */\n lastUpdated?: number;\n /**\n * Whether the shape is locked for editing\n * Locked shapes cannot be modified due to data restrictions or user preference\n */\n locked?: boolean;\n}\n\n/**\n * Circle shape with required circleProperties\n */\nexport interface CircleShape extends BaseShape {\n shape: typeof ShapeFeatureType.Circle;\n feature: StyledFeature & { properties: CircleFeatureProperties };\n}\n\n/**\n * Ellipse shape with required ellipseProperties\n */\nexport interface EllipseShape extends BaseShape {\n shape: typeof ShapeFeatureType.Ellipse;\n feature: StyledFeature & { properties: EllipseFeatureProperties };\n}\n\n/**\n * Polygon shape\n */\nexport interface PolygonShape extends BaseShape {\n shape: typeof ShapeFeatureType.Polygon;\n feature: StyledFeature;\n}\n\n/**\n * Rectangle shape\n */\nexport interface RectangleShape extends BaseShape {\n shape: typeof ShapeFeatureType.Rectangle;\n feature: StyledFeature;\n}\n\n/**\n * LineString shape\n */\nexport interface LineStringShape extends BaseShape {\n shape: typeof ShapeFeatureType.LineString;\n feature: StyledFeature;\n}\n\n/**\n * Point shape\n */\nexport interface PointShape extends BaseShape {\n shape: typeof ShapeFeatureType.Point;\n feature: StyledFeature;\n}\n\n/**\n * Discriminated union of all shape types.\n *\n * Use this for type narrowing based on shape:\n * @example\n * ```ts\n * function handleShape(shape: Shape) {\n * if (shape.shape === 'Circle') {\n * // TypeScript knows shape.feature.properties.circleProperties exists\n * const { center, radius } = shape.feature.properties.circleProperties;\n * }\n * }\n * ```\n */\nexport type Shape =\n | CircleShape\n | EllipseShape\n | PolygonShape\n | RectangleShape\n | LineStringShape\n | PointShape;\n\n/**\n * Alias for ShapeFeatureType values\n */\nexport type ShapeFeatureTypeValues = ShapeFeatureType;\n\n/**\n * Alias for StyledFeature (shape feature)\n */\nexport type ShapeFeature = StyledFeature;\n\n/**\n * Alias for StyledFeature properties\n */\nexport type ShapeFeatureProperties = StyledFeature['properties'];\n\n/**\n * Circle radius type\n */\nexport type CircleRadius = CircleProperties['radius'];\n\n/**\n * Coordinate as [longitude, latitude]\n */\nexport type Coordinate = [number, number];\n\n/**\n * Function type for subscription (useSyncExternalStore pattern).\n * Used by draw-shape-layer and edit-shape-layer stores.\n */\nexport type Subscription = (onStoreChange: () => void) => () => void;\n\n// =============================================================================\n// Type Guards\n// =============================================================================\n\n/**\n * Type guard for Circle shapes.\n *\n * @example\n * ```ts\n * if (isCircleShape(shape)) {\n * // shape.feature.properties.circleProperties is available\n * const { center, radius } = shape.feature.properties.circleProperties;\n * }\n * ```\n */\nexport function isCircleShape(shape: Shape): shape is CircleShape {\n return shape.shape === ShapeFeatureType.Circle;\n}\n\n/**\n * Type guard for Ellipse shapes.\n *\n * @example\n * ```ts\n * if (isEllipseShape(shape)) {\n * // shape.feature.properties.ellipseProperties is available\n * const { center, xSemiAxis, ySemiAxis } = shape.feature.properties.ellipseProperties;\n * }\n * ```\n */\nexport function isEllipseShape(shape: Shape): shape is EllipseShape {\n return shape.shape === ShapeFeatureType.Ellipse;\n}\n\n/**\n * Type guard for Polygon shapes.\n */\nexport function isPolygonShape(shape: Shape): shape is PolygonShape {\n return shape.shape === ShapeFeatureType.Polygon;\n}\n\n/**\n * Type guard for Rectangle shapes.\n */\nexport function isRectangleShape(shape: Shape): shape is RectangleShape {\n return shape.shape === ShapeFeatureType.Rectangle;\n}\n\n/**\n * Type guard for LineString shapes.\n */\nexport function isLineStringShape(shape: Shape): shape is LineStringShape {\n return shape.shape === ShapeFeatureType.LineString;\n}\n\n/**\n * Type guard for Point shapes.\n */\nexport function isPointShape(shape: Shape): shape is PointShape {\n return shape.shape === ShapeFeatureType.Point;\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;AAsBA,MAAa,mBAAmB;CAC9B,QAAQ;CACR,SAAS;CACT,SAAS;CACT,WAAW;CACX,YAAY;CACZ,OAAO;CACR;;;;;;;;;;;;AAwSD,SAAgB,cAAc,OAAoC;AAChE,QAAO,MAAM,UAAU,iBAAiB;;;;;;;;;;;;;AAc1C,SAAgB,eAAe,OAAqC;AAClE,QAAO,MAAM,UAAU,iBAAiB;;;;;AAM1C,SAAgB,eAAe,OAAqC;AAClE,QAAO,MAAM,UAAU,iBAAiB;;;;;AAM1C,SAAgB,iBAAiB,OAAuC;AACtE,QAAO,MAAM,UAAU,iBAAiB;;;;;AAM1C,SAAgB,kBAAkB,OAAwC;AACxE,QAAO,MAAM,UAAU,iBAAiB;;;;;AAM1C,SAAgB,aAAa,OAAmC;AAC9D,QAAO,MAAM,UAAU,iBAAiB"}
@@ -0,0 +1,128 @@
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 { distance, point } from "@turf/turf";
17
+
18
+ //#region src/deckgl/shapes/shared/utils/geometry-measurements.ts
19
+ /**
20
+ * Compute circle measurements from center and edge point.
21
+ *
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
26
+ *
27
+ * @example
28
+ * ```ts
29
+ * const { radius, diameter, area } = computeCircleMeasurements(
30
+ * [-122.4, 37.8],
31
+ * [-122.3, 37.8],
32
+ * 'kilometers'
33
+ * );
34
+ * ```
35
+ */
36
+ function computeCircleMeasurements(center, edgePoint, units) {
37
+ const radius = distance(center, edgePoint, { units });
38
+ return {
39
+ radius,
40
+ diameter: radius * 2,
41
+ area: Math.PI * radius ** 2
42
+ };
43
+ }
44
+ /**
45
+ * Compute rectangle measurements from adjacent corner points.
46
+ *
47
+ * Uses geodesic distance calculations for accurate measurements on Earth's surface.
48
+ * Corners should be provided in order: corner0 -> corner1 -> corner2 where:
49
+ * - corner0 to corner1 defines one edge (width)
50
+ * - corner1 to corner2 defines the adjacent edge (height)
51
+ *
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
57
+ *
58
+ * @example
59
+ * ```ts
60
+ * const coords = polygon.geometry.coordinates[0];
61
+ * const { width, height, area } = computeRectangleMeasurementsFromCorners(
62
+ * coords[0] as [number, number],
63
+ * coords[1] as [number, number],
64
+ * coords[2] as [number, number],
65
+ * 'kilometers'
66
+ * );
67
+ * ```
68
+ */
69
+ function computeRectangleMeasurementsFromCorners(corner0, corner1, corner2, units) {
70
+ const width = distance(point(corner0), point(corner1), { units });
71
+ const height = distance(point(corner1), point(corner2), { units });
72
+ return {
73
+ width,
74
+ height,
75
+ area: width * height
76
+ };
77
+ }
78
+ /**
79
+ * Compute ellipse measurements from polygon coordinates.
80
+ *
81
+ * For an ellipse approximated as a polygon, calculates the major and minor axes
82
+ * by measuring distances between opposite points on the perimeter.
83
+ *
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
87
+ *
88
+ * @example
89
+ * ```ts
90
+ * const coords = polygon.geometry.coordinates[0];
91
+ * const { majorAxis, minorAxis, area } = computeEllipseMeasurementsFromPolygon(
92
+ * coords as [number, number][],
93
+ * 'kilometers'
94
+ * );
95
+ * ```
96
+ */
97
+ 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 {
100
+ majorAxis: 0,
101
+ minorAxis: 0,
102
+ area: 0
103
+ };
104
+ const halfLen = Math.floor(points.length / 2);
105
+ let maxDist = 0;
106
+ let minDist = Number.POSITIVE_INFINITY;
107
+ for (let i = 0; i < halfLen; i++) {
108
+ const p1 = points[i];
109
+ const p2 = points[i + halfLen];
110
+ if (!(p1 && p2)) continue;
111
+ const dist = distance([p1[0], p1[1]], [p2[0], p2[1]], { units });
112
+ if (dist > maxDist) maxDist = dist;
113
+ if (dist < minDist) minDist = dist;
114
+ }
115
+ const majorAxis = maxDist;
116
+ const minorAxis = minDist === Number.POSITIVE_INFINITY ? maxDist : minDist;
117
+ const semiMajor = majorAxis / 2;
118
+ const semiMinor = minorAxis / 2;
119
+ return {
120
+ majorAxis,
121
+ minorAxis,
122
+ area: Math.PI * semiMajor * semiMinor
123
+ };
124
+ }
125
+
126
+ //#endregion
127
+ export { computeCircleMeasurements, computeEllipseMeasurementsFromPolygon, computeRectangleMeasurementsFromCorners };
128
+ //# sourceMappingURL=geometry-measurements.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"geometry-measurements.js","names":[],"sources":["../../../../../src/deckgl/shapes/shared/utils/geometry-measurements.ts"],"sourcesContent":["/*\n * Copyright 2025 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 * ```ts\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 * ```ts\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 * ```ts\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 * ```ts\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"}
@@ -0,0 +1,50 @@
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 { DEFAULT_EDIT_HANDLE_COLOR, EDITABLE_LAYER_SUBLAYER_PROPS } from "../constants.js";
17
+ import { DEFAULT_DISTANCE_UNITS, getDistanceUnitFromAbbreviation } from "../../../../shared/units.js";
18
+
19
+ //#region src/deckgl/shapes/shared/utils/layer-config.ts
20
+ /**
21
+ * Returns default props for EditableGeoJsonLayer configuration.
22
+ *
23
+ * This consolidates the common configuration shared between DrawShapeLayer and EditShapeLayer:
24
+ * - Edit handle colors
25
+ * - Mode configuration with distance units
26
+ * - Sublayer props for tooltips and handles
27
+ *
28
+ * @param unitAbbrev - Optional unit abbreviation (e.g., 'km', 'mi'). Defaults to DEFAULT_DISTANCE_UNITS.
29
+ * @returns Default props to spread onto EditableGeoJsonLayer
30
+ *
31
+ * @example
32
+ * ```tsx
33
+ * <editableGeoJsonLayer
34
+ * {...getDefaultEditableLayerProps(unit)}
35
+ * // other props
36
+ * />
37
+ * ```
38
+ */
39
+ function getDefaultEditableLayerProps(unitAbbrev) {
40
+ return {
41
+ getEditHandlePointColor: DEFAULT_EDIT_HANDLE_COLOR,
42
+ getEditHandlePointOutlineColor: DEFAULT_EDIT_HANDLE_COLOR,
43
+ modeConfig: { distanceUnits: unitAbbrev ? getDistanceUnitFromAbbreviation(unitAbbrev) ?? DEFAULT_DISTANCE_UNITS : DEFAULT_DISTANCE_UNITS },
44
+ _subLayerProps: EDITABLE_LAYER_SUBLAYER_PROPS
45
+ };
46
+ }
47
+
48
+ //#endregion
49
+ export { getDefaultEditableLayerProps };
50
+ //# sourceMappingURL=layer-config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"layer-config.js","names":[],"sources":["../../../../../src/deckgl/shapes/shared/utils/layer-config.ts"],"sourcesContent":["/*\n * Copyright 2025 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"}