@geospatial-sdk/core 0.0.5-dev.55 → 0.0.5-dev.56

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.
@@ -2,6 +2,7 @@ import { EndpointError } from "@camptocamp/ogc-client";
2
2
  import { Feature } from "geojson";
3
3
  import BaseEvent from "ol/events/Event.js";
4
4
  import type { Extent } from "ol/extent.js";
5
+ import { ResolvedMapLayerState, ResolvedMapState, ResolvedMapViewState } from "./resolved-map-state.js";
5
6
  export type FeaturesByLayerIndex = Map<number, Feature[]>;
6
7
  export declare const FeaturesClickEventType = "features-click";
7
8
  export interface FeaturesClickEvent {
@@ -20,11 +21,46 @@ export interface MapClickEvent {
20
21
  type: typeof MapClickEventType;
21
22
  coordinate: [number, number];
22
23
  }
24
+ export declare const MapViewStateChangeEventType = "map-view-state-change";
25
+ export interface MapViewStateChangeEvent {
26
+ type: typeof MapViewStateChangeEventType;
27
+ viewState: ResolvedMapViewState;
28
+ }
29
+ export declare const MapLayerStateChangeEventType = "map-layer-state-change";
30
+ export interface MapLayerStateChangeEvent {
31
+ type: typeof MapLayerStateChangeEventType;
32
+ layerState: ResolvedMapLayerState;
33
+ layerIndex: number;
34
+ }
35
+ export declare const MapStateChangeEventType = "map-state-change";
36
+ export interface MapStateChangeEvent {
37
+ type: typeof MapStateChangeEventType;
38
+ mapState: ResolvedMapState;
39
+ }
40
+ export declare const LayerCreationErrorEventType = "layer-creation-error";
41
+ export interface LayerCreationErrorEvent {
42
+ type: typeof LayerCreationErrorEventType;
43
+ error: Error;
44
+ }
45
+ export declare const LayerLoadingErrorEventType = "layer-loading-error";
46
+ export interface LayerLoadingErrorEvent {
47
+ type: typeof LayerLoadingErrorEventType;
48
+ error: Error;
49
+ httpStatus?: number;
50
+ }
51
+ /**
52
+ * DEPRECATED
53
+ * Use the MapViewStateChangeEvent instead
54
+ */
23
55
  export declare const MapExtentChangeEventType = "map-extent-change";
24
56
  export interface MapExtentChangeEvent {
25
57
  type: typeof MapExtentChangeEventType;
26
58
  extent: Extent;
27
59
  }
60
+ /**
61
+ * DEPRECATED
62
+ * Use the MapLayerStateChangeEvent and LayerLoadingErrorEvent instead
63
+ */
28
64
  export declare const SourceLoadErrorType = "source-load-error";
29
65
  export declare class SourceLoadErrorEvent extends BaseEvent {
30
66
  message: string;
@@ -35,6 +71,14 @@ export interface MapEventsByType {
35
71
  [FeaturesClickEventType]: FeaturesClickEvent;
36
72
  [FeaturesHoverEventType]: FeaturesHoverEvent;
37
73
  [MapClickEventType]: MapClickEvent;
74
+ [MapViewStateChangeEventType]: MapViewStateChangeEvent;
75
+ [MapLayerStateChangeEventType]: MapLayerStateChangeEvent;
76
+ [MapStateChangeEventType]: MapStateChangeEvent;
77
+ [LayerCreationErrorEventType]: LayerCreationErrorEvent;
78
+ [LayerLoadingErrorEventType]: LayerLoadingErrorEvent;
79
+ /**
80
+ * DEPRECATED
81
+ */
38
82
  [MapExtentChangeEventType]: MapExtentChangeEvent;
39
83
  [SourceLoadErrorType]: SourceLoadErrorEvent;
40
84
  }
@@ -1 +1 @@
1
- {"version":3,"file":"events.d.ts","sourceRoot":"","sources":["../../lib/model/events.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AACvD,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAClC,OAAO,SAAS,MAAM,oBAAoB,CAAC;AAC3C,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AAE3C,MAAM,MAAM,oBAAoB,GAAG,GAAG,CAAC,MAAM,EAAE,OAAO,EAAE,CAAC,CAAC;AAE1D,eAAO,MAAM,sBAAsB,mBAAmB,CAAC;AACvD,MAAM,WAAW,kBAAkB;IACjC,IAAI,EAAE,OAAO,sBAAsB,CAAC;IACpC,QAAQ,EAAE,OAAO,EAAE,CAAC;IACpB,eAAe,EAAE,oBAAoB,CAAC;CACvC;AAED,eAAO,MAAM,sBAAsB,mBAAmB,CAAC;AACvD,MAAM,WAAW,kBAAkB;IACjC,IAAI,EAAE,OAAO,sBAAsB,CAAC;IACpC,QAAQ,EAAE,OAAO,EAAE,CAAC;IACpB,eAAe,EAAE,oBAAoB,CAAC;CACvC;AAED,eAAO,MAAM,iBAAiB,cAAc,CAAC;AAC7C,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,OAAO,iBAAiB,CAAC;IAC/B,UAAU,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAC9B;AAED,eAAO,MAAM,wBAAwB,sBAAsB,CAAC;AAC5D,MAAM,WAAW,oBAAoB;IACnC,IAAI,EAAE,OAAO,wBAAwB,CAAC;IACtC,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,eAAO,MAAM,mBAAmB,sBAAsB,CAAC;AACvD,qBAAa,oBAAqB,SAAQ,SAAS;IACjD,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,CAAC,EAAE,MAAM,CAAC;gBACR,KAAK,EAAE,aAAa,GAAG,KAAK,GAAG,QAAQ;CAiBpD;AAED,MAAM,WAAW,eAAe;IAC9B,CAAC,sBAAsB,CAAC,EAAE,kBAAkB,CAAC;IAC7C,CAAC,sBAAsB,CAAC,EAAE,kBAAkB,CAAC;IAC7C,CAAC,iBAAiB,CAAC,EAAE,aAAa,CAAC;IACnC,CAAC,wBAAwB,CAAC,EAAE,oBAAoB,CAAC;IACjD,CAAC,mBAAmB,CAAC,EAAE,oBAAoB,CAAC;CAC7C"}
1
+ {"version":3,"file":"events.d.ts","sourceRoot":"","sources":["../../lib/model/events.ts"],"names":[],"mappings":"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"}
@@ -1,8 +1,22 @@
1
+ import { EndpointError } from "@camptocamp/ogc-client";
1
2
  import BaseEvent from "ol/events/Event.js";
2
3
  export const FeaturesClickEventType = "features-click";
3
4
  export const FeaturesHoverEventType = "features-hover";
4
5
  export const MapClickEventType = "map-click";
6
+ export const MapViewStateChangeEventType = "map-view-state-change";
7
+ export const MapLayerStateChangeEventType = "map-layer-state-change";
8
+ export const MapStateChangeEventType = "map-state-change";
9
+ export const LayerCreationErrorEventType = "layer-creation-error";
10
+ export const LayerLoadingErrorEventType = "layer-loading-error";
11
+ /**
12
+ * DEPRECATED
13
+ * Use the MapViewStateChangeEvent instead
14
+ */
5
15
  export const MapExtentChangeEventType = "map-extent-change";
16
+ /**
17
+ * DEPRECATED
18
+ * Use the MapLayerStateChangeEvent and LayerLoadingErrorEvent instead
19
+ */
6
20
  export const SourceLoadErrorType = "source-load-error";
7
21
  export class SourceLoadErrorEvent extends BaseEvent {
8
22
  constructor(error) {
@@ -11,9 +25,7 @@ export class SourceLoadErrorEvent extends BaseEvent {
11
25
  this.message = error.statusText;
12
26
  this.httpStatus = error.status;
13
27
  }
14
- else if (error instanceof Error &&
15
- "isCrossOriginRelated" in error &&
16
- "httpStatus" in error) {
28
+ else if (error instanceof EndpointError) {
17
29
  const e = error;
18
30
  this.message = e.message;
19
31
  this.httpStatus = e.httpStatus;
@@ -5,4 +5,6 @@
5
5
  export * from "./map-context.js";
6
6
  export * from "./map-context-diff.js";
7
7
  export * from "./events.js";
8
+ export * from "./resolved-map-state.js";
9
+ export * from "./style.js";
8
10
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
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
+ {"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;AAC5B,cAAc,yBAAyB,CAAC;AACxC,cAAc,YAAY,CAAC"}
@@ -5,3 +5,5 @@
5
5
  export * from "./map-context.js";
6
6
  export * from "./map-context-diff.js";
7
7
  export * from "./events.js";
8
+ export * from "./resolved-map-state.js";
9
+ export * from "./style.js";
@@ -1,17 +1,28 @@
1
1
  import { FeatureCollection, Geometry } from "geojson";
2
2
  import { VectorStyle } from "./style.js";
3
+ export type LayerDimensionValueSingle = string | number | Date;
4
+ export type LayerDimensionValueRange = {
5
+ start: LayerDimensionValueSingle | null;
6
+ end: LayerDimensionValueSingle | null;
7
+ };
3
8
  /**
4
9
  * @private
5
10
  * @inline
6
11
  */
7
- export type LayerDimensions = Record<string, string>;
12
+ export type LayerDimensionValues = Record<string, LayerDimensionValueSingle | LayerDimensionValueRange>;
8
13
  /**
9
14
  * @private
10
15
  * @inline
11
16
  */
12
17
  export type LayerExtras = Record<string, unknown>;
13
18
  export interface MapContextBaseLayer {
19
+ /**
20
+ * An optional identifier for the layer; if provided, will improve performance when the layers is updated through a context diff.
21
+ */
14
22
  id?: string | number;
23
+ /**
24
+ * Optional version indicator; if provided, must be increased by the application for the change detection to trigger, otherwise the SDK will consider that the layer is unchanged.
25
+ */
15
26
  version?: number;
16
27
  /**
17
28
  * This property can be used to store anything application-specific on layers; as its content may occasionally
@@ -19,25 +30,51 @@ export interface MapContextBaseLayer {
19
30
  * non-serializable entities
20
31
  */
21
32
  extras?: LayerExtras;
33
+ /**
34
+ * Whether the layer is visible or not on the map. A non-visible layer will still have its data queried and kept in memory, so switching this on/off shows immediately on the map.
35
+ *
36
+ * Default value is `true` (visible).
37
+ */
22
38
  visibility?: boolean;
39
+ /**
40
+ * Opacity level; between 0 and 1.
41
+ *
42
+ * Default value is 1 (fully opaque).
43
+ */
23
44
  opacity?: number;
45
+ /**
46
+ * Optional label for the layer, typically used to represent the layer in a layer list or when showing a popup above a feature.
47
+ */
24
48
  label?: string;
49
+ /**
50
+ * Attributions for the layer. Optional but strongly recommended: remember to attribute your map!
51
+ */
25
52
  attributions?: string;
53
+ /**
54
+ * Whether data on the layer can be picked up using the `feature-click` event.
55
+ *
56
+ * Default value is `true`. Set to `false` to save performance.
57
+ */
26
58
  clickable?: boolean;
59
+ /**
60
+ * Whether features on the layer can be picked up using the `feature-hover` event. Mostly has an effect only for vector layers.
61
+ *
62
+ * Default value is `false`.
63
+ */
27
64
  hoverable?: boolean;
28
65
  }
29
66
  export interface MapContextLayerWms extends MapContextBaseLayer {
30
67
  type: "wms";
31
68
  url: string;
32
69
  name: string;
33
- dimensions?: LayerDimensions;
70
+ dimensionValues?: LayerDimensionValues;
34
71
  style?: string;
35
72
  }
36
73
  export interface MapContextLayerWmts extends MapContextBaseLayer {
37
74
  type: "wmts";
38
75
  url: string;
39
76
  name: string;
40
- dimensions?: LayerDimensions;
77
+ dimensionValues?: LayerDimensionValues;
41
78
  style?: string;
42
79
  }
43
80
  export interface MapContextLayerVector {
@@ -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":"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"}
@@ -0,0 +1,46 @@
1
+ import { Coordinate, Extent } from "./map-context.js";
2
+ export type MapLayerCreationStatus = {
3
+ created: true;
4
+ } | {
5
+ creationError: true;
6
+ creationErrorMessage: string;
7
+ };
8
+ export type MapLayerLoadingStatus = {
9
+ loaded: true;
10
+ } | {
11
+ loadingError: true;
12
+ loadingErrorMessage: string;
13
+ loadingErrorHttpStatus?: number;
14
+ } | {
15
+ loading: true;
16
+ };
17
+ export interface MapLayerDataInfo {
18
+ featuresCount?: number;
19
+ geometryTypes?: Array<"Point" | "LineString" | "Polygon">;
20
+ }
21
+ export type ResolvedMapLayerState = MapLayerCreationStatus & MapLayerLoadingStatus & MapLayerDataInfo;
22
+ /**
23
+ * Describes the actual view state of a map
24
+ */
25
+ export interface ResolvedMapViewState {
26
+ /** View center in longitude/latitude */
27
+ center: Coordinate;
28
+ /** Actual view extent in longitude/latitude */
29
+ extent: Extent;
30
+ /** Map units per pixel */
31
+ resolution: number;
32
+ /** Scale denominator (takes into account an estimated DPI) */
33
+ scaleDenominator: number;
34
+ /** Bearing in degrees; 90 is North (up) */
35
+ bearing: number;
36
+ }
37
+ /**
38
+ * Describes the actual state of a map after a context or context diff was applied to it.
39
+ * A `view` of null means the view state hasn't been changed yet.
40
+ * A `layer` item of null means the layer state hasn't been changed yet.
41
+ */
42
+ export interface ResolvedMapState {
43
+ layers: Array<ResolvedMapLayerState | null>;
44
+ view: ResolvedMapViewState | null;
45
+ }
46
+ //# sourceMappingURL=resolved-map-state.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resolved-map-state.d.ts","sourceRoot":"","sources":["../../lib/model/resolved-map-state.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAEtD,MAAM,MAAM,sBAAsB,GAC9B;IACE,OAAO,EAAE,IAAI,CAAC;CACf,GACD;IACE,aAAa,EAAE,IAAI,CAAC;IACpB,oBAAoB,EAAE,MAAM,CAAC;CAC9B,CAAC;AAEN,MAAM,MAAM,qBAAqB,GAC7B;IACE,MAAM,EAAE,IAAI,CAAC;CACd,GACD;IACE,YAAY,EAAE,IAAI,CAAC;IACnB,mBAAmB,EAAE,MAAM,CAAC;IAC5B,sBAAsB,CAAC,EAAE,MAAM,CAAC;CACjC,GACD;IACE,OAAO,EAAE,IAAI,CAAC;CACf,CAAC;AAEN,MAAM,WAAW,gBAAgB;IAC/B,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,aAAa,CAAC,EAAE,KAAK,CAAC,OAAO,GAAG,YAAY,GAAG,SAAS,CAAC,CAAC;CAC3D;AAED,MAAM,MAAM,qBAAqB,GAAG,sBAAsB,GACxD,qBAAqB,GACrB,gBAAgB,CAAC;AAEnB;;GAEG;AACH,MAAM,WAAW,oBAAoB;IACnC,wCAAwC;IACxC,MAAM,EAAE,UAAU,CAAC;IAEnB,+CAA+C;IAC/C,MAAM,EAAE,MAAM,CAAC;IAEf,0BAA0B;IAC1B,UAAU,EAAE,MAAM,CAAC;IAEnB,8DAA8D;IAC9D,gBAAgB,EAAE,MAAM,CAAC;IAEzB,2CAA2C;IAC3C,OAAO,EAAE,MAAM,CAAC;CACjB;AAED;;;;GAIG;AACH,MAAM,WAAW,gBAAgB;IAC/B,MAAM,EAAE,KAAK,CAAC,qBAAqB,GAAG,IAAI,CAAC,CAAC;IAC5C,IAAI,EAAE,oBAAoB,GAAG,IAAI,CAAC;CACnC"}
@@ -0,0 +1 @@
1
+ export {};
@@ -1,5 +1,5 @@
1
1
  function isGeoJsonGeometry(object) {
2
- return "type" in object && "coordinates" in object;
2
+ return "type" in object && ("coordinates" in object || "features" in object);
3
3
  }
4
4
  export function getHash(input, ignoreKeys = []) {
5
5
  if (input instanceof Object && isGeoJsonGeometry(input)) {
@@ -2,6 +2,11 @@ import { EndpointError } from "@camptocamp/ogc-client";
2
2
  import { Feature } from "geojson";
3
3
  import BaseEvent from "ol/events/Event.js";
4
4
  import type { Extent } from "ol/extent.js";
5
+ import {
6
+ ResolvedMapLayerState,
7
+ ResolvedMapState,
8
+ ResolvedMapViewState,
9
+ } from "./resolved-map-state.js";
5
10
 
6
11
  export type FeaturesByLayerIndex = Map<number, Feature[]>;
7
12
 
@@ -25,12 +30,52 @@ export interface MapClickEvent {
25
30
  coordinate: [number, number]; // expressed in lon/lat
26
31
  }
27
32
 
33
+ export const MapViewStateChangeEventType = "map-view-state-change";
34
+ export interface MapViewStateChangeEvent {
35
+ type: typeof MapViewStateChangeEventType;
36
+ viewState: ResolvedMapViewState;
37
+ }
38
+
39
+ export const MapLayerStateChangeEventType = "map-layer-state-change";
40
+ export interface MapLayerStateChangeEvent {
41
+ type: typeof MapLayerStateChangeEventType;
42
+ layerState: ResolvedMapLayerState;
43
+ layerIndex: number;
44
+ }
45
+
46
+ export const MapStateChangeEventType = "map-state-change";
47
+ export interface MapStateChangeEvent {
48
+ type: typeof MapStateChangeEventType;
49
+ mapState: ResolvedMapState;
50
+ }
51
+
52
+ export const LayerCreationErrorEventType = "layer-creation-error";
53
+ export interface LayerCreationErrorEvent {
54
+ type: typeof LayerCreationErrorEventType;
55
+ error: Error;
56
+ }
57
+
58
+ export const LayerLoadingErrorEventType = "layer-loading-error";
59
+ export interface LayerLoadingErrorEvent {
60
+ type: typeof LayerLoadingErrorEventType;
61
+ error: Error;
62
+ httpStatus?: number;
63
+ }
64
+
65
+ /**
66
+ * DEPRECATED
67
+ * Use the MapViewStateChangeEvent instead
68
+ */
28
69
  export const MapExtentChangeEventType = "map-extent-change";
29
70
  export interface MapExtentChangeEvent {
30
71
  type: typeof MapExtentChangeEventType;
31
72
  extent: Extent;
32
73
  }
33
74
 
75
+ /**
76
+ * DEPRECATED
77
+ * Use the MapLayerStateChangeEvent and LayerLoadingErrorEvent instead
78
+ */
34
79
  export const SourceLoadErrorType = "source-load-error";
35
80
  export class SourceLoadErrorEvent extends BaseEvent {
36
81
  message: string;
@@ -40,11 +85,7 @@ export class SourceLoadErrorEvent extends BaseEvent {
40
85
  if (error instanceof Response) {
41
86
  this.message = error.statusText;
42
87
  this.httpStatus = error.status;
43
- } else if (
44
- error instanceof Error &&
45
- "isCrossOriginRelated" in error &&
46
- "httpStatus" in error
47
- ) {
88
+ } else if (error instanceof EndpointError) {
48
89
  const e = error as EndpointError;
49
90
  this.message = e.message;
50
91
  this.httpStatus = e.httpStatus;
@@ -58,6 +99,14 @@ export interface MapEventsByType {
58
99
  [FeaturesClickEventType]: FeaturesClickEvent;
59
100
  [FeaturesHoverEventType]: FeaturesHoverEvent;
60
101
  [MapClickEventType]: MapClickEvent;
102
+ [MapViewStateChangeEventType]: MapViewStateChangeEvent;
103
+ [MapLayerStateChangeEventType]: MapLayerStateChangeEvent;
104
+ [MapStateChangeEventType]: MapStateChangeEvent;
105
+ [LayerCreationErrorEventType]: LayerCreationErrorEvent;
106
+ [LayerLoadingErrorEventType]: LayerLoadingErrorEvent;
107
+ /**
108
+ * DEPRECATED
109
+ */
61
110
  [MapExtentChangeEventType]: MapExtentChangeEvent;
62
111
  [SourceLoadErrorType]: SourceLoadErrorEvent;
63
112
  }
@@ -6,3 +6,5 @@
6
6
  export * from "./map-context.js";
7
7
  export * from "./map-context-diff.js";
8
8
  export * from "./events.js";
9
+ export * from "./resolved-map-state.js";
10
+ export * from "./style.js";
@@ -1,11 +1,20 @@
1
1
  import { FeatureCollection, Geometry } from "geojson";
2
2
  import { VectorStyle } from "./style.js";
3
3
 
4
+ export type LayerDimensionValueSingle = string | number | Date;
5
+ export type LayerDimensionValueRange = {
6
+ start: LayerDimensionValueSingle | null;
7
+ end: LayerDimensionValueSingle | null;
8
+ };
9
+
4
10
  /**
5
11
  * @private
6
12
  * @inline
7
13
  */
8
- export type LayerDimensions = Record<string, string>;
14
+ export type LayerDimensionValues = Record<
15
+ string,
16
+ LayerDimensionValueSingle | LayerDimensionValueRange
17
+ >;
9
18
 
10
19
  /**
11
20
  * @private
@@ -14,7 +23,13 @@ export type LayerDimensions = Record<string, string>;
14
23
  export type LayerExtras = Record<string, unknown>;
15
24
 
16
25
  export interface MapContextBaseLayer {
26
+ /**
27
+ * An optional identifier for the layer; if provided, will improve performance when the layers is updated through a context diff.
28
+ */
17
29
  id?: string | number;
30
+ /**
31
+ * Optional version indicator; if provided, must be increased by the application for the change detection to trigger, otherwise the SDK will consider that the layer is unchanged.
32
+ */
18
33
  version?: number;
19
34
 
20
35
  /**
@@ -23,11 +38,43 @@ export interface MapContextBaseLayer {
23
38
  * non-serializable entities
24
39
  */
25
40
  extras?: LayerExtras;
41
+
42
+ /**
43
+ * Whether the layer is visible or not on the map. A non-visible layer will still have its data queried and kept in memory, so switching this on/off shows immediately on the map.
44
+ *
45
+ * Default value is `true` (visible).
46
+ */
26
47
  visibility?: boolean;
48
+
49
+ /**
50
+ * Opacity level; between 0 and 1.
51
+ *
52
+ * Default value is 1 (fully opaque).
53
+ */
27
54
  opacity?: number;
55
+
56
+ /**
57
+ * Optional label for the layer, typically used to represent the layer in a layer list or when showing a popup above a feature.
58
+ */
28
59
  label?: string;
60
+
61
+ /**
62
+ * Attributions for the layer. Optional but strongly recommended: remember to attribute your map!
63
+ */
29
64
  attributions?: string;
65
+
66
+ /**
67
+ * Whether data on the layer can be picked up using the `feature-click` event.
68
+ *
69
+ * Default value is `true`. Set to `false` to save performance.
70
+ */
30
71
  clickable?: boolean;
72
+
73
+ /**
74
+ * Whether features on the layer can be picked up using the `feature-hover` event. Mostly has an effect only for vector layers.
75
+ *
76
+ * Default value is `false`.
77
+ */
31
78
  hoverable?: boolean;
32
79
  }
33
80
 
@@ -35,7 +82,8 @@ export interface MapContextLayerWms extends MapContextBaseLayer {
35
82
  type: "wms";
36
83
  url: string;
37
84
  name: string;
38
- dimensions?: LayerDimensions;
85
+ // TODO: add support for these
86
+ dimensionValues?: LayerDimensionValues;
39
87
  style?: string;
40
88
  }
41
89
 
@@ -43,7 +91,8 @@ export interface MapContextLayerWmts extends MapContextBaseLayer {
43
91
  type: "wmts";
44
92
  url: string;
45
93
  name: string;
46
- dimensions?: LayerDimensions;
94
+ // TODO: add support for these
95
+ dimensionValues?: LayerDimensionValues;
47
96
  style?: string;
48
97
  }
49
98
 
@@ -0,0 +1,62 @@
1
+ import { Coordinate, Extent } from "./map-context.js";
2
+
3
+ export type MapLayerCreationStatus =
4
+ | {
5
+ created: true;
6
+ }
7
+ | {
8
+ creationError: true;
9
+ creationErrorMessage: string;
10
+ };
11
+
12
+ export type MapLayerLoadingStatus =
13
+ | {
14
+ loaded: true;
15
+ }
16
+ | {
17
+ loadingError: true;
18
+ loadingErrorMessage: string;
19
+ loadingErrorHttpStatus?: number;
20
+ }
21
+ | {
22
+ loading: true;
23
+ };
24
+
25
+ export interface MapLayerDataInfo {
26
+ featuresCount?: number;
27
+ geometryTypes?: Array<"Point" | "LineString" | "Polygon">;
28
+ }
29
+
30
+ export type ResolvedMapLayerState = MapLayerCreationStatus &
31
+ MapLayerLoadingStatus &
32
+ MapLayerDataInfo;
33
+
34
+ /**
35
+ * Describes the actual view state of a map
36
+ */
37
+ export interface ResolvedMapViewState {
38
+ /** View center in longitude/latitude */
39
+ center: Coordinate;
40
+
41
+ /** Actual view extent in longitude/latitude */
42
+ extent: Extent;
43
+
44
+ /** Map units per pixel */
45
+ resolution: number;
46
+
47
+ /** Scale denominator (takes into account an estimated DPI) */
48
+ scaleDenominator: number;
49
+
50
+ /** Bearing in degrees; 90 is North (up) */
51
+ bearing: number;
52
+ }
53
+
54
+ /**
55
+ * Describes the actual state of a map after a context or context diff was applied to it.
56
+ * A `view` of null means the view state hasn't been changed yet.
57
+ * A `layer` item of null means the layer state hasn't been changed yet.
58
+ */
59
+ export interface ResolvedMapState {
60
+ layers: Array<ResolvedMapLayerState | null>;
61
+ view: ResolvedMapViewState | null;
62
+ }
@@ -66,6 +66,21 @@ describe("getHash", () => {
66
66
  });
67
67
  expect(hashB).toEqual(hashA);
68
68
  });
69
+ it("stable with identical GeoJSON collection", () => {
70
+ const hashA = getHash({
71
+ geometry: {
72
+ type: "FeatureCollection",
73
+ features: [{ type: "Feature", properties: {}, geometry: null }],
74
+ },
75
+ });
76
+ const hashB = getHash({
77
+ geometry: {
78
+ type: "FeatureCollection",
79
+ features: [{ type: "Feature", properties: {}, geometry: null }],
80
+ },
81
+ });
82
+ expect(hashB).toEqual(hashA);
83
+ });
69
84
  it("different if GeoJSON geometry properties are not in the same order", () => {
70
85
  const hashA = getHash({
71
86
  geometry: {
package/lib/utils/hash.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  function isGeoJsonGeometry(object: object) {
2
- return "type" in object && "coordinates" in object;
2
+ return "type" in object && ("coordinates" in object || "features" in object);
3
3
  }
4
4
 
5
5
  export function getHash(input: unknown, ignoreKeys: string[] = []): string {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@geospatial-sdk/core",
3
- "version": "0.0.5-dev.55+475f057",
3
+ "version": "0.0.5-dev.56+eae591c",
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": "475f057bccd243497d84db212b50812633e7398b",
25
+ "gitHead": "eae591cfcca0346c3cac6fe7d5dcddf88fe408f4",
26
26
  "dependencies": {
27
27
  "chroma-js": "^2.4.2",
28
28
  "proj4": "^2.9.2"