@geospatial-sdk/core 0.0.5-dev.43 → 0.0.5-dev.45

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,11 +1,44 @@
1
- # `core`
1
+ # `@geospatial-sdk/core`
2
2
 
3
- > TODO: description
3
+ <!-- #region body -->
4
4
 
5
- ## Usage
5
+ This package provides the foundation for the Geospatial SDK.
6
+
7
+ It includes:
8
+
9
+ - **Map Context model**: TypeScript types and interfaces for declaratively defining maps, layers, and views
10
+ - **Diff algorithms**: Utilities to compute differences between Map Context objects (`computeMapContextDiff`)
11
+ - **Validation utilities**: Tools for working with and validating geospatial data
12
+ - **Shared constants**: Common definitions used across all packages
13
+
14
+ The `@geospatial-sdk/core` package is framework-agnostic and does not depend on any specific mapping library. It's required by all other packages in the SDK.
6
15
 
16
+ ## Installation
17
+
18
+ ```sh
19
+ npm install @geospatial-sdk/core
7
20
  ```
8
- const core = require('core');
9
21
 
10
- // TODO: DEMONSTRATE API
22
+ ## Usage
23
+
24
+ ```typescript
25
+ import { computeMapContextDiff, type MapContext } from "@geospatial-sdk/core";
26
+
27
+ const oldContext: MapContext = {
28
+ layers: [{ type: "xyz", url: "https://example.com/{z}/{x}/{y}.png" }],
29
+ view: { center: [0, 0], zoom: 2 },
30
+ };
31
+
32
+ const newContext: MapContext = {
33
+ layers: [{ type: "xyz", url: "https://example.com/{z}/{x}/{y}.png" }],
34
+ view: { center: [5, 45], zoom: 5 },
35
+ };
36
+
37
+ const diff = computeMapContextDiff(newContext, oldContext);
11
38
  ```
