@geospatial-sdk/openlayers 0.0.5-dev.47 → 0.0.5-dev.49

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.
@@ -1 +1 @@
1
- {"version":3,"file":"apply-context-diff.d.ts","sourceRoot":"","sources":["../../lib/map/apply-context-diff.ts"],"names":[],"mappings":"AAAA,OAAO,GAAG,MAAM,WAAW,CAAC;AAC5B,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAQtD;;;;GAIG;AACH,wBAAsB,qBAAqB,CACzC,GAAG,EAAE,GAAG,EACR,WAAW,EAAE,cAAc,GAC1B,OAAO,CAAC,GAAG,CAAC,CA2Fd"}
1
+ {"version":3,"file":"apply-context-diff.d.ts","sourceRoot":"","sources":["../../lib/map/apply-context-diff.ts"],"names":[],"mappings":"AAAA,OAAO,GAAG,MAAM,WAAW,CAAC;AAC5B,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAQtD;;;;GAIG;AACH,wBAAsB,qBAAqB,CACzC,GAAG,EAAE,GAAG,EACR,WAAW,EAAE,cAAc,GAC1B,OAAO,CAAC,GAAG,CAAC,CA6Fd"}
@@ -1,4 +1,4 @@
1
- import { createLayer, createView } from "./create-map.js";
1
+ import { createLayer, createView, updateLayerInMap } from "./create-map.js";
2
2
  import { fromLonLat, transformExtent } from "ol/proj.js";
3
3
  import GeoJSON from "ol/format/GeoJSON.js";
4
4
  const GEOJSON = new GeoJSON();
@@ -38,12 +38,9 @@ export async function applyContextDiffToMap(map, contextDiff) {
38
38
  }
39
39
  map.setLayers([...layersArray]);
40
40
  }
41
- // recreate changed layers
41
+ // update or recreate changed layers
42
42
  for (const layerChanged of contextDiff.layersChanged) {
43
- layers.item(layerChanged.position).dispose();
44
- createLayer(layerChanged.layer).then((layer) => {
45
- layers.setAt(layerChanged.position, layer);
46
- });
43
+ updateLayerInMap(map, layerChanged.layer, layerChanged.position, layerChanged.previousLayer);
47
44
  }
