@accelint/map-toolkit 0.6.0 → 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (207) hide show
  1. package/CHANGELOG.md +81 -0
  2. package/catalog-info.yaml +7 -6
  3. package/dist/camera/events.js.map +1 -1
  4. package/dist/camera/index.d.ts +2 -2
  5. package/dist/camera/index.js +2 -2
  6. package/dist/camera/store.d.ts +120 -0
  7. package/dist/camera/store.js +279 -0
  8. package/dist/camera/store.js.map +1 -0
  9. package/dist/cursor-coordinates/index.d.ts +4 -2
  10. package/dist/cursor-coordinates/index.js +3 -2
  11. package/dist/cursor-coordinates/store.d.ts +48 -0
  12. package/dist/cursor-coordinates/store.js +92 -0
  13. package/dist/cursor-coordinates/store.js.map +1 -0
  14. package/dist/cursor-coordinates/types.d.ts +87 -0
  15. package/dist/cursor-coordinates/types.js +12 -0
  16. package/dist/cursor-coordinates/use-cursor-coordinates.d.ts +41 -37
  17. package/dist/cursor-coordinates/use-cursor-coordinates.js +131 -202
  18. package/dist/cursor-coordinates/use-cursor-coordinates.js.map +1 -1
  19. package/dist/deckgl/base-map/constants.d.ts +1 -6
  20. package/dist/deckgl/base-map/constants.js +1 -6
  21. package/dist/deckgl/base-map/constants.js.map +1 -1
  22. package/dist/deckgl/base-map/controls.js +2 -0
  23. package/dist/deckgl/base-map/controls.js.map +1 -1
  24. package/dist/deckgl/base-map/events.js.map +1 -1
  25. package/dist/deckgl/base-map/index.d.ts +2 -2
  26. package/dist/deckgl/base-map/index.js +10 -11
  27. package/dist/deckgl/base-map/index.js.map +1 -1
  28. package/dist/deckgl/base-map/provider.d.ts +2 -2
  29. package/dist/deckgl/base-map/provider.js +1 -1
  30. package/dist/deckgl/base-map/provider.js.map +1 -1
  31. package/dist/deckgl/index.d.ts +4 -4
  32. package/dist/deckgl/index.js +4 -4
  33. package/dist/deckgl/saved-viewports/index.js.map +1 -1
  34. package/dist/deckgl/saved-viewports/storage.js +10 -2
  35. package/dist/deckgl/saved-viewports/storage.js.map +1 -1
  36. package/dist/deckgl/shapes/display-shape-layer/constants.js +5 -8
  37. package/dist/deckgl/shapes/display-shape-layer/constants.js.map +1 -1
  38. package/dist/deckgl/shapes/display-shape-layer/fiber.js.map +1 -1
  39. package/dist/deckgl/shapes/display-shape-layer/index.d.ts +18 -14
  40. package/dist/deckgl/shapes/display-shape-layer/index.js +63 -30
  41. package/dist/deckgl/shapes/display-shape-layer/index.js.map +1 -1
  42. package/dist/deckgl/shapes/display-shape-layer/shape-label-layer.js +2 -16
  43. package/dist/deckgl/shapes/display-shape-layer/shape-label-layer.js.map +1 -1
  44. package/dist/deckgl/shapes/display-shape-layer/store.js +58 -272
  45. package/dist/deckgl/shapes/display-shape-layer/store.js.map +1 -1
  46. package/dist/deckgl/shapes/display-shape-layer/types.d.ts +22 -11
  47. package/dist/deckgl/shapes/display-shape-layer/{use-shape-selection.d.ts → use-select-shape.d.ts} +9 -9
  48. package/dist/deckgl/shapes/display-shape-layer/{use-shape-selection.js → use-select-shape.js} +12 -12
  49. package/dist/deckgl/shapes/display-shape-layer/use-select-shape.js.map +1 -0
  50. package/dist/deckgl/shapes/display-shape-layer/utils/display-style.js +5 -66
  51. package/dist/deckgl/shapes/display-shape-layer/utils/display-style.js.map +1 -1
  52. package/dist/deckgl/shapes/display-shape-layer/utils/labels.d.ts +2 -65
  53. package/dist/deckgl/shapes/display-shape-layer/utils/labels.js +3 -121
  54. package/dist/deckgl/shapes/display-shape-layer/utils/labels.js.map +1 -1
  55. package/dist/deckgl/shapes/draw-shape-layer/constants.js +46 -0
  56. package/dist/deckgl/shapes/draw-shape-layer/constants.js.map +1 -0
  57. package/dist/deckgl/shapes/draw-shape-layer/events.d.ts +92 -0
  58. package/dist/deckgl/shapes/draw-shape-layer/events.js +56 -0
  59. package/dist/deckgl/shapes/draw-shape-layer/events.js.map +1 -0
  60. package/dist/deckgl/shapes/draw-shape-layer/fiber.d.ts +11 -0
  61. package/dist/{maplibre/constants.js → deckgl/shapes/draw-shape-layer/fiber.js} +6 -12
  62. package/dist/deckgl/shapes/draw-shape-layer/fiber.js.map +1 -0
  63. package/dist/deckgl/shapes/draw-shape-layer/index.d.ts +53 -0
  64. package/dist/deckgl/shapes/draw-shape-layer/index.js +95 -0
  65. package/dist/deckgl/shapes/draw-shape-layer/index.js.map +1 -0
  66. package/dist/deckgl/shapes/draw-shape-layer/modes/draw-circle-mode-with-tooltip.js +51 -0
  67. package/dist/deckgl/shapes/draw-shape-layer/modes/draw-circle-mode-with-tooltip.js.map +1 -0
  68. package/dist/deckgl/shapes/draw-shape-layer/modes/draw-ellipse-mode-with-tooltip.js +73 -0
  69. package/dist/deckgl/shapes/draw-shape-layer/modes/draw-ellipse-mode-with-tooltip.js.map +1 -0
  70. package/dist/deckgl/shapes/draw-shape-layer/modes/draw-line-string-mode-with-tooltip.js +87 -0
  71. package/dist/deckgl/shapes/draw-shape-layer/modes/draw-line-string-mode-with-tooltip.js.map +1 -0
  72. package/dist/deckgl/shapes/draw-shape-layer/modes/draw-polygon-mode-with-tooltip.js +88 -0
  73. package/dist/deckgl/shapes/draw-shape-layer/modes/draw-polygon-mode-with-tooltip.js.map +1 -0
  74. package/dist/deckgl/shapes/draw-shape-layer/modes/draw-rectangle-mode-with-tooltip.js +77 -0
  75. package/dist/deckgl/shapes/draw-shape-layer/modes/draw-rectangle-mode-with-tooltip.js.map +1 -0
  76. package/dist/deckgl/shapes/draw-shape-layer/modes/index.js +64 -0
  77. package/dist/deckgl/shapes/draw-shape-layer/modes/index.js.map +1 -0
  78. package/dist/deckgl/shapes/draw-shape-layer/store.js +175 -0
  79. package/dist/deckgl/shapes/draw-shape-layer/store.js.map +1 -0
  80. package/dist/deckgl/shapes/draw-shape-layer/types.d.ts +86 -0
  81. package/dist/{viewport/constants.js → deckgl/shapes/draw-shape-layer/types.js} +1 -12
  82. package/dist/deckgl/shapes/draw-shape-layer/use-draw-shape.d.ts +82 -0
  83. package/dist/deckgl/shapes/draw-shape-layer/use-draw-shape.js +112 -0
  84. package/dist/deckgl/shapes/draw-shape-layer/use-draw-shape.js.map +1 -0
  85. package/dist/deckgl/shapes/draw-shape-layer/utils/feature-conversion.js +147 -0
  86. package/dist/deckgl/shapes/draw-shape-layer/utils/feature-conversion.js.map +1 -0
  87. package/dist/deckgl/shapes/edit-shape-layer/constants.js +41 -0
  88. package/dist/deckgl/shapes/edit-shape-layer/constants.js.map +1 -0
  89. package/dist/deckgl/shapes/edit-shape-layer/events.d.ts +92 -0
  90. package/dist/deckgl/shapes/edit-shape-layer/events.js +56 -0
  91. package/dist/deckgl/shapes/edit-shape-layer/events.js.map +1 -0
  92. package/dist/deckgl/shapes/edit-shape-layer/fiber.d.ts +13 -0
  93. package/dist/deckgl/shapes/edit-shape-layer/fiber.js +14 -0
  94. package/dist/deckgl/shapes/edit-shape-layer/index.d.ts +63 -0
  95. package/dist/deckgl/shapes/edit-shape-layer/index.js +162 -0
  96. package/dist/deckgl/shapes/edit-shape-layer/index.js.map +1 -0
  97. package/dist/deckgl/shapes/edit-shape-layer/modes/base-transform-mode.js +154 -0
  98. package/dist/deckgl/shapes/edit-shape-layer/modes/base-transform-mode.js.map +1 -0
  99. package/dist/deckgl/shapes/edit-shape-layer/modes/bounding-transform-mode.js +147 -0
  100. package/dist/deckgl/shapes/edit-shape-layer/modes/bounding-transform-mode.js.map +1 -0
  101. package/dist/deckgl/shapes/edit-shape-layer/modes/circle-transform-mode.js +87 -0
  102. package/dist/deckgl/shapes/edit-shape-layer/modes/circle-transform-mode.js.map +1 -0
  103. package/dist/deckgl/shapes/edit-shape-layer/modes/index.js +61 -0
  104. package/dist/deckgl/shapes/edit-shape-layer/modes/index.js.map +1 -0
  105. package/dist/deckgl/shapes/edit-shape-layer/modes/rotate-mode-with-snap.js +109 -0
  106. package/dist/deckgl/shapes/edit-shape-layer/modes/rotate-mode-with-snap.js.map +1 -0
  107. package/dist/deckgl/shapes/edit-shape-layer/modes/scale-mode-with-free-transform.js +289 -0
  108. package/dist/deckgl/shapes/edit-shape-layer/modes/scale-mode-with-free-transform.js.map +1 -0
  109. package/dist/deckgl/shapes/edit-shape-layer/modes/vertex-transform-mode.js +121 -0
  110. package/dist/deckgl/shapes/edit-shape-layer/modes/vertex-transform-mode.js.map +1 -0
  111. package/dist/deckgl/shapes/edit-shape-layer/store.js +194 -0
  112. package/dist/deckgl/shapes/edit-shape-layer/store.js.map +1 -0
  113. package/dist/deckgl/shapes/edit-shape-layer/types.d.ts +93 -0
  114. package/dist/deckgl/shapes/edit-shape-layer/types.js +14 -0
  115. package/dist/deckgl/shapes/edit-shape-layer/use-edit-shape.d.ts +82 -0
  116. package/dist/deckgl/shapes/edit-shape-layer/use-edit-shape.js +114 -0
  117. package/dist/deckgl/shapes/edit-shape-layer/use-edit-shape.js.map +1 -0
  118. package/dist/deckgl/shapes/index.d.ts +15 -6
  119. package/dist/deckgl/shapes/index.js +12 -5
  120. package/dist/deckgl/shapes/shared/constants.d.ts +27 -32
  121. package/dist/deckgl/shapes/shared/constants.js +189 -25
  122. package/dist/deckgl/shapes/shared/constants.js.map +1 -1
  123. package/dist/deckgl/shapes/shared/events.d.ts +1 -20
  124. package/dist/deckgl/shapes/shared/events.js +1 -31
  125. package/dist/deckgl/shapes/shared/events.js.map +1 -1
  126. package/dist/deckgl/shapes/shared/hooks/use-shift-zoom-disable.js +84 -0
  127. package/dist/deckgl/shapes/shared/hooks/use-shift-zoom-disable.js.map +1 -0
  128. package/dist/deckgl/shapes/shared/types.d.ts +187 -28
  129. package/dist/deckgl/shapes/shared/types.js +55 -1
  130. package/dist/deckgl/shapes/shared/types.js.map +1 -1
  131. package/dist/deckgl/shapes/shared/utils/geometry-measurements.js +128 -0
  132. package/dist/deckgl/shapes/shared/utils/geometry-measurements.js.map +1 -0
  133. package/dist/deckgl/shapes/shared/utils/layer-config.js +50 -0
  134. package/dist/deckgl/shapes/shared/utils/layer-config.js.map +1 -0
  135. package/dist/deckgl/shapes/shared/utils/mode-utils.js +113 -0
  136. package/dist/deckgl/shapes/shared/utils/mode-utils.js.map +1 -0
  137. package/dist/deckgl/shapes/shared/utils/pick-filtering.js +57 -0
  138. package/dist/deckgl/shapes/shared/utils/pick-filtering.js.map +1 -0
  139. package/dist/deckgl/shapes/shared/utils/style-utils.d.ts +64 -0
  140. package/dist/deckgl/shapes/shared/utils/style-utils.js +101 -0
  141. package/dist/deckgl/shapes/shared/utils/style-utils.js.map +1 -0
  142. package/dist/deckgl/symbol-layer/fiber.js.map +1 -1
  143. package/dist/deckgl/symbol-layer/index.js.map +1 -1
  144. package/dist/deckgl/text-layer/character-sets.js.map +1 -1
  145. package/dist/deckgl/text-layer/default-settings.js +4 -24
  146. package/dist/deckgl/text-layer/default-settings.js.map +1 -1
  147. package/dist/deckgl/text-layer/fiber.js.map +1 -1
  148. package/dist/deckgl/text-layer/index.js.map +1 -1
  149. package/dist/deckgl/text-settings.d.ts +77 -0
  150. package/dist/deckgl/text-settings.js +83 -0
  151. package/dist/deckgl/text-settings.js.map +1 -0
  152. package/dist/map-cursor/events.js.map +1 -1
  153. package/dist/map-cursor/index.d.ts +2 -2
  154. package/dist/map-cursor/index.js +2 -2
  155. package/dist/map-cursor/store.d.ts +32 -61
  156. package/dist/map-cursor/store.js +165 -294
  157. package/dist/map-cursor/store.js.map +1 -1
  158. package/dist/map-cursor/use-map-cursor.d.ts +5 -2
  159. package/dist/map-cursor/use-map-cursor.js +33 -15
  160. package/dist/map-cursor/use-map-cursor.js.map +1 -1
  161. package/dist/map-mode/events.js.map +1 -1
  162. package/dist/map-mode/index.d.ts +2 -2
  163. package/dist/map-mode/index.js +2 -2
  164. package/dist/map-mode/store.d.ts +36 -37
  165. package/dist/map-mode/store.js +131 -237
  166. package/dist/map-mode/store.js.map +1 -1
  167. package/dist/map-mode/use-map-mode.js +6 -5
  168. package/dist/map-mode/use-map-mode.js.map +1 -1
  169. package/dist/maplibre/hooks/use-maplibre.js.map +1 -1
  170. package/dist/maplibre/index.d.ts +2 -2
  171. package/dist/maplibre/index.js +2 -2
  172. package/dist/shared/constants.d.ts +19 -0
  173. package/dist/shared/constants.js +33 -0
  174. package/dist/shared/constants.js.map +1 -0
  175. package/dist/shared/create-map-store.d.ts +202 -0
  176. package/dist/shared/create-map-store.js +223 -0
  177. package/dist/shared/create-map-store.js.map +1 -0
  178. package/dist/shared/units.d.ts +39 -0
  179. package/dist/shared/units.js +49 -0
  180. package/dist/shared/units.js.map +1 -0
  181. package/dist/viewport/index.d.ts +3 -3
  182. package/dist/viewport/index.js +3 -3
  183. package/dist/viewport/store.d.ts +69 -0
  184. package/dist/viewport/store.js +125 -0
  185. package/dist/viewport/store.js.map +1 -0
  186. package/dist/viewport/types.d.ts +2 -2
  187. package/dist/viewport/utils.js +2 -2
  188. package/dist/viewport/utils.js.map +1 -1
  189. package/dist/viewport/viewport-size.d.ts +2 -2
  190. package/dist/viewport/viewport-size.js +2 -2
  191. package/dist/viewport/viewport-size.js.map +1 -1
  192. package/package.json +39 -19
  193. package/dist/camera/use-camera-state.d.ts +0 -153
  194. package/dist/camera/use-camera-state.js +0 -418
  195. package/dist/camera/use-camera-state.js.map +0 -1
  196. package/dist/deckgl/shapes/display-shape-layer/constants.d.ts +0 -44
  197. package/dist/deckgl/shapes/display-shape-layer/shape-label-layer.d.ts +0 -66
  198. package/dist/deckgl/shapes/display-shape-layer/store.d.ts +0 -87
  199. package/dist/deckgl/shapes/display-shape-layer/use-shape-selection.js.map +0 -1
  200. package/dist/deckgl/shapes/display-shape-layer/utils/display-style.d.ts +0 -61
  201. package/dist/maplibre/constants.d.ts +0 -13
  202. package/dist/maplibre/constants.js.map +0 -1
  203. package/dist/viewport/constants.d.ts +0 -11
  204. package/dist/viewport/constants.js.map +0 -1
  205. package/dist/viewport/use-viewport-state.d.ts +0 -100
  206. package/dist/viewport/use-viewport-state.js +0 -222
  207. package/dist/viewport/use-viewport-state.js.map +0 -1