39
+
40
+ <!-- #endregion body -->
41
+
42
+ ## Documentation
43
+
44
+ For more detailed API documentation, see the [documentation website](https://camptocamp.github.io/geospatial-sdk/docs/).
package/dist/index.d.ts CHANGED
@@ -1,3 +1,8 @@
1
+ /**
2
+ * {@include ../README.md#body}
3
+ *
4
+ * @module 📦 core
5
+ */
1
6
  export * from "./utils/index.js";
2
7
  export * from "./model/index.js";
3
8
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../lib/index.ts"],"names":[],"mappings":"AACA,cAAc,kBAAkB,CAAC;AACjC,cAAc,kBAAkB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../lib/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,cAAc,kBAAkB,CAAC;AACjC,cAAc,kBAAkB,CAAC"}
package/dist/index.js CHANGED
@@ -1,3 +1,7 @@
1
- // PUBLIC API
1
+ /**
2
+ * {@include ../README.md#body}
3
+ *
4
+ * @module 📦 core
5
+ */
2
6
  export * from "./utils/index.js";
3
7
  export * from "./model/index.js";
@@ -1,3 +1,7 @@
1
+ /**
2
+ * @group Types
3
+ * @packageDocumentation
4
+ */
1
5
  export * from "./map-context.js";
2
6
  export * from "./map-context-diff.js";
3
7
  export * from "./events.js";
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../lib/model/index.ts"],"names":[],"mappings":"AAAA,cAAc,kBAAkB,CAAC;AACjC,cAAc,uBAAuB,CAAC;AACtC,cAAc,aAAa,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../lib/model/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,cAAc,kBAAkB,CAAC;AACjC,cAAc,uBAAuB,CAAC;AACtC,cAAc,aAAa,CAAC"}
@@ -1,3 +1,7 @@
1
+ /**
2
+ * @group Types
3
+ * @packageDocumentation
4
+ */
1
5
  export * from "./map-context.js";
2
6
  export * from "./map-context-diff.js";
3
7
  export * from "./events.js";
@@ -1,6 +1,14 @@
1
1
  import { FeatureCollection, Geometry } from "geojson";
2
2
  import { VectorStyle } from "./style.js";
3
+ /**
4
+ * @private
5
+ * @inline
6
+ */
3
7
  export type LayerDimensions = Record<string, string>;
8
+ /**
9
+ * @private
10
+ * @inline
11
+ */
4
12
  export type LayerExtras = Record<string, unknown>;
5
13
  export interface MapContextBaseLayer {
6
14
  id?: string | number;
@@ -67,17 +75,14 @@ export interface LayerGeojsonWithData extends LayerGeojson {
67
75
  data: FeatureCollection<Geometry | null> | string;
68
76
  url?: never;
69
77
  }
70
- /**
71
- * @interface
72
- */
73
78
  export type MapContextLayerGeojson = LayerGeojsonWithUrl | LayerGeojsonWithData;
74
79
  /**
75
- * @interface
80
+ * A layer that can be used in a map context.
76
81
  */
77
82
  export type MapContextLayer = MapContextLayerWms | MapContextLayerWmts | MapContextLayerWfs | MapContextLayerXyz | MapContextLayerGeojson | MapContextLayerOgcApi | MapContextLayerMapLibreStyle;
78
83
  export type Coordinate = [number, number];
79
84
  /**
80
- * Min X, min Y, max X, max Y
85
+ * Array components are respectively: minX, minY, maxX, maxY
81
86
  */
82
87
  export type Extent = [number, number, number, number];
83
88
  /**
@@ -95,15 +100,28 @@ export interface ViewByExtent {
95
100
  extent: Extent;
96
101
  }
97
102
  /**
98
- * @property geometry Expressed in longitude/latitude
103
+ * @property geometry Expressed in GeoJSON
99
104
  */
100
105
  export interface ViewByGeometry {
101
106
  geometry: Geometry;
102
107
  }
108
+ /**
109
+ * A description of a map viewport in one of three ways:
110
+ * * by center and zoom level,
111
+ * * by extent,
112
+ * * by geometry (in GeoJSON)
113
+ *
114
+ * Also allows specifying constraints for zoom and extent.
115
+ */
103
116
  export type MapContextView = (ViewByZoomAndCenter | ViewByExtent | ViewByGeometry) & {
104
117
  maxZoom?: number;
105
118
  maxExtent?: Extent;
106
119
  };
120
+ /**
121
+ * A map context, containing layers and a view.
122
+ *
123
+ * Note: setting the `view` property to `null` indicates that the map should use a default global view.
124
+ */
107
125
  export interface MapContext {
108
126
  layers: MapContextLayer[];
109
127
  view: MapContextView | null;
@@ -1 +1 @@
1
- {"version":3,"file":"map-context.d.ts","sourceRoot":"","sources":["../../lib/model/map-context.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"map-context.d.ts","sourceRoot":"","sources":["../../lib/model/map-context.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AACtD,OAAO,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAEzC;;;GAGG;AACH,MAAM,MAAM,eAAe,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;AAErD;;;GAGG;AACH,MAAM,MAAM,WAAW,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AAElD,MAAM,WAAW,mBAAmB;IAClC,EAAE,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IACrB,OAAO,CAAC,EAAE,MAAM,CAAC;IAEjB;;;;OAIG;IACH,MAAM,CAAC,EAAE,WAAW,CAAC;IACrB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,WAAW,kBAAmB,SAAQ,mBAAmB;IAC7D,IAAI,EAAE,KAAK,CAAC;IACZ,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,CAAC,EAAE,eAAe,CAAC;IAC7B,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,mBAAoB,SAAQ,mBAAmB;IAC9D,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,CAAC,EAAE,eAAe,CAAC;IAC7B,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,kBAAmB,SAAQ,mBAAmB;IAC7D,IAAI,EAAE,KAAK,CAAC;IACZ,GAAG,EAAE,MAAM,CAAC;IACZ,WAAW,EAAE,MAAM,CAAC;IACpB,KAAK,CAAC,EAAE,WAAW,CAAC;CACrB;AAED,MAAM,WAAW,qBAAsB,SAAQ,mBAAmB;IAChE,IAAI,EAAE,QAAQ,CAAC;IACf,GAAG,EAAE,MAAM,CAAC;IACZ,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,QAAQ,GAAG,KAAK,CAAC;IAC5B,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACjC,KAAK,CAAC,EAAE,WAAW,CAAC;CACrB;AAGD,MAAM,WAAW,4BAA6B,SAAQ,mBAAmB;IACvE,IAAI,EAAE,gBAAgB,CAAC;IACvB,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,kBAAmB,SAAQ,mBAAmB;IAC7D,IAAI,EAAE,KAAK,CAAC;IACZ,GAAG,EAAE,MAAM,CAAC;IACZ,UAAU,CAAC,EAAE,oCAAoC,CAAC;CACnD;AAED,UAAU,YAAa,SAAQ,mBAAmB;IAChD,IAAI,EAAE,SAAS,CAAC;IAChB,KAAK,CAAC,EAAE,WAAW,CAAC;CACrB;AACD,MAAM,WAAW,mBAAoB,SAAQ,YAAY;IACvD,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,CAAC,EAAE,KAAK,CAAC;CACd;AACD,MAAM,WAAW,oBAAqB,SAAQ,YAAY;IACxD,IAAI,EAAE,iBAAiB,CAAC,QAAQ,GAAG,IAAI,CAAC,GAAG,MAAM,CAAC;IAClD,GAAG,CAAC,EAAE,KAAK,CAAC;CACb;AACD,MAAM,MAAM,sBAAsB,GAAG,mBAAmB,GAAG,oBAAoB,CAAC;AAEhF;;GAEG;AACH,MAAM,MAAM,eAAe,GACvB,kBAAkB,GAClB,mBAAmB,GACnB,kBAAkB,GAClB,kBAAkB,GAClB,sBAAsB,GACtB,qBAAqB,GACrB,4BAA4B,CAAC;AAEjC,MAAM,MAAM,UAAU,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;AAE1C;;GAEG;AACH,MAAM,MAAM,MAAM,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;AAEtD;;;GAGG;AACH,MAAM,WAAW,mBAAmB;IAClC,MAAM,EAAE,UAAU,CAAC;IACnB,IAAI,EAAE,MAAM,CAAC;CACd;AAED;;GAEG;AACH,MAAM,WAAW,YAAY;IAC3B,MAAM,EAAE,MAAM,CAAC;CAChB;AAED;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B,QAAQ,EAAE,QAAQ,CAAC;CACpB;AAED;;;;;;;GAOG;AACH,MAAM,MAAM,cAAc,GAAG,CACzB,mBAAmB,GACnB,YAAY,GACZ,cAAc,CACjB,GAAG;IACF,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,CAAC;AAEF;;;;GAIG;AACH,MAAM,WAAW,UAAU;IACzB,MAAM,EAAE,eAAe,EAAE,CAAC;IAC1B,IAAI,EAAE,cAAc,GAAG,IAAI,CAAC;CAC7B"}
@@ -1,3 +1,7 @@
1
+ /**
2
+ * @group Utils
3
+ * @packageDocumentation
4
+ */
1
5
  export * from "./url.js";
2
6
  export * from "./freeze.js";
3
7
  export * from "./hash.js";
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../lib/utils/index.ts"],"names":[],"mappings":"AAAA,cAAc,UAAU,CAAC;AACzB,cAAc,aAAa,CAAC;AAC5B,cAAc,WAAW,CAAC;AAC1B,OAAO,EAAE,qBAAqB,EAAE,MAAM,uBAAuB,CAAC;AAC9D,OAAO,EACL,gBAAgB,EAChB,iBAAiB,EACjB,sBAAsB,EACtB,qBAAqB,EACrB,4BAA4B,GAC7B,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAAE,mBAAmB,EAAE,MAAM,WAAW,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../lib/utils/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,cAAc,UAAU,CAAC;AACzB,cAAc,aAAa,CAAC;AAC5B,cAAc,WAAW,CAAC;AAC1B,OAAO,EAAE,qBAAqB,EAAE,MAAM,uBAAuB,CAAC;AAC9D,OAAO,EACL,gBAAgB,EAChB,iBAAiB,EACjB,sBAAsB,EACtB,qBAAqB,EACrB,4BAA4B,GAC7B,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAAE,mBAAmB,EAAE,MAAM,WAAW,CAAC"}
@@ -1,3 +1,7 @@
1
+ /**
2
+ * @group Utils
3
+ * @packageDocumentation
4
+ */
1
5
  export * from "./url.js";
2
6
  export * from "./freeze.js";
3
7
  export * from "./hash.js";
@@ -1 +1 @@
1
- {"version":3,"file":"map-context.d.ts","sourceRoot":"","sources":["../../lib/utils/map-context.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AAGhE,wBAAgB,YAAY,CAC1B,KAAK,EAAE,eAAe,EACtB,aAAa,UAAQ,GACpB,MAAM,CAER;AAED,wBAAgB,WAAW,CACzB,MAAM,EAAE,eAAe,EACvB,MAAM,EAAE,eAAe,GACtB,OAAO,CAKT;AAED,wBAAgB,uBAAuB,CACrC,MAAM,EAAE,eAAe,EACvB,MAAM,EAAE,eAAe,GACtB,OAAO,CAKT;AAED,wBAAgB,gBAAgB,CAC9B,OAAO,EAAE,UAAU,EACnB,UAAU,EAAE,eAAe,GAC1B,MAAM,CAER;AAED;;;;;;;GAOG;AAEH,wBAAgB,iBAAiB,CAC/B,OAAO,EAAE,UAAU,EACnB,UAAU,EAAE,eAAe,EAC3B,QAAQ,CAAC,EAAE,MAAM,GAChB,UAAU,CAQZ;AAED;;;;;;GAMG;AAEH,wBAAgB,sBAAsB,CACpC,OAAO,EAAE,UAAU,EACnB,UAAU,EAAE,eAAe,GAC1B,UAAU,CAOZ;AAED;;;;;;;GAOG;AAEH,wBAAgB,qBAAqB,CACnC,OAAO,EAAE,UAAU,EACnB,UAAU,EAAE,eAAe,EAC3B,WAAW,EAAE,eAAe,GAC3B,UAAU,CAOZ;AAED;;;;;;;GAOG;AAEH,wBAAgB,4BAA4B,CAC1C,OAAO,EAAE,UAAU,EACnB,UAAU,EAAE,eAAe,EAC3B,QAAQ,EAAE,MAAM,GACf,UAAU,CAGZ"}
1
+ {"version":3,"file":"map-context.d.ts","sourceRoot":"","sources":["../../lib/utils/map-context.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AAGhE,wBAAgB,YAAY,CAC1B,KAAK,EAAE,eAAe,EACtB,aAAa,UAAQ,GACpB,MAAM,CAER;AAED,wBAAgB,WAAW,CACzB,MAAM,EAAE,eAAe,EACvB,MAAM,EAAE,eAAe,GACtB,OAAO,CAKT;AAED,wBAAgB,uBAAuB,CACrC,MAAM,EAAE,eAAe,EACvB,MAAM,EAAE,eAAe,GACtB,OAAO,CAST;AAED,wBAAgB,gBAAgB,CAC9B,OAAO,EAAE,UAAU,EACnB,UAAU,EAAE,eAAe,GAC1B,MAAM,CAER;AAED;;;;;;;GAOG;AAEH,wBAAgB,iBAAiB,CAC/B,OAAO,EAAE,UAAU,EACnB,UAAU,EAAE,eAAe,EAC3B,QAAQ,CAAC,EAAE,MAAM,GAChB,UAAU,CAQZ;AAED;;;;;;GAMG;AAEH,wBAAgB,sBAAsB,CACpC,OAAO,EAAE,UAAU,EACnB,UAAU,EAAE,eAAe,GAC1B,UAAU,CAOZ;AAED;;;;;;;GAOG;AAEH,wBAAgB,qBAAqB,CACnC,OAAO,EAAE,UAAU,EACnB,UAAU,EAAE,eAAe,EAC3B,WAAW,EAAE,eAAe,GAC3B,UAAU,CAOZ;AAED;;;;;;;GAOG;AAEH,wBAAgB,4BAA4B,CAC1C,OAAO,EAAE,UAAU,EACnB,UAAU,EAAE,eAAe,EAC3B,QAAQ,EAAE,MAAM,GACf,UAAU,CAGZ"}
@@ -9,7 +9,9 @@ export function isLayerSame(layerA, layerB) {
9
9
  return getLayerHash(layerA) === getLayerHash(layerB);
10
10
  }
11
11
  export function isLayerSameAndUnchanged(layerA, layerB) {
12
- if ("id" in layerA && "id" in layerB) {
12
+ if ("id" in layerA &&
13
+ "id" in layerB &&
14
+ ("version" in layerA || "version" in layerB)) {
13
15
  return layerA.id == layerB.id && layerA.version == layerB.version;
14
16
  }
15
17
  return getLayerHash(layerA, true) === getLayerHash(layerB, true);
@@ -1,3 +1,25 @@
1
1
  import { MapContextLayer, MapContextView } from "../model/index.js";
2
+ /**
3
+ * Creates a view from a layer by extracting its geographic extent. The returned extent is
4
+ * always expressed in EPSG:4326 (longitude/latitude) coordinates.
5
+ *
6
+ * @param layer - The map context layer to extract the extent from
7
+ * @returns A Promise resolving to a `ViewByExtent` object, or `null` if the extent cannot be determined
8
+ * @throws {Error} If the layer type is not supported
9
+ *
10
+ * @example
11
+ * ```typescript
12
+ * const wmsLayer: MapContextLayerWms = {
13
+ * type: 'wms',
14
+ * url: 'https://example.com/wms',
15
+ * name: 'myLayer'
16
+ * };
17
+ *
18
+ * const view = await createViewFromLayer(wmsLayer);
19
+ * if (view) {
20
+ * console.log('Extent:', view.extent); // [minX, minY, maxX, maxY] in EPSG:4326
21
+ * }
22
+ * ```
23
+ */
2
24
  export declare function createViewFromLayer(layer: MapContextLayer): Promise<MapContextView | null>;
3
25
  //# sourceMappingURL=view.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"view.d.ts","sourceRoot":"","sources":["../../lib/utils/view.ts"],"names":[],"mappings":"AAQA,OAAO,EAEL,eAAe,EAIf,cAAc,EAEf,MAAM,mBAAmB,CAAC;AAK3B,wBAAsB,mBAAmB,CACvC,KAAK,EAAE,eAAe,GACrB,OAAO,CAAC,cAAc,GAAG,IAAI,CAAC,CAYhC"}
1
+ {"version":3,"file":"view.d.ts","sourceRoot":"","sources":["../../lib/utils/view.ts"],"names":[],"mappings":"AAQA,OAAO,EAEL,eAAe,EAIf,cAAc,EAEf,MAAM,mBAAmB,CAAC;AAK3B;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,wBAAsB,mBAAmB,CACvC,KAAK,EAAE,eAAe,GACrB,OAAO,CAAC,cAAc,GAAG,IAAI,CAAC,CAYhC"}
@@ -6,6 +6,28 @@ import GeoJSON from "ol/format/GeoJSON.js";
6
6
  import { extend } from "ol/extent.js";
7
7
  import proj4 from "proj4";
8
8
  const GEOJSON = new GeoJSON();
9
+ /**
10
+ * Creates a view from a layer by extracting its geographic extent. The returned extent is
11
+ * always expressed in EPSG:4326 (longitude/latitude) coordinates.
12
+ *
13
+ * @param layer - The map context layer to extract the extent from
14
+ * @returns A Promise resolving to a `ViewByExtent` object, or `null` if the extent cannot be determined
15
+ * @throws {Error} If the layer type is not supported
16
+ *
17
+ * @example
18
+ * ```typescript
19
+ * const wmsLayer: MapContextLayerWms = {
20
+ * type: 'wms',
21
+ * url: 'https://example.com/wms',
22
+ * name: 'myLayer'
23
+ * };
24
+ *
25
+ * const view = await createViewFromLayer(wmsLayer);
26
+ * if (view) {
27
+ * console.log('Extent:', view.extent); // [minX, minY, maxX, maxY] in EPSG:4326
28
+ * }
29
+ * ```
30
+ */
9
31
  export async function createViewFromLayer(layer) {
10
32
  if (layer.type === "wms") {
11
33
  return await getWmsLayerExtent(layer);
package/lib/index.ts CHANGED
@@ -1,3 +1,8 @@
1
- // PUBLIC API
1
+ /**
2
+ * {@include ../README.md#body}
3
+ *
4
+ * @module 📦 core
5
+ */
6
+
2
7
  export * from "./utils/index.js";
3
8
  export * from "./model/index.js";
@@ -1,3 +1,8 @@
1
+ /**
2
+ * @group Types
3
+ * @packageDocumentation
4
+ */
5
+
1
6
  export * from "./map-context.js";
2
7
  export * from "./map-context-diff.js";
3
8
  export * from "./events.js";
@@ -33,5 +33,5 @@ export interface MapContextDiff {
33
33
  layersReordered: MapContextLayerReordered[];
34
34
  layersRemoved: MapContextLayerPositioned[];
35
35
  layersAdded: MapContextLayerPositioned[];
36
- viewChanges?: MapContextView | null;
36
+ viewChanges?: MapContextView | null; // this is both optional (meaning no view change) and nullable (meaning reset to default view)
37
37
  }
@@ -1,8 +1,16 @@
1
1
  import { FeatureCollection, Geometry } from "geojson";
2
2
  import { VectorStyle } from "./style.js";
3
3
 
4
+ /**
5
+ * @private
6
+ * @inline
7
+ */
4
8
  export type LayerDimensions = Record<string, string>;
5
9
 
10
+ /**
11
+ * @private
12
+ * @inline
13
+ */
6
14
  export type LayerExtras = Record<string, unknown>;
7
15
 
8
16
  export interface MapContextBaseLayer {
@@ -79,14 +87,10 @@ export interface LayerGeojsonWithData extends LayerGeojson {
79
87
  data: FeatureCollection<Geometry | null> | string;
80
88
  url?: never;
81
89
  }
82
-
83
- /**
84
- * @interface
85
- */
86
90
  export type MapContextLayerGeojson = LayerGeojsonWithUrl | LayerGeojsonWithData;
87
91
 
88
92
  /**
89
- * @interface
93
+ * A layer that can be used in a map context.
90
94
  */
91
95
  export type MapContextLayer =
92
96
  | MapContextLayerWms
@@ -100,7 +104,7 @@ export type MapContextLayer =
100
104
  export type Coordinate = [number, number];
101
105
 
102
106
  /**
103
- * Min X, min Y, max X, max Y
107
+ * Array components are respectively: minX, minY, maxX, maxY
104
108
  */
105
109
  export type Extent = [number, number, number, number];
106
110
 
@@ -121,12 +125,20 @@ export interface ViewByExtent {
121
125
  }
122
126
 
123
127
  /**
124
- * @property geometry Expressed in longitude/latitude
128
+ * @property geometry Expressed in GeoJSON
125
129
  */
126
130
  export interface ViewByGeometry {
127
131
  geometry: Geometry;
128
132
  }
129
133
 
134
+ /**
135
+ * A description of a map viewport in one of three ways:
136
+ * * by center and zoom level,
137
+ * * by extent,
138
+ * * by geometry (in GeoJSON)
139
+ *
140
+ * Also allows specifying constraints for zoom and extent.
141
+ */
130
142
  export type MapContextView = (
131
143
  | ViewByZoomAndCenter
132
144
  | ViewByExtent
@@ -136,7 +148,12 @@ export type MapContextView = (
136
148
  maxExtent?: Extent;
137
149
  };
138
150
 
151
+ /**
152
+ * A map context, containing layers and a view.
153
+ *
154
+ * Note: setting the `view` property to `null` indicates that the map should use a default global view.
155
+ */
139
156
  export interface MapContext {
140
157
  layers: MapContextLayer[];
141
- view: MapContextView | null; // a view of "null" means the map will show a default view;
158
+ view: MapContextView | null;
142
159
  }
@@ -1,4 +1,4 @@
1
- import { deepFreeze } from "./freeze";
1
+ import { deepFreeze } from "./freeze.js";
2
2
 
3
3
  describe("freeze util", () => {
4
4
  describe("deepFreeze", () => {
@@ -1,4 +1,4 @@
1
- import { getHash } from "./hash";
1
+ import { getHash } from "./hash.js";
2
2
 
3
3
  describe("getHash", () => {
4
4
  it("generates a hash representing the deep value of an object", () => {
@@ -1,3 +1,8 @@
1
+ /**
2
+ * @group Utils
3
+ * @packageDocumentation
4
+ */
5
+
1
6
  export * from "./url.js";
2
7
  export * from "./freeze.js";
3
8
  export * from "./hash.js";
@@ -1,5 +1,5 @@
1
- import { MapContext, MapContextDiff, MapContextLayer } from "../model";
2
- import { computeMapContextDiff } from "./map-context-diff";
1
+ import { MapContext, MapContextDiff, MapContextLayer } from "../model/index.js";
2
+ import { computeMapContextDiff } from "./map-context-diff.js";
3
3
  import {
4
4
  SAMPLE_CONTEXT,
5
5
  SAMPLE_LAYER1,
@@ -7,8 +7,8 @@ import {
7
7
  SAMPLE_LAYER3,
8
8
  SAMPLE_LAYER4,
9
9
  SAMPLE_LAYER5,
10
- } from "../../fixtures/map-context.fixtures";
11
- import { describe, it, expect, beforeEach } from "vitest";
10
+ } from "../../fixtures/map-context.fixtures.js";
11
+ import { beforeEach, describe, expect, it } from "vitest";
12
12
 
13
13
  describe("Context diff utils", () => {
14
14
  describe("computeMapContextDiff", () => {
@@ -8,14 +8,14 @@ import {
8
8
  isLayerSameAndUnchanged,
9
9
  removeLayerFromContext,
10
10
  replaceLayerInContext,
11
- } from "./map-context";
12
- import { MapContext } from "../model";
11
+ } from "./map-context.js";
12
+ import { MapContext } from "../model/index.js";
13
13
  import {
14
14
  SAMPLE_CONTEXT,
15
15
  SAMPLE_LAYER1,
16
16
  SAMPLE_LAYER2,
17
17
  SAMPLE_LAYER3,
18
- } from "../../fixtures/map-context.fixtures";
18
+ } from "../../fixtures/map-context.fixtures.js";
19
19
 
20
20
  describe("Map context utils", () => {
21
21
  describe("isLayerSame", () => {
@@ -78,6 +78,7 @@ describe("Map context utils", () => {
78
78
  extras: undefined,
79
79
  }),
80
80
  ).toBe(true);
81
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
81
82
  const { extras, ...layer } = SAMPLE_LAYER1;
82
83
  expect(isLayerSame(SAMPLE_LAYER1, layer)).toBe(true);
83
84
  });
@@ -98,8 +99,30 @@ describe("Map context utils", () => {
98
99
  });
99
100
 
100
101
  describe("isLayerSameAndUnchanged", () => {
101
- describe("layers with id", () => {
102
+ describe("layers with id and version", () => {
102
103
  it("compares non-strictly by id and version field", () => {
104
+ expect(
105
+ isLayerSameAndUnchanged(
106
+ { ...SAMPLE_LAYER1, id: "ab", version: 2 },
107
+ { ...SAMPLE_LAYER2, id: "ab", version: 2 },
108
+ ),
109
+ ).toBe(true);
110
+ expect(
111
+ isLayerSameAndUnchanged(
112
+ { ...SAMPLE_LAYER1, id: "ab", version: 2 },
113
+ { ...SAMPLE_LAYER1, id: "ab", version: 1 },
114
+ ),
115
+ ).toBe(false);
116
+ expect(
117
+ isLayerSameAndUnchanged(
118
+ { ...SAMPLE_LAYER1, id: 1 },
119
+ { ...SAMPLE_LAYER1, id: "01", version: 3 },
120
+ ),
121
+ ).toBe(false);
122
+ });
123
+ });
124
+ describe("layers with id and both without version", () => {
125
+ it("compares by properties, including extras", () => {
103
126
  expect(
104
127
  isLayerSameAndUnchanged(
105
128
  { ...SAMPLE_LAYER1, id: "a" },
@@ -111,23 +134,23 @@ describe("Map context utils", () => {
111
134
  { ...SAMPLE_LAYER1, id: "a" },
112
135
  { ...SAMPLE_LAYER2, id: "a" },
113
136
  ),
114
- ).toBe(true);
137
+ ).toBe(false);
115
138
  expect(
116
139
  isLayerSameAndUnchanged(
117
- { ...SAMPLE_LAYER1, id: "ab", version: 2 },
118
- { ...SAMPLE_LAYER2, id: "ab", version: 2 },
140
+ { ...SAMPLE_LAYER1, id: "a" },
141
+ { ...SAMPLE_LAYER1, id: "a" },
119
142
  ),
120
143
  ).toBe(true);
121
144
  expect(
122
145
  isLayerSameAndUnchanged(
123
- { ...SAMPLE_LAYER1, id: "ab", version: 2 },
124
- { ...SAMPLE_LAYER1, id: "ab", version: 1 },
146
+ { ...SAMPLE_LAYER2, id: "b", extras: { hello: "world" } },
147
+ { ...SAMPLE_LAYER2, id: "b", extras: { hello: "world" } },
125
148
  ),
126
- ).toBe(false);
149
+ ).toBe(true);
127
150
  expect(
128
151
  isLayerSameAndUnchanged(
129
- { ...SAMPLE_LAYER1, id: 1 },
130
- { ...SAMPLE_LAYER1, id: "01", version: 3 },
152
+ { ...SAMPLE_LAYER2, id: "b", extras: { hello: "world" } },
153
+ { ...SAMPLE_LAYER2, id: "b", extras: { foo: "bar" } },
131
154
  ),
132
155
  ).toBe(false);
133
156
  });
@@ -179,6 +202,7 @@ describe("Map context utils", () => {
179
202
  extras: undefined,
180
203
  }),
181
204
  ).toBe(false);
205
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
182
206
  const { extras, ...layer } = SAMPLE_LAYER1;
183
207
  expect(isLayerSameAndUnchanged(SAMPLE_LAYER1, layer)).toBe(false);
184
208
  });
@@ -22,7 +22,11 @@ export function isLayerSameAndUnchanged(
22
22
  layerA: MapContextLayer,
23
23
  layerB: MapContextLayer,
24
24
  ): boolean {
25
- if ("id" in layerA && "id" in layerB) {
25
+ if (
26
+ "id" in layerA &&
27
+ "id" in layerB &&
28
+ ("version" in layerA || "version" in layerB)
29
+ ) {
26
30
  return layerA.id == layerB.id && layerA.version == layerB.version;
27
31
  }
28
32
  return getLayerHash(layerA, true) === getLayerHash(layerB, true);
@@ -1,4 +1,4 @@
1
- import { removeSearchParams } from "./url";
1
+ import { removeSearchParams } from "./url.js";
2
2
 
3
3
  describe("URL utils", () => {
4
4
  describe("removeSearchParams", () => {
@@ -1,10 +1,10 @@
1
- import { createViewFromLayer } from "./view";
1
+ import { createViewFromLayer } from "./view.js";
2
2
  import {
3
3
  MapContextLayerGeojson,
4
4
  MapContextLayerWfs,
5
5
  MapContextLayerWms,
6
6
  MapContextLayerWmts,
7
- } from "../model";
7
+ } from "../model/index.js";
8
8
 
9
9
  vitest.mock("@camptocamp/ogc-client", () => ({
10
10
  WmsEndpoint: class {
@@ -46,7 +46,7 @@ vitest.mock("@camptocamp/ogc-client", () => ({
46
46
  isReady() {
47
47
  return Promise.resolve({
48
48
  getSingleLayerName: () => "layerName",
49
- getLayerByName: (name: string) => ({
49
+ getLayerByName: () => ({
50
50
  latLonBoundingBox: [1, 2.6, 3.3, 4.2],
51
51
  }),
52
52
  });
package/lib/utils/view.ts CHANGED
@@ -19,6 +19,28 @@ import { FeatureCollection, Geometry } from "geojson";
19
19
 
20
20
  const GEOJSON = new GeoJSON();
21
21
 
22
+ /**
23
+ * Creates a view from a layer by extracting its geographic extent. The returned extent is
24
+ * always expressed in EPSG:4326 (longitude/latitude) coordinates.
25
+ *
26
+ * @param layer - The map context layer to extract the extent from
27
+ * @returns A Promise resolving to a `ViewByExtent` object, or `null` if the extent cannot be determined
28
+ * @throws {Error} If the layer type is not supported
29
+ *
30
+ * @example
31
+ * ```typescript
32
+ * const wmsLayer: MapContextLayerWms = {
33
+ * type: 'wms',
34
+ * url: 'https://example.com/wms',
35
+ * name: 'myLayer'
36
+ * };
37
+ *
38
+ * const view = await createViewFromLayer(wmsLayer);
39
+ * if (view) {
40
+ * console.log('Extent:', view.extent); // [minX, minY, maxX, maxY] in EPSG:4326
41
+ * }
42
+ * ```
43
+ */
22
44
  export async function createViewFromLayer(
23
45
  layer: MapContextLayer,
24
46
  ): Promise<MapContextView | null> {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@geospatial-sdk/core",
3
- "version": "0.0.5-dev.43+a7f100d",
3
+ "version": "0.0.5-dev.45+a90fe28",
4
4
  "description": "Core functions and models for the SDK",
5
5
  "author": "Olivia <olivia.guyot@camptocamp.com>",
6
6
  "homepage": "",
@@ -22,7 +22,7 @@
22
22
  "test": "vitest",
23
23
  "build": "tsc"
24
24
  },
25
- "gitHead": "a7f100dfebe66dff0f44abb4c630917db89453fd",
25
+ "gitHead": "a90fe28ac749e1d35a976bdcfd02cb47357e8955",
26
26
  "dependencies": {
27
27
  "proj4": "^2.9.2"
28
28
  },