48
45
  if (typeof contextDiff.viewChanges !== "undefined") {
49
46
  const { viewChanges } = contextDiff;
@@ -3,6 +3,7 @@ import Map from "ol/Map.js";
3
3
  import View from "ol/View.js";
4
4
  import Layer from "ol/layer/Layer.js";
5
5
  export declare function createLayer(layerModel: MapContextLayer): Promise<Layer>;
6
+ export declare function updateLayerInMap(map: Map, layerModel: MapContextLayer, layerPosition: number, previousLayerModel: MapContextLayer): void;
6
7
  export declare function createView(viewModel: MapContextView | null, map: Map): View;
7
8
  /**
8
9
  * Create an OpenLayers map from a context; optionally specify a target (root element) for the map
@@ -1 +1 @@
1
- {"version":3,"file":"create-map.d.ts","sourceRoot":"","sources":["../../lib/map/create-map.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,UAAU,EACV,eAAe,EACf,cAAc,EAEf,MAAM,sBAAsB,CAAC;AAC9B,OAAO,GAAG,MAAM,WAAW,CAAC;AAC5B,OAAO,IAAI,MAAM,YAAY,CAAC;AAC9B,OAAO,KAAK,MAAM,mBAAmB,CAAC;AAkCtC,wBAAsB,WAAW,CAAC,UAAU,EAAE,eAAe,GAAG,OAAO,CAAC,KAAK,CAAC,CA8N7E;AAED,wBAAgB,UAAU,CAAC,SAAS,EAAE,cAAc,GAAG,IAAI,EAAE,GAAG,EAAE,GAAG,GAAG,IAAI,CAkC3E;AAED;;;;GAIG;AACH,wBAAsB,oBAAoB,CACxC,OAAO,EAAE,UAAU,EACnB,MAAM,CAAC,EAAE,MAAM,GAAG,WAAW,GAC5B,OAAO,CAAC,GAAG,CAAC,CAKd;AAED;;;;GAIG;AACH,wBAAsB,mBAAmB,CACvC,GAAG,EAAE,GAAG,EACR,OAAO,EAAE,UAAU,GAClB,OAAO,CAAC,GAAG,CAAC,CAQd"}
1
+ {"version":3,"file":"create-map.d.ts","sourceRoot":"","sources":["../../lib/map/create-map.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,UAAU,EACV,eAAe,EACf,cAAc,EAEf,MAAM,sBAAsB,CAAC;AAC9B,OAAO,GAAG,MAAM,WAAW,CAAC;AAC5B,OAAO,IAAI,MAAM,YAAY,CAAC;AAC9B,OAAO,KAAK,MAAM,mBAAmB,CAAC;AAsCtC,wBAAsB,WAAW,CAAC,UAAU,EAAE,eAAe,GAAG,OAAO,CAAC,KAAK,CAAC,CAyN7E;AAED,wBAAgB,gBAAgB,CAC9B,GAAG,EAAE,GAAG,EACR,UAAU,EAAE,eAAe,EAC3B,aAAa,EAAE,MAAM,EACrB,kBAAkB,EAAE,eAAe,QAgBpC;AAED,wBAAgB,UAAU,CAAC,SAAS,EAAE,cAAc,GAAG,IAAI,EAAE,GAAG,EAAE,GAAG,GAAG,IAAI,CAkC3E;AAED;;;;GAIG;AACH,wBAAsB,oBAAoB,CACxC,OAAO,EAAE,UAAU,EACnB,MAAM,CAAC,EAAE,MAAM,GAAG,WAAW,GAC5B,OAAO,CAAC,GAAG,CAAC,CAKd;AAED;;;;GAIG;AACH,wBAAsB,mBAAmB,CACvC,GAAG,EAAE,GAAG,EACR,OAAO,EAAE,UAAU,GAClB,OAAO,CAAC,GAAG,CAAC,CAQd"}
@@ -19,6 +19,7 @@ import { OgcApiEndpoint, WfsEndpoint, WmtsEndpoint, } from "@camptocamp/ogc-clie
19
19
  import { MapboxVectorLayer } from "ol-mapbox-style";
20
20
  import { handleEndpointError, tileLoadErrorCatchFunction, } from "./handle-errors.js";
21
21
  import VectorTile from "ol/source/VectorTile.js";
22
+ import { canDoIncrementalUpdate, updateLayerProperties, } from "./layer-update.js";
22
23
  const GEOJSON = new GeoJSON();
23
24
  const WFS_MAX_FEATURES = 10000;
24
25
  export async function createLayer(layerModel) {
@@ -216,15 +217,23 @@ export async function createLayer(layerModel) {
216
217
  if (!layer) {
217
218
  throw new Error(`Layer could not be created for type: ${layerModel.type}`);
218
219
  }
219
- typeof layerModel.visibility !== "undefined" &&
220
- layer.setVisible(layerModel.visibility);
221
- typeof layerModel.opacity !== "undefined" &&
222
- layer.setOpacity(layerModel.opacity);
223
- typeof layerModel.attributions !== "undefined" &&
224
- layer.getSource()?.setAttributions(layerModel.attributions);
225
- layer.set("label", layerModel.label);
220
+ updateLayerProperties(layerModel, layer);
226
221
  return layer;
227
222
  }
223
+ export function updateLayerInMap(map, layerModel, layerPosition, previousLayerModel) {
224
+ const layers = map.getLayers();
225
+ const updatedLayer = layers.item(layerPosition);
226
+ // if an incremental update is possible, do it to avoid costly layer recreation
227
+ if (canDoIncrementalUpdate(previousLayerModel, layerModel)) {
228
+ updateLayerProperties(layerModel, updatedLayer, previousLayerModel);
229
+ return;
230
+ }
231
+ // dispose and recreate layer
232
+ updatedLayer.dispose();
233
+ createLayer(layerModel).then((layer) => {
234
+ layers.setAt(layerPosition, layer);
235
+ });
236
+ }
228
237
  export function createView(viewModel, map) {
229
238
  if (viewModel === null) {
230
239
  return new View({
@@ -0,0 +1,22 @@
1
+ import { MapContextLayer } from "@geospatial-sdk/core";
2
+ import Layer from "ol/layer/Layer.js";
3
+ /**
4
+ * Incremental update is possible only if certain properties are changed: opacity,
5
+ * visibility, zIndex, etc.
6
+ *
7
+ * Note: we assume that both layers are different versions of the same layer (this
8
+ * will not be checked again)
9
+ * @param oldLayer
10
+ * @param newLayer
11
+ * @return Returns `true` if the only properties changed are the updatable ones
12
+ */
13
+ export declare function canDoIncrementalUpdate(oldLayer: MapContextLayer, newLayer: MapContextLayer): boolean;
14
+ /**
15
+ * Will apply generic properties to the layer; if a previous layer model is provided,
16
+ * only changed properties will be updated (to avoid costly change events in OpenLayers)
17
+ * @param layerModel
18
+ * @param olLayer
19
+ * @param previousLayerModel
20
+ */
21
+ export declare function updateLayerProperties(layerModel: MapContextLayer, olLayer: Layer, previousLayerModel?: MapContextLayer): void;
22
+ //# sourceMappingURL=layer-update.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"layer-update.d.ts","sourceRoot":"","sources":["../../lib/map/layer-update.ts"],"names":[],"mappings":"AAAA,OAAO,EAAW,eAAe,EAAE,MAAM,sBAAsB,CAAC;AAEhE,OAAO,KAAK,MAAM,mBAAmB,CAAC;AAYtC;;;;;;;;;GASG;AACH,wBAAgB,sBAAsB,CACpC,QAAQ,EAAE,eAAe,EACzB,QAAQ,EAAE,eAAe,GACxB,OAAO,CAIT;AAED;;;;;;GAMG;AACH,wBAAgB,qBAAqB,CACnC,UAAU,EAAE,eAAe,EAC3B,OAAO,EAAE,KAAK,EACd,kBAAkB,CAAC,EAAE,eAAe,QA6BrC"}
@@ -0,0 +1,59 @@
1
+ import { getHash } from "@geospatial-sdk/core";
2
+ const UPDATABLE_PROPERTIES = [
3
+ "opacity",
4
+ "visibility",
5
+ "label",
6
+ "attributions",
7
+ "extras",
8
+ "version",
9
+ // TODO (when available) "zIndex"
10
+ ];
11
+ /**
12
+ * Incremental update is possible only if certain properties are changed: opacity,
13
+ * visibility, zIndex, etc.
14
+ *
15
+ * Note: we assume that both layers are different versions of the same layer (this
16
+ * will not be checked again)
17
+ * @param oldLayer
18
+ * @param newLayer
19
+ * @return Returns `true` if the only properties changed are the updatable ones
20
+ */
21
+ export function canDoIncrementalUpdate(oldLayer, newLayer) {
22
+ const oldHash = getHash(oldLayer, UPDATABLE_PROPERTIES);
23
+ const newHash = getHash(newLayer, UPDATABLE_PROPERTIES);
24
+ return oldHash === newHash;
25
+ }
26
+ /**
27
+ * Will apply generic properties to the layer; if a previous layer model is provided,
28
+ * only changed properties will be updated (to avoid costly change events in OpenLayers)
29
+ * @param layerModel
30
+ * @param olLayer
31
+ * @param previousLayerModel
32
+ */
33
+ export function updateLayerProperties(layerModel, olLayer, previousLayerModel) {
34
+ function shouldApplyProperty(prop) {
35
+ // if the new layer model does not define that property, skip it
36
+ // (setting or resetting it to a default value would be counter-intuitive)
37
+ if (!(prop in layerModel) || typeof layerModel[prop] === "undefined")
38
+ return false;
39
+ // if a previous model is provided and the value did not change in the new layer model, skip it
40
+ if (previousLayerModel && layerModel[prop] === previousLayerModel[prop]) {
41
+ return false;
42
+ }
43
+ // any other case: apply the property
44
+ return true;
45
+ }
46
+ if (shouldApplyProperty("visibility")) {
47
+ olLayer.setVisible(layerModel.visibility);
48
+ }
49
+ if (shouldApplyProperty("opacity")) {
50
+ olLayer.setOpacity(layerModel.opacity);
51
+ }
52
+ if (shouldApplyProperty("attributions")) {
53
+ olLayer.getSource()?.setAttributions(layerModel.attributions);
54
+ }
55
+ if (shouldApplyProperty("label")) {
56
+ olLayer.set("label", layerModel.label);
57
+ }
58
+ // TODO: z-index
59
+ }
@@ -127,6 +127,7 @@ describe("applyContextDiffToMap", () => {
127
127
  ...SAMPLE_LAYER2,
128
128
  url: "http://changed/",
129
129
  } as MapContextLayer,
130
+ previousLayer: SAMPLE_LAYER2,
130
131
  position: 0,
131
132
  },
132
133
  {
@@ -137,6 +138,7 @@ describe("applyContextDiffToMap", () => {
137
138
  changed: true,
138
139
  },
139
140
  } as MapContextLayer,
141
+ previousLayer: SAMPLE_LAYER1,
140
142
  position: 1,
141
143
  },
142
144
  ],
