isard 1.1.0 → 1.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (254) hide show
  1. package/CHANGELOG.md +121 -0
  2. package/README.md +44 -39
  3. package/dist/basemap/basemaps.d.ts +1 -1
  4. package/dist/basemap/basemaps.js +2 -2
  5. package/dist/basemap/basemaps.js.map +1 -1
  6. package/dist/basemap/grid.d.ts +5 -5
  7. package/dist/basemap/grid.js +59 -65
  8. package/dist/basemap/grid.js.map +1 -1
  9. package/dist/basemap/mvt.d.ts +1 -1
  10. package/dist/basemap/mvt.js +6 -6
  11. package/dist/basemap/mvt.js.map +1 -1
  12. package/dist/basemap/pmtiles.d.ts +10 -10
  13. package/dist/basemap/pmtiles.js +39 -31
  14. package/dist/basemap/pmtiles.js.map +1 -1
  15. package/dist/basemap/pmtileslayer.d.ts +33 -0
  16. package/dist/basemap/pmtileslayer.js +97 -0
  17. package/dist/basemap/pmtileslayer.js.map +1 -0
  18. package/dist/basemap/resample.d.ts +2 -2
  19. package/dist/basemap/resample.js +16 -14
  20. package/dist/basemap/resample.js.map +1 -1
  21. package/dist/basemap/terrain.d.ts +3 -3
  22. package/dist/basemap/terrain.js +6 -6
  23. package/dist/basemap/terrain.js.map +1 -1
  24. package/dist/basemap/trees.d.ts +26 -0
  25. package/dist/basemap/trees.js +141 -0
  26. package/dist/basemap/trees.js.map +1 -0
  27. package/dist/basemap/vectorstyle.d.ts +22 -10
  28. package/dist/basemap/vectorstyle.js +163 -110
  29. package/dist/basemap/vectorstyle.js.map +1 -1
  30. package/dist/basemap/vectortiles.d.ts +70 -47
  31. package/dist/basemap/vectortiles.js +480 -358
  32. package/dist/basemap/vectortiles.js.map +1 -1
  33. package/dist/basemap/wmts.d.ts +3 -3
  34. package/dist/basemap/wmts.js +16 -11
  35. package/dist/basemap/wmts.js.map +1 -1
  36. package/dist/basemap/workerpool.d.ts +17 -0
  37. package/dist/basemap/workerpool.js +194 -0
  38. package/dist/basemap/workerpool.js.map +1 -0
  39. package/dist/basemap.worker.js +2 -2
  40. package/dist/basemap.worker.js.map +21 -13
  41. package/dist/bind/layers.d.ts +13 -4
  42. package/dist/bind/layers.js +64 -40
  43. package/dist/bind/layers.js.map +1 -1
  44. package/dist/data/crs.d.ts +10 -10
  45. package/dist/data/crs.js +38 -34
  46. package/dist/data/crs.js.map +1 -1
  47. package/dist/data/gpx.d.ts +1 -1
  48. package/dist/data/gpx.js +20 -20
  49. package/dist/data/gpx.js.map +1 -1
  50. package/dist/data/kml.d.ts +1 -1
  51. package/dist/data/kml.js +42 -39
  52. package/dist/data/kml.js.map +1 -1
  53. package/dist/data/topojson.d.ts +1 -1
  54. package/dist/data/topojson.js +15 -10
  55. package/dist/data/topojson.js.map +1 -1
  56. package/dist/data/xml.d.ts +5 -5
  57. package/dist/data/xml.js +19 -18
  58. package/dist/data/xml.js.map +1 -1
  59. package/dist/decoder.worker.js +4 -4
  60. package/dist/decoder.worker.js.map +6 -6
  61. package/dist/engine/decoders.d.ts +2 -2
  62. package/dist/engine/decoders.js +28 -25
  63. package/dist/engine/decoders.js.map +1 -1
  64. package/dist/engine/loader.js +13 -14
  65. package/dist/engine/loader.js.map +1 -1
  66. package/dist/engine/requests.d.ts +1 -1
  67. package/dist/engine/requests.js +19 -16
  68. package/dist/engine/requests.js.map +1 -1
  69. package/dist/engine-loader.d.ts +13 -9
  70. package/dist/engine-loader.js +38 -28
  71. package/dist/engine-loader.js.map +1 -1
  72. package/dist/geoplateforme.d.ts +26 -10
  73. package/dist/geoplateforme.js +45 -20
  74. package/dist/geoplateforme.js.map +1 -1
  75. package/dist/index.d.ts +12 -4
  76. package/dist/index.js +9 -2
  77. package/dist/index.js.map +1 -1
  78. package/dist/isard_bg.wasm +0 -0
  79. package/dist/isard_core_bg.wasm +0 -0
  80. package/dist/isard_points_bg.wasm +0 -0
  81. package/dist/isard_tess_bg.wasm +0 -0
  82. package/dist/layers/extrusions.d.ts +1 -1
  83. package/dist/layers/extrusions.js +10 -5
  84. package/dist/layers/extrusions.js.map +1 -1
  85. package/dist/layers/features.d.ts +10 -10
  86. package/dist/layers/features.js +41 -42
  87. package/dist/layers/features.js.map +1 -1
  88. package/dist/layers/glyphs.d.ts +3 -3
  89. package/dist/layers/glyphs.js +34 -40
  90. package/dist/layers/glyphs.js.map +1 -1
  91. package/dist/layers/icons.d.ts +8 -8
  92. package/dist/layers/icons.js +76 -68
  93. package/dist/layers/icons.js.map +1 -1
  94. package/dist/layers/layers.d.ts +1 -1
  95. package/dist/layers/layers.js +42 -29
  96. package/dist/layers/layers.js.map +1 -1
  97. package/dist/layers/panoramas.d.ts +2 -2
  98. package/dist/layers/panoramas.js +52 -41
  99. package/dist/layers/panoramas.js.map +1 -1
  100. package/dist/layers/pointclouds.d.ts +3 -3
  101. package/dist/layers/pointclouds.js +25 -33
  102. package/dist/layers/pointclouds.js.map +1 -1
  103. package/dist/layers/symbols.d.ts +1 -1
  104. package/dist/layers/symbols.js +68 -71
  105. package/dist/layers/symbols.js.map +1 -1
  106. package/dist/layers/vectors.d.ts +60 -0
  107. package/dist/layers/vectors.js +130 -0
  108. package/dist/layers/vectors.js.map +1 -0
  109. package/dist/map/basemap-layers.d.ts +26 -0
  110. package/dist/map/basemap-layers.js +61 -0
  111. package/dist/map/basemap-layers.js.map +1 -0
  112. package/dist/map/canvas.d.ts +17 -0
  113. package/dist/map/canvas.js +56 -0
  114. package/dist/map/canvas.js.map +1 -0
  115. package/dist/map/checks.d.ts +11 -0
  116. package/dist/map/checks.js +39 -0
  117. package/dist/map/checks.js.map +1 -0
  118. package/dist/map/credits.d.ts +17 -0
  119. package/dist/map/credits.js +34 -0
  120. package/dist/map/credits.js.map +1 -0
  121. package/dist/map/engine-settings.d.ts +15 -0
  122. package/dist/map/engine-settings.js +45 -0
  123. package/dist/map/engine-settings.js.map +1 -0
  124. package/dist/map/engines.d.ts +41 -0
  125. package/dist/map/engines.js +77 -0
  126. package/dist/map/engines.js.map +1 -0
  127. package/dist/map/events.d.ts +14 -0
  128. package/dist/map/events.js +46 -0
  129. package/dist/map/events.js.map +1 -0
  130. package/dist/map/frame-loop.d.ts +64 -0
  131. package/dist/map/frame-loop.js +145 -0
  132. package/dist/map/frame-loop.js.map +1 -0
  133. package/dist/map/hover-pick.d.ts +30 -0
  134. package/dist/map/hover-pick.js +56 -0
  135. package/dist/map/hover-pick.js.map +1 -0
  136. package/dist/map/layer-spec.d.ts +42 -0
  137. package/dist/map/layer-spec.js +34 -0
  138. package/dist/map/layer-spec.js.map +1 -0
  139. package/dist/map/layer-stack.d.ts +36 -0
  140. package/dist/map/layer-stack.js +101 -0
  141. package/dist/map/layer-stack.js.map +1 -0
  142. package/dist/map/overlay-host.d.ts +36 -0
  143. package/dist/map/overlay-host.js +101 -0
  144. package/dist/map/overlay-host.js.map +1 -0
  145. package/dist/map/panorama-host.d.ts +5 -0
  146. package/dist/map/panorama-host.js +32 -0
  147. package/dist/map/panorama-host.js.map +1 -0
  148. package/dist/map/raster-source.d.ts +11 -0
  149. package/dist/map/raster-source.js +26 -0
  150. package/dist/map/raster-source.js.map +1 -0
  151. package/dist/map/symbol-atlases.d.ts +26 -0
  152. package/dist/map/symbol-atlases.js +59 -0
  153. package/dist/map/symbol-atlases.js.map +1 -0
  154. package/dist/map/viewshed.d.ts +5 -0
  155. package/dist/map/viewshed.js +28 -0
  156. package/dist/map/viewshed.js.map +1 -0
  157. package/dist/map/workers.d.ts +46 -0
  158. package/dist/map/workers.js +73 -0
  159. package/dist/map/workers.js.map +1 -0
  160. package/dist/map.d.ts +54 -126
  161. package/dist/map.js +227 -698
  162. package/dist/map.js.map +1 -1
  163. package/dist/react/Control.d.ts +11 -0
  164. package/dist/react/Control.js +18 -0
  165. package/dist/react/Control.js.map +1 -0
  166. package/dist/react/CustomLayer.d.ts +11 -0
  167. package/dist/react/CustomLayer.js +30 -0
  168. package/dist/react/CustomLayer.js.map +1 -0
  169. package/dist/react/IsardMap.d.ts +43 -0
  170. package/dist/react/IsardMap.js +147 -0
  171. package/dist/react/IsardMap.js.map +1 -0
  172. package/dist/react/Layer.d.ts +42 -0
  173. package/dist/react/Layer.js +74 -0
  174. package/dist/react/Layer.js.map +1 -0
  175. package/dist/react/Marker.d.ts +24 -0
  176. package/dist/react/Marker.js +53 -0
  177. package/dist/react/Marker.js.map +1 -0
  178. package/dist/react/Panel.d.ts +11 -0
  179. package/dist/react/Panel.js +37 -0
  180. package/dist/react/Panel.js.map +1 -0
  181. package/dist/react/Popup.d.ts +18 -0
  182. package/dist/react/Popup.js +60 -0
  183. package/dist/react/Popup.js.map +1 -0
  184. package/dist/react/Swipe.d.ts +16 -0
  185. package/dist/react/Swipe.js +52 -0
  186. package/dist/react/Swipe.js.map +1 -0
  187. package/dist/react/VectorGeometry.d.ts +35 -0
  188. package/dist/react/VectorGeometry.js +82 -0
  189. package/dist/react/VectorGeometry.js.map +1 -0
  190. package/dist/react/Viewshed.d.ts +5 -0
  191. package/dist/react/Viewshed.js +28 -0
  192. package/dist/react/Viewshed.js.map +1 -0
  193. package/dist/react/context.d.ts +33 -0
  194. package/dist/react/context.js +20 -0
  195. package/dist/react/context.js.map +1 -0
  196. package/dist/react/index.d.ts +16 -108
  197. package/dist/react/index.js +11 -397
  198. package/dist/react/index.js.map +1 -1
  199. package/dist/settings.d.ts +5 -9
  200. package/dist/settings.js +17 -15
  201. package/dist/settings.js.map +1 -1
  202. package/dist/types.d.ts +27 -4
  203. package/dist/types.js.map +1 -1
  204. package/dist/ui/controls.js +6 -4
  205. package/dist/ui/controls.js.map +1 -1
  206. package/dist/ui/interaction.d.ts +2 -2
  207. package/dist/ui/interaction.js +8 -7
  208. package/dist/ui/interaction.js.map +1 -1
  209. package/dist/ui/minimap.d.ts +25 -0
  210. package/dist/ui/minimap.js +90 -0
  211. package/dist/ui/minimap.js.map +1 -0
  212. package/dist/ui/overlay.js +18 -20
  213. package/dist/ui/overlay.js.map +1 -1
  214. package/dist/ui/scale.d.ts +19 -0
  215. package/dist/ui/scale.js +44 -0
  216. package/dist/ui/scale.js.map +1 -0
  217. package/dist/ui/search.d.ts +25 -0
  218. package/dist/ui/search.js +119 -0
  219. package/dist/ui/search.js.map +1 -0
  220. package/dist/ui/style.d.ts +1 -1
  221. package/dist/ui/style.js +19 -2
  222. package/dist/ui/style.js.map +1 -1
  223. package/dist/util/animation.d.ts +3 -3
  224. package/dist/util/animation.js +6 -6
  225. package/dist/util/animation.js.map +1 -1
  226. package/dist/util/color.d.ts +1 -1
  227. package/dist/util/color.js +14 -16
  228. package/dist/util/color.js.map +1 -1
  229. package/dist/util/geo.d.ts +6 -6
  230. package/dist/util/geo.js +12 -12
  231. package/dist/util/geo.js.map +1 -1
  232. package/dist/util/guards.d.ts +7 -0
  233. package/dist/util/guards.js +8 -0
  234. package/dist/util/guards.js.map +1 -0
  235. package/dist/util/lru.js.map +1 -1
  236. package/dist/util/sun.d.ts +11 -0
  237. package/dist/util/sun.js +26 -0
  238. package/dist/util/sun.js.map +1 -0
  239. package/dist/wasm/isard.d.ts +250 -7
  240. package/dist/wasm/isard.js +375 -8
  241. package/dist/wasm/isard_core.d.ts +226 -7
  242. package/dist/wasm/isard_core.js +351 -8
  243. package/dist/wasm/isard_tess.d.ts +109 -0
  244. package/dist/wasm/isard_tess.js +398 -0
  245. package/dist/workers/basemap/geometry.d.ts +72 -0
  246. package/dist/workers/basemap/labels.d.ts +8 -0
  247. package/dist/workers/basemap/raster.d.ts +10 -0
  248. package/dist/workers/basemap/tiles.d.ts +65 -0
  249. package/dist/workers/basemap/trees.d.ts +19 -0
  250. package/dist/workers/basemap.worker.d.ts +126 -22
  251. package/dist/workers/basemap.worker.js +76 -544
  252. package/dist/workers/basemap.worker.js.map +1 -1
  253. package/package.json +5 -4
  254. package/vite.js +10 -2
