@geolibre/core 3.0.0 → 3.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/dist/index.d.mts +1458 -540
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +5729 -3922
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.d.mts
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import "zustand";
|
|
2
|
+
import "zundo";
|
|
1
3
|
//#region src/cesium-imagery.d.ts
|
|
2
4
|
/**
|
|
3
5
|
* Maps the project's basemap onto imagery the Cesium globe can render.
|
|
@@ -113,42 +115,19 @@ export declare const CESIUM_BASEMAPS: readonly [{
|
|
|
113
115
|
readonly name: "OpenStreetMap";
|
|
114
116
|
readonly icon: "openStreetMap.png";
|
|
115
117
|
readonly category: "Other";
|
|
116
|
-
}, {
|
|
117
|
-
readonly id: "stadia-watercolor";
|
|
118
|
-
readonly name: "Stadia x Stamen Watercolor";
|
|
119
|
-
readonly icon: "stamenWatercolor.png";
|
|
120
|
-
readonly category: "Other";
|
|
121
|
-
readonly stadiaStyle: "stamen_watercolor";
|
|
122
|
-
readonly maximumLevel: 16;
|
|
123
|
-
readonly extension: "jpg";
|
|
124
|
-
}, {
|
|
125
|
-
readonly id: "stadia-toner";
|
|
126
|
-
readonly name: "Stadia x Stamen Toner";
|
|
127
|
-
readonly icon: "stamenToner.png";
|
|
128
|
-
readonly category: "Other";
|
|
129
|
-
readonly stadiaStyle: "stamen_toner";
|
|
130
|
-
readonly maximumLevel: 20;
|
|
131
|
-
readonly extension: "png";
|
|
132
|
-
}, {
|
|
133
|
-
readonly id: "stadia-smooth";
|
|
134
|
-
readonly name: "Stadia Alidade Smooth";
|
|
135
|
-
readonly icon: "stadiaAlidadeSmooth.png";
|
|
136
|
-
readonly category: "Other";
|
|
137
|
-
readonly stadiaStyle: "alidade_smooth";
|
|
138
|
-
readonly maximumLevel: 20;
|
|
139
|
-
readonly extension: "png";
|
|
140
|
-
}, {
|
|
141
|
-
readonly id: "stadia-dark";
|
|
142
|
-
readonly name: "Stadia Alidade Smooth Dark";
|
|
143
|
-
readonly icon: "stadiaAlidadeSmoothDark.png";
|
|
144
|
-
readonly category: "Other";
|
|
145
|
-
readonly stadiaStyle: "alidade_smooth_dark";
|
|
146
|
-
readonly maximumLevel: 20;
|
|
147
|
-
readonly extension: "png";
|
|
148
118
|
}];
|
|
149
119
|
export type CesiumBasemapId = (typeof CESIUM_BASEMAPS)[number]["id"];
|
|
150
120
|
export declare function normalizeCesiumBasemap(value: unknown): CesiumBasemapId;
|
|
151
|
-
/**
|
|
121
|
+
/**
|
|
122
|
+
* Missing credentials fall back to keyless imagery without changing the saved
|
|
123
|
+
* choice.
|
|
124
|
+
*
|
|
125
|
+
* The fallback is ArcGIS World Imagery rather than the project background: a
|
|
126
|
+
* globe wants to look like the Earth, and the project's own basemap is usually
|
|
127
|
+
* a vector street style whose raster analogue is mostly empty ocean from
|
|
128
|
+
* orbit. It needs no key, so the globe looks the same with or without an Ion
|
|
129
|
+
* token — only terrain and the Ion-only basemaps are lost.
|
|
130
|
+
*/
|
|
152
131
|
export declare function availableCesiumBasemap(value: unknown, hasIonToken: boolean): CesiumBasemapId;
|
|
153
132
|
/**
|
|
154
133
|
* What the globe should draw underneath the project's data layers.
|
|
@@ -177,8 +156,6 @@ export type CesiumBasemapImagery = {
|
|
|
177
156
|
kind: "xyz";
|
|
178
157
|
/** Tile template with `{z}`/`{x}`/`{y}` placeholders. */
|
|
179
158
|
template: string;
|
|
180
|
-
/** Credentials are resolved at render time, never embedded in the descriptor. */
|
|
181
|
-
apiKeyProvider?: "stadia";
|
|
182
159
|
/** Credit to show on the globe, as the HTML the 2D map already uses. */
|
|
183
160
|
attribution: string;
|
|
184
161
|
/** Max native zoom of the source, so the globe overzooms rather than 404s. */
|
|
@@ -1347,6 +1324,21 @@ export interface LayerPopupConfig {
|
|
|
1347
1324
|
bodyExpression?: string;
|
|
1348
1325
|
/** `false` drops the synthetic `id` row. Defaults to `true`. */
|
|
1349
1326
|
showFeatureId?: boolean;
|
|
1327
|
+
/**
|
|
1328
|
+
* Widest the click popup may grow, in CSS pixels. Unset keeps the default
|
|
1329
|
+
* (520px, or 420px for a popup carrying an image). Clamped to the range
|
|
1330
|
+
* `resolvePopupMaxWidth` enforces and always capped by the viewport, so a
|
|
1331
|
+
* value wider than the window still leaves the map usable.
|
|
1332
|
+
*/
|
|
1333
|
+
maxWidth?: number;
|
|
1334
|
+
/**
|
|
1335
|
+
* Tallest an `"image"` field's thumbnail may draw inside the popup, in CSS
|
|
1336
|
+
* pixels. Unset keeps the default (`min(50vh, 420px)`). Clamped by
|
|
1337
|
+
* `resolvePopupImageHeight`. Pair it with {@link maxWidth} for a
|
|
1338
|
+
* bigger picture: the thumbnail keeps its aspect ratio, so widening the
|
|
1339
|
+
* popup is what lets a landscape photo use the extra height.
|
|
1340
|
+
*/
|
|
1341
|
+
imageHeight?: number;
|
|
1350
1342
|
/**
|
|
1351
1343
|
* The fields to show and their order. An empty or absent list keeps today's
|
|
1352
1344
|
* behavior: every visible property, in the feature's own key order.
|
|
@@ -1646,7 +1638,9 @@ export interface AddTileLayerOptions {
|
|
|
1646
1638
|
tiles: string[];
|
|
1647
1639
|
/**
|
|
1648
1640
|
* Layer discriminator, controlling how the layer is labelled and (for WMS)
|
|
1649
|
-
* dev-server proxied. Defaults to `"xyz"`.
|
|
1641
|
+
* dev-server proxied. Defaults to `"xyz"`. The layer's `source.type` is
|
|
1642
|
+
* always `"raster"`, so any other value (such as `"vector-tiles"` from an
|
|
1643
|
+
* untyped JS caller) throws rather than persisting a mislabelled source.
|
|
1650
1644
|
*/
|
|
1651
1645
|
type?: "xyz" | "wms" | "wmts" | "raster";
|
|
1652
1646
|
/** Service or base URL recorded on the source for display and restore. */
|
|
@@ -1751,13 +1745,15 @@ export interface MapGridLayout {
|
|
|
1751
1745
|
* `"maplibre"` is the 2D MapLibre GL map that owns the app's plugin, styling,
|
|
1752
1746
|
* and deck.gl integrations. `"cesium"` is the 3D globe (see `CesiumCanvas`),
|
|
1753
1747
|
* which renders the same shared store state — camera, basemap, layers, group
|
|
1754
|
-
* effects — through CesiumJS.
|
|
1748
|
+
* effects — through CesiumJS. `"mapbox"` is Mapbox GL JS and `"arcgis"` the
|
|
1749
|
+
* ArcGIS Maps SDK for JavaScript, loaded from Esri's CDN at runtime (see
|
|
1750
|
+
* `ArcgisCanvas`); both draw the same store state through their own engines.
|
|
1755
1751
|
*
|
|
1756
1752
|
* Used both for secondary panes ({@link SecondaryMapView.viewKind}) and for the
|
|
1757
1753
|
* primary workspace ({@link GeoLibreProject.primaryRenderer}), so the two never
|
|
1758
1754
|
* drift apart.
|
|
1759
1755
|
*/
|
|
1760
|
-
export type MapRendererKind = "maplibre" | "cesium";
|
|
1756
|
+
export type MapRendererKind = "maplibre" | "cesium" | "mapbox" | "arcgis";
|
|
1761
1757
|
/**
|
|
1762
1758
|
* The engine that draws the primary map area when a project says nothing. The
|
|
1763
1759
|
* 2D map: it is the renderer every tool, plugin, and panel is wired to, so an
|
|
@@ -1925,6 +1921,16 @@ export interface MapPreferences {
|
|
|
1925
1921
|
showPointerElevation: boolean;
|
|
1926
1922
|
/** Whether the built-in 3D terrain control and terrain surface are enabled. */
|
|
1927
1923
|
terrainEnabled: boolean;
|
|
1924
|
+
/** Mapbox-only style. New projects use Streets; absent follows the shared basemap. */
|
|
1925
|
+
mapboxStyleUrl?: string;
|
|
1926
|
+
/**
|
|
1927
|
+
* ArcGIS-only basemap: an Esri basemap style id (`arcgis/streets`,
|
|
1928
|
+
* `arcgis/imagery`, `osm/standard`, ...). New projects use Streets. Absent
|
|
1929
|
+
* follows the shared basemap, translated to tiles the SDK can draw; the id
|
|
1930
|
+
* is also set aside when no ArcGIS API key is configured, since Esri's
|
|
1931
|
+
* basemap styles service requires one.
|
|
1932
|
+
*/
|
|
1933
|
+
arcgisBasemap?: string;
|
|
1928
1934
|
/** Cesium imagery override; absent follows the shared project basemap. */
|
|
1929
1935
|
cesiumBasemap?: CesiumBasemapId;
|
|
1930
1936
|
/**
|
|
@@ -1941,6 +1947,12 @@ export interface RuntimeEnvironmentVariable {
|
|
|
1941
1947
|
key: string;
|
|
1942
1948
|
value: string;
|
|
1943
1949
|
enabled: boolean;
|
|
1950
|
+
/**
|
|
1951
|
+
* Absent or `true`: the value is a secret (desktop keeps it in the OS
|
|
1952
|
+
* keychain; every egress removes it). `false`: an ordinary value saved in the
|
|
1953
|
+
* project and kept on share/export.
|
|
1954
|
+
*/
|
|
1955
|
+
secret?: boolean;
|
|
1944
1956
|
}
|
|
1945
1957
|
declare global {
|
|
1946
1958
|
interface Window {
|
|
@@ -2526,8 +2538,32 @@ export interface GeoLibreProject {
|
|
|
2526
2538
|
styleLibrary?: StyleLibraryEntry[];
|
|
2527
2539
|
/** Anchored review comments on map points or features (issue #1518). */
|
|
2528
2540
|
comments?: ProjectComment[];
|
|
2541
|
+
/**
|
|
2542
|
+
* Interaction state applied when the project opens: the Identify target and
|
|
2543
|
+
* which map controls and toolbar panels start shown (issue #2688). Written by
|
|
2544
|
+
* the Python `geolibre` package from `set_identify` / `show_control`, so a
|
|
2545
|
+
* saved or HTML-exported notebook map opens the way it was set up. Omitted
|
|
2546
|
+
* by default; the app keeps what it loaded and writes it back unchanged.
|
|
2547
|
+
*/
|
|
2548
|
+
interaction?: ProjectInteraction;
|
|
2529
2549
|
metadata: Record<string, unknown>;
|
|
2530
2550
|
}
|
|
2551
|
+
/**
|
|
2552
|
+
* Startup interaction state carried by a project (see
|
|
2553
|
+
* {@link GeoLibreProject.interaction}).
|
|
2554
|
+
*/
|
|
2555
|
+
export interface ProjectInteraction {
|
|
2556
|
+
/**
|
|
2557
|
+
* Identify target on open: a layer id, `"all"` for every visible queryable
|
|
2558
|
+
* layer, a list of layer ids to identify only those, or `null` for off.
|
|
2559
|
+
*/
|
|
2560
|
+
identify?: string | string[] | null;
|
|
2561
|
+
/**
|
|
2562
|
+
* Map control or toolbar panel name (`"search"`, `"bookmark"`, `"globe"`,
|
|
2563
|
+
* ...) to whether it starts shown. Unknown names are ignored on open.
|
|
2564
|
+
*/
|
|
2565
|
+
controls?: Record<string, boolean>;
|
|
2566
|
+
}
|
|
2531
2567
|
export type CommentAnchor = {
|
|
2532
2568
|
type: "point";
|
|
2533
2569
|
lngLat: [number, number];
|
|
@@ -3176,8 +3212,9 @@ export declare function horizontalBbox(box: readonly number[] | null | undefined
|
|
|
3176
3212
|
* cached per GeoJSON object, so repeated calls on the same data are free.
|
|
3177
3213
|
*
|
|
3178
3214
|
* @param geojson - Any GeoJSON object (geometry, feature, or collection).
|
|
3215
|
+
* @param includeZero - Accept zero elevations when explicit absolute-height placement matters.
|
|
3179
3216
|
*/
|
|
3180
|
-
export declare function geojsonHasZCoordinates(geojson: GeoJSON$1 | null | undefined): boolean;
|
|
3217
|
+
export declare function geojsonHasZCoordinates(geojson: GeoJSON$1 | null | undefined, includeZero?: boolean): boolean;
|
|
3181
3218
|
/**
|
|
3182
3219
|
* Returns a copy of the GeoJSON with every coordinate's Z value mapped to
|
|
3183
3220
|
* `z * verticalScale + offset` (missing or non-finite Z treated as 0). Used
|
|
@@ -4252,6 +4289,47 @@ export declare function inferFieldTypes(features: ReadonlyArray<{
|
|
|
4252
4289
|
properties?: Record<string, unknown> | null;
|
|
4253
4290
|
}>, names: string[]): Record<string, ExpressionFieldType>;
|
|
4254
4291
|
//#endregion
|
|
4292
|
+
//#region src/style-layer-evaluator.d.ts
|
|
4293
|
+
/** The geometry kinds a MapLibre style expression tells apart (`["geometry-type"]`). */
|
|
4294
|
+
export type StyleGeometryKind = "Point" | "LineString" | "Polygon";
|
|
4295
|
+
/** A feature as a style layer's expressions read it. */
|
|
4296
|
+
export interface StyleFeatureInput {
|
|
4297
|
+
id?: string | number;
|
|
4298
|
+
properties: Record<string, unknown> | null | undefined;
|
|
4299
|
+
kind: StyleGeometryKind;
|
|
4300
|
+
}
|
|
4301
|
+
/** A style layer's filter and property values, evaluated as MapLibre would. */
|
|
4302
|
+
export interface StyleLayerEvaluator {
|
|
4303
|
+
/** Whether the layer's `filter` keeps the feature at `zoom`. */
|
|
4304
|
+
passes: (zoom: number, feature: StyleFeatureInput) => boolean;
|
|
4305
|
+
/**
|
|
4306
|
+
* A paint or layout property's value for a feature at `zoom`: the layer's
|
|
4307
|
+
* value (a literal, a legacy function or an expression) or the spec's
|
|
4308
|
+
* default. A color comes back as `[r, g, b, a]` with channels 0-255 and
|
|
4309
|
+
* alpha 0-1; formatted text as its plain string. `undefined` for a property
|
|
4310
|
+
* the spec does not know or an expression that does not compile.
|
|
4311
|
+
*/
|
|
4312
|
+
value: (group: "paint" | "layout", name: string, zoom: number, feature: StyleFeatureInput) => unknown;
|
|
4313
|
+
}
|
|
4314
|
+
interface StyleLayerInput {
|
|
4315
|
+
id?: string;
|
|
4316
|
+
type: string;
|
|
4317
|
+
filter?: unknown;
|
|
4318
|
+
paint?: Record<string, unknown>;
|
|
4319
|
+
layout?: Record<string, unknown>;
|
|
4320
|
+
}
|
|
4321
|
+
/**
|
|
4322
|
+
* Compile a MapLibre style layer's filter and properties for evaluation
|
|
4323
|
+
* outside MapLibre, for a renderer that draws the layer itself (the ArcGIS
|
|
4324
|
+
* renderer drawing a plugin's own GeoJSON overlay, say). Uses the style spec's
|
|
4325
|
+
* own evaluator, so data-driven and zoom expressions, legacy functions and
|
|
4326
|
+
* defaults behave as they do on MapLibre. Each property compiles once.
|
|
4327
|
+
*
|
|
4328
|
+
* @param layer - The style layer (its `type`, `filter`, `paint`, `layout`).
|
|
4329
|
+
* @returns The layer's evaluator.
|
|
4330
|
+
*/
|
|
4331
|
+
export declare function createStyleLayerEvaluator(layer: StyleLayerInput): StyleLayerEvaluator;
|
|
4332
|
+
//#endregion
|
|
4255
4333
|
//#region src/document-locale.d.ts
|
|
4256
4334
|
/**
|
|
4257
4335
|
* The document language, so formatted numbers and dates follow the UI locale.
|
|
@@ -4423,6 +4501,38 @@ export declare function getExternalNativePaintBridge(layerId: string): ExternalN
|
|
|
4423
4501
|
* `!pluginOwnsPaint(layer)` to decide whether to show the slider at all.
|
|
4424
4502
|
*/
|
|
4425
4503
|
export declare function supportsBridgedOpacity(layerId: string): boolean;
|
|
4504
|
+
/**
|
|
4505
|
+
* True when the primary renderer draws this plugin-painted layer itself, from
|
|
4506
|
+
* the store record, and so applies `layer.opacity` without any plugin bridge.
|
|
4507
|
+
*
|
|
4508
|
+
* A Zarr layer is a MapLibre custom layer owned by the Zarr control on the 2D
|
|
4509
|
+
* map, but the ArcGIS view and the Cesium globe render it natively (an ArcGIS
|
|
4510
|
+
* layer's `opacity`, a Cesium `ImageryLayer.alpha`) and mount no control to
|
|
4511
|
+
* register a bridge. Without this the Opacity slider would be hidden there
|
|
4512
|
+
* although it works (opengeos/GeoLibre#2261).
|
|
4513
|
+
*
|
|
4514
|
+
* @param layer - A store layer.
|
|
4515
|
+
* @param renderer - The primary renderer (`useAppStore().primaryRenderer`).
|
|
4516
|
+
* @returns Whether an Opacity slider reaches the layer through the renderer.
|
|
4517
|
+
*/
|
|
4518
|
+
export declare function rendererAppliesOpacity(layer: {
|
|
4519
|
+
type: string;
|
|
4520
|
+
}, renderer: string | undefined): boolean;
|
|
4521
|
+
/**
|
|
4522
|
+
* Whether `layer` is an Add Vector Layer layer GeoLibre adopted
|
|
4523
|
+
* (`maplibre-gl-vector-adopted`, ADOPTED_VECTOR_SOURCE_KIND in
|
|
4524
|
+
* @geolibre/plugins) that has no features yet. A project saves a URL- or
|
|
4525
|
+
* path-backed adopted layer without them, and the vector control reads them
|
|
4526
|
+
* again on reopen. Until then its `source.url` may name GeoParquet or
|
|
4527
|
+
* GeoPackage, so a renderer must wait rather than load that URL as GeoJSON.
|
|
4528
|
+
*
|
|
4529
|
+
* @param layer - A store layer.
|
|
4530
|
+
* @returns True while the adopted layer awaits its features.
|
|
4531
|
+
*/
|
|
4532
|
+
export declare function isAdoptedVectorAwaitingFeatures(layer: {
|
|
4533
|
+
metadata: Record<string, unknown>;
|
|
4534
|
+
geojson?: unknown;
|
|
4535
|
+
}): boolean;
|
|
4426
4536
|
//#endregion
|
|
4427
4537
|
//#region src/attribute-form.d.ts
|
|
4428
4538
|
/** Options threaded to expression evaluation (constraints, visibility). */
|
|
@@ -4516,6 +4626,36 @@ export interface PopupRow {
|
|
|
4516
4626
|
export declare function isPopupClickEnabled(popup: LayerPopupConfig | undefined): boolean;
|
|
4517
4627
|
/** Whether a hover tooltip should follow the pointer. Default: no. */
|
|
4518
4628
|
export declare function isPopupHoverEnabled(popup: LayerPopupConfig | undefined): boolean;
|
|
4629
|
+
/**
|
|
4630
|
+
* Bounds for {@link LayerPopupConfig.maxWidth}, in CSS pixels. The floor is
|
|
4631
|
+
* the popup's own minimum width (`min-w-[18rem]`), below which the setting
|
|
4632
|
+
* would be overruled by the layout and read as broken; the ceiling keeps a
|
|
4633
|
+
* hand-edited project from authoring a popup that blankets the map.
|
|
4634
|
+
*/
|
|
4635
|
+
export declare const POPUP_MAX_WIDTH_RANGE: {
|
|
4636
|
+
readonly min: 288;
|
|
4637
|
+
readonly max: 1200;
|
|
4638
|
+
};
|
|
4639
|
+
/**
|
|
4640
|
+
* Bounds for {@link LayerPopupConfig.imageHeight}, in CSS pixels. Below the
|
|
4641
|
+
* floor a thumbnail carries no information; the ceiling matches
|
|
4642
|
+
* {@link POPUP_MAX_WIDTH_RANGE}, since a taller picture than that is what the
|
|
4643
|
+
* lightbox is for.
|
|
4644
|
+
*/
|
|
4645
|
+
export declare const POPUP_IMAGE_HEIGHT_RANGE: {
|
|
4646
|
+
readonly min: 40;
|
|
4647
|
+
readonly max: 1200;
|
|
4648
|
+
};
|
|
4649
|
+
/**
|
|
4650
|
+
* The widest the click popup may draw for a layer, in CSS pixels, or
|
|
4651
|
+
* `undefined` to keep the renderer's default.
|
|
4652
|
+
*/
|
|
4653
|
+
export declare function resolvePopupMaxWidth(popup: LayerPopupConfig | undefined): number | undefined;
|
|
4654
|
+
/**
|
|
4655
|
+
* The tallest an `"image"` field may draw inside the popup, in CSS pixels, or
|
|
4656
|
+
* `undefined` to keep the stylesheet's default.
|
|
4657
|
+
*/
|
|
4658
|
+
export declare function resolvePopupImageHeight(popup: LayerPopupConfig | undefined): number | undefined;
|
|
4519
4659
|
/** The label a popup shows for a configured field. */
|
|
4520
4660
|
export declare function popupFieldLabel(config: PopupFieldConfig): string;
|
|
4521
4661
|
/**
|
|
@@ -5087,14 +5227,23 @@ export declare class ElevationFetchError extends Error {
|
|
|
5087
5227
|
}
|
|
5088
5228
|
/** A `fetch`-compatible function, so tests can inject a stub. */
|
|
5089
5229
|
export type FetchLike = (url: string, init?: RequestInit) => Promise<Response>;
|
|
5230
|
+
/**
|
|
5231
|
+
* Normalize longitude into [-180, 180] degrees (handles unwrapped coordinates
|
|
5232
|
+
* from antimeridian cross-overs and world-copy pannings).
|
|
5233
|
+
*/
|
|
5234
|
+
export declare function normalizeLongitude(lng: number): number;
|
|
5235
|
+
/**
|
|
5236
|
+
* Clamp latitude into [-90, 90] degrees.
|
|
5237
|
+
*/
|
|
5238
|
+
export declare function clampLatitude(lat: number): number;
|
|
5090
5239
|
/**
|
|
5091
5240
|
* Fetch elevations (in meters) for an ordered list of coordinates.
|
|
5092
5241
|
*
|
|
5093
5242
|
* @param points - Coordinates as `[lng, lat]`, at most {@link MAX_POINTS_PER_REQUEST}
|
|
5094
5243
|
* @param fetchImpl - Optional `fetch` implementation; defaults to the global `fetch`
|
|
5095
5244
|
* @returns The elevation in meters for each input coordinate, in the same order
|
|
5096
|
-
* @throws {ElevationFetchError} On too many points, a
|
|
5097
|
-
* response, a malformed body, or a length mismatch
|
|
5245
|
+
* @throws {ElevationFetchError} On too many points, a non-finite coordinate, a
|
|
5246
|
+
* network error, a non-2xx response, a malformed body, or a length mismatch
|
|
5098
5247
|
*/
|
|
5099
5248
|
export declare function fetchElevations(points: LngLat[], fetchImpl?: FetchLike): Promise<number[]>;
|
|
5100
5249
|
/** The slice of the MapLibre map the terrain sampler needs (stubbed in tests). */
|
|
@@ -5225,6 +5374,42 @@ export declare function createEmptyProject(name?: string, options?: CreateProjec
|
|
|
5225
5374
|
* @returns The file contents to write.
|
|
5226
5375
|
*/
|
|
5227
5376
|
export declare function serializeProject(project: GeoLibreProject): string;
|
|
5377
|
+
/**
|
|
5378
|
+
* Per-layer serialized text kept across {@link serializeProjectWithLayerCache}
|
|
5379
|
+
* calls, keyed by the layer record each entry was built from. A `WeakMap`, so a
|
|
5380
|
+
* layer the store has replaced or removed drops its text with it.
|
|
5381
|
+
*/
|
|
5382
|
+
export type ProjectLayerSerializationCache = WeakMap<object, {
|
|
5383
|
+
index: number;
|
|
5384
|
+
text: string;
|
|
5385
|
+
}>;
|
|
5386
|
+
/** Create an empty {@link ProjectLayerSerializationCache}. */
|
|
5387
|
+
export declare function createProjectLayerSerializationCache(): ProjectLayerSerializationCache;
|
|
5388
|
+
/**
|
|
5389
|
+
* Serialize a project exactly as {@link serializeProject} does, reusing the
|
|
5390
|
+
* text of every layer whose source record is unchanged since an earlier call.
|
|
5391
|
+
*
|
|
5392
|
+
* Feature data lives inside layer records, so re-stringifying every layer on
|
|
5393
|
+
* each autosave costs megabytes of main-thread work for a project with large
|
|
5394
|
+
* GeoJSON layers — even when only the camera moved (GeoLibre#2633). The store
|
|
5395
|
+
* replaces a layer object whenever it changes, so object identity is a sound
|
|
5396
|
+
* cache key: a camera move reuses every layer, and an edit to one layer
|
|
5397
|
+
* re-serializes only that one.
|
|
5398
|
+
*
|
|
5399
|
+
* `layerSources[i]` must be the record `project.layers[i]` was derived from
|
|
5400
|
+
* (e.g. the store's `layers`, before `projectFromStore` prepared them), and that
|
|
5401
|
+
* derivation must depend on the record alone — as `buildProjectSnapshot`'s does
|
|
5402
|
+
* — or a cached entry could outlive a change it should have reflected. When the
|
|
5403
|
+
* two arrays differ in length the cache is bypassed rather than trusted.
|
|
5404
|
+
*
|
|
5405
|
+
* @param project Project to serialize, as built from `layerSources`.
|
|
5406
|
+
* @param layerSources Immutable source record for each entry of
|
|
5407
|
+
* `project.layers`, in the same order, used as the cache key.
|
|
5408
|
+
* @param cache Cache shared between calls; see
|
|
5409
|
+
* {@link createProjectLayerSerializationCache}.
|
|
5410
|
+
* @returns The same text {@link serializeProject} returns for `project`.
|
|
5411
|
+
*/
|
|
5412
|
+
export declare function serializeProjectWithLayerCache(project: GeoLibreProject, layerSources: readonly object[], cache: ProjectLayerSerializationCache): string;
|
|
5228
5413
|
export declare function parseProject(json: string): GeoLibreProject;
|
|
5229
5414
|
/**
|
|
5230
5415
|
* Validate and coerce a story map loaded from an untrusted project file.
|
|
@@ -5293,10 +5478,11 @@ export declare function normalizeMapLayout(value: unknown): MapGridLayout | null
|
|
|
5293
5478
|
* Returns null for the default 2D map — absent, unknown, or an explicit
|
|
5294
5479
|
* `"maplibre"` — because the field is only written when it is not the default,
|
|
5295
5480
|
* so a MapLibre project serializes byte-identically to before this existed.
|
|
5296
|
-
* The return type is narrowed to `"cesium" | null` rather
|
|
5297
|
-
* {@link MapRendererKind} for that reason: `"maplibre"` is never a
|
|
5481
|
+
* The return type is narrowed to `"cesium" | "mapbox" | "arcgis" | null` rather
|
|
5482
|
+
* than the full {@link MapRendererKind} for that reason: `"maplibre"` is never a
|
|
5483
|
+
* result.
|
|
5298
5484
|
*/
|
|
5299
|
-
export declare function normalizePrimaryRenderer(value: unknown): "cesium" | null;
|
|
5485
|
+
export declare function normalizePrimaryRenderer(value: unknown): "cesium" | "mapbox" | "arcgis" | null;
|
|
5300
5486
|
/**
|
|
5301
5487
|
* Coerce an untrusted `secondaryMapViews` array into valid
|
|
5302
5488
|
* {@link SecondaryMapView} records, dropping entries without a usable id and
|
|
@@ -5335,6 +5521,18 @@ export declare function normalizeWidgets(value: unknown): DashboardWidget[] | nu
|
|
|
5335
5521
|
* @returns An integer column count within [MIN, MAX].
|
|
5336
5522
|
*/
|
|
5337
5523
|
export declare function normalizeDashboardColumns(value: unknown): number;
|
|
5524
|
+
/**
|
|
5525
|
+
* Coerce an untrusted `interaction` block into a {@link ProjectInteraction}.
|
|
5526
|
+
*
|
|
5527
|
+
* Layer ids are kept even when no such layer exists: the block is replayed
|
|
5528
|
+
* against whatever layers the project has when it opens, and the loader drops
|
|
5529
|
+
* the ones it cannot find. Control names are kept as written for the same
|
|
5530
|
+
* reason; the app ignores names it does not know.
|
|
5531
|
+
*
|
|
5532
|
+
* @param value - Raw `interaction` value from the project JSON or the store.
|
|
5533
|
+
* @returns The normalized block, or null when it carries nothing to apply.
|
|
5534
|
+
*/
|
|
5535
|
+
export declare function normalizeProjectInteraction(value: unknown): ProjectInteraction | null;
|
|
5338
5536
|
export declare function isAllowedPluginManifestUrl(url: string): boolean;
|
|
5339
5537
|
export declare function normalizeProjectComments(rawComments: unknown): ProjectComment[];
|
|
5340
5538
|
export declare function projectFromStore(state: {
|
|
@@ -5363,8 +5561,20 @@ export declare function projectFromStore(state: {
|
|
|
5363
5561
|
/** Project-scoped Style Manager entries (the store's `projectStyleLibrary`). */
|
|
5364
5562
|
styleLibrary?: StyleLibraryEntry[] | null;
|
|
5365
5563
|
comments?: ProjectComment[] | null;
|
|
5564
|
+
/** Startup interaction state loaded with the project, written back as-is. */
|
|
5565
|
+
interaction?: ProjectInteraction | null;
|
|
5366
5566
|
metadata: Record<string, unknown>;
|
|
5367
5567
|
}): GeoLibreProject;
|
|
5568
|
+
/**
|
|
5569
|
+
* The plain HTTP(S) WMS template inside the desktop app's `geolibre-wms://`
|
|
5570
|
+
* wrapper (its CORS-exempt native fetcher), or the tile unchanged when it is
|
|
5571
|
+
* not wrapped or the wrapped URL is not HTTP(S). Shared by project export and
|
|
5572
|
+
* the ArcGIS engine's story-export templates.
|
|
5573
|
+
*
|
|
5574
|
+
* @param tile - A tile template, wrapped or not.
|
|
5575
|
+
* @returns The unwrapped template, or `tile` itself.
|
|
5576
|
+
*/
|
|
5577
|
+
export declare function portableWmsTileUrl(tile: unknown): unknown;
|
|
5368
5578
|
export declare function applyProjectToStore(project: GeoLibreProject): {
|
|
5369
5579
|
projectName: string;
|
|
5370
5580
|
mapView: MapViewState;
|
|
@@ -5389,6 +5599,7 @@ export declare function applyProjectToStore(project: GeoLibreProject): {
|
|
|
5389
5599
|
primaryRenderer: MapRendererKind;
|
|
5390
5600
|
projectStyleLibrary: StyleLibraryEntry[];
|
|
5391
5601
|
comments: ProjectComment[];
|
|
5602
|
+
projectInteraction: ProjectInteraction | null;
|
|
5392
5603
|
metadata: Record<string, unknown>;
|
|
5393
5604
|
};
|
|
5394
5605
|
/**
|
|
@@ -5931,6 +6142,101 @@ export declare function extractCopiedLayerStyle(layer: GeoLibreLayer): CopiedLay
|
|
|
5931
6142
|
*/
|
|
5932
6143
|
export declare function applyCopiedLayerStyle(target: GeoLibreLayer, copied: CopiedLayerStyle): Partial<GeoLibreLayer> | null;
|
|
5933
6144
|
//#endregion
|
|
6145
|
+
//#region src/layer-style-file.d.ts
|
|
6146
|
+
/** `type` tag identifying a layer styles file. */
|
|
6147
|
+
export declare const LAYER_STYLES_FILE_TYPE = "geolibre-layer-styles";
|
|
6148
|
+
/** Format version written by {@link serializeLayerStylesFile}. */
|
|
6149
|
+
export declare const LAYER_STYLES_FILE_VERSION = 1;
|
|
6150
|
+
/** One layer's style in a layer styles file, keyed by the layer's name. */
|
|
6151
|
+
export type LayerStyleFileEntry = {
|
|
6152
|
+
/** Name of the layer the style was exported from; the match key. */
|
|
6153
|
+
layerName: string;
|
|
6154
|
+
kind: "vector";
|
|
6155
|
+
/** The full vector {@link LayerStyle} bag. */
|
|
6156
|
+
style: LayerStyle;
|
|
6157
|
+
} | {
|
|
6158
|
+
layerName: string;
|
|
6159
|
+
kind: "raster";
|
|
6160
|
+
/** Raster visualization state (`metadata.rasterState`). */
|
|
6161
|
+
rasterState?: Record<string, unknown>;
|
|
6162
|
+
/** Raster classification symbology (`metadata.rasterSymbology`). */
|
|
6163
|
+
rasterSymbology?: Record<string, unknown>;
|
|
6164
|
+
};
|
|
6165
|
+
/** The on-disk layer styles document. */
|
|
6166
|
+
export interface LayerStylesFile {
|
|
6167
|
+
type: typeof LAYER_STYLES_FILE_TYPE;
|
|
6168
|
+
version: typeof LAYER_STYLES_FILE_VERSION;
|
|
6169
|
+
styles: LayerStyleFileEntry[];
|
|
6170
|
+
}
|
|
6171
|
+
/**
|
|
6172
|
+
* Capture the style of every layer that has one. Layers without copyable
|
|
6173
|
+
* symbology (basemap tiles, 3D tiles, ...) are skipped. Layers that share a
|
|
6174
|
+
* name are all written, in stack order; the first one wins when the file is
|
|
6175
|
+
* applied (see {@link findLayerStyleEntryIndex}).
|
|
6176
|
+
*
|
|
6177
|
+
* @param layers - The layers to export, in store (bottom-to-top) order.
|
|
6178
|
+
* @returns The style entries.
|
|
6179
|
+
*/
|
|
6180
|
+
export declare function extractLayerStyleEntries(layers: readonly GeoLibreLayer[]): LayerStyleFileEntry[];
|
|
6181
|
+
/**
|
|
6182
|
+
* Serialize style entries into the JSON written by Export Layer Styles.
|
|
6183
|
+
*
|
|
6184
|
+
* @param entries - The entries to write.
|
|
6185
|
+
* @returns Pretty-printed file content.
|
|
6186
|
+
*/
|
|
6187
|
+
export declare function serializeLayerStylesFile(entries: readonly LayerStyleFileEntry[]): string;
|
|
6188
|
+
/**
|
|
6189
|
+
* Coerce untrusted entries (a hand-edited file, or a copy kept in settings)
|
|
6190
|
+
* into clean ones. An entry without a name or a known kind is dropped; a
|
|
6191
|
+
* vector style is sanitized and completed against the default style, and a
|
|
6192
|
+
* raster state keeps only well-typed appearance keys, so applying an entry
|
|
6193
|
+
* never hands a renderer an unknown, missing or wrong-typed field.
|
|
6194
|
+
*
|
|
6195
|
+
* @param value - The raw `styles` array.
|
|
6196
|
+
* @returns The usable entries.
|
|
6197
|
+
*/
|
|
6198
|
+
export declare function normalizeLayerStyleEntries(value: unknown): LayerStyleFileEntry[];
|
|
6199
|
+
/**
|
|
6200
|
+
* Parse a file written by {@link serializeLayerStylesFile}.
|
|
6201
|
+
*
|
|
6202
|
+
* @param json - The file content.
|
|
6203
|
+
* @returns The normalized entries.
|
|
6204
|
+
* @throws Error when the content is not a layer styles file, comes from a
|
|
6205
|
+
* newer format version, or holds no usable entries.
|
|
6206
|
+
*/
|
|
6207
|
+
export declare function parseLayerStylesFile(json: string): LayerStyleFileEntry[];
|
|
6208
|
+
/**
|
|
6209
|
+
* Find the entry for a layer name: an exact match first, then one that differs
|
|
6210
|
+
* only in case or surrounding whitespace, so `Roads` still picks up a style
|
|
6211
|
+
* saved for `roads`. The first match in file order wins.
|
|
6212
|
+
*
|
|
6213
|
+
* @param entries - The style entries.
|
|
6214
|
+
* @param layerName - The layer name to look up.
|
|
6215
|
+
* @param kind - When given, only entries of this style family are considered,
|
|
6216
|
+
* so a raster style saved under a shared name does not shadow the vector one.
|
|
6217
|
+
* @returns The matching entry's index in `entries`, or -1.
|
|
6218
|
+
*/
|
|
6219
|
+
export declare function findLayerStyleEntryIndex(entries: readonly LayerStyleFileEntry[], layerName: string, kind?: LayerStyleClipboardKind): number;
|
|
6220
|
+
/** A layer restyled from a style entry, and the entry it took. */
|
|
6221
|
+
export interface LayerStyleMatch {
|
|
6222
|
+
/** Index of the applied entry in the entries array. */
|
|
6223
|
+
entryIndex: number;
|
|
6224
|
+
/** The patch that applies it. */
|
|
6225
|
+
patch: Partial<GeoLibreLayer>;
|
|
6226
|
+
}
|
|
6227
|
+
/**
|
|
6228
|
+
* Build the patch that restyles a layer from the entry matching its name, with
|
|
6229
|
+
* the same semantics as pasting a copied style: a vector style replaces the
|
|
6230
|
+
* whole style bag, a raster style merges its appearance keys and keeps the
|
|
6231
|
+
* layer's own band selection, and layer opacity is left alone.
|
|
6232
|
+
*
|
|
6233
|
+
* @param layer - The layer to restyle.
|
|
6234
|
+
* @param entries - The style entries.
|
|
6235
|
+
* @returns The matched entry and patch, or `null` when no entry of the layer's
|
|
6236
|
+
* style family matches its name (or the layer has no stylable symbology).
|
|
6237
|
+
*/
|
|
6238
|
+
export declare function matchLayerStyleEntry(layer: GeoLibreLayer, entries: readonly LayerStyleFileEntry[]): LayerStyleMatch | null;
|
|
6239
|
+
//#endregion
|
|
5934
6240
|
//#region src/layer-groups.d.ts
|
|
5935
6241
|
/** Opacity a freshly created {@link LayerGroup} starts at (fully opaque). */
|
|
5936
6242
|
export declare const DEFAULT_LAYER_GROUP_OPACITY = 1;
|
|
@@ -6157,6 +6463,35 @@ export declare function reorderLayerGroupInPanel(layers: GeoLibreLayer[], groups
|
|
|
6157
6463
|
layers: GeoLibreLayer[];
|
|
6158
6464
|
groups: LayerGroup[];
|
|
6159
6465
|
} | null;
|
|
6466
|
+
/** Direction {@link sortLayerGroupInPanel} orders names in, top of panel first. */
|
|
6467
|
+
export type LayerGroupSortOrder = "asc" | "desc";
|
|
6468
|
+
/**
|
|
6469
|
+
* Sort what sits directly inside a group by name, A to Z (`"asc"`) or Z to A
|
|
6470
|
+
* (`"desc"`) from the top of the panel down (GeoLibre#2599).
|
|
6471
|
+
*
|
|
6472
|
+
* The group's own layers are sorted among themselves, and its child groups are
|
|
6473
|
+
* sorted among themselves by group name, each carrying everything nested inside
|
|
6474
|
+
* it. The two are not interleaved: a group's own layers are one contiguous
|
|
6475
|
+
* block (see {@link normalizeGroupContiguity}), so that block keeps its slot
|
|
6476
|
+
* among the child groups rather than being split between them. Only direct
|
|
6477
|
+
* children move; the contents of a child group keep their order.
|
|
6478
|
+
*
|
|
6479
|
+
* Like {@link reorderLayerGroupInPanel}, both arrays come back, so empty child
|
|
6480
|
+
* folders follow the sort too.
|
|
6481
|
+
*
|
|
6482
|
+
* @param layers Flat layer list in store (render) order.
|
|
6483
|
+
* @param groups Group definitions.
|
|
6484
|
+
* @param id Group whose children to sort.
|
|
6485
|
+
* @param order `"asc"` for A to Z, `"desc"` for Z to A.
|
|
6486
|
+
* @param locale BCP 47 tag whose collation rules to compare names by, normally
|
|
6487
|
+
* the app's display language. Defaults to the runtime locale.
|
|
6488
|
+
* @returns The new arrays, or `null` when the children are already in that
|
|
6489
|
+
* order and nothing would change.
|
|
6490
|
+
*/
|
|
6491
|
+
export declare function sortLayerGroupInPanel(layers: GeoLibreLayer[], groups: LayerGroup[], id: string, order: LayerGroupSortOrder, locale?: string): {
|
|
6492
|
+
layers: GeoLibreLayer[];
|
|
6493
|
+
groups: LayerGroup[];
|
|
6494
|
+
} | null;
|
|
6160
6495
|
/**
|
|
6161
6496
|
* Which directions {@link reorderLayerGroupInPanel} can actually move each
|
|
6162
6497
|
* group, so the layer panel can disable a menu item that would do nothing.
|
|
@@ -6169,6 +6504,16 @@ export declare function layerGroupMoveability(layers: GeoLibreLayer[], groups: L
|
|
|
6169
6504
|
up: boolean;
|
|
6170
6505
|
down: boolean;
|
|
6171
6506
|
}>;
|
|
6507
|
+
/**
|
|
6508
|
+
* Which orders {@link sortLayerGroupInPanel} would actually change for each
|
|
6509
|
+
* group, so the layer panel can disable a sort that would do nothing.
|
|
6510
|
+
*
|
|
6511
|
+
* @param layers Flat layer list in store (render) order.
|
|
6512
|
+
* @param groups Group definitions.
|
|
6513
|
+
* @param locale Collation locale, as for {@link sortLayerGroupInPanel}.
|
|
6514
|
+
* @returns Per-group flags, keyed by group id.
|
|
6515
|
+
*/
|
|
6516
|
+
export declare function layerGroupSortability(layers: GeoLibreLayer[], groups: LayerGroup[], locale?: string): Map<string, Record<LayerGroupSortOrder, boolean>>;
|
|
6172
6517
|
//#endregion
|
|
6173
6518
|
//#region src/pixel-format.d.ts
|
|
6174
6519
|
/**
|
|
@@ -6183,6 +6528,236 @@ export declare function layerGroupMoveability(layers: GeoLibreLayer[], groups: L
|
|
|
6183
6528
|
*/
|
|
6184
6529
|
export declare function formatPixelValue(value: number): string;
|
|
6185
6530
|
//#endregion
|
|
6531
|
+
//#region src/s3.d.ts
|
|
6532
|
+
/**
|
|
6533
|
+
* Amazon S3 (and S3-compatible) object URLs: parsing, public HTTPS mapping,
|
|
6534
|
+
* SigV4 query-string presigning, and the registry the app uses to plug
|
|
6535
|
+
* credentialed signing into every reader.
|
|
6536
|
+
*
|
|
6537
|
+
* Readers in GeoLibre take a plain HTTPS URL (geotiff.js, cog-tiler-wasm,
|
|
6538
|
+
* pmtiles, DuckDB-WASM's HTTP reader, the vector control). A presigned URL is
|
|
6539
|
+
* the one form of authenticated S3 access all of them accept without a custom
|
|
6540
|
+
* fetch hook, so private objects are read by signing the URL first and handing
|
|
6541
|
+
* the reader the result. Layers keep the unsigned source URL (`s3://…` or the
|
|
6542
|
+
* plain object URL); the signed one is minted again on every load, so a saved
|
|
6543
|
+
* project never carries a signature or a session token.
|
|
6544
|
+
*/
|
|
6545
|
+
/** A bucket and object key, with the endpoint the URL named, if any. */
|
|
6546
|
+
export interface S3ObjectLocation {
|
|
6547
|
+
bucket: string;
|
|
6548
|
+
/** The raw (decoded) object key, without a leading slash. */
|
|
6549
|
+
key: string;
|
|
6550
|
+
/** The region an AWS HTTPS URL named in its host, when it named one. */
|
|
6551
|
+
region?: string;
|
|
6552
|
+
}
|
|
6553
|
+
/** Where and how a bucket is addressed. */
|
|
6554
|
+
export interface S3EndpointConfig {
|
|
6555
|
+
/** Signing region, e.g. `us-east-1`. S3-compatible stores often accept `auto`. */
|
|
6556
|
+
region: string;
|
|
6557
|
+
/**
|
|
6558
|
+
* Custom endpoint origin for S3-compatible stores (MinIO, Cloudflare R2,
|
|
6559
|
+
* Wasabi, Ceph), e.g. `https://minio.example.com:9000`. Empty for AWS.
|
|
6560
|
+
*/
|
|
6561
|
+
endpoint?: string;
|
|
6562
|
+
/** Address the bucket in the path instead of the host name. */
|
|
6563
|
+
pathStyle?: boolean;
|
|
6564
|
+
}
|
|
6565
|
+
/** AWS credentials used to sign a request. */
|
|
6566
|
+
export interface S3Credentials {
|
|
6567
|
+
accessKeyId: string;
|
|
6568
|
+
secretAccessKey: string;
|
|
6569
|
+
sessionToken?: string;
|
|
6570
|
+
/** Epoch milliseconds at which temporary credentials stop working. */
|
|
6571
|
+
expiresAt?: number;
|
|
6572
|
+
}
|
|
6573
|
+
/** A presigned URL and the moment it stops working. */
|
|
6574
|
+
export interface S3SignedUrl {
|
|
6575
|
+
href: string;
|
|
6576
|
+
/** Epoch milliseconds. */
|
|
6577
|
+
expiresAt: number;
|
|
6578
|
+
}
|
|
6579
|
+
/** SigV4 allows a presigned URL to live at most seven days. */
|
|
6580
|
+
export declare const S3_MAX_PRESIGN_SECONDS: number;
|
|
6581
|
+
/**
|
|
6582
|
+
* Parses an `s3://bucket/key` URI or an AWS S3 HTTPS object URL
|
|
6583
|
+
* (virtual-hosted or path-style, any region) into its bucket and key.
|
|
6584
|
+
* Query strings and fragments are ignored, so a presigned URL parses to the
|
|
6585
|
+
* object it signs.
|
|
6586
|
+
*
|
|
6587
|
+
* @param url The URL to parse.
|
|
6588
|
+
* @returns The bucket and key, or null when the URL is not an S3 object URL.
|
|
6589
|
+
*/
|
|
6590
|
+
export declare function parseS3Url(url: string): S3ObjectLocation | null;
|
|
6591
|
+
/** Whether `url` is an `s3://` URI (as opposed to an HTTPS object URL). */
|
|
6592
|
+
export declare function isS3Uri(url: string): boolean;
|
|
6593
|
+
/** Formats a location as an `s3://bucket/key` URI. */
|
|
6594
|
+
export declare function formatS3Uri(location: S3ObjectLocation): string;
|
|
6595
|
+
/**
|
|
6596
|
+
* URI-encodes a key the way SigV4 canonicalizes an S3 path: every byte except
|
|
6597
|
+
* the unreserved set and `/` is percent-encoded, once.
|
|
6598
|
+
*/
|
|
6599
|
+
export declare function encodeS3Key(key: string): string;
|
|
6600
|
+
/**
|
|
6601
|
+
* Builds the HTTPS URL of an object.
|
|
6602
|
+
*
|
|
6603
|
+
* AWS buckets whose name contains a dot are addressed path-style, since the
|
|
6604
|
+
* `*.s3.amazonaws.com` wildcard certificate covers one label only.
|
|
6605
|
+
*
|
|
6606
|
+
* @param location The bucket and key.
|
|
6607
|
+
* @param config The endpoint; without one the global AWS endpoint is used.
|
|
6608
|
+
* @returns The unsigned object URL.
|
|
6609
|
+
*/
|
|
6610
|
+
export declare function s3ObjectHttpsUrl(location: S3ObjectLocation, config?: Partial<S3EndpointConfig>): string;
|
|
6611
|
+
export interface PresignS3Options {
|
|
6612
|
+
/** The unsigned HTTPS object URL (see {@link s3ObjectHttpsUrl}). */
|
|
6613
|
+
url: string;
|
|
6614
|
+
region: string;
|
|
6615
|
+
credentials: S3Credentials;
|
|
6616
|
+
/** Lifetime in seconds, clamped to 1…{@link S3_MAX_PRESIGN_SECONDS}. */
|
|
6617
|
+
expiresIn: number;
|
|
6618
|
+
/** HTTP method the URL authorizes. Defaults to GET. */
|
|
6619
|
+
method?: string;
|
|
6620
|
+
/** Signing time; defaults to now. Exposed for tests. */
|
|
6621
|
+
now?: Date;
|
|
6622
|
+
}
|
|
6623
|
+
/**
|
|
6624
|
+
* Presigns an S3 request with AWS Signature Version 4 in the query string.
|
|
6625
|
+
* Runs on WebCrypto, so it works in the browser, the Tauri webview, and Node.
|
|
6626
|
+
*
|
|
6627
|
+
* The URL authorizes exactly one method: a GET URL cannot answer a HEAD, so
|
|
6628
|
+
* readers that probe with HEAD need a GET range request instead.
|
|
6629
|
+
*
|
|
6630
|
+
* @param options The object URL, region, credentials, and lifetime.
|
|
6631
|
+
* @returns The presigned URL.
|
|
6632
|
+
*/
|
|
6633
|
+
export declare function presignS3Url(options: PresignS3Options): Promise<string>;
|
|
6634
|
+
/** One signed S3 GET: an object read, or a bucket-level call such as ListObjectsV2. */
|
|
6635
|
+
export interface S3PresignRequest {
|
|
6636
|
+
bucket: string;
|
|
6637
|
+
/** Object key; empty for a bucket-level request. */
|
|
6638
|
+
key: string;
|
|
6639
|
+
/** Extra query parameters to sign (e.g. `list-type=2`). */
|
|
6640
|
+
query?: Record<string, string>;
|
|
6641
|
+
/** Region an AWS URL named, used ahead of the connection's default. */
|
|
6642
|
+
region?: string;
|
|
6643
|
+
/**
|
|
6644
|
+
* Sign with this connection instead of the one matched by bucket name (the
|
|
6645
|
+
* S3 browser listing a chosen connection's buckets, where `bucket` is empty).
|
|
6646
|
+
*/
|
|
6647
|
+
connectionId?: string;
|
|
6648
|
+
}
|
|
6649
|
+
/** A configured connection, as the S3 browser lists it. No secrets. */
|
|
6650
|
+
export interface S3ConnectionSummary {
|
|
6651
|
+
id: string;
|
|
6652
|
+
name: string;
|
|
6653
|
+
/** Bucket patterns the connection covers; empty means every bucket. */
|
|
6654
|
+
buckets: string[];
|
|
6655
|
+
}
|
|
6656
|
+
/**
|
|
6657
|
+
* Presigns S3 requests with the app's configured credentials. `presign`
|
|
6658
|
+
* resolves to null when no configured connection covers the bucket, in which
|
|
6659
|
+
* case the object is read anonymously.
|
|
6660
|
+
*/
|
|
6661
|
+
export interface S3UrlSigner {
|
|
6662
|
+
/** Whether a configured connection covers `bucket`. Must be synchronous. */
|
|
6663
|
+
covers(bucket: string): boolean;
|
|
6664
|
+
/** Presigns a GET; rejects when the connection's credentials cannot be resolved. */
|
|
6665
|
+
presign(request: S3PresignRequest, signal?: AbortSignal): Promise<S3SignedUrl | null>;
|
|
6666
|
+
/** The configured connections, for pickers. */
|
|
6667
|
+
connections(): S3ConnectionSummary[];
|
|
6668
|
+
/**
|
|
6669
|
+
* Fetches a presigned bucket-level URL (listing). The desktop app routes it
|
|
6670
|
+
* through its native HTTP client, which needs no bucket CORS rule.
|
|
6671
|
+
*/
|
|
6672
|
+
fetchText?(url: string, signal?: AbortSignal): Promise<{
|
|
6673
|
+
status: number;
|
|
6674
|
+
body: string;
|
|
6675
|
+
}>;
|
|
6676
|
+
/** The persisted location (`s3://bucket/prefix/`) the S3 browser opens at, or "". */
|
|
6677
|
+
defaultLocation?(): string;
|
|
6678
|
+
/** Persists the S3 browser's default location; "" clears it. */
|
|
6679
|
+
setDefaultLocation?(location: string): void;
|
|
6680
|
+
}
|
|
6681
|
+
/** Installs (or with null, removes) the app's S3 signer. */
|
|
6682
|
+
export declare function registerS3UrlSigner(signer: S3UrlSigner | null): void;
|
|
6683
|
+
/**
|
|
6684
|
+
* Whether reading `url` needs the S3 signer: it names an S3 object in a bucket
|
|
6685
|
+
* a configured connection covers.
|
|
6686
|
+
*/
|
|
6687
|
+
export declare function isCredentialedS3Url(url: string): boolean;
|
|
6688
|
+
/**
|
|
6689
|
+
* The unsigned URL a presigned one was minted for by
|
|
6690
|
+
* {@link resolveReadableUrl}, or `url` itself. Layer sync runs every URL a
|
|
6691
|
+
* control reports through this, so the store (and a saved project) keeps the
|
|
6692
|
+
* `s3://` source rather than an expiring signature.
|
|
6693
|
+
*/
|
|
6694
|
+
export declare function unsignedSourceUrl(url: string): string;
|
|
6695
|
+
export declare function unsignedSourceUrl(url: string | undefined): string | undefined;
|
|
6696
|
+
/**
|
|
6697
|
+
* Resolves a data URL into one a plain HTTP reader can fetch:
|
|
6698
|
+
*
|
|
6699
|
+
* - an S3 object in a bucket a configured connection covers → a presigned URL;
|
|
6700
|
+
* - any other `s3://` URI → the public HTTPS object URL (anonymous read);
|
|
6701
|
+
* - anything else → unchanged.
|
|
6702
|
+
*
|
|
6703
|
+
* @param url The URL a layer or query names.
|
|
6704
|
+
* @param signal Aborts a pending credential lookup.
|
|
6705
|
+
* @returns The URL to hand the reader.
|
|
6706
|
+
* @throws When the bucket is covered but its credentials cannot be resolved.
|
|
6707
|
+
*/
|
|
6708
|
+
export declare function resolveReadableUrl(url: string, signal?: AbortSignal): Promise<string>;
|
|
6709
|
+
/** The installed signer, for the S3 browser. */
|
|
6710
|
+
export declare function getS3UrlSigner(): S3UrlSigner | null;
|
|
6711
|
+
/** One page of a ListObjectsV2 response. */
|
|
6712
|
+
export interface S3ListPage {
|
|
6713
|
+
/** Common prefixes ("folders") under the requested prefix. */
|
|
6714
|
+
prefixes: string[];
|
|
6715
|
+
objects: Array<{
|
|
6716
|
+
key: string;
|
|
6717
|
+
size: number;
|
|
6718
|
+
lastModified?: string;
|
|
6719
|
+
}>;
|
|
6720
|
+
/** Present when more results follow. */
|
|
6721
|
+
nextContinuationToken?: string;
|
|
6722
|
+
}
|
|
6723
|
+
/**
|
|
6724
|
+
* Parses a ListObjectsV2 XML body. S3's listing XML is flat and predictable,
|
|
6725
|
+
* so this reads it with patterns rather than an XML DOM, which keeps it usable
|
|
6726
|
+
* in workers and Node tests.
|
|
6727
|
+
*/
|
|
6728
|
+
export declare function parseS3ListObjects(xml: string): S3ListPage;
|
|
6729
|
+
/** The error code and message of an S3 XML error body, when it is one. */
|
|
6730
|
+
export declare function parseS3Error(xml: string): {
|
|
6731
|
+
code: string;
|
|
6732
|
+
message: string;
|
|
6733
|
+
region?: string;
|
|
6734
|
+
} | null;
|
|
6735
|
+
/** Bucket names from a ListBuckets (`GET /` on the service) XML body. */
|
|
6736
|
+
export declare function parseS3BucketList(xml: string): string[];
|
|
6737
|
+
/** A read the bucket's CORS configuration blocked. */
|
|
6738
|
+
export declare class S3CorsError extends Error {
|
|
6739
|
+
readonly bucket: string;
|
|
6740
|
+
readonly origin: string;
|
|
6741
|
+
constructor(message: string, bucket: string, origin: string, cause: unknown);
|
|
6742
|
+
}
|
|
6743
|
+
/** Translates `key`, falling back to `defaultValue` (an app API's `translate`). */
|
|
6744
|
+
export type S3ErrorTranslate = (key: string, defaultValue: string, params?: Record<string, string | number>) => string;
|
|
6745
|
+
/**
|
|
6746
|
+
* Explains why reading an S3 object failed when the browser only said
|
|
6747
|
+
* "Failed to fetch". A browser reports a request the bucket's CORS rules
|
|
6748
|
+
* blocked exactly like a network outage, so this repeats the request twice:
|
|
6749
|
+
* normally, where success means the failure was transient; then in `no-cors`
|
|
6750
|
+
* mode, which CORS cannot block. Only when the first fails and the second gets
|
|
6751
|
+
* an answer is the bucket's CORS configuration the cause.
|
|
6752
|
+
*
|
|
6753
|
+
* @param url The `s3://` URI or object URL that was being read.
|
|
6754
|
+
* @param error What the reader threw.
|
|
6755
|
+
* @param translate Turns the message into the UI language.
|
|
6756
|
+
* @returns An {@link S3CorsError} naming the bucket and the origin to allow,
|
|
6757
|
+
* or `error` unchanged when it is not a CORS refusal of an S3 read.
|
|
6758
|
+
*/
|
|
6759
|
+
export declare function explainS3ReadError(url: string, error: unknown, translate?: S3ErrorTranslate): Promise<unknown>;
|
|
6760
|
+
//#endregion
|
|
6186
6761
|
//#region src/storymap-sample.d.ts
|
|
6187
6762
|
/**
|
|
6188
6763
|
* Build a ready-to-play sample story map.
|
|
@@ -6308,351 +6883,249 @@ export declare function serializeStoryMapCsv(storymap: StoryMap): string;
|
|
|
6308
6883
|
*/
|
|
6309
6884
|
export declare function parseStoryMapCsv(text: string, base?: StoryMap | null): StoryMap;
|
|
6310
6885
|
//#endregion
|
|
6311
|
-
//#region src/store.d.ts
|
|
6312
|
-
|
|
6313
|
-
/**
|
|
6314
|
-
* Identifiers of the vector processing tools. Kept in sync by hand with the
|
|
6315
|
-
* `id` fields of `VECTOR_TOOLS` in `@geolibre/processing` (`vector-tools.ts`);
|
|
6316
|
-
* deriving the type there would create a core -> processing circular import.
|
|
6317
|
-
*/
|
|
6318
|
-
type VectorToolKind = "buffer" | "centroids" | "convex-hull" | "dissolve" | "bounding-box" | "simplify" | "clip" | "intersection" | "difference" | "union" | "spatial-join" | "attribute-join" | "select-by-value" | "select-by-location" | "random-extract" | "reproject" | "explode" | "aggregate" | "smooth" | "extract-vertices" | "points-along-geometry" | "grid" | "voronoi" | "cell-sectors" | "dggs-grid" | "dggs-bin" | "dggs-compact" | "trajectory-speed" | "detect-stops" | "space-time-proximity" | "decode-polyline" | "encode-polyline" | "merge-layers" | "check-validity" | "fix-geometries" | "check-topology-rules" | "fix-topology";
|
|
6319
|
-
/** Identifiers of the network-analysis tools (`NETWORK_TOOLS` ids). */
|
|
6320
|
-
type NetworkToolKind = "isochrone" | "od-matrix" | "sequential-route";
|
|
6321
|
-
/** Identifiers of the spatial-statistics tools (`STATISTICS_TOOLS` ids). */
|
|
6322
|
-
type StatisticsToolKind = "global-morans-i" | "local-morans-i" | "getis-ord-gi" | "average-nearest-neighbor" | "kernel-density" | "emerging-hot-spot" | "composite-score";
|
|
6323
|
-
/**
|
|
6324
|
-
* Identifiers of the raster processing tools. Kept in sync by hand with the
|
|
6325
|
-
* `id` fields of `RASTER_TOOLS` in `@geolibre/processing` (`raster-tools.ts`);
|
|
6326
|
-
* deriving the type there would create a core -> processing circular import.
|
|
6327
|
-
*/
|
|
6328
|
-
type RasterToolKind = "hillshade" | "slope" | "aspect" | "reproject" | "resample" | "clip-extent" | "clip-mask" | "polygonize" | "contour" | "interpolate" | "zonal" | "raster-calc" | "spectral-index" | "reclassify" | "mosaic" | "focal";
|
|
6329
|
-
/**
|
|
6330
|
-
* Latest live device-GPS fix published by the GPS Tracking tool (issue #1316),
|
|
6331
|
-
* read by the status bar readout. Device state, not project state: excluded
|
|
6332
|
-
* from undo history (partialize never lists it) and from project files, and
|
|
6333
|
-
* deliberately left untouched on project switches.
|
|
6334
|
-
*/
|
|
6335
|
-
interface GpsStatusFix {
|
|
6336
|
-
lng: number;
|
|
6337
|
-
lat: number;
|
|
6338
|
-
/** Horizontal accuracy radius in meters. */
|
|
6339
|
-
accuracy: number;
|
|
6340
|
-
/** Satellites used for the fix, or null when the provider does not report it. */
|
|
6341
|
-
satellites: number | null;
|
|
6342
|
-
/** Ground speed in m/s, or null when the device doesn't report one. */
|
|
6343
|
-
speed: number | null;
|
|
6344
|
-
/** Fix time in epoch milliseconds. */
|
|
6345
|
-
timestamp: number;
|
|
6346
|
-
}
|
|
6347
|
-
interface AppState {
|
|
6348
|
-
projectName: string;
|
|
6349
|
-
projectPath: string | null;
|
|
6350
|
-
projectGeneration: number;
|
|
6351
|
-
isDirty: boolean;
|
|
6352
|
-
mapView: MapViewState;
|
|
6353
|
-
basemapStyleUrl: string;
|
|
6354
|
-
basemapVisible: boolean;
|
|
6355
|
-
basemapOpacity: number;
|
|
6356
|
-
blankBackgroundColor: string | null;
|
|
6357
|
-
layers: GeoLibreLayer[];
|
|
6358
|
-
layerGroups: LayerGroup[];
|
|
6359
|
-
preferences: ProjectPreferences;
|
|
6360
|
-
projectPlugins: ProjectPluginState | null;
|
|
6361
|
-
legend: LegendConfig;
|
|
6362
|
-
/** Print Layout composer settings for the open project (discussion #1992). */
|
|
6363
|
-
printLayout: PrintLayoutConfig;
|
|
6364
|
-
storymap: StoryMap | null;
|
|
6365
|
-
/** Saved processing pipelines (batch/model chaining; issue #344). */
|
|
6366
|
-
models: ProcessingModel[];
|
|
6367
|
-
/**
|
|
6368
|
-
* App-level Style Manager library (issue #1294). Lives outside the project
|
|
6369
|
-
* lifecycle: never serialized into the project file, untouched by
|
|
6370
|
-
* newProject/loadProject, and persisted by the desktop app (IndexedDB).
|
|
6371
|
-
*/
|
|
6372
|
-
styleLibrary: StyleLibraryEntry[];
|
|
6373
|
-
/**
|
|
6374
|
-
* App-level Layer Library (issue #1520) — the Browser panel's My Data
|
|
6375
|
-
* section. Like {@link styleLibrary} it lives outside the project lifecycle:
|
|
6376
|
-
* never serialized into the project file, untouched by newProject/loadProject,
|
|
6377
|
-
* and persisted by the desktop app (IndexedDB). Most recently saved first.
|
|
6378
|
-
*/
|
|
6379
|
-
layerLibrary: LayerLibraryEntry[];
|
|
6380
|
-
/**
|
|
6381
|
-
* App-level Template Library. Persisted by the desktop app (IndexedDB).
|
|
6382
|
-
*/
|
|
6383
|
-
templateLibrary: ProjectTemplateEntry[];
|
|
6886
|
+
//#region src/store/capabilities-slice.d.ts
|
|
6887
|
+
interface CapabilitiesSlice {
|
|
6384
6888
|
/**
|
|
6385
|
-
*
|
|
6386
|
-
*
|
|
6889
|
+
* What this *deployment* is allowed to do (issue #1673). Set once at startup
|
|
6890
|
+
* from the deployment configuration; never from a project file, a URL
|
|
6891
|
+
* parameter, or anything else the visitor controls, and never edited from the
|
|
6892
|
+
* UI. Defaults to the full set so an unconfigured build behaves as before.
|
|
6893
|
+
*
|
|
6894
|
+
* Excluded from the project file and from undo history: it describes the
|
|
6895
|
+
* server that served the app, not the document being edited.
|
|
6387
6896
|
*/
|
|
6388
|
-
|
|
6389
|
-
/** Recorded processing tool runs, oldest first (Processing History; #1292). */
|
|
6390
|
-
processingHistory: ProcessingRun[];
|
|
6391
|
-
/** Saved Dashboard panel chart widgets (issue #401). */
|
|
6392
|
-
widgets: DashboardWidget[];
|
|
6393
|
-
/** Number of columns in the Dashboard widget grid. */
|
|
6394
|
-
dashboardColumns: number;
|
|
6897
|
+
deploymentCapabilities: ReadonlySet<DeploymentCapability>;
|
|
6395
6898
|
/**
|
|
6396
|
-
*
|
|
6397
|
-
*
|
|
6398
|
-
*
|
|
6899
|
+
* Ephemeral application capability model (issue #1672). Gating role and
|
|
6900
|
+
* privileges for the current session/deployment. Excluded from the project file
|
|
6901
|
+
* and undo history.
|
|
6399
6902
|
*/
|
|
6400
|
-
|
|
6903
|
+
capabilities: AppCapabilities;
|
|
6401
6904
|
/**
|
|
6402
|
-
*
|
|
6403
|
-
*
|
|
6905
|
+
* Narrow what this deployment may do. Intended for the startup path only —
|
|
6906
|
+
* calling it later would leave already-rendered surfaces stale.
|
|
6404
6907
|
*/
|
|
6405
|
-
|
|
6406
|
-
/** User-entered label for the primary pane (shown only in multi-map mode). */
|
|
6407
|
-
primaryMapLabel: string;
|
|
6908
|
+
setDeploymentCapabilities: (capabilities: Iterable<DeploymentCapability>) => void;
|
|
6408
6909
|
/**
|
|
6409
|
-
*
|
|
6410
|
-
*
|
|
6411
|
-
* keeps the camera, basemap, layers, groups, visibility, and opacity — it
|
|
6412
|
-
* only changes what draws them. Independent of `mapLayout`: switching never
|
|
6413
|
-
* adds or removes panes.
|
|
6910
|
+
* Assign an application role (e.g. "viewer", "editor", "publisher", "administrator", "custom"),
|
|
6911
|
+
* deriving the effective privileges and optional reason.
|
|
6414
6912
|
*/
|
|
6415
|
-
|
|
6416
|
-
|
|
6417
|
-
|
|
6418
|
-
|
|
6419
|
-
|
|
6420
|
-
|
|
6421
|
-
|
|
6422
|
-
|
|
6423
|
-
|
|
6913
|
+
setAppRole: (role: AppRole, options?: {
|
|
6914
|
+
customPrivileges?: AppPrivilege[];
|
|
6915
|
+
reason?: string;
|
|
6916
|
+
}) => void;
|
|
6917
|
+
/** Set explicit custom privileges and an optional reason. */
|
|
6918
|
+
setAppPrivileges: (privileges: AppPrivilege[], reason?: string) => void;
|
|
6919
|
+
/** Grant an individual application privilege. */
|
|
6920
|
+
grantAppPrivilege: (privilege: AppPrivilege) => void;
|
|
6921
|
+
/** Revoke an individual application privilege with an optional reason. */
|
|
6922
|
+
revokeAppPrivilege: (privilege: AppPrivilege, reason?: string) => void;
|
|
6923
|
+
/** Reset application capabilities back to the default unconstrained Administrator role. */
|
|
6924
|
+
resetAppCapabilities: () => void;
|
|
6925
|
+
/** Check if the current capabilities grant the requested privilege. */
|
|
6926
|
+
hasAppPrivilege: (privilege: AppPrivilege) => boolean;
|
|
6927
|
+
}
|
|
6928
|
+
//#endregion
|
|
6929
|
+
//#region src/store/collaboration-slice.d.ts
|
|
6930
|
+
/**
|
|
6931
|
+
* A fresh, inactive collaboration slice (no live session). Frozen (like
|
|
6932
|
+
* DEFAULT_LEGEND_CONFIG) to guard against accidental in-place mutation; store
|
|
6933
|
+
* actions always produce new objects via spread, so the frozen default is only
|
|
6934
|
+
* ever read.
|
|
6935
|
+
*/
|
|
6936
|
+
export declare const DEFAULT_COLLABORATION_STATE: CollaborationState;
|
|
6937
|
+
interface CollaborationSlice {
|
|
6938
|
+
collaboration: CollaborationState;
|
|
6939
|
+
setCollaboration: (patch: Partial<CollaborationState>) => void;
|
|
6940
|
+
updateCollaborationPresence: (clientId: string, presence: CollaborationPresence | null) => void;
|
|
6941
|
+
/** Append a chat message to the session log (bounded; #754). */
|
|
6942
|
+
addCollaborationChat: (message: CollaborationChatMessage) => void;
|
|
6943
|
+
resetCollaboration: () => void;
|
|
6944
|
+
}
|
|
6945
|
+
//#endregion
|
|
6946
|
+
//#region src/store/layer-groups-slice.d.ts
|
|
6947
|
+
interface LayerGroupsSlice {
|
|
6948
|
+
layerGroups: LayerGroup[];
|
|
6949
|
+
addLayerGroup: (name?: string, layerIds?: string[]) => string;
|
|
6950
|
+
removeLayerGroup: (id: string, options?: {
|
|
6951
|
+
removeChildren?: boolean;
|
|
6952
|
+
}) => void;
|
|
6953
|
+
renameLayerGroup: (id: string, name: string) => void;
|
|
6954
|
+
setLayerGroupVisibility: (id: string, visible: boolean) => void;
|
|
6955
|
+
setLayerGroupOpacity: (id: string, opacity: number) => void;
|
|
6956
|
+
toggleLayerGroupCollapsed: (id: string) => void;
|
|
6957
|
+
moveLayerToGroup: (layerId: string, groupId: string | null, beforeLayerId?: string | null) => void;
|
|
6958
|
+
moveLayersToGroup: (layerIds: string[], groupId: string | null, beforeLayerId?: string | null) => void;
|
|
6959
|
+
moveLayerGroupToGroup: (id: string, parentId: string | null) => void;
|
|
6960
|
+
reorderLayerGroup: (id: string, direction: "up" | "down") => void;
|
|
6961
|
+
/**
|
|
6962
|
+
* Sort a group's direct children by name, A to Z or Z to A (top of panel
|
|
6963
|
+
* first), collating by `locale` (the app's display language) when given.
|
|
6424
6964
|
*/
|
|
6425
|
-
|
|
6965
|
+
sortLayerGroup: (id: string, order: LayerGroupSortOrder, locale?: string) => void;
|
|
6966
|
+
}
|
|
6967
|
+
//#endregion
|
|
6968
|
+
//#region src/store/layers-slice.d.ts
|
|
6969
|
+
interface LayersSlice {
|
|
6970
|
+
layers: GeoLibreLayer[];
|
|
6971
|
+
addLayer: (layer: GeoLibreLayer, beforeLayerId?: string | null) => void;
|
|
6972
|
+
removeLayer: (id: string) => void;
|
|
6973
|
+
updateLayer: (id: string, patch: Partial<GeoLibreLayer>) => void;
|
|
6974
|
+
setLayerVisibility: (id: string, visible: boolean) => void;
|
|
6975
|
+
setLayerOpacity: (id: string, opacity: number) => void;
|
|
6976
|
+
setLayerStyle: (id: string, style: Partial<LayerStyle>) => void;
|
|
6426
6977
|
/**
|
|
6427
|
-
*
|
|
6428
|
-
*
|
|
6429
|
-
*
|
|
6978
|
+
* Transient clipboard holding a layer's symbology, captured by
|
|
6979
|
+
* {@link copyLayerStyle} and applied by {@link pasteLayerStyle} (copy/paste
|
|
6980
|
+
* styles, issue #1339). Runtime-only: excluded from undo history
|
|
6981
|
+
* (`partialize` never lists it) and from the saved project. `null` until a
|
|
6982
|
+
* style is copied this session. Cleared by `newProject`/`loadProject` so a
|
|
6983
|
+
* paste can't apply an entry from a different project; it deliberately
|
|
6984
|
+
* survives undo/redo within a project (it holds a deep snapshot, not a live
|
|
6985
|
+
* layer reference, so a paste stays valid even if the source layer is undone
|
|
6986
|
+
* away — only the displayed source name may then be stale).
|
|
6430
6987
|
*/
|
|
6431
|
-
|
|
6432
|
-
pointerCoords: [number, number] | null;
|
|
6988
|
+
copiedLayerStyle: CopiedLayerStyle | null;
|
|
6433
6989
|
/**
|
|
6434
|
-
*
|
|
6435
|
-
*
|
|
6436
|
-
*
|
|
6437
|
-
*
|
|
6438
|
-
*
|
|
6990
|
+
* Snapshot the given layer's style into {@link copiedLayerStyle} so it can be
|
|
6991
|
+
* pasted onto a compatible layer. No-op when the layer is missing or has no
|
|
6992
|
+
* copyable symbology (leaving any prior clipboard entry untouched). Returns
|
|
6993
|
+
* `true` when a style was captured, so callers can skip the confirmation on a
|
|
6994
|
+
* no-op.
|
|
6439
6995
|
*/
|
|
6440
|
-
|
|
6996
|
+
copyLayerStyle: (id: string) => boolean;
|
|
6441
6997
|
/**
|
|
6442
|
-
*
|
|
6443
|
-
*
|
|
6444
|
-
*
|
|
6445
|
-
*
|
|
6446
|
-
* Null before the map loads, or when MapLibre cannot report it.
|
|
6998
|
+
* Apply the {@link copiedLayerStyle} clipboard entry onto the given layer.
|
|
6999
|
+
* No-op when the clipboard is empty, the layer is missing, or the entry's
|
|
7000
|
+
* style family does not match the target layer's. Returns `true` when the
|
|
7001
|
+
* style was applied, so callers can skip the confirmation on a no-op.
|
|
6447
7002
|
*/
|
|
6448
|
-
|
|
6449
|
-
/** Live GPS fix for the status bar, or null while GPS tracking is off. */
|
|
6450
|
-
gpsStatus: GpsStatusFix | null;
|
|
6451
|
-
/** Anchored review comments on map points or features (issue #1518). */
|
|
6452
|
-
comments: ProjectComment[];
|
|
6453
|
-
metadata: Record<string, unknown>;
|
|
6454
|
-
recentProjects: RecentProjectEntry[];
|
|
6455
|
-
attributeFilter: string;
|
|
7003
|
+
pasteLayerStyle: (id: string) => boolean;
|
|
6456
7004
|
/**
|
|
6457
|
-
*
|
|
6458
|
-
*
|
|
6459
|
-
*
|
|
6460
|
-
*
|
|
7005
|
+
* Restyle layers from layer styles file entries matched by layer name
|
|
7006
|
+
* (Import Layer Styles, and the Startup setting's auto-apply). Each matched
|
|
7007
|
+
* layer is patched the way {@link pasteLayerStyle} would patch it, all in a
|
|
7008
|
+
* single store update so the import is one undo step.
|
|
6461
7009
|
*
|
|
6462
|
-
*
|
|
6463
|
-
*
|
|
7010
|
+
* @param entries - The parsed style entries.
|
|
7011
|
+
* @param layerIds - Restrict the restyle to these layers; every layer when
|
|
7012
|
+
* omitted.
|
|
7013
|
+
* @returns Each restyled layer's id with the index of the entry it took, in
|
|
7014
|
+
* stack order.
|
|
7015
|
+
*/
|
|
7016
|
+
applyLayerStyleEntries: (entries: readonly LayerStyleFileEntry[], layerIds?: readonly string[]) => {
|
|
7017
|
+
layerId: string;
|
|
7018
|
+
entryIndex: number;
|
|
7019
|
+
}[];
|
|
7020
|
+
/**
|
|
7021
|
+
* Replace a layer's persistent attribute joins and immediately re-derive its
|
|
7022
|
+
* joined columns (strip what the previous joins added, apply the new list).
|
|
7023
|
+
* Pass an empty array to detach every join and restore the base attributes.
|
|
6464
7024
|
*/
|
|
6465
|
-
|
|
6466
|
-
collaboration: CollaborationState;
|
|
7025
|
+
setLayerJoins: (id: string, joins: LayerJoin[]) => void;
|
|
6467
7026
|
/**
|
|
6468
|
-
*
|
|
6469
|
-
*
|
|
6470
|
-
*
|
|
7027
|
+
* Replace the layer's Attribute Form designer configuration (per-field edit
|
|
7028
|
+
* widgets, constraints, conditional visibility). Pass `undefined` to remove
|
|
7029
|
+
* the form config entirely.
|
|
6471
7030
|
*/
|
|
6472
|
-
|
|
6473
|
-
ui: {
|
|
6474
|
-
processingOpen: boolean;
|
|
6475
|
-
/**
|
|
6476
|
-
* Tool id to preselect when the Whitebox toolbox dialog opens, set when the
|
|
6477
|
-
* user picks a specific tool from the Processing menu's category submenus.
|
|
6478
|
-
* Consumed and cleared by ProcessingDialog. Null means "no preselection".
|
|
6479
|
-
*/
|
|
6480
|
-
processingInitialTool: string | null;
|
|
6481
|
-
conversionOpen: ConversionToolKind | null;
|
|
6482
|
-
vectorToolOpen: VectorToolKind | null;
|
|
6483
|
-
networkToolOpen: NetworkToolKind | null;
|
|
6484
|
-
statisticsToolOpen: StatisticsToolKind | null;
|
|
6485
|
-
rasterToolOpen: RasterToolKind | null;
|
|
6486
|
-
segmentationOpen: boolean;
|
|
6487
|
-
objectDetectionOpen: boolean;
|
|
6488
|
-
segmentEverythingOpen: boolean;
|
|
6489
|
-
geocodeOpen: boolean;
|
|
6490
|
-
sqlWorkspaceOpen: boolean;
|
|
6491
|
-
loadEditorFeaturesOpen: boolean;
|
|
6492
|
-
loadEditorFeaturesLayerId: string | null;
|
|
6493
|
-
pythonConsoleOpen: boolean;
|
|
6494
|
-
notebookOpen: boolean;
|
|
6495
|
-
assistantOpen: boolean;
|
|
6496
|
-
attributeTableOpen: boolean;
|
|
6497
|
-
/** Whether the Raster Attribute Table bottom panel is open (issue #1307). */
|
|
6498
|
-
rasterAttributeTableOpen: boolean;
|
|
6499
|
-
dashboardOpen: boolean;
|
|
6500
|
-
storymapPanelOpen: boolean;
|
|
6501
|
-
storymapPresenting: boolean;
|
|
6502
|
-
storymapReturnToEditor: boolean;
|
|
6503
|
-
/**
|
|
6504
|
-
* Layer opacities the active story presentation has applied so far, keyed
|
|
6505
|
-
* by store layer id. Playback fades layers by writing MapLibre paint
|
|
6506
|
-
* properties directly (never the persisted `layers[].opacity`), so this is
|
|
6507
|
-
* how renderers outside MapLibre's paint model (deck.gl diagrams, 3D
|
|
6508
|
-
* Z-value geometry) and the on-map Legend follow a chapter's fades. Empty
|
|
6509
|
-
* while not presenting; never saved with the project.
|
|
6510
|
-
*/
|
|
6511
|
-
storymapLayerOpacity: Record<string, number>;
|
|
6512
|
-
storymapComposingId: string | null;
|
|
6513
|
-
/** The Batch tools dialog (run one tool across many layers). */
|
|
6514
|
-
batchToolsOpen: boolean;
|
|
6515
|
-
/** The Model Builder canvas panel (author a processing graph). */
|
|
6516
|
-
modelBuilderOpen: boolean;
|
|
6517
|
-
/** One-shot request for Model Builder to load a saved model. */
|
|
6518
|
-
modelBuilderRequestedModelId: string | null;
|
|
6519
|
-
/** Style Manager dialog visibility (issue #1294). */
|
|
6520
|
-
styleManagerOpen: boolean;
|
|
6521
|
-
/** Processing History panel visibility (#1292). */
|
|
6522
|
-
processingHistoryOpen: boolean;
|
|
6523
|
-
/** Select by Expression dialog visibility (#1314). */
|
|
6524
|
-
selectByExpressionOpen: boolean;
|
|
6525
|
-
selectByExpressionLayerId: string | null;
|
|
6526
|
-
/** Select by Location dialog visibility (#1314). */
|
|
6527
|
-
selectByLocationOpen: boolean;
|
|
6528
|
-
/** Same contract as `selectByExpressionLayerId`, for Select by Location. */
|
|
6529
|
-
selectByLocationLayerId: string | null;
|
|
6530
|
-
/**
|
|
6531
|
-
* Pending "re-run from History" request. Written by the History panel just
|
|
6532
|
-
* before it opens the target processing dialog; consumed and cleared by
|
|
6533
|
-
* that dialog once it has pre-filled its parameter form. Null when idle.
|
|
6534
|
-
*/
|
|
6535
|
-
processingRerun: ProcessingRerunRequest | null;
|
|
6536
|
-
zoomToSelectedFeature: boolean;
|
|
6537
|
-
collaborateDialogOpen: boolean;
|
|
6538
|
-
};
|
|
6539
|
-
setPointerCoords: (coords: [number, number] | null) => void;
|
|
6540
|
-
setPointerElevation: (elevation: number | null) => void;
|
|
6541
|
-
setCameraAltitude: (altitude: number | null) => void;
|
|
6542
|
-
setGpsStatus: (fix: GpsStatusFix | null) => void;
|
|
6543
|
-
setCollaboration: (patch: Partial<CollaborationState>) => void;
|
|
6544
|
-
updateCollaborationPresence: (clientId: string, presence: CollaborationPresence | null) => void;
|
|
6545
|
-
/** Append a chat message to the session log (bounded; #754). */
|
|
6546
|
-
addCollaborationChat: (message: CollaborationChatMessage) => void;
|
|
6547
|
-
resetCollaboration: () => void;
|
|
6548
|
-
setMapView: (view: Partial<MapViewState>, markDirty?: boolean) => void;
|
|
7031
|
+
setLayerAttributeForm: (id: string, attributeForm: AttributeFormConfig | undefined) => void;
|
|
6549
7032
|
/**
|
|
6550
|
-
*
|
|
6551
|
-
*
|
|
6552
|
-
*
|
|
7033
|
+
* Replace the layer's popup/tooltip design (which fields the Identify popup
|
|
7034
|
+
* shows, in what order and under what labels, plus the hover tooltip). Pass
|
|
7035
|
+
* `undefined` to restore the default full-property dump.
|
|
6553
7036
|
*/
|
|
6554
|
-
|
|
6555
|
-
/** Toggle synchronized camera across all panes. */
|
|
6556
|
-
setSyncView: (syncView: boolean) => void;
|
|
6557
|
-
/** Patch one secondary pane's camera by id (no-op if the id is unknown). */
|
|
6558
|
-
setSecondaryMapView: (id: string, view: Partial<MapViewState>, markDirty?: boolean) => void;
|
|
7037
|
+
setLayerPopup: (id: string, popup: LayerPopupConfig | undefined) => void;
|
|
6559
7038
|
/**
|
|
6560
|
-
*
|
|
6561
|
-
*
|
|
6562
|
-
*
|
|
7039
|
+
* Replace the layer's editor tracking configuration (whether creation/edit
|
|
7040
|
+
* author and timestamp columns are maintained, and under which names). Pass
|
|
7041
|
+
* `undefined` to drop the configuration entirely.
|
|
6563
7042
|
*/
|
|
6564
|
-
|
|
6565
|
-
/** Set the primary pane's custom label. */
|
|
6566
|
-
setPrimaryMapLabel: (label: string) => void;
|
|
7043
|
+
setLayerEditorTracking: (id: string, editorTracking: EditorTrackingConfig | undefined) => void;
|
|
6567
7044
|
/**
|
|
6568
|
-
*
|
|
6569
|
-
*
|
|
6570
|
-
*
|
|
7045
|
+
* Replace a layer's virtual fields and immediately re-derive its computed
|
|
7046
|
+
* columns (strip what the previous fields added, evaluate the new list).
|
|
7047
|
+
* Pass an empty array to detach every virtual field.
|
|
6571
7048
|
*/
|
|
6572
|
-
|
|
6573
|
-
/** Set one secondary pane's custom label (no-op if the id is unknown). */
|
|
6574
|
-
setSecondaryMapLabel: (id: string, label: string) => void;
|
|
7049
|
+
setLayerVirtualFields: (id: string, fields: LayerVirtualField[]) => void;
|
|
6575
7050
|
/**
|
|
6576
|
-
*
|
|
6577
|
-
*
|
|
7051
|
+
* Replace a layer's quick filters (issue #2114). The controls persist with
|
|
7052
|
+
* the project and are compiled to a MapLibre filter at sync time, so this
|
|
7053
|
+
* only stores state — nothing re-derives the layer's data. Pass an empty
|
|
7054
|
+
* array to remove every control.
|
|
6578
7055
|
*/
|
|
6579
|
-
|
|
6580
|
-
/**
|
|
6581
|
-
|
|
6582
|
-
|
|
7056
|
+
setLayerQuickFilters: (id: string, filters: LayerQuickFilter[]) => void;
|
|
7057
|
+
/** Set or clear the project-persisted expression filter for a layer. */
|
|
7058
|
+
setLayerFilterExpression: (id: string, expression: unknown[] | null) => void;
|
|
7059
|
+
reorderLayer: (id: string, direction: "up" | "down") => void;
|
|
7060
|
+
moveLayer: (id: string, targetIndex: number) => void;
|
|
7061
|
+
moveLayersRelative: (layerIds: string[], targetLayerId: string, position: "above" | "below") => void;
|
|
7062
|
+
addGeoJsonLayer: (name: string, geojson: FeatureCollection, sourcePath?: string, beforeLayerId?: string | null) => string;
|
|
6583
7063
|
/**
|
|
6584
|
-
*
|
|
6585
|
-
*
|
|
6586
|
-
*
|
|
7064
|
+
* Add a georeferenced image overlay (a MapLibre `image` source rendered as a
|
|
7065
|
+
* raster layer) from an image URL and its four corner coordinates, and return
|
|
7066
|
+
* its id. Used for KML/KMZ `<GroundOverlay>` imports; the layer persists and
|
|
7067
|
+
* renders exactly like a Raster Georeferencer overlay. Corners are `[lng,
|
|
7068
|
+
* lat]` in top-left, top-right, bottom-right, bottom-left order.
|
|
6587
7069
|
*/
|
|
6588
|
-
|
|
7070
|
+
addImageOverlayLayer: (name: string, source: {
|
|
7071
|
+
url: string;
|
|
7072
|
+
coordinates: [number, number][];
|
|
7073
|
+
}, options?: {
|
|
7074
|
+
opacity?: number;
|
|
7075
|
+
bounds?: [number, number, number, number];
|
|
7076
|
+
sourcePath?: string;
|
|
7077
|
+
/** Initial visibility (default true); a time-slider frame past the first
|
|
7078
|
+
* starts hidden. */
|
|
7079
|
+
visible?: boolean;
|
|
7080
|
+
/** Epoch-ms time bounds of a KML `<TimeSpan>`/`<TimeStamp>` frame; the
|
|
7081
|
+
* Time Slider toggles this frame's visibility by the current date. */
|
|
7082
|
+
timeSpan?: {
|
|
7083
|
+
begin: number | null;
|
|
7084
|
+
end: number | null;
|
|
7085
|
+
};
|
|
7086
|
+
/**
|
|
7087
|
+
* What produced the overlay, e.g. a NetCDF grid baked to pixels. Defaults
|
|
7088
|
+
* to the KML ground overlay this was first written for; panels gate their
|
|
7089
|
+
* per-source controls on it.
|
|
7090
|
+
*/
|
|
7091
|
+
sourceKind?: string;
|
|
7092
|
+
/** Extra metadata merged onto the layer (e.g. a symbology record). */
|
|
7093
|
+
metadata?: Record<string, unknown>;
|
|
7094
|
+
}, beforeLayerId?: string | null) => string;
|
|
6589
7095
|
/**
|
|
6590
|
-
*
|
|
6591
|
-
*
|
|
6592
|
-
*
|
|
7096
|
+
* Add a native raster tile layer (XYZ, WMS, or WMTS) from one or more tile
|
|
7097
|
+
* URL templates and return its id. The layer appears in the Layers panel and
|
|
7098
|
+
* persists with the project exactly like a layer added through the Add Data
|
|
7099
|
+
* dialog, so callers (e.g. an external plugin) do not have to touch MapLibre
|
|
7100
|
+
* directly. See {@link AddTileLayerOptions}.
|
|
6593
7101
|
*/
|
|
6594
|
-
|
|
6595
|
-
|
|
6596
|
-
|
|
6597
|
-
|
|
6598
|
-
|
|
6599
|
-
setLegend: (legend: LegendConfig) => void;
|
|
7102
|
+
addTileLayer: (name: string, options: AddTileLayerOptions, beforeLayerId?: string | null) => string;
|
|
7103
|
+
}
|
|
7104
|
+
//#endregion
|
|
7105
|
+
//#region src/store/libraries-slice.d.ts
|
|
7106
|
+
interface LibrariesSlice {
|
|
6600
7107
|
/**
|
|
6601
|
-
*
|
|
6602
|
-
*
|
|
6603
|
-
*
|
|
7108
|
+
* App-level Style Manager library (issue #1294). Lives outside the project
|
|
7109
|
+
* lifecycle: never serialized into the project file, untouched by
|
|
7110
|
+
* newProject/loadProject, and persisted by the desktop app (IndexedDB).
|
|
6604
7111
|
*/
|
|
6605
|
-
|
|
6606
|
-
setProjectPlugins: (projectPlugins: ProjectPluginState | null, shouldMarkDirty?: boolean) => void;
|
|
6607
|
-
selectLayer: (id: string | null) => void;
|
|
6608
|
-
selectFeature: (id: string | null) => void;
|
|
7112
|
+
styleLibrary: StyleLibraryEntry[];
|
|
6609
7113
|
/**
|
|
6610
|
-
*
|
|
6611
|
-
*
|
|
6612
|
-
*
|
|
7114
|
+
* App-level Layer Library (issue #1520) — the Browser panel's My Data
|
|
7115
|
+
* section. Like {@link styleLibrary} it lives outside the project lifecycle:
|
|
7116
|
+
* never serialized into the project file, untouched by newProject/loadProject,
|
|
7117
|
+
* and persisted by the desktop app (IndexedDB). Most recently saved first.
|
|
6613
7118
|
*/
|
|
6614
|
-
|
|
6615
|
-
setIdentifyLayer: (id: string | null) => void;
|
|
6616
|
-
setAttributeFilter: (filter: string) => void;
|
|
6617
|
-
setProcessingOpen: (open: boolean) => void;
|
|
6618
|
-
setProcessingInitialTool: (toolId: string | null) => void;
|
|
6619
|
-
setConversionOpen: (kind: ConversionToolKind | null) => void;
|
|
6620
|
-
setVectorToolOpen: (kind: VectorToolKind | null) => void;
|
|
6621
|
-
setNetworkToolOpen: (kind: NetworkToolKind | null) => void;
|
|
6622
|
-
setStatisticsToolOpen: (kind: StatisticsToolKind | null) => void;
|
|
6623
|
-
setRasterToolOpen: (kind: RasterToolKind | null) => void;
|
|
6624
|
-
setSegmentationOpen: (open: boolean) => void;
|
|
6625
|
-
setObjectDetectionOpen: (open: boolean) => void;
|
|
6626
|
-
setSegmentEverythingOpen: (open: boolean) => void;
|
|
6627
|
-
setGeocodeOpen: (open: boolean) => void;
|
|
6628
|
-
setSqlWorkspaceOpen: (open: boolean) => void;
|
|
6629
|
-
setLoadEditorFeaturesOpen: (open: boolean, layerId?: string | null) => void;
|
|
6630
|
-
setPythonConsoleOpen: (open: boolean) => void;
|
|
6631
|
-
setNotebookOpen: (open: boolean) => void;
|
|
6632
|
-
setAssistantOpen: (open: boolean) => void;
|
|
6633
|
-
setAttributeTableOpen: (open: boolean) => void;
|
|
6634
|
-
setRasterAttributeTableOpen: (open: boolean) => void;
|
|
6635
|
-
setDashboardOpen: (open: boolean) => void;
|
|
6636
|
-
setStorymapPanelOpen: (open: boolean) => void;
|
|
6637
|
-
setStorymapPresenting: (presenting: boolean, returnToEditor?: boolean) => void;
|
|
7119
|
+
layerLibrary: LayerLibraryEntry[];
|
|
6638
7120
|
/**
|
|
6639
|
-
*
|
|
6640
|
-
* presentation's running map (see `ui.storymapLayerOpacity`).
|
|
7121
|
+
* App-level Template Library. Persisted by the desktop app (IndexedDB).
|
|
6641
7122
|
*/
|
|
6642
|
-
|
|
6643
|
-
|
|
6644
|
-
|
|
6645
|
-
|
|
6646
|
-
|
|
6647
|
-
|
|
6648
|
-
/** Open/close Select by Expression, optionally preselecting a target layer. */
|
|
6649
|
-
setSelectByExpressionOpen: (open: boolean, layerId?: string | null) => void;
|
|
6650
|
-
/** Open/close Select by Location, optionally preselecting a target layer. */
|
|
6651
|
-
setSelectByLocationOpen: (open: boolean, layerId?: string | null) => void;
|
|
6652
|
-
setProcessingRerun: (request: ProcessingRerunRequest | null) => void;
|
|
6653
|
-
setCollaborateDialogOpen: (open: boolean) => void;
|
|
6654
|
-
setZoomToSelectedFeature: (enabled: boolean) => void;
|
|
6655
|
-
setStyleManagerOpen: (open: boolean) => void;
|
|
7123
|
+
templateLibrary: ProjectTemplateEntry[];
|
|
7124
|
+
/**
|
|
7125
|
+
* Project-scoped Style Manager entries (issue #1294), serialized into the
|
|
7126
|
+
* `.geolibre.json` `styleLibrary` array and replaced on project load.
|
|
7127
|
+
*/
|
|
7128
|
+
projectStyleLibrary: StyleLibraryEntry[];
|
|
6656
7129
|
/**
|
|
6657
7130
|
* Replace the app-level style library wholesale. Used by the persistence
|
|
6658
7131
|
* layer on startup and by bundle imports.
|
|
@@ -6665,35 +7138,125 @@ interface AppState {
|
|
|
6665
7138
|
* unrelated entry after loading a project authored elsewhere. Project-scope
|
|
6666
7139
|
* saves mark the project dirty.
|
|
6667
7140
|
*/
|
|
6668
|
-
saveStyleLibraryEntry: (entry: StyleLibraryEntry, scope?: "app" | "project") => void;
|
|
7141
|
+
saveStyleLibraryEntry: (entry: StyleLibraryEntry, scope?: "app" | "project") => void;
|
|
7142
|
+
/**
|
|
7143
|
+
* Remove a Style Manager entry by id. When `scope` is given only that list
|
|
7144
|
+
* is touched — the two scopes can legitimately hold the same id after
|
|
7145
|
+
* loading a project authored elsewhere, and deleting a project entry must
|
|
7146
|
+
* not erase a local app-library style (or vice versa). Omitting `scope`
|
|
7147
|
+
* removes the id from both lists.
|
|
7148
|
+
*/
|
|
7149
|
+
deleteStyleLibraryEntry: (id: string, scope?: "app" | "project") => void;
|
|
7150
|
+
/**
|
|
7151
|
+
* Replace the app-level Layer Library wholesale. Used by the persistence
|
|
7152
|
+
* layer on startup and by bundle imports.
|
|
7153
|
+
*/
|
|
7154
|
+
setLayerLibrary: (entries: LayerLibraryEntry[]) => void;
|
|
7155
|
+
/**
|
|
7156
|
+
* Insert or replace (matching by `id`) a Layer Library entry. New entries go
|
|
7157
|
+
* to the front so the most recently saved layer leads the My Data section.
|
|
7158
|
+
*/
|
|
7159
|
+
saveLayerLibraryEntry: (entry: LayerLibraryEntry) => void;
|
|
7160
|
+
/** Rename a Layer Library entry; a blank name is ignored. */
|
|
7161
|
+
renameLayerLibraryEntry: (id: string, name: string) => void;
|
|
7162
|
+
/** Remove a Layer Library entry by id. */
|
|
7163
|
+
deleteLayerLibraryEntry: (id: string) => void;
|
|
7164
|
+
/** Replace the app-level template library wholesale. */
|
|
7165
|
+
setTemplateLibrary: (templates: ProjectTemplateEntry[]) => void;
|
|
7166
|
+
/** Insert or replace a template in the Template Library. */
|
|
7167
|
+
saveTemplateEntry: (entry: ProjectTemplateEntry) => void;
|
|
7168
|
+
/** Remove a template entry by id from the Template Library. */
|
|
7169
|
+
deleteTemplateEntry: (id: string) => void;
|
|
7170
|
+
}
|
|
7171
|
+
//#endregion
|
|
7172
|
+
//#region src/store/map-view-slice.d.ts
|
|
7173
|
+
interface MapViewSlice {
|
|
7174
|
+
mapView: MapViewState;
|
|
7175
|
+
basemapStyleUrl: string;
|
|
7176
|
+
basemapVisible: boolean;
|
|
7177
|
+
basemapOpacity: number;
|
|
7178
|
+
blankBackgroundColor: string | null;
|
|
7179
|
+
preferences: ProjectPreferences;
|
|
7180
|
+
/**
|
|
7181
|
+
* Multi-map grid layout (issue: split/grid view). A 1x1 grid is the normal
|
|
7182
|
+
* single-map workspace. `rows * cols` panes are shown; pane 0 is the primary
|
|
7183
|
+
* map driven by `mapView` / `basemap*`, panes 1.. are `secondaryMapViews`.
|
|
7184
|
+
*/
|
|
7185
|
+
mapLayout: MapGridLayout;
|
|
7186
|
+
/**
|
|
7187
|
+
* Secondary map panes (everything past the primary pane). The store keeps
|
|
7188
|
+
* exactly `rows * cols - 1` entries in sync with `mapLayout`.
|
|
7189
|
+
*/
|
|
7190
|
+
secondaryMapViews: SecondaryMapView[];
|
|
7191
|
+
/** User-entered label for the primary pane (shown only in multi-map mode). */
|
|
7192
|
+
primaryMapLabel: string;
|
|
7193
|
+
/**
|
|
7194
|
+
* Which engine draws the primary map area (issue #2217): the 2D MapLibre map
|
|
7195
|
+
* or the 3D Cesium globe. Both render the same store state, so switching
|
|
7196
|
+
* keeps the camera, basemap, layers, groups, visibility, and opacity — it
|
|
7197
|
+
* only changes what draws them. Independent of `mapLayout`: switching never
|
|
7198
|
+
* adds or removes panes.
|
|
7199
|
+
*/
|
|
7200
|
+
primaryRenderer: MapRendererKind;
|
|
7201
|
+
setMapView: (view: Partial<MapViewState>, markDirty?: boolean) => void;
|
|
7202
|
+
/**
|
|
7203
|
+
* Resize the map grid. Clamps `rows`/`cols` into range and grows/shrinks
|
|
7204
|
+
* `secondaryMapViews` so it always holds `rows * cols - 1` panes; new panes
|
|
7205
|
+
* clone the primary map's current camera and basemap.
|
|
7206
|
+
*/
|
|
7207
|
+
setMapGrid: (rows: number, cols: number) => void;
|
|
7208
|
+
/** Toggle synchronized camera across all panes. */
|
|
7209
|
+
setSyncView: (syncView: boolean) => void;
|
|
7210
|
+
/** Patch one secondary pane's camera by id (no-op if the id is unknown). */
|
|
7211
|
+
setSecondaryMapView: (id: string, view: Partial<MapViewState>, markDirty?: boolean) => void;
|
|
7212
|
+
/**
|
|
7213
|
+
* Override a layer's visibility in one secondary pane (no-op if the pane id is
|
|
7214
|
+
* unknown). The override forces the layer visible/hidden in that pane only,
|
|
7215
|
+
* independent of the primary map's visibility.
|
|
7216
|
+
*/
|
|
7217
|
+
setSecondaryLayerVisibility: (id: string, layerId: string, visible: boolean) => void;
|
|
7218
|
+
/** Set the primary pane's custom label. */
|
|
7219
|
+
setPrimaryMapLabel: (label: string) => void;
|
|
7220
|
+
/**
|
|
7221
|
+
* Switch the primary map area between the 2D map and the 3D globe (no-op if
|
|
7222
|
+
* unchanged). Touches nothing else in the store, so the shared camera, layer,
|
|
7223
|
+
* and basemap state carries straight across the swap.
|
|
7224
|
+
*/
|
|
7225
|
+
setPrimaryRenderer: (renderer: MapRendererKind) => void;
|
|
7226
|
+
/** Set one secondary pane's custom label (no-op if the id is unknown). */
|
|
7227
|
+
setSecondaryMapLabel: (id: string, label: string) => void;
|
|
6669
7228
|
/**
|
|
6670
|
-
*
|
|
6671
|
-
* is
|
|
6672
|
-
* loading a project authored elsewhere, and deleting a project entry must
|
|
6673
|
-
* not erase a local app-library style (or vice versa). Omitting `scope`
|
|
6674
|
-
* removes the id from both lists.
|
|
7229
|
+
* Switch one secondary pane between the 2D map and the 3D globe (no-op if the
|
|
7230
|
+
* id is unknown or the kind is unchanged).
|
|
6675
7231
|
*/
|
|
6676
|
-
|
|
7232
|
+
setSecondaryViewKind: (id: string, viewKind: NonNullable<SecondaryMapView["viewKind"]>) => void;
|
|
7233
|
+
/** Remove one secondary pane and collapse the grid back toward 1x1. */
|
|
7234
|
+
removeSecondaryMapView: (id: string) => void;
|
|
7235
|
+
setBasemapStyleUrl: (url: string) => void;
|
|
6677
7236
|
/**
|
|
6678
|
-
*
|
|
6679
|
-
*
|
|
7237
|
+
* Apply a planetary basemap and sync the project's ellipsoid to the body it
|
|
7238
|
+
* depicts, so measurements and the globe control use that body's radius. Used
|
|
7239
|
+
* by both the basemap picker and the Layers-panel planet switcher.
|
|
6680
7240
|
*/
|
|
6681
|
-
|
|
7241
|
+
applyPlanetaryBasemap: (basemap: PlanetaryBasemap) => void;
|
|
6682
7242
|
/**
|
|
6683
|
-
*
|
|
6684
|
-
*
|
|
7243
|
+
* Return to Earth: apply `styleUrl` (typically the Earth basemap that was
|
|
7244
|
+
* active before a planet was selected, e.g. Liberty) and reset the ellipsoid
|
|
7245
|
+
* to Earth. Used when a planet is deselected in the switcher.
|
|
6685
7246
|
*/
|
|
6686
|
-
|
|
6687
|
-
|
|
6688
|
-
|
|
6689
|
-
|
|
6690
|
-
|
|
6691
|
-
|
|
6692
|
-
|
|
6693
|
-
|
|
6694
|
-
|
|
6695
|
-
/**
|
|
6696
|
-
|
|
7247
|
+
restoreEarthBasemap: (styleUrl: string) => void;
|
|
7248
|
+
setBasemapVisible: (visible: boolean) => void;
|
|
7249
|
+
setBasemapOpacity: (opacity: number) => void;
|
|
7250
|
+
setBlankBackgroundColor: (color: string | null) => void;
|
|
7251
|
+
setPreferences: (preferences: ProjectPreferences) => void;
|
|
7252
|
+
}
|
|
7253
|
+
//#endregion
|
|
7254
|
+
//#region src/store/processing-slice.d.ts
|
|
7255
|
+
interface ProcessingSlice {
|
|
7256
|
+
/** Saved processing pipelines (batch/model chaining; issue #344). */
|
|
7257
|
+
models: ProcessingModel[];
|
|
7258
|
+
/** Recorded processing tool runs, oldest first (Processing History; #1292). */
|
|
7259
|
+
processingHistory: ProcessingRun[];
|
|
6697
7260
|
/** Insert a new model or replace an existing one matching by `id`. */
|
|
6698
7261
|
saveModel: (model: ProcessingModel) => void;
|
|
6699
7262
|
/** Remove a saved model by id. */
|
|
@@ -6704,6 +7267,23 @@ interface AppState {
|
|
|
6704
7267
|
updateProcessingRun: (id: string, patch: Partial<Omit<ProcessingRun, "id">>) => void;
|
|
6705
7268
|
/** Drop all recorded processing runs. */
|
|
6706
7269
|
clearProcessingHistory: () => void;
|
|
7270
|
+
}
|
|
7271
|
+
//#endregion
|
|
7272
|
+
//#region src/store/project-content-slice.d.ts
|
|
7273
|
+
interface ProjectContentSlice {
|
|
7274
|
+
storymap: StoryMap | null;
|
|
7275
|
+
/** Saved Dashboard panel chart widgets (issue #401). */
|
|
7276
|
+
widgets: DashboardWidget[];
|
|
7277
|
+
/** Number of columns in the Dashboard widget grid. */
|
|
7278
|
+
dashboardColumns: number;
|
|
7279
|
+
/** Anchored review comments on map points or features (issue #1518). */
|
|
7280
|
+
comments: ProjectComment[];
|
|
7281
|
+
/**
|
|
7282
|
+
* The loaded project's startup `interaction` block (issue #2688). Applied
|
|
7283
|
+
* once on load and written back unchanged on save; live Identify and control
|
|
7284
|
+
* changes do not edit it.
|
|
7285
|
+
*/
|
|
7286
|
+
projectInteraction: ProjectInteraction | null;
|
|
6707
7287
|
/** Append a new dashboard widget. */
|
|
6708
7288
|
addWidget: (widget: DashboardWidget) => void;
|
|
6709
7289
|
/** Patch an existing dashboard widget by id (no-op if absent). Merges, so an
|
|
@@ -6726,6 +7306,35 @@ interface AppState {
|
|
|
6726
7306
|
updateStoryChapter: (id: string, patch: Partial<StoryChapter>) => void;
|
|
6727
7307
|
removeStoryChapter: (id: string) => void;
|
|
6728
7308
|
moveStoryChapter: (id: string, targetIndex: number) => void;
|
|
7309
|
+
addComment: (comment: ProjectComment) => void;
|
|
7310
|
+
replyToComment: (commentId: string, reply: CommentReply) => void;
|
|
7311
|
+
toggleResolveComment: (commentId: string, resolved?: boolean) => void;
|
|
7312
|
+
deleteComment: (commentId: string) => void;
|
|
7313
|
+
setComments: (comments: ProjectComment[]) => void;
|
|
7314
|
+
}
|
|
7315
|
+
//#endregion
|
|
7316
|
+
//#region src/store/project-slice.d.ts
|
|
7317
|
+
/** Derive a human-friendly display name from a file path or URL. */
|
|
7318
|
+
export declare function projectPathLabel(path: string): string;
|
|
7319
|
+
interface ProjectSlice {
|
|
7320
|
+
projectName: string;
|
|
7321
|
+
projectPath: string | null;
|
|
7322
|
+
projectGeneration: number;
|
|
7323
|
+
isDirty: boolean;
|
|
7324
|
+
projectPlugins: ProjectPluginState | null;
|
|
7325
|
+
legend: LegendConfig;
|
|
7326
|
+
/** Print Layout composer settings for the open project (discussion #1992). */
|
|
7327
|
+
printLayout: PrintLayoutConfig;
|
|
7328
|
+
metadata: Record<string, unknown>;
|
|
7329
|
+
recentProjects: RecentProjectEntry[];
|
|
7330
|
+
setLegend: (legend: LegendConfig) => void;
|
|
7331
|
+
/**
|
|
7332
|
+
* Replace the Print Layout composer settings. A config equal to the current
|
|
7333
|
+
* one is ignored, so re-opening the composer (or a project load seeding the
|
|
7334
|
+
* dialog) never marks the project dirty.
|
|
7335
|
+
*/
|
|
7336
|
+
setPrintLayout: (printLayout: PrintLayoutConfig) => void;
|
|
7337
|
+
setProjectPlugins: (projectPlugins: ProjectPluginState | null, shouldMarkDirty?: boolean) => void;
|
|
6729
7338
|
newProject: (options?: CreateProjectOptions & {
|
|
6730
7339
|
name?: string;
|
|
6731
7340
|
}) => void;
|
|
@@ -6735,179 +7344,271 @@ interface AppState {
|
|
|
6735
7344
|
}) => void;
|
|
6736
7345
|
setProjectPath: (path: string | null) => void;
|
|
6737
7346
|
setProjectName: (name: string) => void;
|
|
6738
|
-
/**
|
|
6739
|
-
* Narrow what this deployment may do. Intended for the startup path only —
|
|
6740
|
-
* calling it later would leave already-rendered surfaces stale.
|
|
6741
|
-
*/
|
|
6742
|
-
setDeploymentCapabilities: (capabilities: Iterable<DeploymentCapability>) => void;
|
|
6743
7347
|
setRecentProjects: (projects: RecentProjectEntry[]) => void;
|
|
6744
7348
|
rememberRecentProject: (entry: RecentProjectEntry) => void;
|
|
6745
7349
|
forgetRecentProject: (path: string) => void;
|
|
6746
7350
|
clearRecentProjects: () => void;
|
|
6747
7351
|
markSaved: () => void;
|
|
7352
|
+
}
|
|
7353
|
+
//#endregion
|
|
7354
|
+
//#region src/store/session-slice.d.ts
|
|
7355
|
+
/**
|
|
7356
|
+
* Latest live device-GPS fix published by the GPS Tracking tool (issue #1316),
|
|
7357
|
+
* read by the status bar readout. Device state, not project state: excluded
|
|
7358
|
+
* from undo history (partialize never lists it) and from project files, and
|
|
7359
|
+
* deliberately left untouched on project switches.
|
|
7360
|
+
*/
|
|
7361
|
+
interface GpsStatusFix {
|
|
7362
|
+
lng: number;
|
|
7363
|
+
lat: number;
|
|
7364
|
+
/** Horizontal accuracy radius in meters. */
|
|
7365
|
+
accuracy: number;
|
|
7366
|
+
/** Satellites used for the fix, or null when the provider does not report it. */
|
|
7367
|
+
satellites: number | null;
|
|
7368
|
+
/** Ground speed in m/s, or null when the device doesn't report one. */
|
|
7369
|
+
speed: number | null;
|
|
7370
|
+
/** Fix time in epoch milliseconds. */
|
|
7371
|
+
timestamp: number;
|
|
7372
|
+
}
|
|
7373
|
+
/** Reserved Identify target for querying every visible queryable layer at once. */
|
|
7374
|
+
export declare const IDENTIFY_ALL_LAYERS_ID = "__geolibre_identify_all_layers__";
|
|
7375
|
+
/** The Identify fields of the store, as set together by an Identify change. */
|
|
7376
|
+
interface IdentifyState {
|
|
7377
|
+
identifyLayerId: string | null;
|
|
7378
|
+
identifyLayerIds: string[] | null;
|
|
7379
|
+
}
|
|
7380
|
+
/**
|
|
7381
|
+
* Resolve an Identify target against the layers that exist.
|
|
7382
|
+
*
|
|
7383
|
+
* Shared by the scripting `setIdentify` command and by project load, which
|
|
7384
|
+
* applies a project's saved `interaction.identify` (issue #2688).
|
|
7385
|
+
*
|
|
7386
|
+
* @param target - A layer id, `"all"`, a list of layer ids, or null/undefined.
|
|
7387
|
+
* @param layerIds - Ids of the layers currently in the project.
|
|
7388
|
+
* @returns The store fields to set. Ids that name no layer are dropped; a list
|
|
7389
|
+
* that keeps one id becomes a single-layer target, and one that keeps several
|
|
7390
|
+
* becomes the all-layers mode restricted to those ids.
|
|
7391
|
+
*/
|
|
7392
|
+
export declare function resolveIdentifyTarget(target: string | readonly string[] | null | undefined, layerIds: Iterable<string>): IdentifyState;
|
|
7393
|
+
/**
|
|
7394
|
+
* Whether the all-layers Identify mode may query a layer.
|
|
7395
|
+
*
|
|
7396
|
+
* @param layerId - The candidate layer's id.
|
|
7397
|
+
* @param identifyLayerIds - The store's `identifyLayerIds` restriction.
|
|
7398
|
+
* @returns True when there is no restriction or the layer is in it.
|
|
7399
|
+
*/
|
|
7400
|
+
export declare function identifyAllIncludes(layerId: string, identifyLayerIds: readonly string[] | null | undefined): boolean;
|
|
7401
|
+
/**
|
|
7402
|
+
* Drop removed layers from the Identify state.
|
|
7403
|
+
*
|
|
7404
|
+
* @param state - The current Identify fields.
|
|
7405
|
+
* @param removed - Ids of the layers being removed.
|
|
7406
|
+
* @returns The Identify fields with those layers gone. A restricted all-layers
|
|
7407
|
+
* mode left with one layer narrows to it, and with none turns Identify off.
|
|
7408
|
+
*/
|
|
7409
|
+
export declare function identifyStateWithoutLayers(state: IdentifyState, removed: ReadonlySet<string>): IdentifyState;
|
|
7410
|
+
interface SessionSlice {
|
|
7411
|
+
/** Local viewing switch; saved layer popup settings are left untouched. */
|
|
7412
|
+
hoverTooltipsEnabled: boolean;
|
|
7413
|
+
setHoverTooltipsEnabled: (enabled: boolean) => void;
|
|
7414
|
+
selectedLayerId: string | null;
|
|
7415
|
+
selectedFeatureId: string | null;
|
|
6748
7416
|
/**
|
|
6749
|
-
*
|
|
6750
|
-
*
|
|
6751
|
-
|
|
6752
|
-
|
|
6753
|
-
|
|
6754
|
-
reason?: string;
|
|
6755
|
-
}) => void;
|
|
6756
|
-
/** Set explicit custom privileges and an optional reason. */
|
|
6757
|
-
setAppPrivileges: (privileges: AppPrivilege[], reason?: string) => void;
|
|
6758
|
-
/** Grant an individual application privilege. */
|
|
6759
|
-
grantAppPrivilege: (privilege: AppPrivilege) => void;
|
|
6760
|
-
/** Revoke an individual application privilege with an optional reason. */
|
|
6761
|
-
revokeAppPrivilege: (privilege: AppPrivilege, reason?: string) => void;
|
|
6762
|
-
/** Reset application capabilities back to the default unconstrained Administrator role. */
|
|
6763
|
-
resetAppCapabilities: () => void;
|
|
6764
|
-
/** Check if the current capabilities grant the requested privilege. */
|
|
6765
|
-
hasAppPrivilege: (privilege: AppPrivilege) => boolean;
|
|
6766
|
-
addLayer: (layer: GeoLibreLayer, beforeLayerId?: string | null) => void;
|
|
6767
|
-
removeLayer: (id: string) => void;
|
|
6768
|
-
updateLayer: (id: string, patch: Partial<GeoLibreLayer>) => void;
|
|
6769
|
-
setLayerVisibility: (id: string, visible: boolean) => void;
|
|
6770
|
-
setLayerOpacity: (id: string, opacity: number) => void;
|
|
6771
|
-
setLayerStyle: (id: string, style: Partial<LayerStyle>) => void;
|
|
6772
|
-
/**
|
|
6773
|
-
* Transient clipboard holding a layer's symbology, captured by
|
|
6774
|
-
* {@link copyLayerStyle} and applied by {@link pasteLayerStyle} (copy/paste
|
|
6775
|
-
* styles, issue #1339). Runtime-only: excluded from undo history
|
|
6776
|
-
* (`partialize` never lists it) and from the saved project. `null` until a
|
|
6777
|
-
* style is copied this session. Cleared by `newProject`/`loadProject` so a
|
|
6778
|
-
* paste can't apply an entry from a different project; it deliberately
|
|
6779
|
-
* survives undo/redo within a project (it holds a deep snapshot, not a live
|
|
6780
|
-
* layer reference, so a paste stays valid even if the source layer is undone
|
|
6781
|
-
* away — only the displayed source name may then be stale).
|
|
6782
|
-
*/
|
|
6783
|
-
copiedLayerStyle: CopiedLayerStyle | null;
|
|
6784
|
-
/**
|
|
6785
|
-
* Snapshot the given layer's style into {@link copiedLayerStyle} so it can be
|
|
6786
|
-
* pasted onto a compatible layer. No-op when the layer is missing or has no
|
|
6787
|
-
* copyable symbology (leaving any prior clipboard entry untouched). Returns
|
|
6788
|
-
* `true` when a style was captured, so callers can skip the confirmation on a
|
|
6789
|
-
* no-op.
|
|
6790
|
-
*/
|
|
6791
|
-
copyLayerStyle: (id: string) => boolean;
|
|
6792
|
-
/**
|
|
6793
|
-
* Apply the {@link copiedLayerStyle} clipboard entry onto the given layer.
|
|
6794
|
-
* No-op when the clipboard is empty, the layer is missing, or the entry's
|
|
6795
|
-
* style family does not match the target layer's. Returns `true` when the
|
|
6796
|
-
* style was applied, so callers can skip the confirmation on a no-op.
|
|
6797
|
-
*/
|
|
6798
|
-
pasteLayerStyle: (id: string) => boolean;
|
|
6799
|
-
/**
|
|
6800
|
-
* Replace a layer's persistent attribute joins and immediately re-derive its
|
|
6801
|
-
* joined columns (strip what the previous joins added, apply the new list).
|
|
6802
|
-
* Pass an empty array to detach every join and restore the base attributes.
|
|
6803
|
-
*/
|
|
6804
|
-
setLayerJoins: (id: string, joins: LayerJoin[]) => void;
|
|
6805
|
-
/**
|
|
6806
|
-
* Replace the layer's Attribute Form designer configuration (per-field edit
|
|
6807
|
-
* widgets, constraints, conditional visibility). Pass `undefined` to remove
|
|
6808
|
-
* the form config entirely.
|
|
7417
|
+
* Full set of selected feature ids. The attribute table extends the single
|
|
7418
|
+
* selection to many rows via Ctrl/Cmd (toggle) and Shift (range). The anchor
|
|
7419
|
+
* — `selectedFeatureId` — is the primary/last-clicked feature used for map
|
|
7420
|
+
* fit, DuckDB highlight, and scripting, and is always one of these ids (or
|
|
7421
|
+
* `null` when the set is empty). A single click leaves exactly one id here.
|
|
6809
7422
|
*/
|
|
6810
|
-
|
|
7423
|
+
selectedFeatureIds: string[];
|
|
6811
7424
|
/**
|
|
6812
|
-
*
|
|
6813
|
-
*
|
|
6814
|
-
*
|
|
7425
|
+
* Store-layer id targeted by Identify, or {@link IDENTIFY_ALL_LAYERS_ID} for
|
|
7426
|
+
* the map-level mode that queries every visible queryable layer — vector,
|
|
7427
|
+
* DuckDB query, WMS, COG, NetCDF image and time-slider raster alike.
|
|
6815
7428
|
*/
|
|
6816
|
-
|
|
7429
|
+
identifyLayerId: string | null;
|
|
6817
7430
|
/**
|
|
6818
|
-
*
|
|
6819
|
-
*
|
|
6820
|
-
*
|
|
7431
|
+
* Layers the all-layers Identify mode is limited to, or null for every
|
|
7432
|
+
* visible queryable layer. Set only alongside {@link IDENTIFY_ALL_LAYERS_ID},
|
|
7433
|
+
* by a script or project that names several layers (issue #2688), and
|
|
7434
|
+
* cleared by every `setIdentifyLayer` call so the in-app buttons keep their
|
|
7435
|
+
* plain meaning.
|
|
6821
7436
|
*/
|
|
6822
|
-
|
|
7437
|
+
identifyLayerIds: string[] | null;
|
|
7438
|
+
pointerCoords: [number, number] | null;
|
|
6823
7439
|
/**
|
|
6824
|
-
*
|
|
6825
|
-
*
|
|
6826
|
-
*
|
|
7440
|
+
* Ground elevation in true metres under the pointer, for the status bar
|
|
7441
|
+
* (issue #1813). Null when it cannot be resolved — the pointer is off the
|
|
7442
|
+
* map, terrain is off and the remote lookup has not answered (or failed), or
|
|
7443
|
+
* the active body is not Earth. Set alongside `pointerCoords` by MapCanvas,
|
|
7444
|
+
* which owns the map instance the terrain sample comes from.
|
|
6827
7445
|
*/
|
|
6828
|
-
|
|
7446
|
+
pointerElevation: number | null;
|
|
6829
7447
|
/**
|
|
6830
|
-
*
|
|
6831
|
-
*
|
|
6832
|
-
*
|
|
6833
|
-
*
|
|
7448
|
+
* Camera height above sea level in metres — Google Earth Pro's "Eye alt"
|
|
7449
|
+
* (issue #1816). Derived from the camera, so deliberately *not* part of
|
|
7450
|
+
* `mapView`: that shape is persisted into the project file, and a stored
|
|
7451
|
+
* altitude could only drift from the center/zoom/pitch it is computed from.
|
|
7452
|
+
* Null before the map loads, or when MapLibre cannot report it.
|
|
6834
7453
|
*/
|
|
6835
|
-
|
|
6836
|
-
/**
|
|
6837
|
-
|
|
6838
|
-
|
|
6839
|
-
|
|
6840
|
-
|
|
6841
|
-
|
|
6842
|
-
|
|
6843
|
-
|
|
6844
|
-
|
|
6845
|
-
|
|
6846
|
-
*
|
|
6847
|
-
*
|
|
7454
|
+
cameraAltitude: number | null;
|
|
7455
|
+
/** Live GPS fix for the status bar, or null while GPS tracking is off. */
|
|
7456
|
+
gpsStatus: GpsStatusFix | null;
|
|
7457
|
+
attributeFilter: string;
|
|
7458
|
+
setPointerCoords: (coords: [number, number] | null) => void;
|
|
7459
|
+
setPointerElevation: (elevation: number | null) => void;
|
|
7460
|
+
setCameraAltitude: (altitude: number | null) => void;
|
|
7461
|
+
setGpsStatus: (fix: GpsStatusFix | null) => void;
|
|
7462
|
+
selectLayer: (id: string | null) => void;
|
|
7463
|
+
selectFeature: (id: string | null) => void;
|
|
7464
|
+
/**
|
|
7465
|
+
* Replace the multi-selection with `ids`. The anchor (`selectedFeatureId`)
|
|
7466
|
+
* becomes `anchorId` when provided, otherwise the last id in the list (or
|
|
7467
|
+
* `null` when the list is empty).
|
|
6848
7468
|
*/
|
|
6849
|
-
|
|
6850
|
-
|
|
6851
|
-
|
|
6852
|
-
|
|
6853
|
-
|
|
6854
|
-
|
|
6855
|
-
|
|
6856
|
-
|
|
6857
|
-
|
|
6858
|
-
|
|
6859
|
-
|
|
6860
|
-
|
|
6861
|
-
|
|
6862
|
-
|
|
6863
|
-
|
|
6864
|
-
|
|
7469
|
+
selectFeatures: (ids: string[], anchorId?: string | null) => void;
|
|
7470
|
+
setIdentifyLayer: (id: string | null) => void;
|
|
7471
|
+
/** Set both Identify fields at once (see {@link resolveIdentifyTarget}). */
|
|
7472
|
+
setIdentifyState: (state: IdentifyState) => void;
|
|
7473
|
+
setAttributeFilter: (filter: string) => void;
|
|
7474
|
+
}
|
|
7475
|
+
//#endregion
|
|
7476
|
+
//#region src/store/ui-slice.d.ts
|
|
7477
|
+
type ConversionToolKind = "vector-to-vector" | "vector-to-geoparquet" | "vector-to-flatgeobuf" | "vector-to-shapefile" | "vector-to-geopackage" | "csv-to-geoparquet" | "vector-to-pmtiles" | "raster-to-pmtiles" | "raster-to-cog";
|
|
7478
|
+
/**
|
|
7479
|
+
* Identifiers of the vector processing tools. Kept in sync by hand with the
|
|
7480
|
+
* `id` fields of `VECTOR_TOOLS` in `@geolibre/processing` (`vector-tools.ts`);
|
|
7481
|
+
* deriving the type there would create a core -> processing circular import.
|
|
7482
|
+
*/
|
|
7483
|
+
type VectorToolKind = "buffer" | "centroids" | "convex-hull" | "dissolve" | "bounding-box" | "simplify" | "clip" | "intersection" | "difference" | "union" | "spatial-join" | "attribute-join" | "select-by-value" | "select-by-location" | "random-extract" | "reproject" | "explode" | "aggregate" | "smooth" | "extract-vertices" | "points-along-geometry" | "grid" | "voronoi" | "cell-sectors" | "dggs-grid" | "dggs-bin" | "dggs-compact" | "trajectory-speed" | "detect-stops" | "space-time-proximity" | "decode-polyline" | "encode-polyline" | "merge-layers" | "check-validity" | "fix-geometries" | "check-topology-rules" | "fix-topology";
|
|
7484
|
+
/** Identifiers of the network-analysis tools (`NETWORK_TOOLS` ids). */
|
|
7485
|
+
type NetworkToolKind = "isochrone" | "od-matrix" | "sequential-route";
|
|
7486
|
+
/** Identifiers of the spatial-statistics tools (`STATISTICS_TOOLS` ids). */
|
|
7487
|
+
type StatisticsToolKind = "global-morans-i" | "local-morans-i" | "getis-ord-gi" | "average-nearest-neighbor" | "kernel-density" | "emerging-hot-spot" | "composite-score";
|
|
7488
|
+
/**
|
|
7489
|
+
* Identifiers of the raster processing tools. Kept in sync by hand with the
|
|
7490
|
+
* `id` fields of `RASTER_TOOLS` in `@geolibre/processing` (`raster-tools.ts`);
|
|
7491
|
+
* deriving the type there would create a core -> processing circular import.
|
|
7492
|
+
*/
|
|
7493
|
+
type RasterToolKind = "hillshade" | "slope" | "aspect" | "reproject" | "resample" | "clip-extent" | "clip-mask" | "polygonize" | "contour" | "interpolate" | "zonal" | "raster-calc" | "spectral-index" | "reclassify" | "mosaic" | "focal";
|
|
7494
|
+
interface UiSlice {
|
|
7495
|
+
ui: {
|
|
7496
|
+
processingOpen: boolean;
|
|
6865
7497
|
/**
|
|
6866
|
-
*
|
|
6867
|
-
*
|
|
6868
|
-
*
|
|
7498
|
+
* Tool id to preselect when the Whitebox toolbox dialog opens, set when the
|
|
7499
|
+
* user picks a specific tool from the Processing menu's category submenus.
|
|
7500
|
+
* Consumed and cleared by ProcessingDialog. Null means "no preselection".
|
|
6869
7501
|
*/
|
|
6870
|
-
|
|
6871
|
-
|
|
6872
|
-
|
|
6873
|
-
|
|
7502
|
+
processingInitialTool: string | null;
|
|
7503
|
+
conversionOpen: ConversionToolKind | null;
|
|
7504
|
+
vectorToolOpen: VectorToolKind | null;
|
|
7505
|
+
networkToolOpen: NetworkToolKind | null;
|
|
7506
|
+
statisticsToolOpen: StatisticsToolKind | null;
|
|
7507
|
+
rasterToolOpen: RasterToolKind | null;
|
|
7508
|
+
segmentationOpen: boolean;
|
|
7509
|
+
objectDetectionOpen: boolean;
|
|
7510
|
+
segmentEverythingOpen: boolean;
|
|
7511
|
+
geocodeOpen: boolean;
|
|
7512
|
+
sqlWorkspaceOpen: boolean;
|
|
7513
|
+
loadEditorFeaturesOpen: boolean;
|
|
7514
|
+
loadEditorFeaturesLayerId: string | null;
|
|
7515
|
+
pythonConsoleOpen: boolean;
|
|
7516
|
+
notebookOpen: boolean;
|
|
7517
|
+
assistantOpen: boolean;
|
|
7518
|
+
attributeTableOpen: boolean;
|
|
7519
|
+
/** Whether the Raster Attribute Table bottom panel is open (issue #1307). */
|
|
7520
|
+
rasterAttributeTableOpen: boolean;
|
|
7521
|
+
dashboardOpen: boolean;
|
|
7522
|
+
storymapPanelOpen: boolean;
|
|
7523
|
+
storymapPresenting: boolean;
|
|
7524
|
+
storymapReturnToEditor: boolean;
|
|
7525
|
+
/**
|
|
7526
|
+
* Layer opacities the active story presentation has applied so far, keyed
|
|
7527
|
+
* by store layer id. Playback fades layers by writing MapLibre paint
|
|
7528
|
+
* properties directly (never the persisted `layers[].opacity`), so this is
|
|
7529
|
+
* how renderers outside MapLibre's paint model (deck.gl diagrams, 3D
|
|
7530
|
+
* Z-value geometry) and the on-map Legend follow a chapter's fades. Empty
|
|
7531
|
+
* while not presenting; never saved with the project.
|
|
7532
|
+
*/
|
|
7533
|
+
storymapLayerOpacity: Record<string, number>;
|
|
7534
|
+
storymapComposingId: string | null;
|
|
7535
|
+
/** The Batch tools dialog (run one tool across many layers). */
|
|
7536
|
+
batchToolsOpen: boolean;
|
|
7537
|
+
/** The Model Builder canvas panel (author a processing graph). */
|
|
7538
|
+
modelBuilderOpen: boolean;
|
|
7539
|
+
/** One-shot request for Model Builder to load a saved model. */
|
|
7540
|
+
modelBuilderRequestedModelId: string | null;
|
|
7541
|
+
/** Style Manager dialog visibility (issue #1294). */
|
|
7542
|
+
styleManagerOpen: boolean;
|
|
7543
|
+
/** Processing History panel visibility (#1292). */
|
|
7544
|
+
processingHistoryOpen: boolean;
|
|
7545
|
+
/** Select by Expression dialog visibility (#1314). */
|
|
7546
|
+
selectByExpressionOpen: boolean;
|
|
7547
|
+
selectByExpressionLayerId: string | null;
|
|
7548
|
+
/** Select by Location dialog visibility (#1314). */
|
|
7549
|
+
selectByLocationOpen: boolean;
|
|
7550
|
+
/** Same contract as `selectByExpressionLayerId`, for Select by Location. */
|
|
7551
|
+
selectByLocationLayerId: string | null;
|
|
7552
|
+
/**
|
|
7553
|
+
* Pending "re-run from History" request. Written by the History panel just
|
|
7554
|
+
* before it opens the target processing dialog; consumed and cleared by
|
|
7555
|
+
* that dialog once it has pre-filled its parameter form. Null when idle.
|
|
7556
|
+
*/
|
|
7557
|
+
processingRerun: ProcessingRerunRequest | null;
|
|
7558
|
+
zoomToSelectedFeature: boolean;
|
|
7559
|
+
collaborateDialogOpen: boolean;
|
|
7560
|
+
};
|
|
7561
|
+
setProcessingOpen: (open: boolean) => void;
|
|
7562
|
+
setProcessingInitialTool: (toolId: string | null) => void;
|
|
7563
|
+
setConversionOpen: (kind: ConversionToolKind | null) => void;
|
|
7564
|
+
setVectorToolOpen: (kind: VectorToolKind | null) => void;
|
|
7565
|
+
setNetworkToolOpen: (kind: NetworkToolKind | null) => void;
|
|
7566
|
+
setStatisticsToolOpen: (kind: StatisticsToolKind | null) => void;
|
|
7567
|
+
setRasterToolOpen: (kind: RasterToolKind | null) => void;
|
|
7568
|
+
setSegmentationOpen: (open: boolean) => void;
|
|
7569
|
+
setObjectDetectionOpen: (open: boolean) => void;
|
|
7570
|
+
setSegmentEverythingOpen: (open: boolean) => void;
|
|
7571
|
+
setGeocodeOpen: (open: boolean) => void;
|
|
7572
|
+
setSqlWorkspaceOpen: (open: boolean) => void;
|
|
7573
|
+
setLoadEditorFeaturesOpen: (open: boolean, layerId?: string | null) => void;
|
|
7574
|
+
setPythonConsoleOpen: (open: boolean) => void;
|
|
7575
|
+
setNotebookOpen: (open: boolean) => void;
|
|
7576
|
+
setAssistantOpen: (open: boolean) => void;
|
|
7577
|
+
setAttributeTableOpen: (open: boolean) => void;
|
|
7578
|
+
setRasterAttributeTableOpen: (open: boolean) => void;
|
|
7579
|
+
setDashboardOpen: (open: boolean) => void;
|
|
7580
|
+
setStorymapPanelOpen: (open: boolean) => void;
|
|
7581
|
+
setStorymapPresenting: (presenting: boolean, returnToEditor?: boolean) => void;
|
|
6874
7582
|
/**
|
|
6875
|
-
*
|
|
6876
|
-
*
|
|
6877
|
-
* persists with the project exactly like a layer added through the Add Data
|
|
6878
|
-
* dialog, so callers (e.g. an external plugin) do not have to touch MapLibre
|
|
6879
|
-
* directly. See {@link AddTileLayerOptions}.
|
|
7583
|
+
* Record the layer opacities a story chapter applied, merging into the
|
|
7584
|
+
* presentation's running map (see `ui.storymapLayerOpacity`).
|
|
6880
7585
|
*/
|
|
6881
|
-
|
|
6882
|
-
|
|
6883
|
-
|
|
6884
|
-
|
|
6885
|
-
|
|
6886
|
-
|
|
6887
|
-
|
|
6888
|
-
|
|
6889
|
-
|
|
6890
|
-
|
|
6891
|
-
|
|
6892
|
-
|
|
6893
|
-
|
|
6894
|
-
|
|
6895
|
-
replyToComment: (commentId: string, reply: CommentReply) => void;
|
|
6896
|
-
toggleResolveComment: (commentId: string, resolved?: boolean) => void;
|
|
6897
|
-
deleteComment: (commentId: string) => void;
|
|
6898
|
-
setComments: (comments: ProjectComment[]) => void;
|
|
7586
|
+
setStorymapLayerOpacity: (changes: Record<string, number>) => void;
|
|
7587
|
+
setStorymapComposing: (chapterId: string | null) => void;
|
|
7588
|
+
setBatchToolsOpen: (open: boolean) => void;
|
|
7589
|
+
setModelBuilderOpen: (open: boolean) => void;
|
|
7590
|
+
setModelBuilderRequestedModelId: (id: string | null) => void;
|
|
7591
|
+
setProcessingHistoryOpen: (open: boolean) => void;
|
|
7592
|
+
/** Open/close Select by Expression, optionally preselecting a target layer. */
|
|
7593
|
+
setSelectByExpressionOpen: (open: boolean, layerId?: string | null) => void;
|
|
7594
|
+
/** Open/close Select by Location, optionally preselecting a target layer. */
|
|
7595
|
+
setSelectByLocationOpen: (open: boolean, layerId?: string | null) => void;
|
|
7596
|
+
setProcessingRerun: (request: ProcessingRerunRequest | null) => void;
|
|
7597
|
+
setCollaborateDialogOpen: (open: boolean) => void;
|
|
7598
|
+
setZoomToSelectedFeature: (enabled: boolean) => void;
|
|
7599
|
+
setStyleManagerOpen: (open: boolean) => void;
|
|
6899
7600
|
}
|
|
6900
|
-
|
|
6901
|
-
|
|
7601
|
+
//#endregion
|
|
7602
|
+
//#region src/store/types.d.ts
|
|
6902
7603
|
/**
|
|
6903
|
-
*
|
|
6904
|
-
*
|
|
6905
|
-
* actions always produce new objects via spread, so the frozen default is only
|
|
6906
|
-
* ever read.
|
|
7604
|
+
* The whole app store: every slice's state and actions in one flat object.
|
|
7605
|
+
* The slices are an internal split of `store.ts`; consumers see one store.
|
|
6907
7606
|
*/
|
|
6908
|
-
|
|
6909
|
-
|
|
6910
|
-
|
|
7607
|
+
interface AppState extends ProjectSlice, MapViewSlice, LayersSlice, LayerGroupsSlice, ProjectContentSlice, ProcessingSlice, LibrariesSlice, SessionSlice, CollaborationSlice, CapabilitiesSlice, UiSlice {}
|
|
7608
|
+
//#endregion
|
|
7609
|
+
//#region src/store/undo-history.d.ts
|
|
7610
|
+
/** The fields undo/redo snapshots, restores and compares. */
|
|
7611
|
+
type HistoryState = Pick<AppState, "layers" | "layerGroups" | "basemapStyleUrl" | "basemapVisible" | "basemapOpacity" | "blankBackgroundColor" | "storymap" | "comments">;
|
|
6911
7612
|
export declare function subscribeProjectRestoreHistory(listener: () => void): () => void;
|
|
6912
7613
|
export declare function canUndoProjectRestore(): boolean;
|
|
6913
7614
|
export declare function canRedoProjectRestore(): boolean;
|
|
@@ -6918,18 +7619,6 @@ export declare function canRedoProjectRestore(): boolean;
|
|
|
6918
7619
|
* serialized state, so it needs a full canonical project pair.
|
|
6919
7620
|
*/
|
|
6920
7621
|
export declare function registerProjectRestoreHistory(before: GeoLibreProject, beforePath: string | null, after: GeoLibreProject, afterPath?: string | null): void;
|
|
6921
|
-
export declare const useAppStore: import("zustand").UseBoundStore<Omit<import("zustand").StoreApi<AppState>, "temporal"> & {
|
|
6922
|
-
temporal: import("zustand").StoreApi<import("zundo").TemporalState<{
|
|
6923
|
-
layers: GeoLibreLayer[];
|
|
6924
|
-
layerGroups: LayerGroup[];
|
|
6925
|
-
basemapStyleUrl: string;
|
|
6926
|
-
basemapVisible: boolean;
|
|
6927
|
-
basemapOpacity: number;
|
|
6928
|
-
blankBackgroundColor: string | null;
|
|
6929
|
-
storymap: StoryMap | null;
|
|
6930
|
-
comments: ProjectComment[];
|
|
6931
|
-
}>>;
|
|
6932
|
-
}>;
|
|
6933
7622
|
/**
|
|
6934
7623
|
* Step the layer/basemap history back one entry and mark the project dirty.
|
|
6935
7624
|
* zundo restores the partialized slice via the store's set; the resulting new
|
|
@@ -6941,6 +7630,11 @@ export declare function undo(): void;
|
|
|
6941
7630
|
export declare function redo(): void;
|
|
6942
7631
|
/** Empty both the undo and redo stacks (e.g. on new/loaded project). */
|
|
6943
7632
|
export declare function clearHistory(): void;
|
|
7633
|
+
//#endregion
|
|
7634
|
+
//#region src/store.d.ts
|
|
7635
|
+
export declare const useAppStore: import("zustand").UseBoundStore<Omit<import("zustand").StoreApi<AppState>, "temporal"> & {
|
|
7636
|
+
temporal: import("zustand").StoreApi<import("zundo").TemporalState<HistoryState>>;
|
|
7637
|
+
}>;
|
|
6944
7638
|
/**
|
|
6945
7639
|
* React hook for consuming application capability state for a specific privilege.
|
|
6946
7640
|
*
|
|
@@ -6952,6 +7646,109 @@ export declare function useAppCapability(privilege: AppPrivilege): {
|
|
|
6952
7646
|
reason?: string;
|
|
6953
7647
|
};
|
|
6954
7648
|
//#endregion
|
|
7649
|
+
//#region src/layer-selectors.d.ts
|
|
7650
|
+
/**
|
|
7651
|
+
* The fields a layer list needs: enough to draw a row, a `<select>` option or
|
|
7652
|
+
* a visibility checkbox. It deliberately leaves out opacity, style, source,
|
|
7653
|
+
* metadata and feature data, which change far more often.
|
|
7654
|
+
*/
|
|
7655
|
+
interface LayerSummary {
|
|
7656
|
+
/** The layer id. */
|
|
7657
|
+
readonly id: string;
|
|
7658
|
+
/** The display name. */
|
|
7659
|
+
readonly name: string;
|
|
7660
|
+
/** The layer kind. */
|
|
7661
|
+
readonly type: LayerType;
|
|
7662
|
+
/** Whether the layer is shown on the primary map. */
|
|
7663
|
+
readonly visible: boolean;
|
|
7664
|
+
/** The layer panel group the layer belongs to, if any. */
|
|
7665
|
+
readonly groupId: string | undefined;
|
|
7666
|
+
}
|
|
7667
|
+
/**
|
|
7668
|
+
* The array {@link useLayersWhen} returns while inactive. Frozen, and shared so
|
|
7669
|
+
* the inactive selection never changes identity.
|
|
7670
|
+
*/
|
|
7671
|
+
export declare const NO_LAYERS: GeoLibreLayer[];
|
|
7672
|
+
/**
|
|
7673
|
+
* Select one layer record by id.
|
|
7674
|
+
*
|
|
7675
|
+
* @param state - The app state.
|
|
7676
|
+
* @param id - The layer id; `null`/`undefined` selects nothing.
|
|
7677
|
+
* @returns The layer record, or `undefined` when there is no such layer.
|
|
7678
|
+
*/
|
|
7679
|
+
export declare function selectLayerById(state: Pick<AppState, "layers">, id: string | null | undefined): GeoLibreLayer | undefined;
|
|
7680
|
+
/**
|
|
7681
|
+
* Select the layer ids in store order (bottom to top).
|
|
7682
|
+
*
|
|
7683
|
+
* Returns a new array on every call; pair it with a shallow comparison (as
|
|
7684
|
+
* {@link useLayerIds} does) so an unchanged id list keeps its identity.
|
|
7685
|
+
*
|
|
7686
|
+
* @param state - The app state.
|
|
7687
|
+
* @returns The layer ids.
|
|
7688
|
+
*/
|
|
7689
|
+
export declare function selectLayerIds(state: Pick<AppState, "layers">): string[];
|
|
7690
|
+
/**
|
|
7691
|
+
* Select a {@link LayerSummary} per layer, in store order (bottom to top).
|
|
7692
|
+
*
|
|
7693
|
+
* Each summary keeps its identity while its own fields are unchanged, so the
|
|
7694
|
+
* returned array is shallow-equal to the previous one after an edit that
|
|
7695
|
+
* touches none of those fields (opacity, style, data, metadata).
|
|
7696
|
+
*
|
|
7697
|
+
* @param state - The app state.
|
|
7698
|
+
* @returns One summary per layer.
|
|
7699
|
+
*/
|
|
7700
|
+
export declare function selectLayerSummaries(state: Pick<AppState, "layers">): LayerSummary[];
|
|
7701
|
+
/**
|
|
7702
|
+
* Build a selector for the full `layers` array that is live only while
|
|
7703
|
+
* `active`.
|
|
7704
|
+
*
|
|
7705
|
+
* @param active - Whether the caller currently needs the layers.
|
|
7706
|
+
* @returns A selector returning `state.layers` while active, and the constant
|
|
7707
|
+
* {@link NO_LAYERS} otherwise.
|
|
7708
|
+
*/
|
|
7709
|
+
export declare function selectLayersWhen(active: boolean): (state: Pick<AppState, "layers">) => GeoLibreLayer[];
|
|
7710
|
+
/**
|
|
7711
|
+
* Subscribe to one layer record.
|
|
7712
|
+
*
|
|
7713
|
+
* Re-renders only when that layer changes (or appears/disappears), not when
|
|
7714
|
+
* another layer is edited.
|
|
7715
|
+
*
|
|
7716
|
+
* @param id - The layer id; `null`/`undefined` subscribes to nothing.
|
|
7717
|
+
* @returns The layer record, or `undefined` when there is no such layer.
|
|
7718
|
+
*/
|
|
7719
|
+
export declare function useLayer(id: string | null | undefined): GeoLibreLayer | undefined;
|
|
7720
|
+
/**
|
|
7721
|
+
* Subscribe to the ordered list of layer ids.
|
|
7722
|
+
*
|
|
7723
|
+
* Re-renders only when a layer is added, removed or reordered.
|
|
7724
|
+
*
|
|
7725
|
+
* @returns The layer ids in store order (bottom to top).
|
|
7726
|
+
*/
|
|
7727
|
+
export declare function useLayerIds(): string[];
|
|
7728
|
+
/**
|
|
7729
|
+
* Subscribe to a {@link LayerSummary} per layer.
|
|
7730
|
+
*
|
|
7731
|
+
* Re-renders only when a layer is added, removed, reordered, renamed, shown or
|
|
7732
|
+
* hidden, retyped or regrouped; opacity, style, data and metadata edits do not
|
|
7733
|
+
* re-render the caller.
|
|
7734
|
+
*
|
|
7735
|
+
* @returns One summary per layer, in store order (bottom to top).
|
|
7736
|
+
*/
|
|
7737
|
+
export declare function useLayerSummaries(): LayerSummary[];
|
|
7738
|
+
/**
|
|
7739
|
+
* Subscribe to the full `layers` array only while `active`.
|
|
7740
|
+
*
|
|
7741
|
+
* For always-mounted surfaces (dialogs, floating panels) that need every layer
|
|
7742
|
+
* record while open but keep local state across closes and so cannot simply be
|
|
7743
|
+
* unmounted. While inactive the caller gets the constant {@link NO_LAYERS} and
|
|
7744
|
+
* layer edits do not re-render it.
|
|
7745
|
+
*
|
|
7746
|
+
* @param active - Whether the caller currently needs the layers (for example,
|
|
7747
|
+
* whether its dialog is open).
|
|
7748
|
+
* @returns `layers` while active, otherwise an empty, frozen array.
|
|
7749
|
+
*/
|
|
7750
|
+
export declare function useLayersWhen(active: boolean): GeoLibreLayer[];
|
|
7751
|
+
//#endregion
|
|
6955
7752
|
//#region src/history.d.ts
|
|
6956
7753
|
export declare function setHistoryCoalesceMs(ms: number): void;
|
|
6957
7754
|
export declare function getHistoryCoalesceMs(): number;
|
|
@@ -7420,6 +8217,23 @@ export declare function getGoogleMapsApiKey(env?: Record<string, string | undefi
|
|
|
7420
8217
|
* @returns The trimmed token, or undefined when unset.
|
|
7421
8218
|
*/
|
|
7422
8219
|
export declare function getMapboxAccessToken(env?: Record<string, string | undefined>): string | undefined;
|
|
8220
|
+
/**
|
|
8221
|
+
* Resolves the ArcGIS API key from the runtime environment.
|
|
8222
|
+
*
|
|
8223
|
+
* The ArcGIS renderer draws the translated project basemap and non-Esri layers
|
|
8224
|
+
* without a key; Esri's basemap styles and location services require one
|
|
8225
|
+
* (an ArcGIS Location Platform or ArcGIS Online API key credential). It is
|
|
8226
|
+
* supplied via `VITE_ARCGIS_API_KEY` (baked in at build time from the bare
|
|
8227
|
+
* `ARCGIS_API_KEY` env var, which `vite.config.ts` copies into the prefixed
|
|
8228
|
+
* name) or set at runtime through Settings → Environment variables
|
|
8229
|
+
* (`window.__GEOLIBRE_RUNTIME_ENV__`, so a bare `ARCGIS_API_KEY` entry works
|
|
8230
|
+
* there too). Same precedence as {@link getMapboxAccessToken}.
|
|
8231
|
+
*
|
|
8232
|
+
* @param env - Environment record (defaults to the runtime environment);
|
|
8233
|
+
* injectable for testing.
|
|
8234
|
+
* @returns The trimmed key, or undefined when unset.
|
|
8235
|
+
*/
|
|
8236
|
+
export declare function getArcgisApiKey(env?: Record<string, string | undefined>): string | undefined;
|
|
7423
8237
|
/**
|
|
7424
8238
|
* Resolves the Cesium Ion access token from the runtime environment.
|
|
7425
8239
|
*
|
|
@@ -7486,12 +8300,31 @@ type CesiumIonAssetKind = "3d-tiles" | "imagery";
|
|
|
7486
8300
|
export declare const CESIUM_OSM_BUILDINGS_ASSET_ID = 96188;
|
|
7487
8301
|
/** Bing Maps Aerial through Ion, the imagery asset every Ion account can use. */
|
|
7488
8302
|
export declare const CESIUM_BING_AERIAL_ASSET_ID = 2;
|
|
7489
|
-
/**
|
|
7490
|
-
|
|
8303
|
+
/**
|
|
8304
|
+
* Google Photorealistic 3D Tiles served through Ion. Unlike the two above it
|
|
8305
|
+
* is not free on every plan: Ion accounts without it get a 403 the globe
|
|
8306
|
+
* surfaces as a layer error.
|
|
8307
|
+
*/
|
|
8308
|
+
export declare const CESIUM_GOOGLE_PHOTOREALISTIC_ASSET_ID = 2275207;
|
|
8309
|
+
/**
|
|
8310
|
+
* Which tier of the Ion catalog a quick pick comes from. `global` assets ship
|
|
8311
|
+
* with every Ion account; `depot` assets are Asset Depot samples the account
|
|
8312
|
+
* has to add once at ion.cesium.com before they stream (until then the
|
|
8313
|
+
* endpoint 404s and the globe reports a layer error).
|
|
8314
|
+
*/
|
|
8315
|
+
type CesiumIonQuickPickGroup = "global" | "depot";
|
|
8316
|
+
interface CesiumIonQuickPick {
|
|
7491
8317
|
assetId: number;
|
|
7492
8318
|
kind: CesiumIonAssetKind;
|
|
7493
8319
|
name: string;
|
|
7494
|
-
|
|
8320
|
+
group: CesiumIonQuickPickGroup;
|
|
8321
|
+
}
|
|
8322
|
+
/**
|
|
8323
|
+
* Ion assets offered as one-click picks in the Add Data dialog. Asset ids are
|
|
8324
|
+
* the dropdown's option values, so they have to stay unique; the ids below are
|
|
8325
|
+
* the ones Cesium's own samples use.
|
|
8326
|
+
*/
|
|
8327
|
+
export declare const CESIUM_ION_QUICK_PICKS: ReadonlyArray<CesiumIonQuickPick>;
|
|
7495
8328
|
/** Parse an Ion asset id the way the Add Data form and the project file carry it. */
|
|
7496
8329
|
export declare function parseCesiumIonAssetId(value: unknown): number | null;
|
|
7497
8330
|
/**
|
|
@@ -7577,6 +8410,8 @@ interface CzmlLayerOptions {
|
|
|
7577
8410
|
url?: string;
|
|
7578
8411
|
/** Local path when loaded from disk. */
|
|
7579
8412
|
sourcePath?: string;
|
|
8413
|
+
/** Credit shown in the globe's attribution control while the layer is present. */
|
|
8414
|
+
attribution?: string;
|
|
7580
8415
|
}
|
|
7581
8416
|
/**
|
|
7582
8417
|
* Build a typed GeoLibreLayer representing a CZML dynamic scene on the Cesium globe.
|
|
@@ -7614,6 +8449,89 @@ export declare function resolveThreeDTilesRequestHeaders(url: string, headers: R
|
|
|
7614
8449
|
*/
|
|
7615
8450
|
export declare function persistedThreeDTilesRequestHeaders(url: string, headers: Record<string, string> | undefined): Record<string, string> | undefined;
|
|
7616
8451
|
//#endregion
|
|
8452
|
+
//#region src/project-credential-refs.d.ts
|
|
8453
|
+
export declare function geocodingApiKeyAccount(providerId: string): string;
|
|
8454
|
+
export declare function environmentVariableAccount(key: string): string;
|
|
8455
|
+
/** Rows are secret unless explicitly marked `secret: false`. */
|
|
8456
|
+
export declare function isSecretEnvironmentVariable(variable: RuntimeEnvironmentVariable): boolean;
|
|
8457
|
+
type ProjectCredentialLookup = (account: string) => string | undefined;
|
|
8458
|
+
/** Install (or clear, with `null`) the source of stored project credentials. */
|
|
8459
|
+
export declare function setProjectCredentialLookup(lookup: ProjectCredentialLookup | null): void;
|
|
8460
|
+
/** The stored value for `account`, or `undefined` when none (or no lookup). */
|
|
8461
|
+
export declare function lookupProjectCredential(account: string): string | undefined;
|
|
8462
|
+
/** Fill empty geocoding API keys from the stored ones. */
|
|
8463
|
+
export declare function overlayStoredGeocodingApiKeys(geocoding: GeocodingPreferences): GeocodingPreferences;
|
|
8464
|
+
/** Fill empty secret environment variable values from the stored ones. */
|
|
8465
|
+
export declare function overlayStoredEnvironmentVariables(variables: RuntimeEnvironmentVariable[]): RuntimeEnvironmentVariable[];
|
|
8466
|
+
/** Preferences with every empty stored credential filled in. */
|
|
8467
|
+
export declare function overlayStoredPreferenceCredentials(preferences: ProjectPreferences): ProjectPreferences;
|
|
8468
|
+
/**
|
|
8469
|
+
* The credential changes an edited Settings draft makes, keyed by account
|
|
8470
|
+
* (`""` deletes).
|
|
8471
|
+
*
|
|
8472
|
+
* - `seeded`: the overlaid preferences the dialog opened with.
|
|
8473
|
+
* - `next`: the normalized draft being saved.
|
|
8474
|
+
*
|
|
8475
|
+
* Only values the user changed are returned, so an untouched session override
|
|
8476
|
+
* (plaintext from the opened file) stays out of the keychain and opening a
|
|
8477
|
+
* file never writes it. Removing, renaming, or un-secreting a variable never
|
|
8478
|
+
* deletes its stored value: names are shared by every project on the device.
|
|
8479
|
+
* Clearing a field deletes the stored value only when the field showed that
|
|
8480
|
+
* stored value; clearing a file override that differed from it just drops the
|
|
8481
|
+
* override, so the shared value applies again and other projects keep it.
|
|
8482
|
+
*/
|
|
8483
|
+
export declare function changedPreferenceCredentials(seeded: ProjectPreferences, next: ProjectPreferences): Record<string, string>;
|
|
8484
|
+
/**
|
|
8485
|
+
* Move unambiguous geocoding API keys and secret environment variable values
|
|
8486
|
+
* out of `project` (a copy; the input is untouched) into `secrets`, keyed by
|
|
8487
|
+
* account. Secret environment rows that have no unique name remain in the
|
|
8488
|
+
* project for an explicit keep/strip choice. Layers pass through: their
|
|
8489
|
+
* request headers reference variables as `${NAME}` rather than holding
|
|
8490
|
+
* secrets that need moving.
|
|
8491
|
+
*/
|
|
8492
|
+
export declare function splitProjectCredentials(project: GeoLibreProject): {
|
|
8493
|
+
project: GeoLibreProject;
|
|
8494
|
+
secrets: Record<string, string>;
|
|
8495
|
+
};
|
|
8496
|
+
/**
|
|
8497
|
+
* `headers` with every `${NAME}` resolved from the project's enabled
|
|
8498
|
+
* Environment Variables (stored secret values filled in). Only those rows
|
|
8499
|
+
* count, not the OS environment or build-time values that share the runtime
|
|
8500
|
+
* env. A header referencing an unset variable is dropped.
|
|
8501
|
+
*/
|
|
8502
|
+
export declare function resolveProjectHeaderReferences(headers: Record<string, string> | undefined): Record<string, string> | undefined;
|
|
8503
|
+
//#endregion
|
|
8504
|
+
//#region src/header-references.d.ts
|
|
8505
|
+
/**
|
|
8506
|
+
* `${NAME}` references in request header values.
|
|
8507
|
+
*
|
|
8508
|
+
* A header such as `Authorization: Bearer ${TILES_TOKEN}` is saved as typed
|
|
8509
|
+
* and resolved from the project's Environment Variables when a request is
|
|
8510
|
+
* made, so the secret itself never sits on the layer. This module is pure (no
|
|
8511
|
+
* store import): `credentials.ts` depends on it, and the store depends on
|
|
8512
|
+
* `credentials.ts`.
|
|
8513
|
+
*/
|
|
8514
|
+
export declare function hasHeaderReferences(headers: Record<string, string> | undefined): boolean;
|
|
8515
|
+
/**
|
|
8516
|
+
* Whether `value` carries no secret of its own: at most a scheme word such as
|
|
8517
|
+
* `Bearer` followed by a single `${NAME}`. Redaction keeps such values.
|
|
8518
|
+
*/
|
|
8519
|
+
export declare function isHeaderReferenceOnly(value: string): boolean;
|
|
8520
|
+
/**
|
|
8521
|
+
* Whether credential-bearing request headers may be sent to `url`: HTTPS, or
|
|
8522
|
+
* plain HTTP to loopback so a local dev server still works. The scheme is read
|
|
8523
|
+
* off a parsed URL, so an unusually cased `HTTPS://` is not misread as
|
|
8524
|
+
* plaintext; a relative or unparseable URL is refused.
|
|
8525
|
+
*/
|
|
8526
|
+
export declare function allowsCredentialHeaders(url: string): boolean;
|
|
8527
|
+
/**
|
|
8528
|
+
* `headers` with every `${NAME}` replaced by `values[NAME]`. A header that
|
|
8529
|
+
* references an unset (or empty) variable is omitted rather than sent with a
|
|
8530
|
+
* hole in it. Returns the input unchanged when nothing references a variable,
|
|
8531
|
+
* and `undefined` when no header remains.
|
|
8532
|
+
*/
|
|
8533
|
+
export declare function resolveHeaderReferences(headers: Record<string, string> | undefined, values: Readonly<Record<string, string>>): Record<string, string> | undefined;
|
|
8534
|
+
//#endregion
|
|
7617
8535
|
//#region src/credentials.d.ts
|
|
7618
8536
|
/**
|
|
7619
8537
|
* Project fields whose values are credentials. Keep this registry as the
|
|
@@ -7859,5 +8777,5 @@ export declare function localFileName(path: string): string;
|
|
|
7859
8777
|
/** Keep imported layers distinguishable, including within a multi-file import. */
|
|
7860
8778
|
export declare function uniqueImportedLayerName(name: string, names: Iterable<string>): string;
|
|
7861
8779
|
//#endregion
|
|
7862
|
-
export type { AppState, CesiumIonAssetKind, CesiumIonLayerOptions, CesiumKmlLayerOptions, ConversionToolKind, CredentialRedactionResult, CzmlDocument, CzmlLayerOptions, CzmlPacket, CzmlSource, GeocodeMatch, GeocodeRequest, GeocodeStatus, GeocoderConfig, GeocodingPreferenceInput, GeocodingProvider, GeocodingProviderId, GpsStatusFix, NetworkToolKind, NominatimForwardResult, NominatimReverseResult, RasterToolKind, ReverseGeocodeDisplay, StatisticsToolKind, VectorToolKind };
|
|
8780
|
+
export type { AppState, CesiumIonAssetKind, CesiumIonLayerOptions, CesiumIonQuickPick, CesiumIonQuickPickGroup, CesiumKmlLayerOptions, ConversionToolKind, CredentialRedactionResult, CzmlDocument, CzmlLayerOptions, CzmlPacket, CzmlSource, GeocodeMatch, GeocodeRequest, GeocodeStatus, GeocoderConfig, GeocodingPreferenceInput, GeocodingProvider, GeocodingProviderId, GpsStatusFix, IdentifyState, LayerSummary, NetworkToolKind, NominatimForwardResult, NominatimReverseResult, ProjectCredentialLookup, RasterToolKind, ReverseGeocodeDisplay, StatisticsToolKind, VectorToolKind };
|
|
7863
8781
|
//# sourceMappingURL=index.d.mts.map
|