@geolibre/core 3.3.0 → 3.5.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 +671 -466
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +1019 -7353
- package/dist/index.mjs.map +1 -1
- package/dist/project-diff-CPb5ZXb_.mjs +10415 -0
- package/dist/project-diff-CPb5ZXb_.mjs.map +1 -0
- package/dist/{joins-CRZZcLqX.d.mts → project-diff-CyR4d8Sl.d.mts} +719 -15
- package/dist/project-diff-CyR4d8Sl.d.mts.map +1 -0
- package/dist/worker-safe.d.mts +2 -2
- package/dist/worker-safe.mjs +1 -2
- package/package.json +3 -3
- package/dist/joins-CGcRoTpc.mjs +0 -1822
- package/dist/joins-CGcRoTpc.mjs.map +0 -1
- package/dist/joins-CRZZcLqX.d.mts.map +0 -1
|
@@ -378,6 +378,71 @@ interface FeatureCollection<G extends Geometry | null = Geometry, P = GeoJsonPro
|
|
|
378
378
|
features: Array<Feature<G, P>>;
|
|
379
379
|
}
|
|
380
380
|
//#endregion
|
|
381
|
+
//#region src/geoarrow.d.ts
|
|
382
|
+
/** Supported GeoArrow geometry types. */
|
|
383
|
+
type GeoArrowGeometryType = "Point" | "MultiPoint" | "LineString" | "MultiLineString" | "Polygon" | "MultiPolygon";
|
|
384
|
+
/**
|
|
385
|
+
* A contiguous columnar vector batch compatible with GeoArrow layout.
|
|
386
|
+
*/
|
|
387
|
+
interface GeoArrowBatch {
|
|
388
|
+
/** The primary geometry type of the features in this batch. */
|
|
389
|
+
readonly geometryType: GeoArrowGeometryType;
|
|
390
|
+
/**
|
|
391
|
+
* Contiguous coordinates array: [x0, y0, (z0), x1, y1, (z1), ...].
|
|
392
|
+
* Length is coordinateCount * coordDimensions.
|
|
393
|
+
*/
|
|
394
|
+
readonly coordinates: Float64Array;
|
|
395
|
+
/** Coordinate dimensions: 2 for XY (default), 3 for XYZ. */
|
|
396
|
+
readonly coordDimensions: 2 | 3;
|
|
397
|
+
/**
|
|
398
|
+
* For Point: omitted (each feature has 1 position).
|
|
399
|
+
* For LineString / MultiPoint: offset into `coordinates` (in vertex units, not ordinate units)
|
|
400
|
+
* for each feature. Length = featureCount + 1.
|
|
401
|
+
* For Polygon: offset into `ringOffsets` for each polygon. Length = featureCount + 1.
|
|
402
|
+
*/
|
|
403
|
+
readonly geomOffsets?: Int32Array;
|
|
404
|
+
/**
|
|
405
|
+
* For Polygon / MultiLineString: offset into `coordinates` (in vertex units) for each ring or line.
|
|
406
|
+
* Length = totalRingsCount + 1.
|
|
407
|
+
*/
|
|
408
|
+
readonly ringOffsets?: Int32Array;
|
|
409
|
+
/**
|
|
410
|
+
* For MultiPolygon: offset into `geomOffsets` (or ringOffsets) for each feature.
|
|
411
|
+
* Length = featureCount + 1.
|
|
412
|
+
*/
|
|
413
|
+
readonly polygonOffsets?: Int32Array;
|
|
414
|
+
/** Total number of features in this batch. */
|
|
415
|
+
readonly featureCount: number;
|
|
416
|
+
/** Feature properties as an array of row objects or column dictionary. */
|
|
417
|
+
readonly properties?: ReadonlyArray<Record<string, unknown>>;
|
|
418
|
+
/** Optional feature identifiers. */
|
|
419
|
+
readonly featureIds?: ReadonlyArray<string | number | undefined>;
|
|
420
|
+
/** Optional precomputed 2D bounding box [minX, minY, maxX, maxY]. */
|
|
421
|
+
readonly bbox?: [number, number, number, number];
|
|
422
|
+
}
|
|
423
|
+
/**
|
|
424
|
+
* Type guard for {@link GeoArrowBatch}.
|
|
425
|
+
* Validates structure and basic buffer invariants without deep scanning.
|
|
426
|
+
*/
|
|
427
|
+
declare function isGeoArrowBatch(value: unknown): value is GeoArrowBatch;
|
|
428
|
+
/**
|
|
429
|
+
* Computes a 2D bounding box [minX, minY, maxX, maxY] for a {@link GeoArrowBatch}
|
|
430
|
+
* in a single fast, vectorized pass over the flat coordinates buffer.
|
|
431
|
+
* Returns null if the batch contains no finite coordinates.
|
|
432
|
+
*/
|
|
433
|
+
declare function computeGeoArrowBBox(batch: GeoArrowBatch): [number, number, number, number] | null;
|
|
434
|
+
/**
|
|
435
|
+
* Convert a {@link GeoArrowBatch} to a standard GeoJSON {@link FeatureCollection}.
|
|
436
|
+
* Lossless round-trip converter for renderers or components (Cesium, Attribute Table, Turf)
|
|
437
|
+
* that expect standard GeoJSON objects.
|
|
438
|
+
*/
|
|
439
|
+
declare function geoArrowToFeatureCollection(batch: GeoArrowBatch): FeatureCollection<Geometry | null>;
|
|
440
|
+
/**
|
|
441
|
+
* Flatten supported Point, MultiPoint, LineString and Polygon collections.
|
|
442
|
+
* Empty collections produce an empty Point batch; unsupported geometries return null.
|
|
443
|
+
*/
|
|
444
|
+
declare function featureCollectionToGeoArrow(collection: FeatureCollection<Geometry | null>): GeoArrowBatch | null;
|
|
445
|
+
//#endregion
|
|
381
446
|
//#region src/print-layout-config.d.ts
|
|
382
447
|
/**
|
|
383
448
|
* Print Layout composer settings that belong to a project.
|
|
@@ -994,7 +1059,11 @@ interface LayerStyle {
|
|
|
994
1059
|
markerShape: MarkerShape;
|
|
995
1060
|
markerColor: string;
|
|
996
1061
|
markerSize: number;
|
|
997
|
-
/**
|
|
1062
|
+
/**
|
|
1063
|
+
* The custom marker image used when {@link markerShape} is `"custom"`: raw
|
|
1064
|
+
* SVG markup, a `data:` URL (SVG or a raster PNG/JPEG/GIF), or an `http(s)`
|
|
1065
|
+
* URL. Only SVG sources take {@link markerColor}; raster images draw as-is.
|
|
1066
|
+
*/
|
|
998
1067
|
markerSvg: string;
|
|
999
1068
|
/**
|
|
1000
1069
|
* When true, per-feature [simplestyle-spec](https://github.com/mapbox/simplestyle-spec)
|
|
@@ -1138,14 +1207,14 @@ declare function styleValue<K extends keyof LayerStyle>(style: LayerStyle, key:
|
|
|
1138
1207
|
*/
|
|
1139
1208
|
declare const LARGE_VECTOR_FEATURE_THRESHOLD = 50000;
|
|
1140
1209
|
/**
|
|
1141
|
-
* Decide whether a
|
|
1210
|
+
* Decide whether a vector layer should use the tiled rendering path.
|
|
1142
1211
|
*
|
|
1143
|
-
* @param
|
|
1212
|
+
* @param data - The layer's feature collection or GeoArrow batch (may be undefined for
|
|
1144
1213
|
* non-vector layers).
|
|
1145
|
-
* @returns `true` when the
|
|
1146
|
-
* {@link LARGE_VECTOR_FEATURE_THRESHOLD}
|
|
1214
|
+
* @returns `true` when the feature count exceeds
|
|
1215
|
+
* {@link LARGE_VECTOR_FEATURE_THRESHOLD}.
|
|
1147
1216
|
*/
|
|
1148
|
-
declare function shouldUseTiledRendering(
|
|
1217
|
+
declare function shouldUseTiledRendering(data: GeoJSON.FeatureCollection | GeoArrowBatch | undefined): boolean;
|
|
1149
1218
|
/**
|
|
1150
1219
|
* Match statistics from the last time a {@link LayerJoin} was applied, shown in
|
|
1151
1220
|
* the Joins UI so silent key mismatches are visible (mirrors QGIS's join
|
|
@@ -1228,6 +1297,15 @@ interface AttributeFormFieldConfig {
|
|
|
1228
1297
|
required?: boolean;
|
|
1229
1298
|
/** Dropdown entries for the `valueMap` widget. */
|
|
1230
1299
|
valueMap?: AttributeFormValueMapEntry[];
|
|
1300
|
+
/**
|
|
1301
|
+
* Declared storage type of the field. When set, coercion follows it instead
|
|
1302
|
+
* of guessing from the value map (a text field whose codes are "1" and "2"
|
|
1303
|
+
* still stores strings), and validation rejects values of another type or,
|
|
1304
|
+
* for `integer`, fractional numbers. Service-derived configs (ArcGIS domains)
|
|
1305
|
+
* set it from the field's declared type; designer-authored configs leave it
|
|
1306
|
+
* unset.
|
|
1307
|
+
*/
|
|
1308
|
+
valueType?: "string" | "number" | "integer";
|
|
1231
1309
|
/** Lower bound for `number`/`range` widgets (inclusive). */
|
|
1232
1310
|
min?: number;
|
|
1233
1311
|
/** Upper bound for `number`/`range` widgets (inclusive). */
|
|
@@ -1582,6 +1660,11 @@ interface GeoLibreLayer {
|
|
|
1582
1660
|
metadata: Record<string, unknown>;
|
|
1583
1661
|
beforeId?: string;
|
|
1584
1662
|
geojson?: FeatureCollection;
|
|
1663
|
+
/**
|
|
1664
|
+
* Optional binary GeoArrow representation for high-performance vector rendering,
|
|
1665
|
+
* zero-copy Web Worker vector tiling, and compact in-memory storage.
|
|
1666
|
+
*/
|
|
1667
|
+
geoarrow?: GeoArrowBatch;
|
|
1585
1668
|
/** A SQL Server write needs a successful table reread before it may be submitted again. */
|
|
1586
1669
|
mssqlWritebackPending?: boolean;
|
|
1587
1670
|
/**
|
|
@@ -1973,6 +2056,11 @@ interface MapPreferences {
|
|
|
1973
2056
|
showPointerElevation: boolean;
|
|
1974
2057
|
/** Whether the built-in 3D terrain control and terrain surface are enabled. */
|
|
1975
2058
|
terrainEnabled: boolean;
|
|
2059
|
+
/**
|
|
2060
|
+
* Optional Cesium Ion terrain asset used by the globe when terrain is enabled.
|
|
2061
|
+
* Ignored by 2D renderers; absent means the renderer's normal global source.
|
|
2062
|
+
*/
|
|
2063
|
+
terrainIonAssetId?: number;
|
|
1976
2064
|
/** Mapbox-only style. New projects use Streets; absent follows the shared basemap. */
|
|
1977
2065
|
mapboxStyleUrl?: string;
|
|
1978
2066
|
/**
|
|
@@ -1983,6 +2071,24 @@ interface MapPreferences {
|
|
|
1983
2071
|
* basemap styles service requires one.
|
|
1984
2072
|
*/
|
|
1985
2073
|
arcgisBasemap?: string;
|
|
2074
|
+
/**
|
|
2075
|
+
* ArcGIS-only projection of the flat map, as a WKID the ArcGIS Maps SDK
|
|
2076
|
+
* resolves (`54099` Spilhaus, `54030` Robinson, ...). Absent means Web
|
|
2077
|
+
* Mercator. Vector layers are reprojected on the client; tiled layers and
|
|
2078
|
+
* basemaps cannot be, so they do not draw in another projection. The globe
|
|
2079
|
+
* (a `SceneView`) ignores it. See `arcgis-projection.ts`.
|
|
2080
|
+
*/
|
|
2081
|
+
arcgisWkid?: number;
|
|
2082
|
+
/**
|
|
2083
|
+
* Coordinate reference system of the flat MapLibre map (issue #1128): a
|
|
2084
|
+
* preset id from `MAP_CRS_PRESETS` (polar and simple-cylindrical grids of
|
|
2085
|
+
* Earth, the Moon, Mars and other bodies) or `"EPSG:<code>"`. Absent means
|
|
2086
|
+
* the default Web Mercator map or globe. Tiles are not reprojected, so only
|
|
2087
|
+
* GeoJSON, image/video overlays and WMS or ArcGIS export layers (asked for
|
|
2088
|
+
* each tile's box in this CRS) draw; XYZ, vector tile and plugin layers are
|
|
2089
|
+
* set aside, and the globe and terrain are off. See `map-crs.ts`.
|
|
2090
|
+
*/
|
|
2091
|
+
mapCrs?: string;
|
|
1986
2092
|
/** Cesium imagery override; absent follows the shared project basemap. */
|
|
1987
2093
|
cesiumBasemap?: CesiumBasemapId;
|
|
1988
2094
|
/**
|
|
@@ -2043,6 +2149,43 @@ interface GeocodingPreferences {
|
|
|
2043
2149
|
reverseEndpoint?: string;
|
|
2044
2150
|
/** Contact email sent to identify the client (used by Nominatim). */
|
|
2045
2151
|
email?: string;
|
|
2152
|
+
/** Named organization-hosted ArcGIS GeocodeServer locators. */
|
|
2153
|
+
locators?: GeocodingLocator[];
|
|
2154
|
+
/** The {@link GeocodingLocator.id} used by the `arcgis-locator` provider. */
|
|
2155
|
+
locatorId?: string;
|
|
2156
|
+
}
|
|
2157
|
+
/**
|
|
2158
|
+
* An organization-hosted ArcGIS GeocodeServer locator. Everything here is
|
|
2159
|
+
* nonsecret: the URL is stored without its query string, so a pasted token never
|
|
2160
|
+
* reaches the project file, and a secured locator borrows the token of the
|
|
2161
|
+
* portal named by `portalUrl` at request time.
|
|
2162
|
+
*
|
|
2163
|
+
* The capability fields are read from the service's `?f=json` metadata when the
|
|
2164
|
+
* locator is checked in Settings; they are absent until then.
|
|
2165
|
+
*/
|
|
2166
|
+
interface GeocodingLocator {
|
|
2167
|
+
/** Stable id, unique within the project. */
|
|
2168
|
+
id: string;
|
|
2169
|
+
/** Display name, e.g. "County Parcel Locator". */
|
|
2170
|
+
name: string;
|
|
2171
|
+
/** The GeocodeServer base URL, ending in `/GeocodeServer`. */
|
|
2172
|
+
url: string;
|
|
2173
|
+
/** Portal whose sign-in authorizes this locator, when it is secured. */
|
|
2174
|
+
portalUrl?: string;
|
|
2175
|
+
/** The single-line input field the locator publishes (usually `SingleLine`). */
|
|
2176
|
+
singleLineField?: string;
|
|
2177
|
+
/** The structured input fields the locator publishes, in service order. */
|
|
2178
|
+
addressFields?: string[];
|
|
2179
|
+
/** Whether the service advertises `reverseGeocode`. */
|
|
2180
|
+
reverse?: boolean;
|
|
2181
|
+
/** Whether the service advertises `suggest`. */
|
|
2182
|
+
suggest?: boolean;
|
|
2183
|
+
/**
|
|
2184
|
+
* The published input field a search string goes to, chosen by the user for
|
|
2185
|
+
* a locator whose inputs are structured (an asset or parcel ID field, say).
|
|
2186
|
+
* Unset means the single-line field, or the only published field.
|
|
2187
|
+
*/
|
|
2188
|
+
searchField?: string;
|
|
2046
2189
|
}
|
|
2047
2190
|
interface ProjectPreferences {
|
|
2048
2191
|
map: MapPreferences;
|
|
@@ -2167,7 +2310,7 @@ interface StoryLayerOpacityChange {
|
|
|
2167
2310
|
/** Transition duration in milliseconds. */
|
|
2168
2311
|
duration?: number;
|
|
2169
2312
|
}
|
|
2170
|
-
/** A single scene in a
|
|
2313
|
+
/** A single scene in a story map. */
|
|
2171
2314
|
interface StoryChapter {
|
|
2172
2315
|
id: string;
|
|
2173
2316
|
title: string;
|
|
@@ -2181,6 +2324,8 @@ interface StoryChapter {
|
|
|
2181
2324
|
mapAnimation: StoryChapterAnimation;
|
|
2182
2325
|
/** Slowly rotate the camera once the transition settles. */
|
|
2183
2326
|
rotateAnimation: boolean;
|
|
2327
|
+
/** Autoplay dwell time after the camera arrives, in seconds (1–3600; default 15). */
|
|
2328
|
+
durationSeconds?: number;
|
|
2184
2329
|
onChapterEnter: StoryLayerOpacityChange[];
|
|
2185
2330
|
onChapterExit: StoryLayerOpacityChange[];
|
|
2186
2331
|
}
|
|
@@ -2198,7 +2343,7 @@ type StoryInsetPosition = "top-left" | "top-right" | "bottom-left" | "bottom-rig
|
|
|
2198
2343
|
type StorySlideMode = "none" | "blank" | "black" | "global" | "adjacent";
|
|
2199
2344
|
/** A start/closing slide that is actually shown (every mode except `"none"`). */
|
|
2200
2345
|
type StoryActiveSlideMode = Exclude<StorySlideMode, "none">;
|
|
2201
|
-
/**
|
|
2346
|
+
/** Story map authored on top of a GeoLibre project. */
|
|
2202
2347
|
interface StoryMap {
|
|
2203
2348
|
title: string;
|
|
2204
2349
|
subtitle: string;
|
|
@@ -2401,6 +2546,40 @@ type DashboardWidgetAggregation = "count" | "sum" | "mean";
|
|
|
2401
2546
|
* keys are simply ignored, so the record stays flat and easy to hand-edit.
|
|
2402
2547
|
* Saved in the project file so a dashboard reopens with its widgets intact.
|
|
2403
2548
|
*/
|
|
2549
|
+
/**
|
|
2550
|
+
* A saved map view in the Bookmarks panel. Mirrors `MapBookmark` from
|
|
2551
|
+
* maplibre-gl-components so the panel can load it unchanged.
|
|
2552
|
+
*/
|
|
2553
|
+
interface ProjectBookmark {
|
|
2554
|
+
/** Unique within the project. */
|
|
2555
|
+
id: string;
|
|
2556
|
+
name: string;
|
|
2557
|
+
/** Camera center longitude, -180..180. */
|
|
2558
|
+
lng: number;
|
|
2559
|
+
/** Camera center latitude, -90..90. */
|
|
2560
|
+
lat: number;
|
|
2561
|
+
zoom: number;
|
|
2562
|
+
/** Camera tilt in degrees, 0..85. */
|
|
2563
|
+
pitch: number;
|
|
2564
|
+
/** Camera rotation in degrees. */
|
|
2565
|
+
bearing: number;
|
|
2566
|
+
/** Creation time, milliseconds since the epoch. */
|
|
2567
|
+
createdAt: number;
|
|
2568
|
+
/** The {@link ProjectBookmarkGroup} it belongs to; absent when ungrouped. */
|
|
2569
|
+
groupId?: string;
|
|
2570
|
+
/**
|
|
2571
|
+
* Host state captured with the view. GeoLibre stores `visibleLayerIds`
|
|
2572
|
+
* (the layers to show when the bookmark is opened).
|
|
2573
|
+
*/
|
|
2574
|
+
extra?: Record<string, unknown>;
|
|
2575
|
+
}
|
|
2576
|
+
/** A folder in the Bookmarks panel. Folders do not nest. */
|
|
2577
|
+
interface ProjectBookmarkGroup {
|
|
2578
|
+
id: string;
|
|
2579
|
+
name: string;
|
|
2580
|
+
/** Whether the folder is collapsed in the panel. */
|
|
2581
|
+
collapsed: boolean;
|
|
2582
|
+
}
|
|
2404
2583
|
interface DashboardWidget {
|
|
2405
2584
|
/** Stable id, unique within the project (React key and store key). */
|
|
2406
2585
|
id: string;
|
|
@@ -2579,8 +2758,23 @@ interface GeoLibreProject {
|
|
|
2579
2758
|
models?: ProcessingModel[];
|
|
2580
2759
|
/** Recorded processing tool runs (Processing History; issue #1292). */
|
|
2581
2760
|
processingHistory?: ProcessingRun[];
|
|
2761
|
+
/**
|
|
2762
|
+
* Object-Based Analysis workbench state and run provenance (issue #3053):
|
|
2763
|
+
* settings, classes, and the tool calls, parameters, seeds and engine
|
|
2764
|
+
* versions behind the last segmentation, measurement and classification.
|
|
2765
|
+
* A versioned JSON object owned by the desktop app; omitted until the
|
|
2766
|
+
* workbench is used.
|
|
2767
|
+
*/
|
|
2768
|
+
obia?: Record<string, unknown>;
|
|
2582
2769
|
/** Saved Dashboard panel chart widgets (issue #401). */
|
|
2583
2770
|
widgets?: DashboardWidget[];
|
|
2771
|
+
/**
|
|
2772
|
+
* Saved map views (the Bookmarks panel), in panel order. Omitted when there
|
|
2773
|
+
* are none. Before #2869 these lived only in the browser's localStorage.
|
|
2774
|
+
*/
|
|
2775
|
+
bookmarks?: ProjectBookmark[];
|
|
2776
|
+
/** Folders the {@link bookmarks} are organized into. Omitted when none. */
|
|
2777
|
+
bookmarkGroups?: ProjectBookmarkGroup[];
|
|
2584
2778
|
/** Number of columns in the Dashboard widget grid; omitted when default. */
|
|
2585
2779
|
dashboardColumns?: number;
|
|
2586
2780
|
/**
|
|
@@ -2722,11 +2916,11 @@ declare function detectNonGeographicCoordinates(geojson: GeoJSON.FeatureCollecti
|
|
|
2722
2916
|
/**
|
|
2723
2917
|
* Celestial-body ellipsoids and the planetary basemaps that pair with them.
|
|
2724
2918
|
*
|
|
2725
|
-
* GeoLibre is Earth-centric by construction:
|
|
2726
|
-
* and all vector data is kept as
|
|
2727
|
-
* change that
|
|
2728
|
-
*
|
|
2729
|
-
*
|
|
2919
|
+
* GeoLibre is Earth-centric by construction: the default map is Web Mercator
|
|
2920
|
+
* and all vector data is kept as lon/lat GeoJSON. This module does *not*
|
|
2921
|
+
* change that (a map drawn in a body's own polar or simple-cylindrical CRS is
|
|
2922
|
+
* `map-crs.ts`). What it adds is a per-project notion of *which body* the
|
|
2923
|
+
* coordinates describe, so that:
|
|
2730
2924
|
*
|
|
2731
2925
|
* - distance / area / scale measurements use that body's radius instead of a
|
|
2732
2926
|
* hardcoded Earth radius, and
|
|
@@ -3214,5 +3408,515 @@ declare function cascadeLayerJoinRefresh(layers: GeoLibreLayer[], seedId: string
|
|
|
3214
3408
|
*/
|
|
3215
3409
|
declare function reapplyLayerJoins(layers: GeoLibreLayer[]): GeoLibreLayer[];
|
|
3216
3410
|
//#endregion
|
|
3217
|
-
|
|
3218
|
-
|
|
3411
|
+
//#region src/project.d.ts
|
|
3412
|
+
/** Placeholder name a project carries before the user names it. */
|
|
3413
|
+
declare const DEFAULT_PROJECT_NAME = "Untitled Project";
|
|
3414
|
+
interface CreateProjectOptions {
|
|
3415
|
+
basemapStyleUrl?: string;
|
|
3416
|
+
mapView?: MapViewState;
|
|
3417
|
+
/** Celestial body the project describes; defaults to Earth when omitted. */
|
|
3418
|
+
ellipsoidId?: string;
|
|
3419
|
+
}
|
|
3420
|
+
declare function normalizeBlankBackgroundColor(value: unknown): string | null;
|
|
3421
|
+
declare function createDefaultMapView(): MapViewState;
|
|
3422
|
+
declare function createEmptyProject(name?: string, options?: CreateProjectOptions): GeoLibreProject;
|
|
3423
|
+
/**
|
|
3424
|
+
* Serialize a project to `.geolibre.json` text: indented project structure with
|
|
3425
|
+
* compact (unindented) embedded GeoJSON. See {@link serializeProjectValue} for
|
|
3426
|
+
* why the two halves are formatted differently.
|
|
3427
|
+
*
|
|
3428
|
+
* @param project Project to serialize.
|
|
3429
|
+
* @returns The file contents to write.
|
|
3430
|
+
*/
|
|
3431
|
+
declare function serializeProject(project: GeoLibreProject): string;
|
|
3432
|
+
/**
|
|
3433
|
+
* Per-layer serialized text kept across {@link serializeProjectWithLayerCache}
|
|
3434
|
+
* calls, keyed by the layer record each entry was built from. A `WeakMap`, so a
|
|
3435
|
+
* layer the store has replaced or removed drops its text with it.
|
|
3436
|
+
*/
|
|
3437
|
+
type ProjectLayerSerializationCache = WeakMap<object, {
|
|
3438
|
+
index: number;
|
|
3439
|
+
text: string;
|
|
3440
|
+
}>;
|
|
3441
|
+
/** Create an empty {@link ProjectLayerSerializationCache}. */
|
|
3442
|
+
declare function createProjectLayerSerializationCache(): ProjectLayerSerializationCache;
|
|
3443
|
+
/**
|
|
3444
|
+
* Serialize a project exactly as {@link serializeProject} does, reusing the
|
|
3445
|
+
* text of every layer whose source record is unchanged since an earlier call.
|
|
3446
|
+
*
|
|
3447
|
+
* Feature data lives inside layer records, so re-stringifying every layer on
|
|
3448
|
+
* each autosave costs megabytes of main-thread work for a project with large
|
|
3449
|
+
* GeoJSON layers — even when only the camera moved (GeoLibre#2633). The store
|
|
3450
|
+
* replaces a layer object whenever it changes, so object identity is a sound
|
|
3451
|
+
* cache key: a camera move reuses every layer, and an edit to one layer
|
|
3452
|
+
* re-serializes only that one.
|
|
3453
|
+
*
|
|
3454
|
+
* `layerSources[i]` must be the record `project.layers[i]` was derived from
|
|
3455
|
+
* (e.g. the store's `layers`, before `projectFromStore` prepared them), and that
|
|
3456
|
+
* derivation must depend on the record alone — as `buildProjectSnapshot`'s does
|
|
3457
|
+
* — or a cached entry could outlive a change it should have reflected. When the
|
|
3458
|
+
* two arrays differ in length the cache is bypassed rather than trusted.
|
|
3459
|
+
*
|
|
3460
|
+
* @param project Project to serialize, as built from `layerSources`.
|
|
3461
|
+
* @param layerSources Immutable source record for each entry of
|
|
3462
|
+
* `project.layers`, in the same order, used as the cache key.
|
|
3463
|
+
* @param cache Cache shared between calls; see
|
|
3464
|
+
* {@link createProjectLayerSerializationCache}.
|
|
3465
|
+
* @returns The same text {@link serializeProject} returns for `project`.
|
|
3466
|
+
*/
|
|
3467
|
+
declare function serializeProjectWithLayerCache(project: GeoLibreProject, layerSources: readonly object[], cache: ProjectLayerSerializationCache): string;
|
|
3468
|
+
/**
|
|
3469
|
+
* {@link serializeProjectWithLayerCache} that hands the main thread back
|
|
3470
|
+
* between layers, so autosave on a project with several large layers is many
|
|
3471
|
+
* short tasks instead of one 300-400 ms freeze (GeoLibre#2869).
|
|
3472
|
+
*
|
|
3473
|
+
* The cache makes a camera move free, so the cost lands on the first autosave
|
|
3474
|
+
* and on edits to a big layer: each layer that misses the cache is serialized
|
|
3475
|
+
* in its own slice, and the thread is released once a slice has run longer than
|
|
3476
|
+
* a few milliseconds. A single huge layer is still one slice. The result is
|
|
3477
|
+
* identical to the synchronous call. `project` and `layerSources` must not be
|
|
3478
|
+
* mutated while this runs; the store replaces records rather than editing them,
|
|
3479
|
+
* so a snapshot taken from it stays valid.
|
|
3480
|
+
*
|
|
3481
|
+
* @param project Project to serialize, as built from `layerSources`.
|
|
3482
|
+
* @param layerSources Immutable source record for each entry of
|
|
3483
|
+
* `project.layers`, in the same order, used as the cache key.
|
|
3484
|
+
* @param cache Cache shared between calls.
|
|
3485
|
+
* @param yieldFn Hands the thread back; replaced in tests.
|
|
3486
|
+
* @returns The same text {@link serializeProject} returns for `project`.
|
|
3487
|
+
*/
|
|
3488
|
+
declare function serializeProjectWithLayerCacheAsync(project: GeoLibreProject, layerSources: readonly object[], cache: ProjectLayerSerializationCache, yieldFn?: () => Promise<void>): Promise<string>;
|
|
3489
|
+
declare function parseProject(json: string): GeoLibreProject;
|
|
3490
|
+
/**
|
|
3491
|
+
* Coerce an untrusted (possibly hand-edited) legend config into a valid
|
|
3492
|
+
* {@link LegendConfig}, dropping malformed entries. Returns undefined when no
|
|
3493
|
+
* usable config is present so the default is applied downstream.
|
|
3494
|
+
*/
|
|
3495
|
+
declare function normalizeLegendConfig(legend: unknown): LegendConfig | undefined;
|
|
3496
|
+
/**
|
|
3497
|
+
* Validate and coerce a story map loaded from an untrusted project file.
|
|
3498
|
+
*
|
|
3499
|
+
* Returns null when the value carries no chapters so empty story maps stay out
|
|
3500
|
+
* of the saved project, mirroring how plugins are only persisted when present.
|
|
3501
|
+
*
|
|
3502
|
+
* @param storymap Raw value read from the project JSON.
|
|
3503
|
+
* @returns A normalized story map, or null when there is nothing to keep.
|
|
3504
|
+
*/
|
|
3505
|
+
declare function normalizeStoryMap(storymap: unknown): StoryMap | null;
|
|
3506
|
+
/** Whether a story map carries chapters or any non-default setting. */
|
|
3507
|
+
declare function storyMapHasContent(story: StoryMap): boolean;
|
|
3508
|
+
/**
|
|
3509
|
+
* Coerce an untrusted (possibly hand-edited) `models` array into valid
|
|
3510
|
+
* {@link ProcessingModel} records. Drops models and steps without a usable id or
|
|
3511
|
+
* tool id, de-duplicates models by id, and keeps step `parameters` as a plain
|
|
3512
|
+
* object (the runner validates parameter values per tool at run time). Returns
|
|
3513
|
+
* `null` when there is nothing worth persisting, so a model-less project stays
|
|
3514
|
+
* free of the key.
|
|
3515
|
+
*
|
|
3516
|
+
* @param value Raw `models` value from the project JSON.
|
|
3517
|
+
* @returns Normalized models, or `null` when none survive.
|
|
3518
|
+
*/
|
|
3519
|
+
declare function normalizeModels(value: unknown): ProcessingModel[] | null;
|
|
3520
|
+
/**
|
|
3521
|
+
* Coerce an untrusted `graph` value into a {@link ProcessingModelGraph}. Drops
|
|
3522
|
+
* nodes without a usable id or an unknown kind, de-duplicates node ids, and
|
|
3523
|
+
* drops edges that do not connect two surviving nodes or that name an empty
|
|
3524
|
+
* port. Self-edges are dropped too, since a node cannot feed itself.
|
|
3525
|
+
*
|
|
3526
|
+
* Structural validity beyond this (cycles, type mismatches, missing required
|
|
3527
|
+
* inputs) is the runner's job — those depend on the tool registries, which the
|
|
3528
|
+
* project layer deliberately does not import.
|
|
3529
|
+
*
|
|
3530
|
+
* @param value Raw `graph` value from the project JSON.
|
|
3531
|
+
* @returns The normalized graph, or `null` when it has no usable nodes.
|
|
3532
|
+
*/
|
|
3533
|
+
declare function normalizeModelGraph(value: unknown): ProcessingModelGraph | null;
|
|
3534
|
+
/**
|
|
3535
|
+
* Coerce an untrusted (possibly hand-edited) `processingHistory` array into
|
|
3536
|
+
* valid {@link ProcessingRun} records. Drops entries without a usable id, tool
|
|
3537
|
+
* id, or known kind, de-duplicates by id, keeps `parameters` as a plain object,
|
|
3538
|
+
* and caps the list at {@link MAX_PROCESSING_HISTORY} (keeping the newest,
|
|
3539
|
+
* i.e. last, entries). Returns `null` when nothing survives, so a history-less
|
|
3540
|
+
* project stays free of the key.
|
|
3541
|
+
*
|
|
3542
|
+
* @param value Raw `processingHistory` value from the project JSON.
|
|
3543
|
+
* @returns Normalized runs, or `null` when none survive.
|
|
3544
|
+
*/
|
|
3545
|
+
/**
|
|
3546
|
+
* Accept the Object-Based Analysis workbench blob (`obia`) only as a plain,
|
|
3547
|
+
* JSON-serializable object carrying a numeric `version`. Its fields are owned
|
|
3548
|
+
* and validated by the desktop app, which treats anything it does not
|
|
3549
|
+
* recognise as absent; core only guarantees the shape survives a round trip.
|
|
3550
|
+
*
|
|
3551
|
+
* @param value Raw `obia` value from the project JSON.
|
|
3552
|
+
* @returns A detached copy, or `null` when absent or malformed.
|
|
3553
|
+
*/
|
|
3554
|
+
declare function normalizeObiaWorkbench(value: unknown): Record<string, unknown> | null;
|
|
3555
|
+
declare function normalizeProcessingHistory(value: unknown): ProcessingRun[] | null;
|
|
3556
|
+
/**
|
|
3557
|
+
* Coerce an untrusted (possibly hand-edited) camera object into a valid
|
|
3558
|
+
* {@link MapViewState}, falling back to the default view for missing parts.
|
|
3559
|
+
*/
|
|
3560
|
+
declare function normalizeMapViewState(value: unknown): MapViewState;
|
|
3561
|
+
/**
|
|
3562
|
+
* Coerce an untrusted `mapLayout` into a valid {@link MapGridLayout}. Returns
|
|
3563
|
+
* null when absent or effectively single-pane so default projects stay
|
|
3564
|
+
* byte-identical (the field is only written when the grid is larger than 1x1).
|
|
3565
|
+
*/
|
|
3566
|
+
declare function normalizeMapLayout(value: unknown): MapGridLayout | null;
|
|
3567
|
+
/**
|
|
3568
|
+
* Coerce an untrusted `primaryRenderer` into a known engine id (issue #2217).
|
|
3569
|
+
*
|
|
3570
|
+
* Returns null for the default 2D map — absent, unknown, or an explicit
|
|
3571
|
+
* `"maplibre"` — because the field is only written when it is not the default,
|
|
3572
|
+
* so a MapLibre project serializes byte-identically to before this existed.
|
|
3573
|
+
* The return type is narrowed to `"cesium" | "mapbox" | "arcgis" | null` rather
|
|
3574
|
+
* than the full {@link MapRendererKind} for that reason: `"maplibre"` is never a
|
|
3575
|
+
* result.
|
|
3576
|
+
*/
|
|
3577
|
+
declare function normalizePrimaryRenderer(value: unknown): "cesium" | "mapbox" | "arcgis" | null;
|
|
3578
|
+
/**
|
|
3579
|
+
* Coerce an untrusted `secondaryMapViews` array into valid
|
|
3580
|
+
* {@link SecondaryMapView} records, dropping entries without a usable id and
|
|
3581
|
+
* de-duplicating by id. Returns null when none are valid.
|
|
3582
|
+
*/
|
|
3583
|
+
declare function normalizeSecondaryMapViews(value: unknown): SecondaryMapView[] | null;
|
|
3584
|
+
/**
|
|
3585
|
+
* Reconcile a parsed grid layout with its secondary panes so the store invariant
|
|
3586
|
+
* holds: `secondaryMapViews.length === rows * cols - 1`. Surplus panes are
|
|
3587
|
+
* dropped; missing panes are filled by cloning the primary map. A null/absent
|
|
3588
|
+
* layout (or a 1x1 grid) collapses to the single-map default.
|
|
3589
|
+
*/
|
|
3590
|
+
declare function resolveMapGrid(layout: MapGridLayout | null, secondaryViews: SecondaryMapView[] | null, primary: {
|
|
3591
|
+
mapView: MapViewState;
|
|
3592
|
+
}): {
|
|
3593
|
+
mapLayout: MapGridLayout;
|
|
3594
|
+
secondaryMapViews: SecondaryMapView[];
|
|
3595
|
+
};
|
|
3596
|
+
/** Bookmarks kept per project, as the panel's own default limit allows. */
|
|
3597
|
+
declare const MAX_PROJECT_BOOKMARKS = 500;
|
|
3598
|
+
/**
|
|
3599
|
+
* Coerce an untrusted `bookmarkGroups` array into valid folders: drops entries
|
|
3600
|
+
* without a string id and de-duplicates by id. A missing name becomes
|
|
3601
|
+
* "Folder"; `collapsed` defaults to false.
|
|
3602
|
+
*
|
|
3603
|
+
* @param value Raw `bookmarkGroups` value from the project JSON.
|
|
3604
|
+
* @returns The folders (possibly empty).
|
|
3605
|
+
*/
|
|
3606
|
+
declare function normalizeBookmarkGroups(value: unknown): ProjectBookmarkGroup[];
|
|
3607
|
+
/**
|
|
3608
|
+
* Coerce an untrusted `bookmarks` array into valid saved views: drops entries
|
|
3609
|
+
* without a string id or a finite, in-range camera, de-duplicates by id, wraps
|
|
3610
|
+
* the bearing into 0-360, and drops a `groupId` that names no folder in
|
|
3611
|
+
* `groups`. Keeps at most {@link MAX_PROJECT_BOOKMARKS}.
|
|
3612
|
+
*
|
|
3613
|
+
* @param value Raw `bookmarks` value from the project JSON.
|
|
3614
|
+
* @param groups The project's (normalized) folders.
|
|
3615
|
+
* @returns The bookmarks (possibly empty).
|
|
3616
|
+
*/
|
|
3617
|
+
declare function normalizeBookmarks(value: unknown, groups?: readonly ProjectBookmarkGroup[]): ProjectBookmark[];
|
|
3618
|
+
/**
|
|
3619
|
+
* Coerce an untrusted (possibly hand-edited) `widgets` array into valid
|
|
3620
|
+
* {@link DashboardWidget} records. Drops widgets without a usable id, layer id,
|
|
3621
|
+
* or recognized chart type, de-duplicates by id, and keeps only the optional
|
|
3622
|
+
* keys that are present and well-typed (the Dashboard panel falls back to
|
|
3623
|
+
* sensible defaults for anything missing). Returns `null` when there is nothing
|
|
3624
|
+
* worth persisting, so a widget-less project stays free of the key.
|
|
3625
|
+
*
|
|
3626
|
+
* @param value Raw `widgets` value from the project JSON.
|
|
3627
|
+
* @returns Normalized widgets, or `null` when none survive.
|
|
3628
|
+
*/
|
|
3629
|
+
declare function normalizeWidgets(value: unknown): DashboardWidget[] | null;
|
|
3630
|
+
/**
|
|
3631
|
+
* Clamp an untrusted dashboard column count into the supported range, falling
|
|
3632
|
+
* back to the default for a missing or non-finite value.
|
|
3633
|
+
*
|
|
3634
|
+
* @param value Raw `dashboardColumns` value from the project JSON.
|
|
3635
|
+
* @returns An integer column count within [MIN, MAX].
|
|
3636
|
+
*/
|
|
3637
|
+
declare function normalizeDashboardColumns(value: unknown): number;
|
|
3638
|
+
/**
|
|
3639
|
+
* Coerce an untrusted `interaction` block into a {@link ProjectInteraction}.
|
|
3640
|
+
*
|
|
3641
|
+
* Layer ids are kept even when no such layer exists: the block is replayed
|
|
3642
|
+
* against whatever layers the project has when it opens, and the loader drops
|
|
3643
|
+
* the ones it cannot find. Control names are kept as written for the same
|
|
3644
|
+
* reason; the app ignores names it does not know.
|
|
3645
|
+
*
|
|
3646
|
+
* @param value - Raw `interaction` value from the project JSON or the store.
|
|
3647
|
+
* @returns The normalized block, or null when it carries nothing to apply.
|
|
3648
|
+
*/
|
|
3649
|
+
declare function normalizeProjectInteraction(value: unknown): ProjectInteraction | null;
|
|
3650
|
+
declare function isAllowedPluginManifestUrl(url: string): boolean;
|
|
3651
|
+
declare function normalizeProjectComments(rawComments: unknown): ProjectComment[];
|
|
3652
|
+
declare function projectFromStore(state: {
|
|
3653
|
+
projectName: string;
|
|
3654
|
+
mapView: MapViewState;
|
|
3655
|
+
basemapStyleUrl: string;
|
|
3656
|
+
basemapVisible: boolean;
|
|
3657
|
+
basemapOpacity: number;
|
|
3658
|
+
blankBackgroundColor?: string | null;
|
|
3659
|
+
layers: GeoLibreLayer[];
|
|
3660
|
+
selectedLayerId?: string | null;
|
|
3661
|
+
layerGroups?: LayerGroup[];
|
|
3662
|
+
preferences: ProjectPreferences;
|
|
3663
|
+
plugins?: ProjectPluginState | null;
|
|
3664
|
+
legend?: LegendConfig | null;
|
|
3665
|
+
printLayout?: PrintLayoutConfig | null;
|
|
3666
|
+
storymap?: StoryMap | null;
|
|
3667
|
+
models?: ProcessingModel[] | null;
|
|
3668
|
+
processingHistory?: ProcessingRun[] | null;
|
|
3669
|
+
obia?: Record<string, unknown> | null;
|
|
3670
|
+
widgets?: DashboardWidget[] | null;
|
|
3671
|
+
bookmarks?: ProjectBookmark[] | null;
|
|
3672
|
+
bookmarkGroups?: ProjectBookmarkGroup[] | null;
|
|
3673
|
+
dashboardColumns?: number;
|
|
3674
|
+
mapLayout?: MapGridLayout;
|
|
3675
|
+
secondaryMapViews?: SecondaryMapView[];
|
|
3676
|
+
primaryMapLabel?: string;
|
|
3677
|
+
primaryRenderer?: MapRendererKind;
|
|
3678
|
+
/** Project-scoped Style Manager entries (the store's `projectStyleLibrary`). */
|
|
3679
|
+
styleLibrary?: StyleLibraryEntry[] | null;
|
|
3680
|
+
comments?: ProjectComment[] | null;
|
|
3681
|
+
/** Startup interaction state loaded with the project, written back as-is. */
|
|
3682
|
+
interaction?: ProjectInteraction | null;
|
|
3683
|
+
metadata: Record<string, unknown>;
|
|
3684
|
+
}): GeoLibreProject;
|
|
3685
|
+
/**
|
|
3686
|
+
* Whether a layer lives only for the current session and is never written to a
|
|
3687
|
+
* project file. A plugin sets `metadata.sessionOnly` on a store row that mirrors
|
|
3688
|
+
* something it draws itself and cannot restore, such as a point cloud streamed
|
|
3689
|
+
* from a short-lived signed URL, so the row shows in the Layers panel while the
|
|
3690
|
+
* plugin runs but a reopened project carries no dead entry for it.
|
|
3691
|
+
*
|
|
3692
|
+
* @param layer - The layer to check.
|
|
3693
|
+
* @returns `true` when the layer must be left out of saved projects.
|
|
3694
|
+
*/
|
|
3695
|
+
declare function isSessionOnlyLayer(layer: GeoLibreLayer): boolean;
|
|
3696
|
+
/**
|
|
3697
|
+
* The plain HTTP(S) WMS template inside the desktop app's `geolibre-wms://`
|
|
3698
|
+
* wrapper (its CORS-exempt native fetcher), or the tile unchanged when it is
|
|
3699
|
+
* not wrapped or the wrapped URL is not HTTP(S). Shared by project export and
|
|
3700
|
+
* the ArcGIS engine's story-export templates.
|
|
3701
|
+
*
|
|
3702
|
+
* @param tile - A tile template, wrapped or not.
|
|
3703
|
+
* @returns The unwrapped template, or `tile` itself.
|
|
3704
|
+
*/
|
|
3705
|
+
declare function portableWmsTileUrl(tile: unknown): unknown;
|
|
3706
|
+
/**
|
|
3707
|
+
* The store form of one project layer: its style completed from
|
|
3708
|
+
* {@link DEFAULT_LAYER_STYLE} and the project's top-level `styles` entry.
|
|
3709
|
+
*
|
|
3710
|
+
* Legacy and externally-authored projects can carry a partial top-level style
|
|
3711
|
+
* alongside newer fields on the layer itself. Those layer fields are kept,
|
|
3712
|
+
* while the top-level copy stays authoritative where it explicitly supplies a
|
|
3713
|
+
* value.
|
|
3714
|
+
*
|
|
3715
|
+
* @param project - The project the layer belongs to (for its `styles` map).
|
|
3716
|
+
* @param layer - One of `project.layers`.
|
|
3717
|
+
* @returns A new layer record ready for the store.
|
|
3718
|
+
*/
|
|
3719
|
+
declare function hydrateProjectLayer(project: Pick<GeoLibreProject, "styles">, layer: GeoLibreLayer): GeoLibreLayer;
|
|
3720
|
+
declare function applyProjectToStore(project: GeoLibreProject): {
|
|
3721
|
+
projectName: string;
|
|
3722
|
+
mapView: MapViewState;
|
|
3723
|
+
basemapStyleUrl: string;
|
|
3724
|
+
basemapVisible: boolean;
|
|
3725
|
+
basemapOpacity: number;
|
|
3726
|
+
blankBackgroundColor: string | null;
|
|
3727
|
+
layers: GeoLibreLayer[];
|
|
3728
|
+
layerGroups: LayerGroup[];
|
|
3729
|
+
preferences: ProjectPreferences;
|
|
3730
|
+
projectPlugins: ProjectPluginState | null;
|
|
3731
|
+
legend: LegendConfig;
|
|
3732
|
+
printLayout: PrintLayoutConfig;
|
|
3733
|
+
storymap: StoryMap | null;
|
|
3734
|
+
models: ProcessingModel[];
|
|
3735
|
+
processingHistory: ProcessingRun[];
|
|
3736
|
+
obiaWorkbench: Record<string, unknown> | null;
|
|
3737
|
+
widgets: DashboardWidget[];
|
|
3738
|
+
bookmarks: ProjectBookmark[];
|
|
3739
|
+
bookmarkGroups: ProjectBookmarkGroup[];
|
|
3740
|
+
dashboardColumns: number;
|
|
3741
|
+
mapLayout: MapGridLayout;
|
|
3742
|
+
secondaryMapViews: SecondaryMapView[];
|
|
3743
|
+
primaryMapLabel: string;
|
|
3744
|
+
primaryRenderer: MapRendererKind;
|
|
3745
|
+
projectStyleLibrary: StyleLibraryEntry[];
|
|
3746
|
+
comments: ProjectComment[];
|
|
3747
|
+
projectInteraction: ProjectInteraction | null;
|
|
3748
|
+
metadata: Record<string, unknown>;
|
|
3749
|
+
};
|
|
3750
|
+
/**
|
|
3751
|
+
* Create an unlinked copy of a project, suffixed with "(copy)" by default and
|
|
3752
|
+
* stripped of share-specific metadata (shareId, shareUrl, etc.).
|
|
3753
|
+
*/
|
|
3754
|
+
declare function detachProjectCopy(project: GeoLibreProject, options?: {
|
|
3755
|
+
nameSuffix?: string;
|
|
3756
|
+
}): GeoLibreProject;
|
|
3757
|
+
/**
|
|
3758
|
+
* Create a template snapshot of a project. Optionally strips data layers while
|
|
3759
|
+
* keeping basemap, layer groups, styles, legend config, preferences, widgets, and
|
|
3760
|
+
* print layout.
|
|
3761
|
+
*/
|
|
3762
|
+
declare function createProjectTemplate(project: GeoLibreProject, options?: {
|
|
3763
|
+
name?: string;
|
|
3764
|
+
stripDataLayers?: boolean;
|
|
3765
|
+
}): GeoLibreProject;
|
|
3766
|
+
//#endregion
|
|
3767
|
+
//#region src/project-diff.d.ts
|
|
3768
|
+
/** One changed value, with bounded human-readable previews of each side. */
|
|
3769
|
+
interface ProjectValueChange {
|
|
3770
|
+
/** Dotted key path relative to the section, e.g. `fillColor` or `labels.field`. */
|
|
3771
|
+
path: string;
|
|
3772
|
+
/** Preview of the earlier value; `undefined` when the key was absent. */
|
|
3773
|
+
before?: string;
|
|
3774
|
+
/** Preview of the later value; `undefined` when the key is now absent. */
|
|
3775
|
+
after?: string;
|
|
3776
|
+
}
|
|
3777
|
+
/** Counts of embedded GeoJSON feature changes in one layer. */
|
|
3778
|
+
interface FeatureChangeSummary {
|
|
3779
|
+
added: number;
|
|
3780
|
+
removed: number;
|
|
3781
|
+
modified: number;
|
|
3782
|
+
unchanged: number;
|
|
3783
|
+
/**
|
|
3784
|
+
* How features were matched: `"id"` when every feature carries a unique
|
|
3785
|
+
* `id`, `"geometry"` when none does (matched by geometry hash), `"mixed"`
|
|
3786
|
+
* otherwise.
|
|
3787
|
+
*/
|
|
3788
|
+
matchedBy: "id" | "geometry" | "mixed";
|
|
3789
|
+
}
|
|
3790
|
+
/** Changes to one layer between the two projects. */
|
|
3791
|
+
interface LayerDiff {
|
|
3792
|
+
id: string;
|
|
3793
|
+
/** Layer name in the later project (or the earlier one when removed). */
|
|
3794
|
+
name: string;
|
|
3795
|
+
/** Layer type in the later project (or the earlier one when removed). */
|
|
3796
|
+
type: string;
|
|
3797
|
+
status: "added" | "removed" | "changed";
|
|
3798
|
+
/** Set when the layer was renamed. */
|
|
3799
|
+
renamed?: {
|
|
3800
|
+
before: string;
|
|
3801
|
+
after: string;
|
|
3802
|
+
};
|
|
3803
|
+
/**
|
|
3804
|
+
* Set when the layer changed position relative to the layers present in
|
|
3805
|
+
* both projects (bottom-to-top indexes in each project's `layers`).
|
|
3806
|
+
*/
|
|
3807
|
+
moved?: {
|
|
3808
|
+
before: number;
|
|
3809
|
+
after: number;
|
|
3810
|
+
};
|
|
3811
|
+
visibility?: {
|
|
3812
|
+
before: boolean;
|
|
3813
|
+
after: boolean;
|
|
3814
|
+
};
|
|
3815
|
+
opacity?: {
|
|
3816
|
+
before: number;
|
|
3817
|
+
after: number;
|
|
3818
|
+
};
|
|
3819
|
+
/** Style keys other than labels. */
|
|
3820
|
+
style: ProjectValueChange[];
|
|
3821
|
+
/** Label style keys (`style.labels.*`), without the `labels.` prefix. */
|
|
3822
|
+
labels: ProjectValueChange[];
|
|
3823
|
+
/** `filterExpression` and `quickFilters`. */
|
|
3824
|
+
filter: ProjectValueChange[];
|
|
3825
|
+
/** `type`, `source.*` and `sourcePath`. */
|
|
3826
|
+
source: ProjectValueChange[];
|
|
3827
|
+
/** Any other persisted layer field (popup, joins, metadata.*, ...). */
|
|
3828
|
+
other: ProjectValueChange[];
|
|
3829
|
+
/** Embedded GeoJSON feature changes; absent when the data is unchanged. */
|
|
3830
|
+
features?: FeatureChangeSummary;
|
|
3831
|
+
/** Feature count for an added or removed layer with embedded GeoJSON. */
|
|
3832
|
+
featureCount?: number;
|
|
3833
|
+
}
|
|
3834
|
+
/** Changes to one plugin's project state. */
|
|
3835
|
+
interface PluginDiff {
|
|
3836
|
+
id: string;
|
|
3837
|
+
/** `added`/`removed` mean the plugin was activated/deactivated. */
|
|
3838
|
+
status: "added" | "removed" | "changed";
|
|
3839
|
+
changes: ProjectValueChange[];
|
|
3840
|
+
}
|
|
3841
|
+
/** The full structured difference between two projects. */
|
|
3842
|
+
interface ProjectDiff {
|
|
3843
|
+
layers: {
|
|
3844
|
+
added: LayerDiff[];
|
|
3845
|
+
removed: LayerDiff[];
|
|
3846
|
+
changed: LayerDiff[];
|
|
3847
|
+
/** True when any layer present in both projects changed position. */
|
|
3848
|
+
reordered: boolean;
|
|
3849
|
+
};
|
|
3850
|
+
camera: ProjectValueChange[];
|
|
3851
|
+
basemap: ProjectValueChange[];
|
|
3852
|
+
/** Map projection (`preferences.map.projection`). */
|
|
3853
|
+
projection: ProjectValueChange[];
|
|
3854
|
+
/** Other project preferences (`preferences.*` minus the projection). */
|
|
3855
|
+
preferences: ProjectValueChange[];
|
|
3856
|
+
plugins: PluginDiff[];
|
|
3857
|
+
/** Plugin manifest URLs added to or removed from the project. */
|
|
3858
|
+
pluginManifests: {
|
|
3859
|
+
added: string[];
|
|
3860
|
+
removed: string[];
|
|
3861
|
+
};
|
|
3862
|
+
/** Project name (`name`), `metadata.description` and other metadata keys. */
|
|
3863
|
+
metadata: ProjectValueChange[];
|
|
3864
|
+
/** Other top-level sections that changed (`legend`, `storymap`, ...). */
|
|
3865
|
+
sections: string[];
|
|
3866
|
+
/** Total number of reported changes; 0 means the projects are equivalent. */
|
|
3867
|
+
changeCount: number;
|
|
3868
|
+
}
|
|
3869
|
+
/** Options for {@link diffProjects}. */
|
|
3870
|
+
interface ProjectDiffOptions {
|
|
3871
|
+
/** Maximum characters of a before/after preview (default 80). */
|
|
3872
|
+
maxPreviewLength?: number;
|
|
3873
|
+
}
|
|
3874
|
+
/**
|
|
3875
|
+
* Deep structural equality for JSON-like values. A key whose value is
|
|
3876
|
+
* `undefined` is treated as absent, so an in-memory record compares equal to
|
|
3877
|
+
* its JSON round trip.
|
|
3878
|
+
*
|
|
3879
|
+
* @param a - First value.
|
|
3880
|
+
* @param b - Second value.
|
|
3881
|
+
* @returns True when the two values are structurally equal.
|
|
3882
|
+
*/
|
|
3883
|
+
declare function jsonValuesEqual(a: unknown, b: unknown): boolean;
|
|
3884
|
+
/**
|
|
3885
|
+
* Render a bounded JSON-ish preview of a value without serializing more of it
|
|
3886
|
+
* than the preview can show, so a large array or object costs no more than
|
|
3887
|
+
* `maxLength` characters of work.
|
|
3888
|
+
*
|
|
3889
|
+
* @param value - The value to preview.
|
|
3890
|
+
* @param maxLength - Maximum preview length; longer output ends with `…`.
|
|
3891
|
+
* @returns The preview, or `undefined` for `undefined`.
|
|
3892
|
+
*/
|
|
3893
|
+
declare function previewValue(value: unknown, maxLength?: number): string | undefined;
|
|
3894
|
+
/**
|
|
3895
|
+
* Count the features added, removed and modified between two feature
|
|
3896
|
+
* collections. Features are matched by `id` when they carry one; id-less
|
|
3897
|
+
* features are matched by geometry hash, so a feature whose properties
|
|
3898
|
+
* changed but whose geometry did not counts as modified, while a moved
|
|
3899
|
+
* id-less feature counts as one removal plus one addition.
|
|
3900
|
+
*
|
|
3901
|
+
* @param before - Earlier collection (absent counts as empty).
|
|
3902
|
+
* @param after - Later collection (absent counts as empty).
|
|
3903
|
+
* @returns The change counts.
|
|
3904
|
+
*/
|
|
3905
|
+
declare function diffFeatureCollections(before: FeatureCollection | null | undefined, after: FeatureCollection | null | undefined): FeatureChangeSummary;
|
|
3906
|
+
/**
|
|
3907
|
+
* Compute a structured summary of what changed from `before` to `after`.
|
|
3908
|
+
*
|
|
3909
|
+
* Layers are matched by id. Embedded GeoJSON is compared per feature (by id,
|
|
3910
|
+
* falling back to geometry hash) and each feature is hashed once per object,
|
|
3911
|
+
* so diffing the same parsed project against several others reuses its
|
|
3912
|
+
* hashes; callers keep and pass the same parsed project objects to benefit.
|
|
3913
|
+
*
|
|
3914
|
+
* @param before - The earlier project (e.g. an autosave snapshot).
|
|
3915
|
+
* @param after - The later project (e.g. the current project).
|
|
3916
|
+
* @param options - Preview length and other tuning.
|
|
3917
|
+
* @returns The grouped change summary.
|
|
3918
|
+
*/
|
|
3919
|
+
declare function diffProjects(before: GeoLibreProject, after: GeoLibreProject, options?: ProjectDiffOptions): ProjectDiff;
|
|
3920
|
+
//#endregion
|
|
3921
|
+
export { collectTransitiveJoinSourceIds as $, LegendConfig as $n, RuntimeEnvironmentVariable as $r, CollaborationParticipant as $t, normalizeMapViewState as A, scrubPrintLayoutForLayers as Ai, GeometryGeneratorType as An, PopupDateFormat as Ar, getActiveBodyRadiusRatio as At, normalizeWidgets as B, Geometry as Bi, LayerDescriptiveMetadata as Bn, ProcessingRunStatus as Br, AppCapabilities as Bt, isSessionOnlyLayer as C, PrintLayoutCorner as Ci, EditorTrackingConfig as Cn, NETCDF_IMAGE_SOURCE_KIND as Cr, PLANET_SWITCHER_OPTIONS as Ct, normalizeDashboardColumns as D, isDefaultPrintLayout as Di, GeoLibreProject as Dn, PROTOMAPS_BASEMAPS as Dr, bodyLengthToEarth as Dt, normalizeBookmarks as E, createDefaultPrintLayout as Ei, GeoLibreLayer as En, PROJECT_VERSION as Er, PlanetaryBasemapSectionId as Et, normalizeProcessingHistory as F, featureCollectionToGeoArrow as Fi, LabelDedupe as Fn, ProcessingModelGraph as Fr, getPlanetaryBasemapById as Ft, serializeProject as G, CESIUM_BASEMAPS as Gi, LayerMetadataContact as Gn, ProjectPluginControlPosition as Gr, AttributeFormValueMapEntry as Gt, portableWmsTileUrl as H, MultiPolygon as Hi, LayerJoin as Hn, ProjectBookmarkGroup as Hr, AppRole as Ht, normalizeProjectComments as I, geoArrowToFeatureCollection as Ii, LabelStyle as In, ProcessingModelStep as Ir, getPlanetaryBasemapByStyleUrl as It, storyMapHasContent as J, availableCesiumBasemap as Ji, LayerPopupConfig as Jn, ProjectTemplateEntry as Jr, BLEND_MODES as Jt, serializeProjectWithLayerCache as K, CesiumBasemapId as Ki, LayerMetadataLink as Kn, ProjectPluginState as Kr, AttributeFormWidget as Kt, normalizeProjectInteraction as L, isGeoArrowBatch as Li, LabelTransform as Ln, ProcessingRerunRequest as Lr, meanRadiusMeters as Lt, normalizeModels as M, GeoArrowBatch as Mi, LARGE_VECTOR_FEATURE_THRESHOLD as Mn, PopupFieldFormat as Mr, getActiveMeanRadiusMeters as Mt, normalizeObiaWorkbench as N, GeoArrowGeometryType as Ni, LAYER_TYPES as Nn, PopupFieldKind as Nr, getActiveSemiMajorAxisMeters as Nt, normalizeLegendConfig as O, normalizePrintLayoutConfig as Oi, GeocodingLocator as On, ParticipantIdentity as Or, earthAreaToBody as Ot, normalizePrimaryRenderer as P, computeGeoArrowBBox as Pi, LabelAnchor as Pn, ProcessingModel as Pr, getEllipsoid as Pt, cascadeLayerJoinRefresh as Q, LayerVirtualField as Qn, RecentProjectEntry as Qr, CollaborationMode as Qt, normalizeSecondaryMapViews as R, Feature as Ri, LayerCapabilities as Rn, ProcessingRun as Rr, setActiveEllipsoidId as Rt, isAllowedPluginManifestUrl as S, PrintLayoutConfig as Si, DiagramType as Sn, ModelToolProvider as Sr, PLANETARY_BASEMAP_SENTINEL_PREFIX as St, normalizeBookmarkGroups as T, PrintLayoutPageFilter as Ti, FillPattern as Tn, OPENFREEMAP_BASEMAPS as Tr, PlanetaryBasemapGroup as Tt, projectFromStore as U, Point as Ui, LayerJoinStats as Un, ProjectComment as Ur, AttributeFormConfig as Ut, parseProject as V, LineString as Vi, LayerGroup as Vn, ProjectBookmark as Vr, AppPrivilege as Vt, resolveMapGrid as W, Polygon as Wi, LayerLibraryEntry as Wn, ProjectInteraction as Wr, AttributeFormFieldConfig as Wt, applyJoinsToLayer as X, normalizeCesiumBasemap as Xi, LayerStyle as Xn, QuickFilterKind as Xr, CollabInvite as Xt, ApplyLayerJoinsResult as Y, basemapToCesiumImagery as Yi, LayerQuickFilter as Yn, QuickFilterDateKind as Yr, BlendMode as Yt, applyLayerJoins as Z, sameCesiumImagery as Zi, LayerType as Zn, QuickFilterTextOperator as Zr, CollaborationChatMessage as Zt, createEmptyProject as _, detectNonGeographicCoordinates as _i, DashboardWidget as _n, ModelGraphEdge as _r, ELLIPSOIDS as _t, ProjectDiffOptions as a, StoryChapterAnimation as ai, CommentReply as an, LineDecoration as ar, batchDecodePolylines as at, detachProjectCopy as b, styleValue as bi, DiagramField as bn, ModelGraphPort as br, PLANETARY_BASEMAPS as bt, diffProjects as c, StoryLayerOpacityChange as ci, DEFAULT_DASHBOARD_COLUMNS as cn, MAX_PROCESSING_HISTORY as cr, encodePolyline as ct, CreateProjectOptions as d, StrokeWidthUnit as di, DEFAULT_MAP_GRID_LAYOUT as dn, MapPreferences as dr, unescapePolyline as dt, SQL_QUERY_SOURCE_KIND as ei, CollaborationPresence as en, LegendCustomEntry as er, layerJoinKey as et, DEFAULT_PROJECT_NAME as f, StyleLibraryEntry as fi, DEFAULT_PRIMARY_RENDERER as fn, MapProjection as fr, geojsonHasZCoordinates as ft, createDefaultMapView as g, VectorStyleStop as gi, DUCKDB_VECTOR_ROUTE_BYTES as gn, MarkerShape as gr, EARTH_MEAN_RADIUS_METERS as gt, applyProjectToStore as h, VectorStyleMode as hi, DUCKDB_VECTOR_FEATURE_WARN_COUNT as hn, MapViewState as hr, DEFAULT_ELLIPSOID_ID as ht, ProjectDiff as i, StoryChapterAlignment as ii, CommentAuthor as in, LegendPanelPosition as ir, PolylineDecodeResult as it, normalizeModelGraph as j, scrubPrintLayoutForRemovedLayers as ji, IndicatorAggregation as jn, PopupFieldConfig as jr, getActiveEllipsoid as jt, normalizeMapLayout as k, printLayoutConfigsEqual as ki, GeocodingPreferences as kn, PointRenderer as kr, earthLengthToBody as kt, jsonValuesEqual as l, StoryMap as li, DEFAULT_LAYER_STYLE as ln, MIN_DASHBOARD_COLUMNS as lr, geoJSONToPolylineStr as lt, ProjectLayerSerializationCache as m, VectorRule as mi, DEFAULT_STORY_MAP as mn, MapScaleUnit as mr, transformGeojsonElevation as mt, LayerDiff as n, StoryActiveSlideMode as ni, CollaborationState as nn, LegendCustomShape as nr, stripJoinFields as nt, ProjectValueChange as o, StoryChapterLocation as oi, DEFAULT_BASEMAP as on, MAX_DASHBOARD_COLUMNS as or, decodePolyline as ot, MAX_PROJECT_BOOKMARKS as p, StyleLibraryEntryKind as pi, DEFAULT_PROJECT_PREFERENCES as pn, MapRendererKind as pr, horizontalBbox as pt, serializeProjectWithLayerCacheAsync as q, CesiumBasemapImagery as qi, LayerMetadataTemporalExtent as qn, ProjectPreferences as qr, BLANK_BASEMAP as qt, PluginDiff as r, StoryChapter as ri, CommentAnchor as rn, LegendItemOverride as rr, PolylineBatchOptions as rt, diffFeatureCollections as s, StoryInsetPosition as si, DEFAULT_BLEND_MODE as sn, MAX_MAP_GRID_DIM as sr, decodePolylineDetailed as st, FeatureChangeSummary as t, SecondaryMapView as ti, CollaborationRole as tn, LegendCustomItem as tr, reapplyLayerJoins as tt, previewValue as u, StorySlideMode as ui, DEFAULT_LEGEND_CONFIG as un, MapGridLayout as ur, polylineStrToGeoJSON as ut, createProjectLayerSerializationCache as v, isDuckDBQueryLayer as vi, DashboardWidgetAggregation as vn, ModelGraphNode as vr, Ellipsoid as vt, normalizeBlankBackgroundColor as w, PrintLayoutLegendEntry as wi, FieldVisibility as wn, NonGeographicCoordinates as wr, PlanetaryBasemap as wt, hydrateProjectLayer as x, DEFAULT_PRINT_LAYOUT as xi, DiagramSizeMode as xn, ModelPortKind as xr, PLANETARY_BASEMAP_GROUPS as xt, createProjectTemplate as y, shouldUseTiledRendering as yi, DashboardWidgetType as yn, ModelGraphNodeKind as yr, EllipsoidId as yt, normalizeStoryMap as z, FeatureCollection as zi, LayerConnection as zn, ProcessingRunKind as zr, AddTileLayerOptions as zt };
|
|
3922
|
+
//# sourceMappingURL=project-diff-CyR4d8Sl.d.mts.map
|