@@ -9,401 +9,15 @@
9
9
  * </IsardMap>
10
10
  * ```
11
11
  */
12
- import { createContext, createElement, forwardRef, useContext, useEffect, useImperativeHandle, useLayoutEffect, useMemo, useRef, useState, } from 'react';
13
- import { createPortal } from 'react-dom';
14
- import { applyLayerChange, LayerOrder, layerChange } from "../bind/layers.js";
15
- import { GeoMap } from "../map.js";
16
- import { Marker as MarkerHandle, Panel as PanelHandle, Popup as PopupHandle, } from "../ui/overlay.js";
17
- const MapContext = createContext(undefined);
18
- /** The map of the `<IsardMap>` around, once created (undefined before) */
19
- export function useMap() {
20
- return useContext(MapContext)?.map;
21
- }
22
- /** Listens to an event of the map around while the component is mounted; the listener may change at each render */
23
- export function useMapEvent(type, listener) {
24
- const map = useMap();
25
- const latest = useRef(listener);
26
- latest.current = listener;
27
- useEffect(() => map?.on(type, (event) => latest.current(event)), [map, type]);
28
- }
29
- const EVENT_PROPS = {
30
- onMoveStart: 'movestart',
31
- onMove: 'move',
32
- onMoveEnd: 'moveend',
33
- onResize: 'resize',
34
- onHover: 'hover',
35
- onHoverFeature: 'hoverfeature',
36
- onClick: 'click',
37
- onRender: 'render',
38
- onIdle: 'idle',
39
- onLeave: 'leave',
40
- };
41
- /** Options the map takes again after its creation, and how */
42
- const LIVE_OPTIONS = {
43
- basemap: (map, p) => {
44
- if (p.basemap)
45
- map.setBasemap(p.basemap, p.hillshade);
46
- },
47
- hillshade: (map, p) => {
48
- if (p.basemap)
49
- map.setBasemap(p.basemap, p.hillshade);
50
- },
51
- terrain: (map, p) => map.setTerrain(p.terrain ?? false),
52
- minZoom: (map, p) => map.setMinZoom(p.minZoom ?? 0),
53
- maxZoom: (map, p) => map.setMaxZoom(p.maxZoom ?? 22),
54
- maxPitch: (map, p) => map.setMaxPitch(p.maxPitch ?? 70),
55
- atmosphere: (map, p) => map.setAtmosphere(p.atmosphere),
56
- projection: (map, p) => map.setProjection(p.projection ?? 'globe'),
57
- loading: (map, p) => map.setLoading(p.loading ?? 'immediate'),
58
- sky: (map, p) => map.setSky(p.sky ?? true),
59
- background: (map, p) => {
60
- if (p.background)
61
- map.setBackground(p.background);
62
- },
63
- };
64
- function sameCamera(a, b) {
65
- return ((b.center === undefined || (a.center[0] === b.center[0] && a.center[1] === b.center[1])) &&
66
- (b.zoom === undefined || a.zoom === b.zoom) &&
67
- (b.pitch === undefined || a.pitch === b.pitch) &&
68
- (b.bearing === undefined || a.bearing === b.bearing));
69
- }
70
- /**
71
- * A map filling its element (give it a height). Created once mounted, destroyed when unmounted; the options read at
72
- * creation only (`body`, `preset`, `interactive`, the URLs) need a new `key` to take another value
73
- */
74
- export const IsardMap = forwardRef(function IsardMap(props, ref) {
75
- const element = useRef(null);
76
- const [binding, setBinding] = useState();
77
- const latest = useRef(props);
78
- latest.current = props;
79
- useImperativeHandle(ref, () => binding?.map, [binding]);
80
- useEffect(() => {
81
- const container = element.current;
82
- if (!container)
83
- return;
84
- let cancelled = false;
85
- let created;
86
- const { camera, center, zoom, pitch, bearing, children: _, ...options } = latest.current;
87
- GeoMap.create(container, {
88
- ...stripProps(options),
89
- ...defined({ center, zoom, pitch, bearing }),
90
- ...camera,
91
- }).then((map) => {
92
- // Unmounted while the engine was loading (or StrictMode's second mount): that map is not wanted
93
- if (cancelled) {
94
- map.destroy();
95
- return;
96
- }
97
- created = map;
98
- const viewsheds = new Map();
99
- setBinding({
100
- map,
101
- order: new LayerOrder(),
102
- viewsheds,
103
- applyViewsheds: () => map.setViewshed(viewsheds.size > 0 ? [...viewsheds.values()] : undefined),
104
- });
105
- latest.current.onLoad?.(map);
106
- }, (error) => {
107
- if (cancelled)
108
- return;
109
- if (latest.current.onError)
110
- latest.current.onError(error);
111
- else
112
- console.error(error);
113
- });
114
- return () => {
115
- cancelled = true;
116
- created?.destroy();
117
- setBinding(undefined);
118
- };
119
- }, []);
120
- // The events, each listened to once: the props may give another function at each render
121
- const map = binding?.map;
122
- useEffect(() => {
123
- if (!map)
124
- return;
125
- const offs = Object.entries(EVENT_PROPS).map(([prop, type]) => map.on(type, (event) => latest.current[prop]?.(event)));
126
- return () => {
127
- for (const off of offs)
128
- off();
129
- };
130
- }, [map]);
131
- // The options taken again, compared with what the map was given last
132
- const applied = useRef(props);
133
- useEffect(() => {
134
- if (!map)
135
- return;
136
- const last = applied.current;
137
- applied.current = props;
138
- const done = new Set();
139
- for (const [key, apply] of Object.entries(LIVE_OPTIONS)) {
140
- if (!apply || done.has(apply) || Object.is(last[key], props[key])) {
141
- continue;
142
- }
143
- done.add(apply);
144
- apply(map, props);
145
- }
146
- });
147
- const { camera } = props;
148
- useEffect(() => {
149
- if (map && camera && !sameCamera(map.getCamera(), camera))
150
- map.setCamera(camera);
151
- }, [map, camera]);
152
- return createElement('div', { ref: element, id: props.id, className: props.className, style: props.style }, binding ? createElement(MapContext.Provider, { value: binding }, props.children) : null);
153
- });
154
- /** The props that are not options of the map */
155
- function stripProps(props) {
156
- const options = { ...props };
157
- for (const key of [...Object.keys(EVENT_PROPS), 'onLoad', 'onError', 'id', 'className', 'style'])
158
- delete options[key];
159
- return options;
160
- }
161
- /** The entries of an object whose value is defined (`exactOptionalPropertyTypes`) */
162
- function defined(object) {
163
- return Object.fromEntries(Object.entries(object).filter(([, value]) => value !== undefined));
164
- }
165
- // ── Layers ──
166
- const SwipeContext = createContext(undefined);
167
- /**
168
- * A layer: the options of its `add…` method with its `type` (`map.add`). A change of data, style or instances updates
169
- * it; a change of what is set at creation (its URL, grid, nodes…) makes it anew, in its place. Data, functions and
170
- * arrays are compared by identity: keep them in a memo or a state. The ref gives the layer's handle
171
- */
172
- export const Layer = forwardRef(function Layer(props, ref) {
173
- const binding = useContext(MapContext);
174
- const swipe = useContext(SwipeContext);
175
- const { order = 0, onLayer, ...spec } = props;
176
- const state = useRef(undefined);
177
- const [layer, setLayer] = useState();
178
- useImperativeHandle(ref, () => layer, [layer]);
179
- const latest = useRef({ spec, order, onLayer });
180
- latest.current = { spec, order, onLayer };
181
- useEffect(() => {
182
- if (!binding)
183
- return;
184
- const { spec, order, onLayer } = latest.current;
185
- const created = binding.map.add(spec);
186
- binding.order.place(created, order);
187
- state.current = { layer: created, spec, order };
188
- swipe?.set(created);
189
- setLayer(created);
190
- onLayer?.(created);
191
- return () => {
192
- const current = state.current;
193
- state.current = undefined;
194
- if (!current)
195
- return;
196
- binding.order.remove(current.layer);
197
- swipe?.unset(current.layer);
198
- if (binding.map.hasLayer(current.layer))
199
- current.layer.remove();
200
- };
201
- }, [binding, swipe]);
202
- useEffect(() => {
203
- const current = state.current;
204
- if (!binding || !current)
205
- return;
206
- const next = spec;
207
- const change = layerChange(current.spec, next);
208
- current.spec = next;
209
- if (change?.rebuild) {
210
- const old = current.layer;
211
- const fresh = binding.map.rebuildLayer(old, next);
212
- binding.order.place(fresh, order, old);
213
- swipe?.unset(old);
214
- swipe?.set(fresh);
215
- current.layer = fresh;
216
- current.order = order;
217
- setLayer(fresh);
218
- latest.current.onLayer?.(fresh);
219
- return;
220
- }
221
- if (change)
222
- applyLayerChange(current.layer, next, change);
223
- if (current.order !== order) {
224
- current.order = order;
225
- binding.order.place(current.layer, order, current.layer);
226
- }
227
- });
228
- return null;
229
- });
230
- // ── Markers, popups, panels ──
231
- /** The marker of a `<Marker>` around (a `<Popup>` in it opens on its click) */
232
- const MarkerContext = createContext(undefined);
233
- /** A marker at a position, its look the default pin or the `icon` given */
234
- export function Marker(props) {
235
- const map = useMap();
236
- const custom = props.icon !== undefined;
237
- const { anchor, className } = props;
238
- const element = useMemo(() => (custom ? document.createElement('div') : undefined), [custom]);
239
- const marker = useMemo(() => new MarkerHandle({ ...defined({ anchor, className, element }) }), [anchor, className, element]);
240
- const latest = useRef(props);
241
- latest.current = props;
242
- useEffect(() => {
243
- if (!map)
244
- return;
245
- marker.addTo(map);
246
- const offs = [
247
- marker.on('dragstart', (e) => latest.current.onDragStart?.(e.lonLat)),
248
- marker.on('drag', (e) => latest.current.onDrag?.(e.lonLat)),
249
- marker.on('dragend', (e) => latest.current.onDragEnd?.(e.lonLat)),
250
- ];
251
- return () => {
252
- for (const off of offs)
253
- off();
254
- marker.remove();
255
- };
256
- }, [map, marker]);
257
- const { lonLat, height = 0, base = 0, draggable = false, offset } = props;
258
- useLayoutEffect(() => {
259
- marker.setLonLat(lonLat);
260
- }, [marker, lonLat[0], lonLat[1]]);
261
- useLayoutEffect(() => {
262
- marker.setHeight(height, base);
263
- }, [marker, height, base]);
264
- useLayoutEffect(() => {
265
- marker.setDraggable(draggable);
266
- }, [marker, draggable]);
267
- useLayoutEffect(() => {
268
- if (offset)
269
- marker.setOffset(offset);
270
- }, [marker, offset?.[0], offset?.[1]]);
271
- return createElement(MarkerContext.Provider, { value: marker }, element ? createPortal(props.icon, element) : null, props.children);
272
- }
273
- /** A popup of JSX content, at a position or on a `<Marker>` */
274
- export function Popup(props) {
275
- const map = useMap();
276
- const marker = useContext(MarkerContext);
277
- const { anchor, closeButton, closeOnClick, maxWidth, className } = props;
278
- const content = useMemo(() => document.createElement('div'), []);
279
- const popup = useMemo(() => new PopupHandle(defined({ anchor, closeButton, closeOnClick, maxWidth, className })).setDOMContent(content), [anchor, closeButton, closeOnClick, maxWidth, className, content]);
280
- const latest = useRef(props);
281
- latest.current = props;
282
- useEffect(() => {
283
- if (!map)
284
- return;
285
- const offs = [
286
- popup.on('open', () => latest.current.onOpen?.()),
287
- popup.on('close', () => latest.current.onClose?.()),
288
- ];
289
- if (marker)
290
- marker.setPopup(popup);
291
- return () => {
292
- for (const off of offs)
293
- off();
294
- if (marker?.getPopup() === popup)
295
- marker.setPopup(undefined);
296
- popup.remove();
297
- };
298
- }, [map, marker, popup]);
299
- const { lonLat, height, open, offset } = props;
300
- const opened = open ?? !marker;
301
- useLayoutEffect(() => {
302
- if (offset)
303
- popup.setOffset(offset);
304
- }, [popup, offset?.[0], offset?.[1]]);
305
- useLayoutEffect(() => {
306
- if (!map)
307
- return;
308
- if (lonLat)
309
- popup.setLonLat(lonLat);
310
- else if (marker)
311
- popup.setLonLat(marker.getLonLat());
312
- if (height !== undefined)
313
- popup.setHeight(height);
314
- if (open === undefined && marker)
315
- return;
316
- if (opened && !popup.isOpen())
317
- popup.addTo(map);
318
- if (!opened && popup.isOpen())
319
- popup.remove();
320
- }, [map, marker, popup, lonLat?.[0], lonLat?.[1], height, open, opened]);
321
- return createPortal(props.children, content);
322
- }
323
- /** JSX standing in 3D at a position, `width` metres wide, facing `heading` */
324
- export function Panel(props) {
325
- const map = useMap();
326
- const { className } = props;
327
- const element = useMemo(() => document.createElement('div'), []);
328
- // The width at creation: the placement is set again by the effect below
329
- const initialWidth = useRef(props.width);
330
- const panel = useMemo(() => new PanelHandle({ element, width: initialWidth.current, ...defined({ className }) }), [element, className]);
331
- useEffect(() => {
332
- if (!map)
333
- return;
334
- panel.addTo(map);
335
- return () => {
336
- panel.remove();
337
- };
338
- }, [map, panel]);
339
- const { lonLat, width, heading, pitch, height } = props;
340
- useLayoutEffect(() => {
341
- panel.setLonLat(lonLat);
342
- }, [panel, lonLat[0], lonLat[1]]);
343
- useLayoutEffect(() => {
344
- panel.setPlacement(defined({ width, heading, pitch, height }));
345
- }, [panel, width, heading, pitch, height]);
346
- // Its content may change its CSS size
347
- useLayoutEffect(() => {
348
- panel.resize();
349
- });
350
- return createPortal(props.children, element);
351
- }
352
- // ── Effects ──
353
- /** An observer's viewshed; several `<Viewshed>` are drawn together */
354
- export function Viewshed(props) {
355
- const binding = useContext(MapContext);
356
- const key = useMemo(() => ({}), []);
357
- useEffect(() => {
358
- if (!binding)
359
- return;
360
- return () => {
361
- binding.viewsheds.delete(key);
362
- binding.applyViewsheds();
363
- };
364
- }, [binding, key]);
365
- // Numbers, strings and the position: compared by value
366
- const options = JSON.stringify(props);
367
- useEffect(() => {
368
- if (!binding)
369
- return;
370
- binding.viewsheds.set(key, JSON.parse(options));
371
- binding.applyViewsheds();
372
- }, [binding, key, options]);
373
- return null;
374
- }
375
- /** The `<Layer>` in it shown on one side of a vertical line only, at `position` CSS pixels from the left */
376
- export function Swipe(props) {
377
- const map = useMap();
378
- const layers = useMemo(() => new Set(), []);
379
- const latest = useRef(props);
380
- latest.current = props;
381
- const group = useMemo(() => {
382
- if (!map)
383
- return undefined;
384
- const apply = () => {
385
- const { position, side } = latest.current;
386
- map.setSwipe(layers.size > 0 ? { position, layers: [...layers], ...defined({ side }) } : undefined);
387
- };
388
- return {
389
- set: (layer) => {
390
- layers.add(layer);
391
- apply();
392
- },
393
- unset: (layer) => {
394
- layers.delete(layer);
395
- apply();
396
- },
397
- };
398
- }, [map, layers]);
399
- const { position, side } = props;
400
- useEffect(() => {
401
- if (map && layers.size > 0)
402
- map.setSwipe({ position, layers: [...layers], ...defined({ side }) });
403
- }, [map, layers, position, side]);
404
- useEffect(() => () => {
405
- map?.setSwipe(undefined);
406
- }, [map]);
407
- return createElement(SwipeContext.Provider, { value: group }, props.children);
408
- }
12
+ export { Control } from "./Control.js";
13
+ export { CustomLayer } from "./CustomLayer.js";
14
+ export { useMap, useMapEvent } from "./context.js";
15
+ export { IsardMap } from "./IsardMap.js";
16
+ export { Layer } from "./Layer.js";
17
+ export { Marker } from "./Marker.js";
18
+ export { Panel } from "./Panel.js";
19
+ export { Popup } from "./Popup.js";
20
+ export { Swipe, SwipeOther } from "./Swipe.js";
21
+ export { VectorGeometry } from "./VectorGeometry.js";
22
+ export { Viewshed } from "./Viewshed.js";
409
23
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/react/index.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Isard in React: the map, its layers, markers, popups, panels and effects as components, created when they mount,\n * updated by the least their props need and removed when they unmount.\n *\n * ```tsx\n * <IsardMap preset=\"ign-3d\" center={[2.35, 48.85]} zoom={15} style={{ height: 400 }}>\n * <Layer type=\"lines\" data={routes} color=\"#0057b8\" width={3} />\n * <Marker lonLat={[2.35, 48.85]}><Popup>Here</Popup></Marker>\n * </IsardMap>\n * ```\n */\n\nimport {\n type CSSProperties,\n createContext,\n createElement,\n forwardRef,\n type ReactNode,\n useContext,\n useEffect,\n useImperativeHandle,\n useLayoutEffect,\n useMemo,\n useRef,\n useState,\n} from 'react';\nimport { createPortal } from 'react-dom';\nimport { applyLayerChange, LayerOrder, layerChange } from '../bind/layers.ts';\nimport type { Layer as LayerHandle } from '../layers/layers.ts';\nimport { GeoMap, type LayerSpec } from '../map.ts';\nimport type { GeoMapOptions, LonLat, MapEvents, Point, SwipeOptions, ViewshedOptions } from '../types.ts';\nimport {\n type Anchor,\n Marker as MarkerHandle,\n Panel as PanelHandle,\n type PanelOptions,\n Popup as PopupHandle,\n type PopupOptions,\n} from '../ui/overlay.ts';\nimport type { Camera } from '../wasm/isard.js';\n\n// ── The map ──\n\ninterface Binding {\n map: GeoMap;\n order: LayerOrder;\n /** The observers of the `<Viewshed>` components, set on the map together */\n viewsheds: Map<object, ViewshedOptions>;\n applyViewsheds(): void;\n}\n\nconst MapContext = createContext<Binding | undefined>(undefined);\n\n/** The map of the `<IsardMap>` around, once created (undefined before) */\nexport function useMap(): GeoMap | undefined {\n return useContext(MapContext)?.map;\n}\n\n/** Listens to an event of the map around while the component is mounted; the listener may change at each render */\nexport function useMapEvent<K extends keyof MapEvents>(type: K, listener: (event: MapEvents[K]) => void): void {\n const map = useMap();\n const latest = useRef(listener);\n latest.current = listener;\n useEffect(() => map?.on(type, (event) => latest.current(event)), [map, type]);\n}\n\n/** The props of the map's events: `onClick` for 'click', `onMoveEnd` for 'moveend'… */\nexport interface MapEventProps {\n onMoveStart?: (camera: Camera) => void;\n onMove?: (camera: Camera) => void;\n onMoveEnd?: (camera: Camera) => void;\n onResize?: (event: MapEvents['resize']) => void;\n onHover?: (event: MapEvents['hover']) => void;\n onHoverFeature?: (event: MapEvents['hoverfeature']) => void;\n onClick?: (event: MapEvents['click']) => void;\n onRender?: (event: MapEvents['render']) => void;\n onIdle?: () => void;\n onLeave?: () => void;\n}\n\nconst EVENT_PROPS = {\n onMoveStart: 'movestart',\n onMove: 'move',\n onMoveEnd: 'moveend',\n onResize: 'resize',\n onHover: 'hover',\n onHoverFeature: 'hoverfeature',\n onClick: 'click',\n onRender: 'render',\n onIdle: 'idle',\n onLeave: 'leave',\n} as const satisfies Record<keyof MapEventProps, keyof MapEvents>;\n\nexport interface IsardMapProps extends Omit<GeoMapOptions, keyof Camera>, MapEventProps {\n /** The camera at creation, then left to the user's gestures */\n center?: LonLat;\n zoom?: number;\n pitch?: number;\n bearing?: number;\n /** A camera the map follows: set again whenever it changes (with `onMove` to keep it in a state) */\n camera?: Partial<Camera>;\n /** The map, once created */\n onLoad?: (map: GeoMap) => void;\n /** The map's creation failed (no WebGL2, the engine not found) */\n onError?: (error: unknown) => void;\n id?: string;\n className?: string;\n style?: CSSProperties;\n /** Layers, markers, popups, panels, effects; drawn once the map is created */\n children?: ReactNode;\n}\n\n/** Options the map takes again after its creation, and how */\nconst LIVE_OPTIONS: { [K in keyof GeoMapOptions]?: (map: GeoMap, props: IsardMapProps) => void } = {\n basemap: (map, p) => {\n if (p.basemap) map.setBasemap(p.basemap, p.hillshade);\n },\n hillshade: (map, p) => {\n if (p.basemap) map.setBasemap(p.basemap, p.hillshade);\n },\n terrain: (map, p) => map.setTerrain(p.terrain ?? false),\n minZoom: (map, p) => map.setMinZoom(p.minZoom ?? 0),\n maxZoom: (map, p) => map.setMaxZoom(p.maxZoom ?? 22),\n maxPitch: (map, p) => map.setMaxPitch(p.maxPitch ?? 70),\n atmosphere: (map, p) => map.setAtmosphere(p.atmosphere),\n projection: (map, p) => map.setProjection(p.projection ?? 'globe'),\n loading: (map, p) => map.setLoading(p.loading ?? 'immediate'),\n sky: (map, p) => map.setSky(p.sky ?? true),\n background: (map, p) => {\n if (p.background) map.setBackground(p.background);\n },\n};\n\nfunction sameCamera(a: Camera, b: Partial<Camera>): boolean {\n return (\n (b.center === undefined || (a.center[0] === b.center[0] && a.center[1] === b.center[1])) &&\n (b.zoom === undefined || a.zoom === b.zoom) &&\n (b.pitch === undefined || a.pitch === b.pitch) &&\n (b.bearing === undefined || a.bearing === b.bearing)\n );\n}\n\n/**\n * A map filling its element (give it a height). Created once mounted, destroyed when unmounted; the options read at\n * creation only (`body`, `preset`, `interactive`, the URLs) need a new `key` to take another value\n */\nexport const IsardMap = forwardRef<GeoMap | undefined, IsardMapProps>(function IsardMap(props, ref) {\n const element = useRef<HTMLDivElement>(null);\n const [binding, setBinding] = useState<Binding>();\n const latest = useRef(props);\n latest.current = props;\n useImperativeHandle(ref, () => binding?.map, [binding]);\n\n useEffect(() => {\n const container = element.current;\n if (!container) return;\n let cancelled = false;\n let created: GeoMap | undefined;\n const { camera, center, zoom, pitch, bearing, children: _, ...options } = latest.current;\n GeoMap.create(container, {\n ...stripProps(options),\n ...defined({ center, zoom, pitch, bearing }),\n ...camera,\n }).then(\n (map) => {\n // Unmounted while the engine was loading (or StrictMode's second mount): that map is not wanted\n if (cancelled) {\n map.destroy();\n return;\n }\n created = map;\n const viewsheds = new Map<object, ViewshedOptions>();\n setBinding({\n map,\n order: new LayerOrder(),\n viewsheds,\n applyViewsheds: () => map.setViewshed(viewsheds.size > 0 ? [...viewsheds.values()] : undefined),\n });\n latest.current.onLoad?.(map);\n },\n (error: unknown) => {\n if (cancelled) return;\n if (latest.current.onError) latest.current.onError(error);\n else console.error(error);\n },\n );\n return () => {\n cancelled = true;\n created?.destroy();\n setBinding(undefined);\n };\n }, []);\n\n // The events, each listened to once: the props may give another function at each render\n const map = binding?.map;\n useEffect(() => {\n if (!map) return;\n const offs = Object.entries(EVENT_PROPS).map(([prop, type]) =>\n map.on(type, (event) =>\n (latest.current[prop as keyof MapEventProps] as ((e: unknown) => void) | undefined)?.(event),\n ),\n );\n return () => {\n for (const off of offs) off();\n };\n }, [map]);\n\n // The options taken again, compared with what the map was given last\n const applied = useRef<IsardMapProps>(props);\n useEffect(() => {\n if (!map) return;\n const last = applied.current;\n applied.current = props;\n const done = new Set<(map: GeoMap, props: IsardMapProps) => void>();\n for (const [key, apply] of Object.entries(LIVE_OPTIONS)) {\n if (!apply || done.has(apply) || Object.is(last[key as keyof IsardMapProps], props[key as keyof IsardMapProps])) {\n continue;\n }\n done.add(apply);\n apply(map, props);\n }\n });\n\n const { camera } = props;\n useEffect(() => {\n if (map && camera && !sameCamera(map.getCamera(), camera)) map.setCamera(camera);\n }, [map, camera]);\n\n return createElement(\n 'div',\n { ref: element, id: props.id, className: props.className, style: props.style },\n binding ? createElement(MapContext.Provider, { value: binding }, props.children) : null,\n );\n});\n\n/** The props that are not options of the map */\nfunction stripProps(props: Partial<IsardMapProps>): GeoMapOptions {\n const options: Record<string, unknown> = { ...props };\n for (const key of [...Object.keys(EVENT_PROPS), 'onLoad', 'onError', 'id', 'className', 'style']) delete options[key];\n return options as GeoMapOptions;\n}\n\n/** The entries of an object whose value is defined (`exactOptionalPropertyTypes`) */\nfunction defined<T extends object>(object: T): { [K in keyof T]?: Exclude<T[K], undefined> } {\n return Object.fromEntries(Object.entries(object).filter(([, value]) => value !== undefined)) as {\n [K in keyof T]?: Exclude<T[K], undefined>;\n };\n}\n\n// ── Layers ──\n\nconst SwipeContext = createContext<SwipeGroup | undefined>(undefined);\n\nexport type LayerProps<P = Record<string, unknown>> = LayerSpec<P> & {\n /** Its place among the layers of the components: from the bottom up, the same order by mounting (default 0) */\n order?: number;\n /** The layer, once created and each time it is made anew */\n onLayer?: (layer: LayerHandle) => void;\n};\n\n/**\n * A layer: the options of its `add…` method with its `type` (`map.add`). A change of data, style or instances updates\n * it; a change of what is set at creation (its URL, grid, nodes…) makes it anew, in its place. Data, functions and\n * arrays are compared by identity: keep them in a memo or a state. The ref gives the layer's handle\n */\nexport const Layer = forwardRef<LayerHandle | undefined, LayerProps>(function Layer(props, ref) {\n const binding = useContext(MapContext);\n const swipe = useContext(SwipeContext);\n const { order = 0, onLayer, ...spec } = props;\n const state = useRef<{ layer: LayerHandle; spec: LayerSpec; order: number }>(undefined);\n const [layer, setLayer] = useState<LayerHandle>();\n useImperativeHandle(ref, () => layer, [layer]);\n const latest = useRef({ spec, order, onLayer });\n latest.current = { spec, order, onLayer };\n\n useEffect(() => {\n if (!binding) return;\n const { spec, order, onLayer } = latest.current;\n const created = binding.map.add(spec as LayerSpec);\n binding.order.place(created, order);\n state.current = { layer: created, spec, order };\n swipe?.set(created);\n setLayer(created);\n onLayer?.(created);\n return () => {\n const current = state.current;\n state.current = undefined;\n if (!current) return;\n binding.order.remove(current.layer);\n swipe?.unset(current.layer);\n if (binding.map.hasLayer(current.layer)) current.layer.remove();\n };\n }, [binding, swipe]);\n\n useEffect(() => {\n const current = state.current;\n if (!binding || !current) return;\n const next = spec as LayerSpec;\n const change = layerChange(current.spec, next);\n current.spec = next;\n if (change?.rebuild) {\n const old = current.layer;\n const fresh = binding.map.rebuildLayer(old, next);\n binding.order.place(fresh, order, old);\n swipe?.unset(old);\n swipe?.set(fresh);\n current.layer = fresh;\n current.order = order;\n setLayer(fresh);\n latest.current.onLayer?.(fresh);\n return;\n }\n if (change) applyLayerChange(current.layer, next, change);\n if (current.order !== order) {\n current.order = order;\n binding.order.place(current.layer, order, current.layer);\n }\n });\n\n return null;\n});\n\n// ── Markers, popups, panels ──\n\n/** The marker of a `<Marker>` around (a `<Popup>` in it opens on its click) */\nconst MarkerContext = createContext<MarkerHandle | undefined>(undefined);\n\nexport interface MarkerProps {\n lonLat: LonLat;\n /** Metres above the ground, its stem down to `base` (what it stands on: a roof, a mesh) */\n height?: number;\n base?: number;\n draggable?: boolean;\n offset?: Point;\n /** Which part of the element sits on the position (default 'bottom' for the pin, 'center' with an icon) */\n anchor?: Anchor;\n className?: string;\n /** The marker's look, in place of the default pin; the element changes with it */\n icon?: ReactNode;\n onDragStart?: (lonLat: LonLat) => void;\n onDrag?: (lonLat: LonLat) => void;\n onDragEnd?: (lonLat: LonLat) => void;\n /** A `<Popup>` opened by a click on the marker */\n children?: ReactNode;\n}\n\n/** A marker at a position, its look the default pin or the `icon` given */\nexport function Marker(props: MarkerProps): ReactNode {\n const map = useMap();\n const custom = props.icon !== undefined;\n const { anchor, className } = props;\n const element = useMemo(() => (custom ? document.createElement('div') : undefined), [custom]);\n const marker = useMemo(\n () => new MarkerHandle({ ...defined({ anchor, className, element }) }),\n [anchor, className, element],\n );\n const latest = useRef(props);\n latest.current = props;\n\n useEffect(() => {\n if (!map) return;\n marker.addTo(map);\n const offs = [\n marker.on('dragstart', (e) => latest.current.onDragStart?.(e.lonLat)),\n marker.on('drag', (e) => latest.current.onDrag?.(e.lonLat)),\n marker.on('dragend', (e) => latest.current.onDragEnd?.(e.lonLat)),\n ];\n return () => {\n for (const off of offs) off();\n marker.remove();\n };\n }, [map, marker]);\n\n const { lonLat, height = 0, base = 0, draggable = false, offset } = props;\n useLayoutEffect(() => {\n marker.setLonLat(lonLat);\n }, [marker, lonLat[0], lonLat[1]]);\n useLayoutEffect(() => {\n marker.setHeight(height, base);\n }, [marker, height, base]);\n useLayoutEffect(() => {\n marker.setDraggable(draggable);\n }, [marker, draggable]);\n useLayoutEffect(() => {\n if (offset) marker.setOffset(offset);\n }, [marker, offset?.[0], offset?.[1]]);\n\n return createElement(\n MarkerContext.Provider,\n { value: marker },\n element ? createPortal(props.icon, element) : null,\n props.children,\n );\n}\n\nexport interface PopupProps extends PopupOptions {\n /** Its position; in a `<Marker>`, the marker's */\n lonLat?: LonLat;\n /** Metres above the ground (in a `<Marker>`, the marker's) */\n height?: number;\n /** Open or closed, when the application decides; else open when mounted alone, on the marker's click in a marker */\n open?: boolean;\n onOpen?: () => void;\n /** Closed by its button, a click on the map, or the marker's click */\n onClose?: () => void;\n children?: ReactNode;\n}\n\n/** A popup of JSX content, at a position or on a `<Marker>` */\nexport function Popup(props: PopupProps): ReactNode {\n const map = useMap();\n const marker = useContext(MarkerContext);\n const { anchor, closeButton, closeOnClick, maxWidth, className } = props;\n const content = useMemo(() => document.createElement('div'), []);\n const popup = useMemo(\n () => new PopupHandle(defined({ anchor, closeButton, closeOnClick, maxWidth, className })).setDOMContent(content),\n [anchor, closeButton, closeOnClick, maxWidth, className, content],\n );\n const latest = useRef(props);\n latest.current = props;\n\n useEffect(() => {\n if (!map) return;\n const offs = [\n popup.on('open', () => latest.current.onOpen?.()),\n popup.on('close', () => latest.current.onClose?.()),\n ];\n if (marker) marker.setPopup(popup);\n return () => {\n for (const off of offs) off();\n if (marker?.getPopup() === popup) marker.setPopup(undefined);\n popup.remove();\n };\n }, [map, marker, popup]);\n\n const { lonLat, height, open, offset } = props;\n const opened = open ?? !marker;\n useLayoutEffect(() => {\n if (offset) popup.setOffset(offset);\n }, [popup, offset?.[0], offset?.[1]]);\n useLayoutEffect(() => {\n if (!map) return;\n if (lonLat) popup.setLonLat(lonLat);\n else if (marker) popup.setLonLat(marker.getLonLat());\n if (height !== undefined) popup.setHeight(height);\n if (open === undefined && marker) return;\n if (opened && !popup.isOpen()) popup.addTo(map);\n if (!opened && popup.isOpen()) popup.remove();\n }, [map, marker, popup, lonLat?.[0], lonLat?.[1], height, open, opened]);\n\n return createPortal(props.children, content);\n}\n\nexport interface PanelProps extends Omit<PanelOptions, 'element'> {\n lonLat: LonLat;\n /** What stands in 3D: a video, an iframe, a sign */\n children?: ReactNode;\n}\n\n/** JSX standing in 3D at a position, `width` metres wide, facing `heading` */\nexport function Panel(props: PanelProps): ReactNode {\n const map = useMap();\n const { className } = props;\n const element = useMemo(() => document.createElement('div'), []);\n // The width at creation: the placement is set again by the effect below\n const initialWidth = useRef(props.width);\n const panel = useMemo(\n () => new PanelHandle({ element, width: initialWidth.current, ...defined({ className }) }),\n [element, className],\n );\n\n useEffect(() => {\n if (!map) return;\n panel.addTo(map);\n return () => {\n panel.remove();\n };\n }, [map, panel]);\n\n const { lonLat, width, heading, pitch, height } = props;\n useLayoutEffect(() => {\n panel.setLonLat(lonLat);\n }, [panel, lonLat[0], lonLat[1]]);\n useLayoutEffect(() => {\n panel.setPlacement(defined({ width, heading, pitch, height }));\n }, [panel, width, heading, pitch, height]);\n // Its content may change its CSS size\n useLayoutEffect(() => {\n panel.resize();\n });\n\n return createPortal(props.children, element);\n}\n\n// ── Effects ──\n\n/** An observer's viewshed; several `<Viewshed>` are drawn together */\nexport function Viewshed(props: ViewshedOptions): ReactNode {\n const binding = useContext(MapContext);\n const key = useMemo(() => ({}), []);\n useEffect(() => {\n if (!binding) return;\n return () => {\n binding.viewsheds.delete(key);\n binding.applyViewsheds();\n };\n }, [binding, key]);\n // Numbers, strings and the position: compared by value\n const options = JSON.stringify(props);\n useEffect(() => {\n if (!binding) return;\n binding.viewsheds.set(key, JSON.parse(options) as ViewshedOptions);\n binding.applyViewsheds();\n }, [binding, key, options]);\n return null;\n}\n\ninterface SwipeGroup {\n set(layer: LayerHandle): void;\n unset(layer: LayerHandle): void;\n}\n\nexport interface SwipeProps extends Omit<SwipeOptions, 'layers'> {\n /** The `<Layer>` shown on one side of the line only */\n children?: ReactNode;\n}\n\n/** The `<Layer>` in it shown on one side of a vertical line only, at `position` CSS pixels from the left */\nexport function Swipe(props: SwipeProps): ReactNode {\n const map = useMap();\n const layers = useMemo(() => new Set<LayerHandle>(), []);\n const latest = useRef(props);\n latest.current = props;\n const group = useMemo<SwipeGroup | undefined>(() => {\n if (!map) return undefined;\n const apply = () => {\n const { position, side } = latest.current;\n map.setSwipe(layers.size > 0 ? { position, layers: [...layers], ...defined({ side }) } : undefined);\n };\n return {\n set: (layer) => {\n layers.add(layer);\n apply();\n },\n unset: (layer) => {\n layers.delete(layer);\n apply();\n },\n };\n }, [map, layers]);\n\n const { position, side } = props;\n useEffect(() => {\n if (map && layers.size > 0) map.setSwipe({ position, layers: [...layers], ...defined({ side }) });\n }, [map, layers, position, side]);\n useEffect(\n () => () => {\n map?.setSwipe(undefined);\n },\n [map],\n );\n\n return createElement(SwipeContext.Provider, { value: group }, props.children);\n}\n\nexport type { Camera, GeoMap, LayerHandle, LayerSpec, LonLat, MarkerHandle, PanelHandle, PopupHandle };\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/react/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAOH,OAAO,EAAE,OAAO,EAAqB,MAAM,cAAe,CAAC;AAC3D,OAAO,EAAE,WAAW,EAAyB,MAAM,kBAAmB,CAAC;AACvE,OAAO,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AACnD,OAAO,EAAE,QAAQ,EAA0C,MAAM,eAAgB,CAAC;AAClF,OAAO,EAAE,KAAK,EAAsD,MAAM,YAAa,CAAC;AACxF,OAAO,EAAE,MAAM,EAAoB,MAAM,aAAc,CAAC;AACxD,OAAO,EAAE,KAAK,EAAmB,MAAM,YAAa,CAAC;AACrD,OAAO,EAAE,KAAK,EAAmB,MAAM,YAAa,CAAC;AACrD,OAAO,EAAE,KAAK,EAAE,UAAU,EAAmB,MAAM,YAAa,CAAC;AACjE,OAAO,EAAE,cAAc,EAA4B,MAAM,qBAAsB,CAAC;AAChF,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAgB,CAAC","sourcesContent":["/**\n * Isard in React: the map, its layers, markers, popups, panels and effects as components, created when they mount,\n * updated by the least their props need and removed when they unmount.\n *\n * ```tsx\n * <IsardMap preset=\"ign-3d\" center={[2.35, 48.85]} zoom={15} style={{ height: 400 }}>\n * <Layer type=\"lines\" data={routes} color=\"#0057b8\" width={3} />\n * <Marker lonLat={[2.35, 48.85]}><Popup>Here</Popup></Marker>\n * </IsardMap>\n * ```\n */\n\nexport type { Layer as LayerHandle } from '../layers/layers.ts';\nexport type { GeoMap, LayerSpec } from '../map.ts';\nexport type { LonLat } from '../types.ts';\nexport type { Marker as MarkerHandle, Panel as PanelHandle, Popup as PopupHandle } from '../ui/overlay.ts';\nexport type { Camera } from '../wasm/isard.js';\nexport { Control, type ControlProps } from './Control.tsx';\nexport { CustomLayer, type CustomLayerProps } from './CustomLayer.tsx';\nexport { useMap, useMapEvent } from './context.ts';\nexport { IsardMap, type IsardMapProps, type MapEventProps } from './IsardMap.tsx';\nexport { Layer, type LayerHandles, type LayerProps, type LayerType } from './Layer.tsx';\nexport { Marker, type MarkerProps } from './Marker.tsx';\nexport { Panel, type PanelProps } from './Panel.tsx';\nexport { Popup, type PopupProps } from './Popup.tsx';\nexport { Swipe, SwipeOther, type SwipeProps } from './Swipe.tsx';\nexport { VectorGeometry, type VectorGeometryProps } from './VectorGeometry.tsx';\nexport { Viewshed } from './Viewshed.tsx';\n"]}
@@ -25,15 +25,11 @@ export interface Settings {
25
25
  globeColor: [r: number, g: number, b: number];
26
26
  }