@@ -151,6 +153,38 @@ describe("applyContextDiffToMap", () => {
151
153
  assertEqualsToModel(layersArray[0], diff.layersChanged[0].layer);
152
154
  assertEqualsToModel(layersArray[1], diff.layersChanged[1].layer);
153
155
  });
156
+
157
+ describe("layers changed (updatable properties only)", () => {
158
+ let prevOlLayer: BaseLayer;
159
+ let newOlLayer: BaseLayer;
160
+ beforeEach(() => {
161
+ diff = {
162
+ layersAdded: [],
163
+ layersChanged: [
164
+ {
165
+ layer: {
166
+ ...SAMPLE_LAYER1,
167
+ attributions: "new attributions!",
168
+ } as MapContextLayer,
169
+ previousLayer: SAMPLE_LAYER1,
170
+ position: 1,
171
+ },
172
+ ],
173
+ layersRemoved: [],
174
+ layersReordered: [],
175
+ };
176
+ prevOlLayer = map.getLayers().item(1);
177
+ applyContextDiffToMap(map, diff);
178
+ newOlLayer = map.getLayers().item(1);
179
+ });
180
+ it("modifies the layer without recreating it", () => {
181
+ expect(prevOlLayer).toBe(newOlLayer);
182
+ const newAttributions = (newOlLayer as any)
183
+ .getSource()
184
+ ?.getAttributions();
185
+ expect(newAttributions()).toEqual(["new attributions!"]);
186
+ });
187
+ });
154
188
  });