@@ -0,0 +1,69 @@
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
+ import { MapStore } from "../shared/create-map-store.js";
14
+ import { MapViewportPayload } from "../deckgl/base-map/types.js";
15
+ import { UniqueId } from "@accelint/core";
16
+
17
+ //#region src/viewport/store.d.ts
18
+ /**
19
+ * State shape for viewport - mirrors MapViewportPayload but with
20
+ * a placeholder id that gets replaced per-instance
21
+ */
22
+ type ViewportState = MapViewportPayload;
23
+ /**
24
+ * No actions needed - viewport state is read-only from bus events
25
+ */
26
+ type ViewportActions = Record<string, never>;
27
+ /**
28
+ * Viewport store instance.
29
+ *
30
+ * Note: The defaultState uses a placeholder id that gets replaced
31
+ * when instances are created. The actual id comes from the bus event payload.
32
+ */
33
+ declare const viewportStore: MapStore<MapViewportPayload, ViewportActions>;
34
+ /**
35
+ * Hook to subscribe to viewport state changes for a specific map.
36
+ *
37
+ * @param mapId - Unique identifier for the map instance
38
+ * @returns Current viewport state including bounds, latitude, longitude, zoom, width, height
39
+ *
40
+ * @example
41
+ * ```tsx
42
+ * function MapInfo({ mapId }) {
43
+ * const viewport = useMapViewport(mapId);
44
+ * return (
45
+ * <div>
46
+ * Lat: {viewport.latitude?.toFixed(2)}, Lon: {viewport.longitude?.toFixed(2)}, Zoom: {viewport.zoom}
47
+ * </div>
48
+ * );
49
+ * }
50
+ * ```
51
+ */
52
+ declare function useMapViewport(mapId: UniqueId): ViewportState;
53
+ /**
54
+ * Get current viewport state (non-reactive, for imperative code).
55
+ *
56
+ * @param mapId - Unique identifier for the map instance
57
+ * @returns Current viewport state
58
+ */
59
+ declare function getViewport(mapId: UniqueId): ViewportState;
60
+ /**
61
+ * Manually clear viewport state for a specific map instance.
62
+ * This is typically not needed as cleanup happens automatically when all subscribers unmount.
63
+ *
64
+ * @param mapId - The unique identifier for the map instance to clear
65
+ */
66
+ declare function clearViewportState(mapId: UniqueId): void;
67
+ //#endregion
68
+ export { clearViewportState, getViewport, useMapViewport, viewportStore };
69
+ //# sourceMappingURL=store.d.ts.map
@@ -0,0 +1,125 @@
1
+ /*
2
+ * Copyright 2025 Hypergiant Galactic Systems Inc. All rights reserved.
3
+ * This file is licensed to you under the Apache License, Version 2.0 (the "License");
4
+ * you may not use this file except in compliance with the License. You may obtain a copy
5
+ * of the License at https://www.apache.org/licenses/LICENSE-2.0
6
+ *
7
+ * Unless required by applicable law or agreed to in writing, software distributed under
8
+ * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
9
+ * OF ANY KIND, either express or implied. See the License for the specific language
10
+ * governing permissions and limitations under the License.
11
+ */
12
+
13
+
14
+ import { createMapStore } from "../shared/create-map-store.js";
15
+ import { MapEvents } from "../deckgl/base-map/events.js";
16
+ import { Broadcast } from "@accelint/bus";
17
+
18
+ //#region src/viewport/store.ts
19
+ /**
20
+ * Viewport Store
21
+ *
22
+ * Manages viewport state (bounds, lat/lon, zoom, dimensions) per map instance.
23
+ * State is updated automatically from MapEvents.viewport bus events.
24
+ *
25
+ * @example
26
+ * ```tsx
27
+ * import { viewportStore } from '@accelint/map-toolkit/viewport';
28
+ *
29
+ * function MapInfo({ mapId }) {
30
+ * const { state } = viewportStore.use(mapId);
31
+ * return (
32
+ * <div>
33
+ * Lat: {state.latitude.toFixed(2)}, Lon: {state.longitude.toFixed(2)}
34
+ * </div>
35
+ * );
36
+ * }
37
+ * ```
38
+ */
39
+ const bus = Broadcast.getInstance();
40
+ /**
41
+ * Create default state for a given mapId.
42
+ * Returns uninitialized values that indicate no viewport data yet.
43
+ */
44
+ function createDefaultState(mapId) {
45
+ return {
46
+ id: mapId,
47
+ bounds: void 0,
48
+ latitude: NaN,
49
+ longitude: NaN,
50
+ zoom: NaN,
51
+ width: 0,
52
+ height: 0
53
+ };
54
+ }
55
+ /**
56
+ * Viewport store instance.
57
+ *
58
+ * Note: The defaultState uses a placeholder id that gets replaced
59
+ * when instances are created. The actual id comes from the bus event payload.
60
+ */
61
+ const viewportStore = createMapStore({
62
+ defaultState: {
63
+ id: "",
64
+ bounds: void 0,
65
+ latitude: NaN,
66
+ longitude: NaN,
67
+ zoom: NaN,
68
+ width: 0,
69
+ height: 0
70
+ },
71
+ actions: () => ({}),
72
+ bus: (mapId, { replace }) => {
73
+ return bus.on(MapEvents.viewport, ({ payload }) => {
74
+ if (payload.id === mapId) replace(payload);
75
+ });
76
+ }
77
+ });
78
+ /**
79
+ * Hook to subscribe to viewport state changes for a specific map.
80
+ *
81
+ * @param mapId - Unique identifier for the map instance
82
+ * @returns Current viewport state including bounds, latitude, longitude, zoom, width, height
83
+ *
84
+ * @example
85
+ * ```tsx
86
+ * function MapInfo({ mapId }) {
87
+ * const viewport = useMapViewport(mapId);
88
+ * return (
89
+ * <div>
90
+ * Lat: {viewport.latitude?.toFixed(2)}, Lon: {viewport.longitude?.toFixed(2)}, Zoom: {viewport.zoom}
91
+ * </div>
92
+ * );
93
+ * }
94
+ * ```
95
+ */
96
+ function useMapViewport(mapId) {
97
+ return viewportStore.useSelector(mapId, (state) => {
98
+ if (state.id === "") return createDefaultState(mapId);
99
+ return state;
100
+ });
101
+ }
102
+ /**
103
+ * Get current viewport state (non-reactive, for imperative code).
104
+ *
105
+ * @param mapId - Unique identifier for the map instance
106
+ * @returns Current viewport state
107
+ */
108
+ function getViewport(mapId) {
109
+ const state = viewportStore.get(mapId);
110
+ if (state.id === "") return createDefaultState(mapId);
111
+ return state;
112
+ }
113
+ /**
114
+ * Manually clear viewport state for a specific map instance.
115
+ * This is typically not needed as cleanup happens automatically when all subscribers unmount.
116
+ *
117
+ * @param mapId - The unique identifier for the map instance to clear
118
+ */
119
+ function clearViewportState(mapId) {
120
+ viewportStore.clear(mapId);
121
+ }
122
+
123
+ //#endregion
124
+ export { clearViewportState, getViewport, useMapViewport, viewportStore };
125
+ //# sourceMappingURL=store.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"store.js","names":[],"sources":["../../src/viewport/store.ts"],"sourcesContent":["/*\n * Copyright 2026 Hypergiant Galactic Systems Inc. All rights reserved.\n * This file is licensed to you under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License. You may obtain a copy\n * of the License at https://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software distributed under\n * the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS\n * OF ANY KIND, either express or implied. See the License for the specific language\n * governing permissions and limitations under the License.\n */\n\n/**\n * Viewport Store\n *\n * Manages viewport state (bounds, lat/lon, zoom, dimensions) per map instance.\n * State is updated automatically from MapEvents.viewport bus events.\n *\n * @example\n * ```tsx\n * import { viewportStore } from '@accelint/map-toolkit/viewport';\n *\n * function MapInfo({ mapId }) {\n * const { state } = viewportStore.use(mapId);\n * return (\n * <div>\n * Lat: {state.latitude.toFixed(2)}, Lon: {state.longitude.toFixed(2)}\n * </div>\n * );\n * }\n * ```\n */\n\nimport { Broadcast } from '@accelint/bus';\nimport { MapEvents } from '../deckgl/base-map/events';\nimport { createMapStore } from '../shared/create-map-store';\nimport type { UniqueId } from '@accelint/core';\nimport type {\n MapEventType,\n MapViewportPayload,\n} from '../deckgl/base-map/types';\n\nconst bus = Broadcast.getInstance<MapEventType>();\n\n/**\n * State shape for viewport - mirrors MapViewportPayload but with\n * a placeholder id that gets replaced per-instance\n */\ntype ViewportState = MapViewportPayload;\n\n/**\n * No actions needed - viewport state is read-only from bus events\n */\ntype ViewportActions = Record<string, never>;\n\n/**\n * Create default state for a given mapId.\n * Returns uninitialized values that indicate no viewport data yet.\n */\nfunction createDefaultState(mapId: UniqueId): ViewportState {\n return {\n id: mapId,\n bounds: undefined,\n latitude: Number.NaN,\n longitude: Number.NaN,\n zoom: Number.NaN,\n width: 0,\n height: 0,\n };\n}\n\n/**\n * Viewport store instance.\n *\n * Note: The defaultState uses a placeholder id that gets replaced\n * when instances are created. The actual id comes from the bus event payload.\n */\nexport const viewportStore = createMapStore<ViewportState, ViewportActions>({\n // Placeholder default state - actual instances get proper id from bus events\n defaultState: {\n id: '' as UniqueId,\n bounds: undefined,\n latitude: Number.NaN,\n longitude: Number.NaN,\n zoom: Number.NaN,\n width: 0,\n height: 0,\n },\n\n // No actions - state is read-only from bus events\n actions: () => ({}) as ViewportActions,\n\n bus: (mapId, { replace }) => {\n const unsub = bus.on(MapEvents.viewport, ({ payload }) => {\n if (payload.id === mapId) {\n // Replace entire state with the new payload\n replace(payload);\n }\n });\n\n return unsub;\n },\n});\n\n// =============================================================================\n// Convenience exports\n// =============================================================================\n\n/**\n * Hook to subscribe to viewport state changes for a specific map.\n *\n * @param mapId - Unique identifier for the map instance\n * @returns Current viewport state including bounds, latitude, longitude, zoom, width, height\n *\n * @example\n * ```tsx\n * function MapInfo({ mapId }) {\n * const viewport = useMapViewport(mapId);\n * return (\n * <div>\n * Lat: {viewport.latitude?.toFixed(2)}, Lon: {viewport.longitude?.toFixed(2)}, Zoom: {viewport.zoom}\n * </div>\n * );\n * }\n * ```\n */\nexport function useMapViewport(mapId: UniqueId): ViewportState {\n return viewportStore.useSelector(mapId, (state) => {\n // Return proper default state with correct mapId if uninitialized\n if (state.id === '') {\n return createDefaultState(mapId);\n }\n return state;\n });\n}\n\n/**\n * Get current viewport state (non-reactive, for imperative code).\n *\n * @param mapId - Unique identifier for the map instance\n * @returns Current viewport state\n */\nexport function getViewport(mapId: UniqueId): ViewportState {\n const state = viewportStore.get(mapId);\n // Return proper default state with correct mapId if uninitialized\n if (state.id === '') {\n return createDefaultState(mapId);\n }\n return state;\n}\n\n/**\n * Manually clear viewport state for a specific map instance.\n * This is typically not needed as cleanup happens automatically when all subscribers unmount.\n *\n * @param mapId - The unique identifier for the map instance to clear\n */\nexport function clearViewportState(mapId: UniqueId): void {\n viewportStore.clear(mapId);\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA0CA,MAAM,MAAM,UAAU,aAA2B;;;;;AAiBjD,SAAS,mBAAmB,OAAgC;AAC1D,QAAO;EACL,IAAI;EACJ,QAAQ;EACR,UAAU;EACV,WAAW;EACX,MAAM;EACN,OAAO;EACP,QAAQ;EACT;;;;;;;;AASH,MAAa,gBAAgB,eAA+C;CAE1E,cAAc;EACZ,IAAI;EACJ,QAAQ;EACR,UAAU;EACV,WAAW;EACX,MAAM;EACN,OAAO;EACP,QAAQ;EACT;CAGD,gBAAgB,EAAE;CAElB,MAAM,OAAO,EAAE,cAAc;AAQ3B,SAPc,IAAI,GAAG,UAAU,WAAW,EAAE,cAAc;AACxD,OAAI,QAAQ,OAAO,MAEjB,SAAQ,QAAQ;IAElB;;CAIL,CAAC;;;;;;;;;;;;;;;;;;;AAwBF,SAAgB,eAAe,OAAgC;AAC7D,QAAO,cAAc,YAAY,QAAQ,UAAU;AAEjD,MAAI,MAAM,OAAO,GACf,QAAO,mBAAmB,MAAM;AAElC,SAAO;GACP;;;;;;;;AASJ,SAAgB,YAAY,OAAgC;CAC1D,MAAM,QAAQ,cAAc,IAAI,MAAM;AAEtC,KAAI,MAAM,OAAO,GACf,QAAO,mBAAmB,MAAM;AAElC,QAAO;;;;;;;;AAST,SAAgB,mBAAmB,OAAuB;AACxD,eAAc,MAAM,MAAM"}
@@ -11,10 +11,10 @@
11
11
  */
