isard 1.0.0 → 1.2.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 (268) hide show
  1. package/CHANGELOG.md +51 -0
  2. package/dist/{basemaps.d.ts → basemap/basemaps.d.ts} +3 -3
  3. package/dist/{basemaps.js → basemap/basemaps.js} +3 -3
  4. package/dist/basemap/basemaps.js.map +1 -0
  5. package/dist/{grid.d.ts → basemap/grid.d.ts} +6 -6
  6. package/dist/{grid.js → basemap/grid.js} +61 -67
  7. package/dist/basemap/grid.js.map +1 -0
  8. package/dist/{mvt.d.ts → basemap/mvt.d.ts} +1 -1
  9. package/dist/{mvt.js → basemap/mvt.js} +6 -6
  10. package/dist/basemap/mvt.js.map +1 -0
  11. package/dist/{pmtiles.d.ts → basemap/pmtiles.d.ts} +16 -10
  12. package/dist/{pmtiles.js → basemap/pmtiles.js} +41 -33
  13. package/dist/basemap/pmtiles.js.map +1 -0
  14. package/dist/{resample.d.ts → basemap/resample.d.ts} +11 -2
  15. package/dist/{resample.js → basemap/resample.js} +18 -16
  16. package/dist/basemap/resample.js.map +1 -0
  17. package/dist/{terrain.d.ts → basemap/terrain.d.ts} +3 -3
  18. package/dist/{terrain.js → basemap/terrain.js} +7 -7
  19. package/dist/basemap/terrain.js.map +1 -0
  20. package/dist/{vectorstyle.d.ts → basemap/vectorstyle.d.ts} +12 -10
  21. package/dist/{vectorstyle.js → basemap/vectorstyle.js} +129 -111
  22. package/dist/basemap/vectorstyle.js.map +1 -0
  23. package/dist/{vectortiles.d.ts → basemap/vectortiles.d.ts} +18 -18
  24. package/dist/{vectortiles.js → basemap/vectortiles.js} +157 -109
  25. package/dist/basemap/vectortiles.js.map +1 -0
  26. package/dist/{wmts.d.ts → basemap/wmts.d.ts} +3 -3
  27. package/dist/{wmts.js → basemap/wmts.js} +19 -14
  28. package/dist/basemap/wmts.js.map +1 -0
  29. package/dist/basemap.worker.js +2 -2
  30. package/dist/basemap.worker.js.map +14 -13
  31. package/dist/bind/layers.d.ts +46 -0
  32. package/dist/bind/layers.js +154 -0
  33. package/dist/bind/layers.js.map +1 -0
  34. package/dist/{crs.d.ts → data/crs.d.ts} +11 -11
  35. package/dist/{crs.js → data/crs.js} +38 -34
  36. package/dist/data/crs.js.map +1 -0
  37. package/dist/{gpx.d.ts → data/gpx.d.ts} +2 -2
  38. package/dist/{gpx.js → data/gpx.js} +20 -20
  39. package/dist/data/gpx.js.map +1 -0
  40. package/dist/{kml.d.ts → data/kml.d.ts} +2 -2
  41. package/dist/{kml.js → data/kml.js} +42 -39
  42. package/dist/data/kml.js.map +1 -0
  43. package/dist/{topojson.d.ts → data/topojson.d.ts} +2 -2
  44. package/dist/{topojson.js → data/topojson.js} +15 -10
  45. package/dist/data/topojson.js.map +1 -0
  46. package/dist/{xml.d.ts → data/xml.d.ts} +5 -5
  47. package/dist/{xml.js → data/xml.js} +19 -18
  48. package/dist/data/xml.js.map +1 -0
  49. package/dist/decoder.worker.js +4 -4
  50. package/dist/decoder.worker.js.map +7 -7
  51. package/dist/{decoders.d.ts → engine/decoders.d.ts} +3 -3
  52. package/dist/{decoders.js → engine/decoders.js} +28 -25
  53. package/dist/engine/decoders.js.map +1 -0
  54. package/dist/{loader.d.ts → engine/loader.d.ts} +1 -1
  55. package/dist/{loader.js → engine/loader.js} +17 -14
  56. package/dist/engine/loader.js.map +1 -0
  57. package/dist/{protocol.d.ts → engine/protocol.d.ts} +1 -1
  58. package/dist/engine/protocol.js +3 -0
  59. package/dist/engine/protocol.js.map +1 -0
  60. package/dist/{requests.d.ts → engine/requests.d.ts} +1 -1
  61. package/dist/{requests.js → engine/requests.js} +19 -16
  62. package/dist/engine/requests.js.map +1 -0
  63. package/dist/engine-loader.d.ts +13 -9
  64. package/dist/engine-loader.js +30 -30
  65. package/dist/engine-loader.js.map +1 -1
  66. package/dist/formats.d.ts +3 -3
  67. package/dist/formats.js +3 -3
  68. package/dist/formats.js.map +1 -1
  69. package/dist/geoplateforme.d.ts +13 -13
  70. package/dist/geoplateforme.js +23 -21
  71. package/dist/geoplateforme.js.map +1 -1
  72. package/dist/index.d.ts +30 -29
  73. package/dist/index.js +18 -18
  74. package/dist/index.js.map +1 -1
  75. package/dist/isard_bg.wasm +0 -0
  76. package/dist/isard_core_bg.wasm +0 -0
  77. package/dist/isard_points_bg.wasm +0 -0
  78. package/dist/{extrusions.d.ts → layers/extrusions.d.ts} +1 -1
  79. package/dist/{extrusions.js → layers/extrusions.js} +10 -5
  80. package/dist/layers/extrusions.js.map +1 -0
  81. package/dist/{features.d.ts → layers/features.d.ts} +10 -10
  82. package/dist/{features.js → layers/features.js} +44 -45
  83. package/dist/layers/features.js.map +1 -0
  84. package/dist/{glyphs.d.ts → layers/glyphs.d.ts} +6 -6
  85. package/dist/{glyphs.js → layers/glyphs.js} +45 -41
  86. package/dist/layers/glyphs.js.map +1 -0
  87. package/dist/{icons.d.ts → layers/icons.d.ts} +10 -10
  88. package/dist/{icons.js → layers/icons.js} +84 -69
  89. package/dist/layers/icons.js.map +1 -0
  90. package/dist/{layers.d.ts → layers/layers.d.ts} +9 -4
  91. package/dist/{layers.js → layers/layers.js} +35 -31
  92. package/dist/layers/layers.js.map +1 -0
  93. package/dist/{panoramas.d.ts → layers/panoramas.d.ts} +3 -3
  94. package/dist/{panoramas.js → layers/panoramas.js} +54 -43
  95. package/dist/layers/panoramas.js.map +1 -0
  96. package/dist/{pointclouds.d.ts → layers/pointclouds.d.ts} +5 -5
  97. package/dist/{pointclouds.js → layers/pointclouds.js} +26 -34
  98. package/dist/layers/pointclouds.js.map +1 -0
  99. package/dist/{symbols.d.ts → layers/symbols.d.ts} +3 -3
  100. package/dist/{symbols.js → layers/symbols.js} +69 -72
  101. package/dist/layers/symbols.js.map +1 -0
  102. package/dist/map/basemap-layers.d.ts +26 -0
  103. package/dist/map/basemap-layers.js +61 -0
  104. package/dist/map/basemap-layers.js.map +1 -0
  105. package/dist/map/canvas.d.ts +17 -0
  106. package/dist/map/canvas.js +56 -0
  107. package/dist/map/canvas.js.map +1 -0
  108. package/dist/map/checks.d.ts +11 -0
  109. package/dist/map/checks.js +39 -0
  110. package/dist/map/checks.js.map +1 -0
  111. package/dist/map/credits.d.ts +17 -0
  112. package/dist/map/credits.js +34 -0
  113. package/dist/map/credits.js.map +1 -0
  114. package/dist/map/engine-settings.d.ts +15 -0
  115. package/dist/map/engine-settings.js +45 -0
  116. package/dist/map/engine-settings.js.map +1 -0
  117. package/dist/map/engines.d.ts +41 -0
  118. package/dist/map/engines.js +77 -0
  119. package/dist/map/engines.js.map +1 -0
  120. package/dist/map/events.d.ts +14 -0
  121. package/dist/map/events.js +46 -0
  122. package/dist/map/events.js.map +1 -0
  123. package/dist/map/frame-loop.d.ts +61 -0
  124. package/dist/map/frame-loop.js +139 -0
  125. package/dist/map/frame-loop.js.map +1 -0
  126. package/dist/map/hover-pick.d.ts +30 -0
  127. package/dist/map/hover-pick.js +56 -0
  128. package/dist/map/hover-pick.js.map +1 -0
  129. package/dist/map/layer-spec.d.ts +42 -0
  130. package/dist/map/layer-spec.js +34 -0
  131. package/dist/map/layer-spec.js.map +1 -0
  132. package/dist/map/layer-stack.d.ts +36 -0
  133. package/dist/map/layer-stack.js +101 -0
  134. package/dist/map/layer-stack.js.map +1 -0
  135. package/dist/map/overlay-host.d.ts +36 -0
  136. package/dist/map/overlay-host.js +101 -0
  137. package/dist/map/overlay-host.js.map +1 -0
  138. package/dist/map/panorama-host.d.ts +5 -0
  139. package/dist/map/panorama-host.js +32 -0
  140. package/dist/map/panorama-host.js.map +1 -0
  141. package/dist/map/raster-source.d.ts +11 -0
  142. package/dist/map/raster-source.js +26 -0
  143. package/dist/map/raster-source.js.map +1 -0
  144. package/dist/map/symbol-atlases.d.ts +26 -0
  145. package/dist/map/symbol-atlases.js +59 -0
  146. package/dist/map/symbol-atlases.js.map +1 -0
  147. package/dist/map/viewshed.d.ts +5 -0
  148. package/dist/map/viewshed.js +28 -0
  149. package/dist/map/viewshed.js.map +1 -0
  150. package/dist/map/workers.d.ts +46 -0
  151. package/dist/map/workers.js +73 -0
  152. package/dist/map/workers.js.map +1 -0
  153. package/dist/map.d.ts +46 -127
  154. package/dist/map.js +183 -698
  155. package/dist/map.js.map +1 -1
  156. package/dist/projections.d.ts +3 -3
  157. package/dist/projections.js +2 -2
  158. package/dist/projections.js.map +1 -1
  159. package/dist/react/Control.d.ts +11 -0
  160. package/dist/react/Control.js +18 -0
  161. package/dist/react/Control.js.map +1 -0
  162. package/dist/react/CustomLayer.d.ts +11 -0
  163. package/dist/react/CustomLayer.js +30 -0
  164. package/dist/react/CustomLayer.js.map +1 -0
  165. package/dist/react/IsardMap.d.ts +43 -0
  166. package/dist/react/IsardMap.js +146 -0
  167. package/dist/react/IsardMap.js.map +1 -0
  168. package/dist/react/Layer.d.ts +42 -0
  169. package/dist/react/Layer.js +74 -0
  170. package/dist/react/Layer.js.map +1 -0
  171. package/dist/react/Marker.d.ts +24 -0
  172. package/dist/react/Marker.js +53 -0
  173. package/dist/react/Marker.js.map +1 -0
  174. package/dist/react/Panel.d.ts +11 -0
  175. package/dist/react/Panel.js +37 -0
  176. package/dist/react/Panel.js.map +1 -0
  177. package/dist/react/Popup.d.ts +18 -0
  178. package/dist/react/Popup.js +60 -0
  179. package/dist/react/Popup.js.map +1 -0
  180. package/dist/react/Swipe.d.ts +9 -0
  181. package/dist/react/Swipe.js +41 -0
  182. package/dist/react/Swipe.js.map +1 -0
  183. package/dist/react/Viewshed.d.ts +5 -0
  184. package/dist/react/Viewshed.js +28 -0
  185. package/dist/react/Viewshed.js.map +1 -0
  186. package/dist/react/context.d.ts +32 -0
  187. package/dist/react/context.js +20 -0
  188. package/dist/react/context.js.map +1 -0
  189. package/dist/react/index.d.ts +26 -0
  190. package/dist/react/index.js +22 -0
  191. package/dist/react/index.js.map +1 -0
  192. package/dist/settings.d.ts +6 -10
  193. package/dist/settings.js +19 -17
  194. package/dist/settings.js.map +1 -1
  195. package/dist/types.d.ts +8 -8
  196. package/dist/types.js +1 -0
  197. package/dist/types.js.map +1 -1
  198. package/dist/{controls.d.ts → ui/controls.d.ts} +1 -1
  199. package/dist/{controls.js → ui/controls.js} +6 -4
  200. package/dist/ui/controls.js.map +1 -0
  201. package/dist/{interaction.d.ts → ui/interaction.d.ts} +9 -5
  202. package/dist/{interaction.js → ui/interaction.js} +9 -8
  203. package/dist/ui/interaction.js.map +1 -0
  204. package/dist/{overlay.d.ts → ui/overlay.d.ts} +2 -2
  205. package/dist/{overlay.js → ui/overlay.js} +18 -20
  206. package/dist/ui/overlay.js.map +1 -0
  207. package/dist/{style.d.ts → ui/style.d.ts} +1 -1
  208. package/dist/{style.js → ui/style.js} +2 -2
  209. package/dist/ui/style.js.map +1 -0
  210. package/dist/{animation.d.ts → util/animation.d.ts} +9 -5
  211. package/dist/{animation.js → util/animation.js} +6 -6
  212. package/dist/util/animation.js.map +1 -0
  213. package/dist/{color.d.ts → util/color.d.ts} +1 -1
  214. package/dist/{color.js → util/color.js} +14 -16
  215. package/dist/util/color.js.map +1 -0
  216. package/dist/{geo.d.ts → util/geo.d.ts} +6 -6
  217. package/dist/{geo.js → util/geo.js} +12 -12
  218. package/dist/util/geo.js.map +1 -0
  219. package/dist/util/guards.d.ts +7 -0
  220. package/dist/util/guards.js +8 -0
  221. package/dist/util/guards.js.map +1 -0
  222. package/dist/util/lru.js.map +1 -0
  223. package/dist/wasm/isard.d.ts +168 -0
  224. package/dist/wasm/isard.js +146 -0
  225. package/dist/wasm/isard_core.d.ts +144 -0
  226. package/dist/wasm/isard_core.js +122 -0
  227. package/dist/{basemap.worker.d.ts → workers/basemap.worker.d.ts} +17 -7
  228. package/dist/workers/basemap.worker.js +658 -0
  229. package/dist/workers/basemap.worker.js.map +1 -0
  230. package/package.json +24 -1
  231. package/vite.js +1 -1
  232. package/dist/animation.js.map +0 -1
  233. package/dist/basemaps.js.map +0 -1
  234. package/dist/color.js.map +0 -1
  235. package/dist/controls.js.map +0 -1
  236. package/dist/crs.js.map +0 -1
  237. package/dist/decoders.js.map +0 -1
  238. package/dist/extrusions.js.map +0 -1
  239. package/dist/features.js.map +0 -1
  240. package/dist/geo.js.map +0 -1
  241. package/dist/glyphs.js.map +0 -1
  242. package/dist/gpx.js.map +0 -1
  243. package/dist/grid.js.map +0 -1
  244. package/dist/icons.js.map +0 -1
  245. package/dist/interaction.js.map +0 -1
  246. package/dist/kml.js.map +0 -1
  247. package/dist/layers.js.map +0 -1
  248. package/dist/loader.js.map +0 -1
  249. package/dist/lru.js.map +0 -1
  250. package/dist/mvt.js.map +0 -1
  251. package/dist/overlay.js.map +0 -1
  252. package/dist/panoramas.js.map +0 -1
  253. package/dist/pmtiles.js.map +0 -1
  254. package/dist/pointclouds.js.map +0 -1
  255. package/dist/protocol.js +0 -2
  256. package/dist/protocol.js.map +0 -1
  257. package/dist/requests.js.map +0 -1
  258. package/dist/resample.js.map +0 -1
  259. package/dist/style.js.map +0 -1
  260. package/dist/symbols.js.map +0 -1
  261. package/dist/terrain.js.map +0 -1
  262. package/dist/topojson.js.map +0 -1
  263. package/dist/vectorstyle.js.map +0 -1
  264. package/dist/vectortiles.js.map +0 -1
  265. package/dist/wmts.js.map +0 -1
  266. package/dist/xml.js.map +0 -1
  267. /package/dist/{lru.d.ts → util/lru.d.ts} +0 -0
  268. /package/dist/{lru.js → util/lru.js} +0 -0
