@open-pioneer/map 1.4.0-dev.20260727093741 → 1.4.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 +39 -21
- package/LayerFactory.d.ts +1 -1
- package/LayerFactory.js.map +1 -1
- package/MapRegistry.js.map +1 -1
- package/layers/AbstractLayer.d.ts +36 -3
- package/layers/AbstractLayer.js +123 -79
- package/layers/AbstractLayer.js.map +1 -1
- package/layers/AbstractLayerBase.d.ts +2 -2
- package/layers/AbstractLayerBase.js.map +1 -1
- package/layers/GroupLayer.d.ts +2 -1
- package/layers/GroupLayer.js +4 -1
- package/layers/GroupLayer.js.map +1 -1
- package/layers/SimpleLayer.d.ts +1 -1
- package/layers/SimpleLayer.js +1 -1
- package/layers/SimpleLayer.js.map +1 -1
- package/layers/WMSLayer.js +58 -10
- package/layers/WMSLayer.js.map +1 -1
- package/layers/WMTSLayer.d.ts +1 -1
- package/layers/WMTSLayer.js +10 -4
- package/layers/WMTSLayer.js.map +1 -1
- package/layers/group/GroupLayerCollection.d.ts +2 -2
- package/layers/group/GroupLayerCollection.js +1 -1
- package/layers/group/GroupLayerCollection.js.map +1 -1
- package/layers/shared/SublayerBaseType.d.ts +9 -0
- package/layers/shared/SublayersCollection.js.map +1 -1
- package/layers/shared/getRecursiveLayers.d.ts +1 -1
- package/layers/shared/getRecursiveLayers.js +12 -5
- package/layers/shared/getRecursiveLayers.js.map +1 -1
- package/layers/shared/internals.d.ts +3 -2
- package/layers/shared/internals.js +2 -1
- package/layers/shared/internals.js.map +1 -1
- package/layers/unions.js.map +1 -1
- package/layers/wms/WMSSublayer.d.ts +14 -1
- package/layers/wms/WMSSublayer.js +29 -2
- package/layers/wms/WMSSublayer.js.map +1 -1
- package/layers/wms/getAttributions.js.map +1 -1
- package/layers/wms/getLegendUrl.js.map +1 -1
- package/layers/wmts/getAttributions.js.map +1 -1
- package/layers/wmts/getLegendUrl.js.map +1 -1
- package/model/Highlights.js.map +1 -1
- package/model/LayerCollection.js.map +1 -1
- package/model/MapAttributions.js.map +1 -1
- package/model/MapModel.d.ts +5 -5
- package/model/MapModel.js +4 -4
- package/model/MapModel.js.map +1 -1
- package/model/Overlays.d.ts +2 -2
- package/model/Overlays.js +2 -2
- package/model/Overlays.js.map +1 -1
- package/model/createMapModel.js +2 -2
- package/model/createMapModel.js.map +1 -1
- package/model/getGeometries.js.map +1 -1
- package/package.json +7 -7
- package/ui/DefaultMapProvider.js.map +1 -1
- package/ui/MapAnchor.js.map +1 -1
- package/ui/MapContainer.js +1 -1
- package/ui/MapContainer.js.map +1 -1
- package/ui/MapContainerContext.js.map +1 -1
- package/ui/OverlaysRenderer.js.map +1 -1
- package/ui/computeMapAnchorStyles.js.map +1 -1
- package/ui/hooks/useMapModel.js +2 -2
- package/ui/hooks/useMapModel.js.map +1 -1
- package/utils/fetch.js.map +1 -1
- package/utils/geometry-utils.js.map +1 -1
- package/utils/ol-test-support.js.map +1 -1
- package/utils/projections.js.map +1 -1
- package/utils/sanitize.js.map +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AbstractLayer.js","sources":["AbstractLayer.ts"],"sourcesContent":["// SPDX-FileCopyrightText: 2023-2025 Open Pioneer project (https://github.com/open-pioneer)\n// SPDX-License-Identifier: Apache-2.0\nimport {\n computed,\n reactive,\n Reactive,\n ReadonlyReactive,\n synchronized\n} from \"@conterra/reactivity-core\";\nimport { createLogger, destroyResource, Resource } from \"@open-pioneer/core\";\nimport { EventsKey } from \"ol/events\";\nimport OlBaseLayer from \"ol/layer/Base\";\nimport OlLayer from \"ol/layer/Layer\";\nimport { unByKey } from \"ol/Observable\";\nimport OlSource from \"ol/source/Source\";\nimport { sourceId } from \"open-pioneer:source-info\";\nimport { MapModel } from \"../model/MapModel\";\nimport { InternalConstructorTag } from \"../utils/InternalConstructorTag\";\nimport { AbstractLayerBase } from \"./AbstractLayerBase\";\nimport {\n ATTACH_TO_MAP,\n GET_DEPS,\n getLayerDependencies,\n LAYER_DEPS,\n LayerDependencies,\n SET_VISIBLE\n} from \"./shared/internals\";\nimport { HealthCheckFunction, LayerConfig } from \"./shared/LayerConfig\";\nimport { SimpleLayer, SimpleLayerConfig } from \"./SimpleLayer\";\nimport { Layer, LayerTypes } from \"./unions\";\n\nconst LOG = createLogger(sourceId);\n\n/**\n * The load state of a layer.\n *\n * @group Layer Utilities\n **/\nexport type LayerLoadState = \"not-loaded\" | \"loading\" | \"loaded\" | \"error\";\n\n/**\n * Represents an operational layer in the map.\n *\n * These layers always have an associated OpenLayers layer.\n *\n * Instances of this interface cannot be constructed directly; use a real layer\n * class such as {@link SimpleLayer} instead.\n *\n * @group Layers\n */\nexport abstract class AbstractLayer extends AbstractLayerBase {\n // Layer dependencies are present when the LayerFactory API was used to construct the layer.\n // They may currently be undefined for compatibility reasons (in which case they will be used\n // from the map, once connected).\n #deps: LayerDependencies | undefined;\n #olLayer: OlBaseLayer;\n #isBaseLayer: boolean;\n #healthCheck?: string | HealthCheckFunction;\n\n #visible: ReadonlyReactive<boolean>;\n #minResolution: ReadonlyReactive<number>;\n #maxResolution: ReadonlyReactive<number>;\n #minZoom: ReadonlyReactive<number>;\n #maxZoom: ReadonlyReactive<number>;\n #loadState: Reactive<LayerLoadState>;\n\n #stateWatchResource: Resource | undefined;\n\n #visibleInScale: ReadonlyReactive<boolean>;\n\n constructor(\n config: SimpleLayerConfig,\n deps?: LayerDependencies,\n internalTag?: InternalConstructorTag\n ) {\n super(config);\n this.#deps = getLayerDependencies(deps, internalTag);\n this.#olLayer = config.olLayer;\n this.#isBaseLayer = config.isBaseLayer ?? false;\n this.#healthCheck = config.healthCheck;\n this.#visible = synchronized(\n () => this.#olLayer.getVisible(),\n (cb) => {\n const key = this.#olLayer.on(\"change:visible\", cb);\n return () => unByKey(key);\n }\n );\n this.#minResolution = synchronized(\n () => this.#olLayer.getMinResolution(),\n (cb) => {\n const key = this.#olLayer.on(\"change:minResolution\", cb);\n return () => unByKey(key);\n }\n );\n this.#maxResolution = synchronized(\n () => this.#olLayer.getMaxResolution(),\n (cb) => {\n const key = this.#olLayer.on(\"change:maxResolution\", cb);\n return () => unByKey(key);\n }\n );\n this.#minZoom = synchronized(\n () => this.#olLayer.getMinZoom(),\n (cb) => {\n const key = this.#olLayer.on(\"change:minZoom\", cb);\n return () => unByKey(key);\n }\n );\n this.#maxZoom = synchronized(\n () => this.#olLayer.getMaxZoom(),\n (cb) => {\n const key = this.#olLayer.on(\"change:maxZoom\", cb);\n return () => unByKey(key);\n }\n );\n\n this.#loadState = reactive(getSourceState(getSource(this.#olLayer)));\n\n this[SET_VISIBLE](config.visible ?? true); // apply initial visibility\n\n this.#visibleInScale = computed(() => {\n const map = this.nullableMap; // handle case where not in the map yet\n if (!map) {\n return true; // or false? doesn't really matter\n }\n\n const zoom = map.zoomLevel;\n const resolution = map.resolution;\n if (zoom == null || resolution == null) {\n return false;\n }\n\n const parent = this.parent;\n if (parent && parent.type === \"group\" && !parent.visibleInScale) {\n return false;\n }\n\n if (resolution < this.minResolution || resolution >= this.maxResolution) {\n return false;\n }\n\n return zoom > this.minZoom && zoom <= this.maxZoom;\n });\n\n if (config.maxResolution) {\n this.#olLayer.setMaxResolution(config.maxResolution);\n }\n if (config.minResolution) {\n this.#olLayer.setMinResolution(config.minResolution);\n }\n\n if (config.maxZoom) {\n this.#olLayer.setMaxZoom(config.maxZoom);\n }\n if (config.minZoom) {\n this.#olLayer.setMinZoom(config.minZoom);\n }\n }\n\n override destroy() {\n if (this.isDestroyed) {\n return;\n }\n\n this.#stateWatchResource = destroyResource(this.#stateWatchResource);\n this.olLayer.dispose();\n super.destroy();\n }\n\n /**\n * Identifies the type of this layer.\n */\n abstract override readonly type: LayerTypes;\n\n override get visible(): boolean {\n return this.#visible.value;\n }\n\n /**\n * The raw OpenLayers layer.\n */\n get olLayer(): OlBaseLayer {\n return this.#olLayer;\n }\n\n /**\n * True if this layer is a base layer.\n *\n * Only one base layer can be visible at a time.\n */\n get isBaseLayer(): boolean {\n return this.#isBaseLayer;\n }\n\n /**\n * The load state of a layer.\n */\n get loadState(): LayerLoadState {\n return this.#loadState.value;\n }\n\n /**\n * The minimum resolution (inclusive) at which this layer will be visible.\n */\n get minResolution() {\n return this.#minResolution.value;\n }\n\n /**\n * The maximum resolution (exclusive) below which this layer will be visible.\n */\n get maxResolution() {\n return this.#maxResolution.value;\n }\n\n /**\n * The minimum view zoom level (exclusive) above which this layer will be visible.\n */\n get minZoom() {\n return this.#minZoom.value;\n }\n\n /**\n * The maximum view zoom level (inclusive) at which this layer will be visible.\n */\n get maxZoom() {\n return this.#maxZoom.value;\n }\n\n /**\n * Whether the layer is visible in the current map scale or not.\n */\n get visibleInScale(): boolean {\n return this.#visibleInScale.value;\n }\n\n /**\n * The minimum resolution (inclusive) at which this layer will be visible.\n */\n setMinResolution(value: number): void {\n this.#olLayer.setMinResolution(value);\n }\n\n /**\n * The maximum resolution (exclusive) below which this layer will be visible.\n */\n setMaxResolution(value: number): void {\n this.#olLayer.setMaxResolution(value);\n }\n\n /**\n * The minimum view zoom level (exclusive) above which this layer will be visible.\n */\n setMinZoom(value: number): void {\n this.#olLayer.setMinZoom(value);\n }\n\n /**\n * The maximum view zoom level (inclusive) at which this layer will be visible.\n */\n setMaxZoom(value: number): void {\n this.#olLayer.setMaxZoom(value);\n }\n\n /**\n * Called by the map model when the layer is added to the map.\n *\n * @internal\n */\n override [ATTACH_TO_MAP](map: MapModel): void {\n super[ATTACH_TO_MAP](map);\n\n if (!this.#stateWatchResource) {\n const { initial: initialState, resource: stateWatchResource } = watchLoadState(\n this,\n this.#healthCheck,\n (state) => {\n this.#loadState.value = state;\n }\n );\n this.#stateWatchResource = stateWatchResource;\n this.#loadState.value = initialState;\n }\n }\n\n override setVisible(newVisibility: boolean): void {\n if (this.isBaseLayer) {\n LOG.warn(\n `Cannot change visibility of base layer '${this.id}': use activateBaseLayer() on the map's LayerCollection instead.`\n );\n return;\n }\n\n this[SET_VISIBLE](newVisibility);\n }\n\n /** @internal */\n [SET_VISIBLE](newVisibility: boolean): void {\n if (this.#olLayer.getVisible() !== newVisibility) {\n this.#olLayer.setVisible(newVisibility);\n }\n }\n\n /** @internal */\n [GET_DEPS](): LayerDependencies {\n const deps = this.#deps;\n if (deps) {\n return deps;\n }\n\n const map = this.nullableMap;\n if (map) {\n return map[LAYER_DEPS];\n }\n throw new Error(\n `Layer '${this.id}' has not been attached to a map yet. \"\n + \"Use the LayerFactory to create an instance or add the layer to the map first.`\n );\n }\n}\n\nfunction watchLoadState(\n layer: AbstractLayer,\n healthCheck: LayerConfig[\"healthCheck\"],\n onChange: (newState: LayerLoadState) => void\n): { initial: LayerLoadState; resource: Resource } {\n const olLayer = layer.olLayer;\n\n if (!(olLayer instanceof OlLayer)) {\n // Some layers don't have a source (such as group)\n return {\n initial: \"loaded\",\n resource: {\n destroy() {\n void 0;\n }\n }\n };\n }\n\n let currentSource = getSource(olLayer);\n const currentOlLayerState = getSourceState(currentSource);\n\n let currentLoadState: LayerLoadState = currentOlLayerState;\n let currentHealthState = \"loading\"; // initial state loading until health check finished\n\n // custom health check not needed when OpenLayers already returning an error state\n if (currentOlLayerState !== \"error\") {\n // health check only once during initialization\n doHealthCheck(layer, healthCheck).then((state: LayerLoadState) => {\n currentHealthState = state;\n updateState();\n });\n }\n\n const updateState = () => {\n const olLayerState = getSourceState(currentSource);\n const nextLoadState: LayerLoadState =\n currentHealthState === \"error\" ? \"error\" : olLayerState;\n\n if (currentLoadState !== nextLoadState) {\n currentLoadState = nextLoadState;\n onChange(currentLoadState);\n }\n };\n\n let stateHandle: EventsKey | undefined;\n stateHandle = currentSource?.on(\"change\", () => {\n updateState();\n });\n\n const sourceHandle = olLayer.on(\"change:source\", () => {\n // unsubscribe from old source\n stateHandle && unByKey(stateHandle);\n stateHandle = undefined;\n\n // subscribe to new source and update state\n currentSource = getSource(olLayer);\n stateHandle = currentSource?.on(\"change\", () => {\n updateState();\n });\n updateState();\n });\n return {\n initial: currentLoadState,\n resource: {\n destroy() {\n stateHandle && unByKey(stateHandle);\n unByKey(sourceHandle);\n }\n }\n };\n}\n\nasync function doHealthCheck(\n layer: AbstractLayer,\n healthCheck: LayerConfig[\"healthCheck\"]\n): Promise<LayerLoadState> {\n if (healthCheck == null) {\n return \"loaded\";\n }\n\n let healthCheckFn: HealthCheckFunction;\n if (typeof healthCheck === \"function\") {\n healthCheckFn = healthCheck;\n } else if (typeof healthCheck === \"string\") {\n healthCheckFn = async () => {\n const httpService = layer[GET_DEPS]().httpService;\n const response = await httpService.fetch(healthCheck);\n if (response.ok) {\n return \"loaded\";\n }\n LOG.warn(\n `Health check failed for layer '${layer.id}' (http status ${response.status})`\n );\n return \"error\";\n };\n } else {\n LOG.error(\n `Unexpected object for 'healthCheck' parameter of layer '${layer.id}'`,\n healthCheck\n );\n return \"error\";\n }\n\n try {\n return await healthCheckFn(layer as Layer);\n } catch (e) {\n LOG.warn(`Health check failed for layer '${layer.id}'`, e);\n return \"error\";\n }\n}\n\nfunction getSource(olLayer: OlLayer | OlBaseLayer) {\n if (!(olLayer instanceof OlLayer)) {\n return undefined;\n }\n return (olLayer?.getSource() as OlSource | null) ?? undefined;\n}\n\nfunction getSourceState(olSource: OlSource | undefined) {\n const state = olSource?.getState();\n switch (state) {\n case undefined:\n return \"loaded\";\n case \"undefined\":\n return \"not-loaded\";\n case \"loading\":\n return \"loading\";\n case \"ready\":\n return \"loaded\";\n case \"error\":\n return \"error\";\n }\n}\n"],"names":[],"mappings":";;;;;;;;AA+BA,MAAM,GAAA,GAAM,aAAa,QAAQ,CAAA;AAmB1B,MAAe,sBAAsB,iBAAA,CAAkB;AAAA;AAAA;AAAA;AAAA,EAI1D,KAAA;AAAA,EACA,QAAA;AAAA,EACA,YAAA;AAAA,EACA,YAAA;AAAA,EAEA,QAAA;AAAA,EACA,cAAA;AAAA,EACA,cAAA;AAAA,EACA,QAAA;AAAA,EACA,QAAA;AAAA,EACA,UAAA;AAAA,EAEA,mBAAA;AAAA,EAEA,eAAA;AAAA,EAEA,WAAA,CACI,MAAA,EACA,IAAA,EACA,WAAA,EACF;AACE,IAAA,KAAA,CAAM,MAAM,CAAA;AACZ,IAAA,IAAA,CAAK,KAAA,GAAQ,oBAAA,CAAqB,IAAA,EAAM,WAAW,CAAA;AACnD,IAAA,IAAA,CAAK,WAAW,MAAA,CAAO,OAAA;AACvB,IAAA,IAAA,CAAK,YAAA,GAAe,OAAO,WAAA,IAAe,KAAA;AAC1C,IAAA,IAAA,CAAK,eAAe,MAAA,CAAO,WAAA;AAC3B,IAAA,IAAA,CAAK,QAAA,GAAW,YAAA;AAAA,MACZ,MAAM,IAAA,CAAK,QAAA,CAAS,UAAA,EAAW;AAAA,MAC/B,CAAC,EAAA,KAAO;AACJ,QAAA,MAAM,GAAA,GAAM,IAAA,CAAK,QAAA,CAAS,EAAA,CAAG,kBAAkB,EAAE,CAAA;AACjD,QAAA,OAAO,MAAM,QAAQ,GAAG,CAAA;AAAA,MAC5B;AAAA,KACJ;AACA,IAAA,IAAA,CAAK,cAAA,GAAiB,YAAA;AAAA,MAClB,MAAM,IAAA,CAAK,QAAA,CAAS,gBAAA,EAAiB;AAAA,MACrC,CAAC,EAAA,KAAO;AACJ,QAAA,MAAM,GAAA,GAAM,IAAA,CAAK,QAAA,CAAS,EAAA,CAAG,wBAAwB,EAAE,CAAA;AACvD,QAAA,OAAO,MAAM,QAAQ,GAAG,CAAA;AAAA,MAC5B;AAAA,KACJ;AACA,IAAA,IAAA,CAAK,cAAA,GAAiB,YAAA;AAAA,MAClB,MAAM,IAAA,CAAK,QAAA,CAAS,gBAAA,EAAiB;AAAA,MACrC,CAAC,EAAA,KAAO;AACJ,QAAA,MAAM,GAAA,GAAM,IAAA,CAAK,QAAA,CAAS,EAAA,CAAG,wBAAwB,EAAE,CAAA;AACvD,QAAA,OAAO,MAAM,QAAQ,GAAG,CAAA;AAAA,MAC5B;AAAA,KACJ;AACA,IAAA,IAAA,CAAK,QAAA,GAAW,YAAA;AAAA,MACZ,MAAM,IAAA,CAAK,QAAA,CAAS,UAAA,EAAW;AAAA,MAC/B,CAAC,EAAA,KAAO;AACJ,QAAA,MAAM,GAAA,GAAM,IAAA,CAAK,QAAA,CAAS,EAAA,CAAG,kBAAkB,EAAE,CAAA;AACjD,QAAA,OAAO,MAAM,QAAQ,GAAG,CAAA;AAAA,MAC5B;AAAA,KACJ;AACA,IAAA,IAAA,CAAK,QAAA,GAAW,YAAA;AAAA,MACZ,MAAM,IAAA,CAAK,QAAA,CAAS,UAAA,EAAW;AAAA,MAC/B,CAAC,EAAA,KAAO;AACJ,QAAA,MAAM,GAAA,GAAM,IAAA,CAAK,QAAA,CAAS,EAAA,CAAG,kBAAkB,EAAE,CAAA;AACjD,QAAA,OAAO,MAAM,QAAQ,GAAG,CAAA;AAAA,MAC5B;AAAA,KACJ;AAEA,IAAA,IAAA,CAAK,aAAa,QAAA,CAAS,cAAA,CAAe,UAAU,IAAA,CAAK,QAAQ,CAAC,CAAC,CAAA;AAEnE,IAAA,IAAA,CAAK,WAAW,CAAA,CAAE,MAAA,CAAO,OAAA,IAAW,IAAI,CAAA;AAExC,IAAA,IAAA,CAAK,eAAA,GAAkB,SAAS,MAAM;AAClC,MAAA,MAAM,MAAM,IAAA,CAAK,WAAA;AACjB,MAAA,IAAI,CAAC,GAAA,EAAK;AACN,QAAA,OAAO,IAAA;AAAA,MACX;AAEA,MAAA,MAAM,OAAO,GAAA,CAAI,SAAA;AACjB,MAAA,MAAM,aAAa,GAAA,CAAI,UAAA;AACvB,MAAA,IAAI,IAAA,IAAQ,IAAA,IAAQ,UAAA,IAAc,IAAA,EAAM;AACpC,QAAA,OAAO,KAAA;AAAA,MACX;AAEA,MAAA,MAAM,SAAS,IAAA,CAAK,MAAA;AACpB,MAAA,IAAI,UAAU,MAAA,CAAO,IAAA,KAAS,OAAA,IAAW,CAAC,OAAO,cAAA,EAAgB;AAC7D,QAAA,OAAO,KAAA;AAAA,MACX;AAEA,MAAA,IAAI,UAAA,GAAa,IAAA,CAAK,aAAA,IAAiB,UAAA,IAAc,KAAK,aAAA,EAAe;AACrE,QAAA,OAAO,KAAA;AAAA,MACX;AAEA,MAAA,OAAO,IAAA,GAAO,IAAA,CAAK,OAAA,IAAW,IAAA,IAAQ,IAAA,CAAK,OAAA;AAAA,IAC/C,CAAC,CAAA;AAED,IAAA,IAAI,OAAO,aAAA,EAAe;AACtB,MAAA,IAAA,CAAK,QAAA,CAAS,gBAAA,CAAiB,MAAA,CAAO,aAAa,CAAA;AAAA,IACvD;AACA,IAAA,IAAI,OAAO,aAAA,EAAe;AACtB,MAAA,IAAA,CAAK,QAAA,CAAS,gBAAA,CAAiB,MAAA,CAAO,aAAa,CAAA;AAAA,IACvD;AAEA,IAAA,IAAI,OAAO,OAAA,EAAS;AAChB,MAAA,IAAA,CAAK,QAAA,CAAS,UAAA,CAAW,MAAA,CAAO,OAAO,CAAA;AAAA,IAC3C;AACA,IAAA,IAAI,OAAO,OAAA,EAAS;AAChB,MAAA,IAAA,CAAK,QAAA,CAAS,UAAA,CAAW,MAAA,CAAO,OAAO,CAAA;AAAA,IAC3C;AAAA,EACJ;AAAA,EAES,OAAA,GAAU;AACf,IAAA,IAAI,KAAK,WAAA,EAAa;AAClB,MAAA;AAAA,IACJ;AAEA,IAAA,IAAA,CAAK,mBAAA,GAAsB,eAAA,CAAgB,IAAA,CAAK,mBAAmB,CAAA;AACnE,IAAA,IAAA,CAAK,QAAQ,OAAA,EAAQ;AACrB,IAAA,KAAA,CAAM,OAAA,EAAQ;AAAA,EAClB;AAAA,EAOA,IAAa,OAAA,GAAmB;AAC5B,IAAA,OAAO,KAAK,QAAA,CAAS,KAAA;AAAA,EACzB;AAAA;AAAA;AAAA;AAAA,EAKA,IAAI,OAAA,GAAuB;AACvB,IAAA,OAAO,IAAA,CAAK,QAAA;AAAA,EAChB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,IAAI,WAAA,GAAuB;AACvB,IAAA,OAAO,IAAA,CAAK,YAAA;AAAA,EAChB;AAAA;AAAA;AAAA;AAAA,EAKA,IAAI,SAAA,GAA4B;AAC5B,IAAA,OAAO,KAAK,UAAA,CAAW,KAAA;AAAA,EAC3B;AAAA;AAAA;AAAA;AAAA,EAKA,IAAI,aAAA,GAAgB;AAChB,IAAA,OAAO,KAAK,cAAA,CAAe,KAAA;AAAA,EAC/B;AAAA;AAAA;AAAA;AAAA,EAKA,IAAI,aAAA,GAAgB;AAChB,IAAA,OAAO,KAAK,cAAA,CAAe,KAAA;AAAA,EAC/B;AAAA;AAAA;AAAA;AAAA,EAKA,IAAI,OAAA,GAAU;AACV,IAAA,OAAO,KAAK,QAAA,CAAS,KAAA;AAAA,EACzB;AAAA;AAAA;AAAA;AAAA,EAKA,IAAI,OAAA,GAAU;AACV,IAAA,OAAO,KAAK,QAAA,CAAS,KAAA;AAAA,EACzB;AAAA;AAAA;AAAA;AAAA,EAKA,IAAI,cAAA,GAA0B;AAC1B,IAAA,OAAO,KAAK,eAAA,CAAgB,KAAA;AAAA,EAChC;AAAA;AAAA;AAAA;AAAA,EAKA,iBAAiB,KAAA,EAAqB;AAClC,IAAA,IAAA,CAAK,QAAA,CAAS,iBAAiB,KAAK,CAAA;AAAA,EACxC;AAAA;AAAA;AAAA;AAAA,EAKA,iBAAiB,KAAA,EAAqB;AAClC,IAAA,IAAA,CAAK,QAAA,CAAS,iBAAiB,KAAK,CAAA;AAAA,EACxC;AAAA;AAAA;AAAA;AAAA,EAKA,WAAW,KAAA,EAAqB;AAC5B,IAAA,IAAA,CAAK,QAAA,CAAS,WAAW,KAAK,CAAA;AAAA,EAClC;AAAA;AAAA;AAAA;AAAA,EAKA,WAAW,KAAA,EAAqB;AAC5B,IAAA,IAAA,CAAK,QAAA,CAAS,WAAW,KAAK,CAAA;AAAA,EAClC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,CAAU,aAAa,CAAA,CAAE,GAAA,EAAqB;AAC1C,IAAA,KAAA,CAAM,aAAa,EAAE,GAAG,CAAA;AAExB,IAAA,IAAI,CAAC,KAAK,mBAAA,EAAqB;AAC3B,MAAA,MAAM,EAAE,OAAA,EAAS,YAAA,EAAc,QAAA,EAAU,oBAAmB,GAAI,cAAA;AAAA,QAC5D,IAAA;AAAA,QACA,IAAA,CAAK,YAAA;AAAA,QACL,CAAC,KAAA,KAAU;AACP,UAAA,IAAA,CAAK,WAAW,KAAA,GAAQ,KAAA;AAAA,QAC5B;AAAA,OACJ;AACA,MAAA,IAAA,CAAK,mBAAA,GAAsB,kBAAA;AAC3B,MAAA,IAAA,CAAK,WAAW,KAAA,GAAQ,YAAA;AAAA,IAC5B;AAAA,EACJ;AAAA,EAES,WAAW,aAAA,EAA8B;AAC9C,IAAA,IAAI,KAAK,WAAA,EAAa;AAClB,MAAA,GAAA,CAAI,IAAA;AAAA,QACA,CAAA,wCAAA,EAA2C,KAAK,EAAE,CAAA,gEAAA;AAAA,OACtD;AACA,MAAA;AAAA,IACJ;AAEA,IAAA,IAAA,CAAK,WAAW,EAAE,aAAa,CAAA;AAAA,EACnC;AAAA;AAAA,EAGA,CAAC,WAAW,CAAA,CAAE,aAAA,EAA8B;AACxC,IAAA,IAAI,IAAA,CAAK,QAAA,CAAS,UAAA,EAAW,KAAM,aAAA,EAAe;AAC9C,MAAA,IAAA,CAAK,QAAA,CAAS,WAAW,aAAa,CAAA;AAAA,IAC1C;AAAA,EACJ;AAAA;AAAA,EAGA,CAAC,QAAQ,CAAA,GAAuB;AAC5B,IAAA,MAAM,OAAO,IAAA,CAAK,KAAA;AAClB,IAAA,IAAI,IAAA,EAAM;AACN,MAAA,OAAO,IAAA;AAAA,IACX;AAEA,IAAA,MAAM,MAAM,IAAA,CAAK,WAAA;AACjB,IAAA,IAAI,GAAA,EAAK;AACL,MAAA,OAAO,IAAI,UAAU,CAAA;AAAA,IACzB;AACA,IAAA,MAAM,IAAI,KAAA;AAAA,MACN,CAAA,OAAA,EAAU,KAAK,EAAE,CAAA;AAAA,4FAAA;AAAA,KAErB;AAAA,EACJ;AACJ;AAEA,SAAS,cAAA,CACL,KAAA,EACA,WAAA,EACA,QAAA,EAC+C;AAC/C,EAAA,MAAM,UAAU,KAAA,CAAM,OAAA;AAEtB,EAAA,IAAI,EAAE,mBAAmB,OAAA,CAAA,EAAU;AAE/B,IAAA,OAAO;AAAA,MACH,OAAA,EAAS,QAAA;AAAA,MACT,QAAA,EAAU;AAAA,QACN,OAAA,GAAU;AAAA,QAEV;AAAA;AACJ,KACJ;AAAA,EACJ;AAEA,EAAA,IAAI,aAAA,GAAgB,UAAU,OAAO,CAAA;AACrC,EAAA,MAAM,mBAAA,GAAsB,eAAe,aAAa,CAAA;AAExD,EAAA,IAAI,gBAAA,GAAmC,mBAAA;AACvC,EAAA,IAAI,kBAAA,GAAqB,SAAA;AAGzB,EAAA,IAAI,wBAAwB,OAAA,EAAS;AAEjC,IAAA,aAAA,CAAc,KAAA,EAAO,WAAW,CAAA,CAAE,IAAA,CAAK,CAAC,KAAA,KAA0B;AAC9D,MAAA,kBAAA,GAAqB,KAAA;AACrB,MAAA,WAAA,EAAY;AAAA,IAChB,CAAC,CAAA;AAAA,EACL;AAEA,EAAA,MAAM,cAAc,MAAM;AACtB,IAAA,MAAM,YAAA,GAAe,eAAe,aAAa,CAAA;AACjD,IAAA,MAAM,aAAA,GACF,kBAAA,KAAuB,OAAA,GAAU,OAAA,GAAU,YAAA;AAE/C,IAAA,IAAI,qBAAqB,aAAA,EAAe;AACpC,MAAA,gBAAA,GAAmB,aAAA;AACnB,MAAA,QAAA,CAAS,gBAAgB,CAAA;AAAA,IAC7B;AAAA,EACJ,CAAA;AAEA,EAAA,IAAI,WAAA;AACJ,EAAA,WAAA,GAAc,aAAA,EAAe,EAAA,CAAG,QAAA,EAAU,MAAM;AAC5C,IAAA,WAAA,EAAY;AAAA,EAChB,CAAC,CAAA;AAED,EAAA,MAAM,YAAA,GAAe,OAAA,CAAQ,EAAA,CAAG,eAAA,EAAiB,MAAM;AAEnD,IAAA,WAAA,IAAe,QAAQ,WAAW,CAAA;AAClC,IAAA,WAAA,GAAc,MAAA;AAGd,IAAA,aAAA,GAAgB,UAAU,OAAO,CAAA;AACjC,IAAA,WAAA,GAAc,aAAA,EAAe,EAAA,CAAG,QAAA,EAAU,MAAM;AAC5C,MAAA,WAAA,EAAY;AAAA,IAChB,CAAC,CAAA;AACD,IAAA,WAAA,EAAY;AAAA,EAChB,CAAC,CAAA;AACD,EAAA,OAAO;AAAA,IACH,OAAA,EAAS,gBAAA;AAAA,IACT,QAAA,EAAU;AAAA,MACN,OAAA,GAAU;AACN,QAAA,WAAA,IAAe,QAAQ,WAAW,CAAA;AAClC,QAAA,OAAA,CAAQ,YAAY,CAAA;AAAA,MACxB;AAAA;AACJ,GACJ;AACJ;AAEA,eAAe,aAAA,CACX,OACA,WAAA,EACuB;AACvB,EAAA,IAAI,eAAe,IAAA,EAAM;AACrB,IAAA,OAAO,QAAA;AAAA,EACX;AAEA,EAAA,IAAI,aAAA;AACJ,EAAA,IAAI,OAAO,gBAAgB,UAAA,EAAY;AACnC,IAAA,aAAA,GAAgB,WAAA;AAAA,EACpB,CAAA,MAAA,IAAW,OAAO,WAAA,KAAgB,QAAA,EAAU;AACxC,IAAA,aAAA,GAAgB,YAAY;AACxB,MAAA,MAAM,WAAA,GAAc,KAAA,CAAM,QAAQ,CAAA,EAAE,CAAE,WAAA;AACtC,MAAA,MAAM,QAAA,GAAW,MAAM,WAAA,CAAY,KAAA,CAAM,WAAW,CAAA;AACpD,MAAA,IAAI,SAAS,EAAA,EAAI;AACb,QAAA,OAAO,QAAA;AAAA,MACX;AACA,MAAA,GAAA,CAAI,IAAA;AAAA,QACA,CAAA,+BAAA,EAAkC,KAAA,CAAM,EAAE,CAAA,eAAA,EAAkB,SAAS,MAAM,CAAA,CAAA;AAAA,OAC/E;AACA,MAAA,OAAO,OAAA;AAAA,IACX,CAAA;AAAA,EACJ,CAAA,MAAO;AACH,IAAA,GAAA,CAAI,KAAA;AAAA,MACA,CAAA,wDAAA,EAA2D,MAAM,EAAE,CAAA,CAAA,CAAA;AAAA,MACnE;AAAA,KACJ;AACA,IAAA,OAAO,OAAA;AAAA,EACX;AAEA,EAAA,IAAI;AACA,IAAA,OAAO,MAAM,cAAc,KAAc,CAAA;AAAA,EAC7C,SAAS,CAAA,EAAG;AACR,IAAA,GAAA,CAAI,IAAA,CAAK,CAAA,+BAAA,EAAkC,KAAA,CAAM,EAAE,KAAK,CAAC,CAAA;AACzD,IAAA,OAAO,OAAA;AAAA,EACX;AACJ;AAEA,SAAS,UAAU,OAAA,EAAgC;AAC/C,EAAA,IAAI,EAAE,mBAAmB,OAAA,CAAA,EAAU;AAC/B,IAAA,OAAO,MAAA;AAAA,EACX;AACA,EAAA,OAAQ,OAAA,EAAS,WAAU,IAAyB,MAAA;AACxD;AAEA,SAAS,eAAe,QAAA,EAAgC;AACpD,EAAA,MAAM,KAAA,GAAQ,UAAU,QAAA,EAAS;AACjC,EAAA,QAAQ,KAAA;AAAO,IACX,KAAK,MAAA;AACD,MAAA,OAAO,QAAA;AAAA,IACX,KAAK,WAAA;AACD,MAAA,OAAO,YAAA;AAAA,IACX,KAAK,SAAA;AACD,MAAA,OAAO,SAAA;AAAA,IACX,KAAK,OAAA;AACD,MAAA,OAAO,QAAA;AAAA,IACX,KAAK,OAAA;AACD,MAAA,OAAO,OAAA;AAAA;AAEnB;;;;"}
|
|
1
|
+
{"version":3,"file":"AbstractLayer.js","sources":["AbstractLayer.ts"],"sourcesContent":["// SPDX-FileCopyrightText: 2023-2025 Open Pioneer project (https://github.com/open-pioneer)\n// SPDX-License-Identifier: Apache-2.0\n\nimport {\n computed,\n constant,\n reactive,\n Reactive,\n ReadonlyReactive,\n synchronized\n} from \"@conterra/reactivity-core\";\nimport { createLogger } from \"@open-pioneer/core\";\nimport OlBaseLayer from \"ol/layer/Base\";\nimport OlLayer from \"ol/layer/Layer\";\nimport { unByKey } from \"ol/Observable\";\nimport OlSource from \"ol/source/Source\";\nimport { sourceId } from \"open-pioneer:source-info\";\nimport { MapModel } from \"../model/MapModel\";\nimport { InternalConstructorTag } from \"../utils/InternalConstructorTag\";\nimport { AbstractLayerBase } from \"./AbstractLayerBase\";\nimport {\n ATTACH_TO_MAP,\n GET_DEPS,\n getLayerDependencies,\n LAYER_DEPS,\n LayerDependencies,\n SET_METADATA_LOAD_INFO,\n SET_VISIBLE\n} from \"./shared/internals\";\nimport { HealthCheckFunction, LayerConfig } from \"./shared/LayerConfig\";\n// oxlint-disable-next-line @typescript-eslint/no-unused-vars\nimport { SimpleLayer, SimpleLayerConfig } from \"./SimpleLayer\";\nimport { Layer, LayerTypes } from \"./unions\";\n\nconst LOG = createLogger(sourceId);\n\n/**\n * The load state of a layer.\n *\n * @group Layer Utilities\n **/\nexport type LayerLoadState = \"not-loaded\" | \"loading\" | \"loaded\" | \"error\";\n\n/**\n * Load state of a single layer, bundling the state with its error.\n *\n * @internal\n */\nexport type LayerLoadInfo = \"not-loaded\" | \"loading\" | \"loaded\" | { kind: \"error\"; error: Error };\n\n/**\n * Represents an operational layer in the map.\n *\n * These layers always have an associated OpenLayers layer.\n *\n * Instances of this interface cannot be constructed directly; use a real layer\n * class such as {@link SimpleLayer} instead.\n *\n * @group Layers\n */\nexport abstract class AbstractLayer extends AbstractLayerBase {\n // Layer dependencies are present when the LayerFactory API was used to construct the layer.\n // They may currently be undefined for compatibility reasons (in which case they will be used\n // from the map, once connected).\n #deps: LayerDependencies | undefined;\n #olLayer: OlBaseLayer;\n #olSource: ReadonlyReactive<OlSource | undefined>;\n #isBaseLayer: boolean;\n #healthCheck?: string | HealthCheckFunction;\n\n #visible: ReadonlyReactive<boolean>;\n #minResolution: ReadonlyReactive<number>;\n #maxResolution: ReadonlyReactive<number>;\n #minZoom: ReadonlyReactive<number>;\n #maxZoom: ReadonlyReactive<number>;\n\n #sourceState: ReadonlyReactive<ReadonlyReactive<LayerLoadState> | undefined>;\n #sourceInfo: ReadonlyReactive<LayerLoadInfo>;\n #healthInfo: Reactive<LayerLoadInfo>;\n #healthCheckStarted = false;\n #metadataInfo: Reactive<LayerLoadInfo>;\n #loadInfo = computed(() =>\n combineLoadInfos(this.#sourceInfo.value, this.#healthInfo.value, this.#metadataInfo.value)\n );\n #visibleInScale: ReadonlyReactive<boolean>;\n\n constructor(\n config: SimpleLayerConfig & {\n /** The initial load state (default: not-loaded). */\n initialLoadInfo?: LayerLoadInfo;\n },\n deps?: LayerDependencies,\n internalTag?: InternalConstructorTag\n ) {\n super(config);\n this.#deps = getLayerDependencies(deps, internalTag);\n this.#olLayer = config.olLayer;\n this.#olSource = synchronizedOlSource(this.#olLayer);\n this.#isBaseLayer = config.isBaseLayer ?? false;\n this.#healthCheck = config.healthCheck;\n this.#visible = synchronized(\n () => this.#olLayer.getVisible(),\n (cb) => {\n const key = this.#olLayer.on(\"change:visible\", cb);\n return () => unByKey(key);\n }\n );\n this.#minResolution = synchronized(\n () => this.#olLayer.getMinResolution(),\n (cb) => {\n const key = this.#olLayer.on(\"change:minResolution\", cb);\n return () => unByKey(key);\n }\n );\n this.#maxResolution = synchronized(\n () => this.#olLayer.getMaxResolution(),\n (cb) => {\n const key = this.#olLayer.on(\"change:maxResolution\", cb);\n return () => unByKey(key);\n }\n );\n this.#minZoom = synchronized(\n () => this.#olLayer.getMinZoom(),\n (cb) => {\n const key = this.#olLayer.on(\"change:minZoom\", cb);\n return () => unByKey(key);\n }\n );\n this.#maxZoom = synchronized(\n () => this.#olLayer.getMaxZoom(),\n (cb) => {\n const key = this.#olLayer.on(\"change:maxZoom\", cb);\n return () => unByKey(key);\n }\n );\n this.#sourceState = computed(() => {\n const olSource = this.olSource;\n if (!olSource) {\n return undefined;\n }\n\n return synchronized(\n () => getSourceState(olSource),\n (cb) => {\n const key = olSource.on(\"change\", cb);\n return () => unByKey(key);\n }\n );\n });\n this.#sourceInfo = computed(() => makeSourceInfo(this.id, this.#sourceState.value?.value));\n this.#healthInfo = reactive<LayerLoadInfo>(\"not-loaded\");\n this.#metadataInfo = reactive<LayerLoadInfo>(config.initialLoadInfo ?? \"not-loaded\");\n\n this[SET_VISIBLE](config.visible ?? true); // apply initial visibility\n\n this.#visibleInScale = computed(() => {\n const map = this.nullableMap; // handle case where not in the map yet\n if (!map) {\n return true; // or false? doesn't really matter\n }\n\n const zoom = map.zoomLevel;\n const resolution = map.resolution;\n if (zoom == null || resolution == null) {\n return false;\n }\n\n const parent = this.parent;\n if (parent && parent.type === \"group\" && !parent.visibleInScale) {\n return false;\n }\n\n if (resolution < this.minResolution || resolution >= this.maxResolution) {\n return false;\n }\n\n return zoom > this.minZoom && zoom <= this.maxZoom;\n });\n\n if (config.maxResolution) {\n this.#olLayer.setMaxResolution(config.maxResolution);\n }\n if (config.minResolution) {\n this.#olLayer.setMinResolution(config.minResolution);\n }\n\n if (config.maxZoom) {\n this.#olLayer.setMaxZoom(config.maxZoom);\n }\n if (config.minZoom) {\n this.#olLayer.setMinZoom(config.minZoom);\n }\n }\n\n override destroy() {\n if (this.isDestroyed) {\n return;\n }\n\n this.olLayer.dispose();\n super.destroy();\n }\n\n /**\n * Identifies the type of this layer.\n */\n abstract override readonly type: LayerTypes;\n\n override get visible(): boolean {\n return this.#visible.value;\n }\n\n /**\n * The raw OpenLayers layer.\n */\n get olLayer(): OlBaseLayer {\n return this.#olLayer;\n }\n\n /**\n * The current source of the {@link olLayer}.\n */\n get olSource(): OlSource | undefined {\n return this.#olSource.value;\n }\n\n /**\n * True if this layer is a base layer.\n *\n * Only one base layer can be visible at a time.\n */\n get isBaseLayer(): boolean {\n return this.#isBaseLayer;\n }\n\n /**\n * The combined load state of a layer.\n *\n * Aggregates the OpenLayers source state, health check and metadata state.\n * Priority for the state: `error` > `loading` > `not-loaded` > `loaded`.\n */\n get loadState(): LayerLoadState {\n return loadInfoState(this.#loadInfo.value);\n }\n\n /**\n * The error (if any) that prevented this layer from loading.\n *\n * Combines errors from the OpenLayers source, the health check and the\n * metadata request (health > metadata > source).\n */\n get loadError(): Error | undefined {\n return errorOf(this.#loadInfo.value);\n }\n\n /**\n * The minimum resolution (inclusive) at which this layer will be visible.\n */\n get minResolution() {\n return this.#minResolution.value;\n }\n\n /**\n * The maximum resolution (exclusive) below which this layer will be visible.\n */\n get maxResolution() {\n return this.#maxResolution.value;\n }\n\n /**\n * The minimum view zoom level (exclusive) above which this layer will be visible.\n */\n get minZoom() {\n return this.#minZoom.value;\n }\n\n /**\n * The maximum view zoom level (inclusive) at which this layer will be visible.\n */\n get maxZoom() {\n return this.#maxZoom.value;\n }\n\n /**\n * Whether the layer is visible in the current map scale or not.\n */\n get visibleInScale(): boolean {\n return this.#visibleInScale.value;\n }\n\n /**\n * The minimum resolution (inclusive) at which this layer will be visible.\n */\n setMinResolution(value: number): void {\n this.#olLayer.setMinResolution(value);\n }\n\n /**\n * The maximum resolution (exclusive) below which this layer will be visible.\n */\n setMaxResolution(value: number): void {\n this.#olLayer.setMaxResolution(value);\n }\n\n /**\n * The minimum view zoom level (exclusive) above which this layer will be visible.\n */\n setMinZoom(value: number): void {\n this.#olLayer.setMinZoom(value);\n }\n\n /**\n * The maximum view zoom level (inclusive) at which this layer will be visible.\n */\n setMaxZoom(value: number): void {\n this.#olLayer.setMaxZoom(value);\n }\n\n /**\n * Called by the map model when the layer is added to the map.\n *\n * @internal\n */\n override [ATTACH_TO_MAP](map: MapModel): void {\n super[ATTACH_TO_MAP](map);\n\n // Custom health check is not needed when OpenLayers already reports an error state.\n if (!this.#healthCheckStarted && errorOf(this.#sourceInfo.value) == null) {\n this.#healthCheckStarted = true;\n doHealthCheck(this, this.#healthCheck).then((loadInfo) => {\n this.#healthInfo.value = loadInfo;\n });\n }\n }\n\n /**\n * Updates the load state of the layer's metadata request.\n *\n * @internal\n */\n [SET_METADATA_LOAD_INFO](loadInfo: LayerLoadInfo): void {\n this.#metadataInfo.value = loadInfo;\n }\n\n override setVisible(newVisibility: boolean): void {\n if (this.isBaseLayer) {\n LOG.warn(\n `Cannot change visibility of base layer '${this.id}': use activateBaseLayer() on the map's LayerCollection instead.`\n );\n return;\n }\n\n this[SET_VISIBLE](newVisibility);\n }\n\n /** @internal */\n [SET_VISIBLE](newVisibility: boolean): void {\n if (this.#olLayer.getVisible() !== newVisibility) {\n this.#olLayer.setVisible(newVisibility);\n }\n }\n\n /** @internal */\n [GET_DEPS](): LayerDependencies {\n const deps = this.#deps;\n if (deps) {\n return deps;\n }\n\n const map = this.nullableMap;\n if (map) {\n return map[LAYER_DEPS];\n }\n throw new Error(\n `Layer '${this.id}' has not been attached to a map yet. \"\n + \"Use the LayerFactory to create an instance or add the layer to the map first.`\n );\n }\n}\n\nasync function doHealthCheck(\n layer: AbstractLayer,\n healthCheck: LayerConfig[\"healthCheck\"]\n): Promise<LayerLoadInfo> {\n if (healthCheck == null) {\n return \"loaded\";\n }\n\n let healthCheckFn: HealthCheckFunction;\n if (typeof healthCheck === \"function\") {\n healthCheckFn = healthCheck;\n } else if (typeof healthCheck === \"string\") {\n healthCheckFn = async () => {\n const httpService = layer[GET_DEPS]().httpService;\n const response = await httpService.fetch(healthCheck);\n if (response.ok) {\n return \"loaded\";\n }\n LOG.warn(\n `Health check failed for layer '${layer.id}' (http status ${response.status})`\n );\n return \"error\";\n };\n } else {\n LOG.error(\n `Unexpected object for 'healthCheck' parameter of layer '${layer.id}'`,\n healthCheck\n );\n return {\n kind: \"error\",\n error: new Error(`Invalid 'healthCheck' configuration for layer '${layer.id}'`)\n };\n }\n\n try {\n const state = await healthCheckFn(layer as Layer);\n if (state === \"error\") {\n return {\n kind: \"error\",\n error: new Error(`Health check failed for layer '${layer.id}'`)\n };\n }\n return state;\n } catch (e) {\n LOG.warn(`Health check failed for layer '${layer.id}'`, e);\n return {\n kind: \"error\",\n error: e instanceof Error ? e : new Error(String(e))\n };\n }\n}\n\nconst LOAD_STATE_SEVERITY: Record<LayerLoadState, number> = {\n \"not-loaded\": 0,\n loaded: 1,\n loading: 2,\n error: 3\n};\n\n/** Returns the higher severity of two load states: error > loading > not-loaded > loaded. */\nfunction higherSeverity(a: LayerLoadState, b: LayerLoadState): LayerLoadState {\n return LOAD_STATE_SEVERITY[a] >= LOAD_STATE_SEVERITY[b] ? a : b;\n}\n\nfunction combineLoadInfos(\n source: LayerLoadInfo,\n health: LayerLoadInfo,\n metadata: LayerLoadInfo\n): LayerLoadInfo {\n // If several channels are in error, report the most relevant one (health > metadata > source).\n const error = errorOf(health) ?? errorOf(metadata) ?? errorOf(source);\n if (error) {\n return { kind: \"error\", error };\n }\n return higherSeverity(loadInfoState(source), loadInfoState(metadata)) as LayerLoadInfo;\n}\n\nfunction errorOf(info: LayerLoadInfo): Error | undefined {\n return typeof info === \"object\" ? info.error : undefined;\n}\n\nfunction loadInfoState(info: LayerLoadInfo): LayerLoadState {\n return typeof info === \"object\" ? \"error\" : info;\n}\n\n// OpenLayers sources carry no error detail, so synthesize one.\nfunction makeSourceInfo(id: string, state: LayerLoadState | undefined): LayerLoadInfo {\n if (state == null) {\n // no state -> no source -> just pretend its loaded\n return \"loaded\";\n }\n if (state === \"error\") {\n return {\n kind: \"error\",\n error: new Error(`Source of layer '${id}' is in error state`)\n };\n }\n return state;\n}\n\nfunction synchronizedOlSource(layer: OlBaseLayer): ReadonlyReactive<OlSource | undefined> {\n if (!(layer instanceof OlLayer)) {\n // GroupLayer etc.\n return constant(undefined);\n }\n\n return synchronized(\n () => layer.getSource() ?? undefined,\n (cb) => {\n const key = layer.on(\"change:source\", cb);\n return () => unByKey(key);\n }\n );\n}\n\nfunction getSourceState(olSource: OlSource) {\n const state = olSource.getState();\n switch (state) {\n case undefined:\n return \"loaded\";\n case \"undefined\":\n return \"not-loaded\";\n case \"loading\":\n return \"loading\";\n case \"ready\":\n return \"loaded\";\n case \"error\":\n return \"error\";\n }\n}\n"],"names":[],"mappings":"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"}
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import { EventSource } from "@conterra/reactivity-events";
|
|
2
2
|
import { MapModel } from "../model/MapModel";
|
|
3
|
-
import { GroupLayer } from "./GroupLayer";
|
|
4
3
|
import { GroupLayerCollection } from "./group/GroupLayerCollection";
|
|
4
|
+
import { GroupLayer } from "./GroupLayer";
|
|
5
5
|
import { ChildrenCollection } from "./shared/ChildrenCollection";
|
|
6
|
+
import { ATTACH_TO_GROUP, ATTACH_TO_MAP, DETACH_FROM_GROUP, DETACH_FROM_MAP } from "./shared/internals";
|
|
6
7
|
import { SublayersCollection } from "./shared/SublayersCollection";
|
|
7
8
|
import { AnyLayer, AnyLayerTypes, Sublayer } from "./unions";
|
|
8
|
-
import { ATTACH_TO_GROUP, ATTACH_TO_MAP, DETACH_FROM_GROUP, DETACH_FROM_MAP } from "./shared/internals";
|
|
9
9
|
export interface AbstractLayerBaseOptions {
|
|
10
10
|
id?: string;
|
|
11
11
|
title: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AbstractLayerBase.js","sources":["AbstractLayerBase.ts"],"sourcesContent":["// SPDX-FileCopyrightText: 2023-2025 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 reactiveMap,\n ReadonlyReactive\n} from \"@conterra/reactivity-core\";\nimport { emit, emitter, EventSource } from \"@conterra/reactivity-events\";\nimport { v4 as uuid4v } from \"uuid\";\nimport { MapModel } from \"../model/MapModel\";\nimport { GroupLayer } from \"./GroupLayer\";\nimport { GroupLayerCollection } from \"./group/GroupLayerCollection\";\nimport { ChildrenCollection } from \"./shared/ChildrenCollection\";\nimport { SublayersCollection } from \"./shared/SublayersCollection\";\nimport { AnyLayer, AnyLayerTypes, Sublayer } from \"./unions\";\nimport {\n ATTACH_TO_GROUP,\n ATTACH_TO_MAP,\n DETACH_FROM_GROUP,\n DETACH_FROM_MAP\n} from \"./shared/internals\";\n\nexport interface AbstractLayerBaseOptions {\n id?: string;\n title: string;\n description?: string;\n attributes?: Record<string, unknown>;\n internal?: boolean;\n}\n\n/**\n * Interface shared by all layer types (operational layers and sublayers).\n *\n * Instances of this interface cannot be constructed directly; use a real layer\n * class such as {@link SimpleLayer} instead.\n *\n * @group Layers\n */\nexport abstract class AbstractLayerBase {\n #map = reactive<MapModel>();\n #parent: AnyLayer | undefined;\n\n #id: string;\n #title: Reactive<string>;\n #description: Reactive<string>;\n #attributesMap = reactiveMap<string | symbol, unknown>();\n #attributes: ReadonlyReactive<Record<string | symbol, unknown>>;\n #isDestroyed = reactive(false);\n #internal: Reactive<boolean>;\n\n #destroyed = emitter();\n\n constructor(config: AbstractLayerBaseOptions) {\n this.#id = config.id ?? uuid4v();\n this.#attributes = computed(() => {\n return Object.fromEntries(this.#attributesMap.entries());\n });\n this.#title = reactive(config.title);\n this.#description = reactive(config.description ?? \"\");\n this.#internal = reactive(config.internal ?? false);\n\n if (config.attributes) {\n this.updateAttributes(config.attributes);\n }\n }\n\n /**\n * Destroys the layer and everything owned by it.\n *\n * > NOTE: Layers that are part of the map will be destroyed automatically\n * > when that map is being destroyed.\n */\n destroy() {\n if (this.#isDestroyed.value) {\n return;\n }\n\n batch(() => {\n this.#isDestroyed.value = true;\n this.sublayers?.destroy();\n this.layers?.destroy();\n emit(this.#destroyed);\n });\n }\n\n /** True if the layer has been destroyed. */\n get isDestroyed() {\n return this.#isDestroyed.value;\n }\n\n /**\n * Emits an event when the layer is destroyed.\n */\n get destroyed(): EventSource<void> {\n return this.#destroyed;\n }\n\n /**\n * The unique id of this layer within its map model.\n *\n * NOTE: layer ids may not be globally unique: layers that belong\n * to different map models may have the same id.\n */\n get id(): string {\n return this.#id;\n }\n\n /** The human-readable title of this layer. */\n get title(): string {\n return this.#title.value;\n }\n\n /** The human-readable description of this layer. May be empty. */\n get description(): string {\n return this.#description.value;\n }\n\n /**\n * Property that specifies if the layer is an \"internal\" layer. Internal layers are not considered by any UI widget (e.g. Toc or Legend).\n * The internal state is independent of the layer's visibility which is determined by {@link visible}\n *\n * NOTE: Some UI widgets might use component specific attributes or props that have precedence over the internal property.\n */\n get internal(): boolean {\n return this.#internal.value;\n }\n\n /**\n * Additional attributes associated with this layer.\n *\n * NOTE: Do not modify vis this getter.\n * Use {@link updateAttributes} or {@link deleteAttribute} instead.\n */\n get attributes(): Record<string | symbol, unknown> {\n return this.#attributes.value;\n }\n\n /**\n * The map this layer belongs to.\n *\n * NOTE: Throws if the layer is not part of a map.\n */\n get map(): MapModel {\n const map = this.nullableMap;\n if (!map) {\n throw new Error(`Layer '${this.id}' has not been attached to a map yet.`);\n }\n return map;\n }\n\n /**\n * The map this layer belongs to, or undefined if the layer is not part of a map.\n */\n get nullableMap(): MapModel | undefined {\n return this.#map.value;\n }\n\n /**\n * The direct parent of this layer instance, used for sublayers or for layers in a group layer.\n *\n * The property shall be undefined if the layer is not a sublayer or member of a group layer.\n */\n get parent(): AnyLayer | undefined {\n return this.#parent;\n }\n\n /**\n * The direct children of this layer.\n *\n * The children may either be a set of operational layers (e.g. for a group layer) or a set of sublayers, or `undefined`.\n *\n * See also {@link layers} and {@link sublayers}.\n */\n get children(): ChildrenCollection<AnyLayer> | undefined {\n return this.layers ?? this.sublayers ?? undefined;\n }\n\n /**\n * Identifies the type of this layer.\n */\n abstract get type(): AnyLayerTypes;\n\n /**\n * Whether the layer is visible or not.\n *\n * NOTE: The model's visible state may do more than influence the raw OpenLayers's visibility property.\n * Future versions may completely remove invisible layers from the OpenLayer's map under some circumstances.\n */\n abstract get visible(): boolean;\n\n /**\n * If this layer is a group layer this property contains a collection of all layers that are members of the group.\n *\n * The property shall be `undefined` if it is not a group layer.\n *\n * The properties `layers` and `sublayers` are mutually exclusive.\n */\n abstract get layers(): GroupLayerCollection | undefined;\n\n /**\n * The collection of child sublayers for this layer. Sublayers are layers that cannot exist without an appropriate parent layer.\n *\n * Layers that can never have any sublayers may not have a `sublayers` collection.\n *\n * The properties `layers` and `sublayers` are mutually exclusive.\n */\n abstract get sublayers(): SublayersCollection<Sublayer> | undefined;\n\n /**\n * Legend URL from the service capabilities, if available.\n *\n * Note: this property may be expanded upon in the future, e.g. to support more variants than just image URLs.\n */\n abstract get legend(): string | undefined;\n\n /**\n * Attaches the layer to its owning map.\n *\n * @internal\n */\n [ATTACH_TO_MAP](map: MapModel): void {\n if (this.#map.value) {\n throw new Error(\n `Layer '${this.id}' has already been attached to the map '${this.map.id}'`\n );\n }\n this.#map.value = map;\n }\n\n /**\n * Attach group layers to its parent group layer.\n * Called by the parent layer.\n *\n * @internal\n */\n [ATTACH_TO_GROUP](parent: GroupLayer): void {\n if (this.#parent) {\n throw new Error(\n `Layer '${this.id}' has already been attached to the group layer '${this.#parent.id}'`\n );\n }\n this.#parent = parent;\n }\n\n /**\n * Called when a layer is removed from the map.\n *\n * @internal\n */\n [DETACH_FROM_MAP](): void {\n this.#map.value = undefined;\n }\n\n /**\n * Detach layer from parent group layer.\n *\n * Called by the parent group layer when destroyed or the layer gets removed.\n *\n * @internal\n */\n [DETACH_FROM_GROUP](): void {\n this.#parent = undefined;\n }\n\n /**\n * Updates the title of this layer.\n */\n setTitle(newTitle: string): void {\n this.#title.value = newTitle;\n }\n\n /**\n * Updates the description of this layer.\n */\n setDescription(newDescription: string): void {\n this.#description.value = newDescription;\n }\n\n /**\n * Updates the internal property of this layer to the new value.\n */\n setInternal(newIsInternal: boolean): void {\n this.#internal.value = newIsInternal;\n }\n\n /**\n * Updates the attributes of this layer.\n * Values in `newAttributes` will override existing values with the same key.\n */\n updateAttributes(newAttributes: Record<string | symbol, unknown>): void {\n const keys = Reflect.ownKeys(newAttributes);\n batch(() => {\n for (const key of keys) {\n this.#attributesMap.set(key, newAttributes[key]);\n }\n });\n }\n\n /**\n * Deletes the attribute of this layer.\n */\n deleteAttribute(deleteAttribute: string | symbol): void {\n this.#attributesMap.delete(deleteAttribute);\n }\n\n /**\n * Updates the visibility of this layer to the new value.\n *\n * NOTE: The visibility of base layers cannot be changed through this method.\n * Call {@link LayerCollection.activateBaseLayer} instead.\n */\n abstract setVisible(newVisibility: boolean): void;\n}\n"],"names":["uuid4v"],"mappings":";;;;;AAyCO,MAAe,iBAAA,CAAkB;AAAA,EACpC,OAAO,QAAA,EAAmB;AAAA,EAC1B,OAAA;AAAA,EAEA,GAAA;AAAA,EACA,MAAA;AAAA,EACA,YAAA;AAAA,EACA,iBAAiB,WAAA,EAAsC;AAAA,EACvD,WAAA;AAAA,EACA,YAAA,GAAe,SAAS,KAAK,CAAA;AAAA,EAC7B,SAAA;AAAA,EAEA,aAAa,OAAA,EAAQ;AAAA,EAErB,YAAY,MAAA,EAAkC;AAC1C,IAAA,IAAA,CAAK,GAAA,GAAM,MAAA,CAAO,EAAA,IAAMA,EAAA,EAAO;AAC/B,IAAA,IAAA,CAAK,WAAA,GAAc,SAAS,MAAM;AAC9B,MAAA,OAAO,MAAA,CAAO,WAAA,CAAY,IAAA,CAAK,cAAA,CAAe,SAAS,CAAA;AAAA,IAC3D,CAAC,CAAA;AACD,IAAA,IAAA,CAAK,MAAA,GAAS,QAAA,CAAS,MAAA,CAAO,KAAK,CAAA;AACnC,IAAA,IAAA,CAAK,YAAA,GAAe,QAAA,CAAS,MAAA,CAAO,WAAA,IAAe,EAAE,CAAA;AACrD,IAAA,IAAA,CAAK,SAAA,GAAY,QAAA,CAAS,MAAA,CAAO,QAAA,IAAY,KAAK,CAAA;AAElD,IAAA,IAAI,OAAO,UAAA,EAAY;AACnB,MAAA,IAAA,CAAK,gBAAA,CAAiB,OAAO,UAAU,CAAA;AAAA,IAC3C;AAAA,EACJ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,OAAA,GAAU;AACN,IAAA,IAAI,IAAA,CAAK,aAAa,KAAA,EAAO;AACzB,MAAA;AAAA,IACJ;AAEA,IAAA,KAAA,CAAM,MAAM;AACR,MAAA,IAAA,CAAK,aAAa,KAAA,GAAQ,IAAA;AAC1B,MAAA,IAAA,CAAK,WAAW,OAAA,EAAQ;AACxB,MAAA,IAAA,CAAK,QAAQ,OAAA,EAAQ;AACrB,MAAA,IAAA,CAAK,KAAK,UAAU,CAAA;AAAA,IACxB,CAAC,CAAA;AAAA,EACL;AAAA;AAAA,EAGA,IAAI,WAAA,GAAc;AACd,IAAA,OAAO,KAAK,YAAA,CAAa,KAAA;AAAA,EAC7B;AAAA;AAAA;AAAA;AAAA,EAKA,IAAI,SAAA,GAA+B;AAC/B,IAAA,OAAO,IAAA,CAAK,UAAA;AAAA,EAChB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,IAAI,EAAA,GAAa;AACb,IAAA,OAAO,IAAA,CAAK,GAAA;AAAA,EAChB;AAAA;AAAA,EAGA,IAAI,KAAA,GAAgB;AAChB,IAAA,OAAO,KAAK,MAAA,CAAO,KAAA;AAAA,EACvB;AAAA;AAAA,EAGA,IAAI,WAAA,GAAsB;AACtB,IAAA,OAAO,KAAK,YAAA,CAAa,KAAA;AAAA,EAC7B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,IAAI,QAAA,GAAoB;AACpB,IAAA,OAAO,KAAK,SAAA,CAAU,KAAA;AAAA,EAC1B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,IAAI,UAAA,GAA+C;AAC/C,IAAA,OAAO,KAAK,WAAA,CAAY,KAAA;AAAA,EAC5B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,IAAI,GAAA,GAAgB;AAChB,IAAA,MAAM,MAAM,IAAA,CAAK,WAAA;AACjB,IAAA,IAAI,CAAC,GAAA,EAAK;AACN,MAAA,MAAM,IAAI,KAAA,CAAM,CAAA,OAAA,EAAU,IAAA,CAAK,EAAE,CAAA,qCAAA,CAAuC,CAAA;AAAA,IAC5E;AACA,IAAA,OAAO,GAAA;AAAA,EACX;AAAA;AAAA;AAAA;AAAA,EAKA,IAAI,WAAA,GAAoC;AACpC,IAAA,OAAO,KAAK,IAAA,CAAK,KAAA;AAAA,EACrB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,IAAI,MAAA,GAA+B;AAC/B,IAAA,OAAO,IAAA,CAAK,OAAA;AAAA,EAChB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,IAAI,QAAA,GAAqD;AACrD,IAAA,OAAO,IAAA,CAAK,MAAA,IAAU,IAAA,CAAK,SAAA,IAAa,MAAA;AAAA,EAC5C;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EA6CA,CAAC,aAAa,CAAA,CAAE,GAAA,EAAqB;AACjC,IAAA,IAAI,IAAA,CAAK,KAAK,KAAA,EAAO;AACjB,MAAA,MAAM,IAAI,KAAA;AAAA,QACN,UAAU,IAAA,CAAK,EAAE,CAAA,wCAAA,EAA2C,IAAA,CAAK,IAAI,EAAE,CAAA,CAAA;AAAA,OAC3E;AAAA,IACJ;AACA,IAAA,IAAA,CAAK,KAAK,KAAA,GAAQ,GAAA;AAAA,EACtB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,CAAC,eAAe,CAAA,CAAE,MAAA,EAA0B;AACxC,IAAA,IAAI,KAAK,OAAA,EAAS;AACd,MAAA,MAAM,IAAI,KAAA;AAAA,QACN,UAAU,IAAA,CAAK,EAAE,CAAA,gDAAA,EAAmD,IAAA,CAAK,QAAQ,EAAE,CAAA,CAAA;AAAA,OACvF;AAAA,IACJ;AACA,IAAA,IAAA,CAAK,OAAA,GAAU,MAAA;AAAA,EACnB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,CAAC,eAAe,CAAA,GAAU;AACtB,IAAA,IAAA,CAAK,KAAK,KAAA,GAAQ,MAAA;AAAA,EACtB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,CAAC,iBAAiB,CAAA,GAAU;AACxB,IAAA,IAAA,CAAK,OAAA,GAAU,MAAA;AAAA,EACnB;AAAA;AAAA;AAAA;AAAA,EAKA,SAAS,QAAA,EAAwB;AAC7B,IAAA,IAAA,CAAK,OAAO,KAAA,GAAQ,QAAA;AAAA,EACxB;AAAA;AAAA;AAAA;AAAA,EAKA,eAAe,cAAA,EAA8B;AACzC,IAAA,IAAA,CAAK,aAAa,KAAA,GAAQ,cAAA;AAAA,EAC9B;AAAA;AAAA;AAAA;AAAA,EAKA,YAAY,aAAA,EAA8B;AACtC,IAAA,IAAA,CAAK,UAAU,KAAA,GAAQ,aAAA;AAAA,EAC3B;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,iBAAiB,aAAA,EAAuD;AACpE,IAAA,MAAM,IAAA,GAAO,OAAA,CAAQ,OAAA,CAAQ,aAAa,CAAA;AAC1C,IAAA,KAAA,CAAM,MAAM;AACR,MAAA,KAAA,MAAW,OAAO,IAAA,EAAM;AACpB,QAAA,IAAA,CAAK,cAAA,CAAe,GAAA,CAAI,GAAA,EAAK,aAAA,CAAc,GAAG,CAAC,CAAA;AAAA,MACnD;AAAA,IACJ,CAAC,CAAA;AAAA,EACL;AAAA;AAAA;AAAA;AAAA,EAKA,gBAAgB,eAAA,EAAwC;AACpD,IAAA,IAAA,CAAK,cAAA,CAAe,OAAO,eAAe,CAAA;AAAA,EAC9C;AASJ;;;;"}
|
|
1
|
+
{"version":3,"file":"AbstractLayerBase.js","sources":["AbstractLayerBase.ts"],"sourcesContent":["// SPDX-FileCopyrightText: 2023-2025 Open Pioneer project (https://github.com/open-pioneer)\n// SPDX-License-Identifier: Apache-2.0\n\nimport {\n batch,\n computed,\n reactive,\n Reactive,\n reactiveMap,\n ReadonlyReactive\n} from \"@conterra/reactivity-core\";\nimport { emit, emitter, EventSource } from \"@conterra/reactivity-events\";\nimport { v4 as uuid4v } from \"uuid\";\nimport { MapModel } from \"../model/MapModel\";\nimport { GroupLayerCollection } from \"./group/GroupLayerCollection\";\nimport { GroupLayer } from \"./GroupLayer\";\nimport { ChildrenCollection } from \"./shared/ChildrenCollection\";\nimport {\n ATTACH_TO_GROUP,\n ATTACH_TO_MAP,\n DETACH_FROM_GROUP,\n DETACH_FROM_MAP\n} from \"./shared/internals\";\nimport { SublayersCollection } from \"./shared/SublayersCollection\";\nimport { AnyLayer, AnyLayerTypes, Sublayer } from \"./unions\";\n\nexport interface AbstractLayerBaseOptions {\n id?: string;\n title: string;\n description?: string;\n attributes?: Record<string, unknown>;\n internal?: boolean;\n}\n\n/**\n * Interface shared by all layer types (operational layers and sublayers).\n *\n * Instances of this interface cannot be constructed directly; use a real layer\n * class such as {@link SimpleLayer} instead.\n *\n * @group Layers\n */\nexport abstract class AbstractLayerBase {\n #map = reactive<MapModel>();\n #parent: AnyLayer | undefined;\n\n #id: string;\n #title: Reactive<string>;\n #description: Reactive<string>;\n #attributesMap = reactiveMap<string | symbol, unknown>();\n #attributes: ReadonlyReactive<Record<string | symbol, unknown>>;\n #isDestroyed = reactive(false);\n #internal: Reactive<boolean>;\n\n #destroyed = emitter();\n\n constructor(config: AbstractLayerBaseOptions) {\n this.#id = config.id ?? uuid4v();\n this.#attributes = computed(() => {\n return Object.fromEntries(this.#attributesMap.entries());\n });\n this.#title = reactive(config.title);\n this.#description = reactive(config.description ?? \"\");\n this.#internal = reactive(config.internal ?? false);\n\n if (config.attributes) {\n this.updateAttributes(config.attributes);\n }\n }\n\n /**\n * Destroys the layer and everything owned by it.\n *\n * > NOTE: Layers that are part of the map will be destroyed automatically\n * > when that map is being destroyed.\n */\n destroy() {\n if (this.#isDestroyed.value) {\n return;\n }\n\n batch(() => {\n this.#isDestroyed.value = true;\n this.sublayers?.destroy();\n this.layers?.destroy();\n emit(this.#destroyed);\n });\n }\n\n /** True if the layer has been destroyed. */\n get isDestroyed() {\n return this.#isDestroyed.value;\n }\n\n /**\n * Emits an event when the layer is destroyed.\n */\n get destroyed(): EventSource<void> {\n return this.#destroyed;\n }\n\n /**\n * The unique id of this layer within its map model.\n *\n * NOTE: layer ids may not be globally unique: layers that belong\n * to different map models may have the same id.\n */\n get id(): string {\n return this.#id;\n }\n\n /** The human-readable title of this layer. */\n get title(): string {\n return this.#title.value;\n }\n\n /** The human-readable description of this layer. May be empty. */\n get description(): string {\n return this.#description.value;\n }\n\n /**\n * Property that specifies if the layer is an \"internal\" layer. Internal layers are not considered by any UI widget (e.g. Toc or Legend).\n * The internal state is independent of the layer's visibility which is determined by {@link visible}\n *\n * NOTE: Some UI widgets might use component specific attributes or props that have precedence over the internal property.\n */\n get internal(): boolean {\n return this.#internal.value;\n }\n\n /**\n * Additional attributes associated with this layer.\n *\n * NOTE: Do not modify vis this getter.\n * Use {@link updateAttributes} or {@link deleteAttribute} instead.\n */\n get attributes(): Record<string | symbol, unknown> {\n return this.#attributes.value;\n }\n\n /**\n * The map this layer belongs to.\n *\n * NOTE: Throws if the layer is not part of a map.\n */\n get map(): MapModel {\n const map = this.nullableMap;\n if (!map) {\n throw new Error(`Layer '${this.id}' has not been attached to a map yet.`);\n }\n return map;\n }\n\n /**\n * The map this layer belongs to, or undefined if the layer is not part of a map.\n */\n get nullableMap(): MapModel | undefined {\n return this.#map.value;\n }\n\n /**\n * The direct parent of this layer instance, used for sublayers or for layers in a group layer.\n *\n * The property shall be undefined if the layer is not a sublayer or member of a group layer.\n */\n get parent(): AnyLayer | undefined {\n return this.#parent;\n }\n\n /**\n * The direct children of this layer.\n *\n * The children may either be a set of operational layers (e.g. for a group layer) or a set of sublayers, or `undefined`.\n *\n * See also {@link layers} and {@link sublayers}.\n */\n get children(): ChildrenCollection<AnyLayer> | undefined {\n return this.layers ?? this.sublayers ?? undefined;\n }\n\n /**\n * Identifies the type of this layer.\n */\n abstract get type(): AnyLayerTypes;\n\n /**\n * Whether the layer is visible or not.\n *\n * NOTE: The model's visible state may do more than influence the raw OpenLayers's visibility property.\n * Future versions may completely remove invisible layers from the OpenLayer's map under some circumstances.\n */\n abstract get visible(): boolean;\n\n /**\n * If this layer is a group layer this property contains a collection of all layers that are members of the group.\n *\n * The property shall be `undefined` if it is not a group layer.\n *\n * The properties `layers` and `sublayers` are mutually exclusive.\n */\n abstract get layers(): GroupLayerCollection | undefined;\n\n /**\n * The collection of child sublayers for this layer. Sublayers are layers that cannot exist without an appropriate parent layer.\n *\n * Layers that can never have any sublayers may not have a `sublayers` collection.\n *\n * The properties `layers` and `sublayers` are mutually exclusive.\n */\n abstract get sublayers(): SublayersCollection<Sublayer> | undefined;\n\n /**\n * Legend URL from the service capabilities, if available.\n *\n * Note: this property may be expanded upon in the future, e.g. to support more variants than just image URLs.\n */\n abstract get legend(): string | undefined;\n\n /**\n * Attaches the layer to its owning map.\n *\n * @internal\n */\n [ATTACH_TO_MAP](map: MapModel): void {\n if (this.#map.value) {\n throw new Error(\n `Layer '${this.id}' has already been attached to the map '${this.map.id}'`\n );\n }\n this.#map.value = map;\n }\n\n /**\n * Attach group layers to its parent group layer.\n * Called by the parent layer.\n *\n * @internal\n */\n [ATTACH_TO_GROUP](parent: GroupLayer): void {\n if (this.#parent) {\n throw new Error(\n `Layer '${this.id}' has already been attached to the group layer '${this.#parent.id}'`\n );\n }\n this.#parent = parent;\n }\n\n /**\n * Called when a layer is removed from the map.\n *\n * @internal\n */\n [DETACH_FROM_MAP](): void {\n this.#map.value = undefined;\n }\n\n /**\n * Detach layer from parent group layer.\n *\n * Called by the parent group layer when destroyed or the layer gets removed.\n *\n * @internal\n */\n [DETACH_FROM_GROUP](): void {\n this.#parent = undefined;\n }\n\n /**\n * Updates the title of this layer.\n */\n setTitle(newTitle: string): void {\n this.#title.value = newTitle;\n }\n\n /**\n * Updates the description of this layer.\n */\n setDescription(newDescription: string): void {\n this.#description.value = newDescription;\n }\n\n /**\n * Updates the internal property of this layer to the new value.\n */\n setInternal(newIsInternal: boolean): void {\n this.#internal.value = newIsInternal;\n }\n\n /**\n * Updates the attributes of this layer.\n * Values in `newAttributes` will override existing values with the same key.\n */\n updateAttributes(newAttributes: Record<string | symbol, unknown>): void {\n const keys = Reflect.ownKeys(newAttributes);\n batch(() => {\n for (const key of keys) {\n this.#attributesMap.set(key, newAttributes[key]);\n }\n });\n }\n\n /**\n * Deletes the attribute of this layer.\n */\n deleteAttribute(deleteAttribute: string | symbol): void {\n this.#attributesMap.delete(deleteAttribute);\n }\n\n /**\n * Updates the visibility of this layer to the new value.\n *\n * NOTE: The visibility of base layers cannot be changed through this method.\n * Call {@link LayerCollection.activateBaseLayer} instead.\n */\n abstract setVisible(newVisibility: boolean): void;\n}\n"],"names":["uuid4v"],"mappings":"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"}
|
package/layers/GroupLayer.d.ts
CHANGED
|
@@ -3,8 +3,8 @@ import { MapModel } from "../model/MapModel";
|
|
|
3
3
|
import { InternalConstructorTag } from "../utils/InternalConstructorTag";
|
|
4
4
|
import { AbstractLayer } from "./AbstractLayer";
|
|
5
5
|
import { GroupLayerCollection } from "./group/GroupLayerCollection";
|
|
6
|
-
import { LayerConfig } from "./shared/LayerConfig";
|
|
7
6
|
import { ATTACH_TO_MAP, DETACH_FROM_MAP, LayerDependencies } from "./shared/internals";
|
|
7
|
+
import { LayerConfig } from "./shared/LayerConfig";
|
|
8
8
|
import { Layer } from "./unions";
|
|
9
9
|
/**
|
|
10
10
|
* Configuration options to construct a {@link GroupLayer}.
|
|
@@ -42,6 +42,7 @@ export declare class GroupLayer extends AbstractLayer {
|
|
|
42
42
|
constructor(config: GroupLayerConfig, deps: LayerDependencies, internalTag: InternalConstructorTag);
|
|
43
43
|
get type(): "group";
|
|
44
44
|
get legend(): undefined;
|
|
45
|
+
get olSource(): undefined;
|
|
45
46
|
/**
|
|
46
47
|
* Layers contained in this group.
|
|
47
48
|
*/
|
package/layers/GroupLayer.js
CHANGED
|
@@ -19,7 +19,7 @@ class GroupLayer extends AbstractLayer {
|
|
|
19
19
|
}
|
|
20
20
|
const groupLayers = config.layers;
|
|
21
21
|
const olGroup = new Group({ layers: groupLayers.map((sublayer) => sublayer.olLayer) });
|
|
22
|
-
super({ ...config, olLayer: olGroup }, deps, internalTag);
|
|
22
|
+
super({ ...config, olLayer: olGroup, initialLoadInfo: "loaded" }, deps, internalTag);
|
|
23
23
|
this.#children = new GroupLayerCollection(groupLayers, this, INTERNAL_CONSTRUCTOR_TAG);
|
|
24
24
|
}
|
|
25
25
|
get type() {
|
|
@@ -28,6 +28,9 @@ class GroupLayer extends AbstractLayer {
|
|
|
28
28
|
get legend() {
|
|
29
29
|
return void 0;
|
|
30
30
|
}
|
|
31
|
+
get olSource() {
|
|
32
|
+
return void 0;
|
|
33
|
+
}
|
|
31
34
|
/**
|
|
32
35
|
* Layers contained in this group.
|
|
33
36
|
*/
|
package/layers/GroupLayer.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"GroupLayer.js","sources":["GroupLayer.ts"],"sourcesContent":["// SPDX-FileCopyrightText: 2023-2025 Open Pioneer project (https://github.com/open-pioneer)\n// SPDX-License-Identifier: Apache-2.0\nimport { deprecated } from \"@open-pioneer/core\";\nimport { Group } from \"ol/layer\";\nimport type { LayerFactory } from \"../LayerFactory\";\nimport { MapModel } from \"../model/MapModel\";\nimport { INTERNAL_CONSTRUCTOR_TAG, InternalConstructorTag } from \"../utils/InternalConstructorTag\";\nimport { AbstractLayer } from \"./AbstractLayer\";\nimport { GroupLayerCollection } from \"./group/GroupLayerCollection\";\nimport {
|
|
1
|
+
{"version":3,"file":"GroupLayer.js","sources":["GroupLayer.ts"],"sourcesContent":["// SPDX-FileCopyrightText: 2023-2025 Open Pioneer project (https://github.com/open-pioneer)\n// SPDX-License-Identifier: Apache-2.0\n\nimport { deprecated } from \"@open-pioneer/core\";\nimport { Group } from \"ol/layer\";\n// oxlint-disable-next-line @typescript-eslint/no-unused-vars\nimport type { LayerFactory } from \"../LayerFactory\";\nimport { MapModel } from \"../model/MapModel\";\nimport { INTERNAL_CONSTRUCTOR_TAG, InternalConstructorTag } from \"../utils/InternalConstructorTag\";\nimport { AbstractLayer } from \"./AbstractLayer\";\nimport { GroupLayerCollection } from \"./group/GroupLayerCollection\";\nimport {\n ATTACH_TO_MAP,\n DETACH_FROM_MAP,\n GET_RAW_LAYERS,\n LayerConstructor,\n LayerDependencies\n} from \"./shared/internals\";\nimport { LayerConfig } from \"./shared/LayerConfig\";\nimport { Layer } from \"./unions\";\n\n/**\n * Configuration options to construct a {@link GroupLayer}.\n *\n * @group Layers\n */\nexport interface GroupLayerConfig extends LayerConfig {\n /**\n * List of layers that belong to the new group layer.\n *\n * The group layer takes ownership of the given layers: they will be destroyed when the parent is destroyed.\n * A layer must have a unique parent: it can only be added to the map or a single group layer.\n */\n layers: Layer[];\n}\n\nconst deprecatedConstructor = deprecated({\n name: \"GroupLayer constructor\",\n packageName: \"@open-pioneer/map\",\n since: \"v1.0.0\",\n alternative: \"use LayerFactory.create() instead\"\n});\n\n/**\n * Represents a group of layers.\n *\n * A group layer contains a collection of {@link Layer} children.\n * Groups can be nested to form a hierarchy.\n *\n * @group Layers\n */\nexport class GroupLayer extends AbstractLayer {\n #children: GroupLayerCollection;\n\n /**\n * @deprecated Prefer using {@link LayerFactory.create} instead of calling the constructor directly\n */\n constructor(config: GroupLayerConfig);\n\n /**\n * NOTE: Do not use this overload. Use {@link LayerFactory.create} instead.\n *\n * @internal\n */\n constructor(\n config: GroupLayerConfig,\n deps: LayerDependencies,\n internalTag: InternalConstructorTag\n );\n\n constructor(\n config: GroupLayerConfig,\n deps?: LayerDependencies,\n internalTag?: InternalConstructorTag\n ) {\n if (!internalTag) {\n deprecatedConstructor();\n }\n\n const groupLayers = config.layers;\n const olGroup = new Group({ layers: groupLayers.map((sublayer) => sublayer.olLayer) });\n super({ ...config, olLayer: olGroup, initialLoadInfo: \"loaded\" }, deps, internalTag);\n this.#children = new GroupLayerCollection(groupLayers, this, INTERNAL_CONSTRUCTOR_TAG);\n }\n\n override get type() {\n return \"group\" as const;\n }\n\n override get legend() {\n return undefined;\n }\n\n override get olSource() {\n return undefined;\n }\n\n /**\n * Layers contained in this group.\n */\n override get layers(): GroupLayerCollection {\n return this.#children;\n }\n\n override get sublayers(): undefined {\n return undefined;\n }\n\n /**\n * Raw OpenLayers group instance.\n *\n * **Warning:** Do not manipulate the collection of layers in this group directly, changes are not synchronized!\n */\n override get olLayer(): Group {\n return super.olLayer as Group;\n }\n\n /** @internal */\n override [ATTACH_TO_MAP](map: MapModel): void {\n super[ATTACH_TO_MAP](map);\n this.layers[GET_RAW_LAYERS]().forEach((layer) => layer[ATTACH_TO_MAP](map));\n }\n\n /** @internal */\n override [DETACH_FROM_MAP](): void {\n super[DETACH_FROM_MAP]();\n this.layers[GET_RAW_LAYERS]().forEach((layer) => layer[DETACH_FROM_MAP]());\n }\n}\n\n// Ensure layer class is assignable to the constructor interface (there is no \"implements\" for the class itself).\n// oxlint-disable-next-line no-constant-condition\nif (false) {\n const check: LayerConstructor<GroupLayerConfig, GroupLayer> = GroupLayer;\n void check;\n}\n"],"names":[],"mappings":";;;;;;;AAoCA,MAAM,wBAAwB,UAAA,CAAW;AAAA,EACrC,IAAA,EAAM,wBAAA;AAAA,EACN,WAAA,EAAa,mBAAA;AAAA,EACb,KAAA,EAAO,QAAA;AAAA,EACP,WAAA,EAAa;AACjB,CAAC,CAAA;AAUM,MAAM,mBAAmB,aAAA,CAAc;AAAA,EAC1C,SAAA;AAAA,EAkBA,WAAA,CACI,MAAA,EACA,IAAA,EACA,WAAA,EACF;AACE,IAAA,IAAI,CAAC,WAAA,EAAa;AACd,MAAA,qBAAA,EAAsB;AAAA,IAC1B;AAEA,IAAA,MAAM,cAAc,MAAA,CAAO,MAAA;AAC3B,IAAA,MAAM,OAAA,GAAU,IAAI,KAAA,CAAM,EAAE,MAAA,EAAQ,WAAA,CAAY,GAAA,CAAI,CAAC,QAAA,KAAa,QAAA,CAAS,OAAO,CAAA,EAAG,CAAA;AACrF,IAAA,KAAA,CAAM,EAAE,GAAG,MAAA,EAAQ,OAAA,EAAS,SAAS,eAAA,EAAiB,QAAA,EAAS,EAAG,IAAA,EAAM,WAAW,CAAA;AACnF,IAAA,IAAA,CAAK,SAAA,GAAY,IAAI,oBAAA,CAAqB,WAAA,EAAa,MAAM,wBAAwB,CAAA;AAAA,EACzF;AAAA,EAEA,IAAa,IAAA,GAAO;AAChB,IAAA,OAAO,OAAA;AAAA,EACX;AAAA,EAEA,IAAa,MAAA,GAAS;AAClB,IAAA,OAAO,MAAA;AAAA,EACX;AAAA,EAEA,IAAa,QAAA,GAAW;AACpB,IAAA,OAAO,MAAA;AAAA,EACX;AAAA;AAAA;AAAA;AAAA,EAKA,IAAa,MAAA,GAA+B;AACxC,IAAA,OAAO,IAAA,CAAK,SAAA;AAAA,EAChB;AAAA,EAEA,IAAa,SAAA,GAAuB;AAChC,IAAA,OAAO,MAAA;AAAA,EACX;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,IAAa,OAAA,GAAiB;AAC1B,IAAA,OAAO,KAAA,CAAM,OAAA;AAAA,EACjB;AAAA;AAAA,EAGA,CAAU,aAAa,CAAA,CAAE,GAAA,EAAqB;AAC1C,IAAA,KAAA,CAAM,aAAa,EAAE,GAAG,CAAA;AACxB,IAAA,IAAA,CAAK,MAAA,CAAO,cAAc,CAAA,EAAE,CAAE,OAAA,CAAQ,CAAC,KAAA,KAAU,KAAA,CAAM,aAAa,CAAA,CAAE,GAAG,CAAC,CAAA;AAAA,EAC9E;AAAA;AAAA,EAGA,CAAU,eAAe,CAAA,GAAU;AAC/B,IAAA,KAAA,CAAM,eAAe,CAAA,EAAE;AACvB,IAAA,IAAA,CAAK,MAAA,CAAO,cAAc,CAAA,EAAE,CAAE,OAAA,CAAQ,CAAC,KAAA,KAAU,KAAA,CAAM,eAAe,CAAA,EAAG,CAAA;AAAA,EAC7E;AACJ;;;;"}
|
package/layers/SimpleLayer.d.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import type OlBaseLayer from "ol/layer/Base";
|
|
2
2
|
import { InternalConstructorTag } from "../utils/InternalConstructorTag";
|
|
3
3
|
import { AbstractLayer } from "./AbstractLayer";
|
|
4
|
-
import { LayerConfig } from "./shared/LayerConfig";
|
|
5
4
|
import { LayerDependencies } from "./shared/internals";
|
|
5
|
+
import { LayerConfig } from "./shared/LayerConfig";
|
|
6
6
|
/**
|
|
7
7
|
* Options to construct a simple layer.
|
|
8
8
|
*
|
package/layers/SimpleLayer.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SimpleLayer.js","sources":["SimpleLayer.ts"],"sourcesContent":["// SPDX-FileCopyrightText: 2023-2025 Open Pioneer project (https://github.com/open-pioneer)\n// SPDX-License-Identifier: Apache-2.0\nimport { deprecated } from \"@open-pioneer/core\";\nimport type OlBaseLayer from \"ol/layer/Base\";\nimport type { LayerFactory } from \"../LayerFactory\";\nimport { InternalConstructorTag } from \"../utils/InternalConstructorTag\";\nimport { AbstractLayer } from \"./AbstractLayer\";\nimport {
|
|
1
|
+
{"version":3,"file":"SimpleLayer.js","sources":["SimpleLayer.ts"],"sourcesContent":["// SPDX-FileCopyrightText: 2023-2025 Open Pioneer project (https://github.com/open-pioneer)\n// SPDX-License-Identifier: Apache-2.0\n\nimport { deprecated } from \"@open-pioneer/core\";\nimport type OlBaseLayer from \"ol/layer/Base\";\n// oxlint-disable-next-line @typescript-eslint/no-unused-vars\nimport type { LayerFactory } from \"../LayerFactory\";\nimport { InternalConstructorTag } from \"../utils/InternalConstructorTag\";\nimport { AbstractLayer } from \"./AbstractLayer\";\nimport { LayerConstructor, LayerDependencies } from \"./shared/internals\";\nimport { LayerConfig } from \"./shared/LayerConfig\";\n\n/**\n * Options to construct a simple layer.\n *\n * Simple layers are wrappers around a custom OpenLayers layer.\n *\n * @group Layers\n */\nexport interface SimpleLayerConfig extends LayerConfig {\n /**\n * The raw OpenLayers instance.\n */\n olLayer: OlBaseLayer;\n}\n\nconst deprecatedConstructor = deprecated({\n name: \"SimpleLayer constructor\",\n packageName: \"@open-pioneer/map\",\n since: \"v1.0.0\",\n alternative: \"use LayerFactory.create() instead\"\n});\n\n/**\n * A simple layer that accepts a custom OpenLayers layer instance.\n *\n * Any kind of open layers can be made to work with the map package using this class.\n * Some API features (such as sublayers) may not be available.\n *\n * @group Layers\n */\nexport class SimpleLayer extends AbstractLayer {\n /**\n * @deprecated Prefer using {@link LayerFactory.create} instead of calling the constructor directly\n */\n constructor(config: SimpleLayerConfig);\n\n /**\n * NOTE: Do not use this overload. Use {@link LayerFactory.create} instead.\n *\n * @internal\n */\n constructor(\n config: SimpleLayerConfig,\n deps: LayerDependencies,\n internalTag: InternalConstructorTag\n );\n constructor(\n config: SimpleLayerConfig,\n deps?: LayerDependencies,\n internalTag?: InternalConstructorTag\n ) {\n if (!internalTag) {\n deprecatedConstructor();\n }\n super({ ...config, initialLoadInfo: \"loaded\" }, deps, internalTag);\n }\n\n override get type() {\n return \"simple\" as const;\n }\n\n override get legend(): undefined {\n return undefined;\n }\n\n override get layers(): undefined {\n return undefined;\n }\n\n override get sublayers(): undefined {\n return undefined;\n }\n}\n\n// Ensure layer class is assignable to the constructor interface (there is no \"implements\" for the class itself).\n// oxlint-disable-next-line no-constant-condition\nif (false) {\n const check: LayerConstructor<SimpleLayerConfig, SimpleLayer> = SimpleLayer;\n void check;\n}\n"],"names":[],"mappings":";;;AA0BA,MAAM,wBAAwB,UAAA,CAAW;AAAA,EACrC,IAAA,EAAM,yBAAA;AAAA,EACN,WAAA,EAAa,mBAAA;AAAA,EACb,KAAA,EAAO,QAAA;AAAA,EACP,WAAA,EAAa;AACjB,CAAC,CAAA;AAUM,MAAM,oBAAoB,aAAA,CAAc;AAAA,EAgB3C,WAAA,CACI,MAAA,EACA,IAAA,EACA,WAAA,EACF;AACE,IAAA,IAAI,CAAC,WAAA,EAAa;AACd,MAAA,qBAAA,EAAsB;AAAA,IAC1B;AACA,IAAA,KAAA,CAAM,EAAE,GAAG,MAAA,EAAQ,iBAAiB,QAAA,EAAS,EAAG,MAAM,WAAW,CAAA;AAAA,EACrE;AAAA,EAEA,IAAa,IAAA,GAAO;AAChB,IAAA,OAAO,QAAA;AAAA,EACX;AAAA,EAEA,IAAa,MAAA,GAAoB;AAC7B,IAAA,OAAO,MAAA;AAAA,EACX;AAAA,EAEA,IAAa,MAAA,GAAoB;AAC7B,IAAA,OAAO,MAAA;AAAA,EACX;AAAA,EAEA,IAAa,SAAA,GAAuB;AAChC,IAAA,OAAO,MAAA;AAAA,EACX;AACJ;;;;"}
|
package/layers/WMSLayer.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { computed, watch, batch } from '@conterra/reactivity-core';
|
|
1
|
+
import { reactive, computed, watch, batch } from '@conterra/reactivity-core';
|
|
2
2
|
import { createLogger, deprecated, destroyResource, isAbortError } from '@open-pioneer/core';
|
|
3
3
|
import WMSCapabilities from 'ol/format/WMSCapabilities.js';
|
|
4
4
|
import ImageLayer from 'ol/layer/Image.js';
|
|
@@ -7,11 +7,11 @@ import { sourceId$7 as sourceId } from '../_virtual/source-info.js';
|
|
|
7
7
|
import { fetchText } from '../utils/fetch.js';
|
|
8
8
|
import { INTERNAL_CONSTRUCTOR_TAG } from '../utils/InternalConstructorTag.js';
|
|
9
9
|
import { AbstractLayer } from './AbstractLayer.js';
|
|
10
|
-
import { GET_RAW_SUBLAYERS, ATTACH_TO_PARENT, ATTACH_TO_MAP, DETACH_FROM_MAP, GET_DEPS, SET_LEGEND } from './shared/internals.js';
|
|
10
|
+
import { GET_RAW_SUBLAYERS, ATTACH_TO_PARENT, ATTACH_TO_MAP, DETACH_FROM_MAP, SET_METADATA_LOAD_INFO, GET_DEPS, SET_LEGEND } from './shared/internals.js';
|
|
11
11
|
import { SublayersCollection } from './shared/SublayersCollection.js';
|
|
12
12
|
import { getAttributions } from './wms/getAttributions.js';
|
|
13
13
|
import { getLegendUrl } from './wms/getLegendUrl.js';
|
|
14
|
-
import { constructSublayers } from './wms/WMSSublayer.js';
|
|
14
|
+
import { constructSublayers, SET_SUBLAYER_LOAD_INFO } from './wms/WMSSublayer.js';
|
|
15
15
|
|
|
16
16
|
const LOG = createLogger(sourceId);
|
|
17
17
|
const deprecatedConstructor = deprecated({
|
|
@@ -27,8 +27,9 @@ class WMSLayer extends AbstractLayer {
|
|
|
27
27
|
#source;
|
|
28
28
|
#fetchCapabilities;
|
|
29
29
|
#loadStarted = false;
|
|
30
|
-
//
|
|
30
|
+
// oxlint-disable-next-line @typescript-eslint/no-explicit-any
|
|
31
31
|
#capabilities;
|
|
32
|
+
#invalidSublayerNames = reactive();
|
|
32
33
|
#abortController = new AbortController();
|
|
33
34
|
#visibleSublayers;
|
|
34
35
|
#sublayersWatch;
|
|
@@ -142,16 +143,22 @@ class WMSLayer extends AbstractLayer {
|
|
|
142
143
|
return;
|
|
143
144
|
}
|
|
144
145
|
this.#loadStarted = true;
|
|
146
|
+
this[SET_METADATA_LOAD_INFO]("loading");
|
|
145
147
|
this.#fetchWMSCapabilities().then((result) => {
|
|
146
148
|
batch(() => {
|
|
147
149
|
this.#initializeWithMetadata(result);
|
|
150
|
+
this[SET_METADATA_LOAD_INFO]("loaded");
|
|
148
151
|
});
|
|
149
152
|
}).catch((error) => {
|
|
150
153
|
if (isAbortError(error)) {
|
|
151
154
|
LOG.debug(`Layer '${this.id}' has been destroyed before fetching capabilities`);
|
|
152
|
-
return;
|
|
153
155
|
}
|
|
154
156
|
LOG.error(`Failed to initialize WMS layer '${this.id}'`, error);
|
|
157
|
+
const wrappedError = error instanceof Error ? error : new Error(`Failed to initialize WMS layer '${this.id}'`);
|
|
158
|
+
this[SET_METADATA_LOAD_INFO]({
|
|
159
|
+
kind: "error",
|
|
160
|
+
error: wrappedError
|
|
161
|
+
});
|
|
155
162
|
});
|
|
156
163
|
}
|
|
157
164
|
/**
|
|
@@ -160,7 +167,7 @@ class WMSLayer extends AbstractLayer {
|
|
|
160
167
|
*/
|
|
161
168
|
#updateLayersParam(layers) {
|
|
162
169
|
this.#source.updateParams({
|
|
163
|
-
|
|
170
|
+
LAYERS: layers
|
|
164
171
|
});
|
|
165
172
|
const source = layers.length === 0 ? null : this.#source;
|
|
166
173
|
if (this.#layer.getSource() !== source) {
|
|
@@ -168,9 +175,13 @@ class WMSLayer extends AbstractLayer {
|
|
|
168
175
|
}
|
|
169
176
|
}
|
|
170
177
|
#getVisibleLayerNames() {
|
|
178
|
+
const invalidSublayerNames = this.#invalidSublayerNames.value;
|
|
171
179
|
const layers = [];
|
|
172
180
|
const filter = (sublayer) => sublayer.visible;
|
|
173
181
|
for (const sublayer of walkLeaves(this.#sublayers, filter)) {
|
|
182
|
+
if (sublayer.name && invalidSublayerNames && invalidSublayerNames.has(sublayer.name)) {
|
|
183
|
+
continue;
|
|
184
|
+
}
|
|
174
185
|
if (sublayer.name) {
|
|
175
186
|
layers.push(sublayer.name);
|
|
176
187
|
}
|
|
@@ -192,12 +203,31 @@ class WMSLayer extends AbstractLayer {
|
|
|
192
203
|
this.#source.setAttributions(attributions);
|
|
193
204
|
}
|
|
194
205
|
}
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
206
|
+
const hasCapabilityTree = !!capabilities?.Capability?.Layer;
|
|
207
|
+
const sublayerNames = hasCapabilityTree ? collectLayerNames(capabilities) : void 0;
|
|
208
|
+
const invalidSublayerNames = /* @__PURE__ */ new Set();
|
|
209
|
+
for (const sublayer of walkLeaves(this.#sublayers)) {
|
|
210
|
+
if (!sublayer.name) {
|
|
211
|
+
continue;
|
|
199
212
|
}
|
|
213
|
+
if (sublayerNames && !sublayerNames.has(sublayer.name)) {
|
|
214
|
+
LOG.error(
|
|
215
|
+
`WMS sublayer name '${sublayer.name}' of layer '${this.id}' not found in capabilities.`
|
|
216
|
+
);
|
|
217
|
+
invalidSublayerNames.add(sublayer.name);
|
|
218
|
+
sublayer[SET_SUBLAYER_LOAD_INFO]({
|
|
219
|
+
kind: "error",
|
|
220
|
+
error: new Error(
|
|
221
|
+
`WMS sublayer name '${sublayer.name}' not found in capabilities.`
|
|
222
|
+
)
|
|
223
|
+
});
|
|
224
|
+
continue;
|
|
225
|
+
}
|
|
226
|
+
sublayer[SET_SUBLAYER_LOAD_INFO]("loaded");
|
|
227
|
+
const legendUrl = getLegendUrl(capabilities, sublayer.name);
|
|
228
|
+
sublayer[SET_LEGEND](legendUrl);
|
|
200
229
|
}
|
|
230
|
+
this.#invalidSublayerNames.value = invalidSublayerNames;
|
|
201
231
|
}
|
|
202
232
|
async #loadImage(imageWrapper, imageUrl) {
|
|
203
233
|
const httpService = this[GET_DEPS]().httpService;
|
|
@@ -218,6 +248,24 @@ class WMSLayer extends AbstractLayer {
|
|
|
218
248
|
image.src = objectUrl;
|
|
219
249
|
}
|
|
220
250
|
}
|
|
251
|
+
function collectLayerNames(capabilities) {
|
|
252
|
+
const names = /* @__PURE__ */ new Set();
|
|
253
|
+
const visit = (layer) => {
|
|
254
|
+
if (!layer) {
|
|
255
|
+
return;
|
|
256
|
+
}
|
|
257
|
+
if (typeof layer.Name === "string") {
|
|
258
|
+
names.add(layer.Name);
|
|
259
|
+
}
|
|
260
|
+
if (Array.isArray(layer.Layer)) {
|
|
261
|
+
for (const child of layer.Layer) {
|
|
262
|
+
visit(child);
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
};
|
|
266
|
+
visit(capabilities?.Capability?.Layer);
|
|
267
|
+
return names;
|
|
268
|
+
}
|
|
221
269
|
function* walkLeaves(sublayers, filter) {
|
|
222
270
|
for (const sublayer of sublayers[GET_RAW_SUBLAYERS]()) {
|
|
223
271
|
if (filter && !filter(sublayer)) {
|
package/layers/WMSLayer.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"WMSLayer.js","sources":["WMSLayer.ts"],"sourcesContent":["// SPDX-FileCopyrightText: 2023-2025 Open Pioneer project (https://github.com/open-pioneer)\n// SPDX-License-Identifier: Apache-2.0\nimport { batch, computed, ReadonlyReactive, watch } from \"@conterra/reactivity-core\";\nimport {\n createLogger,\n deprecated,\n destroyResource,\n isAbortError,\n Resource\n} 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 type { Options as WMSSourceOptions } from \"ol/source/ImageWMS\";\nimport ImageWMS from \"ol/source/ImageWMS\";\nimport { sourceId } from \"open-pioneer:source-info\";\nimport type { LayerFactory } from \"../LayerFactory\";\nimport { MapModel } from \"../model/MapModel\";\nimport { fetchText } from \"../utils/fetch\";\nimport { INTERNAL_CONSTRUCTOR_TAG, InternalConstructorTag } from \"../utils/InternalConstructorTag\";\nimport { AbstractLayer } from \"./AbstractLayer\";\nimport {\n ATTACH_TO_MAP,\n ATTACH_TO_PARENT,\n DETACH_FROM_MAP,\n GET_DEPS,\n GET_RAW_SUBLAYERS,\n LayerConstructor,\n LayerDependencies,\n SET_LEGEND\n} from \"./shared/internals\";\nimport { LayerConfig } from \"./shared/LayerConfig\";\nimport { SublayersCollection } from \"./shared/SublayersCollection\";\nimport { getAttributions } from \"./wms/getAttributions\";\nimport { getLegendUrl } from \"./wms/getLegendUrl\";\nimport { constructSublayers, WMSSublayer, WMSSublayerConfig } from \"./wms/WMSSublayer\";\nimport { Sublayer } from \"./unions\";\n\n/**\n * Configuration options to construct a {@link WMSLayer}.\n *\n * @group Layers\n */\nexport interface WMSLayerConfig extends LayerConfig {\n /** URL of the WMS service. */\n url: string;\n\n /** Configures the layer's sublayers. */\n sublayers?: WMSSublayerConfig[];\n\n /**\n * Additional source options for the layer's WMS source.\n *\n * NOTE: These options are intended for advanced configuration:\n * the WMS Layer manages some of the OpenLayers source options itself.\n */\n sourceOptions?: Partial<WMSSourceOptions>;\n\n /**\n * Whether to automatically fetch capabilities from the service when needed (default: `true`).\n *\n * Setting this to `false` can be useful as a performance optimization when capabilities are not really required by the application.\n * Note that this will disable some features of the WMS layer: for example, the legend URL will not be available.\n */\n fetchCapabilities?: boolean;\n}\n\nconst LOG = createLogger(sourceId);\n\nconst deprecatedConstructor = deprecated({\n name: \"WMSLayer constructor\",\n packageName: \"@open-pioneer/map\",\n since: \"v1.0.0\",\n alternative: \"use LayerFactory.create() instead\"\n});\n\n/**\n * Displays an OGC Web Map Service (WMS).\n *\n * @group Layers\n */\nexport class WMSLayer extends AbstractLayer {\n #url: string;\n #sublayers: SublayersCollection<WMSSublayer>;\n #layer: ImageLayer<ImageSource>;\n #source: ImageWMS;\n #fetchCapabilities: boolean;\n\n #loadStarted = false;\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 /**\n * @deprecated Prefer using {@link LayerFactory.create} instead of calling the constructor directly\n */\n constructor(config: WMSLayerConfig);\n\n /**\n * NOTE: Do not use this overload. Use {@link LayerFactory.create} instead.\n *\n * @internal\n */\n constructor(\n config: WMSLayerConfig,\n deps: LayerDependencies,\n internalTag: InternalConstructorTag\n );\n constructor(\n config: WMSLayerConfig,\n deps?: LayerDependencies,\n internalTag?: InternalConstructorTag\n ) {\n if (!internalTag) {\n deprecatedConstructor();\n }\n\n const layer = new ImageLayer();\n super(\n {\n ...config,\n olLayer: layer\n },\n deps,\n internalTag\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.#fetchCapabilities = config.fetchCapabilities ?? true;\n this.#source = source;\n this.#layer = layer;\n\n this.#sublayers = new SublayersCollection(\n constructSublayers(config.sublayers),\n INTERNAL_CONSTRUCTOR_TAG\n );\n this.#sublayers\n [GET_RAW_SUBLAYERS]()\n .forEach((sublayer) => sublayer[ATTACH_TO_PARENT](this, this));\n\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 override 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 /**\n * Returns the current source associated with this layer as a reactive property.\n *\n * Note that the return type may be expanded in the future with additional source types.\n */\n get olSource(): ImageWMS | undefined {\n // source does not change in this class; no signal is required\n return this.#source;\n }\n\n /** The URL of the WMS service that was used during layer construction. */\n get url(): string {\n return this.#url;\n }\n\n get layers(): undefined {\n return undefined;\n }\n\n /**\n * Holds the sublayers of this layer.\n */\n get sublayers(): SublayersCollection<WMSSublayer> {\n return this.#sublayers;\n }\n\n /**\n * @internal\n *\n * Note: this property was never documented and has been exposed by accident.\n **/\n get capabilities() {\n return this.#capabilities;\n }\n\n /** @internal */\n [ATTACH_TO_MAP](map: MapModel): void {\n super[ATTACH_TO_MAP](map);\n for (const sublayer of this.#sublayers.getSublayers()) {\n sublayer[ATTACH_TO_MAP](map);\n }\n\n this.#load();\n }\n\n /** @internal */\n [DETACH_FROM_MAP](): void {\n super[DETACH_FROM_MAP]();\n for (const sublayer of this.#sublayers.getSublayers()) {\n sublayer[DETACH_FROM_MAP]();\n }\n }\n\n #load() {\n if (this.#loadStarted || !this.#fetchCapabilities) {\n return;\n }\n this.#loadStarted = true;\n this.#fetchWMSCapabilities()\n .then((result: string) => {\n batch(() => {\n this.#initializeWithMetadata(result);\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 initialize WMS 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 filter = (sublayer: Sublayer) => sublayer.visible;\n for (const sublayer of walkLeaves(this.#sublayers, filter)) {\n // Push sublayer if layer name is not an empty string | undefined | ...\n if (sublayer.name) {\n layers.push(sublayer.name);\n }\n }\n return layers;\n }\n\n async #fetchWMSCapabilities(): Promise<string> {\n const httpService = this[GET_DEPS]().httpService;\n const url = `${this.#url}?LANGUAGE=ger&SERVICE=WMS&REQUEST=GetCapabilities`;\n return fetchText(url, httpService, this.#abortController.signal);\n }\n\n #initializeWithMetadata(metadata: string) {\n const parser = new WMSCapabilities();\n const capabilities = parser.read(metadata);\n this.#capabilities = capabilities;\n\n // Apply attributions from metadata if none are set.\n if (this.#source.getAttributions() == null) {\n const attributions = getAttributions(capabilities);\n if (attributions) {\n this.#source.setAttributions(attributions);\n }\n }\n\n for (const layer of walkLeaves(this.#sublayers)) {\n if (layer.name) {\n const legendUrl = getLegendUrl(capabilities, layer.name);\n layer[SET_LEGEND](legendUrl);\n }\n }\n }\n\n async #loadImage(imageWrapper: ImageWrapper, imageUrl: string): Promise<void> {\n const httpService = this[GET_DEPS]().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\n/**\n * Yields all leaf notes in the given collection (recursively).\n */\nfunction* walkLeaves(\n sublayers: SublayersCollection<WMSSublayer>,\n filter?: (sublayer: Sublayer) => boolean\n): Generator<WMSSublayer> {\n for (const sublayer of sublayers[GET_RAW_SUBLAYERS]()) {\n if (filter && !filter(sublayer)) {\n continue;\n }\n\n const nested = sublayer.sublayers[GET_RAW_SUBLAYERS]();\n if (nested.length) {\n yield* walkLeaves(sublayer.sublayers, filter);\n } else {\n yield sublayer;\n }\n }\n}\n\n// Ensure layer class is assignable to the constructor interface (there is no \"implements\" for the class itself).\n// eslint-disable-next-line no-constant-condition\nif (false) {\n const check: LayerConstructor<WMSLayerConfig, WMSLayer> = WMSLayer;\n void check;\n}\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"WMSLayer.js","sources":["WMSLayer.ts"],"sourcesContent":["// SPDX-FileCopyrightText: 2023-2025 Open Pioneer project (https://github.com/open-pioneer)\n// SPDX-License-Identifier: Apache-2.0\n\nimport { batch, computed, reactive, ReadonlyReactive, watch } from \"@conterra/reactivity-core\";\nimport {\n createLogger,\n deprecated,\n destroyResource,\n isAbortError,\n Resource\n} 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 type { Options as WMSSourceOptions } from \"ol/source/ImageWMS\";\nimport ImageWMS from \"ol/source/ImageWMS\";\nimport { sourceId } from \"open-pioneer:source-info\";\n// oxlint-disable-next-line @typescript-eslint/no-unused-vars\nimport type { LayerFactory } from \"../LayerFactory\";\nimport { MapModel } from \"../model/MapModel\";\nimport { fetchText } from \"../utils/fetch\";\nimport { INTERNAL_CONSTRUCTOR_TAG, InternalConstructorTag } from \"../utils/InternalConstructorTag\";\nimport { AbstractLayer } from \"./AbstractLayer\";\nimport {\n ATTACH_TO_MAP,\n ATTACH_TO_PARENT,\n DETACH_FROM_MAP,\n GET_DEPS,\n GET_RAW_SUBLAYERS,\n LayerConstructor,\n LayerDependencies,\n SET_LEGEND,\n SET_METADATA_LOAD_INFO\n} from \"./shared/internals\";\nimport { LayerConfig } from \"./shared/LayerConfig\";\nimport { SublayersCollection } from \"./shared/SublayersCollection\";\nimport { Sublayer } from \"./unions\";\nimport { getAttributions } from \"./wms/getAttributions\";\nimport { getLegendUrl } from \"./wms/getLegendUrl\";\nimport {\n constructSublayers,\n SET_SUBLAYER_LOAD_INFO,\n WMSSublayer,\n WMSSublayerConfig\n} from \"./wms/WMSSublayer\";\n\n/**\n * Configuration options to construct a {@link WMSLayer}.\n *\n * @group Layers\n */\nexport interface WMSLayerConfig extends LayerConfig {\n /** URL of the WMS service. */\n url: string;\n\n /** Configures the layer's sublayers. */\n sublayers?: WMSSublayerConfig[];\n\n /**\n * Additional source options for the layer's WMS source.\n *\n * NOTE: These options are intended for advanced configuration:\n * the WMS Layer manages some of the OpenLayers source options itself.\n */\n sourceOptions?: Partial<WMSSourceOptions>;\n\n /**\n * Whether to automatically fetch capabilities from the service when needed (default: `true`).\n *\n * Setting this to `false` can be useful as a performance optimization when capabilities are not really required by the application.\n * Note that this will disable some features of the WMS layer: for example, the legend URL will not be available.\n */\n fetchCapabilities?: boolean;\n}\n\nconst LOG = createLogger(sourceId);\n\nconst deprecatedConstructor = deprecated({\n name: \"WMSLayer constructor\",\n packageName: \"@open-pioneer/map\",\n since: \"v1.0.0\",\n alternative: \"use LayerFactory.create() instead\"\n});\n\n/**\n * Displays an OGC Web Map Service (WMS).\n *\n * @group Layers\n */\nexport class WMSLayer extends AbstractLayer {\n #url: string;\n #sublayers: SublayersCollection<WMSSublayer>;\n #layer: ImageLayer<ImageSource>;\n #source: ImageWMS;\n #fetchCapabilities: boolean;\n\n #loadStarted = false;\n // oxlint-disable-next-line @typescript-eslint/no-explicit-any\n #capabilities: Record<string, any> | undefined;\n readonly #invalidSublayerNames = reactive<Set<string>>();\n readonly #abortController = new AbortController();\n\n #visibleSublayers: ReadonlyReactive<string[]>;\n #sublayersWatch: Resource | undefined;\n\n /**\n * @deprecated Prefer using {@link LayerFactory.create} instead of calling the constructor directly\n */\n constructor(config: WMSLayerConfig);\n\n /**\n * NOTE: Do not use this overload. Use {@link LayerFactory.create} instead.\n *\n * @internal\n */\n constructor(\n config: WMSLayerConfig,\n deps: LayerDependencies,\n internalTag: InternalConstructorTag\n );\n constructor(\n config: WMSLayerConfig,\n deps?: LayerDependencies,\n internalTag?: InternalConstructorTag\n ) {\n if (!internalTag) {\n deprecatedConstructor();\n }\n\n const layer = new ImageLayer();\n super(\n {\n ...config,\n olLayer: layer\n },\n deps,\n internalTag\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.#fetchCapabilities = config.fetchCapabilities ?? true;\n this.#source = source;\n this.#layer = layer;\n\n this.#sublayers = new SublayersCollection(\n constructSublayers(config.sublayers),\n INTERNAL_CONSTRUCTOR_TAG\n );\n this.#sublayers\n [GET_RAW_SUBLAYERS]()\n .forEach((sublayer) => sublayer[ATTACH_TO_PARENT](this, this));\n\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 override 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 /**\n * Returns the current source associated with this layer as a reactive property.\n *\n * Note that the return type may be expanded in the future with additional source types.\n */\n get olSource(): ImageWMS | undefined {\n // source does not change in this class; no signal is required\n return this.#source;\n }\n\n /** The URL of the WMS service that was used during layer construction. */\n get url(): string {\n return this.#url;\n }\n\n get layers(): undefined {\n return undefined;\n }\n\n /**\n * Holds the sublayers of this layer.\n */\n get sublayers(): SublayersCollection<WMSSublayer> {\n return this.#sublayers;\n }\n\n /**\n * @internal\n *\n * Note: this property was never documented and has been exposed by accident.\n **/\n get capabilities() {\n return this.#capabilities;\n }\n\n /** @internal */\n [ATTACH_TO_MAP](map: MapModel): void {\n super[ATTACH_TO_MAP](map);\n for (const sublayer of this.#sublayers.getSublayers()) {\n sublayer[ATTACH_TO_MAP](map);\n }\n\n this.#load();\n }\n\n /** @internal */\n [DETACH_FROM_MAP](): void {\n super[DETACH_FROM_MAP]();\n for (const sublayer of this.#sublayers.getSublayers()) {\n sublayer[DETACH_FROM_MAP]();\n }\n }\n\n #load() {\n if (this.#loadStarted || !this.#fetchCapabilities) {\n return;\n }\n this.#loadStarted = true;\n this[SET_METADATA_LOAD_INFO](\"loading\");\n this.#fetchWMSCapabilities()\n .then((result: string) => {\n batch(() => {\n this.#initializeWithMetadata(result);\n this[SET_METADATA_LOAD_INFO](\"loaded\");\n });\n })\n .catch((error: unknown) => {\n if (isAbortError(error)) {\n LOG.debug(`Layer '${this.id}' has been destroyed before fetching capabilities`);\n }\n LOG.error(`Failed to initialize WMS layer '${this.id}'`, error);\n const wrappedError =\n error instanceof Error\n ? error\n : new Error(`Failed to initialize WMS layer '${this.id}'`);\n this[SET_METADATA_LOAD_INFO]({\n kind: \"error\",\n error: wrappedError\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(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 invalidSublayerNames = this.#invalidSublayerNames.value;\n\n const layers: string[] = [];\n const filter = (sublayer: Sublayer) => sublayer.visible;\n for (const sublayer of walkLeaves(this.#sublayers, filter)) {\n // Skip sublayers with an invalid name: including them in the request would\n // make the whole GetMap fail and hide the valid sublayers as well.\n if (sublayer.name && invalidSublayerNames && invalidSublayerNames.has(sublayer.name)) {\n continue;\n }\n // Push sublayer if layer name is not an empty string | undefined | ...\n if (sublayer.name) {\n layers.push(sublayer.name);\n }\n }\n return layers;\n }\n\n async #fetchWMSCapabilities(): Promise<string> {\n const httpService = this[GET_DEPS]().httpService;\n const url = `${this.#url}?LANGUAGE=ger&SERVICE=WMS&REQUEST=GetCapabilities`;\n return fetchText(url, httpService, this.#abortController.signal);\n }\n\n #initializeWithMetadata(metadata: string) {\n const parser = new WMSCapabilities();\n const capabilities = parser.read(metadata);\n this.#capabilities = capabilities;\n\n // Apply attributions from metadata if none are set.\n if (this.#source.getAttributions() == null) {\n const attributions = getAttributions(capabilities);\n if (attributions) {\n this.#source.setAttributions(attributions);\n }\n }\n\n const hasCapabilityTree = !!capabilities?.Capability?.Layer;\n const sublayerNames = hasCapabilityTree ? collectLayerNames(capabilities) : undefined;\n const invalidSublayerNames = new Set<string>();\n for (const sublayer of walkLeaves(this.#sublayers)) {\n if (!sublayer.name) {\n continue;\n }\n if (sublayerNames && !sublayerNames.has(sublayer.name)) {\n LOG.error(\n `WMS sublayer name '${sublayer.name}' of layer '${this.id}' not found in capabilities.`\n );\n invalidSublayerNames.add(sublayer.name);\n sublayer[SET_SUBLAYER_LOAD_INFO]({\n kind: \"error\",\n error: new Error(\n `WMS sublayer name '${sublayer.name}' not found in capabilities.`\n )\n });\n continue;\n }\n sublayer[SET_SUBLAYER_LOAD_INFO](\"loaded\");\n const legendUrl = getLegendUrl(capabilities, sublayer.name);\n sublayer[SET_LEGEND](legendUrl);\n }\n\n this.#invalidSublayerNames.value = invalidSublayerNames;\n }\n\n async #loadImage(imageWrapper: ImageWrapper, imageUrl: string): Promise<void> {\n const httpService = this[GET_DEPS]().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\n/**\n * Collects all layer `Name` values from a parsed WMS capabilities document.\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nfunction collectLayerNames(capabilities: Record<string, any> | undefined): Set<string> {\n const names = new Set<string>();\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const visit = (layer: Record<string, any> | undefined) => {\n if (!layer) {\n return;\n }\n if (typeof layer.Name === \"string\") {\n names.add(layer.Name);\n }\n if (Array.isArray(layer.Layer)) {\n for (const child of layer.Layer) {\n visit(child);\n }\n }\n };\n visit(capabilities?.Capability?.Layer);\n return names;\n}\n\n/**\n * Yields all leaf notes in the given collection (recursively).\n */\nfunction* walkLeaves(\n sublayers: SublayersCollection<WMSSublayer>,\n filter?: (sublayer: Sublayer) => boolean\n): Generator<WMSSublayer> {\n for (const sublayer of sublayers[GET_RAW_SUBLAYERS]()) {\n if (filter && !filter(sublayer)) {\n continue;\n }\n\n const nested = sublayer.sublayers[GET_RAW_SUBLAYERS]();\n if (nested.length) {\n yield* walkLeaves(sublayer.sublayers, filter);\n } else {\n yield sublayer;\n }\n }\n}\n\n// Ensure layer class is assignable to the constructor interface (there is no \"implements\" for the class itself).\n// oxlint-disable-next-line no-constant-condition\nif (false) {\n const check: LayerConstructor<WMSLayerConfig, WMSLayer> = WMSLayer;\n void check;\n}\n"],"names":[],"mappings":"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"}
|
package/layers/WMTSLayer.d.ts
CHANGED
|
@@ -2,8 +2,8 @@ import WMTS, { Options as WMTSSourceOptions } from "ol/source/WMTS";
|
|
|
2
2
|
import { MapModel } from "../model/MapModel";
|
|
3
3
|
import { InternalConstructorTag } from "../utils/InternalConstructorTag";
|
|
4
4
|
import { AbstractLayer } from "./AbstractLayer";
|
|
5
|
-
import { LayerConfig } from "./shared/LayerConfig";
|
|
6
5
|
import { ATTACH_TO_MAP, LayerDependencies } from "./shared/internals";
|
|
6
|
+
import { LayerConfig } from "./shared/LayerConfig";
|
|
7
7
|
/**
|
|
8
8
|
* Configuration options supported by {@link WMTSLayer}.
|
|
9
9
|
*
|
package/layers/WMTSLayer.js
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
import { reactive, batch } from '@conterra/reactivity-core';
|
|
2
2
|
import { createLogger, deprecated, isAbortError } from '@open-pioneer/core';
|
|
3
3
|
import { ImageTile } from 'ol';
|
|
4
|
-
import TileState from 'ol/TileState.js';
|
|
5
4
|
import WMTSCapabilities from 'ol/format/WMTSCapabilities.js';
|
|
6
5
|
import TileLayer from 'ol/layer/Tile.js';
|
|
7
6
|
import WMTS, { optionsFromCapabilities } from 'ol/source/WMTS.js';
|
|
7
|
+
import TileState from 'ol/TileState.js';
|
|
8
8
|
import { sourceId$9 as sourceId } from '../_virtual/source-info.js';
|
|
9
9
|
import { fetchText } from '../utils/fetch.js';
|
|
10
10
|
import { AbstractLayer } from './AbstractLayer.js';
|
|
11
|
-
import { ATTACH_TO_MAP, GET_DEPS } from './shared/internals.js';
|
|
11
|
+
import { ATTACH_TO_MAP, SET_METADATA_LOAD_INFO, GET_DEPS } from './shared/internals.js';
|
|
12
12
|
import { getAttributions } from './wmts/getAttributions.js';
|
|
13
13
|
import { getLegendUrl } from './wmts/getLegendUrl.js';
|
|
14
14
|
|
|
@@ -93,16 +93,22 @@ class WMTSLayer extends AbstractLayer {
|
|
|
93
93
|
return;
|
|
94
94
|
}
|
|
95
95
|
this.#loadStarted = true;
|
|
96
|
+
this[SET_METADATA_LOAD_INFO]("loading");
|
|
96
97
|
this.#fetchWMTSCapabilities().then((result) => {
|
|
97
98
|
batch(() => {
|
|
98
99
|
this.#initializeWithMetadata(result);
|
|
100
|
+
this[SET_METADATA_LOAD_INFO]("loaded");
|
|
99
101
|
});
|
|
100
102
|
}).catch((error) => {
|
|
101
103
|
if (isAbortError(error)) {
|
|
102
104
|
LOG.debug(`Layer '${this.name}' has been destroyed before fetching the data`);
|
|
103
|
-
return;
|
|
104
105
|
}
|
|
105
106
|
LOG.error(`Failed to initialize WMTS layer '${this.name}'`, error);
|
|
107
|
+
const wrappedError = error instanceof Error ? error : new Error(`Failed to initialize WMTS layer '${this.name}'`);
|
|
108
|
+
this[SET_METADATA_LOAD_INFO]({
|
|
109
|
+
kind: "error",
|
|
110
|
+
error: wrappedError
|
|
111
|
+
});
|
|
106
112
|
});
|
|
107
113
|
}
|
|
108
114
|
async #fetchWMTSCapabilities() {
|
|
@@ -174,7 +180,7 @@ class WMTSLayer extends AbstractLayer {
|
|
|
174
180
|
}
|
|
175
181
|
}
|
|
176
182
|
}
|
|
177
|
-
/*
|
|
183
|
+
/* oxlint-disable @typescript-eslint/no-explicit-any */
|
|
178
184
|
#existsStyleInCapabilities(capabilities, styleToUse) {
|
|
179
185
|
const layerDesc = capabilities.Contents?.Layer?.find(
|
|
180
186
|
(layer) => layer.Identifier === this.#name
|