27
27
  /** A body from the option, its defaults filled in */
28
- export declare function bodySettings(body: CelestialBody | undefined): Required<BodyOptions>;
28
+ export declare const bodySettings: (body: CelestialBody | undefined) => Required<BodyOptions>;
29
29
  /** The halo of an atmosphere for the engine (RGB 0-1 and its strength, the color's alpha): undefined for none */
30
- export declare function haloSettings(atmosphere: boolean | string): Float32Array | undefined;
31
- /** Relief settings from the option: undefined when off. On the Earth the Terrain Tiles by default (worldwide,
32
- * Terrarium PNGs decoded by `terrainLoader`) or the IGN terrain model (France, raised by the geoid); NASA's on the Moon
33
- * and Mars; an ArcGIS image service asked for in the body's Mercator. `terrainLoader`: the loader of PNG tiles in an
34
- * encoding, the same for the same tiles (the engine keeps its tiles when only the exaggeration changes) */
35
- export declare function terrainSettings(terrain: boolean | TerrainModel | TerrainOptions | undefined, body: CelestialBody | undefined, radius: number, terrainLoader: (url: string, encoding: PngEncoding, floor?: number) => TerrainLoader): Settings['terrain'];
30
+ export declare const haloSettings: (atmosphere: boolean | string) => Float32Array | undefined;
31
+ export declare const terrainSettings: (terrain: boolean | TerrainModel | TerrainOptions | undefined, body: CelestialBody | undefined, radius: number, terrainLoader: (url: string, encoding: PngEncoding, floor?: number) => TerrainLoader) => Settings["terrain"];
36
32
  /** Sky settings for the engine: colors (RGB 0-1) and blends, MapLibre's defaults */
