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.
- package/CHANGELOG.md +51 -0
- package/dist/{basemaps.d.ts → basemap/basemaps.d.ts} +3 -3
- package/dist/{basemaps.js → basemap/basemaps.js} +3 -3
- package/dist/basemap/basemaps.js.map +1 -0
- package/dist/{grid.d.ts → basemap/grid.d.ts} +6 -6
- package/dist/{grid.js → basemap/grid.js} +61 -67
- package/dist/basemap/grid.js.map +1 -0
- package/dist/{mvt.d.ts → basemap/mvt.d.ts} +1 -1
- package/dist/{mvt.js → basemap/mvt.js} +6 -6
- package/dist/basemap/mvt.js.map +1 -0
- package/dist/{pmtiles.d.ts → basemap/pmtiles.d.ts} +16 -10
- package/dist/{pmtiles.js → basemap/pmtiles.js} +41 -33
- package/dist/basemap/pmtiles.js.map +1 -0
- package/dist/{resample.d.ts → basemap/resample.d.ts} +11 -2
- package/dist/{resample.js → basemap/resample.js} +18 -16
- package/dist/basemap/resample.js.map +1 -0
- package/dist/{terrain.d.ts → basemap/terrain.d.ts} +3 -3
- package/dist/{terrain.js → basemap/terrain.js} +7 -7
- package/dist/basemap/terrain.js.map +1 -0
- package/dist/{vectorstyle.d.ts → basemap/vectorstyle.d.ts} +12 -10
- package/dist/{vectorstyle.js → basemap/vectorstyle.js} +129 -111
- package/dist/basemap/vectorstyle.js.map +1 -0
- package/dist/{vectortiles.d.ts → basemap/vectortiles.d.ts} +18 -18
- package/dist/{vectortiles.js → basemap/vectortiles.js} +157 -109
- package/dist/basemap/vectortiles.js.map +1 -0
- package/dist/{wmts.d.ts → basemap/wmts.d.ts} +3 -3
- package/dist/{wmts.js → basemap/wmts.js} +19 -14
- package/dist/basemap/wmts.js.map +1 -0
- package/dist/basemap.worker.js +2 -2
- package/dist/basemap.worker.js.map +14 -13
- package/dist/bind/layers.d.ts +46 -0
- package/dist/bind/layers.js +154 -0
- package/dist/bind/layers.js.map +1 -0
- package/dist/{crs.d.ts → data/crs.d.ts} +11 -11
- package/dist/{crs.js → data/crs.js} +38 -34
- package/dist/data/crs.js.map +1 -0
- package/dist/{gpx.d.ts → data/gpx.d.ts} +2 -2
- package/dist/{gpx.js → data/gpx.js} +20 -20
- package/dist/data/gpx.js.map +1 -0
- package/dist/{kml.d.ts → data/kml.d.ts} +2 -2
- package/dist/{kml.js → data/kml.js} +42 -39
- package/dist/data/kml.js.map +1 -0
- package/dist/{topojson.d.ts → data/topojson.d.ts} +2 -2
- package/dist/{topojson.js → data/topojson.js} +15 -10
- package/dist/data/topojson.js.map +1 -0
- package/dist/{xml.d.ts → data/xml.d.ts} +5 -5
- package/dist/{xml.js → data/xml.js} +19 -18
- package/dist/data/xml.js.map +1 -0
- package/dist/decoder.worker.js +4 -4
- package/dist/decoder.worker.js.map +7 -7
- package/dist/{decoders.d.ts → engine/decoders.d.ts} +3 -3
- package/dist/{decoders.js → engine/decoders.js} +28 -25
- package/dist/engine/decoders.js.map +1 -0
- package/dist/{loader.d.ts → engine/loader.d.ts} +1 -1
- package/dist/{loader.js → engine/loader.js} +17 -14
- package/dist/engine/loader.js.map +1 -0
- package/dist/{protocol.d.ts → engine/protocol.d.ts} +1 -1
- package/dist/engine/protocol.js +3 -0
- package/dist/engine/protocol.js.map +1 -0
- package/dist/{requests.d.ts → engine/requests.d.ts} +1 -1
- package/dist/{requests.js → engine/requests.js} +19 -16
- package/dist/engine/requests.js.map +1 -0
- package/dist/engine-loader.d.ts +13 -9
- package/dist/engine-loader.js +30 -30
- package/dist/engine-loader.js.map +1 -1
- package/dist/formats.d.ts +3 -3
- package/dist/formats.js +3 -3
- package/dist/formats.js.map +1 -1
- package/dist/geoplateforme.d.ts +13 -13
- package/dist/geoplateforme.js +23 -21
- package/dist/geoplateforme.js.map +1 -1
- package/dist/index.d.ts +30 -29
- package/dist/index.js +18 -18
- package/dist/index.js.map +1 -1
- package/dist/isard_bg.wasm +0 -0
- package/dist/isard_core_bg.wasm +0 -0
- package/dist/isard_points_bg.wasm +0 -0
- package/dist/{extrusions.d.ts → layers/extrusions.d.ts} +1 -1
- package/dist/{extrusions.js → layers/extrusions.js} +10 -5
- package/dist/layers/extrusions.js.map +1 -0
- package/dist/{features.d.ts → layers/features.d.ts} +10 -10
- package/dist/{features.js → layers/features.js} +44 -45
- package/dist/layers/features.js.map +1 -0
- package/dist/{glyphs.d.ts → layers/glyphs.d.ts} +6 -6
- package/dist/{glyphs.js → layers/glyphs.js} +45 -41
- package/dist/layers/glyphs.js.map +1 -0
- package/dist/{icons.d.ts → layers/icons.d.ts} +10 -10
- package/dist/{icons.js → layers/icons.js} +84 -69
- package/dist/layers/icons.js.map +1 -0
- package/dist/{layers.d.ts → layers/layers.d.ts} +9 -4
- package/dist/{layers.js → layers/layers.js} +35 -31
- package/dist/layers/layers.js.map +1 -0
- package/dist/{panoramas.d.ts → layers/panoramas.d.ts} +3 -3
- package/dist/{panoramas.js → layers/panoramas.js} +54 -43
- package/dist/layers/panoramas.js.map +1 -0
- package/dist/{pointclouds.d.ts → layers/pointclouds.d.ts} +5 -5
- package/dist/{pointclouds.js → layers/pointclouds.js} +26 -34
- package/dist/layers/pointclouds.js.map +1 -0
- package/dist/{symbols.d.ts → layers/symbols.d.ts} +3 -3
- package/dist/{symbols.js → layers/symbols.js} +69 -72
- package/dist/layers/symbols.js.map +1 -0
- package/dist/map/basemap-layers.d.ts +26 -0
- package/dist/map/basemap-layers.js +61 -0
- package/dist/map/basemap-layers.js.map +1 -0
- package/dist/map/canvas.d.ts +17 -0
- package/dist/map/canvas.js +56 -0
- package/dist/map/canvas.js.map +1 -0
- package/dist/map/checks.d.ts +11 -0
- package/dist/map/checks.js +39 -0
- package/dist/map/checks.js.map +1 -0
- package/dist/map/credits.d.ts +17 -0
- package/dist/map/credits.js +34 -0
- package/dist/map/credits.js.map +1 -0
- package/dist/map/engine-settings.d.ts +15 -0
- package/dist/map/engine-settings.js +45 -0
- package/dist/map/engine-settings.js.map +1 -0
- package/dist/map/engines.d.ts +41 -0
- package/dist/map/engines.js +77 -0
- package/dist/map/engines.js.map +1 -0
- package/dist/map/events.d.ts +14 -0
- package/dist/map/events.js +46 -0
- package/dist/map/events.js.map +1 -0
- package/dist/map/frame-loop.d.ts +61 -0
- package/dist/map/frame-loop.js +139 -0
- package/dist/map/frame-loop.js.map +1 -0
- package/dist/map/hover-pick.d.ts +30 -0
- package/dist/map/hover-pick.js +56 -0
- package/dist/map/hover-pick.js.map +1 -0
- package/dist/map/layer-spec.d.ts +42 -0
- package/dist/map/layer-spec.js +34 -0
- package/dist/map/layer-spec.js.map +1 -0
- package/dist/map/layer-stack.d.ts +36 -0
- package/dist/map/layer-stack.js +101 -0
- package/dist/map/layer-stack.js.map +1 -0
- package/dist/map/overlay-host.d.ts +36 -0
- package/dist/map/overlay-host.js +101 -0
- package/dist/map/overlay-host.js.map +1 -0
- package/dist/map/panorama-host.d.ts +5 -0
- package/dist/map/panorama-host.js +32 -0
- package/dist/map/panorama-host.js.map +1 -0
- package/dist/map/raster-source.d.ts +11 -0
- package/dist/map/raster-source.js +26 -0
- package/dist/map/raster-source.js.map +1 -0
- package/dist/map/symbol-atlases.d.ts +26 -0
- package/dist/map/symbol-atlases.js +59 -0
- package/dist/map/symbol-atlases.js.map +1 -0
- package/dist/map/viewshed.d.ts +5 -0
- package/dist/map/viewshed.js +28 -0
- package/dist/map/viewshed.js.map +1 -0
- package/dist/map/workers.d.ts +46 -0
- package/dist/map/workers.js +73 -0
- package/dist/map/workers.js.map +1 -0
- package/dist/map.d.ts +46 -127
- package/dist/map.js +183 -698
- package/dist/map.js.map +1 -1
- package/dist/projections.d.ts +3 -3
- package/dist/projections.js +2 -2
- package/dist/projections.js.map +1 -1
- package/dist/react/Control.d.ts +11 -0
- package/dist/react/Control.js +18 -0
- package/dist/react/Control.js.map +1 -0
- package/dist/react/CustomLayer.d.ts +11 -0
- package/dist/react/CustomLayer.js +30 -0
- package/dist/react/CustomLayer.js.map +1 -0
- package/dist/react/IsardMap.d.ts +43 -0
- package/dist/react/IsardMap.js +146 -0
- package/dist/react/IsardMap.js.map +1 -0
- package/dist/react/Layer.d.ts +42 -0
- package/dist/react/Layer.js +74 -0
- package/dist/react/Layer.js.map +1 -0
- package/dist/react/Marker.d.ts +24 -0
- package/dist/react/Marker.js +53 -0
- package/dist/react/Marker.js.map +1 -0
- package/dist/react/Panel.d.ts +11 -0
- package/dist/react/Panel.js +37 -0
- package/dist/react/Panel.js.map +1 -0
- package/dist/react/Popup.d.ts +18 -0
- package/dist/react/Popup.js +60 -0
- package/dist/react/Popup.js.map +1 -0
- package/dist/react/Swipe.d.ts +9 -0
- package/dist/react/Swipe.js +41 -0
- package/dist/react/Swipe.js.map +1 -0
- package/dist/react/Viewshed.d.ts +5 -0
- package/dist/react/Viewshed.js +28 -0
- package/dist/react/Viewshed.js.map +1 -0
- package/dist/react/context.d.ts +32 -0
- package/dist/react/context.js +20 -0
- package/dist/react/context.js.map +1 -0
- package/dist/react/index.d.ts +26 -0
- package/dist/react/index.js +22 -0
- package/dist/react/index.js.map +1 -0
- package/dist/settings.d.ts +6 -10
- package/dist/settings.js +19 -17
- package/dist/settings.js.map +1 -1
- package/dist/types.d.ts +8 -8
- package/dist/types.js +1 -0
- package/dist/types.js.map +1 -1
- package/dist/{controls.d.ts → ui/controls.d.ts} +1 -1
- package/dist/{controls.js → ui/controls.js} +6 -4
- package/dist/ui/controls.js.map +1 -0
- package/dist/{interaction.d.ts → ui/interaction.d.ts} +9 -5
- package/dist/{interaction.js → ui/interaction.js} +9 -8
- package/dist/ui/interaction.js.map +1 -0
- package/dist/{overlay.d.ts → ui/overlay.d.ts} +2 -2
- package/dist/{overlay.js → ui/overlay.js} +18 -20
- package/dist/ui/overlay.js.map +1 -0
- package/dist/{style.d.ts → ui/style.d.ts} +1 -1
- package/dist/{style.js → ui/style.js} +2 -2
- package/dist/ui/style.js.map +1 -0
- package/dist/{animation.d.ts → util/animation.d.ts} +9 -5
- package/dist/{animation.js → util/animation.js} +6 -6
- package/dist/util/animation.js.map +1 -0
- package/dist/{color.d.ts → util/color.d.ts} +1 -1
- package/dist/{color.js → util/color.js} +14 -16
- package/dist/util/color.js.map +1 -0
- package/dist/{geo.d.ts → util/geo.d.ts} +6 -6
- package/dist/{geo.js → util/geo.js} +12 -12
- package/dist/util/geo.js.map +1 -0
- package/dist/util/guards.d.ts +7 -0
- package/dist/util/guards.js +8 -0
- package/dist/util/guards.js.map +1 -0
- package/dist/util/lru.js.map +1 -0
- package/dist/wasm/isard.d.ts +168 -0
- package/dist/wasm/isard.js +146 -0
- package/dist/wasm/isard_core.d.ts +144 -0
- package/dist/wasm/isard_core.js +122 -0
- package/dist/{basemap.worker.d.ts → workers/basemap.worker.d.ts} +17 -7
- package/dist/workers/basemap.worker.js +658 -0
- package/dist/workers/basemap.worker.js.map +1 -0
- package/package.json +24 -1
- package/vite.js +1 -1
- package/dist/animation.js.map +0 -1
- package/dist/basemaps.js.map +0 -1
- package/dist/color.js.map +0 -1
- package/dist/controls.js.map +0 -1
- package/dist/crs.js.map +0 -1
- package/dist/decoders.js.map +0 -1
- package/dist/extrusions.js.map +0 -1
- package/dist/features.js.map +0 -1
- package/dist/geo.js.map +0 -1
- package/dist/glyphs.js.map +0 -1
- package/dist/gpx.js.map +0 -1
- package/dist/grid.js.map +0 -1
- package/dist/icons.js.map +0 -1
- package/dist/interaction.js.map +0 -1
- package/dist/kml.js.map +0 -1
- package/dist/layers.js.map +0 -1
- package/dist/loader.js.map +0 -1
- package/dist/lru.js.map +0 -1
- package/dist/mvt.js.map +0 -1
- package/dist/overlay.js.map +0 -1
- package/dist/panoramas.js.map +0 -1
- package/dist/pmtiles.js.map +0 -1
- package/dist/pointclouds.js.map +0 -1
- package/dist/protocol.js +0 -2
- package/dist/protocol.js.map +0 -1
- package/dist/requests.js.map +0 -1
- package/dist/resample.js.map +0 -1
- package/dist/style.js.map +0 -1
- package/dist/symbols.js.map +0 -1
- package/dist/terrain.js.map +0 -1
- package/dist/topojson.js.map +0 -1
- package/dist/vectorstyle.js.map +0 -1
- package/dist/vectortiles.js.map +0 -1
- package/dist/wmts.js.map +0 -1
- package/dist/xml.js.map +0 -1
- /package/dist/{lru.d.ts → util/lru.d.ts} +0 -0
- /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 '
|
|
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
|
|
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
|
-
})
|
|
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
|
|
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
|
-
})
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
-
|
|
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
|
|
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
|
|
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
|
|
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
|
-
|
|
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
|
|
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
|
|
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
|
|
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
|
-
|
|
182
|
-
if (
|
|
183
|
-
|
|
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
|
|
194
|
-
const member = data
|
|
195
|
-
const
|
|
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
|
-
|
|
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
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
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 '
|
|
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
|
|
11
|
+
export declare const parseGpx: <P = Properties>(text: string) => FeatureCollection<P>;
|