@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.
@@ -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
- /** Raw SVG markup (or a data URL) used when {@link markerShape} is `"custom"`. */
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 GeoJSON layer should use the tiled rendering path.
1210
+ * Decide whether a vector layer should use the tiled rendering path.
1142
1211
  *
1143
- * @param geojson - The layer's feature collection (may be undefined for
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 collection exceeds
1146
- * {@link LARGE_VECTOR_FEATURE_THRESHOLD} features.
1214
+ * @returns `true` when the feature count exceeds
1215
+ * {@link LARGE_VECTOR_FEATURE_THRESHOLD}.
1147
1216
  */
1148
- declare function shouldUseTiledRendering(geojson: GeoJSON.FeatureCollection | undefined): boolean;
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 scroll-driven story map. */
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
- /** Scroll-driven story map authored on top of a GeoLibre project. */
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: MapLibre only renders Web Mercator
2726
- * and all vector data is kept as WGS84 lon/lat GeoJSON. This module does *not*
2727
- * change that — MapLibre still treats the planet as a unit sphere and there is
2728
- * no true multi-CRS rendering (see maplibre-gl-js#168). What it adds is a
2729
- * per-project notion of *which body* the coordinates describe, so that:
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
- export { BLANK_BASEMAP as $, QuickFilterKind as $n, LayerPopupConfig as $t, PlanetaryBasemap as A, OPENFREEMAP_BASEMAPS as An, isDefaultPrintLayout as Ar, FieldVisibility as At, getEllipsoid as B, ProcessingModelGraph as Bn, Point as Br, LabelDedupe as Bt, ELLIPSOIDS as C, ModelGraphNode as Cn, styleValue as Cr, DashboardWidget as Ct, PLANETARY_BASEMAP_GROUPS as D, ModelToolProvider as Dn, PrintLayoutLegendEntry as Dr, DiagramSizeMode as Dt, PLANETARY_BASEMAPS as E, ModelPortKind as En, PrintLayoutCorner as Er, DiagramField as Et, earthLengthToBody as F, PopupDateFormat as Fn, Feature as Fr, GeometryGeneratorType as Ft, AddTileLayerOptions as G, ProcessingRunStatus as Gn, availableCesiumBasemap as Gr, LayerDescriptiveMetadata as Gt, getPlanetaryBasemapByStyleUrl as H, ProcessingRerunRequest as Hn, CESIUM_BASEMAPS as Hr, LabelTransform as Ht, getActiveBodyRadiusRatio as I, PopupFieldConfig as In, FeatureCollection as Ir, IndicatorAggregation as It, AppRole as J, ProjectPluginControlPosition as Jn, sameCesiumImagery as Jr, LayerJoinStats as Jt, AppCapabilities as K, ProjectComment as Kn, basemapToCesiumImagery as Kr, LayerGroup as Kt, getActiveEllipsoid as L, PopupFieldFormat as Ln, Geometry as Lr, LARGE_VECTOR_FEATURE_THRESHOLD as Lt, PlanetaryBasemapSectionId as M, PROTOMAPS_BASEMAPS as Mn, printLayoutConfigsEqual as Mr, GeoLibreLayer as Mt, bodyLengthToEarth as N, ParticipantIdentity as Nn, scrubPrintLayoutForLayers as Nr, GeoLibreProject as Nt, PLANETARY_BASEMAP_SENTINEL_PREFIX as O, NETCDF_IMAGE_SOURCE_KIND as On, PrintLayoutPageFilter as Or, DiagramType as Ot, earthAreaToBody as P, PointRenderer as Pn, scrubPrintLayoutForRemovedLayers as Pr, GeocodingPreferences as Pt, AttributeFormWidget as Q, QuickFilterDateKind as Qn, LayerMetadataTemporalExtent as Qt, getActiveMeanRadiusMeters as R, PopupFieldKind as Rn, LineString as Rr, LAYER_TYPES as Rt, EARTH_MEAN_RADIUS_METERS as S, ModelGraphEdge as Sn, shouldUseTiledRendering as Sr, DUCKDB_VECTOR_ROUTE_BYTES as St, EllipsoidId as T, ModelGraphPort as Tn, PrintLayoutConfig as Tr, DashboardWidgetType as Tt, meanRadiusMeters as U, ProcessingRun as Un, CesiumBasemapId as Ur, LayerCapabilities as Ut, getPlanetaryBasemapById as V, ProcessingModelStep as Vn, Polygon as Vr, LabelStyle as Vt, setActiveEllipsoidId as W, ProcessingRunKind as Wn, CesiumBasemapImagery as Wr, LayerConnection as Wt, AttributeFormFieldConfig as X, ProjectPreferences as Xn, LayerMetadataContact as Xt, AttributeFormConfig as Y, ProjectPluginState as Yn, LayerLibraryEntry as Yt, AttributeFormValueMapEntry as Z, ProjectTemplateEntry as Zn, LayerMetadataLink as Zt, unescapePolyline as _, MapProjection as _n, VectorRule as _r, DEFAULT_MAP_GRID_LAYOUT as _t, collectTransitiveJoinSourceIds as a, LegendCustomEntry as an, StoryActiveSlideMode as ar, CollaborationParticipant as at, transformGeojsonElevation as b, MapViewState as bn, detectNonGeographicCoordinates as br, DEFAULT_STORY_MAP as bt, stripJoinFields as c, LegendItemOverride as cn, StoryChapterAnimation as cr, CollaborationState as ct, batchDecodePolylines as d, MAX_DASHBOARD_COLUMNS as dn, StoryLayerOpacityChange as dr, CommentReply as dt, LayerQuickFilter as en, QuickFilterTextOperator as er, BLEND_MODES as et, decodePolyline as f, MAX_MAP_GRID_DIM as fn, StoryMap as fr, DEFAULT_BASEMAP as ft, polylineStrToGeoJSON as g, MapPreferences as gn, StyleLibraryEntryKind as gr, DEFAULT_LEGEND_CONFIG as gt, geoJSONToPolylineStr as h, MapGridLayout as hn, StyleLibraryEntry as hr, DEFAULT_LAYER_STYLE as ht, cascadeLayerJoinRefresh as i, LegendConfig as in, SecondaryMapView as ir, CollaborationMode as it, PlanetaryBasemapGroup as j, PROJECT_VERSION as jn, normalizePrintLayoutConfig as jr, FillPattern as jt, PLANET_SWITCHER_OPTIONS as k, NonGeographicCoordinates as kn, createDefaultPrintLayout as kr, EditorTrackingConfig as kt, PolylineBatchOptions as l, LegendPanelPosition as ln, StoryChapterLocation as lr, CommentAnchor as lt, encodePolyline as m, MIN_DASHBOARD_COLUMNS as mn, StrokeWidthUnit as mr, DEFAULT_DASHBOARD_COLUMNS as mt, applyJoinsToLayer as n, LayerType as nn, RuntimeEnvironmentVariable as nr, CollabInvite as nt, layerJoinKey as o, LegendCustomItem as on, StoryChapter as or, CollaborationPresence as ot, decodePolylineDetailed as p, MAX_PROCESSING_HISTORY as pn, StorySlideMode as pr, DEFAULT_BLEND_MODE as pt, AppPrivilege as q, ProjectInteraction as qn, normalizeCesiumBasemap as qr, LayerJoin as qt, applyLayerJoins as r, LayerVirtualField as rn, SQL_QUERY_SOURCE_KIND as rr, CollaborationChatMessage as rt, reapplyLayerJoins as s, LegendCustomShape as sn, StoryChapterAlignment as sr, CollaborationRole as st, ApplyLayerJoinsResult as t, LayerStyle as tn, RecentProjectEntry as tr, BlendMode as tt, PolylineDecodeResult as u, LineDecoration as un, StoryInsetPosition as ur, CommentAuthor as ut, geojsonHasZCoordinates as v, MapRendererKind as vn, VectorStyleMode as vr, DEFAULT_PRIMARY_RENDERER as vt, Ellipsoid as w, ModelGraphNodeKind as wn, DEFAULT_PRINT_LAYOUT as wr, DashboardWidgetAggregation as wt, DEFAULT_ELLIPSOID_ID as x, MarkerShape as xn, isDuckDBQueryLayer as xr, DUCKDB_VECTOR_FEATURE_WARN_COUNT as xt, horizontalBbox as y, MapScaleUnit as yn, VectorStyleStop as yr, DEFAULT_PROJECT_PREFERENCES as yt, getActiveSemiMajorAxisMeters as z, ProcessingModel as zn, MultiPolygon as zr, LabelAnchor as zt };
3218
- //# sourceMappingURL=joins-CRZZcLqX.d.mts.map
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