37
- export declare function atmosphereSettings(options: AtmosphereOptions | undefined): Float32Array | undefined;
33
+ export declare const atmosphereSettings: (options: AtmosphereOptions | undefined) => Float32Array | undefined;
38
34
  /** A CSS color to RGB 0-1 (its alpha dropped); black if unknown */
39
- export declare function rgb(color: string): [r: number, g: number, b: number];
35
+ export declare const rgb: (color: string) => [r: number, g: number, b: number];
package/dist/settings.js CHANGED
@@ -21,31 +21,33 @@ const BODIES = {
21
21
  /** The Earth's halo, RGB 0-1 and its strength: what `atmosphere: true` draws */
22
22
  const EARTH_HALO = Float32Array.of(0.42, 0.66, 1, 1);
23
23
  /** A body from the option, its defaults filled in */
24
- export function bodySettings(body) {
24
+ export const bodySettings = (body) => {
25
25
  if (body === undefined || typeof body === 'string')
26
26
  return BODIES[body ?? 'earth'];
27
27
  const relief = [-0.01 * body.radius, 0.01 * body.radius];
28
28
  return { flattening: 0, atmosphere: false, color: '#808080', relief, ...body };
29
- }
29
+ };
30
30
  /** The halo of an atmosphere for the engine (RGB 0-1 and its strength, the color's alpha): undefined for none */
31
- export function haloSettings(atmosphere) {
31
+ export const haloSettings = (atmosphere) => {
32
32
  if (atmosphere === true)
33
33
  return EARTH_HALO;
34
34
  const color = atmosphere === false ? undefined : parseCssColor(atmosphere);
35
35
  return color && Float32Array.from(color);
36
- }
36
+ };
37
37
  /** Relief settings from the option: undefined when off. On the Earth the Terrain Tiles by default (worldwide,
38
38
  * Terrarium PNGs decoded by `terrainLoader`) or the IGN terrain model (France, raised by the geoid); NASA's on the Moon
39
39
  * and Mars; an ArcGIS image service asked for in the body's Mercator. `terrainLoader`: the loader of PNG tiles in an
40
40
  * encoding, the same for the same tiles (the engine keeps its tiles when only the exaggeration changes) */
41
- export function terrainSettings(terrain, body, radius, terrainLoader) {
41
+ /** The relief options of the option on */
42
+ const terrainOptions = (terrain) => {
43
+ if (typeof terrain === 'string')
44
+ return { model: terrain };
45
+ return terrain === true ? {} : terrain;
46
+ };
47
+ export const terrainSettings = (terrain, body, radius, terrainLoader) => {
42
48
  if (!terrain)
43
49
  return undefined;
44
- let options = {};
45
- if (typeof terrain === 'string')
46
- options = { model: terrain };
47
- else if (terrain !== true)
48
- options = terrain;
50
+ const options = terrainOptions(terrain);
49
51
  const earth = (body ?? 'earth') === 'earth';
50
52
  const exaggeration = options.exaggeration ?? 1;
51
53
  if (options.url === undefined && earth) {
@@ -82,9 +84,9 @@ export function terrainSettings(terrain, body, radius, terrainLoader) {
82
84
  // NASA's credits for its models
83
85
  ...(options.url === undefined && preset ? { attribution: preset.attribution } : {}),
84
86
  };
85
- }
87
+ };
86
88
  /** Sky settings for the engine: colors (RGB 0-1) and blends, MapLibre's defaults */
87
- export function atmosphereSettings(options) {
89
+ export const atmosphereSettings = (options) => {
88
90
  if (!options)
89
91
  return undefined;
90
92
  return Float32Array.from([
@@ -95,10 +97,10 @@ export function atmosphereSettings(options) {
95
97
  options.horizonFogBlend ?? 0.7,
96
98
  options.fogGroundBlend ?? 0.4,
97
99
  ]);
98
- }
100
+ };
99
101
  /** A CSS color to RGB 0-1 (its alpha dropped); black if unknown */
100
- export function rgb(color) {
102
+ export const rgb = (color) => {
101
103
  const [r, g, b] = parseCssColor(color) ?? [0, 0, 0, 1];
102
104
  return [r, g, b];
103
- }
105
+ };
104
106
  //# sourceMappingURL=settings.js.map