@@ -0,0 +1,46 @@
1
+ /**
2
+ * What a framework's binding (isard/react, isard/vue) does when the description of a layer changes: the least the
3
+ * layer needs (its data, its style, its instances), or a new layer in its place when what changed is set at creation
4
+ * (its URL, its grid, its nodes). Free of any framework.
5
+ */
6
+ import type { Layer } from '../layers/layers.ts';
7
+ import type { GeoMap, LayerSpec } from '../map.ts';
8
+ /** A layer as a binding describes it: the options of `map.add`, and the values of its features or nodes
9
+ * (`setValues`: what colors them by a ramp) */
10
+ export type BoundLayerSpec<P = Record<string, unknown>> = LayerSpec<P> & {
11
+ values?: Float32Array;
12
+ };
13
+ /** What to do with a layer whose description went from `prev` to `next` */
14
+ export type LayerChange = {
15
+ rebuild: true;
16
+ } | {
17
+ rebuild: false;
18
+ /** The keys changed, with their new values */
19
+ style: Record<string, unknown>;
20
+ own: Record<string, unknown>;
21
+ };
22
+ /**
23
+ * The change from one description to the next, or `undefined` when nothing changed. Values are compared by identity:
24
+ * data, functions and arrays given anew at each render are changes (keep them in a memo)
25
+ */
26
+ export declare const layerChange: (prev: BoundLayerSpec, next: BoundLayerSpec) => LayerChange | undefined;
27
+ /** Applies a change that keeps the layer (`rebuild: false`) */
28
+ export declare const applyLayerChange: (layer: Layer, next: BoundLayerSpec, change: Extract<LayerChange, {
29
+ rebuild: false;
30
+ }>) => void;
31
+ /** Adds a layer from its description, its values set */
32
+ export declare const addBoundLayer: (map: GeoMap, { values, ...spec }: BoundLayerSpec) => Layer;
33
+ /** A layer made anew from its description in the place of `old`, its values set */
34
+ export declare const rebuildBoundLayer: (map: GeoMap, old: Layer, { values, ...spec }: BoundLayerSpec) => Layer;
35
+ /**
36
+ * The layers of a binding in their declared order: `order` (default 0) from the bottom up, layers of the same order by
37
+ * the time they came. A layer added or made anew is moved under the first layer above it
38
+ */
39
+ export declare class LayerOrder {
40
+ private readonly entries;
41
+ private seq;
42
+ /** Places a new layer, or a layer made anew in place of `old` */
43
+ place(layer: Layer, order: number, old?: Layer): void;
44
+ /** Forgets a layer removed */
45
+ remove(layer: Layer): void;
46
+ }
@@ -0,0 +1,154 @@
1
+ /**
2
+ * What a framework's binding (isard/react, isard/vue) does when the description of a layer changes: the least the
3
+ * layer needs (its data, its style, its instances), or a new layer in its place when what changed is set at creation
4
+ * (its URL, its grid, its nodes). Free of any framework.
5
+ */
6
+ /** The keys `setStyle` takes, by layer type; `'all'`: every key but the data (the feature layers) */
7
+ const STYLE_KEYS = {
8
+ lines: 'all',
9
+ circles: 'all',
10
+ fills: 'all',
11
+ symbols: 'all',
12
+ extrusions: 'all',
13
+ raster: new Set(['opacity', 'saturation']),
14
+ network: new Set(['width', 'max', 'contour', 'opacity', 'halo', 'haloOpacity', 'ramp', 'unreachedColor', 'fade']),
15
+ tiles3d: new Set(['maxScreenSpaceError', 'opacity', 'pointSize', 'color']),
16
+ pointcloud: new Set([
17
+ 'colorBy',
18
+ 'pointSize',
19
+ 'maxPointSize',
20
+ 'sizeMode',
21
+ 'shape',
22
+ 'edl',
23
+ 'classifications',
24
+ 'elevationRange',
25
+ 'elevationRamp',
26
+ 'intensityRange',
27
+ 'maxScreenSpaceError',
28
+ 'pointBudget',
29
+ ]),
30
+ models: new Set(),
31
+ ground: new Set(),
32
+ };
33
+ /** Keys a layer takes by a method of its own, by layer type */
34
+ const OWN_SETTERS = {
35
+ lines: new Set(['data', 'filter', 'values']),
36
+ circles: new Set(['data', 'filter', 'values']),
37
+ fills: new Set(['data', 'filter', 'values']),
38
+ symbols: new Set(['data', 'filter']),
39
+ extrusions: new Set(['data', 'filter', 'values']),
40
+ network: new Set(['costs', 'edgeWidths', 'values']),
41
+ models: new Set(['instances', 'altitudeReference']),
42
+ ground: new Set(['uniforms', 'textures']),
43
+ };
44
+ /** The keys of a description and their values */
45
+ const fields = (spec) => new Map(Object.entries(spec));
46
+ /**
47
+ * The change from one description to the next, or `undefined` when nothing changed. Values are compared by identity:
48
+ * data, functions and arrays given anew at each render are changes (keep them in a memo)
49
+ */
50
+ export const layerChange = (prev, next) => {
51
+ if (prev.type !== next.type)
52
+ return { rebuild: true };
53
+ const before = fields(prev);
54
+ const after = fields(next);
55
+ const styleKeys = STYLE_KEYS[next.type];
56
+ const own = OWN_SETTERS[next.type];
57
+ const change = { rebuild: false, style: {}, own: {} };
58
+ const keys = [...new Set([...before.keys(), ...after.keys()])].filter((key) => key !== 'type' && !Object.is(before.get(key), after.get(key)));
59
+ if (keys.length === 0)
60
+ return undefined;
61
+ const isStyle = (key) => key !== 'before' && (styleKeys === 'all' || styleKeys.has(key));
62
+ // A style or setting taken away: the layer goes back to its defaults, as made anew
63
+ if (keys.some((key) => !after.has(key) || !(own?.has(key) || isStyle(key))))
64
+ return { rebuild: true };
65
+ keys.forEach((key) => {
66
+ if (own?.has(key))
67
+ change.own[key] = after.get(key);
68
+ else
69
+ change.style[key] = after.get(key);
70
+ });
71
+ return change;
72
+ };
73
+ /** Calls a setter of the layer, if its type has it */
74
+ const set = (layer, setter, ...args) => {
75
+ const method = Reflect.get(layer, setter);
76
+ if (typeof method === 'function')
77
+ method.apply(layer, args);
78
+ };
79
+ /** Applies a change that keeps the layer (`rebuild: false`) */
80
+ export const applyLayerChange = (layer, next, change) => {
81
+ const spec = fields(next);
82
+ const own = change.own;
83
+ if ('data' in own)
84
+ set(layer, 'setData', own.data);
85
+ if ('filter' in own)
86
+ set(layer, 'setFilter', own.filter);
87
+ if ('values' in own)
88
+ set(layer, 'setValues', own.values);
89
+ if ('costs' in own)
90
+ set(layer, 'setCosts', own.costs);
91
+ if ('edgeWidths' in own)
92
+ set(layer, 'setEdgeWidths', own.edgeWidths);
93
+ if ('instances' in own || 'altitudeReference' in own) {
94
+ set(layer, 'setInstances', spec.get('instances'), spec.get('altitudeReference'));
95
+ }
96
+ if ('uniforms' in own) {
97
+ Object.entries(own.uniforms ?? {}).forEach(([name, value]) => {
98
+ set(layer, 'setUniform', name, value);
99
+ });
100
+ }
101
+ if ('textures' in own) {
102
+ Object.entries(own.textures ?? {}).forEach(([name, texture]) => {
103
+ set(layer, 'setTexture', name, texture);
104
+ });
105
+ }
106
+ if (Object.keys(change.style).length > 0)
107
+ set(layer, 'setStyle', change.style);
108
+ };
109
+ /** Adds a layer from its description, its values set */
110
+ export const addBoundLayer = (map, { values, ...spec }) => {
111
+ const layer = map.add(spec);
112
+ if (values)
113
+ set(layer, 'setValues', values);
114
+ return layer;
115
+ };
116
+ /** A layer made anew from its description in the place of `old`, its values set */
117
+ export const rebuildBoundLayer = (map, old, { values, ...spec }) => {
118
+ const layer = map.rebuildLayer(old, spec);
119
+ if (values)
120
+ set(layer, 'setValues', values);
121
+ return layer;
122
+ };
123
+ /**
124
+ * The layers of a binding in their declared order: `order` (default 0) from the bottom up, layers of the same order by
125
+ * the time they came. A layer added or made anew is moved under the first layer above it
126
+ */
127
+ export class LayerOrder {
128
+ entries = [];
129
+ seq = 0;
130
+ /** Places a new layer, or a layer made anew in place of `old` */
131
+ place(layer, order, old) {
132
+ const index = old ? this.entries.findIndex((e) => e.layer === old) : -1;
133
+ const entry = index >= 0 ? this.entries[index] : undefined;
134
+ if (entry) {
135
+ entry.layer = layer;
136
+ entry.order = order;
137
+ }
138
+ else {
139
+ this.entries.push({ layer, order, seq: this.seq++ });
140
+ }
141
+ this.entries.sort((a, b) => a.order - b.order || a.seq - b.seq);
142
+ const at = this.entries.findIndex((e) => e.layer === layer);
143
+ const above = this.entries[at + 1]?.layer;
144
+ if (above)
145
+ layer.moveBefore(above);
146
+ }
147
+ /** Forgets a layer removed */
148
+ remove(layer) {
149
+ const index = this.entries.findIndex((e) => e.layer === layer);
150
+ if (index >= 0)
151
+ this.entries.splice(index, 1);
152
+ }
153
+ }
154
+ //# sourceMappingURL=layers.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"layers.js","sourceRoot":"","sources":["../../src/bind/layers.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * What a framework's binding (isard/react, isard/vue) does when the description of a layer changes: the least the\n * layer needs (its data, its style, its instances), or a new layer in its place when what changed is set at creation\n * (its URL, its grid, its nodes). Free of any framework.\n */\n\nimport type { Layer } from '../layers/layers.ts';\nimport type { GeoMap, LayerSpec } from '../map.ts';\n\n/** A layer as a binding describes it: the options of `map.add`, and the values of its features or nodes\n * (`setValues`: what colors them by a ramp) */\nexport type BoundLayerSpec<P = Record<string, unknown>> = LayerSpec<P> & { values?: Float32Array };\n\n/** The keys `setStyle` takes, by layer type; `'all'`: every key but the data (the feature layers) */\nconst STYLE_KEYS: Record<LayerSpec['type'], 'all' | ReadonlySet<string>> = {\n lines: 'all',\n circles: 'all',\n fills: 'all',\n symbols: 'all',\n extrusions: 'all',\n raster: new Set(['opacity', 'saturation']),\n network: new Set(['width', 'max', 'contour', 'opacity', 'halo', 'haloOpacity', 'ramp', 'unreachedColor', 'fade']),\n tiles3d: new Set(['maxScreenSpaceError', 'opacity', 'pointSize', 'color']),\n pointcloud: new Set([\n 'colorBy',\n 'pointSize',\n 'maxPointSize',\n 'sizeMode',\n 'shape',\n 'edl',\n 'classifications',\n 'elevationRange',\n 'elevationRamp',\n 'intensityRange',\n 'maxScreenSpaceError',\n 'pointBudget',\n ]),\n models: new Set(),\n ground: new Set(),\n};\n\n/** Keys a layer takes by a method of its own, by layer type */\nconst OWN_SETTERS: Partial<Record<LayerSpec['type'], ReadonlySet<string>>> = {\n lines: new Set(['data', 'filter', 'values']),\n circles: new Set(['data', 'filter', 'values']),\n fills: new Set(['data', 'filter', 'values']),\n symbols: new Set(['data', 'filter']),\n extrusions: new Set(['data', 'filter', 'values']),\n network: new Set(['costs', 'edgeWidths', 'values']),\n models: new Set(['instances', 'altitudeReference']),\n ground: new Set(['uniforms', 'textures']),\n};\n\n/** The keys of a description and their values */\nconst fields = (spec: BoundLayerSpec): Map<string, unknown> => new Map(Object.entries(spec));\n\n/** What to do with a layer whose description went from `prev` to `next` */\nexport type LayerChange =\n | { rebuild: true }\n | {\n rebuild: false;\n /** The keys changed, with their new values */\n style: Record<string, unknown>;\n own: Record<string, unknown>;\n };\n\n/**\n * The change from one description to the next, or `undefined` when nothing changed. Values are compared by identity:\n * data, functions and arrays given anew at each render are changes (keep them in a memo)\n */\nexport const layerChange = (prev: BoundLayerSpec, next: BoundLayerSpec): LayerChange | undefined => {\n if (prev.type !== next.type) return { rebuild: true };\n\n const before = fields(prev);\n const after = fields(next);\n const styleKeys = STYLE_KEYS[next.type];\n const own = OWN_SETTERS[next.type];\n const change: Extract<LayerChange, { rebuild: false }> = { rebuild: false, style: {}, own: {} };\n const keys = [...new Set([...before.keys(), ...after.keys()])].filter(\n (key) => key !== 'type' && !Object.is(before.get(key), after.get(key)),\n );\n\n if (keys.length === 0) return undefined;\n\n const isStyle = (key: string) => key !== 'before' && (styleKeys === 'all' || styleKeys.has(key));\n\n // A style or setting taken away: the layer goes back to its defaults, as made anew\n if (keys.some((key) => !after.has(key) || !(own?.has(key) || isStyle(key)))) return { rebuild: true };\n keys.forEach((key) => {\n if (own?.has(key)) change.own[key] = after.get(key);\n else change.style[key] = after.get(key);\n });\n\n return change;\n};\n\n/** The methods a change calls on a layer, those of its type */\ntype Setter =\n | 'setStyle'\n | 'setData'\n | 'setFilter'\n | 'setValues'\n | 'setCosts'\n | 'setEdgeWidths'\n | 'setInstances'\n | 'setUniform'\n | 'setTexture';\n\n/** Calls a setter of the layer, if its type has it */\nconst set = (layer: Layer, setter: Setter, ...args: unknown[]): void => {\n const method: unknown = Reflect.get(layer, setter);\n\n if (typeof method === 'function') method.apply(layer, args);\n};\n\n/** Applies a change that keeps the layer (`rebuild: false`) */\nexport const applyLayerChange = (\n layer: Layer,\n next: BoundLayerSpec,\n change: Extract<LayerChange, { rebuild: false }>,\n): void => {\n const spec = fields(next);\n const own = change.own;\n\n if ('data' in own) set(layer, 'setData', own.data);\n if ('filter' in own) set(layer, 'setFilter', own.filter);\n if ('values' in own) set(layer, 'setValues', own.values);\n if ('costs' in own) set(layer, 'setCosts', own.costs);\n if ('edgeWidths' in own) set(layer, 'setEdgeWidths', own.edgeWidths);\n if ('instances' in own || 'altitudeReference' in own) {\n set(layer, 'setInstances', spec.get('instances'), spec.get('altitudeReference'));\n }\n if ('uniforms' in own) {\n Object.entries(own.uniforms ?? {}).forEach(([name, value]) => {\n set(layer, 'setUniform', name, value);\n });\n }\n if ('textures' in own) {\n Object.entries(own.textures ?? {}).forEach(([name, texture]) => {\n set(layer, 'setTexture', name, texture);\n });\n }\n if (Object.keys(change.style).length > 0) set(layer, 'setStyle', change.style);\n};\n\n/** Adds a layer from its description, its values set */\nexport const addBoundLayer = (map: GeoMap, { values, ...spec }: BoundLayerSpec): Layer => {\n const layer = map.add(spec as LayerSpec);\n\n if (values) set(layer, 'setValues', values);\n\n return layer;\n};\n\n/** A layer made anew from its description in the place of `old`, its values set */\nexport const rebuildBoundLayer = (map: GeoMap, old: Layer, { values, ...spec }: BoundLayerSpec): Layer => {\n const layer = map.rebuildLayer(old, spec as LayerSpec);\n\n if (values) set(layer, 'setValues', values);\n\n return layer;\n};\n\n/**\n * The layers of a binding in their declared order: `order` (default 0) from the bottom up, layers of the same order by\n * the time they came. A layer added or made anew is moved under the first layer above it\n */\nexport class LayerOrder {\n private readonly entries: { layer: Layer; order: number; seq: number }[] = [];\n private seq = 0;\n\n /** Places a new layer, or a layer made anew in place of `old` */\n place(layer: Layer, order: number, old?: Layer): void {\n const index = old ? this.entries.findIndex((e) => e.layer === old) : -1;\n const entry = index >= 0 ? this.entries[index] : undefined;\n\n if (entry) {\n entry.layer = layer;\n entry.order = order;\n } else {\n this.entries.push({ layer, order, seq: this.seq++ });\n }\n this.entries.sort((a, b) => a.order - b.order || a.seq - b.seq);\n\n const at = this.entries.findIndex((e) => e.layer === layer);\n const above = this.entries[at + 1]?.layer;\n\n if (above) layer.moveBefore(above);\n }\n\n /** Forgets a layer removed */\n remove(layer: Layer): void {\n const index = this.entries.findIndex((e) => e.layer === layer);\n\n if (index >= 0) this.entries.splice(index, 1);\n }\n}\n"]}
@@ -9,7 +9,7 @@
9
9
  * they differ by less than a metre. Any other CRS is plugged in as an object with `forward` and `inverse`, such as