12
12
 
13
13
  import { Bounds } from "../deckgl/base-map/types.js";
14
- import { UNIT_MAP } from "./constants.js";
14
+ import { DistanceUnitAbbreviation } from "../shared/units.js";
15
15
 
16
16
  //#region src/viewport/types.d.ts
17
- type SupportedDistanceUnit = keyof typeof UNIT_MAP;
17
+ type SupportedDistanceUnit = DistanceUnitAbbreviation;
18
18
  type GetViewportSizeArgs = {
19
19
  /** Geographic bounds, undefined if viewport not yet initialized */
20
20
  bounds?: Bounds;
@@ -11,7 +11,7 @@
11
11
  */
12
12
 
13
13
 
14
- import { UNIT_MAP } from "./constants.js";
14
+ import { getDistanceUnitFromAbbreviation } from "../shared/units.js";
15
15
 
16
16
  //#region src/viewport/utils.ts
17
17
  const numberFormatter = Intl.NumberFormat("en-US");
@@ -65,7 +65,7 @@ function getViewportSize({ bounds, zoom, width: pixelWidth, height: pixelHeight,
65
65
  const metersPerPixel = METERS_PER_PIXEL_AT_ZOOM_0 * Math.cos(centerLat * Math.PI / 180) / 2 ** zoom;
66
66
  const widthMeters = pixelWidth * metersPerPixel;
67
67
  const heightMeters = pixelHeight * metersPerPixel;
68
- const conversionFactor = METERS_TO_UNIT[UNIT_MAP[unit]];
68
+ const conversionFactor = METERS_TO_UNIT[getDistanceUnitFromAbbreviation(unit)];
69
69
  const widthDistance = Math.round(widthMeters * conversionFactor);
70
70
  const heightDistance = Math.round(heightMeters * conversionFactor);
71
71
  return `${formatter.format(widthDistance)} x ${formatter.format(heightDistance)} ${unit.toUpperCase()}`;
@@ -1 +1 @@
1
- {"version":3,"file":"utils.js","names":[],"sources":["../../src/viewport/utils.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\nimport { UNIT_MAP } from './constants';\nimport type { GetViewportSizeArgs } from './types';\n\nconst numberFormatter = Intl.NumberFormat('en-US');\n\n/**\n * Web Mercator constant: meters per pixel at zoom 0, equator.\n * This is Earth's circumference (40075016.686m) divided by 256 (tile size).\n */\nconst METERS_PER_PIXEL_AT_ZOOM_0 = 156543.03392;\n\n/**\n * Unit conversion factors from meters.\n */\nconst METERS_TO_UNIT = {\n kilometers: 0.001,\n meters: 1,\n nauticalmiles: 0.000539957,\n miles: 0.000621371,\n feet: 3.28084,\n} as const;\n\n/**\n * Returns a formatted viewport size string i.e. `660 x 1,801 NM`\n *\n * Calculates the geographic distance of the viewport using zoom level and\n * pixel dimensions with the Web Mercator projection formula. This approach\n * provides stable results without the edge cases of bounds-based calculations.\n *\n * @param args - Viewport size calculation arguments\n * @param args.bounds - Geographic bounds [minLon, minLat, maxLon, maxLat]\n * @param args.zoom - Zoom level for meters-per-pixel calculation\n * @param args.width - Viewport width in pixels\n * @param args.height - Viewport height in pixels\n * @param args.unit - Unit of distance measurement: `km | m | nm | mi | ft`. Defaults to `nm`\n * @param args.formatter - Number formatter for localization (defaults to en-US)\n * @returns Formatted string like \"660 x 1,801 NM\" or \"-- x -- NM\" if invalid\n *\n * @example\n * ```typescript\n * getViewportSize({ bounds: [-82, 22, -71, 52], zoom: 5, width: 800, height: 600, unit: 'nm' })\n * // returns \"612 x 459 NM\"\n *\n * getViewportSize({ bounds: [170, 50, -170, 60], zoom: 4, width: 1024, height: 768, unit: 'km' })\n * // returns \"2,050 x 1,538 KM\"\n * ```\n */\nexport function getViewportSize({\n bounds,\n zoom,\n width: pixelWidth,\n height: pixelHeight,\n unit = 'nm',\n formatter = numberFormatter,\n}: GetViewportSizeArgs) {\n const defaultValue = `-- x -- ${unit.toUpperCase()}`;\n\n // Validate inputs\n if (!bounds || bounds.every((b) => Number.isNaN(b))) {\n return defaultValue;\n }\n\n if (Number.isNaN(zoom) || pixelWidth === 0 || pixelHeight === 0) {\n return defaultValue;\n }\n\n const [, minLat, , maxLat] = bounds;\n\n // Validate latitude bounds are within valid geographic ranges\n if (minLat < -90 || minLat > 90 || maxLat < -90 || maxLat > 90) {\n return defaultValue;\n }\n\n // Calculate center latitude for the viewport\n const centerLat = (minLat + maxLat) / 2;\n\n // Web Mercator formula: meters per pixel at given zoom and latitude\n // Resolution = 156543.03392 * cos(latitude * π/180) / 2^zoom\n const metersPerPixel =\n (METERS_PER_PIXEL_AT_ZOOM_0 * Math.cos((centerLat * Math.PI) / 180)) /\n 2 ** zoom;\n\n // Calculate distances in meters\n const widthMeters = pixelWidth * metersPerPixel;\n const heightMeters = pixelHeight * metersPerPixel;\n\n // Convert to requested unit\n const unitKey = UNIT_MAP[unit] as keyof typeof METERS_TO_UNIT;\n const conversionFactor = METERS_TO_UNIT[unitKey];\n\n const widthDistance = Math.round(widthMeters * conversionFactor);\n const heightDistance = Math.round(heightMeters * conversionFactor);\n\n const width = formatter.format(widthDistance);\n const height = formatter.format(heightDistance);\n\n return `${width} x ${height} ${unit.toUpperCase()}`;\n}\n"],"mappings":";;;;;;;;;;;;;;;;AAeA,MAAM,kBAAkB,KAAK,aAAa,QAAQ;;;;;AAMlD,MAAM,6BAA6B;;;;AAKnC,MAAM,iBAAiB;CACrB,YAAY;CACZ,QAAQ;CACR,eAAe;CACf,OAAO;CACP,MAAM;CACP;;;;;;;;;;;;;;;;;;;;;;;;;;AA2BD,SAAgB,gBAAgB,EAC9B,QACA,MACA,OAAO,YACP,QAAQ,aACR,OAAO,MACP,YAAY,mBACU;CACtB,MAAM,eAAe,WAAW,KAAK,aAAa;AAGlD,KAAI,CAAC,UAAU,OAAO,OAAO,MAAM,OAAO,MAAM,EAAE,CAAC,CACjD,QAAO;AAGT,KAAI,OAAO,MAAM,KAAK,IAAI,eAAe,KAAK,gBAAgB,EAC5D,QAAO;CAGT,MAAM,GAAG,UAAU,UAAU;AAG7B,KAAI,SAAS,OAAO,SAAS,MAAM,SAAS,OAAO,SAAS,GAC1D,QAAO;CAIT,MAAM,aAAa,SAAS,UAAU;CAItC,MAAM,iBACH,6BAA6B,KAAK,IAAK,YAAY,KAAK,KAAM,IAAI,GACnE,KAAK;CAGP,MAAM,cAAc,aAAa;CACjC,MAAM,eAAe,cAAc;CAInC,MAAM,mBAAmB,eADT,SAAS;CAGzB,MAAM,gBAAgB,KAAK,MAAM,cAAc,iBAAiB;CAChE,MAAM,iBAAiB,KAAK,MAAM,eAAe,iBAAiB;AAKlE,QAAO,GAHO,UAAU,OAAO,cAAc,CAG7B,KAFD,UAAU,OAAO,eAAe,CAEnB,GAAG,KAAK,aAAa"}
1
+ {"version":3,"file":"utils.js","names":[],"sources":["../../src/viewport/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 {\n type DistanceUnit,\n getDistanceUnitFromAbbreviation,\n} from '../shared/units';\nimport type { GetViewportSizeArgs } from './types';\n\nconst numberFormatter = Intl.NumberFormat('en-US');\n\n/**\n * Web Mercator constant: meters per pixel at zoom 0, equator.\n * This is Earth's circumference (40075016.686m) divided by 256 (tile size).\n */\nconst METERS_PER_PIXEL_AT_ZOOM_0 = 156543.03392;\n\n/**\n * Unit conversion factors from meters.\n */\nconst METERS_TO_UNIT = {\n kilometers: 0.001,\n meters: 1,\n nauticalmiles: 0.000539957,\n miles: 0.000621371,\n feet: 3.28084,\n} as const;\n\n/**\n * Returns a formatted viewport size string i.e. `660 x 1,801 NM`\n *\n * Calculates the geographic distance of the viewport using zoom level and\n * pixel dimensions with the Web Mercator projection formula. This approach\n * provides stable results without the edge cases of bounds-based calculations.\n *\n * @param args - Viewport size calculation arguments\n * @param args.bounds - Geographic bounds [minLon, minLat, maxLon, maxLat]\n * @param args.zoom - Zoom level for meters-per-pixel calculation\n * @param args.width - Viewport width in pixels\n * @param args.height - Viewport height in pixels\n * @param args.unit - Unit of distance measurement: `km | m | nm | mi | ft`. Defaults to `nm`\n * @param args.formatter - Number formatter for localization (defaults to en-US)\n * @returns Formatted string like \"660 x 1,801 NM\" or \"-- x -- NM\" if invalid\n *\n * @example\n * ```typescript\n * getViewportSize({ bounds: [-82, 22, -71, 52], zoom: 5, width: 800, height: 600, unit: 'nm' })\n * // returns \"612 x 459 NM\"\n *\n * getViewportSize({ bounds: [170, 50, -170, 60], zoom: 4, width: 1024, height: 768, unit: 'km' })\n * // returns \"2,050 x 1,538 KM\"\n * ```\n */\nexport function getViewportSize({\n bounds,\n zoom,\n width: pixelWidth,\n height: pixelHeight,\n unit = 'nm',\n formatter = numberFormatter,\n}: GetViewportSizeArgs) {\n const defaultValue = `-- x -- ${unit.toUpperCase()}`;\n\n // Validate inputs\n if (!bounds || bounds.every((b) => Number.isNaN(b))) {\n return defaultValue;\n }\n\n if (Number.isNaN(zoom) || pixelWidth === 0 || pixelHeight === 0) {\n return defaultValue;\n }\n\n const [, minLat, , maxLat] = bounds;\n\n // Validate latitude bounds are within valid geographic ranges\n if (minLat < -90 || minLat > 90 || maxLat < -90 || maxLat > 90) {\n return defaultValue;\n }\n\n // Calculate center latitude for the viewport\n const centerLat = (minLat + maxLat) / 2;\n\n // Web Mercator formula: meters per pixel at given zoom and latitude\n // Resolution = 156543.03392 * cos(latitude * π/180) / 2^zoom\n const metersPerPixel =\n (METERS_PER_PIXEL_AT_ZOOM_0 * Math.cos((centerLat * Math.PI) / 180)) /\n 2 ** zoom;\n\n // Calculate distances in meters\n const widthMeters = pixelWidth * metersPerPixel;\n const heightMeters = pixelHeight * metersPerPixel;\n\n // Convert to requested unit\n const unitKey = getDistanceUnitFromAbbreviation(unit) as DistanceUnit;\n const conversionFactor = METERS_TO_UNIT[unitKey];\n\n const widthDistance = Math.round(widthMeters * conversionFactor);\n const heightDistance = Math.round(heightMeters * conversionFactor);\n\n const width = formatter.format(widthDistance);\n const height = formatter.format(heightDistance);\n\n return `${width} x ${height} ${unit.toUpperCase()}`;\n}\n"],"mappings":";;;;;;;;;;;;;;;;AAkBA,MAAM,kBAAkB,KAAK,aAAa,QAAQ;;;;;AAMlD,MAAM,6BAA6B;;;;AAKnC,MAAM,iBAAiB;CACrB,YAAY;CACZ,QAAQ;CACR,eAAe;CACf,OAAO;CACP,MAAM;CACP;;;;;;;;;;;;;;;;;;;;;;;;;;AA2BD,SAAgB,gBAAgB,EAC9B,QACA,MACA,OAAO,YACP,QAAQ,aACR,OAAO,MACP,YAAY,mBACU;CACtB,MAAM,eAAe,WAAW,KAAK,aAAa;AAGlD,KAAI,CAAC,UAAU,OAAO,OAAO,MAAM,OAAO,MAAM,EAAE,CAAC,CACjD,QAAO;AAGT,KAAI,OAAO,MAAM,KAAK,IAAI,eAAe,KAAK,gBAAgB,EAC5D,QAAO;CAGT,MAAM,GAAG,UAAU,UAAU;AAG7B,KAAI,SAAS,OAAO,SAAS,MAAM,SAAS,OAAO,SAAS,GAC1D,QAAO;CAIT,MAAM,aAAa,SAAS,UAAU;CAItC,MAAM,iBACH,6BAA6B,KAAK,IAAK,YAAY,KAAK,KAAM,IAAI,GACnE,KAAK;CAGP,MAAM,cAAc,aAAa;CACjC,MAAM,eAAe,cAAc;CAInC,MAAM,mBAAmB,eADT,gCAAgC,KAAK;CAGrD,MAAM,gBAAgB,KAAK,MAAM,cAAc,iBAAiB;CAChE,MAAM,iBAAiB,KAAK,MAAM,eAAe,iBAAiB;AAKlE,QAAO,GAHO,UAAU,OAAO,cAAc,CAG7B,KAFD,UAAU,OAAO,eAAe,CAEnB,GAAG,KAAK,aAAa"}
@@ -13,7 +13,7 @@
13
13
  import { SupportedDistanceUnit } from "./types.js";
14
14
  import { ComponentPropsWithRef } from "react";
15
15
  import { UniqueId } from "@accelint/core";
16
- import * as react_jsx_runtime1 from "react/jsx-runtime";
16
+ import * as react_jsx_runtime0 from "react/jsx-runtime";
17
17
 
18
18
  //#region src/viewport/viewport-size.d.ts
19
19
  type ViewportSizeProps = ComponentPropsWithRef<'span'> & {
@@ -48,7 +48,7 @@ declare function ViewportSize({
48
48
  instanceId,
49
49
  unit,
50
50
  ...rest
51
- }: ViewportSizeProps): react_jsx_runtime1.JSX.Element;
51
+ }: ViewportSizeProps): react_jsx_runtime0.JSX.Element;
52
52
  //#endregion
53
53
  export { ViewportSize, ViewportSizeProps };
54
54
  //# sourceMappingURL=viewport-size.d.ts.map
@@ -11,7 +11,7 @@
11
11
  */
12
12
 
13
13
 
14
- import { useViewportState } from "./use-viewport-state.js";
14
+ import { useMapViewport } from "./store.js";
15
15
  import { getViewportSize } from "./utils.js";
16
16
  import { jsx } from "react/jsx-runtime";
17
17
 
@@ -41,7 +41,7 @@ import { jsx } from "react/jsx-runtime";
41
41
  * ```
42
42
  */
43
43
  function ViewportSize({ instanceId, unit = "nm", ...rest }) {
44
- const { bounds, zoom, width, height } = useViewportState({ instanceId });
44
+ const { bounds, zoom, width, height } = useMapViewport(instanceId);
45
45
  return /* @__PURE__ */ jsx("span", {
46
46
  ...rest,
47
47
  children: getViewportSize({
@@ -1 +1 @@
1
- {"version":3,"file":"viewport-size.js","names":[],"sources":["../../src/viewport/viewport-size.tsx"],"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\nimport { useViewportState } from './use-viewport-state';\nimport { getViewportSize } from './utils';\nimport type { UniqueId } from '@accelint/core';\nimport type { ComponentPropsWithRef } from 'react';\nimport type { SupportedDistanceUnit } from './types';\n\nexport type ViewportSizeProps = ComponentPropsWithRef<'span'> & {\n instanceId: UniqueId;\n unit?: SupportedDistanceUnit;\n};\n\n/**\n * A span element displaying the current viewport bounds in the specified unit.\n *\n * Displays the viewport dimensions in a format like `660 x 1,801 NM`.\n * Updates automatically as the viewport changes by subscribing to viewport events.\n *\n * @param props - Extends `<span>` props\n * @param props.instanceId - The id of the view to subscribe to\n * @param props.unit - Measure of distance: `km | m | nm | mi | ft`. Defaults to `nm`\n * @param props.className - CSS classes for styling\n *\n * @example\n * ```tsx\n * // Basic usage with default nautical miles\n * <ViewportSize instanceId=\"some-uuid\" />\n *\n * // With custom unit and styling\n * <ViewportSize\n * instanceId=\"some-uuid\"\n * unit=\"km\"\n * className=\"text-sm text-gray-600\"\n * />\n * ```\n */\nexport function ViewportSize({\n instanceId,\n unit = 'nm',\n ...rest\n}: ViewportSizeProps) {\n const { bounds, zoom, width, height } = useViewportState({ instanceId });\n\n return (\n <span {...rest}>\n {getViewportSize({ bounds, unit, zoom, width, height })}\n </span>\n );\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA+CA,SAAgB,aAAa,EAC3B,YACA,OAAO,MACP,GAAG,QACiB;CACpB,MAAM,EAAE,QAAQ,MAAM,OAAO,WAAW,iBAAiB,EAAE,YAAY,CAAC;AAExE,QACE,oBAAC;EAAK,GAAI;YACP,gBAAgB;GAAE;GAAQ;GAAM;GAAM;GAAO;GAAQ,CAAC;GAClD"}
1
+ {"version":3,"file":"viewport-size.js","names":[],"sources":["../../src/viewport/viewport-size.tsx"],"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 { useMapViewport } from './store';\nimport { getViewportSize } from './utils';\nimport type { UniqueId } from '@accelint/core';\nimport type { ComponentPropsWithRef } from 'react';\nimport type { SupportedDistanceUnit } from './types';\n\nexport type ViewportSizeProps = ComponentPropsWithRef<'span'> & {\n instanceId: UniqueId;\n unit?: SupportedDistanceUnit;\n};\n\n/**\n * A span element displaying the current viewport bounds in the specified unit.\n *\n * Displays the viewport dimensions in a format like `660 x 1,801 NM`.\n * Updates automatically as the viewport changes by subscribing to viewport events.\n *\n * @param props - Extends `<span>` props\n * @param props.instanceId - The id of the view to subscribe to\n * @param props.unit - Measure of distance: `km | m | nm | mi | ft`. Defaults to `nm`\n * @param props.className - CSS classes for styling\n *\n * @example\n * ```tsx\n * // Basic usage with default nautical miles\n * <ViewportSize instanceId=\"some-uuid\" />\n *\n * // With custom unit and styling\n * <ViewportSize\n * instanceId=\"some-uuid\"\n * unit=\"km\"\n * className=\"text-sm text-gray-600\"\n * />\n * ```\n */\nexport function ViewportSize({\n instanceId,\n unit = 'nm',\n ...rest\n}: ViewportSizeProps) {\n const { bounds, zoom, width, height } = useMapViewport(instanceId);\n\n return (\n <span {...rest}>\n {getViewportSize({ bounds, unit, zoom, width, height })}\n </span>\n );\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA+CA,SAAgB,aAAa,EAC3B,YACA,OAAO,MACP,GAAG,QACiB;CACpB,MAAM,EAAE,QAAQ,MAAM,OAAO,WAAW,eAAe,WAAW;AAElE,QACE,oBAAC;EAAK,GAAI;YACP,gBAAgB;GAAE;GAAQ;GAAM;GAAM;GAAO;GAAQ,CAAC;GAClD"}
package/package.json CHANGED
@@ -1,10 +1,11 @@
1
1
  {
2
2
  "name": "@accelint/map-toolkit",
3
3
  "description": "A collection of components and utilities to simplify visualizing and working with geospatial data.",
4
- "version": "0.6.0",
4
+ "version": "1.1.0",
5
5
  "author": "https://hypergiant.com",
6
6
  "$schema": "https://json.schemastore.org/package",
7
7
  "devDependencies": {
8
+ "@deck.gl-community/editable-layers": "~9.1",
8
9
  "@deck.gl/core": "~9.1",
9
10
  "@deck.gl/extensions": "~9.1",
10
11
  "@deck.gl/layers": "~9.1",
@@ -20,6 +21,8 @@
20
21
  "@testing-library/jest-dom": "^6.9.1",
21
22
  "@testing-library/react": "^16.3.0",
22
23
  "@testing-library/user-event": "^14.6.1",
24
+ "@turf/helpers": "^7.2.0",
25
+ "@turf/turf": "^7.2.0",
23
26
  "@types/geojson": "^7946.0.14",
24
27
  "@types/node": "^22",
25
28
  "@types/react": "^19",
@@ -39,16 +42,17 @@
39
42
  "typescript": "^5.9.3",
40
43
  "vite": "^7.2.7",
41
44
  "vitest": "^4.0.15",
42
- "@accelint/biome-config": "1.0.2",
45
+ "@accelint/biome-config": "1.1.0",
43
46
  "@accelint/bus": "3.0.2",
44
47
  "@accelint/core": "0.5.2",
45
- "@accelint/design-toolkit": "9.1.1",
46
- "@accelint/geo": "0.5.0",
48
+ "@accelint/design-foundation": "2.1.0",
49
+ "@accelint/design-toolkit": "9.3.0",
50
+ "@accelint/geo": "0.5.1",
51
+ "@accelint/logger": "0.1.5",
47
52
  "@accelint/postcss-tailwind-css-modules": "1.0.1",
48
- "@accelint/smeegl": "0.3.4",
49
53
  "@accelint/typescript-config": "0.1.4",
50
54
  "@accelint/vitest-config": "0.1.6",
51
- "@accelint/design-foundation": "2.0.0"
55
+ "@accelint/smeegl": "0.3.4"
52
56
  },
53
57
  "engines": {
54
58
  "node": ">=22",
@@ -57,9 +61,11 @@
57
61
  "exports": {
58
62
  "./camera": "./dist/camera/index.js",
59
63
  "./camera/events": "./dist/camera/events.js",
64
+ "./camera/store": "./dist/camera/store.js",
60
65
  "./camera/types": "./dist/camera/types.js",
61
- "./camera/use-camera-state": "./dist/camera/use-camera-state.js",
62
66
  "./cursor-coordinates": "./dist/cursor-coordinates/index.js",
67
+ "./cursor-coordinates/store": "./dist/cursor-coordinates/store.js",
68
+ "./cursor-coordinates/types": "./dist/cursor-coordinates/types.js",
63
69
  "./cursor-coordinates/use-cursor-coordinates": "./dist/cursor-coordinates/use-cursor-coordinates.js",
64
70
  "./deckgl": "./dist/deckgl/index.js",
65
71
  "./deckgl/base-map": "./dist/deckgl/base-map/index.js",
@@ -72,15 +78,19 @@
72
78
  "./deckgl/saved-viewports/storage": "./dist/deckgl/saved-viewports/storage.js",
73
79
  "./deckgl/shapes": "./dist/deckgl/shapes/index.js",
74
80
  "./deckgl/shapes/display-shape-layer": "./dist/deckgl/shapes/display-shape-layer/index.js",
75
- "./deckgl/shapes/display-shape-layer/constants": "./dist/deckgl/shapes/display-shape-layer/constants.js",
76
81
  "./deckgl/shapes/display-shape-layer/fiber": "./dist/deckgl/shapes/display-shape-layer/fiber.js",
77
- "./deckgl/shapes/display-shape-layer/shape-label-layer": "./dist/deckgl/shapes/display-shape-layer/shape-label-layer.js",
78
- "./deckgl/shapes/display-shape-layer/store": "./dist/deckgl/shapes/display-shape-layer/store.js",
79
82
  "./deckgl/shapes/display-shape-layer/types": "./dist/deckgl/shapes/display-shape-layer/types.js",
80
- "./deckgl/shapes/display-shape-layer/use-shape-selection": "./dist/deckgl/shapes/display-shape-layer/use-shape-selection.js",
81
- "./deckgl/shapes/display-shape-layer/utils/display-style": "./dist/deckgl/shapes/display-shape-layer/utils/display-style.js",
82
- "./deckgl/shapes/display-shape-layer/utils/labels": "./dist/deckgl/shapes/display-shape-layer/utils/labels.js",
83
- "./deckgl/shapes/shared/constants": "./dist/deckgl/shapes/shared/constants.js",
83
+ "./deckgl/shapes/display-shape-layer/use-select-shape": "./dist/deckgl/shapes/display-shape-layer/use-select-shape.js",
84
+ "./deckgl/shapes/draw-shape-layer": "./dist/deckgl/shapes/draw-shape-layer/index.js",
85
+ "./deckgl/shapes/draw-shape-layer/events": "./dist/deckgl/shapes/draw-shape-layer/events.js",
86
+ "./deckgl/shapes/draw-shape-layer/fiber": "./dist/deckgl/shapes/draw-shape-layer/fiber.js",
87
+ "./deckgl/shapes/draw-shape-layer/types": "./dist/deckgl/shapes/draw-shape-layer/types.js",
88
+ "./deckgl/shapes/draw-shape-layer/use-draw-shape": "./dist/deckgl/shapes/draw-shape-layer/use-draw-shape.js",
89
+ "./deckgl/shapes/edit-shape-layer": "./dist/deckgl/shapes/edit-shape-layer/index.js",
90
+ "./deckgl/shapes/edit-shape-layer/events": "./dist/deckgl/shapes/edit-shape-layer/events.js",
91
+ "./deckgl/shapes/edit-shape-layer/fiber": "./dist/deckgl/shapes/edit-shape-layer/fiber.js",
92
+ "./deckgl/shapes/edit-shape-layer/types": "./dist/deckgl/shapes/edit-shape-layer/types.js",
93
+ "./deckgl/shapes/edit-shape-layer/use-edit-shape": "./dist/deckgl/shapes/edit-shape-layer/use-edit-shape.js",
84
94
  "./deckgl/shapes/shared/events": "./dist/deckgl/shapes/shared/events.js",
85
95
  "./deckgl/shapes/shared/types": "./dist/deckgl/shapes/shared/types.js",
86
96
  "./deckgl/symbol-layer": "./dist/deckgl/symbol-layer/index.js",
@@ -89,6 +99,7 @@
89
99
  "./deckgl/text-layer/character-sets": "./dist/deckgl/text-layer/character-sets.js",
90
100
  "./deckgl/text-layer/default-settings": "./dist/deckgl/text-layer/default-settings.js",
91
101
  "./deckgl/text-layer/fiber": "./dist/deckgl/text-layer/fiber.js",
102
+ "./deckgl/text-settings": "./dist/deckgl/text-settings.js",
92
103
  "./map-cursor": "./dist/map-cursor/index.js",
93
104
  "./map-cursor/events": "./dist/map-cursor/events.js",
94
105
  "./map-cursor/store": "./dist/map-cursor/store.js",
@@ -100,12 +111,13 @@
100
111
  "./map-mode/types": "./dist/map-mode/types.js",
101
112
  "./map-mode/use-map-mode": "./dist/map-mode/use-map-mode.js",
102
113
  "./maplibre": "./dist/maplibre/index.js",
103
- "./maplibre/constants": "./dist/maplibre/constants.js",
104
114
  "./maplibre/hooks/use-maplibre": "./dist/maplibre/hooks/use-maplibre.js",
115
+ "./shared/constants": "./dist/shared/constants.js",
116
+ "./shared/create-map-store": "./dist/shared/create-map-store.js",
117
+ "./shared/units": "./dist/shared/units.js",
105
118
  "./viewport": "./dist/viewport/index.js",
106
- "./viewport/constants": "./dist/viewport/constants.js",
119
+ "./viewport/store": "./dist/viewport/store.js",
107
120
  "./viewport/types": "./dist/viewport/types.js",
108
- "./viewport/use-viewport-state": "./dist/viewport/use-viewport-state.js",
109
121
  "./viewport/utils": "./dist/viewport/utils.js",
110
122
  "./viewport/viewport-size": "./dist/viewport/viewport-size.js",
111
123
  "./package.json": "./package.json"
@@ -125,6 +137,7 @@
125
137
  ],
126
138
  "license": "Apache-2.0",
127
139
  "optionalDependencies": {
140
+ "@deck.gl-community/editable-layers": "~9.1",
128
141
  "@deck.gl/core": "~9.1",
129
142
  "@deck.gl/extensions": "~9.1",
130
143
  "@deck.gl/layers": "~9.1",
@@ -132,6 +145,8 @@
132
145
  "@deckgl-fiber-renderer/shared": "^1.4.0",
133
146
  "@deckgl-fiber-renderer/types": "^1.4.0",
134
147
  "@math.gl/web-mercator": "^4.1.0",
148
+ "@turf/helpers": "^7.2.0",
149
+ "@turf/turf": "^7.2.0",
135
150
  "maplibre-gl": "^5.7.1",
136
151
  "milsymbol": "^3.0.2",
137
152
  "mjolnir.js": "^3.0.0",
@@ -142,9 +157,10 @@
142
157
  "peerDependencies": {
143
158
  "@types/geojson": "^7946.0.14",
144
159
  "react": "^19",
145
- "@accelint/bus": "3.0.2",
146
160
  "@accelint/core": "0.5.2",
147
- "@accelint/geo": "0.5.0"
161
+ "@accelint/geo": "0.5.1",
162
+ "@accelint/logger": "0.1.5",
163
+ "@accelint/bus": "3.0.2"
148
164
  },
149
165
  "private": false,
150
166
  "publishConfig": {
@@ -156,9 +172,13 @@
156
172
  },
157
173
  "sideEffects": [
158
174
  "./src/deckgl/shapes/display-shape-layer/fiber.ts",
175
+ "./src/deckgl/shapes/draw-shape-layer/fiber.ts",
176
+ "./src/deckgl/shapes/edit-shape-layer/fiber.ts",
159
177
  "./src/deckgl/symbol-layer/fiber.ts",
160
178
  "./src/deckgl/text-layer/fiber.ts",
161
179
  "./dist/deckgl/shapes/display-shape-layer/fiber.js",
180
+ "./dist/deckgl/shapes/draw-shape-layer/fiber.js",
181
+ "./dist/deckgl/shapes/edit-shape-layer/fiber.js",
162
182
  "./dist/deckgl/symbol-layer/fiber.js",
163
183
  "./dist/deckgl/text-layer/fiber.js"
164
184
  ],
@@ -1,153 +0,0 @@
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
- import { useSyncExternalStore } from "react";
14
- import { UniqueId } from "@accelint/core";
15
-
16
- //#region src/camera/use-camera-state.d.ts
17
- type CameraState2D = {
18
- latitude: number;
19
- longitude: number;
20
- zoom: number;
21
- pitch: 0;
22
- rotation: number;
23
- projection: 'mercator';
24
- view: '2D';
25
- };
26
- type CameraState3D = {
27
- latitude: number;
28
- longitude: number;
29
- zoom: number;
30
- pitch: 0;
31
- rotation: number;
32
- projection: 'globe';
33
- view: '3D';
34
- };
35
- type CameraState2Point5D = {
36
- latitude: number;
37
- longitude: number;
38
- zoom: number;
39
- pitch: number;
40
- rotation: number;
41
- projection: 'mercator';
42
- view: '2.5D';
43
- };
44
- type CameraState = CameraState2D | CameraState3D | CameraState2Point5D;
45
- type UseCameraStateProps = {
46
- instanceId: UniqueId;
47
- initialCameraState?: Partial<CameraState>;
48
- subscribe?: Parameters<typeof useSyncExternalStore<CameraState>>[0];
49
- getSnapshot?: Parameters<typeof useSyncExternalStore<CameraState>>[1];
50
- getServerSnapshot?: Parameters<typeof useSyncExternalStore<CameraState>>[2];
51
- };
52
- /**
53
- * Updates the camera state for a given map instance and notifies subscribers.
54
- *
55
- * @param instanceId - The unique identifier for the map
56
- * @param state - The new state to set, will be merged with existing state
57
- *
58
- * @example
59
- * ```tsx
60
- * // Update camera state manually
61
- * setCameraState('my-map-instance', {
62
- * latitude: 37.7749,
63
- * longitude: -122.4194,
64
- * zoom: 10,
65
- * pitch: 30,
66
- * rotation: 0,
67
- * projection: 'mercator',
68
- * });
69
- * ```
70
- */
71
- declare function setCameraState(instanceId: UniqueId, state: Partial<CameraState>): void;
72
- /**
73
- * Hook to access camera state actions.
74
- *
75
- * This hook uses `useSyncExternalStore` to subscribe to camera state changes,
76
- * providing concurrent-safe mode state updates. Uses a fan-out pattern where
77
- * a single bus listener per map instance notifies N React component subscribers.
78
- *
79
- * A thin wrapper around [useSyncExternalStore](https://react.dev/reference/react/useSyncExternalStore).
80
- *
81
- * @param instanceId - Unique identifier for the camera to track
82
- * @param initialCameraState - Optional initial camera state to set
83
- * @param subscribe - Optional custom subscription function
84
- * @param getSnapshot - Optional custom snapshot getter
85
- * @param getServerSnapshot - Optional server-side snapshot getter
86
- * @returns Current camera state including latitude, longitude, zoom, pitch, rotation, projection
87
- *
88
- * @example
89
- * ```tsx
90
- * function MapInfo({ instanceId }) {
91
- * const { latitude, longitude, zoom } = useCameraState({
92
- * instanceId
93
- * });
94
- *
95
- * return (
96
- * <div>
97
- * Lat: {latitude?.toFixed(2)}, Lon: {longitude?.toFixed(2)}, Zoom: {zoom}
98
- * </div>
99
- * );
100
- * }
101
- * ```
102
- *
103
- * @example
104
- * ```tsx
105
- * // With custom subscribe/getSnapshot for advanced use cases
106
- * function CustomMapInfo() {
107
- * const customSubscribe = (onStoreChange) => {
108
- * // Custom subscription logic
109
- * return () => { // cleanup }
110
- * }
111
- *
112
- * const customGetSnapshot = () => {
113
- * // Custom snapshot logic
114
- * return { latitude: 0, longitude: 0, zoom: 1 };
115
- * };
116
- *
117
- * const viewState = useCameraState({
118
- * instanceId: 'some-uuid',
119
- * subscribe: customSubscribe,
120
- * getSnapshot: customGetSnapshot,
121
- * });
122
- *
123
- * return <div>Custom camera state</div>;
124
- * }
125
- * ```
126
- */
127
- declare function useCameraState({
128
- instanceId,
129
- initialCameraState,
130
- subscribe,
131
- getSnapshot,
132
- getServerSnapshot
133
- }: UseCameraStateProps): {
134
- cameraState: CameraState;
135
- setCameraState: typeof setCameraState;
136
- };
137
- /**
138
- * Manually clear camera state for a specific instanceId.
139
- * This is typically not needed as cleanup happens automatically when all subscribers unmount.
140
- * Use this only in advanced scenarios where manual cleanup is required.
141
- *
142
- * @param instanceId - The unique identifier for the camera to clear
143
- *
144
- * @example
145
- * ```tsx
146
- * // Manual cleanup (rarely needed)
147
- * clearCameraState('my-map-instance');
148
- * ```
149
- */
150
- declare function clearCameraState(instanceId: UniqueId): void;
151
- //#endregion
152
- export { CameraState, UseCameraStateProps, clearCameraState, useCameraState };
153
- //# sourceMappingURL=use-camera-state.d.ts.map