@open-pioneer/map 0.7.0 → 0.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +135 -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/MapContainer.js +7 -0
- package/ui/MapContainer.js.map +1 -1
- 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
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { Group } from "ol/layer";
|
|
2
|
+
import { GroupLayerCollection, Layer, LayerRetrievalOptions } from "../../api";
|
|
3
|
+
import { GroupLayer, GroupLayerConfig } from "../../api/layers/GroupLayer";
|
|
4
|
+
import { AbstractLayer } from "../AbstractLayer";
|
|
5
|
+
import { MapModelImpl } from "../MapModelImpl";
|
|
6
|
+
export declare class GroupLayerImpl extends AbstractLayer implements GroupLayer {
|
|
7
|
+
#private;
|
|
8
|
+
constructor(config: GroupLayerConfig);
|
|
9
|
+
get type(): "group";
|
|
10
|
+
get legend(): undefined;
|
|
11
|
+
get layers(): GroupLayerCollectionImpl;
|
|
12
|
+
get sublayers(): undefined;
|
|
13
|
+
/**
|
|
14
|
+
* return raw OL LayerGroup
|
|
15
|
+
* Warning: Do not manipulate the collection of layers in this group, changes are not synchronized!
|
|
16
|
+
*/
|
|
17
|
+
get olLayer(): Group;
|
|
18
|
+
__attachToMap(map: MapModelImpl): void;
|
|
19
|
+
}
|
|
20
|
+
export declare class GroupLayerCollectionImpl implements GroupLayerCollection {
|
|
21
|
+
#private;
|
|
22
|
+
constructor(layers: Layer[], parent: GroupLayer);
|
|
23
|
+
/**
|
|
24
|
+
* Destroys this collection, all contained layers are detached from their parent group layer
|
|
25
|
+
*/
|
|
26
|
+
destroy(): void;
|
|
27
|
+
getItems(options?: LayerRetrievalOptions): (AbstractLayer & Layer)[];
|
|
28
|
+
getLayers(_options?: LayerRetrievalOptions | undefined): (AbstractLayer & Layer)[];
|
|
29
|
+
/**
|
|
30
|
+
* Returns a reference to the internal group layer array.
|
|
31
|
+
*
|
|
32
|
+
* NOTE: Do not modify directly!
|
|
33
|
+
*/
|
|
34
|
+
__getRawLayers(): (AbstractLayer & Layer)[];
|
|
35
|
+
/**
|
|
36
|
+
* Returns the parent group layer that owns this collection.
|
|
37
|
+
*/
|
|
38
|
+
__getParent(): GroupLayer;
|
|
39
|
+
}
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
import { Group } from 'ol/layer.js';
|
|
2
|
+
import { AbstractLayer } from '../AbstractLayer.js';
|
|
3
|
+
import { AbstractLayerBase } from '../AbstractLayerBase.js';
|
|
4
|
+
|
|
5
|
+
class GroupLayerImpl extends AbstractLayer {
|
|
6
|
+
#children;
|
|
7
|
+
constructor(config) {
|
|
8
|
+
const groupLayers = config.layers;
|
|
9
|
+
const olGroup = new Group({ layers: groupLayers.map((sublayer) => sublayer.olLayer) });
|
|
10
|
+
super({ ...config, olLayer: olGroup });
|
|
11
|
+
this.#children = new GroupLayerCollectionImpl(groupLayers, this);
|
|
12
|
+
}
|
|
13
|
+
get type() {
|
|
14
|
+
return "group";
|
|
15
|
+
}
|
|
16
|
+
get legend() {
|
|
17
|
+
return void 0;
|
|
18
|
+
}
|
|
19
|
+
get layers() {
|
|
20
|
+
return this.#children;
|
|
21
|
+
}
|
|
22
|
+
get sublayers() {
|
|
23
|
+
return void 0;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* return raw OL LayerGroup
|
|
27
|
+
* Warning: Do not manipulate the collection of layers in this group, changes are not synchronized!
|
|
28
|
+
*/
|
|
29
|
+
get olLayer() {
|
|
30
|
+
return super.olLayer;
|
|
31
|
+
}
|
|
32
|
+
__attachToMap(map) {
|
|
33
|
+
super.__attachToMap(map);
|
|
34
|
+
this.layers.__getRawLayers().forEach((layer) => layer.__attachToMap(map));
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
class GroupLayerCollectionImpl {
|
|
38
|
+
#layers;
|
|
39
|
+
#parent;
|
|
40
|
+
constructor(layers, parent) {
|
|
41
|
+
layers = layers.slice();
|
|
42
|
+
for (const layer of layers) {
|
|
43
|
+
if (layer instanceof AbstractLayer) {
|
|
44
|
+
layer.__attachToGroup(parent);
|
|
45
|
+
} else {
|
|
46
|
+
throw new Error(
|
|
47
|
+
`Layer '${layer.id}' of group '${parent.id}' does not implement abstract class '${AbstractLayerBase.name}`
|
|
48
|
+
);
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
this.#layers = layers;
|
|
52
|
+
this.#parent = parent;
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Destroys this collection, all contained layers are detached from their parent group layer
|
|
56
|
+
*/
|
|
57
|
+
destroy() {
|
|
58
|
+
for (const layer of this.#layers) {
|
|
59
|
+
layer.__detachFromGroup();
|
|
60
|
+
layer.destroy();
|
|
61
|
+
}
|
|
62
|
+
this.#layers = [];
|
|
63
|
+
}
|
|
64
|
+
// Generic method name for consistent interface
|
|
65
|
+
getItems(options) {
|
|
66
|
+
return this.getLayers(options);
|
|
67
|
+
}
|
|
68
|
+
getLayers(_options) {
|
|
69
|
+
return this.#layers.slice();
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Returns a reference to the internal group layer array.
|
|
73
|
+
*
|
|
74
|
+
* NOTE: Do not modify directly!
|
|
75
|
+
*/
|
|
76
|
+
__getRawLayers() {
|
|
77
|
+
return this.#layers;
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* Returns the parent group layer that owns this collection.
|
|
81
|
+
*/
|
|
82
|
+
__getParent() {
|
|
83
|
+
return this.#parent;
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
export { GroupLayerCollectionImpl, GroupLayerImpl };
|
|
88
|
+
//# sourceMappingURL=GroupLayerImpl.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"GroupLayerImpl.js","sources":["GroupLayerImpl.ts"],"sourcesContent":["// SPDX-FileCopyrightText: 2023 Open Pioneer project (https://github.com/open-pioneer)\n// SPDX-License-Identifier: Apache-2.0\nimport { Group } from \"ol/layer\";\nimport { GroupLayerCollection, Layer, LayerRetrievalOptions } from \"../../api\";\nimport { GroupLayer, GroupLayerConfig } from \"../../api/layers/GroupLayer\";\nimport { AbstractLayer } from \"../AbstractLayer\";\nimport { AbstractLayerBase } from \"../AbstractLayerBase\";\nimport { MapModelImpl } from \"../MapModelImpl\";\n\nexport class GroupLayerImpl extends AbstractLayer implements GroupLayer {\n #children: GroupLayerCollectionImpl;\n\n constructor(config: GroupLayerConfig) {\n const groupLayers = config.layers;\n const olGroup = new Group({ layers: groupLayers.map((sublayer) => sublayer.olLayer) });\n super({ ...config, olLayer: olGroup });\n this.#children = new GroupLayerCollectionImpl(groupLayers, this);\n }\n\n get type() {\n return \"group\" as const;\n }\n\n get legend() {\n return undefined;\n }\n\n get layers(): GroupLayerCollectionImpl {\n return this.#children;\n }\n\n get sublayers(): undefined {\n return undefined;\n }\n\n /**\n * return raw OL LayerGroup\n * Warning: Do not manipulate the collection of layers in this group, changes are not synchronized!\n */\n get olLayer(): Group {\n return super.olLayer as Group;\n }\n\n __attachToMap(map: MapModelImpl): void {\n super.__attachToMap(map);\n this.layers.__getRawLayers().forEach((layer) => layer.__attachToMap(map));\n }\n}\n\n// NOTE: adding / removing currently not supported.\n// When adding support for dynamic content, make sure to also updating the layer indexing logic in the map (LayerCollectionImpl).\n// Nested children of a group layer must also be found in id-lookups.\nexport class GroupLayerCollectionImpl implements GroupLayerCollection {\n #layers: (AbstractLayer & Layer)[];\n #parent: GroupLayer;\n\n constructor(layers: Layer[], parent: GroupLayer) {\n layers = layers.slice(); // Don't modify the input\n for (const layer of layers) {\n if (layer instanceof AbstractLayer) {\n layer.__attachToGroup(parent); //attach every layer to the parent group layer\n } else {\n throw new Error(\n `Layer '${layer.id}' of group '${parent.id}' does not implement abstract class '${AbstractLayerBase.name}`\n );\n }\n }\n this.#layers = layers as (Layer & AbstractLayer)[];\n this.#parent = parent;\n }\n\n /**\n * Destroys this collection, all contained layers are detached from their parent group layer\n */\n destroy() {\n for (const layer of this.#layers) {\n layer.__detachFromGroup();\n layer.destroy();\n }\n this.#layers = [];\n }\n\n // Generic method name for consistent interface\n getItems(options?: LayerRetrievalOptions): (AbstractLayer & Layer)[] {\n return this.getLayers(options);\n }\n\n getLayers(_options?: LayerRetrievalOptions | undefined): (AbstractLayer & Layer)[] {\n // NOTE: options are ignored because layers are always ordered at this time.\n return this.#layers.slice();\n }\n\n /**\n * Returns a reference to the internal group layer array.\n *\n * NOTE: Do not modify directly!\n */\n __getRawLayers(): (AbstractLayer & Layer)[] {\n return this.#layers;\n }\n\n /**\n * Returns the parent group layer that owns this collection.\n */\n __getParent(): GroupLayer {\n return this.#parent;\n }\n}\n"],"names":[],"mappings":";;;;AASO,MAAM,uBAAuB,aAAoC,CAAA;AAAA,EACpE,SAAA,CAAA;AAAA,EAEA,YAAY,MAA0B,EAAA;AAClC,IAAA,MAAM,cAAc,MAAO,CAAA,MAAA,CAAA;AAC3B,IAAA,MAAM,OAAU,GAAA,IAAI,KAAM,CAAA,EAAE,MAAQ,EAAA,WAAA,CAAY,GAAI,CAAA,CAAC,QAAa,KAAA,QAAA,CAAS,OAAO,CAAA,EAAG,CAAA,CAAA;AACrF,IAAA,KAAA,CAAM,EAAE,GAAG,MAAQ,EAAA,OAAA,EAAS,SAAS,CAAA,CAAA;AACrC,IAAA,IAAA,CAAK,SAAY,GAAA,IAAI,wBAAyB,CAAA,WAAA,EAAa,IAAI,CAAA,CAAA;AAAA,GACnE;AAAA,EAEA,IAAI,IAAO,GAAA;AACP,IAAO,OAAA,OAAA,CAAA;AAAA,GACX;AAAA,EAEA,IAAI,MAAS,GAAA;AACT,IAAO,OAAA,KAAA,CAAA,CAAA;AAAA,GACX;AAAA,EAEA,IAAI,MAAmC,GAAA;AACnC,IAAA,OAAO,IAAK,CAAA,SAAA,CAAA;AAAA,GAChB;AAAA,EAEA,IAAI,SAAuB,GAAA;AACvB,IAAO,OAAA,KAAA,CAAA,CAAA;AAAA,GACX;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,IAAI,OAAiB,GAAA;AACjB,IAAA,OAAO,KAAM,CAAA,OAAA,CAAA;AAAA,GACjB;AAAA,EAEA,cAAc,GAAyB,EAAA;AACnC,IAAA,KAAA,CAAM,cAAc,GAAG,CAAA,CAAA;AACvB,IAAK,IAAA,CAAA,MAAA,CAAO,gBAAiB,CAAA,OAAA,CAAQ,CAAC,KAAU,KAAA,KAAA,CAAM,aAAc,CAAA,GAAG,CAAC,CAAA,CAAA;AAAA,GAC5E;AACJ,CAAA;AAKO,MAAM,wBAAyD,CAAA;AAAA,EAClE,OAAA,CAAA;AAAA,EACA,OAAA,CAAA;AAAA,EAEA,WAAA,CAAY,QAAiB,MAAoB,EAAA;AAC7C,IAAA,MAAA,GAAS,OAAO,KAAM,EAAA,CAAA;AACtB,IAAA,KAAA,MAAW,SAAS,MAAQ,EAAA;AACxB,MAAA,IAAI,iBAAiB,aAAe,EAAA;AAChC,QAAA,KAAA,CAAM,gBAAgB,MAAM,CAAA,CAAA;AAAA,OACzB,MAAA;AACH,QAAA,MAAM,IAAI,KAAA;AAAA,UACN,CAAA,OAAA,EAAU,MAAM,EAAE,CAAA,YAAA,EAAe,OAAO,EAAE,CAAA,qCAAA,EAAwC,kBAAkB,IAAI,CAAA,CAAA;AAAA,SAC5G,CAAA;AAAA,OACJ;AAAA,KACJ;AACA,IAAA,IAAA,CAAK,OAAU,GAAA,MAAA,CAAA;AACf,IAAA,IAAA,CAAK,OAAU,GAAA,MAAA,CAAA;AAAA,GACnB;AAAA;AAAA;AAAA;AAAA,EAKA,OAAU,GAAA;AACN,IAAW,KAAA,MAAA,KAAA,IAAS,KAAK,OAAS,EAAA;AAC9B,MAAA,KAAA,CAAM,iBAAkB,EAAA,CAAA;AACxB,MAAA,KAAA,CAAM,OAAQ,EAAA,CAAA;AAAA,KAClB;AACA,IAAA,IAAA,CAAK,UAAU,EAAC,CAAA;AAAA,GACpB;AAAA;AAAA,EAGA,SAAS,OAA4D,EAAA;AACjE,IAAO,OAAA,IAAA,CAAK,UAAU,OAAO,CAAA,CAAA;AAAA,GACjC;AAAA,EAEA,UAAU,QAAyE,EAAA;AAE/E,IAAO,OAAA,IAAA,CAAK,QAAQ,KAAM,EAAA,CAAA;AAAA,GAC9B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,cAA4C,GAAA;AACxC,IAAA,OAAO,IAAK,CAAA,OAAA,CAAA;AAAA,GAChB;AAAA;AAAA;AAAA;AAAA,EAKA,WAA0B,GAAA;AACtB,IAAA,OAAO,IAAK,CAAA,OAAA,CAAA;AAAA,GAChB;AACJ;;;;"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SimpleLayerImpl.js","sources":["SimpleLayerImpl.ts"],"sourcesContent":["// SPDX-FileCopyrightText: 2023 Open Pioneer project (https://github.com/open-pioneer)\n// SPDX-License-Identifier: Apache-2.0\nimport { SimpleLayer } from \"../../api\";\nimport { AbstractLayer } from \"../AbstractLayer\";\n\n/**\n * A simple layer that accepts a custom OpenLayer's layer instance.\n *\n * Some API features (such as sublayers) will not be available.\n */\nexport class SimpleLayerImpl extends AbstractLayer implements SimpleLayer {\n get type() {\n return \"simple\" as const;\n }\n get legend() {\n return undefined;\n }\n get sublayers(): undefined {\n return undefined;\n }\n}\n"],"names":[],"mappings":";;AAUO,MAAM,wBAAwB,aAAqC,CAAA;AAAA,EACtE,IAAI,IAAO,GAAA;AACP,IAAO,OAAA,QAAA,CAAA;AAAA,GACX;AAAA,
|
|
1
|
+
{"version":3,"file":"SimpleLayerImpl.js","sources":["SimpleLayerImpl.ts"],"sourcesContent":["// SPDX-FileCopyrightText: 2023 Open Pioneer project (https://github.com/open-pioneer)\n// SPDX-License-Identifier: Apache-2.0\nimport { SimpleLayer } from \"../../api\";\nimport { AbstractLayer } from \"../AbstractLayer\";\n\n/**\n * A simple layer that accepts a custom OpenLayer's layer instance.\n *\n * Some API features (such as sublayers) will not be available.\n */\nexport class SimpleLayerImpl extends AbstractLayer implements SimpleLayer {\n get type() {\n return \"simple\" as const;\n }\n\n get legend(): undefined {\n return undefined;\n }\n\n get layers(): undefined {\n return undefined;\n }\n\n get sublayers(): undefined {\n return undefined;\n }\n}\n"],"names":[],"mappings":";;AAUO,MAAM,wBAAwB,aAAqC,CAAA;AAAA,EACtE,IAAI,IAAO,GAAA;AACP,IAAO,OAAA,QAAA,CAAA;AAAA,GACX;AAAA,EAEA,IAAI,MAAoB,GAAA;AACpB,IAAO,OAAA,KAAA,CAAA,CAAA;AAAA,GACX;AAAA,EAEA,IAAI,MAAoB,GAAA;AACpB,IAAO,OAAA,KAAA,CAAA,CAAA;AAAA,GACX;AAAA,EAEA,IAAI,SAAuB,GAAA;AACvB,IAAO,OAAA,KAAA,CAAA,CAAA;AAAA,GACX;AACJ;;;;"}
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import ImageWMS from "ol/source/ImageWMS";
|
|
2
1
|
import { WMSLayer, WMSLayerConfig, WMSSublayer, WMSSublayerConfig } from "../../api";
|
|
3
2
|
import { AbstractLayer } from "../AbstractLayer";
|
|
4
3
|
import { AbstractLayerBase } from "../AbstractLayerBase";
|
|
@@ -7,31 +6,34 @@ import { SublayersCollectionImpl } from "../SublayersCollectionImpl";
|
|
|
7
6
|
export declare class WMSLayerImpl extends AbstractLayer implements WMSLayer {
|
|
8
7
|
#private;
|
|
9
8
|
constructor(config: WMSLayerConfig);
|
|
9
|
+
destroy(): void;
|
|
10
10
|
get type(): "wms";
|
|
11
11
|
get legend(): undefined;
|
|
12
12
|
get url(): string;
|
|
13
|
-
get
|
|
13
|
+
get layers(): undefined;
|
|
14
14
|
get sublayers(): SublayersCollectionImpl<WMSSublayerImpl>;
|
|
15
15
|
get capabilities(): Record<string, any> | undefined;
|
|
16
|
-
|
|
17
|
-
/** Called by the sublayers when their visibility changed. */
|
|
18
|
-
__updateSublayerVisibility(): void;
|
|
16
|
+
__attachToMap(map: MapModelImpl): void;
|
|
19
17
|
}
|
|
20
18
|
declare class WMSSublayerImpl extends AbstractLayerBase implements WMSSublayer {
|
|
21
19
|
#private;
|
|
22
20
|
constructor(config: WMSSublayerConfig);
|
|
23
21
|
get type(): "wms-sublayer";
|
|
24
22
|
get name(): string | undefined;
|
|
23
|
+
get layers(): undefined;
|
|
25
24
|
get sublayers(): SublayersCollectionImpl<WMSSublayerImpl>;
|
|
26
25
|
get parent(): WMSSublayerImpl | WMSLayerImpl;
|
|
27
26
|
get parentLayer(): WMSLayerImpl;
|
|
28
27
|
get legend(): string | undefined;
|
|
29
|
-
|
|
28
|
+
get visible(): boolean;
|
|
30
29
|
/**
|
|
31
30
|
* Called by the parent layer when it is attached to the map to attach all sublayers.
|
|
32
31
|
*/
|
|
33
32
|
__attach(map: MapModelImpl, parentLayer: WMSLayerImpl, parent: WMSLayerImpl | WMSSublayerImpl): void;
|
|
34
|
-
|
|
33
|
+
/**
|
|
34
|
+
* Called by the parent layer to update the legend on load.
|
|
35
|
+
*/
|
|
36
|
+
__setLegend(legendUrl: string | undefined): void;
|
|
35
37
|
setVisible(newVisibility: boolean): void;
|
|
36
38
|
}
|
|
37
39
|
/** extract the legend url from the service capabilities */
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { computed, watch, batch, reactive } from '@conterra/reactivity-core';
|
|
2
|
+
import { createLogger, destroyResource, isAbortError } from '@open-pioneer/core';
|
|
2
3
|
import WMSCapabilities from 'ol/format/WMSCapabilities.js';
|
|
3
4
|
import ImageLayer from 'ol/layer/Image.js';
|
|
4
5
|
import ImageWMS from 'ol/source/ImageWMS.js';
|
|
5
6
|
import { fetchCapabilities } from '../../util/capabilities-utils.js';
|
|
6
|
-
import { defer } from '../../util/defer.js';
|
|
7
7
|
import { AbstractLayer } from '../AbstractLayer.js';
|
|
8
8
|
import { AbstractLayerBase } from '../AbstractLayerBase.js';
|
|
9
9
|
import { SublayersCollectionImpl } from '../SublayersCollectionImpl.js';
|
|
@@ -12,12 +12,13 @@ const LOG = createLogger("map:WMSLayer");
|
|
|
12
12
|
class WMSLayerImpl extends AbstractLayer {
|
|
13
13
|
#url;
|
|
14
14
|
#sublayers;
|
|
15
|
-
#deferredSublayerUpdate;
|
|
16
15
|
#layer;
|
|
17
16
|
#source;
|
|
18
17
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
19
18
|
#capabilities;
|
|
20
19
|
#abortController = new AbortController();
|
|
20
|
+
#visibleSublayers;
|
|
21
|
+
#sublayersWatch;
|
|
21
22
|
constructor(config) {
|
|
22
23
|
const layer = new ImageLayer();
|
|
23
24
|
super({
|
|
@@ -41,7 +42,25 @@ class WMSLayerImpl extends AbstractLayer {
|
|
|
41
42
|
this.#source = source;
|
|
42
43
|
this.#layer = layer;
|
|
43
44
|
this.#sublayers = new SublayersCollectionImpl(constructSublayers(config.sublayers));
|
|
44
|
-
this.#
|
|
45
|
+
this.#visibleSublayers = computed(() => this.#getVisibleLayerNames(), {
|
|
46
|
+
equal(a, b) {
|
|
47
|
+
return a.length === b.length && a.every((v, i) => v === b[i]);
|
|
48
|
+
}
|
|
49
|
+
});
|
|
50
|
+
this.#sublayersWatch = watch(
|
|
51
|
+
() => [this.#visibleSublayers.value],
|
|
52
|
+
([layers]) => {
|
|
53
|
+
this.#updateLayersParam(layers);
|
|
54
|
+
},
|
|
55
|
+
{
|
|
56
|
+
immediate: true
|
|
57
|
+
}
|
|
58
|
+
);
|
|
59
|
+
}
|
|
60
|
+
destroy() {
|
|
61
|
+
this.#abortController.abort();
|
|
62
|
+
this.#sublayersWatch = destroyResource(this.#sublayersWatch);
|
|
63
|
+
super.destroy();
|
|
45
64
|
}
|
|
46
65
|
get type() {
|
|
47
66
|
return "wms";
|
|
@@ -52,8 +71,8 @@ class WMSLayerImpl extends AbstractLayer {
|
|
|
52
71
|
get url() {
|
|
53
72
|
return this.#url;
|
|
54
73
|
}
|
|
55
|
-
get
|
|
56
|
-
return
|
|
74
|
+
get layers() {
|
|
75
|
+
return void 0;
|
|
57
76
|
}
|
|
58
77
|
get sublayers() {
|
|
59
78
|
return this.#sublayers;
|
|
@@ -61,61 +80,48 @@ class WMSLayerImpl extends AbstractLayer {
|
|
|
61
80
|
get capabilities() {
|
|
62
81
|
return this.#capabilities;
|
|
63
82
|
}
|
|
64
|
-
|
|
65
|
-
super.
|
|
83
|
+
__attachToMap(map) {
|
|
84
|
+
super.__attachToMap(map);
|
|
66
85
|
for (const sublayer of this.#sublayers.getSublayers()) {
|
|
67
86
|
sublayer.__attach(map, this, this);
|
|
68
87
|
}
|
|
69
|
-
const
|
|
70
|
-
const getNestedSublayer = (sublayers, layers2) => {
|
|
88
|
+
const getNestedSublayer = (sublayers, layers) => {
|
|
71
89
|
for (const sublayer of sublayers) {
|
|
72
90
|
const nested = sublayer.sublayers.getSublayers();
|
|
73
91
|
if (nested.length) {
|
|
74
|
-
getNestedSublayer(nested,
|
|
92
|
+
getNestedSublayer(nested, layers);
|
|
75
93
|
} else {
|
|
76
94
|
if (sublayer.name) {
|
|
77
|
-
|
|
95
|
+
layers.push(sublayer);
|
|
78
96
|
}
|
|
79
97
|
}
|
|
80
98
|
}
|
|
81
99
|
};
|
|
82
100
|
this.#fetchWMSCapabilities().then((result) => {
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
layer
|
|
90
|
-
|
|
101
|
+
batch(() => {
|
|
102
|
+
const parser = new WMSCapabilities();
|
|
103
|
+
const capabilities = parser.read(result);
|
|
104
|
+
this.#capabilities = capabilities;
|
|
105
|
+
const layers = [];
|
|
106
|
+
getNestedSublayer(this.#sublayers.getSublayers(), layers);
|
|
107
|
+
for (const layer of layers) {
|
|
108
|
+
const legendUrl = getWMSLegendUrl(capabilities, layer.name);
|
|
109
|
+
layer.__setLegend(legendUrl);
|
|
110
|
+
}
|
|
111
|
+
});
|
|
91
112
|
}).catch((error) => {
|
|
92
113
|
if (isAbortError(error)) {
|
|
93
|
-
LOG.
|
|
114
|
+
LOG.debug(`Layer ${this.id} has been destroyed before fetching capabilities`);
|
|
94
115
|
return;
|
|
95
116
|
}
|
|
96
|
-
LOG.error(`Failed
|
|
97
|
-
});
|
|
98
|
-
}
|
|
99
|
-
/** Called by the sublayers when their visibility changed. */
|
|
100
|
-
__updateSublayerVisibility() {
|
|
101
|
-
if (this.#deferredSublayerUpdate?.reschedule()) {
|
|
102
|
-
return;
|
|
103
|
-
}
|
|
104
|
-
this.#deferredSublayerUpdate = defer(() => {
|
|
105
|
-
try {
|
|
106
|
-
this.#updateLayersParam();
|
|
107
|
-
this.#deferredSublayerUpdate = void 0;
|
|
108
|
-
} catch (e) {
|
|
109
|
-
LOG.error(`Failed to update sublayer visibility on WMS layer '${this.id}'.`, e);
|
|
110
|
-
}
|
|
117
|
+
LOG.error(`Failed to fetch WMS capabilities for layer ${this.id}`, error);
|
|
111
118
|
});
|
|
112
119
|
}
|
|
113
120
|
/**
|
|
114
121
|
* Gathers the visibility of _all_ sublayers and assembles the 'layers' WMS parameter.
|
|
115
122
|
* The parameters are then applied to the WMS source.
|
|
116
123
|
*/
|
|
117
|
-
#updateLayersParam() {
|
|
118
|
-
const layers = this.#getVisibleLayerNames();
|
|
124
|
+
#updateLayersParam(layers) {
|
|
119
125
|
this.#source.updateParams({
|
|
120
126
|
"LAYERS": layers
|
|
121
127
|
});
|
|
@@ -174,13 +180,13 @@ class WMSSublayerImpl extends AbstractLayerBase {
|
|
|
174
180
|
#parent;
|
|
175
181
|
#parentLayer;
|
|
176
182
|
#name;
|
|
177
|
-
#legend;
|
|
183
|
+
#legend = reactive();
|
|
178
184
|
#sublayers;
|
|
179
185
|
#visible;
|
|
180
186
|
constructor(config) {
|
|
181
187
|
super(config);
|
|
182
188
|
this.#name = config.name;
|
|
183
|
-
this.#visible = config.visible ?? true;
|
|
189
|
+
this.#visible = reactive(config.visible ?? true);
|
|
184
190
|
this.#sublayers = new SublayersCollectionImpl(constructSublayers(config.sublayers));
|
|
185
191
|
}
|
|
186
192
|
get type() {
|
|
@@ -189,6 +195,9 @@ class WMSSublayerImpl extends AbstractLayerBase {
|
|
|
189
195
|
get name() {
|
|
190
196
|
return this.#name;
|
|
191
197
|
}
|
|
198
|
+
get layers() {
|
|
199
|
+
return void 0;
|
|
200
|
+
}
|
|
192
201
|
get sublayers() {
|
|
193
202
|
return this.#sublayers;
|
|
194
203
|
}
|
|
@@ -207,11 +216,10 @@ class WMSSublayerImpl extends AbstractLayerBase {
|
|
|
207
216
|
return parentLayer;
|
|
208
217
|
}
|
|
209
218
|
get legend() {
|
|
210
|
-
return this.#legend;
|
|
219
|
+
return this.#legend.value;
|
|
211
220
|
}
|
|
212
|
-
|
|
213
|
-
this.#
|
|
214
|
-
this.__emitChangeEvent("changed:legend");
|
|
221
|
+
get visible() {
|
|
222
|
+
return this.#visible.value;
|
|
215
223
|
}
|
|
216
224
|
/**
|
|
217
225
|
* Called by the parent layer when it is attached to the map to attach all sublayers.
|
|
@@ -234,15 +242,14 @@ class WMSSublayerImpl extends AbstractLayerBase {
|
|
|
234
242
|
sublayer.__attach(map, parentLayer, this);
|
|
235
243
|
}
|
|
236
244
|
}
|
|
237
|
-
|
|
238
|
-
|
|
245
|
+
/**
|
|
246
|
+
* Called by the parent layer to update the legend on load.
|
|
247
|
+
*/
|
|
248
|
+
__setLegend(legendUrl) {
|
|
249
|
+
this.#legend.value = legendUrl;
|
|
239
250
|
}
|
|
240
251
|
setVisible(newVisibility) {
|
|
241
|
-
|
|
242
|
-
this.#visible = newVisibility;
|
|
243
|
-
this.#parentLayer?.__updateSublayerVisibility();
|
|
244
|
-
this.__emitChangeEvent("changed:visible");
|
|
245
|
-
}
|
|
252
|
+
this.#visible.value = newVisibility;
|
|
246
253
|
}
|
|
247
254
|
}
|
|
248
255
|
function constructSublayers(sublayerConfigs = []) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"WMSLayerImpl.js","sources":["WMSLayerImpl.ts"],"sourcesContent":["// SPDX-FileCopyrightText: 2023 Open Pioneer project (https://github.com/open-pioneer)\n// SPDX-License-Identifier: Apache-2.0\nimport { createLogger, isAbortError } from \"@open-pioneer/core\";\nimport { ImageWrapper } from \"ol\";\nimport WMSCapabilities from \"ol/format/WMSCapabilities\";\nimport ImageLayer from \"ol/layer/Image\";\nimport type ImageSource from \"ol/source/Image\";\nimport ImageWMS from \"ol/source/ImageWMS\";\nimport { WMSLayer, WMSLayerConfig, WMSSublayer, WMSSublayerConfig } from \"../../api\";\nimport { fetchCapabilities } from \"../../util/capabilities-utils\";\nimport { DeferredExecution, defer } from \"../../util/defer\";\nimport { AbstractLayer } from \"../AbstractLayer\";\nimport { AbstractLayerBase } from \"../AbstractLayerBase\";\nimport { MapModelImpl } from \"../MapModelImpl\";\nimport { SublayersCollectionImpl } from \"../SublayersCollectionImpl\";\n\nconst LOG = createLogger(\"map:WMSLayer\");\n\nexport class WMSLayerImpl extends AbstractLayer implements WMSLayer {\n #url: string;\n #sublayers: SublayersCollectionImpl<WMSSublayerImpl>;\n #deferredSublayerUpdate: DeferredExecution | undefined;\n #layer: ImageLayer<ImageSource>;\n #source: ImageWMS;\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n #capabilities: Record<string, any> | undefined;\n readonly #abortController = new AbortController();\n\n constructor(config: WMSLayerConfig) {\n const layer = new ImageLayer();\n super({\n ...config,\n olLayer: layer\n });\n const source = new ImageWMS({\n ...config.sourceOptions,\n url: config.url,\n params: {\n ...config.sourceOptions?.params\n },\n // Use http service to load tiles; needed for authentication etc.\n imageLoadFunction: (wrapper, url) => {\n return this.#loadImage(wrapper, url).catch((error) => {\n LOG.error(`Failed to load tile at '${url}'`, error);\n });\n }\n });\n this.#url = config.url;\n this.#source = source;\n this.#layer = layer;\n this.#sublayers = new SublayersCollectionImpl(constructSublayers(config.sublayers));\n this.#updateLayersParam();\n }\n\n get type() {\n return \"wms\" as const;\n }\n\n get legend() {\n return undefined;\n }\n\n get url(): string {\n return this.#url;\n }\n get __source() {\n return this.#source;\n }\n\n get sublayers(): SublayersCollectionImpl<WMSSublayerImpl> {\n return this.#sublayers;\n }\n\n get capabilities() {\n return this.#capabilities;\n }\n\n __attach(map: MapModelImpl): void {\n super.__attach(map);\n for (const sublayer of this.#sublayers.getSublayers()) {\n sublayer.__attach(map, this, this);\n }\n const layers: WMSSublayerImpl[] = [];\n /** identify all leaf nodes representing a layer in the structure */\n const getNestedSublayer = (sublayers: WMSSublayerImpl[], layers: WMSSublayerImpl[]) => {\n for (const sublayer of sublayers) {\n const nested = sublayer.sublayers.getSublayers();\n if (nested.length) {\n getNestedSublayer(nested, layers);\n } else {\n if (sublayer.name) {\n layers.push(sublayer);\n }\n }\n }\n };\n this.#fetchWMSCapabilities()\n .then((result: string) => {\n const parser = new WMSCapabilities();\n const capabilities = parser.read(result);\n this.#capabilities = capabilities;\n getNestedSublayer(this.#sublayers.getSublayers(), layers);\n\n for (const layer of layers) {\n const legendUrl = getWMSLegendUrl(capabilities, layer.name!);\n layer.legend = legendUrl;\n }\n })\n .catch((error) => {\n if (isAbortError(error)) {\n LOG.error(`Layer ${this.id} has been destroyed before fetching the data`);\n return;\n }\n LOG.error(`Failed fetching WMS capabilities for Layer ${this.id}`, error);\n });\n }\n\n /** Called by the sublayers when their visibility changed. */\n __updateSublayerVisibility() {\n if (this.#deferredSublayerUpdate?.reschedule()) {\n return;\n }\n this.#deferredSublayerUpdate = defer(() => {\n try {\n this.#updateLayersParam();\n this.#deferredSublayerUpdate = undefined;\n } catch (e) {\n LOG.error(`Failed to update sublayer visibility on WMS layer '${this.id}'.`, e);\n }\n });\n }\n\n /**\n * Gathers the visibility of _all_ sublayers and assembles the 'layers' WMS parameter.\n * The parameters are then applied to the WMS source.\n */\n #updateLayersParam() {\n const layers = this.#getVisibleLayerNames();\n this.#source.updateParams({\n \"LAYERS\": layers\n });\n\n // only set source if there are visible sublayers, otherwise\n // we send an invalid http request\n const source = layers.length === 0 ? null : this.#source;\n if (this.#layer.getSource() !== source) {\n this.#layer.setSource(source);\n }\n }\n\n #getVisibleLayerNames() {\n const layers: string[] = [];\n const visitSublayer = (sublayer: WMSSublayerImpl) => {\n if (!sublayer.visible) {\n return;\n }\n\n const nestedSublayers = sublayer.sublayers.__getRawSublayers();\n if (nestedSublayers.length) {\n for (const nestedSublayer of nestedSublayers) {\n visitSublayer(nestedSublayer);\n }\n } else {\n /**\n * Push sublayer only, if layer name is not an empty string | undefined | ...\n */\n if (sublayer.name) {\n layers.push(sublayer.name);\n }\n }\n };\n\n for (const sublayer of this.sublayers.__getRawSublayers()) {\n visitSublayer(sublayer);\n }\n return layers;\n }\n\n async #fetchWMSCapabilities(): Promise<string> {\n const httpService = this.map.__sharedDependencies.httpService;\n const url = `${this.#url}?LANGUAGE=ger&SERVICE=WMS&REQUEST=GetCapabilities`;\n return fetchCapabilities(url, httpService, this.#abortController.signal);\n }\n\n async #loadImage(imageWrapper: ImageWrapper, imageUrl: string): Promise<void> {\n const httpService = this.map.__sharedDependencies.httpService;\n const image = imageWrapper.getImage() as HTMLImageElement;\n\n const response = await httpService.fetch(imageUrl);\n if (!response.ok) {\n throw new Error(`Request failed with status ${response.status}.`);\n }\n\n const blob = await response.blob();\n const objectUrl = URL.createObjectURL(blob);\n const finish = () => {\n // Cleanup object URL after load to prevent memory leaks.\n // https://stackoverflow.com/questions/62473876/openlayers-6-settileloadfunction-documented-example-uses-url-createobjecturld\n URL.revokeObjectURL(objectUrl);\n image.removeEventListener(\"load\", finish);\n image.removeEventListener(\"error\", finish);\n };\n\n image.addEventListener(\"load\", finish);\n image.addEventListener(\"error\", finish);\n image.src = objectUrl;\n }\n}\n\nclass WMSSublayerImpl extends AbstractLayerBase implements WMSSublayer {\n #parent: WMSSublayerImpl | WMSLayerImpl | undefined;\n #parentLayer: WMSLayerImpl | undefined;\n #name: string | undefined;\n #legend: string | undefined;\n #sublayers: SublayersCollectionImpl<WMSSublayerImpl>;\n #visible: boolean;\n\n constructor(config: WMSSublayerConfig) {\n super(config);\n this.#name = config.name;\n this.#visible = config.visible ?? true;\n this.#sublayers = new SublayersCollectionImpl(constructSublayers(config.sublayers));\n }\n\n get type() {\n return \"wms-sublayer\" as const;\n }\n\n get name(): string | undefined {\n return this.#name;\n }\n\n get sublayers(): SublayersCollectionImpl<WMSSublayerImpl> {\n return this.#sublayers;\n }\n\n get parent(): WMSSublayerImpl | WMSLayerImpl {\n const parent = this.#parent;\n if (!parent) {\n throw new Error(`WMS sublayer ${this.id} has not been attached to its parent yet.`);\n }\n return parent;\n }\n\n get parentLayer(): WMSLayerImpl {\n const parentLayer = this.#parentLayer;\n if (!parentLayer) {\n throw new Error(`WMS sublayer ${this.id} has not been attached to its parent yet.`);\n }\n return parentLayer;\n }\n get legend(): string | undefined {\n return this.#legend;\n }\n\n set legend(legendUrl: string | undefined) {\n this.#legend = legendUrl;\n this.__emitChangeEvent(\"changed:legend\");\n }\n\n /**\n * Called by the parent layer when it is attached to the map to attach all sublayers.\n */\n __attach(\n map: MapModelImpl,\n parentLayer: WMSLayerImpl,\n parent: WMSLayerImpl | WMSSublayerImpl\n ): void {\n super.__attachToMap(map);\n if (this.#parent) {\n throw new Error(\n `WMS sublayer '${this.id}' has already been attached to parent '${this.#parent.id}'`\n );\n }\n this.#parent = parent;\n if (this.#parentLayer) {\n throw new Error(\n `WMS sublayer '${this.id}' has already been attached to parent layer '${this.#parentLayer.id}'`\n );\n }\n this.#parentLayer = parentLayer;\n\n // Recurse into nested sublayers\n for (const sublayer of this.sublayers.__getRawSublayers()) {\n sublayer.__attach(map, parentLayer, this);\n }\n }\n\n get visible(): boolean {\n return this.#visible;\n }\n\n setVisible(newVisibility: boolean): void {\n if (this.visible !== newVisibility) {\n this.#visible = newVisibility;\n this.#parentLayer?.__updateSublayerVisibility();\n this.__emitChangeEvent(\"changed:visible\");\n }\n }\n}\n\nfunction constructSublayers(sublayerConfigs: WMSSublayerConfig[] = []): WMSSublayerImpl[] {\n const sublayers: WMSSublayerImpl[] = [];\n try {\n for (const sublayerConfig of sublayerConfigs) {\n sublayers.push(new WMSSublayerImpl(sublayerConfig));\n }\n return sublayers;\n } catch (e) {\n // Ensure previous sublayers are destroyed if a single constructor throws\n while (sublayers.length) {\n const layer = sublayers.pop()!;\n layer?.destroy();\n }\n throw new Error(\"Failed to construct sublayers.\", { cause: e });\n }\n}\n\n/** extract the legend url from the service capabilities */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport function getWMSLegendUrl(capabilities: Record<string, any>, layerName: string) {\n const capabilitiesContent = capabilities?.Capability;\n const rootLayerCapabilities = capabilitiesContent?.Layer;\n let url: string | undefined = undefined;\n\n /** Recurse search for the currrent layer within the parsed capabilities service*/\n //eslint-disable-next-line @typescript-eslint/no-explicit-any\n const searchNestedLayer = (layer: Record<string, any>[]) => {\n for (const currentLayer of layer) {\n // spec. if, a layer has a <Name>, then it is a map layer\n if (currentLayer?.Name === layerName) {\n const activeLayer = currentLayer;\n const styles = activeLayer.Style;\n if (!styles || !styles.length) {\n LOG.debug(\"No style in WMS layer capabilities - giving up.\");\n return;\n }\n // by parsing of the service capabilities, every child inherits the parent's legend\n // theorfore, extract the legendURL from the first style object in the array (its own legend)\n const activeStyle = styles[0];\n url = activeStyle.LegendURL?.[0]?.OnlineResource;\n } else if (currentLayer.Layer) {\n searchNestedLayer(currentLayer.Layer);\n }\n }\n };\n if (rootLayerCapabilities) {\n searchNestedLayer(rootLayerCapabilities.Layer);\n }\n return url;\n}\n"],"names":["layers"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"WMSLayerImpl.js","sources":["WMSLayerImpl.ts"],"sourcesContent":["// SPDX-FileCopyrightText: 2023 Open Pioneer project (https://github.com/open-pioneer)\n// SPDX-License-Identifier: Apache-2.0\nimport {\n batch,\n computed,\n Reactive,\n reactive,\n ReadonlyReactive,\n watch\n} from \"@conterra/reactivity-core\";\nimport { createLogger, destroyResource, isAbortError, Resource } from \"@open-pioneer/core\";\nimport { ImageWrapper } from \"ol\";\nimport WMSCapabilities from \"ol/format/WMSCapabilities\";\nimport ImageLayer from \"ol/layer/Image\";\nimport type ImageSource from \"ol/source/Image\";\nimport ImageWMS from \"ol/source/ImageWMS\";\nimport { WMSLayer, WMSLayerConfig, WMSSublayer, WMSSublayerConfig } from \"../../api\";\nimport { fetchCapabilities } from \"../../util/capabilities-utils\";\nimport { AbstractLayer } from \"../AbstractLayer\";\nimport { AbstractLayerBase } from \"../AbstractLayerBase\";\nimport { MapModelImpl } from \"../MapModelImpl\";\nimport { SublayersCollectionImpl } from \"../SublayersCollectionImpl\";\n\nconst LOG = createLogger(\"map:WMSLayer\");\n\nexport class WMSLayerImpl extends AbstractLayer implements WMSLayer {\n #url: string;\n #sublayers: SublayersCollectionImpl<WMSSublayerImpl>;\n #layer: ImageLayer<ImageSource>;\n #source: ImageWMS;\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n #capabilities: Record<string, any> | undefined;\n readonly #abortController = new AbortController();\n\n #visibleSublayers: ReadonlyReactive<string[]>;\n #sublayersWatch: Resource | undefined;\n\n constructor(config: WMSLayerConfig) {\n const layer = new ImageLayer();\n super({\n ...config,\n olLayer: layer\n });\n const source = new ImageWMS({\n ...config.sourceOptions,\n url: config.url,\n params: {\n ...config.sourceOptions?.params\n },\n // Use http service to load tiles; needed for authentication etc.\n imageLoadFunction: (wrapper, url) => {\n return this.#loadImage(wrapper, url).catch((error) => {\n LOG.error(`Failed to load tile at '${url}'`, error);\n });\n }\n });\n this.#url = config.url;\n this.#source = source;\n this.#layer = layer;\n this.#sublayers = new SublayersCollectionImpl(constructSublayers(config.sublayers));\n this.#visibleSublayers = computed(() => this.#getVisibleLayerNames(), {\n equal(a, b) {\n return a.length === b.length && a.every((v, i) => v === b[i]);\n }\n });\n\n this.#sublayersWatch = watch(\n () => [this.#visibleSublayers.value],\n ([layers]) => {\n this.#updateLayersParam(layers);\n },\n {\n immediate: true\n }\n );\n }\n\n destroy() {\n this.#abortController.abort();\n this.#sublayersWatch = destroyResource(this.#sublayersWatch);\n super.destroy();\n }\n\n get type() {\n return \"wms\" as const;\n }\n\n get legend() {\n return undefined;\n }\n\n get url(): string {\n return this.#url;\n }\n\n get layers(): undefined {\n return undefined;\n }\n\n get sublayers(): SublayersCollectionImpl<WMSSublayerImpl> {\n return this.#sublayers;\n }\n\n get capabilities() {\n return this.#capabilities;\n }\n\n __attachToMap(map: MapModelImpl): void {\n super.__attachToMap(map);\n for (const sublayer of this.#sublayers.getSublayers()) {\n sublayer.__attach(map, this, this);\n }\n\n /** Find all leaf nodes representing a layer in the structure */\n const getNestedSublayer = (sublayers: WMSSublayerImpl[], layers: WMSSublayerImpl[]) => {\n for (const sublayer of sublayers) {\n const nested = sublayer.sublayers.getSublayers();\n if (nested.length) {\n getNestedSublayer(nested, layers);\n } else {\n if (sublayer.name) {\n layers.push(sublayer);\n }\n }\n }\n };\n\n this.#fetchWMSCapabilities()\n .then((result: string) => {\n batch(() => {\n const parser = new WMSCapabilities();\n const capabilities = parser.read(result);\n this.#capabilities = capabilities;\n\n const layers: WMSSublayerImpl[] = [];\n getNestedSublayer(this.#sublayers.getSublayers(), layers);\n\n for (const layer of layers) {\n const legendUrl = getWMSLegendUrl(capabilities, layer.name!);\n layer.__setLegend(legendUrl);\n }\n });\n })\n .catch((error) => {\n if (isAbortError(error)) {\n LOG.debug(`Layer ${this.id} has been destroyed before fetching capabilities`);\n return;\n }\n LOG.error(`Failed to fetch WMS capabilities for layer ${this.id}`, error);\n });\n }\n\n /**\n * Gathers the visibility of _all_ sublayers and assembles the 'layers' WMS parameter.\n * The parameters are then applied to the WMS source.\n */\n #updateLayersParam(layers: string[]) {\n this.#source.updateParams({\n \"LAYERS\": layers\n });\n\n // only set source if there are visible sublayers, otherwise\n // we send an invalid http request\n const source = layers.length === 0 ? null : this.#source;\n if (this.#layer.getSource() !== source) {\n this.#layer.setSource(source);\n }\n }\n\n #getVisibleLayerNames() {\n const layers: string[] = [];\n const visitSublayer = (sublayer: WMSSublayerImpl) => {\n if (!sublayer.visible) {\n return;\n }\n\n const nestedSublayers = sublayer.sublayers.__getRawSublayers();\n if (nestedSublayers.length) {\n for (const nestedSublayer of nestedSublayers) {\n visitSublayer(nestedSublayer);\n }\n } else {\n /**\n * Push sublayer only, if layer name is not an empty string | undefined | ...\n */\n if (sublayer.name) {\n layers.push(sublayer.name);\n }\n }\n };\n\n for (const sublayer of this.sublayers.__getRawSublayers()) {\n visitSublayer(sublayer);\n }\n return layers;\n }\n\n async #fetchWMSCapabilities(): Promise<string> {\n const httpService = this.map.__sharedDependencies.httpService;\n const url = `${this.#url}?LANGUAGE=ger&SERVICE=WMS&REQUEST=GetCapabilities`;\n return fetchCapabilities(url, httpService, this.#abortController.signal);\n }\n\n async #loadImage(imageWrapper: ImageWrapper, imageUrl: string): Promise<void> {\n const httpService = this.map.__sharedDependencies.httpService;\n const image = imageWrapper.getImage() as HTMLImageElement;\n\n const response = await httpService.fetch(imageUrl);\n if (!response.ok) {\n throw new Error(`Request failed with status ${response.status}.`);\n }\n\n const blob = await response.blob();\n const objectUrl = URL.createObjectURL(blob);\n const finish = () => {\n // Cleanup object URL after load to prevent memory leaks.\n // https://stackoverflow.com/questions/62473876/openlayers-6-settileloadfunction-documented-example-uses-url-createobjecturld\n URL.revokeObjectURL(objectUrl);\n image.removeEventListener(\"load\", finish);\n image.removeEventListener(\"error\", finish);\n };\n\n image.addEventListener(\"load\", finish);\n image.addEventListener(\"error\", finish);\n image.src = objectUrl;\n }\n}\n\nclass WMSSublayerImpl extends AbstractLayerBase implements WMSSublayer {\n #parent: WMSSublayerImpl | WMSLayerImpl | undefined;\n #parentLayer: WMSLayerImpl | undefined;\n #name: string | undefined;\n #legend = reactive<string | undefined>();\n #sublayers: SublayersCollectionImpl<WMSSublayerImpl>;\n #visible: Reactive<boolean>;\n\n constructor(config: WMSSublayerConfig) {\n super(config);\n this.#name = config.name;\n this.#visible = reactive(config.visible ?? true);\n this.#sublayers = new SublayersCollectionImpl(constructSublayers(config.sublayers));\n }\n\n get type() {\n return \"wms-sublayer\" as const;\n }\n\n get name(): string | undefined {\n return this.#name;\n }\n\n get layers(): undefined {\n return undefined;\n }\n\n get sublayers(): SublayersCollectionImpl<WMSSublayerImpl> {\n return this.#sublayers;\n }\n\n get parent(): WMSSublayerImpl | WMSLayerImpl {\n const parent = this.#parent;\n if (!parent) {\n throw new Error(`WMS sublayer ${this.id} has not been attached to its parent yet.`);\n }\n return parent;\n }\n\n get parentLayer(): WMSLayerImpl {\n const parentLayer = this.#parentLayer;\n if (!parentLayer) {\n throw new Error(`WMS sublayer ${this.id} has not been attached to its parent yet.`);\n }\n return parentLayer;\n }\n\n get legend(): string | undefined {\n return this.#legend.value;\n }\n\n get visible(): boolean {\n return this.#visible.value;\n }\n\n /**\n * Called by the parent layer when it is attached to the map to attach all sublayers.\n */\n __attach(\n map: MapModelImpl,\n parentLayer: WMSLayerImpl,\n parent: WMSLayerImpl | WMSSublayerImpl\n ): void {\n super.__attachToMap(map);\n if (this.#parent) {\n throw new Error(\n `WMS sublayer '${this.id}' has already been attached to parent '${this.#parent.id}'`\n );\n }\n this.#parent = parent;\n if (this.#parentLayer) {\n throw new Error(\n `WMS sublayer '${this.id}' has already been attached to parent layer '${this.#parentLayer.id}'`\n );\n }\n this.#parentLayer = parentLayer;\n\n // Recurse into nested sublayers\n for (const sublayer of this.sublayers.__getRawSublayers()) {\n sublayer.__attach(map, parentLayer, this);\n }\n }\n\n /**\n * Called by the parent layer to update the legend on load.\n */\n __setLegend(legendUrl: string | undefined) {\n this.#legend.value = legendUrl;\n }\n\n setVisible(newVisibility: boolean): void {\n this.#visible.value = newVisibility;\n }\n}\n\nfunction constructSublayers(sublayerConfigs: WMSSublayerConfig[] = []): WMSSublayerImpl[] {\n const sublayers: WMSSublayerImpl[] = [];\n try {\n for (const sublayerConfig of sublayerConfigs) {\n sublayers.push(new WMSSublayerImpl(sublayerConfig));\n }\n return sublayers;\n } catch (e) {\n // Ensure previous sublayers are destroyed if a single constructor throws\n while (sublayers.length) {\n const layer = sublayers.pop()!;\n layer?.destroy();\n }\n throw new Error(\"Failed to construct sublayers.\", { cause: e });\n }\n}\n\n/** extract the legend url from the service capabilities */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport function getWMSLegendUrl(capabilities: Record<string, any>, layerName: string) {\n const capabilitiesContent = capabilities?.Capability;\n const rootLayerCapabilities = capabilitiesContent?.Layer;\n let url: string | undefined = undefined;\n\n /** Recurse search for the currrent layer within the parsed capabilities service*/\n //eslint-disable-next-line @typescript-eslint/no-explicit-any\n const searchNestedLayer = (layer: Record<string, any>[]) => {\n for (const currentLayer of layer) {\n // spec. if, a layer has a <Name>, then it is a map layer\n if (currentLayer?.Name === layerName) {\n const activeLayer = currentLayer;\n const styles = activeLayer.Style;\n if (!styles || !styles.length) {\n LOG.debug(\"No style in WMS layer capabilities - giving up.\");\n return;\n }\n // by parsing of the service capabilities, every child inherits the parent's legend\n // theorfore, extract the legendURL from the first style object in the array (its own legend)\n const activeStyle = styles[0];\n url = activeStyle.LegendURL?.[0]?.OnlineResource;\n } else if (currentLayer.Layer) {\n searchNestedLayer(currentLayer.Layer);\n }\n }\n };\n if (rootLayerCapabilities) {\n searchNestedLayer(rootLayerCapabilities.Layer);\n }\n return url;\n}\n"],"names":[],"mappings":"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"}
|
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
import TileLayer from "ol/layer/Tile";
|
|
2
|
-
import type TileSourceType from "ol/source/Tile";
|
|
3
1
|
import { WMTSLayer, WMTSLayerConfig } from "../../api";
|
|
4
2
|
import { AbstractLayer } from "../AbstractLayer";
|
|
5
3
|
import { MapModelImpl } from "../MapModelImpl";
|
|
@@ -9,11 +7,11 @@ export declare class WMTSLayerImpl extends AbstractLayer implements WMTSLayer {
|
|
|
9
7
|
get type(): "wmts";
|
|
10
8
|
destroy(): void;
|
|
11
9
|
get legend(): string | undefined;
|
|
12
|
-
|
|
13
|
-
get
|
|
10
|
+
get sublayers(): undefined;
|
|
11
|
+
get layers(): undefined;
|
|
12
|
+
__attachToMap(map: MapModelImpl): void;
|
|
14
13
|
get url(): string;
|
|
15
14
|
get name(): string;
|
|
16
15
|
get matrixSet(): string;
|
|
17
|
-
get sublayers(): undefined;
|
|
18
16
|
}
|
|
19
17
|
export declare function getWMTSLegendUrl(capabilities: Record<string, any>, activeLayerId: string | undefined, activeStyleId: string | undefined): string | undefined;
|
|
@@ -6,6 +6,7 @@ import WMTS, { optionsFromCapabilities } from 'ol/source/WMTS.js';
|
|
|
6
6
|
import { fetchCapabilities } from '../../util/capabilities-utils.js';
|
|
7
7
|
import { AbstractLayer } from '../AbstractLayer.js';
|
|
8
8
|
import { ImageTile } from 'ol';
|
|
9
|
+
import { reactive } from '@conterra/reactivity-core';
|
|
9
10
|
|
|
10
11
|
const LOG = createLogger("map:WMTSLayer");
|
|
11
12
|
class WMTSLayerImpl extends AbstractLayer {
|
|
@@ -14,8 +15,8 @@ class WMTSLayerImpl extends AbstractLayer {
|
|
|
14
15
|
#matrixSet;
|
|
15
16
|
#layer;
|
|
16
17
|
#source;
|
|
17
|
-
#legend;
|
|
18
18
|
#sourceOptions;
|
|
19
|
+
#legend = reactive();
|
|
19
20
|
#abortController = new AbortController();
|
|
20
21
|
constructor(config) {
|
|
21
22
|
const layer = new TileLayer();
|
|
@@ -33,14 +34,20 @@ class WMTSLayerImpl extends AbstractLayer {
|
|
|
33
34
|
return "wmts";
|
|
34
35
|
}
|
|
35
36
|
destroy() {
|
|
36
|
-
super.destroy();
|
|
37
37
|
this.#abortController.abort();
|
|
38
|
+
super.destroy();
|
|
38
39
|
}
|
|
39
40
|
get legend() {
|
|
40
|
-
return this.#legend;
|
|
41
|
+
return this.#legend.value;
|
|
42
|
+
}
|
|
43
|
+
get sublayers() {
|
|
44
|
+
return void 0;
|
|
41
45
|
}
|
|
42
|
-
|
|
43
|
-
|
|
46
|
+
get layers() {
|
|
47
|
+
return void 0;
|
|
48
|
+
}
|
|
49
|
+
__attachToMap(map) {
|
|
50
|
+
super.__attachToMap(map);
|
|
44
51
|
this.#fetchWMTSCapabilities().then((result) => {
|
|
45
52
|
const parser = new WMTSCapabilities();
|
|
46
53
|
const capabilities = parser.read(result);
|
|
@@ -62,8 +69,7 @@ class WMTSLayerImpl extends AbstractLayer {
|
|
|
62
69
|
this.#layer.setSource(this.#source);
|
|
63
70
|
const activeStyleId = source.getStyle();
|
|
64
71
|
const legendUrl = getWMTSLegendUrl(capabilities, this.name, activeStyleId);
|
|
65
|
-
this.#legend = legendUrl;
|
|
66
|
-
this.__emitChangeEvent("changed:legend");
|
|
72
|
+
this.#legend.value = legendUrl;
|
|
67
73
|
}).catch((error) => {
|
|
68
74
|
if (isAbortError(error)) {
|
|
69
75
|
LOG.error(`Layer ${this.name} has been destroyed before fetching the data`);
|
|
@@ -72,9 +78,6 @@ class WMTSLayerImpl extends AbstractLayer {
|
|
|
72
78
|
LOG.error(`Failed fetching WMTS capabilities for Layer ${this.name}`, error);
|
|
73
79
|
});
|
|
74
80
|
}
|
|
75
|
-
get layer() {
|
|
76
|
-
return this.#layer;
|
|
77
|
-
}
|
|
78
81
|
get url() {
|
|
79
82
|
return this.#url;
|
|
80
83
|
}
|
|
@@ -84,9 +87,6 @@ class WMTSLayerImpl extends AbstractLayer {
|
|
|
84
87
|
get matrixSet() {
|
|
85
88
|
return this.#matrixSet;
|
|
86
89
|
}
|
|
87
|
-
get sublayers() {
|
|
88
|
-
return void 0;
|
|
89
|
-
}
|
|
90
90
|
async #fetchWMTSCapabilities() {
|
|
91
91
|
const httpService = this.map.__sharedDependencies.httpService;
|
|
92
92
|
return fetchCapabilities(this.#url, httpService, this.#abortController.signal);
|