@open-pioneer/map 0.7.0 → 0.8.0-dev.20241120115147
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/CHANGELOG.md +133 -0
- package/README.md +116 -12
- package/api/MapModel.d.ts +48 -15
- package/api/layers/GroupLayer.d.ts +50 -0
- package/api/layers/GroupLayer.js +6 -0
- package/api/layers/GroupLayer.js.map +1 -0
- package/api/layers/SimpleLayer.d.ts +1 -0
- package/api/layers/SimpleLayer.js.map +1 -1
- package/api/layers/WMSLayer.d.ts +1 -0
- package/api/layers/WMSLayer.js.map +1 -1
- package/api/layers/WMTSLayer.d.ts +1 -0
- package/api/layers/WMTSLayer.js.map +1 -1
- package/api/layers/base.d.ts +35 -14
- package/api/layers/base.js.map +1 -1
- package/api/layers/index.d.ts +1 -0
- package/index.js +1 -0
- package/index.js.map +1 -1
- package/model/AbstractLayer.d.ts +2 -2
- package/model/AbstractLayer.js +16 -23
- package/model/AbstractLayer.js.map +1 -1
- package/model/AbstractLayerBase.d.ts +19 -4
- package/model/AbstractLayerBase.js +48 -35
- package/model/AbstractLayerBase.js.map +1 -1
- package/model/Highlights.d.ts +2 -1
- package/model/Highlights.js +2 -0
- package/model/Highlights.js.map +1 -1
- package/model/LayerCollectionImpl.d.ts +5 -3
- package/model/LayerCollectionImpl.js +27 -29
- package/model/LayerCollectionImpl.js.map +1 -1
- package/model/MapModelImpl.d.ts +12 -2
- package/model/MapModelImpl.js +94 -25
- package/model/MapModelImpl.js.map +1 -1
- package/model/SublayersCollectionImpl.d.ts +6 -3
- package/model/SublayersCollectionImpl.js +6 -4
- package/model/SublayersCollectionImpl.js.map +1 -1
- package/model/layers/GroupLayerImpl.d.ts +39 -0
- package/model/layers/GroupLayerImpl.js +88 -0
- package/model/layers/GroupLayerImpl.js.map +1 -0
- package/model/layers/SimpleLayerImpl.d.ts +1 -0
- package/model/layers/SimpleLayerImpl.js +3 -0
- package/model/layers/SimpleLayerImpl.js.map +1 -1
- package/model/layers/WMSLayerImpl.d.ts +9 -7
- package/model/layers/WMSLayerImpl.js +58 -51
- package/model/layers/WMSLayerImpl.js.map +1 -1
- package/model/layers/WMTSLayerImpl.d.ts +3 -5
- package/model/layers/WMTSLayerImpl.js +13 -13
- package/model/layers/WMTSLayerImpl.js.map +1 -1
- package/package.json +9 -8
- package/ui/hooks.d.ts +10 -0
- package/ui/hooks.js.map +1 -1
- package/util/defer.d.ts +0 -18
- package/util/defer.js +0 -21
- package/util/defer.js.map +0 -1
|
@@ -1,24 +1,24 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { reactiveSet, reactive, batch } from '@conterra/reactivity-core';
|
|
2
|
+
import { createLogger } from '@open-pioneer/core';
|
|
2
3
|
import { AbstractLayer } from './AbstractLayer.js';
|
|
3
4
|
|
|
4
5
|
const LOG = createLogger("map:LayerCollection");
|
|
5
6
|
const BASE_LAYER_Z = 0;
|
|
6
7
|
const OPERATION_LAYER_INITIAL_Z = 1;
|
|
7
8
|
const TOPMOST_LAYER_Z = 9999999;
|
|
8
|
-
class LayerCollectionImpl
|
|
9
|
+
class LayerCollectionImpl {
|
|
9
10
|
#map;
|
|
10
11
|
/** Top level layers (base layers, operational layers). No sublayers. */
|
|
11
|
-
#topLevelLayers =
|
|
12
|
+
#topLevelLayers = reactiveSet();
|
|
12
13
|
/** Index of _all_ layer instances, including sublayers. */
|
|
13
14
|
#layersById = /* @__PURE__ */ new Map();
|
|
14
15
|
/** Reverse index of _all_ layers that have an associated OpenLayers layer. */
|
|
15
16
|
#layersByOlLayer = /* @__PURE__ */ new WeakMap();
|
|
16
17
|
/** Currently active base layer. */
|
|
17
|
-
#activeBaseLayer;
|
|
18
|
+
#activeBaseLayer = reactive();
|
|
18
19
|
/** next z-index for operational layer. currently just auto-increments. */
|
|
19
20
|
#nextIndex = OPERATION_LAYER_INITIAL_Z;
|
|
20
21
|
constructor(map) {
|
|
21
|
-
super();
|
|
22
22
|
this.#map = map;
|
|
23
23
|
}
|
|
24
24
|
destroy() {
|
|
@@ -27,18 +27,18 @@ class LayerCollectionImpl extends EventEmitter {
|
|
|
27
27
|
}
|
|
28
28
|
this.#topLevelLayers.clear();
|
|
29
29
|
this.#layersById.clear();
|
|
30
|
-
this.#activeBaseLayer = void 0;
|
|
30
|
+
this.#activeBaseLayer.value = void 0;
|
|
31
31
|
}
|
|
32
32
|
addLayer(layer) {
|
|
33
33
|
checkLayerInstance(layer);
|
|
34
|
-
layer.
|
|
34
|
+
layer.__attachToMap(this.#map);
|
|
35
35
|
this.#addLayer(layer);
|
|
36
36
|
}
|
|
37
37
|
getBaseLayers() {
|
|
38
38
|
return this.getAllLayers().filter((layer) => layer.isBaseLayer);
|
|
39
39
|
}
|
|
40
40
|
getActiveBaseLayer() {
|
|
41
|
-
return this.#activeBaseLayer;
|
|
41
|
+
return this.#activeBaseLayer.value;
|
|
42
42
|
}
|
|
43
43
|
activateBaseLayer(id) {
|
|
44
44
|
let newBaseLayer = void 0;
|
|
@@ -57,10 +57,7 @@ class LayerCollectionImpl extends EventEmitter {
|
|
|
57
57
|
return false;
|
|
58
58
|
}
|
|
59
59
|
}
|
|
60
|
-
|
|
61
|
-
this.#updateBaseLayer(newBaseLayer);
|
|
62
|
-
this.emit("changed");
|
|
63
|
-
}
|
|
60
|
+
this.#updateBaseLayer(newBaseLayer);
|
|
64
61
|
return true;
|
|
65
62
|
}
|
|
66
63
|
getOperationalLayers(options) {
|
|
@@ -95,7 +92,7 @@ class LayerCollectionImpl extends EventEmitter {
|
|
|
95
92
|
const olLayer = model.olLayer;
|
|
96
93
|
if (model.isBaseLayer) {
|
|
97
94
|
olLayer.setZIndex(BASE_LAYER_Z);
|
|
98
|
-
if (!this.#activeBaseLayer && model.visible) {
|
|
95
|
+
if (!this.#activeBaseLayer.value && model.visible) {
|
|
99
96
|
this.#updateBaseLayer(model);
|
|
100
97
|
} else {
|
|
101
98
|
model.__setVisible(false);
|
|
@@ -106,7 +103,6 @@ class LayerCollectionImpl extends EventEmitter {
|
|
|
106
103
|
}
|
|
107
104
|
this.#topLevelLayers.add(model);
|
|
108
105
|
this.#map.olMap.addLayer(olLayer);
|
|
109
|
-
this.emit("changed");
|
|
110
106
|
}
|
|
111
107
|
/**
|
|
112
108
|
* Removes the given layer from the map and all relevant indices.
|
|
@@ -127,7 +123,7 @@ class LayerCollectionImpl extends EventEmitter {
|
|
|
127
123
|
this.#map.olMap.removeLayer(model.olLayer);
|
|
128
124
|
this.#topLevelLayers.delete(model);
|
|
129
125
|
this.#unIndexLayer(model);
|
|
130
|
-
if (this.#activeBaseLayer === model) {
|
|
126
|
+
if (this.#activeBaseLayer.value === model) {
|
|
131
127
|
const newBaselayer = this.getBaseLayers()[0];
|
|
132
128
|
if (newBaselayer) {
|
|
133
129
|
checkLayerInstance(newBaselayer);
|
|
@@ -135,10 +131,9 @@ class LayerCollectionImpl extends EventEmitter {
|
|
|
135
131
|
this.#updateBaseLayer(newBaselayer);
|
|
136
132
|
}
|
|
137
133
|
model.destroy();
|
|
138
|
-
this.emit("changed");
|
|
139
134
|
}
|
|
140
135
|
#updateBaseLayer(model) {
|
|
141
|
-
if (this.#activeBaseLayer === model) {
|
|
136
|
+
if (this.#activeBaseLayer.value === model) {
|
|
142
137
|
return;
|
|
143
138
|
}
|
|
144
139
|
if (LOG.isDebug()) {
|
|
@@ -146,14 +141,14 @@ class LayerCollectionImpl extends EventEmitter {
|
|
|
146
141
|
return model2 ? `'${model2.id}'` : void 0;
|
|
147
142
|
};
|
|
148
143
|
LOG.debug(
|
|
149
|
-
`Switching active base layer from ${getId(this.#activeBaseLayer)} to ${getId(
|
|
150
|
-
model
|
|
151
|
-
)}`
|
|
144
|
+
`Switching active base layer from ${getId(this.#activeBaseLayer.value)} to ${getId(model)}`
|
|
152
145
|
);
|
|
153
146
|
}
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
147
|
+
batch(() => {
|
|
148
|
+
this.#activeBaseLayer.value?.__setVisible(false);
|
|
149
|
+
this.#activeBaseLayer.value = model;
|
|
150
|
+
model?.__setVisible(true);
|
|
151
|
+
});
|
|
157
152
|
}
|
|
158
153
|
/**
|
|
159
154
|
* Index the layer and all its children.
|
|
@@ -169,13 +164,16 @@ class LayerCollectionImpl extends EventEmitter {
|
|
|
169
164
|
);
|
|
170
165
|
}
|
|
171
166
|
if (olLayer && this.#layersByOlLayer.has(olLayer)) {
|
|
172
|
-
throw new Error(`OlLayer has already been used in
|
|
167
|
+
throw new Error(`OlLayer used by layer '${id}' has already been used in map.`);
|
|
173
168
|
}
|
|
174
169
|
this.#layersById.set(id, model2);
|
|
175
170
|
if (olLayer) {
|
|
176
171
|
this.#layersByOlLayer.set(olLayer, model2);
|
|
177
172
|
}
|
|
178
173
|
registrations.push([id, olLayer]);
|
|
174
|
+
for (const layer of model2.layers?.__getRawLayers() ?? []) {
|
|
175
|
+
visit(layer);
|
|
176
|
+
}
|
|
179
177
|
for (const sublayer of model2.sublayers?.__getRawSublayers() ?? []) {
|
|
180
178
|
visit(sublayer);
|
|
181
179
|
}
|
|
@@ -193,7 +191,7 @@ class LayerCollectionImpl extends EventEmitter {
|
|
|
193
191
|
}
|
|
194
192
|
}
|
|
195
193
|
/**
|
|
196
|
-
* Removes index entries for the given layer and all its
|
|
194
|
+
* Removes index entries for the given layer and all its children.
|
|
197
195
|
*/
|
|
198
196
|
#unIndexLayer(model) {
|
|
199
197
|
const visit = (model2) => {
|
|
@@ -201,6 +199,9 @@ class LayerCollectionImpl extends EventEmitter {
|
|
|
201
199
|
this.#layersByOlLayer.delete(model2.olLayer);
|
|
202
200
|
}
|
|
203
201
|
this.#layersById.delete(model2.id);
|
|
202
|
+
for (const layer of model2.layers?.__getRawLayers() ?? []) {
|
|
203
|
+
visit(layer);
|
|
204
|
+
}
|
|
204
205
|
for (const sublayer of model2.sublayers?.__getRawSublayers() ?? []) {
|
|
205
206
|
visit(sublayer);
|
|
206
207
|
}
|
|
@@ -212,10 +213,7 @@ function sortLayersByDisplayOrder(layers) {
|
|
|
212
213
|
layers.sort((left, right) => {
|
|
213
214
|
const leftZ = left.olLayer.getZIndex() ?? 1;
|
|
214
215
|
const rightZ = right.olLayer.getZIndex() ?? 1;
|
|
215
|
-
|
|
216
|
-
return leftZ - rightZ;
|
|
217
|
-
}
|
|
218
|
-
return left.id.localeCompare(right.id, "en");
|
|
216
|
+
return leftZ - rightZ;
|
|
219
217
|
});
|
|
220
218
|
}
|
|
221
219
|
function checkLayerInstance(object) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"LayerCollectionImpl.js","sources":["LayerCollectionImpl.ts"],"sourcesContent":["// SPDX-FileCopyrightText: 2023 Open Pioneer project (https://github.com/open-pioneer)\n// SPDX-License-Identifier: Apache-2.0\nimport { EventEmitter, createLogger } from \"@open-pioneer/core\";\nimport OlBaseLayer from \"ol/layer/Base\";\nimport {\n LayerCollection,\n LayerCollectionEvents,\n Layer,\n LayerRetrievalOptions,\n AnyLayer,\n Sublayer\n} from \"../api\";\nimport { AbstractLayer } from \"./AbstractLayer\";\nimport { AbstractLayerBase } from \"./AbstractLayerBase\";\nimport { MapModelImpl } from \"./MapModelImpl\";\n\nconst LOG = createLogger(\"map:LayerCollection\");\n\nconst BASE_LAYER_Z = 0;\nconst OPERATION_LAYER_INITIAL_Z = 1;\n\ntype LayerType = AbstractLayer & Layer;\ntype LayerBaseType = (AbstractLayerBase & Layer) | (AbstractLayerBase & Sublayer);\n\n/**\n * Z index for layers that should always be rendered on top of all other layers.\n * Note that this is an internal, unstable property!\n *\n * @internal\n */\nexport const TOPMOST_LAYER_Z = 9999999;\n\nexport class LayerCollectionImpl\n extends EventEmitter<LayerCollectionEvents>\n implements LayerCollection\n{\n #map: MapModelImpl;\n\n /** Top level layers (base layers, operational layers). No sublayers. */\n #topLevelLayers = new Set<LayerType>();\n\n /** Index of _all_ layer instances, including sublayers. */\n #layersById = new Map<string, LayerBaseType>();\n\n /** Reverse index of _all_ layers that have an associated OpenLayers layer. */\n #layersByOlLayer: WeakMap<OlBaseLayer, LayerType> = new WeakMap();\n\n /** Currently active base layer. */\n #activeBaseLayer: LayerType | undefined;\n\n /** next z-index for operational layer. currently just auto-increments. */\n #nextIndex = OPERATION_LAYER_INITIAL_Z;\n\n constructor(map: MapModelImpl) {\n super();\n this.#map = map;\n }\n\n destroy() {\n // Collection is destroyed together with the map, there is no need to clean up the olMap\n for (const layer of this.#layersById.values()) {\n layer.destroy();\n }\n this.#topLevelLayers.clear();\n this.#layersById.clear();\n this.#activeBaseLayer = undefined;\n }\n\n addLayer(layer: Layer): void {\n checkLayerInstance(layer);\n\n layer.__attach(this.#map);\n this.#addLayer(layer);\n }\n\n getBaseLayers(): Layer[] {\n return this.getAllLayers().filter((layer) => layer.isBaseLayer);\n }\n\n getActiveBaseLayer(): Layer | undefined {\n return this.#activeBaseLayer;\n }\n\n activateBaseLayer(id: string | undefined): boolean {\n let newBaseLayer = undefined;\n if (id != null) {\n newBaseLayer = this.#layersById.get(id);\n if (!(newBaseLayer instanceof AbstractLayer)) {\n LOG.warn(`Cannot activate base layer '${id}: layer has an invalid type.'`);\n return false;\n }\n if (!newBaseLayer) {\n LOG.warn(`Cannot activate base layer '${id}': layer is unknown.`);\n return false;\n }\n if (!newBaseLayer.isBaseLayer) {\n LOG.warn(`Cannot activate base layer '${id}': layer is not a base layer.`);\n return false;\n }\n }\n\n if (newBaseLayer !== this.#activeBaseLayer) {\n this.#updateBaseLayer(newBaseLayer);\n this.emit(\"changed\");\n }\n return true;\n }\n\n getOperationalLayers(options?: LayerRetrievalOptions): Layer[] {\n return this.getAllLayers(options).filter((layer) => !layer.isBaseLayer);\n }\n\n getAllLayers(options?: LayerRetrievalOptions): Layer[] {\n const layers = Array.from(this.#topLevelLayers.values());\n if (options?.sortByDisplayOrder) {\n sortLayersByDisplayOrder(layers);\n }\n return layers;\n }\n\n getLayerById(id: string): AnyLayer | undefined {\n return this.#layersById.get(id);\n }\n\n removeLayerById(id: string): void {\n const model = this.#layersById.get(id);\n if (!model) {\n LOG.isDebug() && LOG.debug(`Cannot remove layer '${id}': layer is unknown.`);\n return;\n }\n\n this.#removeLayer(model);\n }\n\n getLayerByRawInstance(layer: OlBaseLayer): Layer | undefined {\n return this.#layersByOlLayer?.get(layer);\n }\n\n /**\n * Adds the given layer to the map and all relevant indices.\n */\n #addLayer(model: LayerType) {\n this.#indexLayer(model);\n\n const olLayer = model.olLayer;\n if (model.isBaseLayer) {\n olLayer.setZIndex(BASE_LAYER_Z);\n if (!this.#activeBaseLayer && model.visible) {\n this.#updateBaseLayer(model);\n } else {\n model.__setVisible(false);\n }\n } else {\n olLayer.setZIndex(this.#nextIndex++);\n model.__setVisible(model.visible);\n }\n\n this.#topLevelLayers.add(model);\n this.#map.olMap.addLayer(olLayer);\n this.emit(\"changed\");\n }\n\n /**\n * Removes the given layer from the map and all relevant indices.\n * The layer will be destroyed.\n */\n #removeLayer(model: LayerType | LayerBaseType) {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n if (!this.#topLevelLayers.has(model as any)) {\n LOG.warn(\n `Cannot remove layer '${model.id}': only top level layers can be removed at this time.`\n );\n return;\n }\n\n if (!(model instanceof AbstractLayer)) {\n throw new Error(\n `Internal error: expected top level layer to be an instance of AbstractLayer.`\n );\n }\n\n this.#map.olMap.removeLayer(model.olLayer);\n this.#topLevelLayers.delete(model);\n this.#unIndexLayer(model);\n if (this.#activeBaseLayer === model) {\n const newBaselayer = this.getBaseLayers()[0];\n if (newBaselayer) {\n checkLayerInstance(newBaselayer);\n }\n this.#updateBaseLayer(newBaselayer);\n }\n model.destroy();\n this.emit(\"changed\");\n }\n\n #updateBaseLayer(model: LayerType | undefined) {\n if (this.#activeBaseLayer === model) {\n return;\n }\n\n if (LOG.isDebug()) {\n const getId = (model: AbstractLayer | undefined) => {\n return model ? `'${model.id}'` : undefined;\n };\n\n LOG.debug(\n `Switching active base layer from ${getId(this.#activeBaseLayer)} to ${getId(\n model\n )}`\n );\n }\n this.#activeBaseLayer?.__setVisible(false);\n this.#activeBaseLayer = model;\n this.#activeBaseLayer?.__setVisible(true);\n }\n\n /**\n * Index the layer and all its children.\n */\n #indexLayer(model: LayerType) {\n // layer id -> layer (or sublayer)\n const registrations: [string, OlBaseLayer | undefined][] = [];\n const visit = (model: LayerType | (AbstractLayerBase & Sublayer)) => {\n const id = model.id;\n const olLayer = \"olLayer\" in model ? model.olLayer : undefined;\n if (this.#layersById.has(id)) {\n throw new Error(\n `Layer id '${id}' is not unique. Either assign a unique id yourself ` +\n `or skip configuring 'id' for an automatically generated id.`\n );\n }\n if (olLayer && this.#layersByOlLayer.has(olLayer)) {\n throw new Error(`OlLayer has already been used in this or another layer.`);\n }\n\n // Register this layer with the maps.\n this.#layersById.set(id, model);\n if (olLayer) {\n this.#layersByOlLayer.set(olLayer, model as LayerType); // ol is present --> not a sublayer\n }\n registrations.push([id, olLayer]);\n\n // Recurse into nested sublayers.\n for (const sublayer of model.sublayers?.__getRawSublayers() ?? []) {\n visit(sublayer);\n }\n };\n\n try {\n visit(model);\n } catch (e) {\n for (const [id, olLayer] of registrations) {\n this.#layersById.delete(id);\n if (olLayer) {\n this.#layersByOlLayer.delete(olLayer);\n }\n }\n throw e;\n }\n }\n\n /**\n * Removes index entries for the given layer and all its sublayers.\n */\n #unIndexLayer(model: AbstractLayer) {\n const visit = (model: AbstractLayer | AbstractLayerBase) => {\n if (\"olLayer\" in model) {\n this.#layersByOlLayer.delete(model.olLayer);\n }\n this.#layersById.delete(model.id);\n for (const sublayer of model.sublayers?.__getRawSublayers() ?? []) {\n visit(sublayer);\n }\n };\n visit(model);\n }\n}\n\nfunction sortLayersByDisplayOrder(layers: Layer[]) {\n layers.sort((left, right) => {\n // currently layers are added with increasing z-index (base layers: 0), so\n // ordering by z-index is automatically the correct display order.\n // we use the id as the tie breaker for equal z-indices.\n const leftZ = left.olLayer.getZIndex() ?? 1;\n const rightZ = right.olLayer.getZIndex() ?? 1;\n if (leftZ !== rightZ) {\n return leftZ - rightZ;\n }\n return left.id.localeCompare(right.id, \"en\");\n });\n}\n\nfunction checkLayerInstance(object: Layer): asserts object is Layer & AbstractLayer {\n if (!(object instanceof AbstractLayer)) {\n throw new Error(\n `Layer is not a valid layer instance. Use one of the classes provided by the map package instead.`\n );\n }\n}\n"],"names":["model"],"mappings":";;;AAgBA,MAAM,GAAA,GAAM,aAAa,qBAAqB,CAAA,CAAA;AAE9C,MAAM,YAAe,GAAA,CAAA,CAAA;AACrB,MAAM,yBAA4B,GAAA,CAAA,CAAA;AAW3B,MAAM,eAAkB,GAAA,QAAA;AAExB,MAAM,4BACD,YAEZ,CAAA;AAAA,EACI,IAAA,CAAA;AAAA;AAAA,EAGA,eAAA,uBAAsB,GAAe,EAAA,CAAA;AAAA;AAAA,EAGrC,WAAA,uBAAkB,GAA2B,EAAA,CAAA;AAAA;AAAA,EAG7C,gBAAA,uBAAwD,OAAQ,EAAA,CAAA;AAAA;AAAA,EAGhE,gBAAA,CAAA;AAAA;AAAA,EAGA,UAAa,GAAA,yBAAA,CAAA;AAAA,EAEb,YAAY,GAAmB,EAAA;AAC3B,IAAM,KAAA,EAAA,CAAA;AACN,IAAA,IAAA,CAAK,IAAO,GAAA,GAAA,CAAA;AAAA,GAChB;AAAA,EAEA,OAAU,GAAA;AAEN,IAAA,KAAA,MAAW,KAAS,IAAA,IAAA,CAAK,WAAY,CAAA,MAAA,EAAU,EAAA;AAC3C,MAAA,KAAA,CAAM,OAAQ,EAAA,CAAA;AAAA,KAClB;AACA,IAAA,IAAA,CAAK,gBAAgB,KAAM,EAAA,CAAA;AAC3B,IAAA,IAAA,CAAK,YAAY,KAAM,EAAA,CAAA;AACvB,IAAA,IAAA,CAAK,gBAAmB,GAAA,KAAA,CAAA,CAAA;AAAA,GAC5B;AAAA,EAEA,SAAS,KAAoB,EAAA;AACzB,IAAA,kBAAA,CAAmB,KAAK,CAAA,CAAA;AAExB,IAAM,KAAA,CAAA,QAAA,CAAS,KAAK,IAAI,CAAA,CAAA;AACxB,IAAA,IAAA,CAAK,UAAU,KAAK,CAAA,CAAA;AAAA,GACxB;AAAA,EAEA,aAAyB,GAAA;AACrB,IAAA,OAAO,KAAK,YAAa,EAAA,CAAE,OAAO,CAAC,KAAA,KAAU,MAAM,WAAW,CAAA,CAAA;AAAA,GAClE;AAAA,EAEA,kBAAwC,GAAA;AACpC,IAAA,OAAO,IAAK,CAAA,gBAAA,CAAA;AAAA,GAChB;AAAA,EAEA,kBAAkB,EAAiC,EAAA;AAC/C,IAAA,IAAI,YAAe,GAAA,KAAA,CAAA,CAAA;AACnB,IAAA,IAAI,MAAM,IAAM,EAAA;AACZ,MAAe,YAAA,GAAA,IAAA,CAAK,WAAY,CAAA,GAAA,CAAI,EAAE,CAAA,CAAA;AACtC,MAAI,IAAA,EAAE,wBAAwB,aAAgB,CAAA,EAAA;AAC1C,QAAI,GAAA,CAAA,IAAA,CAAK,CAA+B,4BAAA,EAAA,EAAE,CAA+B,6BAAA,CAAA,CAAA,CAAA;AACzE,QAAO,OAAA,KAAA,CAAA;AAAA,OACX;AACA,MAAA,IAAI,CAAC,YAAc,EAAA;AACf,QAAI,GAAA,CAAA,IAAA,CAAK,CAA+B,4BAAA,EAAA,EAAE,CAAsB,oBAAA,CAAA,CAAA,CAAA;AAChE,QAAO,OAAA,KAAA,CAAA;AAAA,OACX;AACA,MAAI,IAAA,CAAC,aAAa,WAAa,EAAA;AAC3B,QAAI,GAAA,CAAA,IAAA,CAAK,CAA+B,4BAAA,EAAA,EAAE,CAA+B,6BAAA,CAAA,CAAA,CAAA;AACzE,QAAO,OAAA,KAAA,CAAA;AAAA,OACX;AAAA,KACJ;AAEA,IAAI,IAAA,YAAA,KAAiB,KAAK,gBAAkB,EAAA;AACxC,MAAA,IAAA,CAAK,iBAAiB,YAAY,CAAA,CAAA;AAClC,MAAA,IAAA,CAAK,KAAK,SAAS,CAAA,CAAA;AAAA,KACvB;AACA,IAAO,OAAA,IAAA,CAAA;AAAA,GACX;AAAA,EAEA,qBAAqB,OAA0C,EAAA;AAC3D,IAAO,OAAA,IAAA,CAAK,aAAa,OAAO,CAAA,CAAE,OAAO,CAAC,KAAA,KAAU,CAAC,KAAA,CAAM,WAAW,CAAA,CAAA;AAAA,GAC1E;AAAA,EAEA,aAAa,OAA0C,EAAA;AACnD,IAAA,MAAM,SAAS,KAAM,CAAA,IAAA,CAAK,IAAK,CAAA,eAAA,CAAgB,QAAQ,CAAA,CAAA;AACvD,IAAA,IAAI,SAAS,kBAAoB,EAAA;AAC7B,MAAA,wBAAA,CAAyB,MAAM,CAAA,CAAA;AAAA,KACnC;AACA,IAAO,OAAA,MAAA,CAAA;AAAA,GACX;AAAA,EAEA,aAAa,EAAkC,EAAA;AAC3C,IAAO,OAAA,IAAA,CAAK,WAAY,CAAA,GAAA,CAAI,EAAE,CAAA,CAAA;AAAA,GAClC;AAAA,EAEA,gBAAgB,EAAkB,EAAA;AAC9B,IAAA,MAAM,KAAQ,GAAA,IAAA,CAAK,WAAY,CAAA,GAAA,CAAI,EAAE,CAAA,CAAA;AACrC,IAAA,IAAI,CAAC,KAAO,EAAA;AACR,MAAA,GAAA,CAAI,SAAa,IAAA,GAAA,CAAI,KAAM,CAAA,CAAA,qBAAA,EAAwB,EAAE,CAAsB,oBAAA,CAAA,CAAA,CAAA;AAC3E,MAAA,OAAA;AAAA,KACJ;AAEA,IAAA,IAAA,CAAK,aAAa,KAAK,CAAA,CAAA;AAAA,GAC3B;AAAA,EAEA,sBAAsB,KAAuC,EAAA;AACzD,IAAO,OAAA,IAAA,CAAK,gBAAkB,EAAA,GAAA,CAAI,KAAK,CAAA,CAAA;AAAA,GAC3C;AAAA;AAAA;AAAA;AAAA,EAKA,UAAU,KAAkB,EAAA;AACxB,IAAA,IAAA,CAAK,YAAY,KAAK,CAAA,CAAA;AAEtB,IAAA,MAAM,UAAU,KAAM,CAAA,OAAA,CAAA;AACtB,IAAA,IAAI,MAAM,WAAa,EAAA;AACnB,MAAA,OAAA,CAAQ,UAAU,YAAY,CAAA,CAAA;AAC9B,MAAA,IAAI,CAAC,IAAA,CAAK,gBAAoB,IAAA,KAAA,CAAM,OAAS,EAAA;AACzC,QAAA,IAAA,CAAK,iBAAiB,KAAK,CAAA,CAAA;AAAA,OACxB,MAAA;AACH,QAAA,KAAA,CAAM,aAAa,KAAK,CAAA,CAAA;AAAA,OAC5B;AAAA,KACG,MAAA;AACH,MAAQ,OAAA,CAAA,SAAA,CAAU,KAAK,UAAY,EAAA,CAAA,CAAA;AACnC,MAAM,KAAA,CAAA,YAAA,CAAa,MAAM,OAAO,CAAA,CAAA;AAAA,KACpC;AAEA,IAAK,IAAA,CAAA,eAAA,CAAgB,IAAI,KAAK,CAAA,CAAA;AAC9B,IAAK,IAAA,CAAA,IAAA,CAAK,KAAM,CAAA,QAAA,CAAS,OAAO,CAAA,CAAA;AAChC,IAAA,IAAA,CAAK,KAAK,SAAS,CAAA,CAAA;AAAA,GACvB;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,aAAa,KAAkC,EAAA;AAE3C,IAAA,IAAI,CAAC,IAAA,CAAK,eAAgB,CAAA,GAAA,CAAI,KAAY,CAAG,EAAA;AACzC,MAAI,GAAA,CAAA,IAAA;AAAA,QACA,CAAA,qBAAA,EAAwB,MAAM,EAAE,CAAA,qDAAA,CAAA;AAAA,OACpC,CAAA;AACA,MAAA,OAAA;AAAA,KACJ;AAEA,IAAI,IAAA,EAAE,iBAAiB,aAAgB,CAAA,EAAA;AACnC,MAAA,MAAM,IAAI,KAAA;AAAA,QACN,CAAA,4EAAA,CAAA;AAAA,OACJ,CAAA;AAAA,KACJ;AAEA,IAAA,IAAA,CAAK,IAAK,CAAA,KAAA,CAAM,WAAY,CAAA,KAAA,CAAM,OAAO,CAAA,CAAA;AACzC,IAAK,IAAA,CAAA,eAAA,CAAgB,OAAO,KAAK,CAAA,CAAA;AACjC,IAAA,IAAA,CAAK,cAAc,KAAK,CAAA,CAAA;AACxB,IAAI,IAAA,IAAA,CAAK,qBAAqB,KAAO,EAAA;AACjC,MAAA,MAAM,YAAe,GAAA,IAAA,CAAK,aAAc,EAAA,CAAE,CAAC,CAAA,CAAA;AAC3C,MAAA,IAAI,YAAc,EAAA;AACd,QAAA,kBAAA,CAAmB,YAAY,CAAA,CAAA;AAAA,OACnC;AACA,MAAA,IAAA,CAAK,iBAAiB,YAAY,CAAA,CAAA;AAAA,KACtC;AACA,IAAA,KAAA,CAAM,OAAQ,EAAA,CAAA;AACd,IAAA,IAAA,CAAK,KAAK,SAAS,CAAA,CAAA;AAAA,GACvB;AAAA,EAEA,iBAAiB,KAA8B,EAAA;AAC3C,IAAI,IAAA,IAAA,CAAK,qBAAqB,KAAO,EAAA;AACjC,MAAA,OAAA;AAAA,KACJ;AAEA,IAAI,IAAA,GAAA,CAAI,SAAW,EAAA;AACf,MAAM,MAAA,KAAA,GAAQ,CAACA,MAAqC,KAAA;AAChD,QAAA,OAAOA,MAAQ,GAAA,CAAA,CAAA,EAAIA,MAAM,CAAA,EAAE,CAAM,CAAA,CAAA,GAAA,KAAA,CAAA,CAAA;AAAA,OACrC,CAAA;AAEA,MAAI,GAAA,CAAA,KAAA;AAAA,QACA,CAAoC,iCAAA,EAAA,KAAA,CAAM,IAAK,CAAA,gBAAgB,CAAC,CAAO,IAAA,EAAA,KAAA;AAAA,UACnE,KAAA;AAAA,SACH,CAAA,CAAA;AAAA,OACL,CAAA;AAAA,KACJ;AACA,IAAK,IAAA,CAAA,gBAAA,EAAkB,aAAa,KAAK,CAAA,CAAA;AACzC,IAAA,IAAA,CAAK,gBAAmB,GAAA,KAAA,CAAA;AACxB,IAAK,IAAA,CAAA,gBAAA,EAAkB,aAAa,IAAI,CAAA,CAAA;AAAA,GAC5C;AAAA;AAAA;AAAA;AAAA,EAKA,YAAY,KAAkB,EAAA;AAE1B,IAAA,MAAM,gBAAqD,EAAC,CAAA;AAC5D,IAAM,MAAA,KAAA,GAAQ,CAACA,MAAsD,KAAA;AACjE,MAAA,MAAM,KAAKA,MAAM,CAAA,EAAA,CAAA;AACjB,MAAA,MAAM,OAAU,GAAA,SAAA,IAAaA,MAAQA,GAAAA,MAAAA,CAAM,OAAU,GAAA,KAAA,CAAA,CAAA;AACrD,MAAA,IAAI,IAAK,CAAA,WAAA,CAAY,GAAI,CAAA,EAAE,CAAG,EAAA;AAC1B,QAAA,MAAM,IAAI,KAAA;AAAA,UACN,aAAa,EAAE,CAAA,+GAAA,CAAA;AAAA,SAEnB,CAAA;AAAA,OACJ;AACA,MAAA,IAAI,OAAW,IAAA,IAAA,CAAK,gBAAiB,CAAA,GAAA,CAAI,OAAO,CAAG,EAAA;AAC/C,QAAM,MAAA,IAAI,MAAM,CAAyD,uDAAA,CAAA,CAAA,CAAA;AAAA,OAC7E;AAGA,MAAK,IAAA,CAAA,WAAA,CAAY,GAAI,CAAA,EAAA,EAAIA,MAAK,CAAA,CAAA;AAC9B,MAAA,IAAI,OAAS,EAAA;AACT,QAAK,IAAA,CAAA,gBAAA,CAAiB,GAAI,CAAA,OAAA,EAASA,MAAkB,CAAA,CAAA;AAAA,OACzD;AACA,MAAA,aAAA,CAAc,IAAK,CAAA,CAAC,EAAI,EAAA,OAAO,CAAC,CAAA,CAAA;AAGhC,MAAA,KAAA,MAAW,YAAYA,MAAM,CAAA,SAAA,EAAW,iBAAkB,EAAA,IAAK,EAAI,EAAA;AAC/D,QAAA,KAAA,CAAM,QAAQ,CAAA,CAAA;AAAA,OAClB;AAAA,KACJ,CAAA;AAEA,IAAI,IAAA;AACA,MAAA,KAAA,CAAM,KAAK,CAAA,CAAA;AAAA,aACN,CAAG,EAAA;AACR,MAAA,KAAA,MAAW,CAAC,EAAA,EAAI,OAAO,CAAA,IAAK,aAAe,EAAA;AACvC,QAAK,IAAA,CAAA,WAAA,CAAY,OAAO,EAAE,CAAA,CAAA;AAC1B,QAAA,IAAI,OAAS,EAAA;AACT,UAAK,IAAA,CAAA,gBAAA,CAAiB,OAAO,OAAO,CAAA,CAAA;AAAA,SACxC;AAAA,OACJ;AACA,MAAM,MAAA,CAAA,CAAA;AAAA,KACV;AAAA,GACJ;AAAA;AAAA;AAAA;AAAA,EAKA,cAAc,KAAsB,EAAA;AAChC,IAAM,MAAA,KAAA,GAAQ,CAACA,MAA6C,KAAA;AACxD,MAAA,IAAI,aAAaA,MAAO,EAAA;AACpB,QAAK,IAAA,CAAA,gBAAA,CAAiB,MAAOA,CAAAA,MAAAA,CAAM,OAAO,CAAA,CAAA;AAAA,OAC9C;AACA,MAAK,IAAA,CAAA,WAAA,CAAY,MAAOA,CAAAA,MAAAA,CAAM,EAAE,CAAA,CAAA;AAChC,MAAA,KAAA,MAAW,YAAYA,MAAM,CAAA,SAAA,EAAW,iBAAkB,EAAA,IAAK,EAAI,EAAA;AAC/D,QAAA,KAAA,CAAM,QAAQ,CAAA,CAAA;AAAA,OAClB;AAAA,KACJ,CAAA;AACA,IAAA,KAAA,CAAM,KAAK,CAAA,CAAA;AAAA,GACf;AACJ,CAAA;AAEA,SAAS,yBAAyB,MAAiB,EAAA;AAC/C,EAAO,MAAA,CAAA,IAAA,CAAK,CAAC,IAAA,EAAM,KAAU,KAAA;AAIzB,IAAA,MAAM,KAAQ,GAAA,IAAA,CAAK,OAAQ,CAAA,SAAA,EAAe,IAAA,CAAA,CAAA;AAC1C,IAAA,MAAM,MAAS,GAAA,KAAA,CAAM,OAAQ,CAAA,SAAA,EAAe,IAAA,CAAA,CAAA;AAC5C,IAAA,IAAI,UAAU,MAAQ,EAAA;AAClB,MAAA,OAAO,KAAQ,GAAA,MAAA,CAAA;AAAA,KACnB;AACA,IAAA,OAAO,IAAK,CAAA,EAAA,CAAG,aAAc,CAAA,KAAA,CAAM,IAAI,IAAI,CAAA,CAAA;AAAA,GAC9C,CAAA,CAAA;AACL,CAAA;AAEA,SAAS,mBAAmB,MAAwD,EAAA;AAChF,EAAI,IAAA,EAAE,kBAAkB,aAAgB,CAAA,EAAA;AACpC,IAAA,MAAM,IAAI,KAAA;AAAA,MACN,CAAA,gGAAA,CAAA;AAAA,KACJ,CAAA;AAAA,GACJ;AACJ;;;;"}
|
|
1
|
+
{"version":3,"file":"LayerCollectionImpl.js","sources":["LayerCollectionImpl.ts"],"sourcesContent":["// SPDX-FileCopyrightText: 2023 Open Pioneer project (https://github.com/open-pioneer)\n// SPDX-License-Identifier: Apache-2.0\nimport { batch, reactive, reactiveSet } from \"@conterra/reactivity-core\";\nimport { createLogger } from \"@open-pioneer/core\";\nimport OlBaseLayer from \"ol/layer/Base\";\nimport { Layer, LayerCollection, LayerRetrievalOptions, AnyLayer, Sublayer } from \"../api\";\nimport { AbstractLayer } from \"./AbstractLayer\";\nimport { AbstractLayerBase } from \"./AbstractLayerBase\";\nimport { MapModelImpl } from \"./MapModelImpl\";\n\nconst LOG = createLogger(\"map:LayerCollection\");\n\nconst BASE_LAYER_Z = 0;\nconst OPERATION_LAYER_INITIAL_Z = 1;\n\ntype LayerType = AbstractLayer & Layer;\ntype LayerBaseType = (AbstractLayerBase & Layer) | (AbstractLayerBase & Sublayer);\n\n/**\n * Z index for layers that should always be rendered on top of all other layers.\n * Note that this is an internal, unstable property!\n *\n * @internal\n */\nexport const TOPMOST_LAYER_Z = 9999999;\n\n/**\n * Manages the (top-level) content of the map.\n */\nexport class LayerCollectionImpl implements LayerCollection {\n #map: MapModelImpl;\n\n /** Top level layers (base layers, operational layers). No sublayers. */\n #topLevelLayers = reactiveSet<LayerType>();\n\n /** Index of _all_ layer instances, including sublayers. */\n #layersById = new Map<string, LayerBaseType>();\n\n /** Reverse index of _all_ layers that have an associated OpenLayers layer. */\n #layersByOlLayer: WeakMap<OlBaseLayer, LayerType> = new WeakMap();\n\n /** Currently active base layer. */\n #activeBaseLayer = reactive<LayerType>();\n\n /** next z-index for operational layer. currently just auto-increments. */\n #nextIndex = OPERATION_LAYER_INITIAL_Z;\n\n constructor(map: MapModelImpl) {\n this.#map = map;\n }\n\n destroy() {\n // Collection is destroyed together with the map, there is no need to clean up the olMap\n for (const layer of this.#layersById.values()) {\n layer.destroy();\n }\n this.#topLevelLayers.clear();\n this.#layersById.clear();\n this.#activeBaseLayer.value = undefined;\n }\n\n addLayer(layer: Layer): void {\n checkLayerInstance(layer);\n\n layer.__attachToMap(this.#map);\n this.#addLayer(layer);\n }\n\n getBaseLayers(): Layer[] {\n return this.getAllLayers().filter((layer) => layer.isBaseLayer);\n }\n\n getActiveBaseLayer(): Layer | undefined {\n return this.#activeBaseLayer.value;\n }\n\n activateBaseLayer(id: string | undefined): boolean {\n let newBaseLayer = undefined;\n if (id != null) {\n newBaseLayer = this.#layersById.get(id);\n if (!(newBaseLayer instanceof AbstractLayer)) {\n LOG.warn(`Cannot activate base layer '${id}: layer has an invalid type.'`);\n return false;\n }\n if (!newBaseLayer) {\n LOG.warn(`Cannot activate base layer '${id}': layer is unknown.`);\n return false;\n }\n if (!newBaseLayer.isBaseLayer) {\n LOG.warn(`Cannot activate base layer '${id}': layer is not a base layer.`);\n return false;\n }\n }\n\n this.#updateBaseLayer(newBaseLayer);\n return true;\n }\n\n getOperationalLayers(options?: LayerRetrievalOptions): Layer[] {\n return this.getAllLayers(options).filter((layer) => !layer.isBaseLayer);\n }\n\n getAllLayers(options?: LayerRetrievalOptions): Layer[] {\n const layers = Array.from(this.#topLevelLayers.values());\n if (options?.sortByDisplayOrder) {\n sortLayersByDisplayOrder(layers);\n }\n return layers;\n }\n\n getLayerById(id: string): AnyLayer | undefined {\n return this.#layersById.get(id);\n }\n\n removeLayerById(id: string): void {\n const model = this.#layersById.get(id);\n if (!model) {\n LOG.isDebug() && LOG.debug(`Cannot remove layer '${id}': layer is unknown.`);\n return;\n }\n\n this.#removeLayer(model);\n }\n\n getLayerByRawInstance(layer: OlBaseLayer): Layer | undefined {\n return this.#layersByOlLayer?.get(layer);\n }\n\n /**\n * Adds the given layer to the map and all relevant indices.\n */\n #addLayer(model: LayerType) {\n this.#indexLayer(model);\n\n const olLayer = model.olLayer;\n if (model.isBaseLayer) {\n olLayer.setZIndex(BASE_LAYER_Z);\n if (!this.#activeBaseLayer.value && model.visible) {\n this.#updateBaseLayer(model);\n } else {\n model.__setVisible(false);\n }\n } else {\n olLayer.setZIndex(this.#nextIndex++);\n model.__setVisible(model.visible);\n }\n\n this.#topLevelLayers.add(model);\n this.#map.olMap.addLayer(olLayer);\n }\n\n /**\n * Removes the given layer from the map and all relevant indices.\n * The layer will be destroyed.\n */\n #removeLayer(model: LayerType | LayerBaseType) {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n if (!this.#topLevelLayers.has(model as any)) {\n LOG.warn(\n `Cannot remove layer '${model.id}': only top level layers can be removed at this time.`\n );\n return;\n }\n\n if (!(model instanceof AbstractLayer)) {\n throw new Error(\n `Internal error: expected top level layer to be an instance of AbstractLayer.`\n );\n }\n\n this.#map.olMap.removeLayer(model.olLayer);\n this.#topLevelLayers.delete(model);\n this.#unIndexLayer(model);\n if (this.#activeBaseLayer.value === model) {\n const newBaselayer = this.getBaseLayers()[0];\n if (newBaselayer) {\n checkLayerInstance(newBaselayer);\n }\n this.#updateBaseLayer(newBaselayer);\n }\n model.destroy();\n }\n\n #updateBaseLayer(model: LayerType | undefined) {\n if (this.#activeBaseLayer.value === model) {\n return;\n }\n\n if (LOG.isDebug()) {\n const getId = (model: AbstractLayer | undefined) => {\n return model ? `'${model.id}'` : undefined;\n };\n\n LOG.debug(\n `Switching active base layer from ${getId(this.#activeBaseLayer.value)} to ${getId(model)}`\n );\n }\n\n batch(() => {\n this.#activeBaseLayer.value?.__setVisible(false);\n this.#activeBaseLayer.value = model;\n model?.__setVisible(true);\n });\n }\n\n /**\n * Index the layer and all its children.\n */\n #indexLayer(model: LayerType) {\n // layer id -> layer (or sublayer)\n const registrations: [string, OlBaseLayer | undefined][] = [];\n const visit = (model: LayerType | (AbstractLayerBase & Sublayer)) => {\n const id = model.id;\n const olLayer = \"olLayer\" in model ? model.olLayer : undefined;\n if (this.#layersById.has(id)) {\n throw new Error(\n `Layer id '${id}' is not unique. Either assign a unique id yourself ` +\n `or skip configuring 'id' for an automatically generated id.`\n );\n }\n if (olLayer && this.#layersByOlLayer.has(olLayer)) {\n throw new Error(`OlLayer used by layer '${id}' has already been used in map.`);\n }\n\n // Register this layer with the maps.\n this.#layersById.set(id, model);\n if (olLayer) {\n this.#layersByOlLayer.set(olLayer, model as LayerType); // ol is present --> not a sublayer\n }\n registrations.push([id, olLayer]);\n\n // Recurse into nested children.\n for (const layer of model.layers?.__getRawLayers() ?? []) {\n visit(layer);\n }\n for (const sublayer of model.sublayers?.__getRawSublayers() ?? []) {\n visit(sublayer);\n }\n };\n\n try {\n visit(model);\n } catch (e) {\n // If any error happens, undo the indexing.\n // This way we don't leave a partially indexed layer tree behind.\n for (const [id, olLayer] of registrations) {\n this.#layersById.delete(id);\n if (olLayer) {\n this.#layersByOlLayer.delete(olLayer);\n }\n }\n throw e;\n }\n }\n\n /**\n * Removes index entries for the given layer and all its children.\n */\n #unIndexLayer(model: AbstractLayer) {\n const visit = (model: AbstractLayer | AbstractLayerBase) => {\n if (\"olLayer\" in model) {\n this.#layersByOlLayer.delete(model.olLayer);\n }\n this.#layersById.delete(model.id);\n\n for (const layer of model.layers?.__getRawLayers() ?? []) {\n visit(layer);\n }\n\n for (const sublayer of model.sublayers?.__getRawSublayers() ?? []) {\n visit(sublayer);\n }\n };\n visit(model);\n }\n}\n\nfunction sortLayersByDisplayOrder(layers: Layer[]) {\n layers.sort((left, right) => {\n // currently layers are added with increasing z-index (base layers: 0), so\n // ordering by z-index is automatically the correct display order.\n const leftZ = left.olLayer.getZIndex() ?? 1;\n const rightZ = right.olLayer.getZIndex() ?? 1;\n return leftZ - rightZ;\n });\n}\n\nfunction checkLayerInstance(object: Layer): asserts object is Layer & AbstractLayer {\n if (!(object instanceof AbstractLayer)) {\n throw new Error(\n `Layer is not a valid layer instance. Use one of the classes provided by the map package instead.`\n );\n }\n}\n"],"names":["model"],"mappings":"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"}
|
package/model/MapModelImpl.d.ts
CHANGED
|
@@ -1,9 +1,12 @@
|
|
|
1
1
|
import { EventEmitter } from "@open-pioneer/core";
|
|
2
|
+
import { HttpService } from "@open-pioneer/http";
|
|
2
3
|
import OlMap from "ol/Map";
|
|
4
|
+
import OlView from "ol/View";
|
|
5
|
+
import { Coordinate } from "ol/coordinate";
|
|
6
|
+
import { Geometry } from "ol/geom";
|
|
7
|
+
import { Projection } from "ol/proj";
|
|
3
8
|
import { ExtentConfig, Highlight, HighlightOptions, HighlightZoomOptions, MapModel, MapModelEvents } from "../api";
|
|
4
9
|
import { LayerCollectionImpl } from "./LayerCollectionImpl";
|
|
5
|
-
import { Geometry } from "ol/geom";
|
|
6
|
-
import { HttpService } from "@open-pioneer/http";
|
|
7
10
|
/**
|
|
8
11
|
* Shared services or other entities propagated from the map model to all layer instances.
|
|
9
12
|
*/
|
|
@@ -21,10 +24,17 @@ export declare class MapModelImpl extends EventEmitter<MapModelEvents> implement
|
|
|
21
24
|
destroy(): void;
|
|
22
25
|
get id(): string;
|
|
23
26
|
get olMap(): OlMap;
|
|
27
|
+
get olView(): OlView;
|
|
28
|
+
get projection(): Projection;
|
|
29
|
+
get center(): Coordinate | undefined;
|
|
30
|
+
get resolution(): number | undefined;
|
|
31
|
+
get zoomLevel(): number | undefined;
|
|
32
|
+
get scale(): number | undefined;
|
|
24
33
|
get layers(): LayerCollectionImpl;
|
|
25
34
|
get container(): HTMLElement | undefined;
|
|
26
35
|
get initialExtent(): ExtentConfig | undefined;
|
|
27
36
|
get __sharedDependencies(): SharedDependencies;
|
|
37
|
+
setScale(newScale: number): void;
|
|
28
38
|
highlight(geometries: Geometry[], options?: HighlightOptions | undefined): Highlight;
|
|
29
39
|
zoom(geometries: Geometry[], options?: HighlightZoomOptions | undefined): void;
|
|
30
40
|
highlightAndZoom(geometries: Geometry[], options?: HighlightZoomOptions): {
|
package/model/MapModelImpl.js
CHANGED
|
@@ -1,20 +1,26 @@
|
|
|
1
|
+
import { reactive, synchronized, computed } from '@conterra/reactivity-core';
|
|
1
2
|
import { createLogger, EventEmitter, isAbortError, createManualPromise, createAbortError } from '@open-pioneer/core';
|
|
2
3
|
import { unByKey } from 'ol/Observable.js';
|
|
3
4
|
import { getCenter } from 'ol/extent.js';
|
|
4
|
-
import {
|
|
5
|
+
import { getPointResolution } from 'ol/proj.js';
|
|
5
6
|
import { Highlights } from './Highlights.js';
|
|
7
|
+
import { LayerCollectionImpl } from './LayerCollectionImpl.js';
|
|
6
8
|
|
|
7
9
|
const LOG = createLogger("map:MapModel");
|
|
10
|
+
const DEFAULT_DPI = 25.4 / 0.28;
|
|
11
|
+
const INCHES_PER_METRE = 39.37;
|
|
8
12
|
class MapModelImpl extends EventEmitter {
|
|
9
13
|
#id;
|
|
10
14
|
#olMap;
|
|
15
|
+
#olView;
|
|
11
16
|
#layers = new LayerCollectionImpl(this);
|
|
12
17
|
#highlights;
|
|
13
18
|
#sharedDeps;
|
|
14
19
|
#destroyed = false;
|
|
15
20
|
#container;
|
|
16
|
-
#initialExtent;
|
|
17
|
-
#
|
|
21
|
+
#initialExtent = reactive();
|
|
22
|
+
#viewBindings;
|
|
23
|
+
#scale;
|
|
18
24
|
#abortController = new AbortController();
|
|
19
25
|
#displayStatus;
|
|
20
26
|
#displayWaiter;
|
|
@@ -22,7 +28,14 @@ class MapModelImpl extends EventEmitter {
|
|
|
22
28
|
super();
|
|
23
29
|
this.#id = properties.id;
|
|
24
30
|
this.#olMap = properties.olMap;
|
|
25
|
-
this.#
|
|
31
|
+
this.#olView = synchronized(
|
|
32
|
+
() => this.#olMap.getView(),
|
|
33
|
+
(cb) => {
|
|
34
|
+
const key = this.#olMap.on("change:view", cb);
|
|
35
|
+
return () => unByKey(key);
|
|
36
|
+
}
|
|
37
|
+
);
|
|
38
|
+
this.#initialExtent.value = properties.initialExtent;
|
|
26
39
|
this.#sharedDeps = {
|
|
27
40
|
httpService: properties.httpService
|
|
28
41
|
};
|
|
@@ -43,8 +56,22 @@ class MapModelImpl extends EventEmitter {
|
|
|
43
56
|
this.#displayWaiter = void 0;
|
|
44
57
|
}
|
|
45
58
|
);
|
|
46
|
-
this.#
|
|
47
|
-
this.#
|
|
59
|
+
this.#container = synchronized(
|
|
60
|
+
() => this.#olMap.getTargetElement() ?? void 0,
|
|
61
|
+
(cb) => {
|
|
62
|
+
const key = this.#olMap.on("change:target", cb);
|
|
63
|
+
return () => unByKey(key);
|
|
64
|
+
}
|
|
65
|
+
);
|
|
66
|
+
this.#viewBindings = computed(() => createViewBindings(this.#olView.value));
|
|
67
|
+
this.#scale = computed(() => {
|
|
68
|
+
const { projection, resolution, center } = this;
|
|
69
|
+
if (projection == null || resolution == null || center == null) {
|
|
70
|
+
return void 0;
|
|
71
|
+
}
|
|
72
|
+
const pointResolution = getPointResolution(projection, resolution, center);
|
|
73
|
+
const scale = Math.round(pointResolution * INCHES_PER_METRE * DEFAULT_DPI);
|
|
74
|
+
return scale;
|
|
48
75
|
});
|
|
49
76
|
}
|
|
50
77
|
destroy() {
|
|
@@ -57,10 +84,6 @@ class MapModelImpl extends EventEmitter {
|
|
|
57
84
|
} catch (e) {
|
|
58
85
|
LOG.warn(`Unexpected error from event listener during map model destruction:`, e);
|
|
59
86
|
}
|
|
60
|
-
if (this.#targetWatchKey) {
|
|
61
|
-
unByKey(this.#targetWatchKey);
|
|
62
|
-
}
|
|
63
|
-
this.#targetWatchKey = void 0;
|
|
64
87
|
this.#abortController.abort();
|
|
65
88
|
this.#displayWaiter?.reject(new Error("Map model was destroyed."));
|
|
66
89
|
this.#layers.destroy();
|
|
@@ -73,18 +96,48 @@ class MapModelImpl extends EventEmitter {
|
|
|
73
96
|
get olMap() {
|
|
74
97
|
return this.#olMap;
|
|
75
98
|
}
|
|
99
|
+
get olView() {
|
|
100
|
+
return this.#olView.value;
|
|
101
|
+
}
|
|
102
|
+
get projection() {
|
|
103
|
+
return this.#viewBindings.value.projection;
|
|
104
|
+
}
|
|
105
|
+
get center() {
|
|
106
|
+
return this.#viewBindings.value.center.value;
|
|
107
|
+
}
|
|
108
|
+
get resolution() {
|
|
109
|
+
return this.#viewBindings.value.resolution.value;
|
|
110
|
+
}
|
|
111
|
+
get zoomLevel() {
|
|
112
|
+
return this.#viewBindings.value.zoom.value;
|
|
113
|
+
}
|
|
114
|
+
get scale() {
|
|
115
|
+
return this.#scale.value;
|
|
116
|
+
}
|
|
76
117
|
get layers() {
|
|
77
118
|
return this.#layers;
|
|
78
119
|
}
|
|
79
120
|
get container() {
|
|
80
|
-
return this.#container;
|
|
121
|
+
return this.#container.value;
|
|
81
122
|
}
|
|
82
123
|
get initialExtent() {
|
|
83
|
-
return this.#initialExtent;
|
|
124
|
+
return this.#initialExtent.value;
|
|
84
125
|
}
|
|
85
126
|
get __sharedDependencies() {
|
|
86
127
|
return this.#sharedDeps;
|
|
87
128
|
}
|
|
129
|
+
setScale(newScale) {
|
|
130
|
+
const view = this.olView;
|
|
131
|
+
const projection = this.projection;
|
|
132
|
+
const center = this.center;
|
|
133
|
+
if (!center) {
|
|
134
|
+
return;
|
|
135
|
+
}
|
|
136
|
+
const mpu = projection.getMetersPerUnit() ?? 1;
|
|
137
|
+
const resolution = INCHES_PER_METRE * DEFAULT_DPI * mpu;
|
|
138
|
+
const pointResolution = newScale / getPointResolution(projection, resolution, center);
|
|
139
|
+
view.setResolution(pointResolution);
|
|
140
|
+
}
|
|
88
141
|
highlight(geometries, options) {
|
|
89
142
|
return this.#highlights.addHighlight(geometries, options);
|
|
90
143
|
}
|
|
@@ -128,8 +181,8 @@ class MapModelImpl extends EventEmitter {
|
|
|
128
181
|
try {
|
|
129
182
|
const olMap = this.#olMap;
|
|
130
183
|
const view = olMap.getView();
|
|
131
|
-
if (this.#initialExtent) {
|
|
132
|
-
const extent = this.#initialExtent;
|
|
184
|
+
if (this.#initialExtent.value) {
|
|
185
|
+
const extent = this.#initialExtent.value;
|
|
133
186
|
const olExtent = [extent.xMin, extent.yMin, extent.xMax, extent.yMax];
|
|
134
187
|
const olCenter = getCenter(olExtent);
|
|
135
188
|
const resolution = view.getResolutionForExtent(olExtent);
|
|
@@ -143,22 +196,38 @@ class MapModelImpl extends EventEmitter {
|
|
|
143
196
|
const [xMin = 0, yMin = 0, xMax = 0, yMax = 0] = olExtent;
|
|
144
197
|
const extent = { xMin, yMin, xMax, yMax };
|
|
145
198
|
LOG.debug(`Detected initial extent`, extent);
|
|
146
|
-
this.#initialExtent = extent;
|
|
147
|
-
this.emit("changed:initialExtent");
|
|
148
|
-
this.emit("changed");
|
|
199
|
+
this.#initialExtent.value = extent;
|
|
149
200
|
}
|
|
150
201
|
} catch (e) {
|
|
151
202
|
throw new Error(`Failed to apply the initial extent.`, { cause: e });
|
|
152
203
|
}
|
|
153
204
|
}
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
205
|
+
}
|
|
206
|
+
function createViewBindings(view) {
|
|
207
|
+
return {
|
|
208
|
+
resolution: synchronized(
|
|
209
|
+
() => view.getResolution(),
|
|
210
|
+
(cb) => {
|
|
211
|
+
const key = view.on("change:resolution", cb);
|
|
212
|
+
return () => unByKey(key);
|
|
213
|
+
}
|
|
214
|
+
),
|
|
215
|
+
center: synchronized(
|
|
216
|
+
() => view.getCenter(),
|
|
217
|
+
(cb) => {
|
|
218
|
+
const key = view.on("change:center", cb);
|
|
219
|
+
return () => unByKey(key);
|
|
220
|
+
}
|
|
221
|
+
),
|
|
222
|
+
zoom: synchronized(
|
|
223
|
+
() => view.getZoom(),
|
|
224
|
+
(cb) => {
|
|
225
|
+
const key = view.on("change:resolution", cb);
|
|
226
|
+
return () => unByKey(key);
|
|
227
|
+
}
|
|
228
|
+
),
|
|
229
|
+
projection: view.getProjection()
|
|
230
|
+
};
|
|
162
231
|
}
|
|
163
232
|
function waitForMapSize(olMap, signal) {
|
|
164
233
|
const promise = new Promise((resolve, reject) => {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MapModelImpl.js","sources":["MapModelImpl.ts"],"sourcesContent":["// SPDX-FileCopyrightText: 2023 Open Pioneer project (https://github.com/open-pioneer)\n// SPDX-License-Identifier: Apache-2.0\nimport {\n EventEmitter,\n ManualPromise,\n createAbortError,\n createLogger,\n createManualPromise,\n isAbortError\n} from \"@open-pioneer/core\";\nimport OlMap from \"ol/Map\";\nimport { unByKey } from \"ol/Observable\";\nimport { EventsKey } from \"ol/events\";\nimport { getCenter } from \"ol/extent\";\nimport {\n ExtentConfig,\n Highlight,\n HighlightOptions,\n HighlightZoomOptions,\n MapModel,\n MapModelEvents\n} from \"../api\";\nimport { LayerCollectionImpl } from \"./LayerCollectionImpl\";\nimport { Geometry } from \"ol/geom\";\nimport { Highlights } from \"./Highlights\";\nimport { HttpService } from \"@open-pioneer/http\";\n\nconst LOG = createLogger(\"map:MapModel\");\n\n/**\n * Shared services or other entities propagated from the map model to all layer instances.\n */\nexport interface SharedDependencies {\n httpService: HttpService;\n}\n\nexport class MapModelImpl extends EventEmitter<MapModelEvents> implements MapModel {\n readonly #id: string;\n readonly #olMap: OlMap;\n readonly #layers = new LayerCollectionImpl(this);\n readonly #highlights: Highlights;\n readonly #sharedDeps: SharedDependencies;\n\n #destroyed = false;\n #container: HTMLElement | undefined;\n #initialExtent: ExtentConfig | undefined;\n #targetWatchKey: EventsKey | undefined;\n\n readonly #abortController = new AbortController();\n #displayStatus: \"waiting\" | \"ready\" | \"error\";\n #displayWaiter: ManualPromise<void> | undefined;\n\n constructor(properties: {\n id: string;\n olMap: OlMap;\n initialExtent: ExtentConfig | undefined;\n httpService: HttpService;\n }) {\n super();\n this.#id = properties.id;\n this.#olMap = properties.olMap;\n this.#initialExtent = properties.initialExtent;\n this.#sharedDeps = {\n httpService: properties.httpService\n };\n this.#highlights = new Highlights(this.#olMap);\n\n this.#displayStatus = \"waiting\";\n this.#initializeView().then(\n () => {\n this.#displayStatus = \"ready\";\n this.#displayWaiter?.resolve();\n this.#displayWaiter = undefined;\n },\n (error) => {\n if (!isAbortError(error)) {\n LOG.error(`Failed to initialize map`, error);\n }\n\n this.#displayStatus = \"error\";\n this.#displayWaiter?.reject(new Error(`Failed to initialize map.`));\n this.#displayWaiter = undefined;\n }\n );\n this.#targetWatchKey = this.#olMap.on(\"change:target\", () => {\n this.#onTargetChanged();\n });\n }\n\n destroy() {\n if (this.#destroyed) {\n return;\n }\n\n this.#destroyed = true;\n try {\n this.emit(\"destroy\");\n } catch (e) {\n LOG.warn(`Unexpected error from event listener during map model destruction:`, e);\n }\n\n if (this.#targetWatchKey) {\n unByKey(this.#targetWatchKey);\n }\n this.#targetWatchKey = undefined;\n this.#abortController.abort();\n this.#displayWaiter?.reject(new Error(\"Map model was destroyed.\"));\n this.#layers.destroy();\n this.#highlights.destroy();\n this.#olMap.dispose();\n }\n\n get id(): string {\n return this.#id;\n }\n\n get olMap(): OlMap {\n return this.#olMap;\n }\n\n get layers(): LayerCollectionImpl {\n return this.#layers;\n }\n\n get container(): HTMLElement | undefined {\n return this.#container;\n }\n\n get initialExtent(): ExtentConfig | undefined {\n return this.#initialExtent;\n }\n\n get __sharedDependencies(): SharedDependencies {\n return this.#sharedDeps;\n }\n\n highlight(geometries: Geometry[], options?: HighlightOptions | undefined): Highlight {\n return this.#highlights.addHighlight(geometries, options);\n }\n zoom(geometries: Geometry[], options?: HighlightZoomOptions | undefined): void {\n this.#highlights.zoomToHighlight(geometries, options);\n }\n\n highlightAndZoom(geometries: Geometry[], options?: HighlightZoomOptions) {\n return this.#highlights.addHighlightAndZoom(geometries, options ?? {});\n }\n\n removeHighlights() {\n this.#highlights.clearHighlight();\n }\n\n whenDisplayed(): Promise<void> {\n if (this.#destroyed) {\n return Promise.reject(new Error(\"Map model was destroyed.\"));\n }\n if (this.#displayStatus === \"error\") {\n return Promise.reject(new Error(`Failed to initialize map.`));\n }\n if (this.#displayStatus === \"ready\") {\n return Promise.resolve();\n }\n return (this.#displayWaiter ??= createManualPromise()).promise;\n }\n\n /**\n * Waits for the map to be displayed and then initializes the view (if necessary).\n *\n * May simply resolve when done, or throw an error when a problem occurs.\n * AbortError is thrown when cancelled via `this.#abortController`, for example\n * when the map model is destroyed before it has ever been displayed.\n */\n async #initializeView(): Promise<void> {\n try {\n await waitForMapSize(this.olMap, this.#abortController.signal); // may throw on cancel\n } catch (e) {\n if (isAbortError(e)) {\n throw e;\n }\n throw new Error(`Failed to wait for the map to be displayed.`, { cause: e });\n }\n\n try {\n const olMap = this.#olMap;\n const view = olMap.getView();\n\n if (this.#initialExtent) {\n // Initial extent was set from the outside. We simply ensure that it gets displayed by the map.\n const extent = this.#initialExtent;\n const olExtent = [extent.xMin, extent.yMin, extent.xMax, extent.yMax];\n\n const olCenter = getCenter(olExtent);\n const resolution = view.getResolutionForExtent(olExtent);\n LOG.debug(`Applying initial extent`, extent);\n LOG.debug(` Computed center:`, olCenter);\n LOG.debug(` Computed resolution:`, resolution);\n\n view.setCenter(olCenter);\n view.setResolution(resolution);\n } else {\n // Initial extent was NOT set from the outside.\n // We detect whatever the view is displaying and consider it to be the initial extent.\n const olExtent = view.calculateExtent();\n const [xMin = 0, yMin = 0, xMax = 0, yMax = 0] = olExtent;\n const extent: ExtentConfig = { xMin, yMin, xMax, yMax };\n LOG.debug(`Detected initial extent`, extent);\n\n this.#initialExtent = extent;\n this.emit(\"changed:initialExtent\");\n this.emit(\"changed\");\n }\n } catch (e) {\n throw new Error(`Failed to apply the initial extent.`, { cause: e });\n }\n }\n\n #onTargetChanged() {\n const newContainer: HTMLElement | undefined = this.#olMap.getTargetElement() ?? undefined;\n if (this.#container !== newContainer) {\n this.#container = newContainer;\n this.emit(\"changed:container\");\n this.emit(\"changed\");\n }\n }\n}\n\nfunction waitForMapSize(olMap: OlMap, signal: AbortSignal): Promise<void> {\n const promise = new Promise<void>((resolve, reject) => {\n let eventKey: EventsKey | undefined;\n\n function checkSize() {\n const currentSize = olMap.getSize() ?? [];\n const [width = 0, height = 0] = currentSize;\n if (currentSize && width > 0 && height > 0) {\n finish();\n }\n }\n\n function onAbort() {\n finish(createAbortError());\n }\n\n function finish(error?: Error | undefined) {\n if (eventKey) {\n unByKey(eventKey);\n eventKey = undefined;\n }\n signal.removeEventListener(\"abort\", onAbort);\n\n if (error) {\n reject(error);\n } else {\n resolve(wait(25)); // Give the map some time to render\n }\n }\n\n if (signal.aborted) {\n finish(createAbortError());\n return;\n }\n\n signal.addEventListener(\"abort\", onAbort);\n eventKey = olMap.on(\"change:size\", checkSize);\n });\n return promise;\n}\n\nfunction wait(milliseconds: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, milliseconds));\n}\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"MapModelImpl.js","sources":["MapModelImpl.ts"],"sourcesContent":["// SPDX-FileCopyrightText: 2023 Open Pioneer project (https://github.com/open-pioneer)\n// SPDX-License-Identifier: Apache-2.0\nimport { computed, reactive, ReadonlyReactive, synchronized } from \"@conterra/reactivity-core\";\nimport {\n createAbortError,\n createLogger,\n createManualPromise,\n EventEmitter,\n isAbortError,\n ManualPromise\n} from \"@open-pioneer/core\";\nimport { HttpService } from \"@open-pioneer/http\";\nimport OlMap from \"ol/Map\";\nimport { unByKey } from \"ol/Observable\";\nimport OlView from \"ol/View\";\nimport { Coordinate } from \"ol/coordinate\";\nimport { EventsKey } from \"ol/events\";\nimport { getCenter } from \"ol/extent\";\nimport { Geometry } from \"ol/geom\";\nimport { getPointResolution, Projection } from \"ol/proj\";\nimport {\n ExtentConfig,\n Highlight,\n HighlightOptions,\n HighlightZoomOptions,\n MapModel,\n MapModelEvents\n} from \"../api\";\nimport { Highlights } from \"./Highlights\";\nimport { LayerCollectionImpl } from \"./LayerCollectionImpl\";\n\nconst LOG = createLogger(\"map:MapModel\");\n\nconst DEFAULT_DPI = 25.4 / 0.28;\nconst INCHES_PER_METRE = 39.37;\n\n/**\n * Shared services or other entities propagated from the map model to all layer instances.\n */\nexport interface SharedDependencies {\n httpService: HttpService;\n}\n\nexport class MapModelImpl extends EventEmitter<MapModelEvents> implements MapModel {\n readonly #id: string;\n readonly #olMap: OlMap;\n readonly #olView: ReadonlyReactive<OlView>;\n readonly #layers = new LayerCollectionImpl(this);\n readonly #highlights: Highlights;\n readonly #sharedDeps: SharedDependencies;\n\n #destroyed = false;\n #container: ReadonlyReactive<HTMLElement | undefined>;\n #initialExtent = reactive<ExtentConfig>();\n #viewBindings: ReadonlyReactive<ViewBindings>;\n #scale: ReadonlyReactive<number | undefined>;\n\n readonly #abortController = new AbortController();\n #displayStatus: \"waiting\" | \"ready\" | \"error\";\n #displayWaiter: ManualPromise<void> | undefined;\n\n constructor(properties: {\n id: string;\n olMap: OlMap;\n initialExtent: ExtentConfig | undefined;\n httpService: HttpService;\n }) {\n super();\n this.#id = properties.id;\n this.#olMap = properties.olMap;\n this.#olView = synchronized(\n () => this.#olMap.getView(),\n (cb) => {\n const key = this.#olMap.on(\"change:view\", cb);\n return () => unByKey(key);\n }\n );\n this.#initialExtent.value = properties.initialExtent;\n this.#sharedDeps = {\n httpService: properties.httpService\n };\n this.#highlights = new Highlights(this.#olMap);\n\n this.#displayStatus = \"waiting\";\n this.#initializeView().then(\n () => {\n this.#displayStatus = \"ready\";\n this.#displayWaiter?.resolve();\n this.#displayWaiter = undefined;\n },\n (error) => {\n if (!isAbortError(error)) {\n LOG.error(`Failed to initialize map`, error);\n }\n\n this.#displayStatus = \"error\";\n this.#displayWaiter?.reject(new Error(`Failed to initialize map.`));\n this.#displayWaiter = undefined;\n }\n );\n\n this.#container = synchronized(\n () => this.#olMap.getTargetElement() ?? undefined,\n (cb) => {\n const key = this.#olMap.on(\"change:target\", cb);\n return () => unByKey(key);\n }\n );\n\n this.#viewBindings = computed(() => createViewBindings(this.#olView.value));\n this.#scale = computed(() => {\n const { projection, resolution, center } = this;\n if (projection == null || resolution == null || center == null) {\n return undefined;\n }\n\n /**\n * Returns the appropriate scale for the given resolution and units, see OpenLayers function getScaleForResolution()\n * https://github.com/openlayers/openlayers/blob/7fa9df03431e9e1bc517e6c414565d9f848a3132/src/ol/control/ScaleLine.js#L454C3-L454C24\n */\n const pointResolution = getPointResolution(projection, resolution, center);\n const scale = Math.round(pointResolution * INCHES_PER_METRE * DEFAULT_DPI);\n return scale;\n });\n }\n\n destroy() {\n if (this.#destroyed) {\n return;\n }\n\n this.#destroyed = true;\n try {\n this.emit(\"destroy\");\n } catch (e) {\n LOG.warn(`Unexpected error from event listener during map model destruction:`, e);\n }\n\n this.#abortController.abort();\n this.#displayWaiter?.reject(new Error(\"Map model was destroyed.\"));\n this.#layers.destroy();\n this.#highlights.destroy();\n this.#olMap.dispose();\n }\n\n get id(): string {\n return this.#id;\n }\n\n get olMap(): OlMap {\n return this.#olMap;\n }\n\n get olView(): OlView {\n return this.#olView.value;\n }\n\n get projection(): Projection {\n return this.#viewBindings.value.projection;\n }\n\n get center(): Coordinate | undefined {\n return this.#viewBindings.value.center.value;\n }\n\n get resolution(): number | undefined {\n return this.#viewBindings.value.resolution.value;\n }\n\n get zoomLevel(): number | undefined {\n return this.#viewBindings.value.zoom.value;\n }\n\n get scale(): number | undefined {\n return this.#scale.value;\n }\n\n get layers(): LayerCollectionImpl {\n return this.#layers;\n }\n\n get container(): HTMLElement | undefined {\n return this.#container.value;\n }\n\n get initialExtent(): ExtentConfig | undefined {\n return this.#initialExtent.value;\n }\n\n get __sharedDependencies(): SharedDependencies {\n return this.#sharedDeps;\n }\n\n setScale(newScale: number): void {\n const view = this.olView;\n const projection = this.projection;\n const center = this.center;\n if (!center) {\n return;\n }\n\n const mpu = projection.getMetersPerUnit() ?? 1;\n const resolution = INCHES_PER_METRE * DEFAULT_DPI * mpu;\n const pointResolution = newScale / getPointResolution(projection, resolution, center);\n view.setResolution(pointResolution);\n }\n\n highlight(geometries: Geometry[], options?: HighlightOptions | undefined): Highlight {\n return this.#highlights.addHighlight(geometries, options);\n }\n\n zoom(geometries: Geometry[], options?: HighlightZoomOptions | undefined): void {\n this.#highlights.zoomToHighlight(geometries, options);\n }\n\n highlightAndZoom(geometries: Geometry[], options?: HighlightZoomOptions) {\n return this.#highlights.addHighlightAndZoom(geometries, options ?? {});\n }\n\n removeHighlights() {\n this.#highlights.clearHighlight();\n }\n\n whenDisplayed(): Promise<void> {\n if (this.#destroyed) {\n return Promise.reject(new Error(\"Map model was destroyed.\"));\n }\n if (this.#displayStatus === \"error\") {\n return Promise.reject(new Error(`Failed to initialize map.`));\n }\n if (this.#displayStatus === \"ready\") {\n return Promise.resolve();\n }\n return (this.#displayWaiter ??= createManualPromise()).promise;\n }\n\n /**\n * Waits for the map to be displayed and then initializes the view (if necessary).\n *\n * May simply resolve when done, or throw an error when a problem occurs.\n * AbortError is thrown when cancelled via `this.#abortController`, for example\n * when the map model is destroyed before it has ever been displayed.\n */\n async #initializeView(): Promise<void> {\n try {\n await waitForMapSize(this.olMap, this.#abortController.signal); // may throw on cancel\n } catch (e) {\n if (isAbortError(e)) {\n throw e;\n }\n throw new Error(`Failed to wait for the map to be displayed.`, { cause: e });\n }\n\n try {\n const olMap = this.#olMap;\n const view = olMap.getView();\n\n if (this.#initialExtent.value) {\n // Initial extent was set from the outside. We simply ensure that it gets displayed by the map.\n const extent = this.#initialExtent.value;\n const olExtent = [extent.xMin, extent.yMin, extent.xMax, extent.yMax];\n\n const olCenter = getCenter(olExtent);\n const resolution = view.getResolutionForExtent(olExtent);\n LOG.debug(`Applying initial extent`, extent);\n LOG.debug(` Computed center:`, olCenter);\n LOG.debug(` Computed resolution:`, resolution);\n\n view.setCenter(olCenter);\n view.setResolution(resolution);\n } else {\n // Initial extent was NOT set from the outside.\n // We detect whatever the view is displaying and consider it to be the initial extent.\n const olExtent = view.calculateExtent();\n const [xMin = 0, yMin = 0, xMax = 0, yMax = 0] = olExtent;\n const extent: ExtentConfig = { xMin, yMin, xMax, yMax };\n LOG.debug(`Detected initial extent`, extent);\n\n this.#initialExtent.value = extent;\n }\n } catch (e) {\n throw new Error(`Failed to apply the initial extent.`, { cause: e });\n }\n }\n}\n\ninterface ViewBindings {\n resolution: ReadonlyReactive<number | undefined>;\n center: ReadonlyReactive<Coordinate | undefined>;\n zoom: ReadonlyReactive<number | undefined>;\n projection: Projection; // not reactive (change view to change projection)\n}\n\nfunction createViewBindings(view: OlView): ViewBindings {\n return {\n resolution: synchronized(\n () => view.getResolution(),\n (cb) => {\n const key = view.on(\"change:resolution\", cb);\n return () => unByKey(key);\n }\n ),\n center: synchronized(\n () => view.getCenter(),\n (cb) => {\n const key = view.on(\"change:center\", cb);\n return () => unByKey(key);\n }\n ),\n zoom: synchronized(\n () => view.getZoom(),\n (cb) => {\n const key = view.on(\"change:resolution\", cb);\n return () => unByKey(key);\n }\n ),\n projection: view.getProjection()\n };\n}\n\nfunction waitForMapSize(olMap: OlMap, signal: AbortSignal): Promise<void> {\n const promise = new Promise<void>((resolve, reject) => {\n let eventKey: EventsKey | undefined;\n\n function checkSize() {\n const currentSize = olMap.getSize() ?? [];\n const [width = 0, height = 0] = currentSize;\n if (currentSize && width > 0 && height > 0) {\n finish();\n }\n }\n\n function onAbort() {\n finish(createAbortError());\n }\n\n function finish(error?: Error | undefined) {\n if (eventKey) {\n unByKey(eventKey);\n eventKey = undefined;\n }\n signal.removeEventListener(\"abort\", onAbort);\n\n if (error) {\n reject(error);\n } else {\n resolve(wait(25)); // Give the map some time to render\n }\n }\n\n if (signal.aborted) {\n finish(createAbortError());\n return;\n }\n\n signal.addEventListener(\"abort\", onAbort);\n eventKey = olMap.on(\"change:size\", checkSize);\n });\n return promise;\n}\n\nfunction wait(milliseconds: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, milliseconds));\n}\n"],"names":[],"mappings":"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"}
|
|
@@ -1,10 +1,13 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { LayerRetrievalOptions, SublayerBaseType, SublayersCollection, SublayersCollectionEvents } from "../api";
|
|
1
|
+
import { LayerRetrievalOptions, SublayerBaseType, SublayersCollection } from "../api";
|
|
3
2
|
import { AbstractLayerBase } from "./AbstractLayerBase";
|
|
4
|
-
|
|
3
|
+
/**
|
|
4
|
+
* Manages the sublayers of a layer.
|
|
5
|
+
*/
|
|
6
|
+
export declare class SublayersCollectionImpl<Sublayer extends SublayerBaseType & AbstractLayerBase> implements SublayersCollection<Sublayer> {
|
|
5
7
|
#private;
|
|
6
8
|
constructor(sublayers: Sublayer[]);
|
|
7
9
|
destroy(): void;
|
|
10
|
+
getItems(options?: LayerRetrievalOptions): Sublayer[];
|
|
8
11
|
getSublayers(_options?: LayerRetrievalOptions | undefined): Sublayer[];
|
|
9
12
|
/**
|
|
10
13
|
* Returns a reference to the internal sublayers array.
|
|
@@ -1,9 +1,7 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
class SublayersCollectionImpl extends EventEmitter {
|
|
1
|
+
class SublayersCollectionImpl {
|
|
2
|
+
/* eslint-enable indent */
|
|
4
3
|
#sublayers;
|
|
5
4
|
constructor(sublayers) {
|
|
6
|
-
super();
|
|
7
5
|
this.#sublayers = sublayers;
|
|
8
6
|
}
|
|
9
7
|
destroy() {
|
|
@@ -12,6 +10,10 @@ class SublayersCollectionImpl extends EventEmitter {
|
|
|
12
10
|
}
|
|
13
11
|
this.#sublayers = [];
|
|
14
12
|
}
|
|
13
|
+
// Generic method name for consistent interface
|
|
14
|
+
getItems(options) {
|
|
15
|
+
return this.getSublayers(options);
|
|
16
|
+
}
|
|
15
17
|
getSublayers(_options) {
|
|
16
18
|
return this.#sublayers.slice();
|
|
17
19
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SublayersCollectionImpl.js","sources":["SublayersCollectionImpl.ts"],"sourcesContent":["// SPDX-FileCopyrightText: 2023 Open Pioneer project (https://github.com/open-pioneer)\n// SPDX-License-Identifier: Apache-2.0\nimport {
|
|
1
|
+
{"version":3,"file":"SublayersCollectionImpl.js","sources":["SublayersCollectionImpl.ts"],"sourcesContent":["// SPDX-FileCopyrightText: 2023 Open Pioneer project (https://github.com/open-pioneer)\n// SPDX-License-Identifier: Apache-2.0\nimport { LayerRetrievalOptions, SublayerBaseType, SublayersCollection } from \"../api\";\nimport { AbstractLayerBase } from \"./AbstractLayerBase\";\n\n/**\n * Manages the sublayers of a layer.\n */\n// NOTE: adding / removing sublayers currently not supported\n/* eslint-disable indent */\nexport class SublayersCollectionImpl<Sublayer extends SublayerBaseType & AbstractLayerBase>\n implements SublayersCollection<Sublayer>\n{\n /* eslint-enable indent */\n #sublayers: Sublayer[];\n\n constructor(sublayers: Sublayer[]) {\n this.#sublayers = sublayers;\n }\n\n destroy() {\n for (const layer of this.#sublayers) {\n layer.destroy();\n }\n this.#sublayers = [];\n }\n\n // Generic method name for consistent interface\n getItems(options?: LayerRetrievalOptions): Sublayer[] {\n return this.getSublayers(options);\n }\n\n getSublayers(_options?: LayerRetrievalOptions | undefined): Sublayer[] {\n // NOTE: options are ignored because layers are always ordered at this time.\n return this.#sublayers.slice();\n }\n\n /**\n * Returns a reference to the internal sublayers array.\n *\n * NOTE: Do not modify directly!\n */\n __getRawSublayers(): Sublayer[] {\n return this.#sublayers;\n }\n}\n"],"names":[],"mappings":"AAUO,MAAM,uBAEb,CAAA;AAAA;AAAA,EAEI,UAAA,CAAA;AAAA,EAEA,YAAY,SAAuB,EAAA;AAC/B,IAAA,IAAA,CAAK,UAAa,GAAA,SAAA,CAAA;AAAA,GACtB;AAAA,EAEA,OAAU,GAAA;AACN,IAAW,KAAA,MAAA,KAAA,IAAS,KAAK,UAAY,EAAA;AACjC,MAAA,KAAA,CAAM,OAAQ,EAAA,CAAA;AAAA,KAClB;AACA,IAAA,IAAA,CAAK,aAAa,EAAC,CAAA;AAAA,GACvB;AAAA;AAAA,EAGA,SAAS,OAA6C,EAAA;AAClD,IAAO,OAAA,IAAA,CAAK,aAAa,OAAO,CAAA,CAAA;AAAA,GACpC;AAAA,EAEA,aAAa,QAA0D,EAAA;AAEnE,IAAO,OAAA,IAAA,CAAK,WAAW,KAAM,EAAA,CAAA;AAAA,GACjC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,iBAAgC,GAAA;AAC5B,IAAA,OAAO,IAAK,CAAA,UAAA,CAAA;AAAA,GAChB;AACJ;;;;"}
|