@sjvair/map-sdk 0.1.0-beta.1 → 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/README.md +243 -17
- package/dist/core/create-map.svelte.d.ts +72 -5
- package/dist/core/create-map.svelte.js +229 -14
- package/dist/core/gl.d.ts +5 -0
- package/dist/core/interactions.svelte.d.ts +11 -3
- package/dist/core/interactions.svelte.js +128 -11
- package/dist/core/plugin-host.svelte.d.ts +30 -5
- package/dist/core/plugin-host.svelte.js +93 -14
- package/dist/core/plugin.d.ts +44 -2
- package/dist/core/shape-view.d.ts +27 -0
- package/dist/core/shape-view.js +323 -0
- package/dist/data/format.d.ts +1 -1
- package/dist/data/format.js +16 -3
- package/dist/data/messages/en.json +12 -2
- package/dist/data/selection.d.ts +6 -0
- package/dist/data/selection.js +21 -0
- package/dist/data/types.d.ts +5 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.js +1 -0
- package/dist/plugins/points.svelte.d.ts +14 -2
- package/dist/plugins/points.svelte.js +34 -5
- package/dist/plugins/shapes.svelte.d.ts +5 -0
- package/dist/plugins/shapes.svelte.js +20 -2
- package/dist/presets/FireTooltip.svelte +70 -0
- package/dist/presets/FireTooltip.svelte.d.ts +13 -0
- package/dist/presets/MonitorClusterTooltip.svelte +21 -2
- package/dist/presets/cluster-area.d.ts +13 -0
- package/dist/presets/cluster-area.js +34 -0
- package/dist/presets/hms-fire.d.ts +11 -7
- package/dist/presets/hms-fire.js +16 -17
- package/dist/presets/hms-smoke.d.ts +2 -1
- package/dist/presets/hms-smoke.js +4 -2
- package/dist/stores/hms-stores.svelte.d.ts +6 -3
- package/dist/stores/hms-stores.svelte.js +4 -4
- package/dist/ui/FeatureList.svelte +17 -17
- package/dist/ui/Legend.svelte +58 -16
- package/dist/ui/Legend.svelte.d.ts +9 -0
- package/dist/ui/MapTooltip.svelte +253 -14
- package/dist/ui/MapTooltip.svelte.d.ts +9 -0
- package/dist/ui/PickNotice.svelte +56 -0
- package/dist/ui/PickNotice.svelte.d.ts +7 -0
- package/dist/ui/TooltipItem.svelte +12 -12
- package/dist/ui/card.d.ts +29 -0
- package/dist/ui/card.js +1 -0
- package/dist/ui/feature-list.d.ts +17 -2
- package/dist/ui/feature-list.js +45 -10
- package/dist/ui/value-format.d.ts +3 -2
- package/dist/ui/value-format.js +9 -2
- package/dist/view/MapView.svelte +72 -2
- package/dist/view/MapView.svelte.d.ts +8 -0
- package/dist/view/create-gl-map.js +4 -0
- package/package.json +2 -1
|
@@ -7,12 +7,23 @@ export interface PluginHostOptions {
|
|
|
7
7
|
router: InteractionRouter;
|
|
8
8
|
/** Reactive: read inside a plugin's effects. */
|
|
9
9
|
selectedKeys(pluginId: string): ReadonlySet<string>;
|
|
10
|
+
/**
|
|
11
|
+
* Called after each queued setup run finishes (also when it had nothing to do), never after a
|
|
12
|
+
* synchronous one.
|
|
13
|
+
*/
|
|
14
|
+
onSettled?: () => void;
|
|
10
15
|
}
|
|
11
16
|
/**
|
|
12
17
|
* Runs plugins against a GL map. Plugins are set up only when the map's style is loaded, and
|
|
13
18
|
* everything they add through their `PluginContext` is removed on teardown, whatever their own
|
|
14
19
|
* teardown does. The plugin list outlives any one GL map.
|
|
15
20
|
*
|
|
21
|
+
* Setup never runs inside the caller's code. When `add` or `attach` would set plugins up, they
|
|
22
|
+
* are queued and set up in one microtask, where no effect is active: Svelte cuts loose the
|
|
23
|
+
* `$effect.root`s created inside an effect when that effect re-runs, and their effects can stop
|
|
24
|
+
* (see docs/superpowers/specs/2026-11-07-plugin-setup-outside-effects-design.md). Setup on a
|
|
25
|
+
* style load or `restyle` comes from map events, not host code, and stays synchronous.
|
|
26
|
+
*
|
|
16
27
|
* Plugins draw in list order, later on top: each plugin's layers stay together, below the first
|
|
17
28
|
* layer of the next plugin in the list that has any.
|
|
18
29
|
*/
|
|
@@ -21,9 +32,12 @@ export declare class PluginHost {
|
|
|
21
32
|
constructor(opts: PluginHostOptions);
|
|
22
33
|
/** In draw order, bottom first. Reactive. */
|
|
23
34
|
get plugins(): readonly MapPlugin[];
|
|
35
|
+
/** True while a setup run is queued and has not started. Not reactive. */
|
|
36
|
+
get pending(): boolean;
|
|
24
37
|
/**
|
|
25
|
-
* Adds `plugin` on top, or just below the plugin `before` names.
|
|
26
|
-
*
|
|
38
|
+
* Adds `plugin` on top, or just below the plugin `before` names. It is in `plugins` at once;
|
|
39
|
+
* on a live map its setup runs in a microtask. Throws when the same plugin object is set up on
|
|
40
|
+
* another map at the moment (one plugin object per map).
|
|
27
41
|
*/
|
|
28
42
|
add(plugin: MapPlugin, before?: string): void;
|
|
29
43
|
/**
|
|
@@ -32,15 +46,26 @@ export declare class PluginHost {
|
|
|
32
46
|
*/
|
|
33
47
|
move(id: string, before?: string): void;
|
|
34
48
|
remove(id: string): void;
|
|
35
|
-
/**
|
|
49
|
+
/**
|
|
50
|
+
* Uses `gl` from now on, setting up every plugin once its style is loaded (in a microtask when
|
|
51
|
+
* it already is).
|
|
52
|
+
*/
|
|
36
53
|
attach(gl: GlMapLike): void;
|
|
37
54
|
/**
|
|
38
55
|
* Tears every plugin down and stops waiting for a style, before the map's style is replaced:
|
|
39
56
|
* nothing may touch a style on its way out. `restyle` sets them up again.
|
|
40
57
|
*/
|
|
41
58
|
suspend(): void;
|
|
42
|
-
/**
|
|
43
|
-
|
|
59
|
+
/**
|
|
60
|
+
* Tears down and sets up every plugin again (after a basemap or theme change), once the style
|
|
61
|
+
* loads. Pass `styleLoaded` from a `style.load` listener: `isStyleLoaded()` stays false there
|
|
62
|
+
* until every tile has loaded, and `style.load` has already fired, so waiting would last until
|
|
63
|
+
* `idle`. A live host's style is loaded too (`suspend` comes before every `setStyle`), so a theme
|
|
64
|
+
* change sets up at once as well. On a loaded style the setup is synchronous, so only map events
|
|
65
|
+
* and theme watching call this, never code inside an effect: roots created there can stop (see
|
|
66
|
+
* the class comment).
|
|
67
|
+
*/
|
|
68
|
+
restyle(styleLoaded?: boolean): void;
|
|
44
69
|
/** Tears down every plugin. The gl is not touched after this returns. */
|
|
45
70
|
detach(): void;
|
|
46
71
|
}
|
|
@@ -19,6 +19,12 @@ function ownershipError(plugin) {
|
|
|
19
19
|
* everything they add through their `PluginContext` is removed on teardown, whatever their own
|
|
20
20
|
* teardown does. The plugin list outlives any one GL map.
|
|
21
21
|
*
|
|
22
|
+
* Setup never runs inside the caller's code. When `add` or `attach` would set plugins up, they
|
|
23
|
+
* are queued and set up in one microtask, where no effect is active: Svelte cuts loose the
|
|
24
|
+
* `$effect.root`s created inside an effect when that effect re-runs, and their effects can stop
|
|
25
|
+
* (see docs/superpowers/specs/2026-11-07-plugin-setup-outside-effects-design.md). Setup on a
|
|
26
|
+
* style load or `restyle` comes from map events, not host code, and stays synchronous.
|
|
27
|
+
*
|
|
22
28
|
* Plugins draw in list order, later on top: each plugin's layers stay together, below the first
|
|
23
29
|
* layer of the next plugin in the list that has any.
|
|
24
30
|
*/
|
|
@@ -36,6 +42,8 @@ export class PluginHost {
|
|
|
36
42
|
* a style that already loaded while `isStyleLoaded()` is false because sources are loading.
|
|
37
43
|
*/
|
|
38
44
|
#onStyleLoad = null;
|
|
45
|
+
/** True from scheduling a queued setup run until it starts. */
|
|
46
|
+
#setupQueued = false;
|
|
39
47
|
constructor(opts) {
|
|
40
48
|
this.#opts = opts;
|
|
41
49
|
}
|
|
@@ -43,6 +51,10 @@ export class PluginHost {
|
|
|
43
51
|
get plugins() {
|
|
44
52
|
return this.#plugins;
|
|
45
53
|
}
|
|
54
|
+
/** True while a setup run is queued and has not started. Not reactive. */
|
|
55
|
+
get pending() {
|
|
56
|
+
return this.#setupQueued;
|
|
57
|
+
}
|
|
46
58
|
/**
|
|
47
59
|
* The host's own reads are untracked, so calling `add`, `attach`, etc. from inside an effect
|
|
48
60
|
* doesn't make that effect depend on the plugin list.
|
|
@@ -51,8 +63,9 @@ export class PluginHost {
|
|
|
51
63
|
return untrack(() => this.#plugins);
|
|
52
64
|
}
|
|
53
65
|
/**
|
|
54
|
-
* Adds `plugin` on top, or just below the plugin `before` names.
|
|
55
|
-
*
|
|
66
|
+
* Adds `plugin` on top, or just below the plugin `before` names. It is in `plugins` at once;
|
|
67
|
+
* on a live map its setup runs in a microtask. Throws when the same plugin object is set up on
|
|
68
|
+
* another map at the moment (one plugin object per map).
|
|
56
69
|
*/
|
|
57
70
|
add(plugin, before) {
|
|
58
71
|
if (this.#list.some((p) => p.id === plugin.id)) {
|
|
@@ -62,7 +75,7 @@ export class PluginHost {
|
|
|
62
75
|
throw ownershipError(plugin);
|
|
63
76
|
this.#plugins = this.#inserted(this.#list, plugin, before);
|
|
64
77
|
if (this.#live)
|
|
65
|
-
this.#
|
|
78
|
+
this.#queueSetup();
|
|
66
79
|
}
|
|
67
80
|
/**
|
|
68
81
|
* Moves a plugin to the top, or just below the plugin `before` names, with its layers. Does
|
|
@@ -120,16 +133,22 @@ export class PluginHost {
|
|
|
120
133
|
if (!this.#list.some((p) => p.id === id))
|
|
121
134
|
return;
|
|
122
135
|
this.#teardown(id);
|
|
136
|
+
const plugin = this.#list.find((p) => p.id === id);
|
|
137
|
+
if (plugin)
|
|
138
|
+
this.#release(plugin);
|
|
123
139
|
this.#plugins = this.#list.filter((p) => p.id !== id);
|
|
124
140
|
}
|
|
125
|
-
/**
|
|
141
|
+
/**
|
|
142
|
+
* Uses `gl` from now on, setting up every plugin once its style is loaded (in a microtask when
|
|
143
|
+
* it already is).
|
|
144
|
+
*/
|
|
126
145
|
attach(gl) {
|
|
127
146
|
if (this.#gl === gl)
|
|
128
147
|
return;
|
|
129
148
|
if (this.#gl)
|
|
130
149
|
this.detach();
|
|
131
150
|
this.#gl = gl;
|
|
132
|
-
this.#whenStyleLoaded();
|
|
151
|
+
this.#whenStyleLoaded(false);
|
|
133
152
|
}
|
|
134
153
|
/**
|
|
135
154
|
* Tears every plugin down and stops waiting for a style, before the map's style is replaced:
|
|
@@ -141,12 +160,27 @@ export class PluginHost {
|
|
|
141
160
|
this.#cancelStyleWait();
|
|
142
161
|
this.#teardownAll();
|
|
143
162
|
}
|
|
144
|
-
/**
|
|
145
|
-
|
|
163
|
+
/**
|
|
164
|
+
* Tears down and sets up every plugin again (after a basemap or theme change), once the style
|
|
165
|
+
* loads. Pass `styleLoaded` from a `style.load` listener: `isStyleLoaded()` stays false there
|
|
166
|
+
* until every tile has loaded, and `style.load` has already fired, so waiting would last until
|
|
167
|
+
* `idle`. A live host's style is loaded too (`suspend` comes before every `setStyle`), so a theme
|
|
168
|
+
* change sets up at once as well. On a loaded style the setup is synchronous, so only map events
|
|
169
|
+
* and theme watching call this, never code inside an effect: roots created there can stop (see
|
|
170
|
+
* the class comment).
|
|
171
|
+
*/
|
|
172
|
+
restyle(styleLoaded = false) {
|
|
146
173
|
if (!this.#gl)
|
|
147
174
|
return;
|
|
175
|
+
const loaded = styleLoaded || this.#live;
|
|
148
176
|
this.#teardownAll();
|
|
149
|
-
|
|
177
|
+
if (loaded) {
|
|
178
|
+
this.#cancelStyleWait();
|
|
179
|
+
this.#setupAll();
|
|
180
|
+
}
|
|
181
|
+
else {
|
|
182
|
+
this.#whenStyleLoaded(true);
|
|
183
|
+
}
|
|
150
184
|
}
|
|
151
185
|
/** Tears down every plugin. The gl is not touched after this returns. */
|
|
152
186
|
detach() {
|
|
@@ -157,11 +191,22 @@ export class PluginHost {
|
|
|
157
191
|
this.#teardownAll();
|
|
158
192
|
this.#gl = null;
|
|
159
193
|
}
|
|
160
|
-
|
|
194
|
+
/**
|
|
195
|
+
* Sets every plugin up once the style is loaded. On a style that already is, `now` sets them up
|
|
196
|
+
* synchronously (only for callers that never run inside an effect); otherwise they are queued.
|
|
197
|
+
*/
|
|
198
|
+
#whenStyleLoaded(now) {
|
|
161
199
|
const gl = this.#gl;
|
|
162
200
|
this.#cancelStyleWait();
|
|
163
201
|
if (gl.isStyleLoaded()) {
|
|
164
|
-
|
|
202
|
+
if (now) {
|
|
203
|
+
this.#setupAll();
|
|
204
|
+
}
|
|
205
|
+
else {
|
|
206
|
+
// Live already, so an `add` before the microtask joins the queued run.
|
|
207
|
+
this.#live = true;
|
|
208
|
+
this.#queueSetup();
|
|
209
|
+
}
|
|
165
210
|
return;
|
|
166
211
|
}
|
|
167
212
|
const onStyleLoad = () => {
|
|
@@ -175,6 +220,37 @@ export class PluginHost {
|
|
|
175
220
|
for (const type of STYLE_READY_EVENTS)
|
|
176
221
|
gl.on(type, onStyleLoad);
|
|
177
222
|
}
|
|
223
|
+
/**
|
|
224
|
+
* Sets every plugin that isn't running up in a microtask, on whichever gl is live by then.
|
|
225
|
+
* Detach, suspend, and restyle clear `#live`, and only a loaded current gl sets it again, so
|
|
226
|
+
* the run never touches a gl that left. One run covers every request made before it starts.
|
|
227
|
+
*/
|
|
228
|
+
#queueSetup() {
|
|
229
|
+
// Claim the queued plugins now, so another map can't take one before the run.
|
|
230
|
+
for (const plugin of this.#list)
|
|
231
|
+
this.#claim(plugin);
|
|
232
|
+
if (this.#setupQueued)
|
|
233
|
+
return;
|
|
234
|
+
this.#setupQueued = true;
|
|
235
|
+
queueMicrotask(() => {
|
|
236
|
+
this.#setupQueued = false;
|
|
237
|
+
if (this.#live)
|
|
238
|
+
this.#setupAll();
|
|
239
|
+
this.#opts.onSettled?.();
|
|
240
|
+
});
|
|
241
|
+
}
|
|
242
|
+
/** Marks `plugin` as this host's, unless another map holds it. */
|
|
243
|
+
#claim(plugin) {
|
|
244
|
+
if (!ownedElsewhere(plugin, this) && Object.isExtensible(plugin)) {
|
|
245
|
+
plugin[OWNER] = this;
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
/** Releases a plugin this host claimed but isn't running (queued, then removed or left). */
|
|
249
|
+
#release(plugin) {
|
|
250
|
+
const owned = plugin;
|
|
251
|
+
if (owned[OWNER] === this && !this.#running.has(plugin.id))
|
|
252
|
+
delete owned[OWNER];
|
|
253
|
+
}
|
|
178
254
|
#cancelStyleWait() {
|
|
179
255
|
const listener = this.#onStyleLoad;
|
|
180
256
|
if (listener && this.#gl) {
|
|
@@ -202,8 +278,10 @@ export class PluginHost {
|
|
|
202
278
|
}
|
|
203
279
|
#teardownAll() {
|
|
204
280
|
this.#live = false;
|
|
205
|
-
for (const plugin of this.#list)
|
|
281
|
+
for (const plugin of this.#list) {
|
|
206
282
|
this.#teardown(plugin.id);
|
|
283
|
+
this.#release(plugin);
|
|
284
|
+
}
|
|
207
285
|
}
|
|
208
286
|
#setup(plugin) {
|
|
209
287
|
const gl = this.#gl;
|
|
@@ -225,7 +303,8 @@ export class PluginHost {
|
|
|
225
303
|
const ctx = this.#context(plugin.id, running);
|
|
226
304
|
let teardown;
|
|
227
305
|
try {
|
|
228
|
-
// Untracked
|
|
306
|
+
// Untracked, in case a plugin's setup reads state (setup runs from a microtask or a map
|
|
307
|
+
// event, never inside the caller's effect).
|
|
229
308
|
teardown = untrack(() => plugin.setup(ctx));
|
|
230
309
|
}
|
|
231
310
|
catch (error) {
|
|
@@ -338,12 +417,12 @@ export class PluginHost {
|
|
|
338
417
|
interactive(layerIds, toHit) {
|
|
339
418
|
if (running.dead)
|
|
340
419
|
return;
|
|
341
|
-
running.unregisters.push(router.register(pluginId, layerIds, toHit, running.plugin.hoverPriority ?? 0));
|
|
420
|
+
running.unregisters.push(router.register(pluginId, layerIds, toHit, running.plugin.hoverPriority ?? 0, running.plugin.hoverable ?? true));
|
|
342
421
|
},
|
|
343
422
|
blocking(layerIds, toHover, onClick) {
|
|
344
423
|
if (running.dead)
|
|
345
424
|
return;
|
|
346
|
-
running.unregisters.push(router.registerBlocking(pluginId, layerIds, toHover, onClick, running.plugin.hoverPriority ?? 0));
|
|
425
|
+
running.unregisters.push(router.registerBlocking(pluginId, layerIds, toHover, onClick, running.plugin.hoverPriority ?? 0, running.plugin.hoverable ?? true));
|
|
347
426
|
},
|
|
348
427
|
on(type, layerId, listener) {
|
|
349
428
|
if (running.dead)
|
package/dist/core/plugin.d.ts
CHANGED
|
@@ -46,8 +46,33 @@ export interface FeatureListItem {
|
|
|
46
46
|
* metadata's display hint). Without it the value is formatted as given.
|
|
47
47
|
*/
|
|
48
48
|
precision?: number;
|
|
49
|
+
/**
|
|
50
|
+
* Cut a numeric `value` off at `precision` instead of rounding it, so the number never reads
|
|
51
|
+
* as the next level (e.g. fire power: 9.96 MW shows "9.9", not "10.0", beside "<10"). Default
|
|
52
|
+
* false.
|
|
53
|
+
*/
|
|
54
|
+
truncate?: boolean;
|
|
49
55
|
lngLat: [number, number];
|
|
56
|
+
/**
|
|
57
|
+
* The feature's shape. When given, the item is in view (the feature list, the view summary)
|
|
58
|
+
* when the shape overlaps the view, not only when `lngLat` is inside it, and focusing or
|
|
59
|
+
* hovering it while `lngLat` is off-screen pins its tooltip at a point of the shape in view
|
|
60
|
+
* (focus then leaves the camera where it is).
|
|
61
|
+
*/
|
|
62
|
+
geometry?: Geometry;
|
|
63
|
+
/**
|
|
64
|
+
* `geometry`'s bounding box, `[west, south, east, north]` (`geometryBbox`). Optional; computed
|
|
65
|
+
* from `geometry` when missing. A plugin listing many shapes should measure it once per data
|
|
66
|
+
* load, since the list and summary test every item on every move.
|
|
67
|
+
*/
|
|
68
|
+
bbox?: [number, number, number, number];
|
|
50
69
|
selectable: boolean;
|
|
70
|
+
/**
|
|
71
|
+
* A short text about a feature with no level (e.g. "Level 2 charger"), shown where its level
|
|
72
|
+
* would be: in the feature list, its row's accessible name, and the generic tooltip. Ignored
|
|
73
|
+
* when the item has a level.
|
|
74
|
+
*/
|
|
75
|
+
detail?: string;
|
|
51
76
|
}
|
|
52
77
|
export type LegendData = {
|
|
53
78
|
pluginId: string;
|
|
@@ -65,7 +90,17 @@ export type LegendData = {
|
|
|
65
90
|
};
|
|
66
91
|
export interface ClickEvent {
|
|
67
92
|
hits: FeatureHit[];
|
|
93
|
+
/** `modifier || touch`: today's "add to the selection" in multiple mode. */
|
|
68
94
|
additive: boolean;
|
|
95
|
+
/** Shift, ⌘, or Ctrl was held. */
|
|
96
|
+
modifier: boolean;
|
|
97
|
+
/** A touch tap. */
|
|
98
|
+
touch: boolean;
|
|
99
|
+
/**
|
|
100
|
+
* A Shift-click that MapLibre's box zoom swallowed (it fires `boxzoomcancel` instead of
|
|
101
|
+
* `click`). Only `"modifier"` mode acts on it, so other maps behave as before.
|
|
102
|
+
*/
|
|
103
|
+
boxZoom?: boolean;
|
|
69
104
|
lngLat: [number, number];
|
|
70
105
|
}
|
|
71
106
|
/**
|
|
@@ -128,10 +163,17 @@ export interface MapPlugin {
|
|
|
128
163
|
selectable?: boolean;
|
|
129
164
|
/**
|
|
130
165
|
* Which plugin's feature the hover tooltip shows where several are under the pointer: the
|
|
131
|
-
* highest wins, the topmost on a tie. Default 0.
|
|
132
|
-
* beneath
|
|
166
|
+
* highest wins, the topmost on a tie. Default 0. Over a blocking layer (a cluster bubble), a
|
|
167
|
+
* feature beneath shows only if its plugin's priority is higher than the blocking plugin's.
|
|
168
|
+
* Clicks ignore this (topmost first), and a blocking layer on top still blocks them.
|
|
133
169
|
*/
|
|
134
170
|
hoverPriority?: number;
|
|
171
|
+
/**
|
|
172
|
+
* False: the plugin's features never take the hover (so no hover tooltip and no pointer
|
|
173
|
+
* cursor) and never hide a feature beneath from it, as if they weren't rendered. Clicks,
|
|
174
|
+
* `featuresAt`, and keyboard focus from the list are unchanged. Default true.
|
|
175
|
+
*/
|
|
176
|
+
hoverable?: boolean;
|
|
135
177
|
displayOptions?: Snippet;
|
|
136
178
|
/** Richer tooltip content for one of this plugin's features, below its name. */
|
|
137
179
|
tooltip?(item: FeatureListItem): Snippet | undefined;
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import type { Geometry } from "geojson";
|
|
2
|
+
import type { Bounds } from "./create-map.svelte.js";
|
|
3
|
+
/**
|
|
4
|
+
* Shapes against the view: a geometry's bounding box, whether it overlaps the view, and a point of
|
|
5
|
+
* it inside the view. Coordinates are planar lng/lat (as `labelPoint`); no antimeridian handling.
|
|
6
|
+
*/
|
|
7
|
+
/** `[west, south, east, north]`. */
|
|
8
|
+
export type Bbox = [west: number, south: number, east: number, north: number];
|
|
9
|
+
/** The geometry's bounding box, or `null` when it has no coordinates. */
|
|
10
|
+
export declare function geometryBbox(geometry: Geometry): Bbox | null;
|
|
11
|
+
/** Inside an outer ring and outside its holes, for any polygon of the geometry. */
|
|
12
|
+
export declare function containsPoint(geometry: Geometry, p: [number, number]): boolean;
|
|
13
|
+
/**
|
|
14
|
+
* Whether the item is in view: a shape (`geometry`) when it intersects `bounds` (bbox pre-check,
|
|
15
|
+
* then the exact test; holes count), anything else when its `lngLat` is inside. Edges included.
|
|
16
|
+
*/
|
|
17
|
+
export declare function intersectsBounds(item: {
|
|
18
|
+
lngLat: [number, number];
|
|
19
|
+
geometry?: Geometry;
|
|
20
|
+
bbox?: Bbox;
|
|
21
|
+
}, bounds: Bounds): boolean;
|
|
22
|
+
/**
|
|
23
|
+
* A point of the shape inside `view`: `center` when the shape contains it; otherwise a point well
|
|
24
|
+
* inside the shape's visible part (polygons: the largest clipped one, never in a hole; lines: the
|
|
25
|
+
* middle of the longest visible piece); `null` when nothing of it is visible.
|
|
26
|
+
*/
|
|
27
|
+
export declare function shapeAnchor(geometry: Geometry, view: Bounds, center: [number, number]): [number, number] | null;
|