@sjvair/map-sdk 0.0.0-stage → 0.1.0-beta.10
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/LICENSE +21 -0
- package/README.md +713 -2
- package/dist/core/basemap.svelte.d.ts +38 -0
- package/dist/core/basemap.svelte.js +163 -0
- package/dist/core/context.d.ts +5 -0
- package/dist/core/context.js +13 -0
- package/dist/core/create-map.svelte.d.ts +274 -0
- package/dist/core/create-map.svelte.js +591 -0
- package/dist/core/gl.d.ts +97 -0
- package/dist/core/gl.js +1 -0
- package/dist/core/interactions.svelte.d.ts +50 -0
- package/dist/core/interactions.svelte.js +330 -0
- package/dist/core/plugin-host.svelte.d.ts +71 -0
- package/dist/core/plugin-host.svelte.js +445 -0
- package/dist/core/plugin.d.ts +190 -0
- package/dist/core/plugin.js +1 -0
- package/dist/core/scoped-context.d.ts +7 -0
- package/dist/core/scoped-context.js +34 -0
- package/dist/core/shape-view.d.ts +27 -0
- package/dist/core/shape-view.js +323 -0
- package/dist/data/format.d.ts +10 -0
- package/dist/data/format.js +37 -0
- package/dist/data/index.d.ts +9 -0
- package/dist/data/index.js +9 -0
- package/dist/data/messages/en.json +61 -0
- package/dist/data/messages.d.ts +10 -0
- package/dist/data/messages.js +17 -0
- package/dist/data/metadata.d.ts +22 -0
- package/dist/data/metadata.js +110 -0
- package/dist/data/refs.d.ts +18 -0
- package/dist/data/refs.js +61 -0
- package/dist/data/scale-types.d.ts +7 -0
- package/dist/data/scale-types.js +1 -0
- package/dist/data/scale.d.ts +13 -0
- package/dist/data/scale.js +27 -0
- package/dist/data/selection.d.ts +13 -0
- package/dist/data/selection.js +52 -0
- package/dist/data/static-source.d.ts +4 -0
- package/dist/data/static-source.js +3 -0
- package/dist/data/types.d.ts +74 -0
- package/dist/data/types.js +1 -0
- package/dist/index.d.ts +59 -0
- package/dist/index.js +42 -0
- package/dist/plugins/icons.d.ts +21 -0
- package/dist/plugins/icons.js +73 -0
- package/dist/plugins/points-clusters.d.ts +60 -0
- package/dist/plugins/points-clusters.js +93 -0
- package/dist/plugins/points.svelte.d.ts +105 -0
- package/dist/plugins/points.svelte.js +502 -0
- package/dist/plugins/scale-resolution.svelte.d.ts +27 -0
- package/dist/plugins/scale-resolution.svelte.js +111 -0
- package/dist/plugins/shapes.svelte.d.ts +34 -0
- package/dist/plugins/shapes.svelte.js +325 -0
- package/dist/plugins/shared.d.ts +6 -0
- package/dist/plugins/shared.js +18 -0
- package/dist/plugins/style.d.ts +57 -0
- package/dist/plugins/style.js +193 -0
- package/dist/presets/CollocationTooltip.svelte +132 -0
- package/dist/presets/CollocationTooltip.svelte.d.ts +16 -0
- package/dist/presets/FireTooltip.svelte +70 -0
- package/dist/presets/FireTooltip.svelte.d.ts +13 -0
- package/dist/presets/MonitorClusterTooltip.svelte +168 -0
- package/dist/presets/MonitorClusterTooltip.svelte.d.ts +16 -0
- package/dist/presets/MonitorReadingBox.svelte +58 -0
- package/dist/presets/MonitorReadingBox.svelte.d.ts +12 -0
- package/dist/presets/MonitorTooltip.svelte +88 -0
- package/dist/presets/MonitorTooltip.svelte.d.ts +20 -0
- package/dist/presets/calheatscore.d.ts +24 -0
- package/dist/presets/calheatscore.js +22 -0
- package/dist/presets/cluster-area.d.ts +13 -0
- package/dist/presets/cluster-area.js +34 -0
- package/dist/presets/collocation-sites.d.ts +18 -0
- package/dist/presets/collocation-sites.js +67 -0
- package/dist/presets/fire-groups.d.ts +26 -0
- package/dist/presets/fire-groups.js +51 -0
- package/dist/presets/forecast-zones.d.ts +25 -0
- package/dist/presets/forecast-zones.js +23 -0
- package/dist/presets/hms-fire.d.ts +30 -0
- package/dist/presets/hms-fire.js +86 -0
- package/dist/presets/hms-smoke.d.ts +20 -0
- package/dist/presets/hms-smoke.js +22 -0
- package/dist/presets/monitors.d.ts +48 -0
- package/dist/presets/monitors.js +243 -0
- package/dist/presets/reactive-props.svelte.d.ts +4 -0
- package/dist/presets/reactive-props.svelte.js +7 -0
- package/dist/presets/regions.d.ts +24 -0
- package/dist/presets/regions.js +22 -0
- package/dist/stores/abort.d.ts +16 -0
- package/dist/stores/abort.js +52 -0
- package/dist/stores/collocation-store.svelte.d.ts +25 -0
- package/dist/stores/collocation-store.svelte.js +72 -0
- package/dist/stores/hms-stores.svelte.d.ts +38 -0
- package/dist/stores/hms-stores.svelte.js +97 -0
- package/dist/stores/index.d.ts +4 -0
- package/dist/stores/index.js +4 -0
- package/dist/stores/load-once.svelte.d.ts +25 -0
- package/dist/stores/load-once.svelte.js +93 -0
- package/dist/stores/monitors-store.svelte.d.ts +85 -0
- package/dist/stores/monitors-store.svelte.js +340 -0
- package/dist/theme.css +34 -0
- package/dist/ui/FeatureList.svelte +501 -0
- package/dist/ui/FeatureList.svelte.d.ts +14 -0
- package/dist/ui/Legend.svelte +214 -0
- package/dist/ui/Legend.svelte.d.ts +22 -0
- package/dist/ui/LegendBar.svelte +161 -0
- package/dist/ui/LegendBar.svelte.d.ts +11 -0
- package/dist/ui/MapControls.svelte +135 -0
- package/dist/ui/MapControls.svelte.d.ts +11 -0
- package/dist/ui/MapTooltip.svelte +397 -0
- package/dist/ui/MapTooltip.svelte.d.ts +37 -0
- package/dist/ui/PickNotice.svelte +56 -0
- package/dist/ui/PickNotice.svelte.d.ts +7 -0
- package/dist/ui/SelectionBar.svelte +123 -0
- package/dist/ui/SelectionBar.svelte.d.ts +10 -0
- package/dist/ui/TooltipItem.svelte +66 -0
- package/dist/ui/TooltipItem.svelte.d.ts +11 -0
- package/dist/ui/ViewSummary.svelte +97 -0
- package/dist/ui/ViewSummary.svelte.d.ts +7 -0
- package/dist/ui/card.d.ts +29 -0
- package/dist/ui/card.js +1 -0
- package/dist/ui/controls.css +45 -0
- package/dist/ui/data-credits.svelte.d.ts +9 -0
- package/dist/ui/data-credits.svelte.js +52 -0
- package/dist/ui/feature-list.d.ts +46 -0
- package/dist/ui/feature-list.js +115 -0
- package/dist/ui/legend-data.d.ts +41 -0
- package/dist/ui/legend-data.js +40 -0
- package/dist/ui/level-chip.d.ts +11 -0
- package/dist/ui/level-chip.js +15 -0
- package/dist/ui/value-format.d.ts +8 -0
- package/dist/ui/value-format.js +20 -0
- package/dist/ui/view-summary.d.ts +11 -0
- package/dist/ui/view-summary.js +33 -0
- package/dist/view/MapView.svelte +443 -0
- package/dist/view/MapView.svelte.d.ts +51 -0
- package/dist/view/create-gl-map.d.ts +34 -0
- package/dist/view/create-gl-map.js +186 -0
- package/dist/view/list-placement.d.ts +21 -0
- package/dist/view/list-placement.js +13 -0
- package/package.json +104 -5
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import type { GlMapLike } from "./gl.js";
|
|
2
|
+
export interface BasemapConfig {
|
|
3
|
+
styles: Array<{
|
|
4
|
+
id: string;
|
|
5
|
+
style: unknown;
|
|
6
|
+
}>;
|
|
7
|
+
defaultId: string;
|
|
8
|
+
excludedLayers?: string[];
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* The map's current basemap, and switching it on a GL map.
|
|
12
|
+
*
|
|
13
|
+
* The GL map is created with the style of `current` (the map's creator does that), so `attach`
|
|
14
|
+
* calls `setStyle` for nothing. Later `select` calls load the new style. A newer `select`
|
|
15
|
+
* supersedes one still loading. If the style document fails, the map goes back to the last style
|
|
16
|
+
* that loaded and `current` reverts; if that fails too, the map stays unstyled until the next
|
|
17
|
+
* `select`. Right before each `setStyle`, `onStyleChange` is called (it tears the plugins down,
|
|
18
|
+
* so nothing touches the old style while the new one loads). After each successful load,
|
|
19
|
+
* `excludedLayers` are removed and `onStyleReady` is called (it sets the plugins up again). The
|
|
20
|
+
* map's first style is not announced: the plugin host already waits for it.
|
|
21
|
+
*/
|
|
22
|
+
export declare class BasemapState {
|
|
23
|
+
#private;
|
|
24
|
+
constructor(config: BasemapConfig | undefined);
|
|
25
|
+
/** The selected basemap id. Reactive. */
|
|
26
|
+
get current(): string;
|
|
27
|
+
/** Unknown ids are ignored. While no map is attached, only `current` changes. */
|
|
28
|
+
select(id: string): void;
|
|
29
|
+
/**
|
|
30
|
+
* For MapView only (through the map context's `attach`): uses `gl` from now on, which must
|
|
31
|
+
* already show (or be loading) the style of `current`. `onStyleChange` runs right before each
|
|
32
|
+
* `setStyle`, `onStyleReady` once that style has loaded. Reads `current` untracked, so calling
|
|
33
|
+
* this in an effect doesn't make it depend on it.
|
|
34
|
+
*/
|
|
35
|
+
attach(gl: GlMapLike, onStyleReady: () => void, onStyleChange?: () => void): void;
|
|
36
|
+
/** For MapView only (through the map context's `detach`): stops using the GL map. */
|
|
37
|
+
detach(): void;
|
|
38
|
+
}
|
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
import { untrack } from "svelte";
|
|
2
|
+
/** The first of these means the style of a map just created is ready. */
|
|
3
|
+
const STYLE_READY_EVENTS = ["style.load", "idle"];
|
|
4
|
+
/**
|
|
5
|
+
* The map's current basemap, and switching it on a GL map.
|
|
6
|
+
*
|
|
7
|
+
* The GL map is created with the style of `current` (the map's creator does that), so `attach`
|
|
8
|
+
* calls `setStyle` for nothing. Later `select` calls load the new style. A newer `select`
|
|
9
|
+
* supersedes one still loading. If the style document fails, the map goes back to the last style
|
|
10
|
+
* that loaded and `current` reverts; if that fails too, the map stays unstyled until the next
|
|
11
|
+
* `select`. Right before each `setStyle`, `onStyleChange` is called (it tears the plugins down,
|
|
12
|
+
* so nothing touches the old style while the new one loads). After each successful load,
|
|
13
|
+
* `excludedLayers` are removed and `onStyleReady` is called (it sets the plugins up again). The
|
|
14
|
+
* map's first style is not announced: the plugin host already waits for it.
|
|
15
|
+
*/
|
|
16
|
+
export class BasemapState {
|
|
17
|
+
#current = $state("");
|
|
18
|
+
#config;
|
|
19
|
+
#gl = null;
|
|
20
|
+
#onStyleReady = null;
|
|
21
|
+
#onStyleChange = null;
|
|
22
|
+
/** The id last handed to `setStyle` (loaded or loading); null once a load failed with no fallback. */
|
|
23
|
+
#applied = null;
|
|
24
|
+
/** The id the map last finished loading, which a failed change falls back to. */
|
|
25
|
+
#loaded = "";
|
|
26
|
+
#stopWaiting = null;
|
|
27
|
+
constructor(config) {
|
|
28
|
+
this.#config = config;
|
|
29
|
+
this.#current = config?.defaultId ?? "";
|
|
30
|
+
}
|
|
31
|
+
/** The selected basemap id. Reactive. */
|
|
32
|
+
get current() {
|
|
33
|
+
return this.#current;
|
|
34
|
+
}
|
|
35
|
+
/** Unknown ids are ignored. While no map is attached, only `current` changes. */
|
|
36
|
+
select(id) {
|
|
37
|
+
if (!this.#entry(id))
|
|
38
|
+
return;
|
|
39
|
+
this.#current = id;
|
|
40
|
+
if (!this.#gl || id === this.#applied)
|
|
41
|
+
return;
|
|
42
|
+
this.#load(id);
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* For MapView only (through the map context's `attach`): uses `gl` from now on, which must
|
|
46
|
+
* already show (or be loading) the style of `current`. `onStyleChange` runs right before each
|
|
47
|
+
* `setStyle`, `onStyleReady` once that style has loaded. Reads `current` untracked, so calling
|
|
48
|
+
* this in an effect doesn't make it depend on it.
|
|
49
|
+
*/
|
|
50
|
+
attach(gl, onStyleReady, onStyleChange) {
|
|
51
|
+
if (this.#gl === gl)
|
|
52
|
+
return;
|
|
53
|
+
if (this.#gl)
|
|
54
|
+
this.detach();
|
|
55
|
+
this.#gl = gl;
|
|
56
|
+
this.#onStyleReady = onStyleReady;
|
|
57
|
+
this.#onStyleChange = onStyleChange ?? null;
|
|
58
|
+
const id = untrack(() => this.#current);
|
|
59
|
+
this.#applied = id;
|
|
60
|
+
this.#loaded = id;
|
|
61
|
+
// The first style: drop the excluded layers, but leave the plugin host to set itself up.
|
|
62
|
+
this.#whenReady(gl, () => this.#removeExcluded(gl));
|
|
63
|
+
}
|
|
64
|
+
/** For MapView only (through the map context's `detach`): stops using the GL map. */
|
|
65
|
+
detach() {
|
|
66
|
+
this.#stopWaiting?.();
|
|
67
|
+
this.#gl = null;
|
|
68
|
+
this.#onStyleReady = null;
|
|
69
|
+
this.#onStyleChange = null;
|
|
70
|
+
}
|
|
71
|
+
#entry(id) {
|
|
72
|
+
return this.#config?.styles.find((s) => s.id === id);
|
|
73
|
+
}
|
|
74
|
+
/** Runs `fn` once `gl`'s style is ready, at once if it is. Cancelled by `#stopWaiting`. */
|
|
75
|
+
#whenReady(gl, fn) {
|
|
76
|
+
this.#stopWaiting?.();
|
|
77
|
+
if (gl.isStyleLoaded()) {
|
|
78
|
+
fn();
|
|
79
|
+
return;
|
|
80
|
+
}
|
|
81
|
+
const listener = () => {
|
|
82
|
+
stop();
|
|
83
|
+
fn();
|
|
84
|
+
};
|
|
85
|
+
const stop = () => {
|
|
86
|
+
for (const type of STYLE_READY_EVENTS)
|
|
87
|
+
gl.off(type, listener);
|
|
88
|
+
if (this.#stopWaiting === stop)
|
|
89
|
+
this.#stopWaiting = null;
|
|
90
|
+
};
|
|
91
|
+
this.#stopWaiting = stop;
|
|
92
|
+
for (const type of STYLE_READY_EVENTS)
|
|
93
|
+
gl.on(type, listener);
|
|
94
|
+
}
|
|
95
|
+
#removeExcluded(gl) {
|
|
96
|
+
for (const layerId of this.#config?.excludedLayers ?? []) {
|
|
97
|
+
try {
|
|
98
|
+
if (gl.getLayer(layerId))
|
|
99
|
+
gl.removeLayer(layerId);
|
|
100
|
+
}
|
|
101
|
+
catch (error) {
|
|
102
|
+
console.error(`map-sdk: removing basemap layer "${layerId}" failed`, error);
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
#load(id) {
|
|
107
|
+
const gl = this.#gl;
|
|
108
|
+
const entry = this.#entry(id);
|
|
109
|
+
if (!gl || !entry)
|
|
110
|
+
return;
|
|
111
|
+
// A newer change supersedes one still in flight.
|
|
112
|
+
this.#stopWaiting?.();
|
|
113
|
+
this.#applied = id;
|
|
114
|
+
const onLoad = () => {
|
|
115
|
+
stop();
|
|
116
|
+
this.#loaded = id;
|
|
117
|
+
this.#removeExcluded(gl);
|
|
118
|
+
this.#onStyleReady?.();
|
|
119
|
+
};
|
|
120
|
+
// "error" also fires for tiles, sprites and glyphs; only the style document failing means
|
|
121
|
+
// the change failed. That is matched by URL, so a style given as an object (not a URL
|
|
122
|
+
// string) can't be told apart and is never treated as failed.
|
|
123
|
+
const url = typeof entry.style === "string" ? entry.style : null;
|
|
124
|
+
const onError = (event) => {
|
|
125
|
+
if (url === null || !isRequestFor(event.error, url))
|
|
126
|
+
return;
|
|
127
|
+
stop();
|
|
128
|
+
this.#recover(id);
|
|
129
|
+
};
|
|
130
|
+
const stop = () => {
|
|
131
|
+
gl.off("style.load", onLoad);
|
|
132
|
+
gl.off("error", onError);
|
|
133
|
+
if (this.#stopWaiting === stop)
|
|
134
|
+
this.#stopWaiting = null;
|
|
135
|
+
};
|
|
136
|
+
this.#stopWaiting = stop;
|
|
137
|
+
gl.on("style.load", onLoad);
|
|
138
|
+
gl.on("error", onError);
|
|
139
|
+
this.#onStyleChange?.();
|
|
140
|
+
// No diffing: a diff keeps the plugins' sources and layers in some cases and not others.
|
|
141
|
+
gl.setStyle(entry.style, { diff: false });
|
|
142
|
+
}
|
|
143
|
+
/**
|
|
144
|
+
* A style that fails to load leaves the map with no style, so go back to the last one that
|
|
145
|
+
* loaded and make `current` say so. When that one fails too there is nothing to draw on, and
|
|
146
|
+
* the next `select` starts a fresh attempt.
|
|
147
|
+
*/
|
|
148
|
+
#recover(failed) {
|
|
149
|
+
if (failed === this.#loaded) {
|
|
150
|
+
this.#applied = null;
|
|
151
|
+
return;
|
|
152
|
+
}
|
|
153
|
+
this.#current = this.#loaded;
|
|
154
|
+
this.#load(this.#loaded);
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
/** Whether a map "error" event's error is a failed request for `url`, ignoring the query. */
|
|
158
|
+
function isRequestFor(error, url) {
|
|
159
|
+
const failed = error?.url;
|
|
160
|
+
if (typeof failed !== "string")
|
|
161
|
+
return false;
|
|
162
|
+
return failed.split("?")[0] === url.split("?")[0];
|
|
163
|
+
}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { MapContext } from "./create-map.svelte.js";
|
|
2
|
+
/** Provides `ctx` to this component's descendants (MapView does this). */
|
|
3
|
+
export declare function setMapContext(ctx: MapContext): void;
|
|
4
|
+
/** The nearest `MapView`'s map. Throws outside one. */
|
|
5
|
+
export declare function getMapContext(): MapContext;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { getContext, setContext } from "svelte";
|
|
2
|
+
const KEY = Symbol("map-sdk:map");
|
|
3
|
+
/** Provides `ctx` to this component's descendants (MapView does this). */
|
|
4
|
+
export function setMapContext(ctx) {
|
|
5
|
+
setContext(KEY, ctx);
|
|
6
|
+
}
|
|
7
|
+
/** The nearest `MapView`'s map. Throws outside one. */
|
|
8
|
+
export function getMapContext() {
|
|
9
|
+
const ctx = getContext(KEY);
|
|
10
|
+
if (!ctx)
|
|
11
|
+
throw new Error("map-sdk: no map context; use this inside a MapView");
|
|
12
|
+
return ctx;
|
|
13
|
+
}
|
|
@@ -0,0 +1,274 @@
|
|
|
1
|
+
import { type FormatProvider } from "../data/format.js";
|
|
2
|
+
import { type MessageProvider } from "../data/messages.js";
|
|
3
|
+
import { type MetadataProvider } from "../data/metadata.js";
|
|
4
|
+
import type { FeatureRef, SelectionMode, SpatialSelection } from "../data/types.js";
|
|
5
|
+
import { BasemapState, type BasemapConfig } from "./basemap.svelte.js";
|
|
6
|
+
import type { GlMapLike } from "./gl.js";
|
|
7
|
+
import { type Hovered } from "./interactions.svelte.js";
|
|
8
|
+
import type { FeatureHit, FeatureListItem, MapPlugin } from "./plugin.js";
|
|
9
|
+
export interface CameraState {
|
|
10
|
+
center: [number, number];
|
|
11
|
+
zoom: number;
|
|
12
|
+
bearing: number;
|
|
13
|
+
pitch: number;
|
|
14
|
+
}
|
|
15
|
+
export interface Bounds {
|
|
16
|
+
west: number;
|
|
17
|
+
south: number;
|
|
18
|
+
east: number;
|
|
19
|
+
north: number;
|
|
20
|
+
}
|
|
21
|
+
export interface MapConfig {
|
|
22
|
+
maptilerKey: string;
|
|
23
|
+
basemaps?: BasemapConfig;
|
|
24
|
+
initialView?: CameraState;
|
|
25
|
+
cooperativeGestures?: boolean;
|
|
26
|
+
/** Default `"mercator"`. `"globe"` draws the map on a globe when zoomed out. */
|
|
27
|
+
projection?: "mercator" | "globe";
|
|
28
|
+
/**
|
|
29
|
+
* Default `false`. A preset (monitor-map uses `{ preset: "milkyway" }`) draws space behind a
|
|
30
|
+
* globe.
|
|
31
|
+
*/
|
|
32
|
+
space?: false | {
|
|
33
|
+
preset: string;
|
|
34
|
+
};
|
|
35
|
+
/**
|
|
36
|
+
* Default `true`: MapTiler's own default. `false` turns off MapTiler's telemetry (a usage
|
|
37
|
+
* report of the SDK version, the API key, and the session id, sent about 2 s after each map is
|
|
38
|
+
* created) before the GL map is created. It is a page-wide setting in MapTiler's SDK, so once
|
|
39
|
+
* one map turns it off it stays off for every map on the page. MapTiler's session id (`mtsid`)
|
|
40
|
+
* stays on: MapTiler bills SDK maps by session, and its tile cache needs sessions.
|
|
41
|
+
*/
|
|
42
|
+
telemetry?: boolean;
|
|
43
|
+
}
|
|
44
|
+
export interface CreateMapOptions {
|
|
45
|
+
config: MapConfig;
|
|
46
|
+
metadata?: MetadataProvider;
|
|
47
|
+
messages?: MessageProvider;
|
|
48
|
+
format?: FormatProvider;
|
|
49
|
+
}
|
|
50
|
+
export interface PluginOptions {
|
|
51
|
+
/**
|
|
52
|
+
* Draw the plugin just below the plugin with this id (which must be added already). Without
|
|
53
|
+
* it the plugin goes on top.
|
|
54
|
+
*/
|
|
55
|
+
before?: string;
|
|
56
|
+
selectionMode?: SelectionMode;
|
|
57
|
+
selection?: SpatialSelection | null;
|
|
58
|
+
onselectionchange?(sel: SpatialSelection | null): void;
|
|
59
|
+
/**
|
|
60
|
+
* `"click"` (default): today's rules (a click selects; Shift/⌘/Ctrl or a tap adds in
|
|
61
|
+
* `"multiple"` mode). `"modifier"`: a plain click or tap only pins the card (use it with
|
|
62
|
+
* `MapView`'s `card`), and Shift/⌘/Ctrl-click, or the list's Space or Shift+Enter, toggles the
|
|
63
|
+
* feature in the selection.
|
|
64
|
+
*/
|
|
65
|
+
pickWith?: "click" | "modifier";
|
|
66
|
+
/**
|
|
67
|
+
* Called before a user's pick (a click, a list pick, or the card's `toggle`) changes the
|
|
68
|
+
* selection, with the selection it would produce. `true` lets it through; a string refuses it
|
|
69
|
+
* and is the message the map shows (`MapContext.notice`). Not called for `setSelection` or the
|
|
70
|
+
* selection bar's Clear.
|
|
71
|
+
*/
|
|
72
|
+
canSelect?(next: SpatialSelection | null, ref: FeatureRef): true | string;
|
|
73
|
+
}
|
|
74
|
+
export type FeatureClickHandler = (e: {
|
|
75
|
+
pluginId: string;
|
|
76
|
+
ref: FeatureRef;
|
|
77
|
+
/**
|
|
78
|
+
* The click point. For a pick in the feature list, where the item's tooltip pins: its position,
|
|
79
|
+
* or for a shape whose label point is off-screen, a point of the shape in view.
|
|
80
|
+
*/
|
|
81
|
+
lngLat: [number, number];
|
|
82
|
+
}) => void;
|
|
83
|
+
/** Where a camera move ends up. `zoom` wins over `minZoom`. */
|
|
84
|
+
export interface CameraTarget {
|
|
85
|
+
center: [number, number];
|
|
86
|
+
zoom?: number;
|
|
87
|
+
/** Zoom to at least this: the move's zoom is `max(current zoom, minZoom)`. */
|
|
88
|
+
minZoom?: number;
|
|
89
|
+
}
|
|
90
|
+
/** A map's state and services, independent of whether a GL map currently exists. */
|
|
91
|
+
export interface MapContext {
|
|
92
|
+
readonly uid: string;
|
|
93
|
+
readonly config: Readonly<MapConfig>;
|
|
94
|
+
readonly metadata: MetadataProvider;
|
|
95
|
+
readonly messages: MessageProvider;
|
|
96
|
+
readonly format: FormatProvider;
|
|
97
|
+
/** Reactive; updated by MapView on moveend. */
|
|
98
|
+
readonly camera: CameraState;
|
|
99
|
+
/** Reactive; `null` until a map reports its bounds. */
|
|
100
|
+
readonly bounds: Bounds | null;
|
|
101
|
+
readonly basemap: BasemapState;
|
|
102
|
+
/**
|
|
103
|
+
* In draw order, bottom first: later plugins draw above earlier ones, and each plugin's layers
|
|
104
|
+
* stay together. Reactive.
|
|
105
|
+
*/
|
|
106
|
+
readonly plugins: readonly MapPlugin[];
|
|
107
|
+
/** Reactive. */
|
|
108
|
+
readonly attached: boolean;
|
|
109
|
+
/**
|
|
110
|
+
* Reactive. True once the attached map's style has loaded, the map has gone idle for the
|
|
111
|
+
* first time, and any queued plugin setups have run; false again on `detach()` and while a
|
|
112
|
+
* basemap switch reloads the style. Adding a plugin to a ready map leaves it true. A load
|
|
113
|
+
* screen can wait for it.
|
|
114
|
+
*/
|
|
115
|
+
readonly ready: boolean;
|
|
116
|
+
/**
|
|
117
|
+
* Reactive. The attached GL map, or `null`. For markers and popups only (see `maptilerMap`);
|
|
118
|
+
* never add sources or layers through it.
|
|
119
|
+
*/
|
|
120
|
+
readonly gl: GlMapLike | null;
|
|
121
|
+
/**
|
|
122
|
+
* @internal For `MapView` only; hosts never call it. Marks the attached map ready. Does
|
|
123
|
+
* nothing while detached.
|
|
124
|
+
*/
|
|
125
|
+
markReady(): void;
|
|
126
|
+
/**
|
|
127
|
+
* Adds a plugin on top, or below `options.before`. Throws if a plugin with the same id is
|
|
128
|
+
* already added, if `before` names no added plugin, if the same plugin object is set up on
|
|
129
|
+
* another map (create one plugin per map), or after `destroy()`.
|
|
130
|
+
*/
|
|
131
|
+
addPlugin(plugin: MapPlugin, options?: PluginOptions): void;
|
|
132
|
+
/**
|
|
133
|
+
* Moves a plugin and its layers to the top, or just below `options.before`. Does nothing for
|
|
134
|
+
* an unknown `id`; throws if `before` names no added plugin.
|
|
135
|
+
*/
|
|
136
|
+
movePlugin(id: string, options?: {
|
|
137
|
+
before?: string;
|
|
138
|
+
}): void;
|
|
139
|
+
/** Tears the plugin down and forgets its selection, mode, and `onselectionchange`. */
|
|
140
|
+
removePlugin(id: string): void;
|
|
141
|
+
/**
|
|
142
|
+
* Host → map. Kept as given, including ids not in any data. Does not call
|
|
143
|
+
* `onselectionchange`.
|
|
144
|
+
*/
|
|
145
|
+
setSelection(pluginId: string, selection: SpatialSelection | null): void;
|
|
146
|
+
/** Reactive. */
|
|
147
|
+
getSelection(pluginId: string): SpatialSelection | null;
|
|
148
|
+
setSelectionMode(pluginId: string, mode: SelectionMode): void;
|
|
149
|
+
/** Reactive. `"none"` for an unknown plugin. */
|
|
150
|
+
getSelectionMode(pluginId: string): SelectionMode;
|
|
151
|
+
/**
|
|
152
|
+
* Internal, for FeatureList: picks a listed feature exactly like a map click on it. Fires
|
|
153
|
+
* `featureclick`, then applies the same selection rules (`additive` adds or toggles in
|
|
154
|
+
* `multiple` mode), calling `onselectionchange` if the selection changes. An item that isn't
|
|
155
|
+
* selectable is still clicked but not selected. Does nothing for a refKey the plugin doesn't list.
|
|
156
|
+
*/
|
|
157
|
+
pickFromList(pluginId: string, refKey: string, additive: boolean): void;
|
|
158
|
+
/**
|
|
159
|
+
* Internal, for the selection bar: the user clears a plugin's selection. Calls the plugin's
|
|
160
|
+
* `onselectionchange(null)` when it had a selection; does nothing otherwise.
|
|
161
|
+
*/
|
|
162
|
+
clearSelection(pluginId: string): void;
|
|
163
|
+
/**
|
|
164
|
+
* Called for every feature click (the top hit), whatever the selection mode, before the
|
|
165
|
+
* selection changes. Returns an unsubscribe function.
|
|
166
|
+
*/
|
|
167
|
+
on(event: "featureclick", handler: FeatureClickHandler): () => void;
|
|
168
|
+
/** Hits under a canvas point, topmost first. `[]` while detached. */
|
|
169
|
+
featuresAt(point: {
|
|
170
|
+
x: number;
|
|
171
|
+
y: number;
|
|
172
|
+
}): FeatureHit[];
|
|
173
|
+
/**
|
|
174
|
+
* The hit for a feature-list element: the nearest `[data-mapsdk-ref]` ancestor (or the element
|
|
175
|
+
* itself), looked up in the plugins' `features()`: in the row's `data-mapsdk-plugin` plugin when
|
|
176
|
+
* it names one, else the first plugin listing the refKey. Only rows inside this map's own root count:
|
|
177
|
+
* the row's nearest `[data-mapsdk-map]` ancestor must carry this map's `uid`, which MapView
|
|
178
|
+
* sets on its container and FeatureList on its root. `null` otherwise.
|
|
179
|
+
*/
|
|
180
|
+
featureForElement(element: Element): FeatureHit | null;
|
|
181
|
+
/**
|
|
182
|
+
* The top feature under the pointer and where it is. Reactive, for the tooltip. Over a cluster
|
|
183
|
+
* bubble it is the bubble's own hit: a `{ kind: "feature", id: "cluster:…" }` ref no plugin
|
|
184
|
+
* lists, with the bubble's `properties`, never a feature beneath it.
|
|
185
|
+
*/
|
|
186
|
+
readonly hovered: Hovered | null;
|
|
187
|
+
/**
|
|
188
|
+
* Reactive. The feature whose reading card is pinned, and where, while `MapView`'s `card` is
|
|
189
|
+
* on; `null` otherwise. A click on a feature pins it (selection and `featureclick` are
|
|
190
|
+
* unchanged), focusing a feature-list row pins that row's feature, and a click on nothing (or
|
|
191
|
+
* on a cluster bubble or a feature without a hover card) unpins.
|
|
192
|
+
*/
|
|
193
|
+
readonly pinned: Hovered | null;
|
|
194
|
+
/** Reactive. The plugin's `pickWith`: `"click"` for an unknown plugin. */
|
|
195
|
+
getPickWith(pluginId: string): "click" | "modifier";
|
|
196
|
+
/**
|
|
197
|
+
* A user's toggle of `ref` (the card's Select/Remove): the modifier-click rule, with the
|
|
198
|
+
* plugin's `canSelect` and `onselectionchange`, in either `pickWith` mode.
|
|
199
|
+
*/
|
|
200
|
+
togglePick(pluginId: string, ref: FeatureRef): void;
|
|
201
|
+
/**
|
|
202
|
+
* Reactive. The latest refused pick's message; `id` grows with each refusal, so the same
|
|
203
|
+
* message twice is announced again. Cleared by the next pick, `clearNotice()`, and detach.
|
|
204
|
+
*/
|
|
205
|
+
readonly notice: {
|
|
206
|
+
message: string;
|
|
207
|
+
id: number;
|
|
208
|
+
} | null;
|
|
209
|
+
/** @internal For `PickNotice`: clears the notice. */
|
|
210
|
+
clearNotice(): void;
|
|
211
|
+
/** Closes the pinned card. Does nothing when nothing is pinned. */
|
|
212
|
+
unpin(): void;
|
|
213
|
+
/** @internal For `MapView` only: turns pinning on or off. Off also unpins. */
|
|
214
|
+
setCardEnabled(on: boolean): void;
|
|
215
|
+
/**
|
|
216
|
+
* Marks the feature focused and pans to it (no animation under reduced motion): the item in
|
|
217
|
+
* `pluginId`'s features when given, else the first plugin listing `refKey`. `null` clears the
|
|
218
|
+
* focus without moving the camera. Sets `focusedPluginId` to `pluginId` (or `null`). The pan
|
|
219
|
+
* centers the feature in the part of the map the feature list panel leaves clear.
|
|
220
|
+
*/
|
|
221
|
+
focusFeature(refKey: string | null, pluginId?: string): void;
|
|
222
|
+
/**
|
|
223
|
+
* Eases the camera to `target` (no animation under reduced motion). Does nothing while
|
|
224
|
+
* detached.
|
|
225
|
+
*/
|
|
226
|
+
easeTo(target: CameraTarget): void;
|
|
227
|
+
/** Like `easeTo`, with a flying animation. */
|
|
228
|
+
flyTo(target: CameraTarget): void;
|
|
229
|
+
/**
|
|
230
|
+
* Fits the camera to `bounds` (no animation under reduced motion). Does nothing while
|
|
231
|
+
* detached.
|
|
232
|
+
*/
|
|
233
|
+
fitBounds(bounds: Bounds, options?: {
|
|
234
|
+
padding?: number;
|
|
235
|
+
maxZoom?: number;
|
|
236
|
+
}): void;
|
|
237
|
+
/** Reactive. */
|
|
238
|
+
readonly focusedKey: string | null;
|
|
239
|
+
/** Reactive. The plugin `focusFeature` was given with `focusedKey`, or `null`. */
|
|
240
|
+
readonly focusedPluginId: string | null;
|
|
241
|
+
/**
|
|
242
|
+
* Reactive. Where the focused feature's tooltip pins, set by `focusFeature` (`null` without
|
|
243
|
+
* focus): its `lngLat`, or for a shape that overlaps the view with its `lngLat` off-screen, a
|
|
244
|
+
* point of the shape in the part of the view the list panel leaves clear. Fixed at focus
|
|
245
|
+
* time, so it stays on the feature if the map then moves.
|
|
246
|
+
*/
|
|
247
|
+
readonly focusedAnchor: [number, number] | null;
|
|
248
|
+
/**
|
|
249
|
+
* Where `item`'s tooltip pins in the current view, without moving the camera: its `lngLat`,
|
|
250
|
+
* or for a shape (`geometry`) with its `lngLat` off-screen, a point of the shape in view.
|
|
251
|
+
*/
|
|
252
|
+
anchorFor(item: FeatureListItem): [number, number];
|
|
253
|
+
/** For MapView only: uses `gl` from now on. */
|
|
254
|
+
attach(gl: GlMapLike): void;
|
|
255
|
+
/** For MapView only: stops using the current GL map. */
|
|
256
|
+
detach(): void;
|
|
257
|
+
/**
|
|
258
|
+
* For MapView only: how many pixels at the map's left or right edge (`side`, default left)
|
|
259
|
+
* the open feature list panel covers (0 when closed), which `focusFeature` pans clear of.
|
|
260
|
+
*/
|
|
261
|
+
setListInset(width: number, side?: "left" | "right"): void;
|
|
262
|
+
/** For MapView only: records the camera and bounds after a move. */
|
|
263
|
+
updateView(camera: CameraState, bounds: Bounds): void;
|
|
264
|
+
/**
|
|
265
|
+
* For MapView only: the host's theme changed, so plugins set up again and re-read the theme
|
|
266
|
+
* colors they bake into paint and images. Does nothing while detached. Sets plugins up
|
|
267
|
+
* synchronously, so never call it from inside an effect (see `PluginHost`).
|
|
268
|
+
*/
|
|
269
|
+
themeChanged(): void;
|
|
270
|
+
/** Detaches, removes every plugin, and drops handlers. The context can't be used after. */
|
|
271
|
+
destroy(): void;
|
|
272
|
+
}
|
|
273
|
+
/** Creates a map's state and services. `MapView` attaches a GL map to it. */
|
|
274
|
+
export declare function createMap(options: CreateMapOptions): MapContext;
|