155
189
 
156
190
  describe("reordering", () => {
@@ -319,6 +353,7 @@ describe("applyContextDiffToMap", () => {
319
353
  layersChanged: [
320
354
  {
321
355
  layer: changedLayer,
356
+ previousLayer: SAMPLE_LAYER3,
322
357
  position: 1,
323
358
  },
324
359
  ],
@@ -1,6 +1,6 @@
1
1
  import Map from "ol/Map.js";
2
2
  import { MapContextDiff } from "@geospatial-sdk/core";
3
- import { createLayer, createView } from "./create-map.js";
3
+ import { createLayer, createView, updateLayerInMap } from "./create-map.js";
4
4
  import { fromLonLat, transformExtent } from "ol/proj.js";
5
5
  import GeoJSON from "ol/format/GeoJSON.js";
6
6
  import SimpleGeometry from "ol/geom/SimpleGeometry.js";
@@ -58,12 +58,14 @@ export async function applyContextDiffToMap(
58
58
  map.setLayers([...layersArray]);
59
59
  }
60
60
 
61
- // recreate changed layers
61
+ // update or recreate changed layers
62
62
  for (const layerChanged of contextDiff.layersChanged) {
63
- layers.item(layerChanged.position).dispose();
64
- createLayer(layerChanged.layer).then((layer) => {
65
- layers.setAt(layerChanged.position, layer);
66
- });
63
+ updateLayerInMap(
64
+ map,
65
+ layerChanged.layer,
66
+ layerChanged.position,
67
+ layerChanged.previousLayer,
68
+ );
67
69
  }
68
70
 
69
71
  if (typeof contextDiff.viewChanges !== "undefined") {
@@ -36,6 +36,10 @@ import {
36
36
  tileLoadErrorCatchFunction,
37
37
  } from "./handle-errors.js";
38
38
  import VectorTile from "ol/source/VectorTile.js";
39
+ import {
40
+ canDoIncrementalUpdate,
41
+ updateLayerProperties,
42
+ } from "./layer-update.js";
39
43
 
40
44
  const GEOJSON = new GeoJSON();
41
45
  const WFS_MAX_FEATURES = 10000;
@@ -253,17 +257,34 @@ export async function createLayer(layerModel: MapContextLayer): Promise<Layer> {
253
257
  if (!layer) {
254
258
  throw new Error(`Layer could not be created for type: ${layerModel.type}`);
255
259
  }
256
- typeof layerModel.visibility !== "undefined" &&
257
- layer.setVisible(layerModel.visibility);
258
- typeof layerModel.opacity !== "undefined" &&
259
- layer.setOpacity(layerModel.opacity);
260
- typeof layerModel.attributions !== "undefined" &&
261
- layer.getSource()?.setAttributions(layerModel.attributions);
262
- layer.set("label", layerModel.label);
260
+
261
+ updateLayerProperties(layerModel, layer);
263
262
 
264
263
  return layer;
265
264
  }
266
265
 
266
+ export function updateLayerInMap(
267
+ map: Map,
268
+ layerModel: MapContextLayer,
269
+ layerPosition: number,
270
+ previousLayerModel: MapContextLayer,
271
+ ) {
272
+ const layers = map.getLayers();
273
+ const updatedLayer = layers.item(layerPosition) as Layer;
274
+
275
+ // if an incremental update is possible, do it to avoid costly layer recreation
276
+ if (canDoIncrementalUpdate(previousLayerModel, layerModel)) {
277
+ updateLayerProperties(layerModel, updatedLayer, previousLayerModel);
278
+ return;
279
+ }
280
+
281
+ // dispose and recreate layer
282
+ updatedLayer.dispose();
283
+ createLayer(layerModel).then((layer) => {
284
+ layers.setAt(layerPosition, layer);
285
+ });
286
+ }
287
+
267
288
  export function createView(viewModel: MapContextView | null, map: Map): View {
268
289
  if (viewModel === null) {
269
290
  return new View({
@@ -0,0 +1,115 @@
1
+ import {
2
+ canDoIncrementalUpdate,
3
+ updateLayerProperties,
4
+ } from "./layer-update.js";
5
+ import { MapContextLayer } from "@geospatial-sdk/core";
6
+ import Layer from "ol/layer/Layer.js";
7
+ import { Source } from "ol/source.js";
8
+ import { SAMPLE_LAYER1 } from "@geospatial-sdk/core/fixtures/map-context.fixtures.js";
9
+ import VectorSource from "ol/source/Vector.js";
10
+
11
+ describe("Layer update utils", () => {
12
+ describe("canDoIncrementalUpdate", () => {
13
+ it("returns true if only updatable properties are changed", () => {
14
+ const oldLayer = {
15
+ name: "layer1",
16
+ type: "wms",
17
+ url: "https://example.com/wms",
18
+ opacity: 0.5,
19
+ visibility: true,
20
+ label: "Layer 1",
21
+ } as MapContextLayer;
22
+ const newLayer = {
23
+ name: "layer1",
24
+ type: "wms",
25
+ url: "https://example.com/wms",
26
+ opacity: 0.8,
27
+ label: "Layer 1 Updated",
28
+ extras: { hello: "world" },
29
+ } as MapContextLayer;
30
+ expect(canDoIncrementalUpdate(oldLayer, newLayer)).toBe(true);
31
+ });
32
+ it("returns false if non-updatable properties are changed", () => {
33
+ const oldLayer = {
34
+ name: "layer1",
35
+ type: "wms",
36
+ url: "https://example.com/wms",
37
+ opacity: 0.5,
38
+ visibility: true,
39
+ label: "Layer 1",
40
+ } as MapContextLayer;
41
+ const newLayer = {
42
+ name: "layer1",
43
+ type: "wms",
44
+ url: "https://example.com/wms/CHANGED",
45
+ opacity: 0.5,
46
+ visibility: true,
47
+ label: "Layer 1",
48
+ } as MapContextLayer;
49
+ expect(canDoIncrementalUpdate(oldLayer, newLayer)).toBe(false);
50
+ });
51
+ });
52
+
53
+ describe("updateLayerProperties", () => {
54
+ let olLayer: Layer;
55
+ let olSource: Source;
56
+
57
+ beforeEach(() => {
58
+ olSource = new VectorSource({});
59
+ olLayer = new Layer({ source: olSource });
60
+ vi.spyOn(olLayer, "setVisible");
61
+ vi.spyOn(olLayer, "setOpacity");
62
+ vi.spyOn(olLayer, "set");
63
+ vi.spyOn(olSource, "setAttributions");
64
+ });
65
+
66
+ it("applies the properties defined in the layer model", () => {
67
+ const layerModel = {
68
+ ...SAMPLE_LAYER1,
69
+ visibility: false,
70
+ opacity: 0.7,
71
+ attributions: "hello world",
72
+ label: "Test Layer",
73
+ } as MapContextLayer;
74
+ updateLayerProperties(layerModel, olLayer);
75
+ expect(olLayer.setVisible).toHaveBeenCalledWith(false);
76
+ expect(olLayer.setOpacity).toHaveBeenCalledWith(0.7);
77
+ expect(olLayer.set).toHaveBeenCalledWith("label", "Test Layer");
78
+ expect(olSource.setAttributions).toHaveBeenCalledWith("hello world");
79
+ });
80
+
81
+ it("does not apply properties not defined in the layer model", () => {
82
+ const layerModel = {
83
+ type: "wms",
84
+ url: "http://abc.org/wms",
85
+ name: "myLayer",
86
+ label: "Test Layer",
87
+ } as MapContextLayer;
88
+ updateLayerProperties(layerModel, olLayer);
89
+ expect(olLayer.setVisible).not.toHaveBeenCalled();
90
+ expect(olLayer.setOpacity).not.toHaveBeenCalled();
91
+ expect(olSource.setAttributions).not.toHaveBeenCalled();
92
+ expect(olLayer.set).toHaveBeenCalledWith("label", "Test Layer");
93
+ });
94
+
95
+ it("applies properties if they have changed compared to the previous model and they are defined in the new model", () => {
96
+ const layerModel = {
97
+ ...SAMPLE_LAYER1,
98
+ opacity: 0.9,
99
+ attributions: "hello world",
100
+ label: "Test Layer",
101
+ } as MapContextLayer;
102
+ const prevLayerModel = {
103
+ ...SAMPLE_LAYER1,
104
+ visibility: true,
105
+ opacity: 0.7,
106
+ attributions: "hello world (old)",
107
+ } as MapContextLayer;
108
+ updateLayerProperties(layerModel, olLayer, prevLayerModel);
109
+ expect(olLayer.setVisible).not.toHaveBeenCalled();
110
+ expect(olLayer.setOpacity).toHaveBeenCalledWith(0.9);
111
+ expect(olSource.setAttributions).toHaveBeenCalledWith("hello world");
112
+ expect(olLayer.set).toHaveBeenCalledWith("label", "Test Layer");
113
+ });
114
+ });
115
+ });
@@ -0,0 +1,73 @@
1
+ import { getHash, MapContextLayer } from "@geospatial-sdk/core";
2
+ import { MapContextBaseLayer } from "@geospatial-sdk/core/lib/model/map-context.js";
3
+ import Layer from "ol/layer/Layer.js";
4
+
5
+ const UPDATABLE_PROPERTIES: (keyof MapContextBaseLayer)[] = [
6
+ "opacity",
7
+ "visibility",
8
+ "label",
9
+ "attributions",
10
+ "extras",
11
+ "version",
12
+ // TODO (when available) "zIndex"
13
+ ];
14
+
15
+ /**
16
+ * Incremental update is possible only if certain properties are changed: opacity,
17
+ * visibility, zIndex, etc.
18
+ *
19
+ * Note: we assume that both layers are different versions of the same layer (this
20
+ * will not be checked again)
21
+ * @param oldLayer
22
+ * @param newLayer
23
+ * @return Returns `true` if the only properties changed are the updatable ones
24
+ */
25
+ export function canDoIncrementalUpdate(
26
+ oldLayer: MapContextLayer,
27
+ newLayer: MapContextLayer,
28
+ ): boolean {
29
+ const oldHash = getHash(oldLayer, UPDATABLE_PROPERTIES);
30
+ const newHash = getHash(newLayer, UPDATABLE_PROPERTIES);
31
+ return oldHash === newHash;
32
+ }
33
+
34
+ /**
35
+ * Will apply generic properties to the layer; if a previous layer model is provided,
36
+ * only changed properties will be updated (to avoid costly change events in OpenLayers)
37
+ * @param layerModel
38
+ * @param olLayer
39
+ * @param previousLayerModel
40
+ */
41
+ export function updateLayerProperties(
42
+ layerModel: MapContextLayer,
43
+ olLayer: Layer,
44
+ previousLayerModel?: MapContextLayer,
45
+ ) {
46
+ function shouldApplyProperty(prop: keyof MapContextBaseLayer): boolean {
47
+ // if the new layer model does not define that property, skip it
48
+ // (setting or resetting it to a default value would be counter-intuitive)
49
+ if (!(prop in layerModel) || typeof layerModel[prop] === "undefined")
50
+ return false;
51
+
52
+ // if a previous model is provided and the value did not change in the new layer model, skip it
53
+ if (previousLayerModel && layerModel[prop] === previousLayerModel[prop]) {
54
+ return false;
55
+ }
56
+
57
+ // any other case: apply the property
58
+ return true;
59
+ }
60
+ if (shouldApplyProperty("visibility")) {
61
+ olLayer.setVisible(layerModel.visibility!);
62
+ }
63
+ if (shouldApplyProperty("opacity")) {
64
+ olLayer.setOpacity(layerModel.opacity!);
65
+ }
66
+ if (shouldApplyProperty("attributions")) {
67
+ olLayer.getSource()?.setAttributions(layerModel.attributions);
68
+ }
69
+ if (shouldApplyProperty("label")) {
70
+ olLayer.set("label", layerModel.label);
71
+ }
72
+ // TODO: z-index
73
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@geospatial-sdk/openlayers",
3
- "version": "0.0.5-dev.47+37669e8",
3
+ "version": "0.0.5-dev.49+67854c5",
4
4
  "description": "OpenLayers-related utilities",
5
5
  "keywords": [
6
6
  "ol",
@@ -37,10 +37,10 @@
37
37
  "ol": ">6.x"
38
38
  },
39
39
  "dependencies": {
40
- "@geospatial-sdk/core": "^0.0.5-dev.47+37669e8",
40
+ "@geospatial-sdk/core": "^0.0.5-dev.49+67854c5",
41
41
  "chroma-js": "^2.4.2",
42
42
  "lodash.throttle": "^4.1.1",
43
43
  "ol-mapbox-style": "12.4.0"
44
44
  },
45
- "gitHead": "37669e815765d751c4795a67e671ae19e3bf5a92"
45
+ "gitHead": "67854c5bbe5b473e1a8160f5e8e56fe162e1d427"
46
46
  }