10
10
  * `proj4('EPSG:27572')`, directly or by name through `registerCrs`.
11
11
  */
12
- import type { FeatureCollection, FeatureData } from './features.ts';
12
+ import type { FeatureCollection, FeatureData } from '../layers/features.ts';
13
13
  /** A CRS: longitudes and latitudes (degrees) to its coordinates (x east, y north), and back. A converter of proj4
14
14
  * (`proj4('EPSG:2154')`) is one */
15
15
  export interface Crs {
@@ -22,7 +22,7 @@ export type CrsLike = string | Crs;
22
22
  * Lambert Conformal Conic with two standard parallels (EPSG method 9802), angles in degrees: the projection of
23
23
  * Lambert-93 and of the CC zones, and of many national grids
24
24
  */
25
- export declare function lambertConformalConic(p: {
25
+ export declare const lambertConformalConic: (p: {
26
26
  /** Semi-major axis (metres) and flattening (default GRS80) */
27
27
  ellipsoid?: [a: number, f: number];
28
28
  lat0: number;
@@ -31,12 +31,12 @@ export declare function lambertConformalConic(p: {
31
31
  lat2: number;
32
32
  x0: number;
33
33
  y0: number;
34
- }): Crs;
34
+ }) => Crs;
35
35
  /**
36
36
  * Transverse Mercator (EPSG method 9807) by Krüger's series to the sixth order (Karney, 2011), angles in degrees:
37
37
  * exact to the tenth of a millimetre within 4000 km of the central meridian. The projection of the UTM zones
38
38
  */
39
- export declare function transverseMercator(p: {
39
+ export declare const transverseMercator: (p: {
40
40
  /** Semi-major axis (metres) and flattening (default GRS80) */
41
41
  ellipsoid?: [a: number, f: number];
42
42
  lon0: number;
@@ -44,24 +44,24 @@ export declare function transverseMercator(p: {
44
44
  k0: number;
45
45
  x0: number;
46
46
  y0: number;
47
- }): Crs;
47
+ }) => Crs;
48
48
  /**
49
49
  * The EPSG code of a CRS name: `EPSG:2154`, `urn:ogc:def:crs:EPSG::2154`, `urn:ogc:def:crs:EPSG:6.3:2154`,
50
50
  * `http://www.opengis.net/def/crs/EPSG/0/2154`; `CRS:84`, `OGC:CRS84` and the IGN's `IGNF:WGS84G` are 4326, its
51
51
  * `IGNF:LAMB93` 2154, the old names of Web Mercator 3857. Undefined for another name
52
52
  */
53
- export declare function epsgCode(name: string): number | undefined;
53
+ export declare const epsgCode: (name: string) => number | undefined;
54
54
  /** Whether a CRS name is longitudes and latitudes (needs no reprojection) */
55
- export declare function isGeographic(name: string): boolean;
55
+ export declare const isGeographic: (name: string) => boolean;
56
56
  /**
57
57
  * Names a CRS for every place that takes one (`registerCrs('EPSG:27572', proj4('EPSG:27572'))`): the `crs` of a tile
58
58
  * grid, the `crs` member of GeoJSON, `reproject`. A registered name wins over a built-in one
59
59
  */
60
- export declare function registerCrs(name: string, crs: Crs): void;
60
+ export declare const registerCrs: (name: string, crs: Crs) => void;
61
61
  /** The CRS of a name (registered or built in), or the CRS given; throws for an unknown name */
62
- export declare function getCrs(crs: CrsLike): Crs;
62
+ export declare const getCrs: (crs: CrsLike) => Crs;
63
63
  /** The name in the legacy `crs` member of GeoJSON (`{ type: 'name', properties: { name } }`), if any */
64
- export declare function crsOf(data: unknown): string | undefined;
64
+ export declare const crsOf: (data: unknown) => string | undefined;
65
65
  /**
66
66
  * GeoJSON in `from` (default: the CRS its `crs` member names) as GeoJSON in longitudes and latitudes, for the feature
67
67
  * layers: `map.addFills({ data: reproject(parcels, 'EPSG:2154') })`. The features are copied with new geometries, their
@@ -69,4 +69,4 @@ export declare function crsOf(data: unknown): string | undefined;
69
69
  * The feature layers do this by themselves for a collection whose `crs` member names its CRS (a WFS's output in
70
70
  * EPSG:2154)
71
71
  */
72
- export declare function reproject<P>(data: FeatureData<P>, from?: CrsLike): FeatureCollection<P>;
72
+ export declare const reproject: <P>(data: FeatureData<P>, from?: CrsLike) => FeatureCollection<P>;
@@ -1,10 +1,11 @@
1
+ import { isRecord } from "../util/guards.js";
1
2
  const GRS80 = [6378137, 1 / 298.257222101];
2
3
  const WGS84 = [6378137, 1 / 298.257223563];
3
4
  const RAD = Math.PI / 180;
4
5
  /** Isometric latitude of a latitude (radians) on an ellipsoid of eccentricity `e` */
5
6
  const isometric = (phi, e) => Math.atanh(Math.sin(phi)) - e * Math.atanh(e * Math.sin(phi));
6
7
  /** Latitude (radians) of an isometric latitude, by fixed-point iteration (converges by e² at each step) */
7
- function fromIsometric(psi, e) {
8
+ const fromIsometric = (psi, e) => {
8
9
  let phi = Math.asin(Math.tanh(psi));
9
10
  for (let i = 0; i < 20; i += 1) {
10
11
  const next = Math.asin(Math.tanh(psi + e * Math.atanh(e * Math.sin(phi))));
@@ -13,14 +14,14 @@ function fromIsometric(psi, e) {
13
14
  phi = next;
14
15
  }
15
16
  return phi;
16
- }
17
+ };
17
18
  /** An angle (radians) brought into [-π, π] */
18
19
  const wrap = (angle) => angle - 2 * Math.PI * Math.round(angle / (2 * Math.PI));
19
20
  /**
20
21
  * Lambert Conformal Conic with two standard parallels (EPSG method 9802), angles in degrees: the projection of
21
22
  * Lambert-93 and of the CC zones, and of many national grids
22
23
  */
23
- export function lambertConformalConic(p) {
24
+ export const lambertConformalConic = (p) => {
24
25
  const [a, f] = p.ellipsoid ?? GRS80;
25
26
  const e = Math.sqrt(f * (2 - f));
26
27
  const m = (phi) => Math.cos(phi) / Math.sqrt(1 - (e * Math.sin(phi)) ** 2);
@@ -45,12 +46,12 @@ export function lambertConformalConic(p) {
45
46
  return [(theta / n + lon0) / RAD, fromIsometric(-Math.log(r / aF) / n, e) / RAD];
46
47
  },
47
48
  };
48
- }
49
+ };
49
50
  /**
50
51
  * Transverse Mercator (EPSG method 9807) by Krüger's series to the sixth order (Karney, 2011), angles in degrees:
51
52
  * exact to the tenth of a millimetre within 4000 km of the central meridian. The projection of the UTM zones
52
53
  */
53
- export function transverseMercator(p) {
54
+ export const transverseMercator = (p) => {
54
55
  const [a, f] = p.ellipsoid ?? GRS80;
55
56
  const e = Math.sqrt(f * (2 - f));
56
57
  const n = f / (2 - f);
@@ -97,7 +98,7 @@ export function transverseMercator(p) {
97
98
  return [(lon0 + Math.atan2(Math.sinh(eta), Math.cos(xi))) / RAD, fromIsometric(Math.asinh(t), e) / RAD];
98
99
  },
99
100
  };
100
- }
101
+ };
101
102
  /** Longitudes and latitudes themselves */
102
103
  const GEOGRAPHIC = {
103
104
  forward: ([lon, lat]) => [lon, lat],
@@ -118,7 +119,7 @@ const made = new Map();
118
119
  * `http://www.opengis.net/def/crs/EPSG/0/2154`; `CRS:84`, `OGC:CRS84` and the IGN's `IGNF:WGS84G` are 4326, its
119
120
  * `IGNF:LAMB93` 2154, the old names of Web Mercator 3857. Undefined for another name
120
121
  */
121
- export function epsgCode(name) {
122
+ export const epsgCode = (name) => {
122
123
  const n = name.trim().toUpperCase();
123
124
  if (/CRS:?84$/.test(n) || n === 'IGNF:WGS84G')
124
125
  return 4326;
@@ -129,9 +130,9 @@ export function epsgCode(name) {
129
130
  return undefined;
130
131
  const c = Number(code);
131
132
  return c === 900913 || c === 3785 || c === 102100 || c === 102113 ? 3857 : c;
132
- }
133
+ };
133
134
  /** A built-in CRS by EPSG code; undefined if not built in */
134
- function builtin(code) {
135
+ const builtin = (code) => {
135
136
  if (code === 4326 || code === 4258 || code === 4171)
136
137
  return GEOGRAPHIC;
137
138
  if (code === 3857)
@@ -152,12 +153,12 @@ function builtin(code) {
152
153
  if (code >= 25828 && code <= 25838)
153
154
  return utm(code - 25800, false, GRS80);
154
155
  return undefined;
155
- }
156
+ };
156
157
  /** Whether a CRS name is longitudes and latitudes (needs no reprojection) */
157
- export function isGeographic(name) {
158
+ export const isGeographic = (name) => {
158
159
  const code = epsgCode(name);
159
160
  return !registered.has(normalize(name)) && code !== undefined && builtin(code) === GEOGRAPHIC;
160
- }
161
+ };
161
162
  const normalize = (name) => {
162
163
  const code = epsgCode(name);
163
164
  return code === undefined ? name.trim().toUpperCase() : `EPSG:${code}`;
@@ -166,11 +167,11 @@ const normalize = (name) => {
166
167
  * Names a CRS for every place that takes one (`registerCrs('EPSG:27572', proj4('EPSG:27572'))`): the `crs` of a tile
167
168
  * grid, the `crs` member of GeoJSON, `reproject`. A registered name wins over a built-in one
168
169
  */
169
- export function registerCrs(name, crs) {
170
+ export const registerCrs = (name, crs) => {
170
171
  registered.set(normalize(name), crs);
171
- }
172
+ };
172
173
  /** The CRS of a name (registered or built in), or the CRS given; throws for an unknown name */
173
- export function getCrs(crs) {
174
+ export const getCrs = (crs) => {
174
175
  if (typeof crs !== 'string')
175
176
  return crs;
176
177
  const found = registered.get(normalize(crs));
@@ -178,25 +179,23 @@ export function getCrs(crs) {
178
179
  return found;
179
180
  const code = epsgCode(crs);
180
181
  if (code !== undefined) {
181
- let c = made.get(code);
182
- if (!c) {
183
- c = builtin(code);
184
- if (c)
185
- made.set(code, c);
186
- }
187
- if (c)
182
+ const c = made.get(code) ?? builtin(code);
183
+ if (c) {
184
+ made.set(code, c);
188
185
  return c;
186
+ }
189
187
  }
190
188
  throw new Error(`isard: unknown CRS ${crs}: registerCrs('${crs}', proj4('${crs}')) names it`);
191
- }
189
+ };
192
190
  /** The name in the legacy `crs` member of GeoJSON (`{ type: 'name', properties: { name } }`), if any */
193
- export function crsOf(data) {
194
- const member = data?.crs;
195
- const name = member?.properties?.name;
191
+ export const crsOf = (data) => {
192
+ const member = isRecord(data) ? data.crs : undefined;
193
+ const properties = isRecord(member) ? member.properties : undefined;
194
+ const name = isRecord(properties) ? properties.name : undefined;
196
195
  return typeof name === 'string' ? name : undefined;
197
- }
196
+ };
198
197
  /** A geometry with its positions mapped */
199
- function mapGeometry(g, f) {
198
+ const mapGeometry = (g, f) => {
200
199
  switch (g.type) {
201
200
  case 'Point':
202
201
  return { type: g.type, coordinates: f(g.coordinates) };
@@ -211,7 +210,7 @@ function mapGeometry(g, f) {
211
210
  case 'GeometryCollection':
212
211
  return { type: g.type, geometries: g.geometries.map((child) => mapGeometry(child, f)) };
213
212
  }
214
- }
213
+ };
215
214
  /**
216
215
  * GeoJSON in `from` (default: the CRS its `crs` member names) as GeoJSON in longitudes and latitudes, for the feature
217
216
  * layers: `map.addFills({ data: reproject(parcels, 'EPSG:2154') })`. The features are copied with new geometries, their
@@ -219,10 +218,15 @@ function mapGeometry(g, f) {
219
218
  * The feature layers do this by themselves for a collection whose `crs` member names its CRS (a WFS's output in
220
219
  * EPSG:2154)
221
220
  */
222
- export function reproject(data, from) {
223
- let features = Array.isArray(data) ? data : [data];
224
- if (!Array.isArray(data) && data.type === 'FeatureCollection')
225
- features = data.features;
221
+ export const reproject = (data, from) => {
222
+ const featuresOf = () => {
223
+ if (Array.isArray(data))
224
+ return data;
225
+ if (data.type === 'FeatureCollection')
226
+ return data.features;
227
+ return [data];
228
+ };
229
+ const features = featuresOf();
226
230
  const source = from ?? crsOf(data);
227
231
  if (source === undefined || (typeof source === 'string' && isGeographic(source))) {
228
232
  return { type: 'FeatureCollection', features };
@@ -239,5 +243,5 @@ export function reproject(data, from) {
239
243
  geometry: feature.geometry && mapGeometry(feature.geometry, f),
240
244
  })),
241
245
  };
242
- }
246
+ };
243
247
  //# sourceMappingURL=crs.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"crs.js","sourceRoot":"","sources":["../../src/data/crs.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Coordinate reference systems of the data: a CRS turns longitudes and latitudes (degrees) into its coordinates\n * (`forward`) and back (`inverse`). The map stays in Web Mercator (or the globe): data in another CRS is reprojected\n * into it, as rasters (see `TileGrid`) or as GeoJSON (`reproject`).\n *\n * Built in, exact to the millimetre against PROJ: EPSG:4326 (and the geographic ETRS89, RGF93), EPSG:3857, Lambert-93\n * (EPSG:2154), the nine conic zones CC42 to CC50 (EPSG:3942 to 3950), the UTM zones of WGS 84 (EPSG:32601 to 32660\n * north, 32701 to 32760 south) and of ETRS89 (EPSG:25828 to 25838). WGS 84, ETRS89 and RGF93 are taken as one datum:\n * they differ by less than a metre. Any other CRS is plugged in as an object with `forward` and `inverse`, such as\n * `proj4('EPSG:27572')`, directly or by name through `registerCrs`.\n */\nimport type { Feature, FeatureCollection, FeatureData, Geometry, Position } from '../layers/features.ts';\nimport { isRecord } from '../util/guards.ts';\n\n/** A CRS: longitudes and latitudes (degrees) to its coordinates (x east, y north), and back. A converter of proj4\n * (`proj4('EPSG:2154')`) is one */\nexport interface Crs {\n forward(lonLat: [number, number]): readonly number[];\n inverse(xy: [number, number]): readonly number[];\n}\n\n/** A CRS by name (`'EPSG:2154'`, `'urn:ogc:def:crs:EPSG::2154'`, `'CRS:84'`…; built in or registered), or itself */\nexport type CrsLike = string | Crs;\n\n/** An ellipsoid: semi-major axis (metres) and flattening */\ntype Ellipsoid = [a: number, f: number];\nconst GRS80: Ellipsoid = [6378137, 1 / 298.257222101];\nconst WGS84: Ellipsoid = [6378137, 1 / 298.257223563];\n\nconst RAD = Math.PI / 180;\n\n/** Isometric latitude of a latitude (radians) on an ellipsoid of eccentricity `e` */\nconst isometric = (phi: number, e: number) => Math.atanh(Math.sin(phi)) - e * Math.atanh(e * Math.sin(phi));\n\n/** Latitude (radians) of an isometric latitude, by fixed-point iteration (converges by e² at each step) */\nconst fromIsometric = (psi: number, e: number): number => {\n let phi = Math.asin(Math.tanh(psi));\n\n for (let i = 0; i < 20; i += 1) {\n const next = Math.asin(Math.tanh(psi + e * Math.atanh(e * Math.sin(phi))));\n\n if (Math.abs(next - phi) < 1e-15) return next;\n phi = next;\n }\n\n return phi;\n};\n\n/** An angle (radians) brought into [-π, π] */\nconst wrap = (angle: number) => angle - 2 * Math.PI * Math.round(angle / (2 * Math.PI));\n\n/**\n * Lambert Conformal Conic with two standard parallels (EPSG method 9802), angles in degrees: the projection of\n * Lambert-93 and of the CC zones, and of many national grids\n */\nexport const lambertConformalConic = (p: {\n /** Semi-major axis (metres) and flattening (default GRS80) */\n ellipsoid?: [a: number, f: number];\n lat0: number;\n lon0: number;\n lat1: number;\n lat2: number;\n x0: number;\n y0: number;\n}): Crs => {\n const [a, f] = p.ellipsoid ?? GRS80;\n const e = Math.sqrt(f * (2 - f));\n const m = (phi: number) => Math.cos(phi) / Math.sqrt(1 - (e * Math.sin(phi)) ** 2);\n const [phi1, phi2] = [p.lat1 * RAD, p.lat2 * RAD];\n const n =\n phi1 === phi2\n ? Math.sin(phi1)\n : (Math.log(m(phi1)) - Math.log(m(phi2))) / (isometric(phi2, e) - isometric(phi1, e));\n const aF = (a * m(phi1) * Math.exp(n * isometric(phi1, e))) / n;\n const r0 = aF * Math.exp(-n * isometric(p.lat0 * RAD, e));\n const lon0 = p.lon0 * RAD;\n\n return {\n forward: ([lon, lat]) => {\n const r = aF * Math.exp(-n * isometric(lat * RAD, e));\n const theta = n * wrap(lon * RAD - lon0);\n\n return [p.x0 + r * Math.sin(theta), p.y0 + r0 - r * Math.cos(theta)];\n },\n inverse: ([x, y]) => {\n const s = Math.sign(n);\n const [dx, dy] = [x - p.x0, r0 - (y - p.y0)];\n const r = s * Math.hypot(dx, dy);\n const theta = Math.atan2(s * dx, s * dy);\n\n return [(theta / n + lon0) / RAD, fromIsometric(-Math.log(r / aF) / n, e) / RAD];\n },\n };\n};\n\n/**\n * Transverse Mercator (EPSG method 9807) by Krüger's series to the sixth order (Karney, 2011), angles in degrees:\n * exact to the tenth of a millimetre within 4000 km of the central meridian. The projection of the UTM zones\n */\nexport const transverseMercator = (p: {\n /** Semi-major axis (metres) and flattening (default GRS80) */\n ellipsoid?: [a: number, f: number];\n lon0: number;\n /** Scale on the central meridian */\n k0: number;\n x0: number;\n y0: number;\n}): Crs => {\n const [a, f] = p.ellipsoid ?? GRS80;\n const e = Math.sqrt(f * (2 - f));\n const n = f / (2 - f);\n const [n2, n3, n4, n5, n6] = [n ** 2, n ** 3, n ** 4, n ** 5, n ** 6];\n const kA = (p.k0 * a * (1 + n2 / 4 + n4 / 64 + n6 / 256)) / (1 + n);\n const alpha = [\n n / 2 - (2 * n2) / 3 + (5 * n3) / 16 + (41 * n4) / 180 - (127 * n5) / 288 + (7891 * n6) / 37800,\n (13 * n2) / 48 - (3 * n3) / 5 + (557 * n4) / 1440 + (281 * n5) / 630 - (1983433 * n6) / 1935360,\n (61 * n3) / 240 - (103 * n4) / 140 + (15061 * n5) / 26880 + (167603 * n6) / 181440,\n (49561 * n4) / 161280 - (179 * n5) / 168 + (6601661 * n6) / 7257600,\n (34729 * n5) / 80640 - (3418889 * n6) / 1995840,\n (212378941 * n6) / 319334400,\n ];\n const beta = [\n n / 2 - (2 * n2) / 3 + (37 * n3) / 96 - n4 / 360 - (81 * n5) / 512 + (96199 * n6) / 604800,\n n2 / 48 + n3 / 15 - (437 * n4) / 1440 + (46 * n5) / 105 - (1118711 * n6) / 3870720,\n (17 * n3) / 480 - (37 * n4) / 840 - (209 * n5) / 4480 + (5569 * n6) / 90720,\n (4397 * n4) / 161280 - (11 * n5) / 504 - (830251 * n6) / 7257600,\n (4583 * n5) / 161280 - (108847 * n6) / 3991680,\n (20648693 * n6) / 638668800,\n ];\n /** ξ, η moved by the series of coefficients `c`, added (forward) or subtracted (inverse) */\n const series = (xi: number, eta: number, c: number[], sign: number): [number, number] => {\n let [x, y] = [xi, eta];\n\n c.forEach((k, j) => {\n const w = 2 * (j + 1);\n\n x += sign * k * Math.sin(w * xi) * Math.cosh(w * eta);\n y += sign * k * Math.cos(w * xi) * Math.sinh(w * eta);\n });\n\n return [x, y];\n };\n const lon0 = p.lon0 * RAD;\n\n return {\n forward: ([lon, lat]) => {\n const lambda = wrap(lon * RAD - lon0);\n // The conformal latitude's tangent\n const t = Math.sinh(isometric(lat * RAD, e));\n const [xi, eta] = series(\n Math.atan2(t, Math.cos(lambda)),\n Math.asinh(Math.sin(lambda) / Math.hypot(t, Math.cos(lambda))),\n alpha,\n 1,\n );\n\n return [p.x0 + kA * eta, p.y0 + kA * xi];\n },\n inverse: ([x, y]) => {\n const [xi, eta] = series((y - p.y0) / kA, (x - p.x0) / kA, beta, -1);\n const t = Math.sin(xi) / Math.hypot(Math.sinh(eta), Math.cos(xi));\n\n return [(lon0 + Math.atan2(Math.sinh(eta), Math.cos(xi))) / RAD, fromIsometric(Math.asinh(t), e) / RAD];\n },\n };\n};\n\n/** Longitudes and latitudes themselves */\nconst GEOGRAPHIC: Crs = {\n forward: ([lon, lat]) => [lon, lat],\n inverse: ([x, y]) => [x, y],\n};\n\n/** Web Mercator in metres (EPSG:3857) */\nconst R = 6378137;\nconst WEB_MERCATOR: Crs = {\n forward: ([lon, lat]) => [R * lon * RAD, R * Math.log(Math.tan(Math.PI / 4 + (lat * RAD) / 2))],\n inverse: ([x, y]) => [x / R / RAD, (2 * Math.atan(Math.exp(y / R)) - Math.PI / 2) / RAD],\n};\n\n/** The CRSs registered by the application, by name */\nconst registered = new Map<string, Crs>();\n/** The built-in CRSs made so far, by EPSG code */\nconst made = new Map<number, Crs>();\n\n/**\n * The EPSG code of a CRS name: `EPSG:2154`, `urn:ogc:def:crs:EPSG::2154`, `urn:ogc:def:crs:EPSG:6.3:2154`,\n * `http://www.opengis.net/def/crs/EPSG/0/2154`; `CRS:84`, `OGC:CRS84` and the IGN's `IGNF:WGS84G` are 4326, its\n * `IGNF:LAMB93` 2154, the old names of Web Mercator 3857. Undefined for another name\n */\nexport const epsgCode = (name: string): number | undefined => {\n const n = name.trim().toUpperCase();\n\n if (/CRS:?84$/.test(n) || n === 'IGNF:WGS84G') return 4326;\n if (n === 'IGNF:LAMB93') return 2154;\n\n const code = /EPSG(?::+|\\/)(?:[\\d.]+[:/]+)?(\\d+)$/.exec(n)?.[1];\n\n if (code === undefined) return undefined;\n\n const c = Number(code);\n\n return c === 900913 || c === 3785 || c === 102100 || c === 102113 ? 3857 : c;\n};\n\n/** A built-in CRS by EPSG code; undefined if not built in */\nconst builtin = (code: number): Crs | undefined => {\n if (code === 4326 || code === 4258 || code === 4171) return GEOGRAPHIC;\n if (code === 3857) return WEB_MERCATOR;\n if (code === 2154) {\n return lambertConformalConic({ lat0: 46.5, lon0: 3, lat1: 49, lat2: 44, x0: 700000, y0: 6600000 });\n }\n if (code >= 3942 && code <= 3950) {\n const lat0 = code - 3900;\n const y0 = (lat0 - 41) * 1000000 + 200000;\n\n return lambertConformalConic({ lat0, lon0: 3, lat1: lat0 - 0.75, lat2: lat0 + 0.75, x0: 1700000, y0 });\n }\n\n const utm = (zone: number, south: boolean, ellipsoid: Ellipsoid) =>\n transverseMercator({ ellipsoid, lon0: zone * 6 - 183, k0: 0.9996, x0: 500000, y0: south ? 10000000 : 0 });\n\n if (code >= 32601 && code <= 32660) return utm(code - 32600, false, WGS84);\n if (code >= 32701 && code <= 32760) return utm(code - 32700, true, WGS84);\n if (code >= 25828 && code <= 25838) return utm(code - 25800, false, GRS80);\n\n return undefined;\n};\n\n/** Whether a CRS name is longitudes and latitudes (needs no reprojection) */\nexport const isGeographic = (name: string): boolean => {\n const code = epsgCode(name);\n\n return !registered.has(normalize(name)) && code !== undefined && builtin(code) === GEOGRAPHIC;\n};\n\nconst normalize = (name: string) => {\n const code = epsgCode(name);\n\n return code === undefined ? name.trim().toUpperCase() : `EPSG:${code}`;\n};\n\n/**\n * Names a CRS for every place that takes one (`registerCrs('EPSG:27572', proj4('EPSG:27572'))`): the `crs` of a tile\n * grid, the `crs` member of GeoJSON, `reproject`. A registered name wins over a built-in one\n */\nexport const registerCrs = (name: string, crs: Crs): void => {\n registered.set(normalize(name), crs);\n};\n\n/** The CRS of a name (registered or built in), or the CRS given; throws for an unknown name */\nexport const getCrs = (crs: CrsLike): Crs => {\n if (typeof crs !== 'string') return crs;\n\n const found = registered.get(normalize(crs));\n\n if (found) return found;\n\n const code = epsgCode(crs);\n\n if (code !== undefined) {\n const c = made.get(code) ?? builtin(code);\n\n if (c) {\n made.set(code, c);\n\n return c;\n }\n }\n throw new Error(`isard: unknown CRS ${crs}: registerCrs('${crs}', proj4('${crs}')) names it`);\n};\n\n/** The name in the legacy `crs` member of GeoJSON (`{ type: 'name', properties: { name } }`), if any */\nexport const crsOf = (data: unknown): string | undefined => {\n const member = isRecord(data) ? data.crs : undefined;\n const properties = isRecord(member) ? member.properties : undefined;\n const name = isRecord(properties) ? properties.name : undefined;\n\n return typeof name === 'string' ? name : undefined;\n};\n\n/** A geometry with its positions mapped */\nconst mapGeometry = (g: Geometry, f: (p: Position) => Position): Geometry => {\n switch (g.type) {\n case 'Point':\n return { type: g.type, coordinates: f(g.coordinates) };\n case 'MultiPoint':\n case 'LineString':\n return { type: g.type, coordinates: g.coordinates.map(f) };\n case 'MultiLineString':\n case 'Polygon':\n return { type: g.type, coordinates: g.coordinates.map((line) => line.map(f)) };\n case 'MultiPolygon':\n return { type: g.type, coordinates: g.coordinates.map((poly) => poly.map((line) => line.map(f))) };\n case 'GeometryCollection':\n return { type: g.type, geometries: g.geometries.map((child) => mapGeometry(child, f)) };\n }\n};\n\n/**\n * GeoJSON in `from` (default: the CRS its `crs` member names) as GeoJSON in longitudes and latitudes, for the feature\n * layers: `map.addFills({ data: reproject(parcels, 'EPSG:2154') })`. The features are copied with new geometries, their\n * properties shared; altitudes are kept. Data without a CRS, or in longitudes and latitudes, comes back as it is.\n * The feature layers do this by themselves for a collection whose `crs` member names its CRS (a WFS's output in\n * EPSG:2154)\n */\nexport const reproject = <P>(data: FeatureData<P>, from?: CrsLike): FeatureCollection<P> => {\n const featuresOf = (): Feature<P>[] => {\n if (Array.isArray(data)) return data;\n if (data.type === 'FeatureCollection') return data.features;\n\n return [data];\n };\n const features = featuresOf();\n const source = from ?? crsOf(data);\n\n if (source === undefined || (typeof source === 'string' && isGeographic(source))) {\n return { type: 'FeatureCollection', features };\n }\n\n const crs = getCrs(source);\n const f = (p: Position): Position => {\n const [lon, lat] = crs.inverse([p[0], p[1]]);\n\n return [lon ?? Number.NaN, lat ?? Number.NaN, ...p.slice(2)];\n };\n\n return {\n type: 'FeatureCollection',\n features: features.map(\n (feature): Feature<P> => ({\n ...feature,\n geometry: feature.geometry && mapGeometry(feature.geometry, f),\n }),\n ),\n };\n};\n"]}
@@ -1,11 +1,11 @@
1
1
  /**
2
2
  * GPX to GeoJSON, for the feature layers: `map.addLines({ data: parseGpx(await (await fetch(url)).text()) })`.
3
3
  */
4
- import type { FeatureCollection, Properties } from './features.ts';
4
+ import type { FeatureCollection, Properties } from '../layers/features.ts';
5
5
  /**
6
6
  * The waypoints, routes and tracks of a GPX file as GeoJSON features: a waypoint as a point (its `time` a property),
7
7
  * a route as a line, a track as a line or, of several segments, a multi-line; altitudes (`ele`) as the third
8
8
  * coordinate; `name`, `desc`, `cmt`, `type`… as properties, and the times of the points as `times` (one list, or one
9
9
  * per segment) when they all have one
10
10
  */
11
- export declare function parseGpx<P = Properties>(text: string): FeatureCollection<P>;
11
+ export declare const parseGpx: <P = Properties>(text: string) => FeatureCollection<P>;