@open-pioneer/map 1.2.0-dev.20260121105545 → 1.2.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 CHANGED
@@ -1,10 +1,13 @@
1
1
  # @open-pioneer/map
2
2
 
3
- ## 1.2.0-dev.20260121105545
3
+ ## 1.2.0
4
4
 
5
5
  ### Patch Changes
6
6
 
7
+ - 597584b: WMTSLayer: Fix type of `sourceOptions` parameter (was `WMS`, now `WMTS`).
8
+ - 9c29256: Update to core packages 4.4.0
7
9
  - 279ca67: Use `workspace:*` instead of `workspace:^` for local package references as default. This ensures that trails packages from this repository are always referenced with their exact version to avoid potential issues with version mismatches. If a project specifically wants to use other versions for some trails packages, a pnpm override can be used to force other versions.
10
+ - 597584b: WMTSLayer: Report better errors if `matrixSet` and `style` are not found in service capabilities.
8
11
  - 9580bb4: Update various dependencies.
9
12
  - 9580bb4: Update to Chakra 3.31.0
10
13
 
package/MapRegistry.js CHANGED
@@ -1,9 +1,10 @@
1
1
  import { batch } from '@conterra/reactivity-core';
2
2
  import { on } from '@conterra/reactivity-events';
3
3
  import { createLogger } from '@open-pioneer/core';
4
+ import { sourceId } from './_virtual/source-info.js';
4
5
  import { createMapModel } from './model/createMapModel.js';
5
6
 
6
- const LOG = createLogger("map:MapRegistry");
7
+ const LOG = createLogger(sourceId);
7
8
  class MapRegistry {
8
9
  #intl;
9
10
  #httpService;
@@ -1 +1 @@
1
- {"version":3,"file":"MapRegistry.js","sources":["MapRegistry.ts"],"sourcesContent":["// SPDX-FileCopyrightText: 2023-2025 Open Pioneer project (https://github.com/open-pioneer)\n// SPDX-License-Identifier: Apache-2.0\nimport { batch } from \"@conterra/reactivity-core\";\nimport { on } from \"@conterra/reactivity-events\";\nimport { createLogger, Resource } from \"@open-pioneer/core\";\nimport { HttpService } from \"@open-pioneer/http\";\nimport {\n DECLARE_SERVICE_INTERFACE,\n PackageIntl,\n Service,\n ServiceOptions\n} from \"@open-pioneer/runtime\";\nimport OlMap from \"ol/Map\";\nimport { LayerFactory } from \"./LayerFactory\";\nimport { createMapModel } from \"./model/createMapModel\";\nimport { MapConfig } from \"./model/MapConfig\";\nimport { MapModel } from \"./model/MapModel\";\n\nconst LOG = createLogger(\"map:MapRegistry\");\n\n/**\n * Options passed to the {@link MapConfigProvider.getMapConfig} method.\n *\n * @group Services\n */\nexport interface MapConfigProviderOptions {\n /**\n * A reference to the layer factory, for the construction of new layer instances.\n */\n layerFactory: LayerFactory;\n}\n\n/**\n * Provides an OpenLayers map configuration with a given map id.\n *\n * The implementor must also provide the interface name `\"map.MapConfigProvider\"`.\n *\n * @group Services\n */\nexport interface MapConfigProvider {\n /**\n * Unique identifier of the map.\n */\n readonly mapId: string;\n\n /**\n * Returns the map configuration for this map.\n *\n * Called by the {@link MapRegistry} when the map is requested for the first time.\n *\n * See {@link MapConfig} for supported options during map creation.\n * Use {@link MapConfigProviderOptions.layerFactory} to construct new layers.\n */\n getMapConfig(options: MapConfigProviderOptions): Promise<MapConfig>;\n}\n\ninterface References {\n providers: MapConfigProvider[];\n httpService: HttpService;\n layerFactory: LayerFactory;\n}\n\ntype ModelJobResult =\n | { kind: \"model\"; model: MapModel; listener: Resource }\n | { kind: \"error\"; error: Error };\n\n/**\n * Provides access to registered map instances.\n *\n * Maps are identified by a unique id.\n *\n * Inject an instance of this service by referencing the interface name `\"map.MapRegistry\"`.\n *\n * @group Services\n */\nexport class MapRegistry implements Service {\n declare [DECLARE_SERVICE_INTERFACE]: \"map.MapRegistry\";\n\n #intl: PackageIntl;\n #httpService: HttpService;\n #layerFactory: LayerFactory;\n\n #configProviders = new Map<string, MapConfigProvider>();\n #entries = new Map<string, ModelJobResult>();\n #modelCreationJobs = new Map<string, Promise<ModelJobResult>>();\n #modelsByOlMap = new WeakMap<OlMap, MapModel>();\n #destroyed = false;\n\n constructor({ references, intl }: ServiceOptions<References>) {\n this.#intl = intl;\n this.#httpService = references.httpService;\n this.#layerFactory = references.layerFactory;\n\n const providers = references.providers;\n for (const provider of providers) {\n this.#configProviders.set(provider.mapId, provider);\n }\n }\n\n destroy(): void {\n if (this.#destroyed) {\n return;\n }\n\n batch(() => {\n LOG.debug(`Destroy map registry and all maps`);\n this.#destroyed = true;\n this.#entries.forEach((entry) => {\n if (entry.kind === \"model\") {\n entry.listener.destroy();\n entry.model.destroy();\n }\n });\n this.#entries.clear();\n this.#modelCreationJobs.clear();\n });\n }\n\n /**\n * Returns the map model associated with the given id.\n * Returns undefined if there is no such model.\n */\n async getMapModel(mapId: string): Promise<MapModel | undefined> {\n if (this.#destroyed) {\n throw new Error(\"MapRegistry has already been destroyed.\");\n }\n\n const entry = this.#entries.get(mapId);\n if (entry) {\n return unbox(entry);\n }\n\n const creationJob = this.#modelCreationJobs.get(mapId);\n if (creationJob) {\n return await waitForResult(creationJob);\n }\n\n const provider = this.#configProviders.get(mapId);\n if (!provider) {\n LOG.debug(`Failed to find a config provider for map id '${mapId}'.`);\n return undefined;\n }\n\n return await this.#createMapModel(mapId, () =>\n provider.getMapConfig({\n layerFactory: this.#layerFactory\n })\n );\n }\n\n /**\n * Like {@link getMapModel}, but throws if no model exists for the given `mapId`.\n */\n async expectMapModel(mapId: string): Promise<MapModel> {\n const model = await this.getMapModel(mapId);\n if (!model) {\n throw new Error(`No configuration available for map with id '${mapId}'.`);\n }\n return model;\n }\n\n /**\n * Creates a MapModel without the need to provide a {@link MapConfigProvider}.\n * Throws an error if a map with the given id already exists or if the map config is invalid.\n */\n async createMapModel(mapId: string, options?: MapConfig): Promise<MapModel> {\n if (this.#destroyed) {\n throw new Error(\"MapRegistry has already been destroyed.\");\n }\n if (this.#entries.has(mapId)) {\n throw new Error(`Map id '${mapId}' is not unique.`);\n }\n if (this.#modelCreationJobs.has(mapId)) {\n throw new Error(`A map with the id '${mapId}' is already under construction.`);\n }\n return await this.#createMapModel(mapId, () => Promise.resolve(options ?? {}));\n }\n\n /**\n * Given a raw OpenLayers map instance, returns the associated {@link MapModel} - or undefined\n * if the map is unknown to this registry.\n *\n * All OpenLayers maps created by this registry (e.g. via {@link MapConfigProvider} or {@link createMapModel}) have an associated map model.\n */\n getMapModelByRawInstance(olMap: OlMap): MapModel | undefined {\n return this.#modelsByOlMap.get(olMap);\n }\n\n // Wrapper method to ensure that in-progress construction of maps can be observed.\n #createMapModel(mapId: string, configProvider: () => Promise<MapConfig>): Promise<MapModel> {\n const creationJob = this.#modelCreationJobs.get(mapId);\n if (creationJob) {\n throw new Error(\"Internal error: a map model is already being created for this mapId\");\n }\n\n const modelPromise = this.#createMapModelImpl(mapId, configProvider)\n .then((mapModel) => {\n if (this.#destroyed) {\n mapModel.destroy();\n throw new Error(`MapRegistry has been destroyed.`);\n }\n\n const listener = on(\n mapModel.destroyed,\n () => {\n // Allow id reuse for dynamically created maps\n if (this.#isDynamic(mapId)) {\n const currentEntry = this.#entries.get(mapId);\n if (currentEntry === entry) {\n this.#entries.delete(mapId);\n }\n }\n },\n { dispatch: \"sync\" }\n );\n\n const entry: ModelJobResult = { kind: \"model\", model: mapModel, listener };\n this.#entries.set(mapId, entry);\n this.#modelCreationJobs.delete(mapId);\n this.#modelsByOlMap.set(mapModel.olMap, mapModel);\n return entry;\n })\n .catch((cause) => {\n const error = new Error(`Failed to construct map '${mapId}'`, { cause });\n const entry: ModelJobResult = { kind: \"error\", error };\n this.#modelCreationJobs.delete(mapId);\n if (!this.#isDynamic(mapId)) {\n // Don't store errors for dynamically created maps (the caller already got the error via promise).\n this.#entries.set(mapId, entry);\n }\n return entry;\n });\n this.#modelCreationJobs.set(mapId, modelPromise);\n return waitForResult(modelPromise);\n }\n\n async #createMapModelImpl(\n mapId: string,\n configProvider: () => Promise<MapConfig>\n ): Promise<MapModel> {\n LOG.info(`Creating map with id '${mapId}'`);\n const mapConfig = await configProvider();\n const mapModel = await createMapModel(mapId, mapConfig, this.#intl, this.#httpService);\n return mapModel;\n }\n\n #isDynamic(mapId: string): boolean {\n return !this.#configProviders.has(mapId);\n }\n}\n\nasync function waitForResult(job: Promise<ModelJobResult>): Promise<MapModel> {\n return unbox(await job);\n}\n\nfunction unbox(entry: ModelJobResult): MapModel {\n if (entry.kind === \"error\") {\n throw entry.error;\n }\n return entry.model;\n}\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"MapRegistry.js","sources":["MapRegistry.ts"],"sourcesContent":["// SPDX-FileCopyrightText: 2023-2025 Open Pioneer project (https://github.com/open-pioneer)\n// SPDX-License-Identifier: Apache-2.0\nimport { batch } from \"@conterra/reactivity-core\";\nimport { on } from \"@conterra/reactivity-events\";\nimport { createLogger, Resource } from \"@open-pioneer/core\";\nimport { HttpService } from \"@open-pioneer/http\";\nimport {\n DECLARE_SERVICE_INTERFACE,\n PackageIntl,\n Service,\n ServiceOptions\n} from \"@open-pioneer/runtime\";\nimport OlMap from \"ol/Map\";\nimport { sourceId } from \"open-pioneer:source-info\";\nimport { LayerFactory } from \"./LayerFactory\";\nimport { createMapModel } from \"./model/createMapModel\";\nimport { MapConfig } from \"./model/MapConfig\";\nimport { MapModel } from \"./model/MapModel\";\n\nconst LOG = createLogger(sourceId);\n\n/**\n * Options passed to the {@link MapConfigProvider.getMapConfig} method.\n *\n * @group Services\n */\nexport interface MapConfigProviderOptions {\n /**\n * A reference to the layer factory, for the construction of new layer instances.\n */\n layerFactory: LayerFactory;\n}\n\n/**\n * Provides an OpenLayers map configuration with a given map id.\n *\n * The implementor must also provide the interface name `\"map.MapConfigProvider\"`.\n *\n * @group Services\n */\nexport interface MapConfigProvider {\n /**\n * Unique identifier of the map.\n */\n readonly mapId: string;\n\n /**\n * Returns the map configuration for this map.\n *\n * Called by the {@link MapRegistry} when the map is requested for the first time.\n *\n * See {@link MapConfig} for supported options during map creation.\n * Use {@link MapConfigProviderOptions.layerFactory} to construct new layers.\n */\n getMapConfig(options: MapConfigProviderOptions): Promise<MapConfig>;\n}\n\ninterface References {\n providers: MapConfigProvider[];\n httpService: HttpService;\n layerFactory: LayerFactory;\n}\n\ntype ModelJobResult =\n | { kind: \"model\"; model: MapModel; listener: Resource }\n | { kind: \"error\"; error: Error };\n\n/**\n * Provides access to registered map instances.\n *\n * Maps are identified by a unique id.\n *\n * Inject an instance of this service by referencing the interface name `\"map.MapRegistry\"`.\n *\n * @group Services\n */\nexport class MapRegistry implements Service {\n declare [DECLARE_SERVICE_INTERFACE]: \"map.MapRegistry\";\n\n #intl: PackageIntl;\n #httpService: HttpService;\n #layerFactory: LayerFactory;\n\n #configProviders = new Map<string, MapConfigProvider>();\n #entries = new Map<string, ModelJobResult>();\n #modelCreationJobs = new Map<string, Promise<ModelJobResult>>();\n #modelsByOlMap = new WeakMap<OlMap, MapModel>();\n #destroyed = false;\n\n constructor({ references, intl }: ServiceOptions<References>) {\n this.#intl = intl;\n this.#httpService = references.httpService;\n this.#layerFactory = references.layerFactory;\n\n const providers = references.providers;\n for (const provider of providers) {\n this.#configProviders.set(provider.mapId, provider);\n }\n }\n\n destroy(): void {\n if (this.#destroyed) {\n return;\n }\n\n batch(() => {\n LOG.debug(`Destroy map registry and all maps`);\n this.#destroyed = true;\n this.#entries.forEach((entry) => {\n if (entry.kind === \"model\") {\n entry.listener.destroy();\n entry.model.destroy();\n }\n });\n this.#entries.clear();\n this.#modelCreationJobs.clear();\n });\n }\n\n /**\n * Returns the map model associated with the given id.\n * Returns undefined if there is no such model.\n */\n async getMapModel(mapId: string): Promise<MapModel | undefined> {\n if (this.#destroyed) {\n throw new Error(\"MapRegistry has already been destroyed.\");\n }\n\n const entry = this.#entries.get(mapId);\n if (entry) {\n return unbox(entry);\n }\n\n const creationJob = this.#modelCreationJobs.get(mapId);\n if (creationJob) {\n return await waitForResult(creationJob);\n }\n\n const provider = this.#configProviders.get(mapId);\n if (!provider) {\n LOG.debug(`Failed to find a config provider for map id '${mapId}'.`);\n return undefined;\n }\n\n return await this.#createMapModel(mapId, () =>\n provider.getMapConfig({\n layerFactory: this.#layerFactory\n })\n );\n }\n\n /**\n * Like {@link getMapModel}, but throws if no model exists for the given `mapId`.\n */\n async expectMapModel(mapId: string): Promise<MapModel> {\n const model = await this.getMapModel(mapId);\n if (!model) {\n throw new Error(`No configuration available for map with id '${mapId}'.`);\n }\n return model;\n }\n\n /**\n * Creates a MapModel without the need to provide a {@link MapConfigProvider}.\n * Throws an error if a map with the given id already exists or if the map config is invalid.\n */\n async createMapModel(mapId: string, options?: MapConfig): Promise<MapModel> {\n if (this.#destroyed) {\n throw new Error(\"MapRegistry has already been destroyed.\");\n }\n if (this.#entries.has(mapId)) {\n throw new Error(`Map id '${mapId}' is not unique.`);\n }\n if (this.#modelCreationJobs.has(mapId)) {\n throw new Error(`A map with the id '${mapId}' is already under construction.`);\n }\n return await this.#createMapModel(mapId, () => Promise.resolve(options ?? {}));\n }\n\n /**\n * Given a raw OpenLayers map instance, returns the associated {@link MapModel} - or undefined\n * if the map is unknown to this registry.\n *\n * All OpenLayers maps created by this registry (e.g. via {@link MapConfigProvider} or {@link createMapModel}) have an associated map model.\n */\n getMapModelByRawInstance(olMap: OlMap): MapModel | undefined {\n return this.#modelsByOlMap.get(olMap);\n }\n\n // Wrapper method to ensure that in-progress construction of maps can be observed.\n #createMapModel(mapId: string, configProvider: () => Promise<MapConfig>): Promise<MapModel> {\n const creationJob = this.#modelCreationJobs.get(mapId);\n if (creationJob) {\n throw new Error(\"Internal error: a map model is already being created for this mapId\");\n }\n\n const modelPromise = this.#createMapModelImpl(mapId, configProvider)\n .then((mapModel) => {\n if (this.#destroyed) {\n mapModel.destroy();\n throw new Error(`MapRegistry has been destroyed.`);\n }\n\n const listener = on(\n mapModel.destroyed,\n () => {\n // Allow id reuse for dynamically created maps\n if (this.#isDynamic(mapId)) {\n const currentEntry = this.#entries.get(mapId);\n if (currentEntry === entry) {\n this.#entries.delete(mapId);\n }\n }\n },\n { dispatch: \"sync\" }\n );\n\n const entry: ModelJobResult = { kind: \"model\", model: mapModel, listener };\n this.#entries.set(mapId, entry);\n this.#modelCreationJobs.delete(mapId);\n this.#modelsByOlMap.set(mapModel.olMap, mapModel);\n return entry;\n })\n .catch((cause) => {\n const error = new Error(`Failed to construct map '${mapId}'`, { cause });\n const entry: ModelJobResult = { kind: \"error\", error };\n this.#modelCreationJobs.delete(mapId);\n if (!this.#isDynamic(mapId)) {\n // Don't store errors for dynamically created maps (the caller already got the error via promise).\n this.#entries.set(mapId, entry);\n }\n return entry;\n });\n this.#modelCreationJobs.set(mapId, modelPromise);\n return waitForResult(modelPromise);\n }\n\n async #createMapModelImpl(\n mapId: string,\n configProvider: () => Promise<MapConfig>\n ): Promise<MapModel> {\n LOG.info(`Creating map with id '${mapId}'`);\n const mapConfig = await configProvider();\n const mapModel = await createMapModel(mapId, mapConfig, this.#intl, this.#httpService);\n return mapModel;\n }\n\n #isDynamic(mapId: string): boolean {\n return !this.#configProviders.has(mapId);\n }\n}\n\nasync function waitForResult(job: Promise<ModelJobResult>): Promise<MapModel> {\n return unbox(await job);\n}\n\nfunction unbox(entry: ModelJobResult): MapModel {\n if (entry.kind === \"error\") {\n throw entry.error;\n }\n return entry.model;\n}\n"],"names":[],"mappings":"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"}
@@ -0,0 +1,22 @@
1
+ const sourceId$9 = "@open-pioneer/map/ui/MapContainer";
2
+
3
+ const sourceId$8 = "@open-pioneer/map/model/MapModel";
4
+
5
+ const sourceId$7 = "@open-pioneer/map/layers/AbstractLayer";
6
+
7
+ const sourceId$6 = "@open-pioneer/map/model/LayerCollection";
8
+
9
+ const sourceId$5 = "@open-pioneer/map/layers/WMSLayer";
10
+
11
+ const sourceId$4 = "@open-pioneer/map/layers/wms/getLegendUrl";
12
+
13
+ const sourceId$3 = "@open-pioneer/map/layers/WMTSLayer";
14
+
15
+ const sourceId$2 = "@open-pioneer/map/layers/wmts/getLegendUrl";
16
+
17
+ const sourceId$1 = "@open-pioneer/map/MapRegistry";
18
+
19
+ const sourceId = "@open-pioneer/map/model/createMapModel";
20
+
21
+ export { sourceId$1 as sourceId, sourceId$7 as sourceId$1, sourceId$5 as sourceId$2, sourceId$3, sourceId$4, sourceId$2 as sourceId$5, sourceId$6, sourceId$8 as sourceId$7, sourceId as sourceId$8, sourceId$9 };
22
+ //# sourceMappingURL=source-info.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"source-info.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;"}
@@ -2,10 +2,11 @@ import { synchronized, reactive, computed } from '@conterra/reactivity-core';
2
2
  import { createLogger, destroyResource } from '@open-pioneer/core';
3
3
  import OlLayer from 'ol/layer/Layer.js';
4
4
  import { unByKey } from 'ol/Observable.js';
5
+ import { sourceId$1 as sourceId } from '../_virtual/source-info.js';
5
6
  import { AbstractLayerBase } from './AbstractLayerBase.js';
6
7
  import { getLayerDependencies, SET_VISIBLE, ATTACH_TO_MAP, GET_DEPS, LAYER_DEPS } from './shared/internals.js';
7
8
 
8
- const LOG = createLogger("map:AbstractLayer");
9
+ const LOG = createLogger(sourceId);
9
10
  class AbstractLayer extends AbstractLayerBase {
10
11
  // Layer dependencies are present when the LayerFactory API was used to construct the layer.
11
12
  // They may currently be undefined for compatibility reasons (in which case they will be used
@@ -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 { 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(\"map:AbstractLayer\");\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":"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"}
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":"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"}
@@ -3,6 +3,7 @@ import { createLogger, deprecated, destroyResource, isAbortError } from '@open-p
3
3
  import WMSCapabilities from 'ol/format/WMSCapabilities.js';
4
4
  import ImageLayer from 'ol/layer/Image.js';
5
5
  import ImageWMS from 'ol/source/ImageWMS.js';
6
+ import { sourceId$2 as sourceId } from '../_virtual/source-info.js';
6
7
  import { fetchText } from '../utils/fetch.js';
7
8
  import { INTERNAL_CONSTRUCTOR_TAG } from '../utils/InternalConstructorTag.js';
8
9
  import { AbstractLayer } from './AbstractLayer.js';
@@ -11,7 +12,7 @@ import { SublayersCollection } from './shared/SublayersCollection.js';
11
12
  import { getLegendUrl } from './wms/getLegendUrl.js';
12
13
  import { constructSublayers } from './wms/WMSSublayer.js';
13
14
 
14
- const LOG = createLogger("map:WMSLayer");
15
+ const LOG = createLogger(sourceId);
15
16
  const deprecatedConstructor = deprecated({
16
17
  name: "WMSLayer constructor",
17
18
  packageName: "@open-pioneer/map",
@@ -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 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 { getLegendUrl } from \"./wms/getLegendUrl\";\nimport { constructSublayers, WMSSublayer, WMSSublayerConfig } 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(\"map:WMSLayer\");\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\n super(\n {\n ...config,\n olLayer: layer\n },\n deps,\n internalTag\n );\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 /** 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 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\n /** Find all leaf nodes representing a layer in the structure */\n const getNestedSublayer = (sublayers: WMSSublayer[], layers: WMSSublayer[]) => {\n for (const sublayer of sublayers) {\n const nested = sublayer.sublayers.getSublayers();\n if (nested.length) {\n getNestedSublayer(nested, layers);\n } else {\n if (sublayer.name) {\n layers.push(sublayer);\n }\n }\n }\n };\n\n this.#fetchWMSCapabilities()\n .then((result: string) => {\n batch(() => {\n const parser = new WMSCapabilities();\n const capabilities = parser.read(result);\n this.#capabilities = capabilities;\n\n const layers: WMSSublayer[] = [];\n getNestedSublayer(this.#sublayers.getSublayers(), layers);\n\n for (const layer of layers) {\n if (layer.name) {\n const legendUrl = getLegendUrl(capabilities, layer.name);\n layer[SET_LEGEND](legendUrl);\n }\n }\n });\n })\n .catch((error) => {\n if (isAbortError(error)) {\n LOG.debug(`Layer '${this.id}' has been destroyed before fetching capabilities`);\n return;\n }\n LOG.error(`Failed to fetch WMS capabilities for layer '${this.id}'`, error);\n });\n }\n\n /**\n * Gathers the visibility of _all_ sublayers and assembles the 'layers' WMS parameter.\n * The parameters are then applied to the WMS source.\n */\n #updateLayersParam(layers: string[]) {\n this.#source.updateParams({\n \"LAYERS\": layers\n });\n\n // only set source if there are visible sublayers, otherwise\n // we send an invalid http request\n const source = layers.length === 0 ? null : this.#source;\n if (this.#layer.getSource() !== source) {\n this.#layer.setSource(source);\n }\n }\n\n #getVisibleLayerNames() {\n const layers: string[] = [];\n const visitSublayer = (sublayer: WMSSublayer) => {\n if (!sublayer.visible) {\n return;\n }\n\n const nestedSublayers = sublayer.sublayers[GET_RAW_SUBLAYERS]();\n if (nestedSublayers.length) {\n for (const nestedSublayer of nestedSublayers) {\n visitSublayer(nestedSublayer);\n }\n } else {\n /**\n * Push sublayer only, if layer name is not an empty string | undefined | ...\n */\n if (sublayer.name) {\n layers.push(sublayer.name);\n }\n }\n };\n\n for (const sublayer of this.sublayers[GET_RAW_SUBLAYERS]()) {\n visitSublayer(sublayer);\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 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// 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":";;;;;;;;;;;;;AAiEA,MAAM,GAAA,GAAM,aAAa,cAAc,CAAA;AAEvC,MAAM,wBAAwB,UAAA,CAAW;AAAA,EACrC,IAAA,EAAM,sBAAA;AAAA,EACN,WAAA,EAAa,mBAAA;AAAA,EACb,KAAA,EAAO,QAAA;AAAA,EACP,WAAA,EAAa;AACjB,CAAC,CAAA;AAOM,MAAM,iBAAiB,aAAA,CAAc;AAAA,EACxC,IAAA;AAAA,EACA,UAAA;AAAA,EACA,MAAA;AAAA,EACA,OAAA;AAAA,EACA,kBAAA;AAAA,EAEA,YAAA,GAAe,KAAA;AAAA;AAAA,EAEf,aAAA;AAAA,EACS,gBAAA,GAAmB,IAAI,eAAA,EAAgB;AAAA,EAEhD,iBAAA;AAAA,EACA,eAAA;AAAA,EAiBA,WAAA,CACI,MAAA,EACA,IAAA,EACA,WAAA,EACF;AACE,IAAA,IAAI,CAAC,WAAA,EAAa;AACd,MAAA,qBAAA,EAAsB;AAAA,IAC1B;AAEA,IAAA,MAAM,KAAA,GAAQ,IAAI,UAAA,EAAW;AAE7B,IAAA,KAAA;AAAA,MACI;AAAA,QACI,GAAG,MAAA;AAAA,QACH,OAAA,EAAS;AAAA,OACb;AAAA,MACA,IAAA;AAAA,MACA;AAAA,KACJ;AAEA,IAAA,MAAM,MAAA,GAAS,IAAI,QAAA,CAAS;AAAA,MACxB,GAAG,MAAA,CAAO,aAAA;AAAA,MACV,KAAK,MAAA,CAAO,GAAA;AAAA,MACZ,MAAA,EAAQ;AAAA,QACJ,GAAG,OAAO,aAAA,EAAe;AAAA,OAC7B;AAAA;AAAA,MAEA,iBAAA,EAAmB,CAAC,OAAA,EAAS,GAAA,KAAQ;AACjC,QAAA,OAAO,KAAK,UAAA,CAAW,OAAA,EAAS,GAAG,CAAA,CAAE,KAAA,CAAM,CAAC,KAAA,KAAU;AAClD,UAAA,GAAA,CAAI,KAAA,CAAM,CAAA,wBAAA,EAA2B,GAAG,CAAA,CAAA,CAAA,EAAK,KAAK,CAAA;AAAA,QACtD,CAAC,CAAA;AAAA,MACL;AAAA,KACH,CAAA;AACD,IAAA,IAAA,CAAK,OAAO,MAAA,CAAO,GAAA;AACnB,IAAA,IAAA,CAAK,kBAAA,GAAqB,OAAO,iBAAA,IAAqB,IAAA;AACtD,IAAA,IAAA,CAAK,OAAA,GAAU,MAAA;AACf,IAAA,IAAA,CAAK,MAAA,GAAS,KAAA;AAEd,IAAA,IAAA,CAAK,aAAa,IAAI,mBAAA;AAAA,MAClB,kBAAA,CAAmB,OAAO,SAAS,CAAA;AAAA,MACnC;AAAA,KACJ;AACA,IAAA,IAAA,CAAK,UAAA,CACA,iBAAiB,CAAA,EAAE,CACnB,OAAA,CAAQ,CAAC,QAAA,KAAa,QAAA,CAAS,gBAAgB,CAAA,CAAE,IAAA,EAAM,IAAI,CAAC,CAAA;AAEjE,IAAA,IAAA,CAAK,iBAAA,GAAoB,QAAA,CAAS,MAAM,IAAA,CAAK,uBAAsB,EAAG;AAAA,MAClE,KAAA,CAAM,GAAG,CAAA,EAAG;AACR,QAAA,OAAO,CAAA,CAAE,MAAA,KAAW,CAAA,CAAE,MAAA,IAAU,CAAA,CAAE,KAAA,CAAM,CAAC,CAAA,EAAG,CAAA,KAAM,CAAA,KAAM,CAAA,CAAE,CAAC,CAAC,CAAA;AAAA,MAChE;AAAA,KACH,CAAA;AAED,IAAA,IAAA,CAAK,eAAA,GAAkB,KAAA;AAAA,MACnB,MAAM,CAAC,IAAA,CAAK,iBAAA,CAAkB,KAAK,CAAA;AAAA,MACnC,CAAC,CAAC,MAAM,CAAA,KAAM;AACV,QAAA,IAAA,CAAK,mBAAmB,MAAM,CAAA;AAAA,MAClC,CAAA;AAAA,MACA;AAAA,QACI,SAAA,EAAW;AAAA;AACf,KACJ;AAAA,EACJ;AAAA,EAES,OAAA,GAAU;AACf,IAAA,IAAA,CAAK,iBAAiB,KAAA,EAAM;AAC5B,IAAA,IAAA,CAAK,eAAA,GAAkB,eAAA,CAAgB,IAAA,CAAK,eAAe,CAAA;AAC3D,IAAA,KAAA,CAAM,OAAA,EAAQ;AAAA,EAClB;AAAA,EAEA,IAAI,IAAA,GAAO;AACP,IAAA,OAAO,KAAA;AAAA,EACX;AAAA,EAEA,IAAI,MAAA,GAAS;AACT,IAAA,OAAO,MAAA;AAAA,EACX;AAAA;AAAA,EAGA,IAAI,GAAA,GAAc;AACd,IAAA,OAAO,IAAA,CAAK,IAAA;AAAA,EAChB;AAAA,EAEA,IAAI,MAAA,GAAoB;AACpB,IAAA,OAAO,MAAA;AAAA,EACX;AAAA;AAAA;AAAA;AAAA,EAKA,IAAI,SAAA,GAA8C;AAC9C,IAAA,OAAO,IAAA,CAAK,UAAA;AAAA,EAChB;AAAA,EAEA,IAAI,YAAA,GAAe;AACf,IAAA,OAAO,IAAA,CAAK,aAAA;AAAA,EAChB;AAAA;AAAA,EAGA,CAAC,aAAa,CAAA,CAAE,GAAA,EAAqB;AACjC,IAAA,KAAA,CAAM,aAAa,EAAE,GAAG,CAAA;AACxB,IAAA,KAAA,MAAW,QAAA,IAAY,IAAA,CAAK,UAAA,CAAW,YAAA,EAAa,EAAG;AACnD,MAAA,QAAA,CAAS,aAAa,EAAE,GAAG,CAAA;AAAA,IAC/B;AAEA,IAAA,IAAA,CAAK,KAAA,EAAM;AAAA,EACf;AAAA;AAAA,EAGA,CAAC,eAAe,CAAA,GAAU;AACtB,IAAA,KAAA,CAAM,eAAe,CAAA,EAAE;AACvB,IAAA,KAAA,MAAW,QAAA,IAAY,IAAA,CAAK,UAAA,CAAW,YAAA,EAAa,EAAG;AACnD,MAAA,QAAA,CAAS,eAAe,CAAA,EAAE;AAAA,IAC9B;AAAA,EACJ;AAAA,EAEA,KAAA,GAAQ;AACJ,IAAA,IAAI,IAAA,CAAK,YAAA,IAAgB,CAAC,IAAA,CAAK,kBAAA,EAAoB;AAC/C,MAAA;AAAA,IACJ;AACA,IAAA,IAAA,CAAK,YAAA,GAAe,IAAA;AAGpB,IAAA,MAAM,iBAAA,GAAoB,CAAC,SAAA,EAA0B,MAAA,KAA0B;AAC3E,MAAA,KAAA,MAAW,YAAY,SAAA,EAAW;AAC9B,QAAA,MAAM,MAAA,GAAS,QAAA,CAAS,SAAA,CAAU,YAAA,EAAa;AAC/C,QAAA,IAAI,OAAO,MAAA,EAAQ;AACf,UAAA,iBAAA,CAAkB,QAAQ,MAAM,CAAA;AAAA,QACpC,CAAA,MAAO;AACH,UAAA,IAAI,SAAS,IAAA,EAAM;AACf,YAAA,MAAA,CAAO,KAAK,QAAQ,CAAA;AAAA,UACxB;AAAA,QACJ;AAAA,MACJ;AAAA,IACJ,CAAA;AAEA,IAAA,IAAA,CAAK,qBAAA,EAAsB,CACtB,IAAA,CAAK,CAAC,MAAA,KAAmB;AACtB,MAAA,KAAA,CAAM,MAAM;AACR,QAAA,MAAM,MAAA,GAAS,IAAI,eAAA,EAAgB;AACnC,QAAA,MAAM,YAAA,GAAe,MAAA,CAAO,IAAA,CAAK,MAAM,CAAA;AACvC,QAAA,IAAA,CAAK,aAAA,GAAgB,YAAA;AAErB,QAAA,MAAM,SAAwB,EAAC;AAC/B,QAAA,iBAAA,CAAkB,IAAA,CAAK,UAAA,CAAW,YAAA,EAAa,EAAG,MAAM,CAAA;AAExD,QAAA,KAAA,MAAW,SAAS,MAAA,EAAQ;AACxB,UAAA,IAAI,MAAM,IAAA,EAAM;AACZ,YAAA,MAAM,SAAA,GAAY,YAAA,CAAa,YAAA,EAAc,KAAA,CAAM,IAAI,CAAA;AACvD,YAAA,KAAA,CAAM,UAAU,EAAE,SAAS,CAAA;AAAA,UAC/B;AAAA,QACJ;AAAA,MACJ,CAAC,CAAA;AAAA,IACL,CAAC,CAAA,CACA,KAAA,CAAM,CAAC,KAAA,KAAU;AACd,MAAA,IAAI,YAAA,CAAa,KAAK,CAAA,EAAG;AACrB,QAAA,GAAA,CAAI,KAAA,CAAM,CAAA,OAAA,EAAU,IAAA,CAAK,EAAE,CAAA,iDAAA,CAAmD,CAAA;AAC9E,QAAA;AAAA,MACJ;AACA,MAAA,GAAA,CAAI,KAAA,CAAM,CAAA,4CAAA,EAA+C,IAAA,CAAK,EAAE,KAAK,KAAK,CAAA;AAAA,IAC9E,CAAC,CAAA;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,mBAAmB,MAAA,EAAkB;AACjC,IAAA,IAAA,CAAK,QAAQ,YAAA,CAAa;AAAA,MACtB,QAAA,EAAU;AAAA,KACb,CAAA;AAID,IAAA,MAAM,MAAA,GAAS,MAAA,CAAO,MAAA,KAAW,CAAA,GAAI,OAAO,IAAA,CAAK,OAAA;AACjD,IAAA,IAAI,IAAA,CAAK,MAAA,CAAO,SAAA,EAAU,KAAM,MAAA,EAAQ;AACpC,MAAA,IAAA,CAAK,MAAA,CAAO,UAAU,MAAM,CAAA;AAAA,IAChC;AAAA,EACJ;AAAA,EAEA,qBAAA,GAAwB;AACpB,IAAA,MAAM,SAAmB,EAAC;AAC1B,IAAA,MAAM,aAAA,GAAgB,CAAC,QAAA,KAA0B;AAC7C,MAAA,IAAI,CAAC,SAAS,OAAA,EAAS;AACnB,QAAA;AAAA,MACJ;AAEA,MAAA,MAAM,eAAA,GAAkB,QAAA,CAAS,SAAA,CAAU,iBAAiB,CAAA,EAAE;AAC9D,MAAA,IAAI,gBAAgB,MAAA,EAAQ;AACxB,QAAA,KAAA,MAAW,kBAAkB,eAAA,EAAiB;AAC1C,UAAA,aAAA,CAAc,cAAc,CAAA;AAAA,QAChC;AAAA,MACJ,CAAA,MAAO;AAIH,QAAA,IAAI,SAAS,IAAA,EAAM;AACf,UAAA,MAAA,CAAO,IAAA,CAAK,SAAS,IAAI,CAAA;AAAA,QAC7B;AAAA,MACJ;AAAA,IACJ,CAAA;AAEA,IAAA,KAAA,MAAW,QAAA,IAAY,IAAA,CAAK,SAAA,CAAU,iBAAiB,GAAE,EAAG;AACxD,MAAA,aAAA,CAAc,QAAQ,CAAA;AAAA,IAC1B;AACA,IAAA,OAAO,MAAA;AAAA,EACX;AAAA,EAEA,MAAM,qBAAA,GAAyC;AAC3C,IAAA,MAAM,WAAA,GAAc,IAAA,CAAK,QAAQ,CAAA,EAAE,CAAE,WAAA;AACrC,IAAA,MAAM,GAAA,GAAM,CAAA,EAAG,IAAA,CAAK,IAAI,CAAA,iDAAA,CAAA;AACxB,IAAA,OAAO,SAAA,CAAU,GAAA,EAAK,WAAA,EAAa,IAAA,CAAK,iBAAiB,MAAM,CAAA;AAAA,EACnE;AAAA,EAEA,MAAM,UAAA,CAAW,YAAA,EAA4B,QAAA,EAAiC;AAC1E,IAAA,MAAM,WAAA,GAAc,IAAA,CAAK,QAAQ,CAAA,EAAE,CAAE,WAAA;AACrC,IAAA,MAAM,KAAA,GAAQ,aAAa,QAAA,EAAS;AAEpC,IAAA,MAAM,QAAA,GAAW,MAAM,WAAA,CAAY,KAAA,CAAM,QAAQ,CAAA;AACjD,IAAA,IAAI,CAAC,SAAS,EAAA,EAAI;AACd,MAAA,MAAM,IAAI,KAAA,CAAM,CAAA,2BAAA,EAA8B,QAAA,CAAS,MAAM,CAAA,CAAA,CAAG,CAAA;AAAA,IACpE;AAEA,IAAA,MAAM,IAAA,GAAO,MAAM,QAAA,CAAS,IAAA,EAAK;AACjC,IAAA,MAAM,SAAA,GAAY,GAAA,CAAI,eAAA,CAAgB,IAAI,CAAA;AAC1C,IAAA,MAAM,SAAS,MAAM;AAGjB,MAAA,GAAA,CAAI,gBAAgB,SAAS,CAAA;AAC7B,MAAA,KAAA,CAAM,mBAAA,CAAoB,QAAQ,MAAM,CAAA;AACxC,MAAA,KAAA,CAAM,mBAAA,CAAoB,SAAS,MAAM,CAAA;AAAA,IAC7C,CAAA;AAEA,IAAA,KAAA,CAAM,gBAAA,CAAiB,QAAQ,MAAM,CAAA;AACrC,IAAA,KAAA,CAAM,gBAAA,CAAiB,SAAS,MAAM,CAAA;AACtC,IAAA,KAAA,CAAM,GAAA,GAAM,SAAA;AAAA,EAChB;AACJ;;;;"}
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 { getLegendUrl } from \"./wms/getLegendUrl\";\nimport { constructSublayers, WMSSublayer, WMSSublayerConfig } 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 // 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\n super(\n {\n ...config,\n olLayer: layer\n },\n deps,\n internalTag\n );\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 /** 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 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\n /** Find all leaf nodes representing a layer in the structure */\n const getNestedSublayer = (sublayers: WMSSublayer[], layers: WMSSublayer[]) => {\n for (const sublayer of sublayers) {\n const nested = sublayer.sublayers.getSublayers();\n if (nested.length) {\n getNestedSublayer(nested, layers);\n } else {\n if (sublayer.name) {\n layers.push(sublayer);\n }\n }\n }\n };\n\n this.#fetchWMSCapabilities()\n .then((result: string) => {\n batch(() => {\n const parser = new WMSCapabilities();\n const capabilities = parser.read(result);\n this.#capabilities = capabilities;\n\n const layers: WMSSublayer[] = [];\n getNestedSublayer(this.#sublayers.getSublayers(), layers);\n\n for (const layer of layers) {\n if (layer.name) {\n const legendUrl = getLegendUrl(capabilities, layer.name);\n layer[SET_LEGEND](legendUrl);\n }\n }\n });\n })\n .catch((error) => {\n if (isAbortError(error)) {\n LOG.debug(`Layer '${this.id}' has been destroyed before fetching capabilities`);\n return;\n }\n LOG.error(`Failed to fetch WMS capabilities for layer '${this.id}'`, error);\n });\n }\n\n /**\n * Gathers the visibility of _all_ sublayers and assembles the 'layers' WMS parameter.\n * The parameters are then applied to the WMS source.\n */\n #updateLayersParam(layers: string[]) {\n this.#source.updateParams({\n \"LAYERS\": layers\n });\n\n // only set source if there are visible sublayers, otherwise\n // we send an invalid http request\n const source = layers.length === 0 ? null : this.#source;\n if (this.#layer.getSource() !== source) {\n this.#layer.setSource(source);\n }\n }\n\n #getVisibleLayerNames() {\n const layers: string[] = [];\n const visitSublayer = (sublayer: WMSSublayer) => {\n if (!sublayer.visible) {\n return;\n }\n\n const nestedSublayers = sublayer.sublayers[GET_RAW_SUBLAYERS]();\n if (nestedSublayers.length) {\n for (const nestedSublayer of nestedSublayers) {\n visitSublayer(nestedSublayer);\n }\n } else {\n /**\n * Push sublayer only, if layer name is not an empty string | undefined | ...\n */\n if (sublayer.name) {\n layers.push(sublayer.name);\n }\n }\n };\n\n for (const sublayer of this.sublayers[GET_RAW_SUBLAYERS]()) {\n visitSublayer(sublayer);\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 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// 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":";;;;;;;;;;;;;;AAkEA,MAAM,GAAA,GAAM,aAAa,QAAQ,CAAA;AAEjC,MAAM,wBAAwB,UAAA,CAAW;AAAA,EACrC,IAAA,EAAM,sBAAA;AAAA,EACN,WAAA,EAAa,mBAAA;AAAA,EACb,KAAA,EAAO,QAAA;AAAA,EACP,WAAA,EAAa;AACjB,CAAC,CAAA;AAOM,MAAM,iBAAiB,aAAA,CAAc;AAAA,EACxC,IAAA;AAAA,EACA,UAAA;AAAA,EACA,MAAA;AAAA,EACA,OAAA;AAAA,EACA,kBAAA;AAAA,EAEA,YAAA,GAAe,KAAA;AAAA;AAAA,EAEf,aAAA;AAAA,EACS,gBAAA,GAAmB,IAAI,eAAA,EAAgB;AAAA,EAEhD,iBAAA;AAAA,EACA,eAAA;AAAA,EAiBA,WAAA,CACI,MAAA,EACA,IAAA,EACA,WAAA,EACF;AACE,IAAA,IAAI,CAAC,WAAA,EAAa;AACd,MAAA,qBAAA,EAAsB;AAAA,IAC1B;AAEA,IAAA,MAAM,KAAA,GAAQ,IAAI,UAAA,EAAW;AAE7B,IAAA,KAAA;AAAA,MACI;AAAA,QACI,GAAG,MAAA;AAAA,QACH,OAAA,EAAS;AAAA,OACb;AAAA,MACA,IAAA;AAAA,MACA;AAAA,KACJ;AAEA,IAAA,MAAM,MAAA,GAAS,IAAI,QAAA,CAAS;AAAA,MACxB,GAAG,MAAA,CAAO,aAAA;AAAA,MACV,KAAK,MAAA,CAAO,GAAA;AAAA,MACZ,MAAA,EAAQ;AAAA,QACJ,GAAG,OAAO,aAAA,EAAe;AAAA,OAC7B;AAAA;AAAA,MAEA,iBAAA,EAAmB,CAAC,OAAA,EAAS,GAAA,KAAQ;AACjC,QAAA,OAAO,KAAK,UAAA,CAAW,OAAA,EAAS,GAAG,CAAA,CAAE,KAAA,CAAM,CAAC,KAAA,KAAU;AAClD,UAAA,GAAA,CAAI,KAAA,CAAM,CAAA,wBAAA,EAA2B,GAAG,CAAA,CAAA,CAAA,EAAK,KAAK,CAAA;AAAA,QACtD,CAAC,CAAA;AAAA,MACL;AAAA,KACH,CAAA;AACD,IAAA,IAAA,CAAK,OAAO,MAAA,CAAO,GAAA;AACnB,IAAA,IAAA,CAAK,kBAAA,GAAqB,OAAO,iBAAA,IAAqB,IAAA;AACtD,IAAA,IAAA,CAAK,OAAA,GAAU,MAAA;AACf,IAAA,IAAA,CAAK,MAAA,GAAS,KAAA;AAEd,IAAA,IAAA,CAAK,aAAa,IAAI,mBAAA;AAAA,MAClB,kBAAA,CAAmB,OAAO,SAAS,CAAA;AAAA,MACnC;AAAA,KACJ;AACA,IAAA,IAAA,CAAK,UAAA,CACA,iBAAiB,CAAA,EAAE,CACnB,OAAA,CAAQ,CAAC,QAAA,KAAa,QAAA,CAAS,gBAAgB,CAAA,CAAE,IAAA,EAAM,IAAI,CAAC,CAAA;AAEjE,IAAA,IAAA,CAAK,iBAAA,GAAoB,QAAA,CAAS,MAAM,IAAA,CAAK,uBAAsB,EAAG;AAAA,MAClE,KAAA,CAAM,GAAG,CAAA,EAAG;AACR,QAAA,OAAO,CAAA,CAAE,MAAA,KAAW,CAAA,CAAE,MAAA,IAAU,CAAA,CAAE,KAAA,CAAM,CAAC,CAAA,EAAG,CAAA,KAAM,CAAA,KAAM,CAAA,CAAE,CAAC,CAAC,CAAA;AAAA,MAChE;AAAA,KACH,CAAA;AAED,IAAA,IAAA,CAAK,eAAA,GAAkB,KAAA;AAAA,MACnB,MAAM,CAAC,IAAA,CAAK,iBAAA,CAAkB,KAAK,CAAA;AAAA,MACnC,CAAC,CAAC,MAAM,CAAA,KAAM;AACV,QAAA,IAAA,CAAK,mBAAmB,MAAM,CAAA;AAAA,MAClC,CAAA;AAAA,MACA;AAAA,QACI,SAAA,EAAW;AAAA;AACf,KACJ;AAAA,EACJ;AAAA,EAES,OAAA,GAAU;AACf,IAAA,IAAA,CAAK,iBAAiB,KAAA,EAAM;AAC5B,IAAA,IAAA,CAAK,eAAA,GAAkB,eAAA,CAAgB,IAAA,CAAK,eAAe,CAAA;AAC3D,IAAA,KAAA,CAAM,OAAA,EAAQ;AAAA,EAClB;AAAA,EAEA,IAAI,IAAA,GAAO;AACP,IAAA,OAAO,KAAA;AAAA,EACX;AAAA,EAEA,IAAI,MAAA,GAAS;AACT,IAAA,OAAO,MAAA;AAAA,EACX;AAAA;AAAA,EAGA,IAAI,GAAA,GAAc;AACd,IAAA,OAAO,IAAA,CAAK,IAAA;AAAA,EAChB;AAAA,EAEA,IAAI,MAAA,GAAoB;AACpB,IAAA,OAAO,MAAA;AAAA,EACX;AAAA;AAAA;AAAA;AAAA,EAKA,IAAI,SAAA,GAA8C;AAC9C,IAAA,OAAO,IAAA,CAAK,UAAA;AAAA,EAChB;AAAA,EAEA,IAAI,YAAA,GAAe;AACf,IAAA,OAAO,IAAA,CAAK,aAAA;AAAA,EAChB;AAAA;AAAA,EAGA,CAAC,aAAa,CAAA,CAAE,GAAA,EAAqB;AACjC,IAAA,KAAA,CAAM,aAAa,EAAE,GAAG,CAAA;AACxB,IAAA,KAAA,MAAW,QAAA,IAAY,IAAA,CAAK,UAAA,CAAW,YAAA,EAAa,EAAG;AACnD,MAAA,QAAA,CAAS,aAAa,EAAE,GAAG,CAAA;AAAA,IAC/B;AAEA,IAAA,IAAA,CAAK,KAAA,EAAM;AAAA,EACf;AAAA;AAAA,EAGA,CAAC,eAAe,CAAA,GAAU;AACtB,IAAA,KAAA,CAAM,eAAe,CAAA,EAAE;AACvB,IAAA,KAAA,MAAW,QAAA,IAAY,IAAA,CAAK,UAAA,CAAW,YAAA,EAAa,EAAG;AACnD,MAAA,QAAA,CAAS,eAAe,CAAA,EAAE;AAAA,IAC9B;AAAA,EACJ;AAAA,EAEA,KAAA,GAAQ;AACJ,IAAA,IAAI,IAAA,CAAK,YAAA,IAAgB,CAAC,IAAA,CAAK,kBAAA,EAAoB;AAC/C,MAAA;AAAA,IACJ;AACA,IAAA,IAAA,CAAK,YAAA,GAAe,IAAA;AAGpB,IAAA,MAAM,iBAAA,GAAoB,CAAC,SAAA,EAA0B,MAAA,KAA0B;AAC3E,MAAA,KAAA,MAAW,YAAY,SAAA,EAAW;AAC9B,QAAA,MAAM,MAAA,GAAS,QAAA,CAAS,SAAA,CAAU,YAAA,EAAa;AAC/C,QAAA,IAAI,OAAO,MAAA,EAAQ;AACf,UAAA,iBAAA,CAAkB,QAAQ,MAAM,CAAA;AAAA,QACpC,CAAA,MAAO;AACH,UAAA,IAAI,SAAS,IAAA,EAAM;AACf,YAAA,MAAA,CAAO,KAAK,QAAQ,CAAA;AAAA,UACxB;AAAA,QACJ;AAAA,MACJ;AAAA,IACJ,CAAA;AAEA,IAAA,IAAA,CAAK,qBAAA,EAAsB,CACtB,IAAA,CAAK,CAAC,MAAA,KAAmB;AACtB,MAAA,KAAA,CAAM,MAAM;AACR,QAAA,MAAM,MAAA,GAAS,IAAI,eAAA,EAAgB;AACnC,QAAA,MAAM,YAAA,GAAe,MAAA,CAAO,IAAA,CAAK,MAAM,CAAA;AACvC,QAAA,IAAA,CAAK,aAAA,GAAgB,YAAA;AAErB,QAAA,MAAM,SAAwB,EAAC;AAC/B,QAAA,iBAAA,CAAkB,IAAA,CAAK,UAAA,CAAW,YAAA,EAAa,EAAG,MAAM,CAAA;AAExD,QAAA,KAAA,MAAW,SAAS,MAAA,EAAQ;AACxB,UAAA,IAAI,MAAM,IAAA,EAAM;AACZ,YAAA,MAAM,SAAA,GAAY,YAAA,CAAa,YAAA,EAAc,KAAA,CAAM,IAAI,CAAA;AACvD,YAAA,KAAA,CAAM,UAAU,EAAE,SAAS,CAAA;AAAA,UAC/B;AAAA,QACJ;AAAA,MACJ,CAAC,CAAA;AAAA,IACL,CAAC,CAAA,CACA,KAAA,CAAM,CAAC,KAAA,KAAU;AACd,MAAA,IAAI,YAAA,CAAa,KAAK,CAAA,EAAG;AACrB,QAAA,GAAA,CAAI,KAAA,CAAM,CAAA,OAAA,EAAU,IAAA,CAAK,EAAE,CAAA,iDAAA,CAAmD,CAAA;AAC9E,QAAA;AAAA,MACJ;AACA,MAAA,GAAA,CAAI,KAAA,CAAM,CAAA,4CAAA,EAA+C,IAAA,CAAK,EAAE,KAAK,KAAK,CAAA;AAAA,IAC9E,CAAC,CAAA;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,mBAAmB,MAAA,EAAkB;AACjC,IAAA,IAAA,CAAK,QAAQ,YAAA,CAAa;AAAA,MACtB,QAAA,EAAU;AAAA,KACb,CAAA;AAID,IAAA,MAAM,MAAA,GAAS,MAAA,CAAO,MAAA,KAAW,CAAA,GAAI,OAAO,IAAA,CAAK,OAAA;AACjD,IAAA,IAAI,IAAA,CAAK,MAAA,CAAO,SAAA,EAAU,KAAM,MAAA,EAAQ;AACpC,MAAA,IAAA,CAAK,MAAA,CAAO,UAAU,MAAM,CAAA;AAAA,IAChC;AAAA,EACJ;AAAA,EAEA,qBAAA,GAAwB;AACpB,IAAA,MAAM,SAAmB,EAAC;AAC1B,IAAA,MAAM,aAAA,GAAgB,CAAC,QAAA,KAA0B;AAC7C,MAAA,IAAI,CAAC,SAAS,OAAA,EAAS;AACnB,QAAA;AAAA,MACJ;AAEA,MAAA,MAAM,eAAA,GAAkB,QAAA,CAAS,SAAA,CAAU,iBAAiB,CAAA,EAAE;AAC9D,MAAA,IAAI,gBAAgB,MAAA,EAAQ;AACxB,QAAA,KAAA,MAAW,kBAAkB,eAAA,EAAiB;AAC1C,UAAA,aAAA,CAAc,cAAc,CAAA;AAAA,QAChC;AAAA,MACJ,CAAA,MAAO;AAIH,QAAA,IAAI,SAAS,IAAA,EAAM;AACf,UAAA,MAAA,CAAO,IAAA,CAAK,SAAS,IAAI,CAAA;AAAA,QAC7B;AAAA,MACJ;AAAA,IACJ,CAAA;AAEA,IAAA,KAAA,MAAW,QAAA,IAAY,IAAA,CAAK,SAAA,CAAU,iBAAiB,GAAE,EAAG;AACxD,MAAA,aAAA,CAAc,QAAQ,CAAA;AAAA,IAC1B;AACA,IAAA,OAAO,MAAA;AAAA,EACX;AAAA,EAEA,MAAM,qBAAA,GAAyC;AAC3C,IAAA,MAAM,WAAA,GAAc,IAAA,CAAK,QAAQ,CAAA,EAAE,CAAE,WAAA;AACrC,IAAA,MAAM,GAAA,GAAM,CAAA,EAAG,IAAA,CAAK,IAAI,CAAA,iDAAA,CAAA;AACxB,IAAA,OAAO,SAAA,CAAU,GAAA,EAAK,WAAA,EAAa,IAAA,CAAK,iBAAiB,MAAM,CAAA;AAAA,EACnE;AAAA,EAEA,MAAM,UAAA,CAAW,YAAA,EAA4B,QAAA,EAAiC;AAC1E,IAAA,MAAM,WAAA,GAAc,IAAA,CAAK,QAAQ,CAAA,EAAE,CAAE,WAAA;AACrC,IAAA,MAAM,KAAA,GAAQ,aAAa,QAAA,EAAS;AAEpC,IAAA,MAAM,QAAA,GAAW,MAAM,WAAA,CAAY,KAAA,CAAM,QAAQ,CAAA;AACjD,IAAA,IAAI,CAAC,SAAS,EAAA,EAAI;AACd,MAAA,MAAM,IAAI,KAAA,CAAM,CAAA,2BAAA,EAA8B,QAAA,CAAS,MAAM,CAAA,CAAA,CAAG,CAAA;AAAA,IACpE;AAEA,IAAA,MAAM,IAAA,GAAO,MAAM,QAAA,CAAS,IAAA,EAAK;AACjC,IAAA,MAAM,SAAA,GAAY,GAAA,CAAI,eAAA,CAAgB,IAAI,CAAA;AAC1C,IAAA,MAAM,SAAS,MAAM;AAGjB,MAAA,GAAA,CAAI,gBAAgB,SAAS,CAAA;AAC7B,MAAA,KAAA,CAAM,mBAAA,CAAoB,QAAQ,MAAM,CAAA;AACxC,MAAA,KAAA,CAAM,mBAAA,CAAoB,SAAS,MAAM,CAAA;AAAA,IAC7C,CAAA;AAEA,IAAA,KAAA,CAAM,gBAAA,CAAiB,QAAQ,MAAM,CAAA;AACrC,IAAA,KAAA,CAAM,gBAAA,CAAiB,SAAS,MAAM,CAAA;AACtC,IAAA,KAAA,CAAM,GAAA,GAAM,SAAA;AAAA,EAChB;AACJ;;;;"}
@@ -1,4 +1,4 @@
1
- import type { Options as WMSSourceOptions } from "ol/source/ImageWMS";
1
+ import { 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";
@@ -22,7 +22,7 @@ export interface WMTSLayerConfig extends LayerConfig {
22
22
  * NOTE: These options are intended for advanced configuration:
23
23
  * the WMTS Layer manages some of the OpenLayers source options itself.
24
24
  */
25
- sourceOptions?: Partial<WMSSourceOptions>;
25
+ sourceOptions?: Partial<WMTSSourceOptions>;
26
26
  }
27
27
  /**
28
28
  * Displays an OGC Web Map Tile Service (WMTS).
@@ -5,12 +5,13 @@ import TileState from 'ol/TileState.js';
5
5
  import WMTSCapabilities from 'ol/format/WMTSCapabilities.js';
6
6
  import TileLayer from 'ol/layer/Tile.js';
7
7
  import WMTS, { optionsFromCapabilities } from 'ol/source/WMTS.js';
8
+ import { sourceId$3 as sourceId } from '../_virtual/source-info.js';
8
9
  import { fetchText } from '../utils/fetch.js';
9
10
  import { AbstractLayer } from './AbstractLayer.js';
10
11
  import { ATTACH_TO_MAP, GET_DEPS } from './shared/internals.js';
11
12
  import { getLegendUrl } from './wmts/getLegendUrl.js';
12
13
 
13
- const LOG = createLogger("map:WMTSLayer");
14
+ const LOG = createLogger(sourceId);
14
15
  const deprecatedConstructor = deprecated({
15
16
  name: "WMTSLayer constructor",
16
17
  packageName: "@open-pioneer/map",
@@ -91,7 +92,23 @@ class WMTSLayer extends AbstractLayer {
91
92
  matrixSet: this.#matrixSet
92
93
  });
93
94
  if (!options) {
94
- throw new Error("Layer was not found in capabilities");
95
+ throw new Error(`Layer '${this.#name}' was not found in capabilities`);
96
+ }
97
+ if (options.matrixSet !== this.#matrixSet) {
98
+ throw new Error(
99
+ `Tile matrix set '${this.#matrixSet}' was not found in capabilities`
100
+ );
101
+ }
102
+ if (this.#sourceOptions?.style && this.#sourceOptions.style !== options.style) {
103
+ const styleToUse = this.#existsStyleInCapabilities(
104
+ capabilities,
105
+ this.#sourceOptions.style
106
+ );
107
+ if (!styleToUse) {
108
+ throw new Error(
109
+ `Style '${this.#sourceOptions.style}' was not found in capabilities`
110
+ );
111
+ }
95
112
  }
96
113
  const source = new WMTS({
97
114
  ...options,
@@ -107,13 +124,20 @@ class WMTSLayer extends AbstractLayer {
107
124
  this.#legend.value = legendUrl;
108
125
  }).catch((error) => {
109
126
  if (isAbortError(error)) {
110
- LOG.debug(`Layer ${this.name} has been destroyed before fetching the data`);
111
127
  LOG.debug(`Layer ${this.name} has been destroyed before fetching the data`);
112
128
  return;
113
129
  }
114
- LOG.error(`Failed fetching WMTS capabilities for Layer ${this.name}`, error);
130
+ LOG.error(`Failed initialize WMTS for Layer ${this.name}`, error);
115
131
  });
116
132
  }
133
+ /* eslint-disable @typescript-eslint/no-explicit-any */
134
+ #existsStyleInCapabilities(capabilities, styleToUse) {
135
+ const layerDesc = capabilities.Contents?.Layer?.find(
136
+ (layer) => layer.Identifier === this.#name
137
+ );
138
+ return layerDesc?.Style?.some((style) => style.Identifier === styleToUse) ?? false;
139
+ }
140
+ /* eslint-enable @typescript-eslint/no-explicit-any */
117
141
  async #fetchWMTSCapabilities() {
118
142
  const httpService = this[GET_DEPS]().httpService;
119
143
  return fetchText(this.#url, httpService, this.#abortController.signal);
@@ -1 +1 @@
1
- {"version":3,"file":"WMTSLayer.js","sources":["WMTSLayer.ts"],"sourcesContent":["// SPDX-FileCopyrightText: 2023-2025 Open Pioneer project (https://github.com/open-pioneer)\n// SPDX-License-Identifier: Apache-2.0\nimport { reactive } from \"@conterra/reactivity-core\";\nimport { createLogger, deprecated, isAbortError } from \"@open-pioneer/core\";\nimport { ImageTile } from \"ol\";\nimport Tile from \"ol/Tile\";\nimport TileState from \"ol/TileState\";\nimport WMTSCapabilities from \"ol/format/WMTSCapabilities\";\nimport TileLayer from \"ol/layer/Tile\";\nimport type { Options as WMSSourceOptions } from \"ol/source/ImageWMS\";\nimport type TileSourceType from \"ol/source/Tile\";\nimport WMTS, { optionsFromCapabilities } from \"ol/source/WMTS\";\nimport type { LayerFactory } from \"../LayerFactory\";\nimport { MapModel } from \"../model/MapModel\";\nimport { InternalConstructorTag } from \"../utils/InternalConstructorTag\";\nimport { fetchText } from \"../utils/fetch\";\nimport { AbstractLayer } from \"./AbstractLayer\";\nimport { LayerConfig } from \"./shared/LayerConfig\";\nimport { ATTACH_TO_MAP, GET_DEPS, LayerConstructor, LayerDependencies } from \"./shared/internals\";\nimport { getLegendUrl } from \"./wmts/getLegendUrl\";\n\n/**\n * Configuration options supported by {@link WMTSLayer}.\n *\n * @group Layers\n */\nexport interface WMTSLayerConfig extends LayerConfig {\n /** URL of the WMTS service. */\n url: string;\n\n /** The name of the WMTS layer in the service's capabilities. */\n name: string;\n\n /** The name of the tile matrix set in the service's capabilities. */\n matrixSet: string;\n\n /**\n * Additional source options for the layer's WMTS source.\n *\n * NOTE: These options are intended for advanced configuration:\n * the WMTS Layer manages some of the OpenLayers source options itself.\n */\n sourceOptions?: Partial<WMSSourceOptions>;\n}\n\nconst LOG = createLogger(\"map:WMTSLayer\");\n\nconst deprecatedConstructor = deprecated({\n name: \"WMTSLayer 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 Tile Service (WMTS).\n *\n * @group Layers\n */\nexport class WMTSLayer extends AbstractLayer {\n #url: string;\n #name: string;\n #matrixSet: string;\n #layer: TileLayer<TileSourceType>;\n #source: WMTS | undefined;\n #sourceOptions?: Partial<WMSSourceOptions>;\n #legend = reactive<string | undefined>();\n\n #loadStarted = false;\n\n readonly #abortController = new AbortController();\n\n /**\n * @deprecated Prefer using {@link LayerFactory.create} instead of calling the constructor directly\n */\n constructor(config: WMTSLayerConfig);\n\n /**\n * NOTE: Do not use this overload. Use {@link LayerFactory.create} instead.\n *\n * @internal\n */\n constructor(\n config: WMTSLayerConfig,\n deps: LayerDependencies,\n internalTag: InternalConstructorTag\n );\n\n constructor(\n config: WMTSLayerConfig,\n deps?: LayerDependencies,\n internalTag?: InternalConstructorTag\n ) {\n if (!internalTag) {\n deprecatedConstructor();\n }\n\n const layer = new TileLayer();\n super(\n {\n ...config,\n olLayer: layer\n },\n deps,\n internalTag\n );\n this.#url = config.url;\n this.#name = config.name;\n this.#layer = layer;\n this.#matrixSet = config.matrixSet;\n this.#sourceOptions = config.sourceOptions;\n }\n\n destroy(): void {\n this.#abortController.abort();\n super.destroy();\n }\n\n get type() {\n return \"wmts\" as const;\n }\n\n /** URL of the WMTS service. */\n override get legend(): string | undefined {\n return this.#legend.value;\n }\n\n override get sublayers(): undefined {\n return undefined;\n }\n\n override get layers(): undefined {\n return undefined;\n }\n\n get url() {\n return this.#url;\n }\n\n /** The name of the WMTS layer in the service's capabilities. */\n get name() {\n return this.#name;\n }\n\n /** The name of the tile matrix set in the service's capabilities. */\n get matrixSet() {\n return this.#matrixSet;\n }\n\n override [ATTACH_TO_MAP](map: MapModel): void {\n super[ATTACH_TO_MAP](map);\n this.#load();\n }\n\n #load() {\n if (this.#loadStarted) {\n return;\n }\n this.#loadStarted = true;\n this.#fetchWMTSCapabilities()\n .then((result: string) => {\n const parser = new WMTSCapabilities();\n const capabilities = parser.read(result);\n const options = optionsFromCapabilities(capabilities, {\n layer: this.#name,\n matrixSet: this.#matrixSet\n });\n if (!options) {\n throw new Error(\"Layer was not found in capabilities\");\n }\n const source = new WMTS({\n ...options,\n ...this.#sourceOptions,\n tileLoadFunction: (tile, tileUrl) => {\n this.#loadTile(tile, tileUrl);\n }\n });\n this.#source = source;\n this.#layer.setSource(this.#source);\n const activeStyleId = source.getStyle();\n const legendUrl = getLegendUrl(capabilities, this.name, activeStyleId);\n this.#legend.value = legendUrl;\n })\n .catch((error) => {\n if (isAbortError(error)) {\n LOG.debug(`Layer ${this.name} has been destroyed before fetching the data`);\n LOG.debug(`Layer ${this.name} has been destroyed before fetching the data`);\n return;\n }\n LOG.error(`Failed fetching WMTS capabilities for Layer ${this.name}`, error);\n });\n }\n\n async #fetchWMTSCapabilities(): Promise<string> {\n const httpService = this[GET_DEPS]().httpService;\n return fetchText(this.#url, httpService, this.#abortController.signal);\n }\n\n async #loadTile(tile: Tile, tileUrl: string): Promise<void> {\n const httpService = this[GET_DEPS]().httpService;\n try {\n if (!(tile instanceof ImageTile)) {\n throw new Error(\"Only 'ImageTile' is supported for now.\");\n }\n\n const image = tile.getImage();\n if (!isHtmlImage(image)) {\n // Could also be canvas or video\n throw new Error(\"Only <img> tags are supported as tiles for now.\");\n }\n\n const response = await httpService.fetch(tileUrl);\n if (!response.ok) {\n throw new Error(`Tile 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 image.addEventListener(\"load\", finish);\n image.addEventListener(\"error\", finish);\n image.src = objectUrl;\n } catch (e) {\n tile.setState(TileState.ERROR);\n if (!isAbortError(e)) {\n LOG.error(\"Failed to load tile\", e);\n }\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<WMTSLayerConfig, WMTSLayer> = WMTSLayer;\n void check;\n}\n\nfunction isHtmlImage(htmlElement: HTMLElement | OffscreenCanvas): htmlElement is HTMLImageElement {\n return \"tagName\" in htmlElement && htmlElement.tagName === \"IMG\";\n}\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"WMTSLayer.js","sources":["WMTSLayer.ts"],"sourcesContent":["// SPDX-FileCopyrightText: 2023-2025 Open Pioneer project (https://github.com/open-pioneer)\n// SPDX-License-Identifier: Apache-2.0\nimport { reactive } from \"@conterra/reactivity-core\";\nimport { createLogger, deprecated, isAbortError } from \"@open-pioneer/core\";\nimport { ImageTile } from \"ol\";\nimport Tile from \"ol/Tile\";\nimport TileState from \"ol/TileState\";\nimport WMTSCapabilities from \"ol/format/WMTSCapabilities\";\nimport TileLayer from \"ol/layer/Tile\";\nimport type TileSourceType from \"ol/source/Tile\";\nimport WMTS, { optionsFromCapabilities, Options as WMTSSourceOptions } from \"ol/source/WMTS\";\nimport { sourceId } from \"open-pioneer:source-info\";\nimport type { LayerFactory } from \"../LayerFactory\";\nimport { MapModel } from \"../model/MapModel\";\nimport { InternalConstructorTag } from \"../utils/InternalConstructorTag\";\nimport { fetchText } from \"../utils/fetch\";\nimport { AbstractLayer } from \"./AbstractLayer\";\nimport { LayerConfig } from \"./shared/LayerConfig\";\nimport { ATTACH_TO_MAP, GET_DEPS, LayerConstructor, LayerDependencies } from \"./shared/internals\";\nimport { getLegendUrl } from \"./wmts/getLegendUrl\";\n\n/**\n * Configuration options supported by {@link WMTSLayer}.\n *\n * @group Layers\n */\nexport interface WMTSLayerConfig extends LayerConfig {\n /** URL of the WMTS service. */\n url: string;\n\n /** The name of the WMTS layer in the service's capabilities. */\n name: string;\n\n /** The name of the tile matrix set in the service's capabilities. */\n matrixSet: string;\n\n /**\n * Additional source options for the layer's WMTS source.\n *\n * NOTE: These options are intended for advanced configuration:\n * the WMTS Layer manages some of the OpenLayers source options itself.\n */\n sourceOptions?: Partial<WMTSSourceOptions>;\n}\n\nconst LOG = createLogger(sourceId);\n\nconst deprecatedConstructor = deprecated({\n name: \"WMTSLayer 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 Tile Service (WMTS).\n *\n * @group Layers\n */\nexport class WMTSLayer extends AbstractLayer {\n #url: string;\n #name: string;\n #matrixSet: string;\n #layer: TileLayer<TileSourceType>;\n #source: WMTS | undefined;\n #sourceOptions?: Partial<WMTSSourceOptions>;\n #legend = reactive<string | undefined>();\n\n #loadStarted = false;\n\n readonly #abortController = new AbortController();\n\n /**\n * @deprecated Prefer using {@link LayerFactory.create} instead of calling the constructor directly\n */\n constructor(config: WMTSLayerConfig);\n\n /**\n * NOTE: Do not use this overload. Use {@link LayerFactory.create} instead.\n *\n * @internal\n */\n constructor(\n config: WMTSLayerConfig,\n deps: LayerDependencies,\n internalTag: InternalConstructorTag\n );\n\n constructor(\n config: WMTSLayerConfig,\n deps?: LayerDependencies,\n internalTag?: InternalConstructorTag\n ) {\n if (!internalTag) {\n deprecatedConstructor();\n }\n\n const layer = new TileLayer();\n super(\n {\n ...config,\n olLayer: layer\n },\n deps,\n internalTag\n );\n this.#url = config.url;\n this.#name = config.name;\n this.#layer = layer;\n this.#matrixSet = config.matrixSet;\n this.#sourceOptions = config.sourceOptions;\n }\n\n destroy(): void {\n this.#abortController.abort();\n super.destroy();\n }\n\n get type() {\n return \"wmts\" as const;\n }\n\n /** URL of the WMTS service. */\n override get legend(): string | undefined {\n return this.#legend.value;\n }\n\n override get sublayers(): undefined {\n return undefined;\n }\n\n override get layers(): undefined {\n return undefined;\n }\n\n get url() {\n return this.#url;\n }\n\n /** The name of the WMTS layer in the service's capabilities. */\n get name() {\n return this.#name;\n }\n\n /** The name of the tile matrix set in the service's capabilities. */\n get matrixSet() {\n return this.#matrixSet;\n }\n\n override [ATTACH_TO_MAP](map: MapModel): void {\n super[ATTACH_TO_MAP](map);\n this.#load();\n }\n\n #load() {\n if (this.#loadStarted) {\n return;\n }\n this.#loadStarted = true;\n this.#fetchWMTSCapabilities()\n .then((result: string) => {\n const parser = new WMTSCapabilities();\n const capabilities = parser.read(result);\n const options = optionsFromCapabilities(capabilities, {\n layer: this.#name,\n matrixSet: this.#matrixSet\n });\n if (!options) {\n throw new Error(`Layer '${this.#name}' was not found in capabilities`);\n }\n if (options.matrixSet !== this.#matrixSet) {\n throw new Error(\n `Tile matrix set '${this.#matrixSet}' was not found in capabilities`\n );\n }\n if (this.#sourceOptions?.style && this.#sourceOptions.style !== options.style) {\n const styleToUse = this.#existsStyleInCapabilities(\n capabilities,\n this.#sourceOptions.style\n );\n if (!styleToUse) {\n throw new Error(\n `Style '${this.#sourceOptions.style}' was not found in capabilities`\n );\n }\n }\n\n const source = new WMTS({\n ...options,\n ...this.#sourceOptions,\n tileLoadFunction: (tile, tileUrl) => {\n this.#loadTile(tile, tileUrl);\n }\n });\n this.#source = source;\n this.#layer.setSource(this.#source);\n const activeStyleId = source.getStyle();\n const legendUrl = getLegendUrl(capabilities, this.name, activeStyleId);\n this.#legend.value = legendUrl;\n })\n .catch((error) => {\n if (isAbortError(error)) {\n LOG.debug(`Layer ${this.name} has been destroyed before fetching the data`);\n return;\n }\n LOG.error(`Failed initialize WMTS for Layer ${this.name}`, error);\n //TODO: how to set the load state to error?\n });\n }\n\n /* eslint-disable @typescript-eslint/no-explicit-any */\n #existsStyleInCapabilities(capabilities: any, styleToUse: string): boolean {\n // NOTE: we have a style override, check if the style exists in the capabilities\n // the helper optionsFromCapabilities, supports style, too, but uses the Title instead of the Identifier, to find a match in the capabilities\n const layerDesc = capabilities.Contents?.Layer?.find(\n (layer: any) => layer.Identifier === this.#name\n );\n return layerDesc?.Style?.some((style: any) => style.Identifier === styleToUse) ?? false;\n }\n /* eslint-enable @typescript-eslint/no-explicit-any */\n\n async #fetchWMTSCapabilities(): Promise<string> {\n const httpService = this[GET_DEPS]().httpService;\n return fetchText(this.#url, httpService, this.#abortController.signal);\n }\n\n async #loadTile(tile: Tile, tileUrl: string): Promise<void> {\n const httpService = this[GET_DEPS]().httpService;\n try {\n if (!(tile instanceof ImageTile)) {\n throw new Error(\"Only 'ImageTile' is supported for now.\");\n }\n\n const image = tile.getImage();\n if (!isHtmlImage(image)) {\n // Could also be canvas or video\n throw new Error(\"Only <img> tags are supported as tiles for now.\");\n }\n\n const response = await httpService.fetch(tileUrl);\n if (!response.ok) {\n throw new Error(`Tile 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 image.addEventListener(\"load\", finish);\n image.addEventListener(\"error\", finish);\n image.src = objectUrl;\n } catch (e) {\n tile.setState(TileState.ERROR);\n if (!isAbortError(e)) {\n LOG.error(\"Failed to load tile\", e);\n }\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<WMTSLayerConfig, WMTSLayer> = WMTSLayer;\n void check;\n}\n\nfunction isHtmlImage(htmlElement: HTMLElement | OffscreenCanvas): htmlElement is HTMLImageElement {\n return \"tagName\" in htmlElement && htmlElement.tagName === \"IMG\";\n}\n"],"names":[],"mappings":"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"}
@@ -1,6 +1,7 @@
1
1
  import { createLogger } from '@open-pioneer/core';
2
+ import { sourceId$4 as sourceId } from '../../_virtual/source-info.js';
2
3
 
3
- const LOG = createLogger("map:WMSLayer:getLegendUrl");
4
+ const LOG = createLogger(sourceId);
4
5
  function getLegendUrl(capabilities, layerName) {
5
6
  const capabilitiesContent = capabilities?.Capability;
6
7
  const rootLayerCapabilities = capabilitiesContent?.Layer;
@@ -1 +1 @@
1
- {"version":3,"file":"getLegendUrl.js","sources":["getLegendUrl.ts"],"sourcesContent":["// SPDX-FileCopyrightText: 2023-2025 Open Pioneer project (https://github.com/open-pioneer)\n// SPDX-License-Identifier: Apache-2.0\nimport { createLogger } from \"@open-pioneer/core\";\n\nconst LOG = createLogger(\"map:WMSLayer:getLegendUrl\");\n\n/**\n * Extracts the legend url from the service capabilities.\n **/\nexport function getLegendUrl(\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n capabilities: Record<string, any>,\n layerName: string\n): string | undefined {\n const capabilitiesContent = capabilities?.Capability;\n const rootLayerCapabilities = capabilitiesContent?.Layer;\n let url: string | undefined = undefined;\n\n /** Recurse search for the current layer within the parsed capabilities service*/\n //eslint-disable-next-line @typescript-eslint/no-explicit-any\n const searchNestedLayer = (layer: Record<string, any>[]) => {\n for (const currentLayer of layer) {\n // spec. if, a layer has a <Name>, then it is a map layer\n if (currentLayer?.Name === layerName) {\n const activeLayer = currentLayer;\n const styles = activeLayer.Style;\n if (!styles || !styles.length) {\n LOG.debug(\"No style in WMS layer capabilities - giving up.\");\n return;\n }\n // by parsing of the service capabilities, every child inherits the parent's legend\n // therefore, extract the legendURL from the first style object in the array (its own legend)\n const activeStyle = styles[0];\n url = activeStyle.LegendURL?.[0]?.OnlineResource;\n } else if (currentLayer.Layer) {\n searchNestedLayer(currentLayer.Layer);\n }\n }\n };\n if (rootLayerCapabilities) {\n searchNestedLayer(rootLayerCapabilities.Layer);\n }\n return url;\n}\n"],"names":[],"mappings":";;AAIA,MAAM,GAAA,GAAM,aAAa,2BAA2B,CAAA;AAK7C,SAAS,YAAA,CAEZ,cACA,SAAA,EACkB;AAClB,EAAA,MAAM,sBAAsB,YAAA,EAAc,UAAA;AAC1C,EAAA,MAAM,wBAAwB,mBAAA,EAAqB,KAAA;AACnD,EAAA,IAAI,GAAA,GAA0B,MAAA;AAI9B,EAAA,MAAM,iBAAA,GAAoB,CAAC,KAAA,KAAiC;AACxD,IAAA,KAAA,MAAW,gBAAgB,KAAA,EAAO;AAE9B,MAAA,IAAI,YAAA,EAAc,SAAS,SAAA,EAAW;AAClC,QAAA,MAAM,WAAA,GAAc,YAAA;AACpB,QAAA,MAAM,SAAS,WAAA,CAAY,KAAA;AAC3B,QAAA,IAAI,CAAC,MAAA,IAAU,CAAC,MAAA,CAAO,MAAA,EAAQ;AAC3B,UAAA,GAAA,CAAI,MAAM,iDAAiD,CAAA;AAC3D,UAAA;AAAA,QACJ;AAGA,QAAA,MAAM,WAAA,GAAc,OAAO,CAAC,CAAA;AAC5B,QAAA,GAAA,GAAM,WAAA,CAAY,SAAA,GAAY,CAAC,CAAA,EAAG,cAAA;AAAA,MACtC,CAAA,MAAA,IAAW,aAAa,KAAA,EAAO;AAC3B,QAAA,iBAAA,CAAkB,aAAa,KAAK,CAAA;AAAA,MACxC;AAAA,IACJ;AAAA,EACJ,CAAA;AACA,EAAA,IAAI,qBAAA,EAAuB;AACvB,IAAA,iBAAA,CAAkB,sBAAsB,KAAK,CAAA;AAAA,EACjD;AACA,EAAA,OAAO,GAAA;AACX;;;;"}
1
+ {"version":3,"file":"getLegendUrl.js","sources":["getLegendUrl.ts"],"sourcesContent":["// SPDX-FileCopyrightText: 2023-2025 Open Pioneer project (https://github.com/open-pioneer)\n// SPDX-License-Identifier: Apache-2.0\nimport { createLogger } from \"@open-pioneer/core\";\nimport { sourceId } from \"open-pioneer:source-info\";\n\nconst LOG = createLogger(sourceId);\n\n/**\n * Extracts the legend url from the service capabilities.\n **/\nexport function getLegendUrl(\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n capabilities: Record<string, any>,\n layerName: string\n): string | undefined {\n const capabilitiesContent = capabilities?.Capability;\n const rootLayerCapabilities = capabilitiesContent?.Layer;\n let url: string | undefined = undefined;\n\n /** Recurse search for the current layer within the parsed capabilities service*/\n //eslint-disable-next-line @typescript-eslint/no-explicit-any\n const searchNestedLayer = (layer: Record<string, any>[]) => {\n for (const currentLayer of layer) {\n // spec. if, a layer has a <Name>, then it is a map layer\n if (currentLayer?.Name === layerName) {\n const activeLayer = currentLayer;\n const styles = activeLayer.Style;\n if (!styles || !styles.length) {\n LOG.debug(\"No style in WMS layer capabilities - giving up.\");\n return;\n }\n // by parsing of the service capabilities, every child inherits the parent's legend\n // therefore, extract the legendURL from the first style object in the array (its own legend)\n const activeStyle = styles[0];\n url = activeStyle.LegendURL?.[0]?.OnlineResource;\n } else if (currentLayer.Layer) {\n searchNestedLayer(currentLayer.Layer);\n }\n }\n };\n if (rootLayerCapabilities) {\n searchNestedLayer(rootLayerCapabilities.Layer);\n }\n return url;\n}\n"],"names":[],"mappings":";;;AAKA,MAAM,GAAA,GAAM,aAAa,QAAQ,CAAA;AAK1B,SAAS,YAAA,CAEZ,cACA,SAAA,EACkB;AAClB,EAAA,MAAM,sBAAsB,YAAA,EAAc,UAAA;AAC1C,EAAA,MAAM,wBAAwB,mBAAA,EAAqB,KAAA;AACnD,EAAA,IAAI,GAAA,GAA0B,MAAA;AAI9B,EAAA,MAAM,iBAAA,GAAoB,CAAC,KAAA,KAAiC;AACxD,IAAA,KAAA,MAAW,gBAAgB,KAAA,EAAO;AAE9B,MAAA,IAAI,YAAA,EAAc,SAAS,SAAA,EAAW;AAClC,QAAA,MAAM,WAAA,GAAc,YAAA;AACpB,QAAA,MAAM,SAAS,WAAA,CAAY,KAAA;AAC3B,QAAA,IAAI,CAAC,MAAA,IAAU,CAAC,MAAA,CAAO,MAAA,EAAQ;AAC3B,UAAA,GAAA,CAAI,MAAM,iDAAiD,CAAA;AAC3D,UAAA;AAAA,QACJ;AAGA,QAAA,MAAM,WAAA,GAAc,OAAO,CAAC,CAAA;AAC5B,QAAA,GAAA,GAAM,WAAA,CAAY,SAAA,GAAY,CAAC,CAAA,EAAG,cAAA;AAAA,MACtC,CAAA,MAAA,IAAW,aAAa,KAAA,EAAO;AAC3B,QAAA,iBAAA,CAAkB,aAAa,KAAK,CAAA;AAAA,MACxC;AAAA,IACJ;AAAA,EACJ,CAAA;AACA,EAAA,IAAI,qBAAA,EAAuB;AACvB,IAAA,iBAAA,CAAkB,sBAAsB,KAAK,CAAA;AAAA,EACjD;AACA,EAAA,OAAO,GAAA;AACX;;;;"}
@@ -1,6 +1,7 @@
1
1
  import { createLogger } from '@open-pioneer/core';
2
+ import { sourceId$5 as sourceId } from '../../_virtual/source-info.js';
2
3
 
3
- const LOG = createLogger("map:WMTSLayer:getLegendUrl");
4
+ const LOG = createLogger(sourceId);
4
5
  function getLegendUrl(capabilities, activeLayerId, activeStyleId) {
5
6
  const content = capabilities?.Contents;
6
7
  const layers = content?.Layer;
@@ -1 +1 @@
1
- {"version":3,"file":"getLegendUrl.js","sources":["getLegendUrl.ts"],"sourcesContent":["// SPDX-FileCopyrightText: 2023-2025 Open Pioneer project (https://github.com/open-pioneer)\n// SPDX-License-Identifier: Apache-2.0\nimport { createLogger } from \"@open-pioneer/core\";\n\nconst LOG = createLogger(\"map:WMTSLayer:getLegendUrl\");\n\n/* eslint-disable @typescript-eslint/no-explicit-any */\nexport function getLegendUrl(\n capabilities: Record<string, any>,\n activeLayerId: string | undefined,\n activeStyleId: string | undefined\n): string | undefined {\n const content = capabilities?.Contents;\n const layers = content?.Layer;\n\n let activeLayer = layers?.find((layer: any) => layer?.Identifier === activeLayerId);\n if (!activeLayer) {\n LOG.debug(\"Failed to find the active layer in WMTS layer capabilities.\");\n activeLayer = layers?.[0];\n if (!activeLayer) {\n LOG.debug(\"No layer in WMTS capabilities - giving up.\");\n return undefined;\n }\n }\n\n const styles = activeLayer.Style;\n let activeStyle = styles?.find((style: any) => style?.Identifier === activeStyleId);\n if (!activeStyle) {\n LOG.debug(\"Failed to find active style in WMTS layer.\");\n activeStyle = styles?.[0];\n if (!activeStyle) {\n LOG.debug(\"No style in WMTS layer capabilities - giving up.\");\n return undefined;\n }\n }\n\n const legendUrl = activeStyle.LegendURL?.[0]?.href;\n return legendUrl as string | undefined;\n}\n/* eslint-enable @typescript-eslint/no-explicit-any */\n"],"names":[],"mappings":";;AAIA,MAAM,GAAA,GAAM,aAAa,4BAA4B,CAAA;AAG9C,SAAS,YAAA,CACZ,YAAA,EACA,aAAA,EACA,aAAA,EACkB;AAClB,EAAA,MAAM,UAAU,YAAA,EAAc,QAAA;AAC9B,EAAA,MAAM,SAAS,OAAA,EAAS,KAAA;AAExB,EAAA,IAAI,cAAc,MAAA,EAAQ,IAAA,CAAK,CAAC,KAAA,KAAe,KAAA,EAAO,eAAe,aAAa,CAAA;AAClF,EAAA,IAAI,CAAC,WAAA,EAAa;AACd,IAAA,GAAA,CAAI,MAAM,6DAA6D,CAAA;AACvE,IAAA,WAAA,GAAc,SAAS,CAAC,CAAA;AACxB,IAAA,IAAI,CAAC,WAAA,EAAa;AACd,MAAA,GAAA,CAAI,MAAM,4CAA4C,CAAA;AACtD,MAAA,OAAO,MAAA;AAAA,IACX;AAAA,EACJ;AAEA,EAAA,MAAM,SAAS,WAAA,CAAY,KAAA;AAC3B,EAAA,IAAI,cAAc,MAAA,EAAQ,IAAA,CAAK,CAAC,KAAA,KAAe,KAAA,EAAO,eAAe,aAAa,CAAA;AAClF,EAAA,IAAI,CAAC,WAAA,EAAa;AACd,IAAA,GAAA,CAAI,MAAM,4CAA4C,CAAA;AACtD,IAAA,WAAA,GAAc,SAAS,CAAC,CAAA;AACxB,IAAA,IAAI,CAAC,WAAA,EAAa;AACd,MAAA,GAAA,CAAI,MAAM,kDAAkD,CAAA;AAC5D,MAAA,OAAO,MAAA;AAAA,IACX;AAAA,EACJ;AAEA,EAAA,MAAM,SAAA,GAAY,WAAA,CAAY,SAAA,GAAY,CAAC,CAAA,EAAG,IAAA;AAC9C,EAAA,OAAO,SAAA;AACX;;;;"}
1
+ {"version":3,"file":"getLegendUrl.js","sources":["getLegendUrl.ts"],"sourcesContent":["// SPDX-FileCopyrightText: 2023-2025 Open Pioneer project (https://github.com/open-pioneer)\n// SPDX-License-Identifier: Apache-2.0\nimport { createLogger } from \"@open-pioneer/core\";\nimport { sourceId } from \"open-pioneer:source-info\";\n\nconst LOG = createLogger(sourceId);\n\n/* eslint-disable @typescript-eslint/no-explicit-any */\nexport function getLegendUrl(\n capabilities: Record<string, any>,\n activeLayerId: string | undefined,\n activeStyleId: string | undefined\n): string | undefined {\n const content = capabilities?.Contents;\n const layers = content?.Layer;\n\n let activeLayer = layers?.find((layer: any) => layer?.Identifier === activeLayerId);\n if (!activeLayer) {\n LOG.debug(\"Failed to find the active layer in WMTS layer capabilities.\");\n activeLayer = layers?.[0];\n if (!activeLayer) {\n LOG.debug(\"No layer in WMTS capabilities - giving up.\");\n return undefined;\n }\n }\n\n const styles = activeLayer.Style;\n let activeStyle = styles?.find((style: any) => style?.Identifier === activeStyleId);\n if (!activeStyle) {\n LOG.debug(\"Failed to find active style in WMTS layer.\");\n activeStyle = styles?.[0];\n if (!activeStyle) {\n LOG.debug(\"No style in WMTS layer capabilities - giving up.\");\n return undefined;\n }\n }\n\n const legendUrl = activeStyle.LegendURL?.[0]?.href;\n return legendUrl as string | undefined;\n}\n/* eslint-enable @typescript-eslint/no-explicit-any */\n"],"names":[],"mappings":";;;AAKA,MAAM,GAAA,GAAM,aAAa,QAAQ,CAAA;AAG1B,SAAS,YAAA,CACZ,YAAA,EACA,aAAA,EACA,aAAA,EACkB;AAClB,EAAA,MAAM,UAAU,YAAA,EAAc,QAAA;AAC9B,EAAA,MAAM,SAAS,OAAA,EAAS,KAAA;AAExB,EAAA,IAAI,cAAc,MAAA,EAAQ,IAAA,CAAK,CAAC,KAAA,KAAe,KAAA,EAAO,eAAe,aAAa,CAAA;AAClF,EAAA,IAAI,CAAC,WAAA,EAAa;AACd,IAAA,GAAA,CAAI,MAAM,6DAA6D,CAAA;AACvE,IAAA,WAAA,GAAc,SAAS,CAAC,CAAA;AACxB,IAAA,IAAI,CAAC,WAAA,EAAa;AACd,MAAA,GAAA,CAAI,MAAM,4CAA4C,CAAA;AACtD,MAAA,OAAO,MAAA;AAAA,IACX;AAAA,EACJ;AAEA,EAAA,MAAM,SAAS,WAAA,CAAY,KAAA;AAC3B,EAAA,IAAI,cAAc,MAAA,EAAQ,IAAA,CAAK,CAAC,KAAA,KAAe,KAAA,EAAO,eAAe,aAAa,CAAA;AAClF,EAAA,IAAI,CAAC,WAAA,EAAa;AACd,IAAA,GAAA,CAAI,MAAM,4CAA4C,CAAA;AACtD,IAAA,WAAA,GAAc,SAAS,CAAC,CAAA;AACxB,IAAA,IAAI,CAAC,WAAA,EAAa;AACd,MAAA,GAAA,CAAI,MAAM,kDAAkD,CAAA;AAC5D,MAAA,OAAO,MAAA;AAAA,IACX;AAAA,EACJ;AAEA,EAAA,MAAM,SAAA,GAAY,WAAA,CAAY,SAAA,GAAY,CAAC,CAAA,EAAG,IAAA;AAC9C,EAAA,OAAO,SAAA;AACX;;;;"}
@@ -1,8 +1,8 @@
1
1
  import OlBaseLayer from "ol/layer/Base";
2
- import { InternalConstructorTag } from "../utils/InternalConstructorTag";
3
- import { AnyLayer, Layer } from "../layers/unions";
4
2
  import type { AddLayerOptions } from "../layers/shared/AddLayerOptions";
5
3
  import type { LayerRetrievalOptions, RecursiveRetrievalOptions } from "../layers/shared/LayerRetrievalOptions";
4
+ import { AnyLayer, Layer } from "../layers/unions";
5
+ import { InternalConstructorTag } from "../utils/InternalConstructorTag";
6
6
  import { MapModel } from "./MapModel";
7
7
  /**
8
8
  * Contains the layers contained in a {@link MapModel}.
@@ -1,11 +1,12 @@
1
1
  import { reactiveSet, reactiveMap, reactive, reactiveArray, effect, batch } from '@conterra/reactivity-core';
2
2
  import { createLogger } from '@open-pioneer/core';
3
+ import { sourceId$6 as sourceId } from '../_virtual/source-info.js';
3
4
  import { AbstractLayer } from '../layers/AbstractLayer.js';
5
+ import { getRecursiveLayers } from '../layers/shared/getRecursiveLayers.js';
4
6
  import { ATTACH_TO_MAP, DETACH_FROM_MAP, SET_VISIBLE, GET_RAW_LAYERS, GET_RAW_SUBLAYERS } from '../layers/shared/internals.js';
5
7
  import { assertInternalConstructor } from '../utils/InternalConstructorTag.js';
6
- import { getRecursiveLayers } from '../layers/shared/getRecursiveLayers.js';
7
8
 
8
- const LOG = createLogger("map:LayerCollection");
9
+ const LOG = createLogger(sourceId);
9
10
  class LayerCollection {
10
11
  #map;
11
12
  /** Top level layers (base layers, operational layers). No sublayers. */
@@ -1 +1 @@
1
- {"version":3,"file":"LayerCollection.js","sources":["LayerCollection.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 effect,\n reactive,\n ReactiveArray,\n reactiveArray,\n reactiveMap,\n reactiveSet\n} from \"@conterra/reactivity-core\";\nimport { createLogger, Resource } from \"@open-pioneer/core\";\nimport OlBaseLayer from \"ol/layer/Base\";\nimport { AbstractLayer } from \"../layers/AbstractLayer\";\nimport { AbstractLayerBase } from \"../layers/AbstractLayerBase\";\nimport {\n ATTACH_TO_MAP,\n DETACH_FROM_MAP,\n GET_RAW_LAYERS,\n GET_RAW_SUBLAYERS,\n SET_VISIBLE\n} from \"../layers/shared/internals\";\nimport { assertInternalConstructor, InternalConstructorTag } from \"../utils/InternalConstructorTag\";\nimport { AnyLayer, Layer, Sublayer } from \"../layers/unions\";\nimport type { AddLayerOptions } from \"../layers/shared/AddLayerOptions\";\nimport type {\n LayerRetrievalOptions,\n RecursiveRetrievalOptions\n} from \"../layers/shared/LayerRetrievalOptions\";\nimport { MapModel } from \"./MapModel\";\nimport { getRecursiveLayers } from \"../layers/shared/getRecursiveLayers\";\n\nconst LOG = createLogger(\"map:LayerCollection\");\n\ntype LayerType = AbstractLayer & Layer;\ntype LayerBaseType = (AbstractLayerBase & Layer) | (AbstractLayerBase & Sublayer);\n\ninterface OpOrTopmostLayerPos {\n which: \"normal\" | \"topmost\";\n index: number;\n}\n\ninterface BaseLayerPos {\n which: \"base\";\n}\n\ntype LayerPos = OpOrTopmostLayerPos | BaseLayerPos;\n\n/**\n * Contains the layers contained in a {@link MapModel}.\n *\n * @group Map Model\n */\nexport class LayerCollection {\n #map: MapModel;\n\n /** Top level layers (base layers, operational layers). No sublayers. */\n #topLevelLayers = reactiveSet<LayerType>();\n\n /** Index of _all_ layer instances, including sublayers. */\n #layersById = reactiveMap<string, LayerBaseType>();\n\n /** Reverse index of _all_ layers that have an associated OpenLayers layer. */\n #layersByOlLayer: WeakMap<OlBaseLayer, LayerType> = new WeakMap();\n\n /** Currently active base layer. */\n #activeBaseLayer = reactive<LayerType>();\n\n /**\n * Defines the relative order of operational layers.\n * Lower index -> layer is below its successors.\n * Excluding {@link #topMostOperationalLayers}\n */\n #operationalLayerOrder = reactiveArray<LayerType>();\n\n /** Operational layers that are always displayed at the top above all other layers (e.g. a highlight layer) */\n #topMostOperationalLayers = reactiveArray<LayerType>();\n\n #syncHandle: Resource | undefined;\n\n /** @internal */\n constructor(map: MapModel, tag: InternalConstructorTag) {\n assertInternalConstructor(tag);\n\n this.#map = map;\n this.#syncHandle = effect(() => {\n // Contains base layers, normal operational layers, topmost layers in bottom-to-top order.\n const orderedLayers = this.getLayers({\n sortByDisplayOrder: true,\n includeInternalLayers: true\n });\n\n // Simply reassign all z-indices whenever the order changes.\n let index = 0;\n for (const layer of orderedLayers) {\n LOG.isDebug() && LOG.debug(\"Assigning z-index\", layer.id, index);\n layer.olLayer.setZIndex(index);\n index++;\n }\n });\n }\n\n destroy() {\n for (const layer of this.#layersById.values()) {\n layer.destroy();\n }\n this.#topLevelLayers.clear();\n this.#layersById.clear();\n this.#operationalLayerOrder.splice(0, this.#operationalLayerOrder.length);\n this.#activeBaseLayer.value = undefined;\n this.#syncHandle?.destroy();\n this.#syncHandle = undefined;\n }\n\n /**\n * Adds a new layer to the map.\n *\n * The new layer is automatically registered with this collection.\n *\n * ### Display order\n *\n * By default, the new layer will be shown on _top_ of all normal operational layers.\n * Use the `options` parameter to control the insertion point.\n *\n * ### Ownership\n *\n * The map model takes ownership of the new layer.\n * This means that the layer will be destroyed if the map model is destroyed.\n */\n addLayer(layer: Layer, options?: AddLayerOptions): void {\n batch(() => {\n checkLayerInstance(layer);\n\n layer[ATTACH_TO_MAP](this.#map);\n this.#addLayer(layer, options);\n });\n }\n\n /**\n * Returns all configured base layers.\n */\n getBaseLayers(): Layer[] {\n // Slightly inefficient, but we don't need a separate index for base layers right now.\n return Array.from(this.#topLevelLayers).filter((layer) => layer.isBaseLayer);\n }\n\n /**\n * Returns the currently active base layer.\n */\n getActiveBaseLayer(): Layer | undefined {\n return this.#activeBaseLayer.value;\n }\n\n /**\n * Activates the base layer with the given id.\n * `undefined` can be used to hide all base layers.\n *\n * The associated layer is made visible and all other base layers are hidden.\n *\n * Returns true if the given layer has been successfully activated.\n */\n activateBaseLayer(id: string | undefined): boolean {\n let newBaseLayer = undefined;\n if (id != null) {\n newBaseLayer = this.#layersById.get(id);\n if (!newBaseLayer) {\n LOG.warn(`Cannot activate base layer '${id}': layer is unknown.`);\n return false;\n }\n if (!(newBaseLayer instanceof AbstractLayer)) {\n LOG.warn(`Cannot activate base layer '${id}: layer has an invalid type.'`);\n return false;\n }\n if (!newBaseLayer.isBaseLayer) {\n LOG.warn(`Cannot activate base layer '${id}': layer is not a base layer.`);\n return false;\n }\n }\n\n this.#updateBaseLayer(newBaseLayer);\n return true;\n }\n\n /**\n * Returns a list of operational layers, starting from the root of the map's layer hierarchy.\n * The returned list includes top level layers only. Use {@link getRecursiveLayers()} to retrieve (nested) child layers.\n */\n getOperationalLayers(options?: LayerRetrievalOptions): Layer[] {\n return this.getLayers(options).filter((layer) => !layer.isBaseLayer);\n }\n\n /**\n * Returns a list of layers known to this collection. This includes base layers and operational layers.\n * The returned list includes top level layers only. Use {@link getRecursiveLayers()} to retrieve (nested) child layers.\n */\n getLayers(options?: LayerRetrievalOptions): Layer[] {\n let allLayers: Layer[];\n\n if (options?.sortByDisplayOrder) {\n const baseLayers = this.getBaseLayers();\n const order = Array.from(this.#operationalLayerOrder);\n const topMost = Array.from(this.#topMostOperationalLayers);\n allLayers = [...baseLayers, ...order, ...topMost];\n } else {\n allLayers = Array.from(this.#topLevelLayers.values());\n }\n\n if (!options?.includeInternalLayers) {\n allLayers = allLayers.filter((l) => !l.internal);\n }\n return allLayers;\n }\n\n /**\n * Returns a list of layers known to this collection. This includes base layers and operational layers.\n * The returned list includes top level layers only. Use {@link getRecursiveLayers()} to retrieve (nested) child layers.\n *\n * @deprecated Use {@link getLayers()}, {@link getOperationalLayers()} or {@link getRecursiveLayers()} instead.\n * This method name is misleading since it does not recurse into child layers.\n */\n getAllLayers(options?: LayerRetrievalOptions): Layer[] {\n return this.getLayers(options);\n }\n\n /**\n * Returns a list of all layers in this collection, including all children (recursively).\n *\n * > Note: This includes base layers by default (see `options.filter`).\n * > Use the `\"base\"` or `\"operational\"` short hand values to filter by base layer or operational layers.\n * >\n * > If the layer hierarchy is deeply nested, this function could potentially be expensive.\n */\n getRecursiveLayers({\n filter,\n sortByDisplayOrder,\n includeInternalLayers\n }: Omit<RecursiveRetrievalOptions, \"filter\"> & {\n filter?: \"base\" | \"operational\" | ((layer: AnyLayer) => boolean);\n } = {}): AnyLayer[] {\n let filterFunc;\n if (typeof filter === \"function\") {\n filterFunc = filter;\n } else if (typeof filter === \"string\") {\n const filterType = filter;\n const topLevelFilter = (layer: Layer) => {\n return filterType === \"base\" ? layer.isBaseLayer : !layer.isBaseLayer;\n };\n filterFunc = (layer: AnyLayer) => {\n if (!layer.parent && \"isBaseLayer\" in layer) {\n return topLevelFilter(layer);\n }\n // For nested children, include them all.\n return true;\n };\n }\n\n return getRecursiveLayers({\n from: this,\n filter: filterFunc,\n sortByDisplayOrder,\n includeInternalLayers\n });\n }\n\n getItems(options?: LayerRetrievalOptions): Layer[] {\n return this.getLayers(options);\n }\n\n /**\n * Returns the layer identified by the `id` or undefined, if no such layer exists.\n */\n getLayerById(id: string): AnyLayer | undefined {\n return this.#layersById.get(id);\n }\n\n /**\n * Removes a layer identified by the `id` from the map.\n *\n * NOTE: The current implementation only supports removal of _top level_ layers.\n *\n * ### Ownership\n *\n * This function _destroys_ the layer instance and all its children.\n *\n * @deprecated Use {@link removeLayer} instead.\n */\n removeLayerById(id: string): void {\n batch(() => {\n const layer = this.#layersById.get(id);\n if (!layer) {\n LOG.isDebug() && LOG.debug(`Cannot remove layer '${id}': layer is unknown.`);\n return;\n }\n\n checkLayerInstance(layer);\n if (!this.#topLevelLayers.has(layer)) {\n LOG.warn(\n `Cannot remove layer '${layer.id}': only top level layers can be removed at this time.`\n );\n return;\n }\n\n this.#removeLayer(layer);\n layer.destroy();\n });\n }\n\n /**\n * Removes the given top level layer from the map.\n *\n * The layer can be specified directly (as an object) or by an id.\n *\n * Returns the layer instance on success, or `undefined` if the layer was not found.\n *\n * ### Ownership\n *\n * The map releases ownership of this layer.\n * The caller can destroy it or store it for later reuse.\n */\n removeLayer(layer: string | Layer): Layer | undefined {\n return batch(() => {\n let actualLayer;\n if (typeof layer === \"string\") {\n actualLayer = this.#layersById.get(layer);\n if (!actualLayer) {\n return undefined;\n }\n } else {\n actualLayer = layer;\n }\n\n checkLayerInstance(actualLayer);\n if (!this.#topLevelLayers.has(actualLayer)) {\n return undefined;\n }\n\n this.#removeLayer(actualLayer);\n actualLayer[DETACH_FROM_MAP]();\n return actualLayer;\n });\n }\n\n /**\n * Given a raw OpenLayers layer instance, returns the associated {@link Layer} - or undefined\n * if the layer is unknown to this collection.\n */\n getLayerByRawInstance(layer: OlBaseLayer): Layer | undefined {\n return this.#layersByOlLayer?.get(layer);\n }\n\n /**\n * Adds the given layer to the map and all relevant indices.\n */\n #addLayer(layer: LayerType, options: AddLayerOptions | undefined) {\n // Throws; do this before manipulating the data structures\n const pos = this.#getInsertionPos(layer, options);\n this.#indexLayer(layer);\n\n // Everything below this line should not fail.\n if (pos.which === \"base\") {\n if (!this.#activeBaseLayer.value && layer.visible) {\n this.#updateBaseLayer(layer);\n } else {\n layer[SET_VISIBLE](false);\n }\n } else {\n layer[SET_VISIBLE](layer.visible);\n\n const layerList = this.#getLayerList(pos);\n layerList.splice(pos.index, 0, layer); // insert new layer at insertion index\n }\n this.#topLevelLayers.add(layer);\n this.#map.olMap.addLayer(layer.olLayer);\n }\n\n #getInsertionPos(layer: LayerType, options: AddLayerOptions | undefined): LayerPos {\n if (layer.isBaseLayer) {\n if (options?.at) {\n throw new Error(\n `Cannot add base layer '${layer.id}' at a specific position: only operational layers can be added at a specific position.`\n );\n }\n return { which: \"base\" };\n }\n\n switch (options?.at) {\n case undefined:\n case null:\n case \"top\":\n return { which: \"normal\", index: this.#operationalLayerOrder.length };\n case \"topmost\":\n return { which: \"topmost\", index: this.#topMostOperationalLayers.length };\n case \"bottom\":\n return { which: \"normal\", index: 0 };\n case \"above\":\n case \"below\": {\n const reference = this.#getReference(options.reference);\n const pos = this.#findOpOrTopmost(reference);\n if (!pos) {\n // reference is not a top level operational layer -> throw error\n const errorMessage = this.#getInsertErrorMessage(layer, reference);\n throw new Error(errorMessage);\n }\n\n if (options.at === \"above\") {\n pos.index++;\n }\n return pos;\n }\n }\n assertNever(options);\n }\n\n #getReference(reference: Layer | string): LayerType {\n let layer: AnyLayer;\n if (typeof reference === \"string\") {\n const refLayer = this.getLayerById(reference);\n if (!refLayer) {\n throw new Error(`Unknown reference layer '${reference}'.`);\n }\n layer = refLayer;\n } else {\n layer = reference;\n }\n checkLayerInstance(layer);\n return layer;\n }\n\n /**\n * Removes the given top level layer from the map and all relevant indices.\n */\n #removeLayer(layer: LayerType) {\n this.#map.olMap.removeLayer(layer.olLayer);\n this.#topLevelLayers.delete(layer);\n if (!layer.isBaseLayer) {\n const pos = this.#findOpOrTopmost(layer);\n if (!pos) {\n throw new Error(`Internal error: layer '${layer.id}' not found.`);\n }\n const layerList = this.#getLayerList(pos);\n layerList.splice(pos.index, 1);\n }\n\n this.#unIndexLayer(layer);\n if (this.#activeBaseLayer.value === layer) {\n const newBaseLayer = this.getBaseLayers()[0];\n if (newBaseLayer) {\n checkLayerInstance(newBaseLayer);\n }\n this.#updateBaseLayer(newBaseLayer);\n }\n }\n\n #updateBaseLayer(layer: LayerType | undefined) {\n if (this.#activeBaseLayer.value === layer) {\n return;\n }\n\n if (LOG.isDebug()) {\n const getId = (layer: AbstractLayer | undefined) => {\n return layer ? `'${layer.id}'` : undefined;\n };\n\n LOG.debug(\n `Switching active base layer from ${getId(this.#activeBaseLayer.value)} to ${getId(layer)}`\n );\n }\n\n batch(() => {\n this.#activeBaseLayer.value?.[SET_VISIBLE](false);\n this.#activeBaseLayer.value = layer;\n layer?.[SET_VISIBLE](true);\n });\n }\n\n /**\n * Index the layer and all its children.\n */\n #indexLayer(layer: LayerType) {\n // layer id -> layer (or sublayer)\n const registrations: [string, OlBaseLayer | undefined][] = [];\n const visit = (layer: LayerType | (AbstractLayerBase & Sublayer)) => {\n const id = layer.id;\n const olLayer = \"olLayer\" in layer ? layer.olLayer : undefined;\n if (this.#layersById.has(id)) {\n throw new Error(\n `Layer id '${id}' is not unique. Either assign a unique id yourself ` +\n `or skip configuring 'id' for an automatically generated id.`\n );\n }\n if (olLayer && this.#layersByOlLayer.has(olLayer)) {\n throw new Error(`OlLayer used by layer '${id}' has already been used in map.`);\n }\n\n // Register this layer with the map.\n this.#layersById.set(id, layer);\n if (olLayer) {\n this.#layersByOlLayer.set(olLayer, layer as LayerType); // ol is present --> not a sublayer\n }\n registrations.push([id, olLayer]);\n\n // Recurse into nested children.\n for (const childLayer of layer.layers?.[GET_RAW_LAYERS]() ?? []) {\n visit(childLayer);\n }\n for (const sublayer of layer.sublayers?.[GET_RAW_SUBLAYERS]() ?? []) {\n visit(sublayer);\n }\n };\n\n try {\n visit(layer);\n } catch (e) {\n // If any error happens, undo the indexing.\n // This way we don't leave a partially indexed layer tree behind.\n for (const [id, olLayer] of registrations) {\n this.#layersById.delete(id);\n if (olLayer) {\n this.#layersByOlLayer.delete(olLayer);\n }\n }\n throw e;\n }\n }\n\n /**\n * Removes index entries for the given layer and all its children.\n */\n #unIndexLayer(layer: AbstractLayer) {\n const visit = (layer: AbstractLayer | AbstractLayerBase) => {\n if (\"olLayer\" in layer) {\n this.#layersByOlLayer.delete(layer.olLayer);\n }\n this.#layersById.delete(layer.id);\n\n for (const childLayer of layer.layers?.[GET_RAW_LAYERS]() ?? []) {\n visit(childLayer);\n }\n\n for (const sublayer of layer.sublayers?.[GET_RAW_SUBLAYERS]() ?? []) {\n visit(sublayer);\n }\n };\n visit(layer);\n }\n\n #getLayerList(pos: OpOrTopmostLayerPos): ReactiveArray<LayerType> {\n switch (pos.which) {\n case \"topmost\":\n return this.#topMostOperationalLayers;\n case \"normal\":\n return this.#operationalLayerOrder;\n }\n }\n\n #findOpOrTopmost(layer: LayerType): OpOrTopmostLayerPos | undefined {\n let index = this.#operationalLayerOrder.indexOf(layer);\n if (index !== -1) {\n return { which: \"normal\", index };\n }\n\n index = this.#topMostOperationalLayers.indexOf(layer);\n if (index !== -1) {\n return { which: \"topmost\", index };\n }\n return undefined;\n }\n\n #getInsertErrorMessage(layer: LayerType, reference: LayerType) {\n let message: string = `Cannot add layer '${layer.id}'. Reference layer '${reference.id}' is not a top level operational layer.`;\n\n if (reference.isBaseLayer) {\n //is base layer\n message += \" Reference layer is a base layer.\";\n } else if (reference.parent) {\n //is child layer\n message += \" Reference layer is child layer of a group.\";\n }\n\n return message;\n }\n}\n\nfunction checkLayerInstance(object: AnyLayer): asserts object is Layer & AbstractLayer {\n if (!(object instanceof AbstractLayer)) {\n throw new Error(\n `Layer is not a valid layer instance. Use one of the classes provided by the map package instead.`\n );\n }\n}\n\nfunction assertNever(_arg: never): never {\n throw new Error(`Internal error: unhandled option.`);\n}\n"],"names":["layer"],"mappings":"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"}
1
+ {"version":3,"file":"LayerCollection.js","sources":["LayerCollection.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 effect,\n reactive,\n ReactiveArray,\n reactiveArray,\n reactiveMap,\n reactiveSet\n} from \"@conterra/reactivity-core\";\nimport { createLogger, Resource } from \"@open-pioneer/core\";\nimport OlBaseLayer from \"ol/layer/Base\";\nimport { sourceId } from \"open-pioneer:source-info\";\nimport { AbstractLayer } from \"../layers/AbstractLayer\";\nimport { AbstractLayerBase } from \"../layers/AbstractLayerBase\";\nimport type { AddLayerOptions } from \"../layers/shared/AddLayerOptions\";\nimport { getRecursiveLayers } from \"../layers/shared/getRecursiveLayers\";\nimport {\n ATTACH_TO_MAP,\n DETACH_FROM_MAP,\n GET_RAW_LAYERS,\n GET_RAW_SUBLAYERS,\n SET_VISIBLE\n} from \"../layers/shared/internals\";\nimport type {\n LayerRetrievalOptions,\n RecursiveRetrievalOptions\n} from \"../layers/shared/LayerRetrievalOptions\";\nimport { AnyLayer, Layer, Sublayer } from \"../layers/unions\";\nimport { assertInternalConstructor, InternalConstructorTag } from \"../utils/InternalConstructorTag\";\nimport { MapModel } from \"./MapModel\";\n\nconst LOG = createLogger(sourceId);\n\ntype LayerType = AbstractLayer & Layer;\ntype LayerBaseType = (AbstractLayerBase & Layer) | (AbstractLayerBase & Sublayer);\n\ninterface OpOrTopmostLayerPos {\n which: \"normal\" | \"topmost\";\n index: number;\n}\n\ninterface BaseLayerPos {\n which: \"base\";\n}\n\ntype LayerPos = OpOrTopmostLayerPos | BaseLayerPos;\n\n/**\n * Contains the layers contained in a {@link MapModel}.\n *\n * @group Map Model\n */\nexport class LayerCollection {\n #map: MapModel;\n\n /** Top level layers (base layers, operational layers). No sublayers. */\n #topLevelLayers = reactiveSet<LayerType>();\n\n /** Index of _all_ layer instances, including sublayers. */\n #layersById = reactiveMap<string, LayerBaseType>();\n\n /** Reverse index of _all_ layers that have an associated OpenLayers layer. */\n #layersByOlLayer: WeakMap<OlBaseLayer, LayerType> = new WeakMap();\n\n /** Currently active base layer. */\n #activeBaseLayer = reactive<LayerType>();\n\n /**\n * Defines the relative order of operational layers.\n * Lower index -> layer is below its successors.\n * Excluding {@link #topMostOperationalLayers}\n */\n #operationalLayerOrder = reactiveArray<LayerType>();\n\n /** Operational layers that are always displayed at the top above all other layers (e.g. a highlight layer) */\n #topMostOperationalLayers = reactiveArray<LayerType>();\n\n #syncHandle: Resource | undefined;\n\n /** @internal */\n constructor(map: MapModel, tag: InternalConstructorTag) {\n assertInternalConstructor(tag);\n\n this.#map = map;\n this.#syncHandle = effect(() => {\n // Contains base layers, normal operational layers, topmost layers in bottom-to-top order.\n const orderedLayers = this.getLayers({\n sortByDisplayOrder: true,\n includeInternalLayers: true\n });\n\n // Simply reassign all z-indices whenever the order changes.\n let index = 0;\n for (const layer of orderedLayers) {\n LOG.isDebug() && LOG.debug(\"Assigning z-index\", layer.id, index);\n layer.olLayer.setZIndex(index);\n index++;\n }\n });\n }\n\n destroy() {\n for (const layer of this.#layersById.values()) {\n layer.destroy();\n }\n this.#topLevelLayers.clear();\n this.#layersById.clear();\n this.#operationalLayerOrder.splice(0, this.#operationalLayerOrder.length);\n this.#activeBaseLayer.value = undefined;\n this.#syncHandle?.destroy();\n this.#syncHandle = undefined;\n }\n\n /**\n * Adds a new layer to the map.\n *\n * The new layer is automatically registered with this collection.\n *\n * ### Display order\n *\n * By default, the new layer will be shown on _top_ of all normal operational layers.\n * Use the `options` parameter to control the insertion point.\n *\n * ### Ownership\n *\n * The map model takes ownership of the new layer.\n * This means that the layer will be destroyed if the map model is destroyed.\n */\n addLayer(layer: Layer, options?: AddLayerOptions): void {\n batch(() => {\n checkLayerInstance(layer);\n\n layer[ATTACH_TO_MAP](this.#map);\n this.#addLayer(layer, options);\n });\n }\n\n /**\n * Returns all configured base layers.\n */\n getBaseLayers(): Layer[] {\n // Slightly inefficient, but we don't need a separate index for base layers right now.\n return Array.from(this.#topLevelLayers).filter((layer) => layer.isBaseLayer);\n }\n\n /**\n * Returns the currently active base layer.\n */\n getActiveBaseLayer(): Layer | undefined {\n return this.#activeBaseLayer.value;\n }\n\n /**\n * Activates the base layer with the given id.\n * `undefined` can be used to hide all base layers.\n *\n * The associated layer is made visible and all other base layers are hidden.\n *\n * Returns true if the given layer has been successfully activated.\n */\n activateBaseLayer(id: string | undefined): boolean {\n let newBaseLayer = undefined;\n if (id != null) {\n newBaseLayer = this.#layersById.get(id);\n if (!newBaseLayer) {\n LOG.warn(`Cannot activate base layer '${id}': layer is unknown.`);\n return false;\n }\n if (!(newBaseLayer instanceof AbstractLayer)) {\n LOG.warn(`Cannot activate base layer '${id}: layer has an invalid type.'`);\n return false;\n }\n if (!newBaseLayer.isBaseLayer) {\n LOG.warn(`Cannot activate base layer '${id}': layer is not a base layer.`);\n return false;\n }\n }\n\n this.#updateBaseLayer(newBaseLayer);\n return true;\n }\n\n /**\n * Returns a list of operational layers, starting from the root of the map's layer hierarchy.\n * The returned list includes top level layers only. Use {@link getRecursiveLayers()} to retrieve (nested) child layers.\n */\n getOperationalLayers(options?: LayerRetrievalOptions): Layer[] {\n return this.getLayers(options).filter((layer) => !layer.isBaseLayer);\n }\n\n /**\n * Returns a list of layers known to this collection. This includes base layers and operational layers.\n * The returned list includes top level layers only. Use {@link getRecursiveLayers()} to retrieve (nested) child layers.\n */\n getLayers(options?: LayerRetrievalOptions): Layer[] {\n let allLayers: Layer[];\n\n if (options?.sortByDisplayOrder) {\n const baseLayers = this.getBaseLayers();\n const order = Array.from(this.#operationalLayerOrder);\n const topMost = Array.from(this.#topMostOperationalLayers);\n allLayers = [...baseLayers, ...order, ...topMost];\n } else {\n allLayers = Array.from(this.#topLevelLayers.values());\n }\n\n if (!options?.includeInternalLayers) {\n allLayers = allLayers.filter((l) => !l.internal);\n }\n return allLayers;\n }\n\n /**\n * Returns a list of layers known to this collection. This includes base layers and operational layers.\n * The returned list includes top level layers only. Use {@link getRecursiveLayers()} to retrieve (nested) child layers.\n *\n * @deprecated Use {@link getLayers()}, {@link getOperationalLayers()} or {@link getRecursiveLayers()} instead.\n * This method name is misleading since it does not recurse into child layers.\n */\n getAllLayers(options?: LayerRetrievalOptions): Layer[] {\n return this.getLayers(options);\n }\n\n /**\n * Returns a list of all layers in this collection, including all children (recursively).\n *\n * > Note: This includes base layers by default (see `options.filter`).\n * > Use the `\"base\"` or `\"operational\"` short hand values to filter by base layer or operational layers.\n * >\n * > If the layer hierarchy is deeply nested, this function could potentially be expensive.\n */\n getRecursiveLayers({\n filter,\n sortByDisplayOrder,\n includeInternalLayers\n }: Omit<RecursiveRetrievalOptions, \"filter\"> & {\n filter?: \"base\" | \"operational\" | ((layer: AnyLayer) => boolean);\n } = {}): AnyLayer[] {\n let filterFunc;\n if (typeof filter === \"function\") {\n filterFunc = filter;\n } else if (typeof filter === \"string\") {\n const filterType = filter;\n const topLevelFilter = (layer: Layer) => {\n return filterType === \"base\" ? layer.isBaseLayer : !layer.isBaseLayer;\n };\n filterFunc = (layer: AnyLayer) => {\n if (!layer.parent && \"isBaseLayer\" in layer) {\n return topLevelFilter(layer);\n }\n // For nested children, include them all.\n return true;\n };\n }\n\n return getRecursiveLayers({\n from: this,\n filter: filterFunc,\n sortByDisplayOrder,\n includeInternalLayers\n });\n }\n\n getItems(options?: LayerRetrievalOptions): Layer[] {\n return this.getLayers(options);\n }\n\n /**\n * Returns the layer identified by the `id` or undefined, if no such layer exists.\n */\n getLayerById(id: string): AnyLayer | undefined {\n return this.#layersById.get(id);\n }\n\n /**\n * Removes a layer identified by the `id` from the map.\n *\n * NOTE: The current implementation only supports removal of _top level_ layers.\n *\n * ### Ownership\n *\n * This function _destroys_ the layer instance and all its children.\n *\n * @deprecated Use {@link removeLayer} instead.\n */\n removeLayerById(id: string): void {\n batch(() => {\n const layer = this.#layersById.get(id);\n if (!layer) {\n LOG.isDebug() && LOG.debug(`Cannot remove layer '${id}': layer is unknown.`);\n return;\n }\n\n checkLayerInstance(layer);\n if (!this.#topLevelLayers.has(layer)) {\n LOG.warn(\n `Cannot remove layer '${layer.id}': only top level layers can be removed at this time.`\n );\n return;\n }\n\n this.#removeLayer(layer);\n layer.destroy();\n });\n }\n\n /**\n * Removes the given top level layer from the map.\n *\n * The layer can be specified directly (as an object) or by an id.\n *\n * Returns the layer instance on success, or `undefined` if the layer was not found.\n *\n * ### Ownership\n *\n * The map releases ownership of this layer.\n * The caller can destroy it or store it for later reuse.\n */\n removeLayer(layer: string | Layer): Layer | undefined {\n return batch(() => {\n let actualLayer;\n if (typeof layer === \"string\") {\n actualLayer = this.#layersById.get(layer);\n if (!actualLayer) {\n return undefined;\n }\n } else {\n actualLayer = layer;\n }\n\n checkLayerInstance(actualLayer);\n if (!this.#topLevelLayers.has(actualLayer)) {\n return undefined;\n }\n\n this.#removeLayer(actualLayer);\n actualLayer[DETACH_FROM_MAP]();\n return actualLayer;\n });\n }\n\n /**\n * Given a raw OpenLayers layer instance, returns the associated {@link Layer} - or undefined\n * if the layer is unknown to this collection.\n */\n getLayerByRawInstance(layer: OlBaseLayer): Layer | undefined {\n return this.#layersByOlLayer?.get(layer);\n }\n\n /**\n * Adds the given layer to the map and all relevant indices.\n */\n #addLayer(layer: LayerType, options: AddLayerOptions | undefined) {\n // Throws; do this before manipulating the data structures\n const pos = this.#getInsertionPos(layer, options);\n this.#indexLayer(layer);\n\n // Everything below this line should not fail.\n if (pos.which === \"base\") {\n if (!this.#activeBaseLayer.value && layer.visible) {\n this.#updateBaseLayer(layer);\n } else {\n layer[SET_VISIBLE](false);\n }\n } else {\n layer[SET_VISIBLE](layer.visible);\n\n const layerList = this.#getLayerList(pos);\n layerList.splice(pos.index, 0, layer); // insert new layer at insertion index\n }\n this.#topLevelLayers.add(layer);\n this.#map.olMap.addLayer(layer.olLayer);\n }\n\n #getInsertionPos(layer: LayerType, options: AddLayerOptions | undefined): LayerPos {\n if (layer.isBaseLayer) {\n if (options?.at) {\n throw new Error(\n `Cannot add base layer '${layer.id}' at a specific position: only operational layers can be added at a specific position.`\n );\n }\n return { which: \"base\" };\n }\n\n switch (options?.at) {\n case undefined:\n case null:\n case \"top\":\n return { which: \"normal\", index: this.#operationalLayerOrder.length };\n case \"topmost\":\n return { which: \"topmost\", index: this.#topMostOperationalLayers.length };\n case \"bottom\":\n return { which: \"normal\", index: 0 };\n case \"above\":\n case \"below\": {\n const reference = this.#getReference(options.reference);\n const pos = this.#findOpOrTopmost(reference);\n if (!pos) {\n // reference is not a top level operational layer -> throw error\n const errorMessage = this.#getInsertErrorMessage(layer, reference);\n throw new Error(errorMessage);\n }\n\n if (options.at === \"above\") {\n pos.index++;\n }\n return pos;\n }\n }\n assertNever(options);\n }\n\n #getReference(reference: Layer | string): LayerType {\n let layer: AnyLayer;\n if (typeof reference === \"string\") {\n const refLayer = this.getLayerById(reference);\n if (!refLayer) {\n throw new Error(`Unknown reference layer '${reference}'.`);\n }\n layer = refLayer;\n } else {\n layer = reference;\n }\n checkLayerInstance(layer);\n return layer;\n }\n\n /**\n * Removes the given top level layer from the map and all relevant indices.\n */\n #removeLayer(layer: LayerType) {\n this.#map.olMap.removeLayer(layer.olLayer);\n this.#topLevelLayers.delete(layer);\n if (!layer.isBaseLayer) {\n const pos = this.#findOpOrTopmost(layer);\n if (!pos) {\n throw new Error(`Internal error: layer '${layer.id}' not found.`);\n }\n const layerList = this.#getLayerList(pos);\n layerList.splice(pos.index, 1);\n }\n\n this.#unIndexLayer(layer);\n if (this.#activeBaseLayer.value === layer) {\n const newBaseLayer = this.getBaseLayers()[0];\n if (newBaseLayer) {\n checkLayerInstance(newBaseLayer);\n }\n this.#updateBaseLayer(newBaseLayer);\n }\n }\n\n #updateBaseLayer(layer: LayerType | undefined) {\n if (this.#activeBaseLayer.value === layer) {\n return;\n }\n\n if (LOG.isDebug()) {\n const getId = (layer: AbstractLayer | undefined) => {\n return layer ? `'${layer.id}'` : undefined;\n };\n\n LOG.debug(\n `Switching active base layer from ${getId(this.#activeBaseLayer.value)} to ${getId(layer)}`\n );\n }\n\n batch(() => {\n this.#activeBaseLayer.value?.[SET_VISIBLE](false);\n this.#activeBaseLayer.value = layer;\n layer?.[SET_VISIBLE](true);\n });\n }\n\n /**\n * Index the layer and all its children.\n */\n #indexLayer(layer: LayerType) {\n // layer id -> layer (or sublayer)\n const registrations: [string, OlBaseLayer | undefined][] = [];\n const visit = (layer: LayerType | (AbstractLayerBase & Sublayer)) => {\n const id = layer.id;\n const olLayer = \"olLayer\" in layer ? layer.olLayer : undefined;\n if (this.#layersById.has(id)) {\n throw new Error(\n `Layer id '${id}' is not unique. Either assign a unique id yourself ` +\n `or skip configuring 'id' for an automatically generated id.`\n );\n }\n if (olLayer && this.#layersByOlLayer.has(olLayer)) {\n throw new Error(`OlLayer used by layer '${id}' has already been used in map.`);\n }\n\n // Register this layer with the map.\n this.#layersById.set(id, layer);\n if (olLayer) {\n this.#layersByOlLayer.set(olLayer, layer as LayerType); // ol is present --> not a sublayer\n }\n registrations.push([id, olLayer]);\n\n // Recurse into nested children.\n for (const childLayer of layer.layers?.[GET_RAW_LAYERS]() ?? []) {\n visit(childLayer);\n }\n for (const sublayer of layer.sublayers?.[GET_RAW_SUBLAYERS]() ?? []) {\n visit(sublayer);\n }\n };\n\n try {\n visit(layer);\n } catch (e) {\n // If any error happens, undo the indexing.\n // This way we don't leave a partially indexed layer tree behind.\n for (const [id, olLayer] of registrations) {\n this.#layersById.delete(id);\n if (olLayer) {\n this.#layersByOlLayer.delete(olLayer);\n }\n }\n throw e;\n }\n }\n\n /**\n * Removes index entries for the given layer and all its children.\n */\n #unIndexLayer(layer: AbstractLayer) {\n const visit = (layer: AbstractLayer | AbstractLayerBase) => {\n if (\"olLayer\" in layer) {\n this.#layersByOlLayer.delete(layer.olLayer);\n }\n this.#layersById.delete(layer.id);\n\n for (const childLayer of layer.layers?.[GET_RAW_LAYERS]() ?? []) {\n visit(childLayer);\n }\n\n for (const sublayer of layer.sublayers?.[GET_RAW_SUBLAYERS]() ?? []) {\n visit(sublayer);\n }\n };\n visit(layer);\n }\n\n #getLayerList(pos: OpOrTopmostLayerPos): ReactiveArray<LayerType> {\n switch (pos.which) {\n case \"topmost\":\n return this.#topMostOperationalLayers;\n case \"normal\":\n return this.#operationalLayerOrder;\n }\n }\n\n #findOpOrTopmost(layer: LayerType): OpOrTopmostLayerPos | undefined {\n let index = this.#operationalLayerOrder.indexOf(layer);\n if (index !== -1) {\n return { which: \"normal\", index };\n }\n\n index = this.#topMostOperationalLayers.indexOf(layer);\n if (index !== -1) {\n return { which: \"topmost\", index };\n }\n return undefined;\n }\n\n #getInsertErrorMessage(layer: LayerType, reference: LayerType) {\n let message: string = `Cannot add layer '${layer.id}'. Reference layer '${reference.id}' is not a top level operational layer.`;\n\n if (reference.isBaseLayer) {\n //is base layer\n message += \" Reference layer is a base layer.\";\n } else if (reference.parent) {\n //is child layer\n message += \" Reference layer is child layer of a group.\";\n }\n\n return message;\n }\n}\n\nfunction checkLayerInstance(object: AnyLayer): asserts object is Layer & AbstractLayer {\n if (!(object instanceof AbstractLayer)) {\n throw new Error(\n `Layer is not a valid layer instance. Use one of the classes provided by the map package instead.`\n );\n }\n}\n\nfunction assertNever(_arg: never): never {\n throw new Error(`Internal error: unhandled option.`);\n}\n"],"names":["layer"],"mappings":"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"}
@@ -7,8 +7,8 @@ import { Coordinate } from "ol/coordinate";
7
7
  import { Geometry } from "ol/geom";
8
8
  import { Projection } from "ol/proj";
9
9
  import type { StyleLike } from "ol/style/Style";
10
- import type { BaseFeature } from "../utils/BaseFeature";
11
10
  import { LAYER_DEPS, LayerDependencies } from "../layers/shared/internals";
11
+ import type { BaseFeature } from "../utils/BaseFeature";
12
12
  import { InternalConstructorTag } from "../utils/InternalConstructorTag";
13
13
  import { LayerCollection } from "./LayerCollection";
14
14
  import { ExtentConfig } from "./MapConfig";
package/model/MapModel.js CHANGED
@@ -4,12 +4,13 @@ import { createLogger, isAbortError, createManualPromise, createAbortError } fro
4
4
  import { unByKey } from 'ol/Observable.js';
5
5
  import { getCenter } from 'ol/extent.js';
6
6
  import { getPointResolution } from 'ol/proj.js';
7
+ import { sourceId$7 as sourceId } from '../_virtual/source-info.js';
7
8
  import { LAYER_DEPS } from '../layers/shared/internals.js';
8
9
  import { INTERNAL_CONSTRUCTOR_TAG, assertInternalConstructor } from '../utils/InternalConstructorTag.js';
9
10
  import { Highlights } from './Highlights.js';
10
11
  import { LayerCollection } from './LayerCollection.js';
11
12
 
12
- const LOG = createLogger("map:MapModel");
13
+ const LOG = createLogger(sourceId);
13
14
  const DEFAULT_DPI = 25.4 / 0.28;
14
15
  const INCHES_PER_METRE = 39.37;
15
16
  class MapModel {
@@ -1 +1 @@
1
- {"version":3,"file":"MapModel.js","sources":["MapModel.ts"],"sourcesContent":["// SPDX-FileCopyrightText: 2023-2025 Open Pioneer project (https://github.com/open-pioneer)\n// SPDX-License-Identifier: Apache-2.0\nimport { computed, reactive, ReadonlyReactive, synchronized } from \"@conterra/reactivity-core\";\nimport { emit, emitter, EventSource } from \"@conterra/reactivity-events\";\nimport type { Resource } from \"@open-pioneer/core\";\nimport {\n createAbortError,\n createLogger,\n createManualPromise,\n isAbortError,\n ManualPromise\n} from \"@open-pioneer/core\";\nimport { HttpService } from \"@open-pioneer/http\";\nimport OlMap from \"ol/Map\";\nimport { unByKey } from \"ol/Observable\";\nimport OlView from \"ol/View\";\nimport { Coordinate } from \"ol/coordinate\";\nimport { EventsKey } from \"ol/events\";\nimport { getCenter } from \"ol/extent\";\nimport { Geometry } from \"ol/geom\";\nimport { getPointResolution, Projection } from \"ol/proj\";\nimport type { StyleLike } from \"ol/style/Style\";\nimport type { BaseFeature } from \"../utils/BaseFeature\";\nimport { LAYER_DEPS, LayerDependencies } from \"../layers/shared/internals\";\nimport {\n assertInternalConstructor,\n INTERNAL_CONSTRUCTOR_TAG,\n InternalConstructorTag\n} from \"../utils/InternalConstructorTag\";\nimport { Highlights } from \"./Highlights\";\nimport { LayerCollection } from \"./LayerCollection\";\nimport { ExtentConfig } from \"./MapConfig\";\n\nconst LOG = createLogger(\"map:MapModel\");\n\nconst DEFAULT_DPI = 25.4 / 0.28;\nconst INCHES_PER_METRE = 39.37;\n\n/**\n * Style options supported when creating a new {@link Highlight}.\n *\n * @group Map Model\n **/\nexport interface HighlightOptions {\n /**\n * Optional styles to override the default styles.\n */\n highlightStyle?: HighlightStyle;\n}\n\n/**\n * Zoom options supported when creating a new {@link Highlight}.\n *\n * @group Map Model\n **/\nexport interface ZoomOptions {\n /**\n * The zoom-level used if there is no valid extend (such as for single points).\n */\n pointZoom?: number;\n\n /**\n * The maximum zoom-level for multiple points, line or polygon results.\n */\n maxZoom?: number;\n\n /**\n * The view padding to make all features visible.\n */\n viewPadding?: MapPadding;\n\n /**\n * The buffer factor around the extent of the zoomed features. E.g. a value of 1.1 will add\n * 10% to specify the size increase of the extent's width and height.\n */\n buffer?: number;\n}\n\n/**\n * Options supported by the map model's {@link MapModel.highlightAndZoom | highlightAndZoom} method.\n *\n * @group Map Model\n **/\nexport interface HighlightZoomOptions extends HighlightOptions, ZoomOptions {}\n\n/**\n * Custom styles when creating a new {@link Highlight}.\n *\n * @group Map Model\n */\nexport type HighlightStyle = {\n Point?: StyleLike;\n LineString?: StyleLike;\n Polygon?: StyleLike;\n MultiPolygon?: StyleLike;\n MultiPoint?: StyleLike;\n MultiLineString?: StyleLike;\n};\n\n/**\n * Map padding, all values are pixels.\n *\n * See https://openlayers.org/en/latest/apidoc/module-ol_View-View.html#padding\n *\n * @group Map Model\n */\nexport interface MapPadding {\n left?: number;\n right?: number;\n top?: number;\n bottom?: number;\n}\n\n/**\n * Represents the additional graphical representations of objects.\n *\n * See also {@link MapModel.highlight}.\n *\n * @group Map Model\n */\nexport interface Highlight extends Resource {\n readonly isActive: boolean;\n}\n\n/**\n * Represents an object in the map.\n *\n * @group Map Model\n */\nexport type DisplayTarget = BaseFeature | Geometry;\n\n/**\n * Represents a map.\n *\n * @group Map Model\n */\nexport class MapModel {\n readonly #id: string;\n readonly #olMap: OlMap;\n readonly #olView: ReadonlyReactive<OlView>;\n readonly #layers = new LayerCollection(this, INTERNAL_CONSTRUCTOR_TAG);\n readonly #highlights: Highlights;\n readonly #layerDeps: LayerDependencies;\n readonly #destroyed = emitter();\n\n #isDestroyed = false;\n #container: ReadonlyReactive<HTMLElement | undefined>;\n #initialExtent = reactive<ExtentConfig>();\n #viewBindings: ReadonlyReactive<ViewBindings>;\n #scale: ReadonlyReactive<number | undefined>;\n\n readonly #abortController = new AbortController();\n #displayStatus: \"waiting\" | \"ready\" | \"error\";\n #displayWaiter: ManualPromise<void> | undefined;\n\n /**\n * @internal\n */\n constructor(\n properties: {\n id: string;\n olMap: OlMap;\n initialExtent: ExtentConfig | undefined;\n httpService: HttpService;\n },\n tag: InternalConstructorTag\n ) {\n assertInternalConstructor(tag);\n this.#id = properties.id;\n this.#olMap = properties.olMap;\n this.#olView = synchronized(\n () => this.#olMap.getView(),\n (cb) => {\n const key = this.#olMap.on(\"change:view\", cb);\n return () => unByKey(key);\n }\n );\n this.#initialExtent.value = properties.initialExtent;\n this.#layerDeps = {\n httpService: properties.httpService\n };\n\n this.#displayStatus = \"waiting\";\n this.#initializeView().then(\n () => {\n this.#displayStatus = \"ready\";\n this.#displayWaiter?.resolve();\n this.#displayWaiter = undefined;\n },\n (error) => {\n if (!isAbortError(error)) {\n LOG.error(`Failed to initialize map`, error);\n }\n\n this.#displayStatus = \"error\";\n this.#displayWaiter?.reject(new Error(`Failed to initialize map.`));\n this.#displayWaiter = undefined;\n }\n );\n\n this.#container = synchronized(\n () => this.#olMap.getTargetElement() ?? undefined,\n (cb) => {\n const key = this.#olMap.on(\"change:target\", cb);\n return () => unByKey(key);\n }\n );\n\n this.#viewBindings = computed(() => createViewBindings(this.#olView.value));\n this.#scale = computed(() => {\n const { projection, resolution, center } = this;\n if (projection == null || resolution == null || center == null) {\n return undefined;\n }\n\n /**\n * Returns the appropriate scale for the given resolution and units, see OpenLayers function getScaleForResolution()\n * https://github.com/openlayers/openlayers/blob/7fa9df03431e9e1bc517e6c414565d9f848a3132/src/ol/control/ScaleLine.js#L454C3-L454C24\n */\n const pointResolution = getPointResolution(projection, resolution, center, \"m\"); //point resolution in meter per pixel\n const scale = Math.round(pointResolution * INCHES_PER_METRE * DEFAULT_DPI);\n return scale;\n });\n\n // expects fully constructed mapModel\n this.#highlights = new Highlights(this, this.#layerDeps);\n }\n\n /**\n * Destroys this objects, including all layers, highlights and the OL map itself.\n */\n destroy() {\n if (this.#isDestroyed) {\n return;\n }\n\n this.#isDestroyed = true;\n try {\n emit(this.#destroyed);\n } catch (e) {\n LOG.warn(`Unexpected error from event listener during map model destruction:`, e);\n }\n\n this.#abortController.abort();\n this.#displayWaiter?.reject(new Error(\"Map model was destroyed.\"));\n this.#layers.destroy();\n this.#highlights.destroy();\n this.#olMap.dispose();\n }\n\n /**\n * Emitted when the map model is destroyed.\n */\n get destroyed(): EventSource<void> {\n return this.#destroyed;\n }\n\n /**\n * The unique id of the map.\n */\n get id(): string {\n return this.#id;\n }\n\n /**\n * The initial map extent.\n *\n * May be undefined before the map is shown.\n * This is guaranteed to be initialized if the promise returned by {@link whenDisplayed} has resolved.\n */\n get initialExtent(): ExtentConfig | undefined {\n return this.#initialExtent.value;\n }\n\n /**\n * Returns the current projection of the map (reactive).\n */\n get projection(): Projection {\n return this.#viewBindings.value.projection;\n }\n\n /**\n * Returns the current center of the map.\n * Same as `olView.getCenter()`, but reactive.\n */\n get center(): Coordinate | undefined {\n return this.#viewBindings.value.center.value;\n }\n\n /**\n * Returns the current resolution of the map.\n * Same as `olView.getResolution()`, but reactive.\n */\n get resolution(): number | undefined {\n return this.#viewBindings.value.resolution.value;\n }\n\n /**\n * Returns the current zoom level of the map.\n * Same as `olView.getZoom()`, but reactive.\n */\n get zoomLevel(): number | undefined {\n return this.#viewBindings.value.zoom.value;\n }\n\n /**\n * Returns the current scale of the map.\n *\n * The scale is a value derived from the current `center`, `resolution` and `projection` of the map.\n * The scale will change when the map is zoomed in our out, but depending on the projection, it may also\n * change when the map is _panned_.\n *\n * > NOTE: Technically, this is the _denominator_ of the current scale.\n * > In order to display it, use a format like `1:${scale}`.\n */\n get scale(): number | undefined {\n return this.#scale.value;\n }\n\n /**\n * Contains all known layers of this map.\n *\n * Note that not all layers in this collection may be active in the OpenLayers map.\n * Also note that not all layers in the OpenLayers map may be contained in this collection.\n */\n get layers(): LayerCollection {\n return this.#layers;\n }\n\n /**\n * The container in which the map is currently being rendered.\n * This is the same as the target element of the underlying OpenLayers map.\n *\n * May be undefined if the map is not being rendered at the moment.\n * May change at runtime.\n */\n get container(): HTMLElement | undefined {\n return this.#container.value;\n }\n\n /**\n * The raw OpenLayers map.\n */\n get olMap(): OlMap {\n return this.#olMap;\n }\n\n /**\n * Returns the current view of the OpenLayers map.\n */\n get olView(): OlView {\n return this.#olView.value;\n }\n\n /**\n * TODO: Can be removed once the LayerFactory is the only supported way of constructing a layer.\n *\n * @internal\n */\n get [LAYER_DEPS](): LayerDependencies {\n return this.#layerDeps;\n }\n\n /**\n * Changes the current scale of the map to the given value.\n *\n * Internally, this computes a new zoom level / resolution based on the scale\n * and the current center.\n * The new resolution is then applied to the current `olView`.\n *\n * See also {@link scale}.\n */\n setScale(newScale: number): void {\n const view = this.olView;\n const projection = this.projection;\n const center = this.center;\n if (!center) {\n return;\n }\n\n const mpu = projection.getMetersPerUnit() ?? 1;\n const resolution = INCHES_PER_METRE * DEFAULT_DPI * mpu;\n const pointResolution = newScale / getPointResolution(projection, resolution, center);\n view.setResolution(pointResolution);\n }\n\n /**\n * Creates a highlight at the given targets.\n *\n * A highlight is a temporary graphic on the map that calls attention to a point or an area.\n *\n * Call `destroy()` on the returned highlight object to remove the highlight again.\n */\n highlight(geometries: DisplayTarget[], options?: HighlightOptions | undefined): Highlight {\n return this.#highlights.addHighlight(geometries, options);\n }\n\n /**\n * Zooms to the given targets.\n */\n zoom(geometries: DisplayTarget[], options?: ZoomOptions | undefined): void {\n this.#highlights.zoomToHighlight(geometries, options);\n }\n\n /**\n * Creates a highlight and zooms to the given targets.\n *\n * See also {@link highlight} and {@link zoom}.\n */\n highlightAndZoom(geometries: DisplayTarget[], options?: HighlightZoomOptions) {\n return this.#highlights.addHighlightAndZoom(geometries, options ?? {});\n }\n\n /**\n * Removes any existing highlights from the map.\n */\n removeHighlights() {\n this.#highlights.clearHighlight();\n }\n\n /**\n * Returns a promise that resolves when the map has mounted in the DOM.\n */\n whenDisplayed(): Promise<void> {\n if (this.#isDestroyed) {\n return Promise.reject(new Error(\"Map model was destroyed.\"));\n }\n if (this.#displayStatus === \"error\") {\n return Promise.reject(new Error(`Failed to initialize map.`));\n }\n if (this.#displayStatus === \"ready\") {\n return Promise.resolve();\n }\n return (this.#displayWaiter ??= createManualPromise()).promise;\n }\n\n /**\n * Waits for the map to be displayed and then initializes the view (if necessary).\n *\n * May simply resolve when done, or throw an error when a problem occurs.\n * AbortError is thrown when cancelled via `this.#abortController`, for example\n * when the map model is destroyed before it has ever been displayed.\n */\n async #initializeView(): Promise<void> {\n try {\n await waitForMapSize(this.olMap, this.#abortController.signal); // may throw on cancel\n } catch (e) {\n if (isAbortError(e)) {\n throw e;\n }\n throw new Error(`Failed to wait for the map to be displayed.`, { cause: e });\n }\n\n try {\n const olMap = this.#olMap;\n const view = olMap.getView();\n\n if (this.#initialExtent.value) {\n // Initial extent was set from the outside. We simply ensure that it gets displayed by the map.\n const extent = this.#initialExtent.value;\n const olExtent = [extent.xMin, extent.yMin, extent.xMax, extent.yMax];\n\n const olCenter = getCenter(olExtent);\n const resolution = view.getResolutionForExtent(olExtent);\n LOG.debug(`Applying initial extent`, extent);\n LOG.debug(` Computed center:`, olCenter);\n LOG.debug(` Computed resolution:`, resolution);\n\n view.setCenter(olCenter);\n view.setResolution(resolution);\n } else {\n // Initial extent was NOT set from the outside.\n // We detect whatever the view is displaying and consider it to be the initial extent.\n const olExtent = view.calculateExtent();\n const [xMin = 0, yMin = 0, xMax = 0, yMax = 0] = olExtent;\n const extent: ExtentConfig = { xMin, yMin, xMax, yMax };\n LOG.debug(`Detected initial extent`, extent);\n\n this.#initialExtent.value = extent;\n }\n } catch (e) {\n throw new Error(`Failed to apply the initial extent.`, { cause: e });\n }\n }\n}\n\ninterface ViewBindings {\n resolution: ReadonlyReactive<number | undefined>;\n center: ReadonlyReactive<Coordinate | undefined>;\n zoom: ReadonlyReactive<number | undefined>;\n projection: Projection; // not reactive (change view to change projection)\n}\n\nfunction createViewBindings(view: OlView): ViewBindings {\n return {\n resolution: synchronized(\n () => view.getResolution(),\n (cb) => {\n const key = view.on(\"change:resolution\", cb);\n return () => unByKey(key);\n }\n ),\n center: synchronized(\n () => view.getCenter(),\n (cb) => {\n const key = view.on(\"change:center\", cb);\n return () => unByKey(key);\n }\n ),\n zoom: synchronized(\n () => view.getZoom(),\n (cb) => {\n const key = view.on(\"change:resolution\", cb);\n return () => unByKey(key);\n }\n ),\n projection: view.getProjection()\n };\n}\n\nfunction waitForMapSize(olMap: OlMap, signal: AbortSignal): Promise<void> {\n const promise = new Promise<void>((resolve, reject) => {\n let eventKey: EventsKey | undefined;\n\n function checkSize() {\n const currentSize = olMap.getSize() ?? [];\n const [width = 0, height = 0] = currentSize;\n if (currentSize && width > 0 && height > 0) {\n finish();\n }\n }\n\n function onAbort() {\n finish(createAbortError());\n }\n\n function finish(error?: Error | undefined) {\n if (eventKey) {\n unByKey(eventKey);\n eventKey = undefined;\n }\n signal.removeEventListener(\"abort\", onAbort);\n\n if (error) {\n reject(error);\n } else {\n resolve(wait(25)); // Give the map some time to render\n }\n }\n\n if (signal.aborted) {\n finish(createAbortError());\n return;\n }\n\n signal.addEventListener(\"abort\", onAbort);\n eventKey = olMap.on(\"change:size\", checkSize);\n });\n return promise;\n}\n\nfunction wait(milliseconds: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, milliseconds));\n}\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"MapModel.js","sources":["MapModel.ts"],"sourcesContent":["// SPDX-FileCopyrightText: 2023-2025 Open Pioneer project (https://github.com/open-pioneer)\n// SPDX-License-Identifier: Apache-2.0\nimport { computed, reactive, ReadonlyReactive, synchronized } from \"@conterra/reactivity-core\";\nimport { emit, emitter, EventSource } from \"@conterra/reactivity-events\";\nimport type { Resource } from \"@open-pioneer/core\";\nimport {\n createAbortError,\n createLogger,\n createManualPromise,\n isAbortError,\n ManualPromise\n} from \"@open-pioneer/core\";\nimport { HttpService } from \"@open-pioneer/http\";\nimport OlMap from \"ol/Map\";\nimport { unByKey } from \"ol/Observable\";\nimport OlView from \"ol/View\";\nimport { Coordinate } from \"ol/coordinate\";\nimport { EventsKey } from \"ol/events\";\nimport { getCenter } from \"ol/extent\";\nimport { Geometry } from \"ol/geom\";\nimport { getPointResolution, Projection } from \"ol/proj\";\nimport type { StyleLike } from \"ol/style/Style\";\nimport { sourceId } from \"open-pioneer:source-info\";\nimport { LAYER_DEPS, LayerDependencies } from \"../layers/shared/internals\";\nimport type { BaseFeature } from \"../utils/BaseFeature\";\nimport {\n assertInternalConstructor,\n INTERNAL_CONSTRUCTOR_TAG,\n InternalConstructorTag\n} from \"../utils/InternalConstructorTag\";\nimport { Highlights } from \"./Highlights\";\nimport { LayerCollection } from \"./LayerCollection\";\nimport { ExtentConfig } from \"./MapConfig\";\n\nconst LOG = createLogger(sourceId);\n\nconst DEFAULT_DPI = 25.4 / 0.28;\nconst INCHES_PER_METRE = 39.37;\n\n/**\n * Style options supported when creating a new {@link Highlight}.\n *\n * @group Map Model\n **/\nexport interface HighlightOptions {\n /**\n * Optional styles to override the default styles.\n */\n highlightStyle?: HighlightStyle;\n}\n\n/**\n * Zoom options supported when creating a new {@link Highlight}.\n *\n * @group Map Model\n **/\nexport interface ZoomOptions {\n /**\n * The zoom-level used if there is no valid extend (such as for single points).\n */\n pointZoom?: number;\n\n /**\n * The maximum zoom-level for multiple points, line or polygon results.\n */\n maxZoom?: number;\n\n /**\n * The view padding to make all features visible.\n */\n viewPadding?: MapPadding;\n\n /**\n * The buffer factor around the extent of the zoomed features. E.g. a value of 1.1 will add\n * 10% to specify the size increase of the extent's width and height.\n */\n buffer?: number;\n}\n\n/**\n * Options supported by the map model's {@link MapModel.highlightAndZoom | highlightAndZoom} method.\n *\n * @group Map Model\n **/\nexport interface HighlightZoomOptions extends HighlightOptions, ZoomOptions {}\n\n/**\n * Custom styles when creating a new {@link Highlight}.\n *\n * @group Map Model\n */\nexport type HighlightStyle = {\n Point?: StyleLike;\n LineString?: StyleLike;\n Polygon?: StyleLike;\n MultiPolygon?: StyleLike;\n MultiPoint?: StyleLike;\n MultiLineString?: StyleLike;\n};\n\n/**\n * Map padding, all values are pixels.\n *\n * See https://openlayers.org/en/latest/apidoc/module-ol_View-View.html#padding\n *\n * @group Map Model\n */\nexport interface MapPadding {\n left?: number;\n right?: number;\n top?: number;\n bottom?: number;\n}\n\n/**\n * Represents the additional graphical representations of objects.\n *\n * See also {@link MapModel.highlight}.\n *\n * @group Map Model\n */\nexport interface Highlight extends Resource {\n readonly isActive: boolean;\n}\n\n/**\n * Represents an object in the map.\n *\n * @group Map Model\n */\nexport type DisplayTarget = BaseFeature | Geometry;\n\n/**\n * Represents a map.\n *\n * @group Map Model\n */\nexport class MapModel {\n readonly #id: string;\n readonly #olMap: OlMap;\n readonly #olView: ReadonlyReactive<OlView>;\n readonly #layers = new LayerCollection(this, INTERNAL_CONSTRUCTOR_TAG);\n readonly #highlights: Highlights;\n readonly #layerDeps: LayerDependencies;\n readonly #destroyed = emitter();\n\n #isDestroyed = false;\n #container: ReadonlyReactive<HTMLElement | undefined>;\n #initialExtent = reactive<ExtentConfig>();\n #viewBindings: ReadonlyReactive<ViewBindings>;\n #scale: ReadonlyReactive<number | undefined>;\n\n readonly #abortController = new AbortController();\n #displayStatus: \"waiting\" | \"ready\" | \"error\";\n #displayWaiter: ManualPromise<void> | undefined;\n\n /**\n * @internal\n */\n constructor(\n properties: {\n id: string;\n olMap: OlMap;\n initialExtent: ExtentConfig | undefined;\n httpService: HttpService;\n },\n tag: InternalConstructorTag\n ) {\n assertInternalConstructor(tag);\n this.#id = properties.id;\n this.#olMap = properties.olMap;\n this.#olView = synchronized(\n () => this.#olMap.getView(),\n (cb) => {\n const key = this.#olMap.on(\"change:view\", cb);\n return () => unByKey(key);\n }\n );\n this.#initialExtent.value = properties.initialExtent;\n this.#layerDeps = {\n httpService: properties.httpService\n };\n\n this.#displayStatus = \"waiting\";\n this.#initializeView().then(\n () => {\n this.#displayStatus = \"ready\";\n this.#displayWaiter?.resolve();\n this.#displayWaiter = undefined;\n },\n (error) => {\n if (!isAbortError(error)) {\n LOG.error(`Failed to initialize map`, error);\n }\n\n this.#displayStatus = \"error\";\n this.#displayWaiter?.reject(new Error(`Failed to initialize map.`));\n this.#displayWaiter = undefined;\n }\n );\n\n this.#container = synchronized(\n () => this.#olMap.getTargetElement() ?? undefined,\n (cb) => {\n const key = this.#olMap.on(\"change:target\", cb);\n return () => unByKey(key);\n }\n );\n\n this.#viewBindings = computed(() => createViewBindings(this.#olView.value));\n this.#scale = computed(() => {\n const { projection, resolution, center } = this;\n if (projection == null || resolution == null || center == null) {\n return undefined;\n }\n\n /**\n * Returns the appropriate scale for the given resolution and units, see OpenLayers function getScaleForResolution()\n * https://github.com/openlayers/openlayers/blob/7fa9df03431e9e1bc517e6c414565d9f848a3132/src/ol/control/ScaleLine.js#L454C3-L454C24\n */\n const pointResolution = getPointResolution(projection, resolution, center, \"m\"); //point resolution in meter per pixel\n const scale = Math.round(pointResolution * INCHES_PER_METRE * DEFAULT_DPI);\n return scale;\n });\n\n // expects fully constructed mapModel\n this.#highlights = new Highlights(this, this.#layerDeps);\n }\n\n /**\n * Destroys this objects, including all layers, highlights and the OL map itself.\n */\n destroy() {\n if (this.#isDestroyed) {\n return;\n }\n\n this.#isDestroyed = true;\n try {\n emit(this.#destroyed);\n } catch (e) {\n LOG.warn(`Unexpected error from event listener during map model destruction:`, e);\n }\n\n this.#abortController.abort();\n this.#displayWaiter?.reject(new Error(\"Map model was destroyed.\"));\n this.#layers.destroy();\n this.#highlights.destroy();\n this.#olMap.dispose();\n }\n\n /**\n * Emitted when the map model is destroyed.\n */\n get destroyed(): EventSource<void> {\n return this.#destroyed;\n }\n\n /**\n * The unique id of the map.\n */\n get id(): string {\n return this.#id;\n }\n\n /**\n * The initial map extent.\n *\n * May be undefined before the map is shown.\n * This is guaranteed to be initialized if the promise returned by {@link whenDisplayed} has resolved.\n */\n get initialExtent(): ExtentConfig | undefined {\n return this.#initialExtent.value;\n }\n\n /**\n * Returns the current projection of the map (reactive).\n */\n get projection(): Projection {\n return this.#viewBindings.value.projection;\n }\n\n /**\n * Returns the current center of the map.\n * Same as `olView.getCenter()`, but reactive.\n */\n get center(): Coordinate | undefined {\n return this.#viewBindings.value.center.value;\n }\n\n /**\n * Returns the current resolution of the map.\n * Same as `olView.getResolution()`, but reactive.\n */\n get resolution(): number | undefined {\n return this.#viewBindings.value.resolution.value;\n }\n\n /**\n * Returns the current zoom level of the map.\n * Same as `olView.getZoom()`, but reactive.\n */\n get zoomLevel(): number | undefined {\n return this.#viewBindings.value.zoom.value;\n }\n\n /**\n * Returns the current scale of the map.\n *\n * The scale is a value derived from the current `center`, `resolution` and `projection` of the map.\n * The scale will change when the map is zoomed in our out, but depending on the projection, it may also\n * change when the map is _panned_.\n *\n * > NOTE: Technically, this is the _denominator_ of the current scale.\n * > In order to display it, use a format like `1:${scale}`.\n */\n get scale(): number | undefined {\n return this.#scale.value;\n }\n\n /**\n * Contains all known layers of this map.\n *\n * Note that not all layers in this collection may be active in the OpenLayers map.\n * Also note that not all layers in the OpenLayers map may be contained in this collection.\n */\n get layers(): LayerCollection {\n return this.#layers;\n }\n\n /**\n * The container in which the map is currently being rendered.\n * This is the same as the target element of the underlying OpenLayers map.\n *\n * May be undefined if the map is not being rendered at the moment.\n * May change at runtime.\n */\n get container(): HTMLElement | undefined {\n return this.#container.value;\n }\n\n /**\n * The raw OpenLayers map.\n */\n get olMap(): OlMap {\n return this.#olMap;\n }\n\n /**\n * Returns the current view of the OpenLayers map.\n */\n get olView(): OlView {\n return this.#olView.value;\n }\n\n /**\n * TODO: Can be removed once the LayerFactory is the only supported way of constructing a layer.\n *\n * @internal\n */\n get [LAYER_DEPS](): LayerDependencies {\n return this.#layerDeps;\n }\n\n /**\n * Changes the current scale of the map to the given value.\n *\n * Internally, this computes a new zoom level / resolution based on the scale\n * and the current center.\n * The new resolution is then applied to the current `olView`.\n *\n * See also {@link scale}.\n */\n setScale(newScale: number): void {\n const view = this.olView;\n const projection = this.projection;\n const center = this.center;\n if (!center) {\n return;\n }\n\n const mpu = projection.getMetersPerUnit() ?? 1;\n const resolution = INCHES_PER_METRE * DEFAULT_DPI * mpu;\n const pointResolution = newScale / getPointResolution(projection, resolution, center);\n view.setResolution(pointResolution);\n }\n\n /**\n * Creates a highlight at the given targets.\n *\n * A highlight is a temporary graphic on the map that calls attention to a point or an area.\n *\n * Call `destroy()` on the returned highlight object to remove the highlight again.\n */\n highlight(geometries: DisplayTarget[], options?: HighlightOptions | undefined): Highlight {\n return this.#highlights.addHighlight(geometries, options);\n }\n\n /**\n * Zooms to the given targets.\n */\n zoom(geometries: DisplayTarget[], options?: ZoomOptions | undefined): void {\n this.#highlights.zoomToHighlight(geometries, options);\n }\n\n /**\n * Creates a highlight and zooms to the given targets.\n *\n * See also {@link highlight} and {@link zoom}.\n */\n highlightAndZoom(geometries: DisplayTarget[], options?: HighlightZoomOptions) {\n return this.#highlights.addHighlightAndZoom(geometries, options ?? {});\n }\n\n /**\n * Removes any existing highlights from the map.\n */\n removeHighlights() {\n this.#highlights.clearHighlight();\n }\n\n /**\n * Returns a promise that resolves when the map has mounted in the DOM.\n */\n whenDisplayed(): Promise<void> {\n if (this.#isDestroyed) {\n return Promise.reject(new Error(\"Map model was destroyed.\"));\n }\n if (this.#displayStatus === \"error\") {\n return Promise.reject(new Error(`Failed to initialize map.`));\n }\n if (this.#displayStatus === \"ready\") {\n return Promise.resolve();\n }\n return (this.#displayWaiter ??= createManualPromise()).promise;\n }\n\n /**\n * Waits for the map to be displayed and then initializes the view (if necessary).\n *\n * May simply resolve when done, or throw an error when a problem occurs.\n * AbortError is thrown when cancelled via `this.#abortController`, for example\n * when the map model is destroyed before it has ever been displayed.\n */\n async #initializeView(): Promise<void> {\n try {\n await waitForMapSize(this.olMap, this.#abortController.signal); // may throw on cancel\n } catch (e) {\n if (isAbortError(e)) {\n throw e;\n }\n throw new Error(`Failed to wait for the map to be displayed.`, { cause: e });\n }\n\n try {\n const olMap = this.#olMap;\n const view = olMap.getView();\n\n if (this.#initialExtent.value) {\n // Initial extent was set from the outside. We simply ensure that it gets displayed by the map.\n const extent = this.#initialExtent.value;\n const olExtent = [extent.xMin, extent.yMin, extent.xMax, extent.yMax];\n\n const olCenter = getCenter(olExtent);\n const resolution = view.getResolutionForExtent(olExtent);\n LOG.debug(`Applying initial extent`, extent);\n LOG.debug(` Computed center:`, olCenter);\n LOG.debug(` Computed resolution:`, resolution);\n\n view.setCenter(olCenter);\n view.setResolution(resolution);\n } else {\n // Initial extent was NOT set from the outside.\n // We detect whatever the view is displaying and consider it to be the initial extent.\n const olExtent = view.calculateExtent();\n const [xMin = 0, yMin = 0, xMax = 0, yMax = 0] = olExtent;\n const extent: ExtentConfig = { xMin, yMin, xMax, yMax };\n LOG.debug(`Detected initial extent`, extent);\n\n this.#initialExtent.value = extent;\n }\n } catch (e) {\n throw new Error(`Failed to apply the initial extent.`, { cause: e });\n }\n }\n}\n\ninterface ViewBindings {\n resolution: ReadonlyReactive<number | undefined>;\n center: ReadonlyReactive<Coordinate | undefined>;\n zoom: ReadonlyReactive<number | undefined>;\n projection: Projection; // not reactive (change view to change projection)\n}\n\nfunction createViewBindings(view: OlView): ViewBindings {\n return {\n resolution: synchronized(\n () => view.getResolution(),\n (cb) => {\n const key = view.on(\"change:resolution\", cb);\n return () => unByKey(key);\n }\n ),\n center: synchronized(\n () => view.getCenter(),\n (cb) => {\n const key = view.on(\"change:center\", cb);\n return () => unByKey(key);\n }\n ),\n zoom: synchronized(\n () => view.getZoom(),\n (cb) => {\n const key = view.on(\"change:resolution\", cb);\n return () => unByKey(key);\n }\n ),\n projection: view.getProjection()\n };\n}\n\nfunction waitForMapSize(olMap: OlMap, signal: AbortSignal): Promise<void> {\n const promise = new Promise<void>((resolve, reject) => {\n let eventKey: EventsKey | undefined;\n\n function checkSize() {\n const currentSize = olMap.getSize() ?? [];\n const [width = 0, height = 0] = currentSize;\n if (currentSize && width > 0 && height > 0) {\n finish();\n }\n }\n\n function onAbort() {\n finish(createAbortError());\n }\n\n function finish(error?: Error | undefined) {\n if (eventKey) {\n unByKey(eventKey);\n eventKey = undefined;\n }\n signal.removeEventListener(\"abort\", onAbort);\n\n if (error) {\n reject(error);\n } else {\n resolve(wait(25)); // Give the map some time to render\n }\n }\n\n if (signal.aborted) {\n finish(createAbortError());\n return;\n }\n\n signal.addEventListener(\"abort\", onAbort);\n eventKey = olMap.on(\"change:size\", checkSize);\n });\n return promise;\n}\n\nfunction wait(milliseconds: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, milliseconds));\n}\n"],"names":[],"mappings":"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"}
@@ -8,6 +8,7 @@ import { defaults, DragZoom } from 'ol/interaction.js';
8
8
  import TileLayer from 'ol/layer/Tile.js';
9
9
  import { get } from 'ol/proj.js';
10
10
  import OSM from 'ol/source/OSM.js';
11
+ import { sourceId$8 as sourceId } from '../_virtual/source-info.js';
11
12
  import { INTERNAL_CONSTRUCTOR_TAG } from '../utils/InternalConstructorTag.js';
12
13
  import { patchOpenLayersClassesForTesting } from '../utils/ol-test-support.js';
13
14
  import { registerProjections } from '../utils/projections.js';
@@ -17,7 +18,7 @@ registerProjections({
17
18
  "EPSG:25832": "+proj=utm +zone=32 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m +no_defs +type=crs",
18
19
  "EPSG:25833": "+proj=utm +zone=33 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m +no_defs +type=crs"
19
20
  });
20
- const LOG = createLogger("map:createMapModel");
21
+ const LOG = createLogger(sourceId);
21
22
  async function createMapModel(mapId, mapConfig, intl, httpService) {
22
23
  return await new MapModelFactory(mapId, mapConfig, intl, httpService).createMapModel();
23
24
  }
@@ -1 +1 @@
1
- {"version":3,"file":"createMapModel.js","sources":["createMapModel.ts"],"sourcesContent":["// SPDX-FileCopyrightText: 2023-2025 Open Pioneer project (https://github.com/open-pioneer)\n// SPDX-License-Identifier: Apache-2.0\nimport { batch } from \"@conterra/reactivity-core\";\nimport { createLogger } from \"@open-pioneer/core\";\nimport { HttpService } from \"@open-pioneer/http\";\nimport { PackageIntl } from \"@open-pioneer/runtime\";\nimport { MapBrowserEvent } from \"ol\";\nimport OlMap, { MapOptions } from \"ol/Map\";\nimport View, { ViewOptions } from \"ol/View\";\nimport Attribution from \"ol/control/Attribution\";\nimport { getCenter } from \"ol/extent\";\nimport { DragZoom, defaults as defaultInteractions } from \"ol/interaction\";\nimport TileLayer from \"ol/layer/Tile\";\nimport { Projection, get as getProjection } from \"ol/proj\";\nimport OSM from \"ol/source/OSM\";\nimport { INTERNAL_CONSTRUCTOR_TAG } from \"../utils/InternalConstructorTag\";\nimport { patchOpenLayersClassesForTesting } from \"../utils/ol-test-support\";\nimport { registerProjections } from \"../utils/projections\";\nimport { MapConfig } from \"./MapConfig\";\nimport { MapModel } from \"./MapModel\";\n\n/**\n * Register custom projection to the global proj4js definitions. User can select `EPSG:25832`\n * and `EPSG:25833` from the predefined projections without calling `registerProjections`.\n */\nregisterProjections({\n \"EPSG:25832\":\n \"+proj=utm +zone=32 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m +no_defs +type=crs\",\n \"EPSG:25833\":\n \"+proj=utm +zone=33 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m +no_defs +type=crs\"\n});\nconst LOG = createLogger(\"map:createMapModel\");\n\nexport async function createMapModel(\n mapId: string,\n mapConfig: MapConfig,\n intl: PackageIntl,\n httpService: HttpService\n): Promise<MapModel> {\n return await new MapModelFactory(mapId, mapConfig, intl, httpService).createMapModel();\n}\n\nclass MapModelFactory {\n private mapId: string;\n private mapConfig: MapConfig;\n private intl: PackageIntl;\n private httpService: HttpService;\n\n constructor(mapId: string, mapConfig: MapConfig, intl: PackageIntl, httpService: HttpService) {\n this.mapId = mapId;\n this.mapConfig = mapConfig;\n this.intl = intl;\n this.httpService = httpService;\n }\n\n async createMapModel() {\n const mapId = this.mapId;\n const mapConfig = this.mapConfig;\n const { view: viewOption, ...rawOlOptions } = mapConfig.advanced ?? {};\n const mapOptions: MapOptions = {\n ...rawOlOptions\n };\n\n if (!mapOptions.controls) {\n mapOptions.controls = [createDefaultAttribution(this.intl)];\n }\n\n if (!mapOptions.interactions) {\n const shiftCtrlKeysOnly = (\n mapBrowserEvent: MapBrowserEvent<KeyboardEvent | WheelEvent | PointerEvent>\n ) => {\n const originalEvent = mapBrowserEvent.originalEvent;\n return (originalEvent.metaKey || originalEvent.ctrlKey) && originalEvent.shiftKey;\n };\n\n // setting altShiftDragRotate to false disables or excludes DragRotate interaction\n mapOptions.interactions = defaultInteractions({\n dragPan: true,\n altShiftDragRotate: false,\n pinchRotate: false,\n mouseWheelZoom: true\n }).extend([new DragZoom({ out: true, condition: shiftCtrlKeysOnly })]);\n }\n\n const view = (await viewOption) ?? {};\n this.initializeViewOptions(view);\n mapOptions.view = view instanceof View ? view : new View(view);\n\n if (!mapOptions.layers && !mapConfig.layers) {\n mapOptions.layers = [\n new TileLayer({\n source: new OSM()\n })\n ];\n }\n\n const initialView = mapConfig.initialView;\n const initialExtent = initialView?.kind === \"extent\" ? initialView.extent : undefined;\n\n LOG.debug(`Constructing OpenLayers map with options`, mapOptions);\n\n if (import.meta.env.VITEST) {\n patchOpenLayersClassesForTesting();\n }\n\n const olMap = new OlMap(mapOptions);\n const mapModel = new MapModel(\n {\n id: mapId,\n olMap,\n initialExtent,\n httpService: this.httpService\n },\n INTERNAL_CONSTRUCTOR_TAG\n );\n\n return batch(() => {\n try {\n if (mapConfig.layers) {\n for (const layerConfig of mapConfig.layers) {\n mapModel.layers.addLayer(layerConfig);\n }\n }\n return mapModel;\n } catch (e) {\n mapModel.destroy();\n throw e;\n }\n });\n }\n\n private initializeViewOptions(view: View | ViewOptions) {\n const mapId = this.mapId;\n const mapConfig = this.mapConfig;\n if (view instanceof View) {\n const warn = (prop: string) => {\n LOG.warn(\n `The advanced configuration for map id '${mapId}' has provided a fully constructed view instance: ${prop} cannot be applied.\\n` +\n `Use ViewOptions instead of a View instance.`\n );\n };\n\n if (mapConfig.projection != null) {\n warn(\"projection\");\n }\n if (mapConfig.initialView != null) {\n warn(\"initialView\");\n }\n return;\n }\n\n const projection = (view.projection = this.initializeProjection(mapConfig.projection));\n const initialView = mapConfig.initialView;\n if (initialView) {\n switch (initialView.kind) {\n case \"position\":\n view.zoom = initialView.zoom;\n view.center = [initialView.center.x, initialView.center.y];\n break;\n case \"extent\": {\n /*\n OpenLayers does not support configuration of the initial map extent.\n The only relevant options here are center, zoom (and resolution).\n We must set those values because otherwise OpenLayers will not initialize layer sources.\n\n The actual initial extent is applied once tha map has loaded and its size is known.\n */\n const extent = initialView.extent;\n view.zoom = 0;\n view.center = [\n extent.xMin + (extent.xMax - extent.xMin) / 2,\n extent.yMin + (extent.yMax - extent.yMin) / 2\n ];\n break;\n }\n }\n } else {\n this.setViewDefaults(view, projection);\n }\n }\n\n private setViewDefaults(view: ViewOptions, projection: Projection) {\n if (view.center == null) {\n const extent = projection.getExtent(); // can be null\n if (!extent) {\n LOG.warn(\n `Cannot set default center coordinate because the current projection has no associated extent.\\n` +\n `Try to configure 'initialView' explicity.`\n );\n } else {\n view.center = getCenter(extent);\n }\n }\n\n if (view.zoom == null || view.resolution == null) {\n view.zoom = 0;\n }\n }\n\n private initializeProjection(projectionOption: MapConfig[\"projection\"]) {\n if (projectionOption == null) {\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n return getProjection(\"EPSG:3857\")!; // default OpenLayers projection\n }\n\n const projection = getProjection(projectionOption);\n if (!projection) {\n throw new Error(`Failed to retrieve projection for code '${projectionOption}'.`);\n }\n return projection;\n }\n}\n\nfunction createDefaultAttribution(intl: PackageIntl): Attribution {\n const attr = new Attribution({ collapsible: false });\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const element = (attr as any).element as HTMLElement | undefined;\n if (element) {\n element.role = \"region\";\n element.ariaLabel = intl.formatMessage({ id: \"attribution.label\" });\n }\n return attr;\n}\n"],"names":["defaultInteractions","getProjection"],"mappings":"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"}
1
+ {"version":3,"file":"createMapModel.js","sources":["createMapModel.ts"],"sourcesContent":["// SPDX-FileCopyrightText: 2023-2025 Open Pioneer project (https://github.com/open-pioneer)\n// SPDX-License-Identifier: Apache-2.0\nimport { batch } from \"@conterra/reactivity-core\";\nimport { createLogger } from \"@open-pioneer/core\";\nimport { HttpService } from \"@open-pioneer/http\";\nimport { PackageIntl } from \"@open-pioneer/runtime\";\nimport { MapBrowserEvent } from \"ol\";\nimport OlMap, { MapOptions } from \"ol/Map\";\nimport View, { ViewOptions } from \"ol/View\";\nimport Attribution from \"ol/control/Attribution\";\nimport { getCenter } from \"ol/extent\";\nimport { DragZoom, defaults as defaultInteractions } from \"ol/interaction\";\nimport TileLayer from \"ol/layer/Tile\";\nimport { Projection, get as getProjection } from \"ol/proj\";\nimport OSM from \"ol/source/OSM\";\nimport { sourceId } from \"open-pioneer:source-info\";\nimport { INTERNAL_CONSTRUCTOR_TAG } from \"../utils/InternalConstructorTag\";\nimport { patchOpenLayersClassesForTesting } from \"../utils/ol-test-support\";\nimport { registerProjections } from \"../utils/projections\";\nimport { MapConfig } from \"./MapConfig\";\nimport { MapModel } from \"./MapModel\";\n\n/**\n * Register custom projection to the global proj4js definitions. User can select `EPSG:25832`\n * and `EPSG:25833` from the predefined projections without calling `registerProjections`.\n */\nregisterProjections({\n \"EPSG:25832\":\n \"+proj=utm +zone=32 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m +no_defs +type=crs\",\n \"EPSG:25833\":\n \"+proj=utm +zone=33 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m +no_defs +type=crs\"\n});\nconst LOG = createLogger(sourceId);\n\nexport async function createMapModel(\n mapId: string,\n mapConfig: MapConfig,\n intl: PackageIntl,\n httpService: HttpService\n): Promise<MapModel> {\n return await new MapModelFactory(mapId, mapConfig, intl, httpService).createMapModel();\n}\n\nclass MapModelFactory {\n private mapId: string;\n private mapConfig: MapConfig;\n private intl: PackageIntl;\n private httpService: HttpService;\n\n constructor(mapId: string, mapConfig: MapConfig, intl: PackageIntl, httpService: HttpService) {\n this.mapId = mapId;\n this.mapConfig = mapConfig;\n this.intl = intl;\n this.httpService = httpService;\n }\n\n async createMapModel() {\n const mapId = this.mapId;\n const mapConfig = this.mapConfig;\n const { view: viewOption, ...rawOlOptions } = mapConfig.advanced ?? {};\n const mapOptions: MapOptions = {\n ...rawOlOptions\n };\n\n if (!mapOptions.controls) {\n mapOptions.controls = [createDefaultAttribution(this.intl)];\n }\n\n if (!mapOptions.interactions) {\n const shiftCtrlKeysOnly = (\n mapBrowserEvent: MapBrowserEvent<KeyboardEvent | WheelEvent | PointerEvent>\n ) => {\n const originalEvent = mapBrowserEvent.originalEvent;\n return (originalEvent.metaKey || originalEvent.ctrlKey) && originalEvent.shiftKey;\n };\n\n // setting altShiftDragRotate to false disables or excludes DragRotate interaction\n mapOptions.interactions = defaultInteractions({\n dragPan: true,\n altShiftDragRotate: false,\n pinchRotate: false,\n mouseWheelZoom: true\n }).extend([new DragZoom({ out: true, condition: shiftCtrlKeysOnly })]);\n }\n\n const view = (await viewOption) ?? {};\n this.initializeViewOptions(view);\n mapOptions.view = view instanceof View ? view : new View(view);\n\n if (!mapOptions.layers && !mapConfig.layers) {\n mapOptions.layers = [\n new TileLayer({\n source: new OSM()\n })\n ];\n }\n\n const initialView = mapConfig.initialView;\n const initialExtent = initialView?.kind === \"extent\" ? initialView.extent : undefined;\n\n LOG.debug(`Constructing OpenLayers map with options`, mapOptions);\n\n if (import.meta.env.VITEST) {\n patchOpenLayersClassesForTesting();\n }\n\n const olMap = new OlMap(mapOptions);\n const mapModel = new MapModel(\n {\n id: mapId,\n olMap,\n initialExtent,\n httpService: this.httpService\n },\n INTERNAL_CONSTRUCTOR_TAG\n );\n\n return batch(() => {\n try {\n if (mapConfig.layers) {\n for (const layerConfig of mapConfig.layers) {\n mapModel.layers.addLayer(layerConfig);\n }\n }\n return mapModel;\n } catch (e) {\n mapModel.destroy();\n throw e;\n }\n });\n }\n\n private initializeViewOptions(view: View | ViewOptions) {\n const mapId = this.mapId;\n const mapConfig = this.mapConfig;\n if (view instanceof View) {\n const warn = (prop: string) => {\n LOG.warn(\n `The advanced configuration for map id '${mapId}' has provided a fully constructed view instance: ${prop} cannot be applied.\\n` +\n `Use ViewOptions instead of a View instance.`\n );\n };\n\n if (mapConfig.projection != null) {\n warn(\"projection\");\n }\n if (mapConfig.initialView != null) {\n warn(\"initialView\");\n }\n return;\n }\n\n const projection = (view.projection = this.initializeProjection(mapConfig.projection));\n const initialView = mapConfig.initialView;\n if (initialView) {\n switch (initialView.kind) {\n case \"position\":\n view.zoom = initialView.zoom;\n view.center = [initialView.center.x, initialView.center.y];\n break;\n case \"extent\": {\n /*\n OpenLayers does not support configuration of the initial map extent.\n The only relevant options here are center, zoom (and resolution).\n We must set those values because otherwise OpenLayers will not initialize layer sources.\n\n The actual initial extent is applied once tha map has loaded and its size is known.\n */\n const extent = initialView.extent;\n view.zoom = 0;\n view.center = [\n extent.xMin + (extent.xMax - extent.xMin) / 2,\n extent.yMin + (extent.yMax - extent.yMin) / 2\n ];\n break;\n }\n }\n } else {\n this.setViewDefaults(view, projection);\n }\n }\n\n private setViewDefaults(view: ViewOptions, projection: Projection) {\n if (view.center == null) {\n const extent = projection.getExtent(); // can be null\n if (!extent) {\n LOG.warn(\n `Cannot set default center coordinate because the current projection has no associated extent.\\n` +\n `Try to configure 'initialView' explicity.`\n );\n } else {\n view.center = getCenter(extent);\n }\n }\n\n if (view.zoom == null || view.resolution == null) {\n view.zoom = 0;\n }\n }\n\n private initializeProjection(projectionOption: MapConfig[\"projection\"]) {\n if (projectionOption == null) {\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n return getProjection(\"EPSG:3857\")!; // default OpenLayers projection\n }\n\n const projection = getProjection(projectionOption);\n if (!projection) {\n throw new Error(`Failed to retrieve projection for code '${projectionOption}'.`);\n }\n return projection;\n }\n}\n\nfunction createDefaultAttribution(intl: PackageIntl): Attribution {\n const attr = new Attribution({ collapsible: false });\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const element = (attr as any).element as HTMLElement | undefined;\n if (element) {\n element.role = \"region\";\n element.ariaLabel = intl.formatMessage({ id: \"attribution.label\" });\n }\n return attr;\n}\n"],"names":["defaultInteractions","getProjection"],"mappings":"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"}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "type": "module",
3
3
  "name": "@open-pioneer/map",
4
- "version": "1.2.0-dev.20260121105545",
4
+ "version": "1.2.0",
5
5
  "description": "This package integrates OpenLayers maps into an open pioneer trails application.",
6
6
  "keywords": [
7
7
  "open-pioneer-trails"
@@ -15,10 +15,10 @@
15
15
  },
16
16
  "dependencies": {
17
17
  "@chakra-ui/react": "^3.31.0",
18
- "@open-pioneer/core": "4.4.0-dev.20260121102820",
19
- "@open-pioneer/http": "4.4.0-dev.20260121102820",
20
- "@open-pioneer/react-utils": "4.4.0-dev.20260121102820",
21
- "@open-pioneer/runtime": "4.4.0-dev.20260121102820",
18
+ "@open-pioneer/core": "^4.4.0",
19
+ "@open-pioneer/http": "^4.4.0",
20
+ "@open-pioneer/react-utils": "^4.4.0",
21
+ "@open-pioneer/runtime": "^4.4.0",
22
22
  "ol": "^10.7.0",
23
23
  "proj4": "^2.20.2",
24
24
  "react": "^19.2.3",
@@ -1,7 +1,7 @@
1
1
  import { CommonComponentProps } from "@open-pioneer/react-utils";
2
2
  import { ReactNode } from "react";
3
- import { MapModelProps } from "./hooks/useMapModel";
4
3
  import { MapPadding } from "../model/MapModel";
4
+ import { MapModelProps } from "./hooks/useMapModel";
5
5
  /**
6
6
  * @group UI Components and Hooks
7
7
  */
@@ -2,11 +2,12 @@ import { jsxs, jsx } from 'react/jsx-runtime';
2
2
  import { chakra } from '@chakra-ui/react';
3
3
  import { createLogger } from '@open-pioneer/core';
4
4
  import { useCommonComponentProps } from '@open-pioneer/react-utils';
5
+ import { sourceId$9 as sourceId } from '../_virtual/source-info.js';
5
6
  import { useRef, useState, useEffect, useMemo } from 'react';
6
7
  import { MapContainerContextProvider } from './MapContainerContext.js';
7
8
  import { useMapModelValue } from './hooks/useMapModel.js';
8
9
 
9
- const LOG = createLogger("map:MapContainer");
10
+ const LOG = createLogger(sourceId);
10
11
  function MapContainer(props) {
11
12
  const {
12
13
  viewPadding,
@@ -1 +1 @@
1
- {"version":3,"file":"MapContainer.js","sources":["MapContainer.tsx"],"sourcesContent":["// SPDX-FileCopyrightText: 2023-2025 Open Pioneer project (https://github.com/open-pioneer)\n// SPDX-License-Identifier: Apache-2.0\nimport { chakra } from \"@chakra-ui/react\";\nimport { Resource, createLogger } from \"@open-pioneer/core\";\nimport { CommonComponentProps, useCommonComponentProps } from \"@open-pioneer/react-utils\";\nimport type OlMap from \"ol/Map\";\nimport { Extent } from \"ol/extent\";\nimport { ReactNode, useEffect, useMemo, useRef, useState } from \"react\";\nimport { MapContainerContextProvider, MapContainerContextType } from \"./MapContainerContext\";\nimport { MapModelProps, useMapModelValue } from \"./hooks/useMapModel\";\nimport { MapModel, MapPadding } from \"../model/MapModel\";\nconst LOG = createLogger(\"map:MapContainer\");\n\n/**\n * @group UI Components and Hooks\n */\nexport interface MapContainerProps extends CommonComponentProps, MapModelProps {\n /**\n * Sets the map's padding directly.\n * Do not use the view's padding property directly on the OL map.\n *\n * See: https://openlayers.org/en/latest/apidoc/module-ol_View-View.html#padding)\n */\n viewPadding?: MapPadding | undefined;\n\n /**\n * Behavior performed by the map when the view padding changes.\n *\n * - `none`: Do nothing.\n * - `preserve-center`: Ensures that the center point remains the same by animating the view.\n * - `preserve-extent`: Ensures that the extent remains the same by zooming.\n *\n * @default \"preserve-center\"\n */\n viewPaddingChangeBehavior?: \"none\" | \"preserve-center\" | \"preserve-extent\";\n\n children?: ReactNode;\n\n /**\n * Optional role property.\n *\n * This property is directly applied to the map's container div element.\n *\n * @default \"application\"\n */\n role?: string;\n\n /**\n * Optional aria-labelledby property.\n * Do not use together with aria-label.\n *\n * This property is directly applied to the map's container div element.\n */\n \"aria-labelledby\"?: string;\n\n /**\n * Optional aria-label property.\n * Do not use together with aria-label.\n *\n * This property is directly applied to the map's container div element.\n */\n \"aria-label\"?: string;\n}\n\n/**\n * Displays the map with the given id.\n *\n * There can only be at most one MapContainer for every map.\n *\n * @group UI Components and Hooks\n */\nexport function MapContainer(props: MapContainerProps) {\n const {\n viewPadding,\n viewPaddingChangeBehavior,\n children,\n role = \"application\",\n \"aria-label\": ariaLabel,\n \"aria-labelledby\": ariaLabelledBy\n } = props;\n const { containerProps } = useCommonComponentProps(\"map-container-root\", props);\n const mapContainer = useRef<HTMLDivElement>(null);\n const mapAnchorsHost = useRef<HTMLDivElement>(null);\n const map = useMapModelValue(props);\n\n const [ready, setReady] = useState(false);\n\n useEffect(() => {\n // Mount the map into the DOM\n if (mapContainer.current) {\n const resource = registerMapTarget(map, mapContainer.current);\n return () => resource?.destroy();\n }\n }, [map]);\n\n // Wait for mount to make sure that the map anchors host is available\n useEffect(() => {\n setReady(true);\n }, []);\n\n const styleProps = useMemo(() => {\n return {\n height: \"100%\",\n position: \"relative\",\n\n // set css variables according to view padding\n \"--map-padding-top\": `${viewPadding?.top ?? 0}px`,\n \"--map-padding-bottom\": `${viewPadding?.bottom ?? 0}px`,\n \"--map-padding-left\": `${viewPadding?.left ?? 0}px`,\n \"--map-padding-right\": `${viewPadding?.right ?? 0}px`\n };\n }, [viewPadding]);\n\n return (\n <chakra.div {...containerProps} css={styleProps}>\n {/* Used by open layers to mount the map. This node receives the keyboard focus when interacting with the map. */}\n <chakra.div\n className=\"map-container\"\n ref={mapContainer}\n role={role}\n aria-label={ariaLabel}\n aria-labelledby={ariaLabelledBy}\n h=\"100%\"\n w=\"100%\"\n tabIndex={0}\n />\n\n {/* Contains user widgets (map anchors and raw children). These are separate from the map so they don't interfere with mouse/keyboard events. */}\n <chakra.div ref={mapAnchorsHost} className=\"map-anchors\">\n {ready && map && (\n <MapContainerReady\n olMap={map.olMap}\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n mapAnchorsHost={mapAnchorsHost.current!}\n viewPadding={viewPadding}\n viewPaddingChangeBehavior={viewPaddingChangeBehavior}\n >\n {children}\n </MapContainerReady>\n )}\n </chakra.div>\n </chakra.div>\n );\n}\n\n/**\n * This inner component is rendered when the map has been loaded.\n *\n * It provides the map instance and additional properties down the component tree.\n */\nfunction MapContainerReady(\n props: { olMap: OlMap; mapAnchorsHost: HTMLElement } & Omit<\n MapContainerProps,\n \"mapId\" | \"map\" | \"className\"\n >\n): ReactNode {\n const {\n olMap,\n mapAnchorsHost,\n viewPadding: viewPaddingProp,\n viewPaddingChangeBehavior = \"preserve-center\",\n children\n } = props;\n\n const viewPadding = useMemo<Required<MapPadding>>(() => {\n return {\n left: viewPaddingProp?.left ?? 0,\n right: viewPaddingProp?.right ?? 0,\n top: viewPaddingProp?.top ?? 0,\n bottom: viewPaddingProp?.bottom ?? 0\n };\n }, [viewPaddingProp]);\n\n // Apply view padding\n useEffect(() => {\n const mapView = olMap?.getView();\n if (!olMap || !mapView) {\n return;\n }\n\n const oldCenter = mapView.getCenter();\n const oldPadding = fromOlPadding(mapView.padding);\n const oldExtent = extentIncludingPadding(olMap, oldPadding);\n\n mapView.padding = toOlPadding(viewPadding);\n switch (viewPaddingChangeBehavior) {\n case \"preserve-center\":\n mapView.animate({ center: oldCenter, duration: 300 });\n break;\n case \"preserve-extent\": {\n if (oldExtent) {\n mapView.animate({\n center: oldCenter,\n resolution: mapView.getResolutionForExtent(oldExtent),\n duration: 300\n });\n }\n break;\n }\n case \"none\":\n }\n }, [viewPadding, olMap, viewPaddingChangeBehavior]);\n\n const mapContext = useMemo((): MapContainerContextType => {\n return {\n mapAnchorsHost\n };\n }, [mapAnchorsHost]);\n return <MapContainerContextProvider value={mapContext}>{children}</MapContainerContextProvider>;\n}\n\nfunction registerMapTarget(mapModel: MapModel, target: HTMLDivElement): Resource | undefined {\n const mapId = mapModel.id;\n const olMap = mapModel.olMap;\n if (olMap.getTarget()) {\n LOG.error(\n `Failed to display the map: the map already has a target. There may be more than one <MapContainer />.`\n );\n return undefined;\n }\n\n LOG.isDebug() && LOG.debug(`Setting target of map '${mapId}':`, target);\n if (!(\"keyboardEventTarget_\" in olMap)) {\n throw new Error(\n \"Internal error: failed to override keyboard event target. The property is no longer present.\"\n );\n }\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n (olMap as any).keyboardEventTarget_ = target;\n olMap.setTarget(target);\n\n let unregistered = false;\n return {\n destroy() {\n if (!unregistered) {\n LOG.isDebug() && LOG.debug(`Removing target of map '${mapId}':`, target);\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n (olMap as any).keyboardEventTarget_ = undefined;\n olMap.setTarget(undefined);\n unregistered = true;\n }\n }\n };\n}\n\n/**\n * Returns the extent visible in the non-padded region of the map.\n */\nfunction extentIncludingPadding(map: OlMap, padding: Required<MapPadding>): Extent | undefined {\n const size = map.getSize();\n if (!size || size.length < 2) {\n return undefined;\n }\n\n const [width, height] = size as [number, number];\n const bottomLeft = map.getCoordinateFromPixel([padding.left, padding.bottom]);\n const topRight = map.getCoordinateFromPixel([\n Math.max(0, width - padding.right),\n Math.max(0, height - padding.top)\n ]);\n if (!bottomLeft || !topRight) {\n return undefined;\n }\n\n const [xmin, ymin] = bottomLeft;\n const [xmax, ymax] = topRight;\n return [xmin, ymin, xmax, ymax] as Extent;\n}\n\nfunction fromOlPadding(padding: number[] | undefined): Required<MapPadding> {\n // top, right, bottom, left\n return {\n top: padding?.[0] ?? 0,\n right: padding?.[1] ?? 0,\n bottom: padding?.[2] ?? 0,\n left: padding?.[3] ?? 0\n };\n}\n\nfunction toOlPadding(padding: Required<MapPadding>): number[] {\n // top, right, bottom, left\n const { top, right, bottom, left } = padding;\n return [top, right, bottom, left];\n}\n"],"names":[],"mappings":";;;;;;;;AAWA,MAAM,GAAA,GAAM,aAAa,kBAAkB,CAAA;AA4DpC,SAAS,aAAa,KAAA,EAA0B;AACnD,EAAA,MAAM;AAAA,IACF,WAAA;AAAA,IACA,yBAAA;AAAA,IACA,QAAA;AAAA,IACA,IAAA,GAAO,aAAA;AAAA,IACP,YAAA,EAAc,SAAA;AAAA,IACd,iBAAA,EAAmB;AAAA,GACvB,GAAI,KAAA;AACJ,EAAA,MAAM,EAAE,cAAA,EAAe,GAAI,uBAAA,CAAwB,sBAAsB,KAAK,CAAA;AAC9E,EAAA,MAAM,YAAA,GAAe,OAAuB,IAAI,CAAA;AAChD,EAAA,MAAM,cAAA,GAAiB,OAAuB,IAAI,CAAA;AAClD,EAAA,MAAM,GAAA,GAAM,iBAAiB,KAAK,CAAA;AAElC,EAAA,MAAM,CAAC,KAAA,EAAO,QAAQ,CAAA,GAAI,SAAS,KAAK,CAAA;AAExC,EAAA,SAAA,CAAU,MAAM;AAEZ,IAAA,IAAI,aAAa,OAAA,EAAS;AACtB,MAAA,MAAM,QAAA,GAAW,iBAAA,CAAkB,GAAA,EAAK,YAAA,CAAa,OAAO,CAAA;AAC5D,MAAA,OAAO,MAAM,UAAU,OAAA,EAAQ;AAAA,IACnC;AAAA,EACJ,CAAA,EAAG,CAAC,GAAG,CAAC,CAAA;AAGR,EAAA,SAAA,CAAU,MAAM;AACZ,IAAA,QAAA,CAAS,IAAI,CAAA;AAAA,EACjB,CAAA,EAAG,EAAE,CAAA;AAEL,EAAA,MAAM,UAAA,GAAa,QAAQ,MAAM;AAC7B,IAAA,OAAO;AAAA,MACH,MAAA,EAAQ,MAAA;AAAA,MACR,QAAA,EAAU,UAAA;AAAA;AAAA,MAGV,mBAAA,EAAqB,CAAA,EAAG,WAAA,EAAa,GAAA,IAAO,CAAC,CAAA,EAAA,CAAA;AAAA,MAC7C,sBAAA,EAAwB,CAAA,EAAG,WAAA,EAAa,MAAA,IAAU,CAAC,CAAA,EAAA,CAAA;AAAA,MACnD,oBAAA,EAAsB,CAAA,EAAG,WAAA,EAAa,IAAA,IAAQ,CAAC,CAAA,EAAA,CAAA;AAAA,MAC/C,qBAAA,EAAuB,CAAA,EAAG,WAAA,EAAa,KAAA,IAAS,CAAC,CAAA,EAAA;AAAA,KACrD;AAAA,EACJ,CAAA,EAAG,CAAC,WAAW,CAAC,CAAA;AAEhB,EAAA,4BACK,MAAA,CAAO,GAAA,EAAP,EAAY,GAAG,cAAA,EAAgB,KAAK,UAAA,EAEjC,QAAA,EAAA;AAAA,oBAAA,GAAA;AAAA,MAAC,MAAA,CAAO,GAAA;AAAA,MAAP;AAAA,QACG,SAAA,EAAU,eAAA;AAAA,QACV,GAAA,EAAK,YAAA;AAAA,QACL,IAAA;AAAA,QACA,YAAA,EAAY,SAAA;AAAA,QACZ,iBAAA,EAAiB,cAAA;AAAA,QACjB,CAAA,EAAE,MAAA;AAAA,QACF,CAAA,EAAE,MAAA;AAAA,QACF,QAAA,EAAU;AAAA;AAAA,KACd;AAAA,oBAGA,GAAA,CAAC,OAAO,GAAA,EAAP,EAAW,KAAK,cAAA,EAAgB,SAAA,EAAU,aAAA,EACtC,QAAA,EAAA,KAAA,IAAS,GAAA,oBACN,GAAA;AAAA,MAAC,iBAAA;AAAA,MAAA;AAAA,QACG,OAAO,GAAA,CAAI,KAAA;AAAA,QAEX,gBAAgB,cAAA,CAAe,OAAA;AAAA,QAC/B,WAAA;AAAA,QACA,yBAAA;AAAA,QAEC;AAAA;AAAA,KACL,EAER;AAAA,GAAA,EACJ,CAAA;AAER;AAOA,SAAS,kBACL,KAAA,EAIS;AACT,EAAA,MAAM;AAAA,IACF,KAAA;AAAA,IACA,cAAA;AAAA,IACA,WAAA,EAAa,eAAA;AAAA,IACb,yBAAA,GAA4B,iBAAA;AAAA,IAC5B;AAAA,GACJ,GAAI,KAAA;AAEJ,EAAA,MAAM,WAAA,GAAc,QAA8B,MAAM;AACpD,IAAA,OAAO;AAAA,MACH,IAAA,EAAM,iBAAiB,IAAA,IAAQ,CAAA;AAAA,MAC/B,KAAA,EAAO,iBAAiB,KAAA,IAAS,CAAA;AAAA,MACjC,GAAA,EAAK,iBAAiB,GAAA,IAAO,CAAA;AAAA,MAC7B,MAAA,EAAQ,iBAAiB,MAAA,IAAU;AAAA,KACvC;AAAA,EACJ,CAAA,EAAG,CAAC,eAAe,CAAC,CAAA;AAGpB,EAAA,SAAA,CAAU,MAAM;AACZ,IAAA,MAAM,OAAA,GAAU,OAAO,OAAA,EAAQ;AAC/B,IAAA,IAAI,CAAC,KAAA,IAAS,CAAC,OAAA,EAAS;AACpB,MAAA;AAAA,IACJ;AAEA,IAAA,MAAM,SAAA,GAAY,QAAQ,SAAA,EAAU;AACpC,IAAA,MAAM,UAAA,GAAa,aAAA,CAAc,OAAA,CAAQ,OAAO,CAAA;AAChD,IAAA,MAAM,SAAA,GAAY,sBAAA,CAAuB,KAAA,EAAO,UAAU,CAAA;AAE1D,IAAA,OAAA,CAAQ,OAAA,GAAU,YAAY,WAAW,CAAA;AACzC,IAAA,QAAQ,yBAAA;AAA2B,MAC/B,KAAK,iBAAA;AACD,QAAA,OAAA,CAAQ,QAAQ,EAAE,MAAA,EAAQ,SAAA,EAAW,QAAA,EAAU,KAAK,CAAA;AACpD,QAAA;AAAA,MACJ,KAAK,iBAAA,EAAmB;AACpB,QAAA,IAAI,SAAA,EAAW;AACX,UAAA,OAAA,CAAQ,OAAA,CAAQ;AAAA,YACZ,MAAA,EAAQ,SAAA;AAAA,YACR,UAAA,EAAY,OAAA,CAAQ,sBAAA,CAAuB,SAAS,CAAA;AAAA,YACpD,QAAA,EAAU;AAAA,WACb,CAAA;AAAA,QACL;AACA,QAAA;AAAA,MACJ;AACK;AACT,EACJ,CAAA,EAAG,CAAC,WAAA,EAAa,KAAA,EAAO,yBAAyB,CAAC,CAAA;AAElD,EAAA,MAAM,UAAA,GAAa,QAAQ,MAA+B;AACtD,IAAA,OAAO;AAAA,MACH;AAAA,KACJ;AAAA,EACJ,CAAA,EAAG,CAAC,cAAc,CAAC,CAAA;AACnB,EAAA,uBAAO,GAAA,CAAC,2BAAA,EAAA,EAA4B,KAAA,EAAO,UAAA,EAAa,QAAA,EAAS,CAAA;AACrE;AAEA,SAAS,iBAAA,CAAkB,UAAoB,MAAA,EAA8C;AACzF,EAAA,MAAM,QAAQ,QAAA,CAAS,EAAA;AACvB,EAAA,MAAM,QAAQ,QAAA,CAAS,KAAA;AACvB,EAAA,IAAI,KAAA,CAAM,WAAU,EAAG;AACnB,IAAA,GAAA,CAAI,KAAA;AAAA,MACA,CAAA,qGAAA;AAAA,KACJ;AACA,IAAA,OAAO,MAAA;AAAA,EACX;AAEA,EAAA,GAAA,CAAI,SAAQ,IAAK,GAAA,CAAI,MAAM,CAAA,uBAAA,EAA0B,KAAK,MAAM,MAAM,CAAA;AACtE,EAAA,IAAI,EAAE,0BAA0B,KAAA,CAAA,EAAQ;AACpC,IAAA,MAAM,IAAI,KAAA;AAAA,MACN;AAAA,KACJ;AAAA,EACJ;AAGA,EAAC,MAAc,oBAAA,GAAuB,MAAA;AACtC,EAAA,KAAA,CAAM,UAAU,MAAM,CAAA;AAEtB,EAAA,IAAI,YAAA,GAAe,KAAA;AACnB,EAAA,OAAO;AAAA,IACH,OAAA,GAAU;AACN,MAAA,IAAI,CAAC,YAAA,EAAc;AACf,QAAA,GAAA,CAAI,SAAQ,IAAK,GAAA,CAAI,MAAM,CAAA,wBAAA,EAA2B,KAAK,MAAM,MAAM,CAAA;AAEvE,QAAC,MAAc,oBAAA,GAAuB,MAAA;AACtC,QAAA,KAAA,CAAM,UAAU,MAAS,CAAA;AACzB,QAAA,YAAA,GAAe,IAAA;AAAA,MACnB;AAAA,IACJ;AAAA,GACJ;AACJ;AAKA,SAAS,sBAAA,CAAuB,KAAY,OAAA,EAAmD;AAC3F,EAAA,MAAM,IAAA,GAAO,IAAI,OAAA,EAAQ;AACzB,EAAA,IAAI,CAAC,IAAA,IAAQ,IAAA,CAAK,MAAA,GAAS,CAAA,EAAG;AAC1B,IAAA,OAAO,MAAA;AAAA,EACX;AAEA,EAAA,MAAM,CAAC,KAAA,EAAO,MAAM,CAAA,GAAI,IAAA;AACxB,EAAA,MAAM,UAAA,GAAa,IAAI,sBAAA,CAAuB,CAAC,QAAQ,IAAA,EAAM,OAAA,CAAQ,MAAM,CAAC,CAAA;AAC5E,EAAA,MAAM,QAAA,GAAW,IAAI,sBAAA,CAAuB;AAAA,IACxC,IAAA,CAAK,GAAA,CAAI,CAAA,EAAG,KAAA,GAAQ,QAAQ,KAAK,CAAA;AAAA,IACjC,IAAA,CAAK,GAAA,CAAI,CAAA,EAAG,MAAA,GAAS,QAAQ,GAAG;AAAA,GACnC,CAAA;AACD,EAAA,IAAI,CAAC,UAAA,IAAc,CAAC,QAAA,EAAU;AAC1B,IAAA,OAAO,MAAA;AAAA,EACX;AAEA,EAAA,MAAM,CAAC,IAAA,EAAM,IAAI,CAAA,GAAI,UAAA;AACrB,EAAA,MAAM,CAAC,IAAA,EAAM,IAAI,CAAA,GAAI,QAAA;AACrB,EAAA,OAAO,CAAC,IAAA,EAAM,IAAA,EAAM,IAAA,EAAM,IAAI,CAAA;AAClC;AAEA,SAAS,cAAc,OAAA,EAAqD;AAExE,EAAA,OAAO;AAAA,IACH,GAAA,EAAK,OAAA,GAAU,CAAC,CAAA,IAAK,CAAA;AAAA,IACrB,KAAA,EAAO,OAAA,GAAU,CAAC,CAAA,IAAK,CAAA;AAAA,IACvB,MAAA,EAAQ,OAAA,GAAU,CAAC,CAAA,IAAK,CAAA;AAAA,IACxB,IAAA,EAAM,OAAA,GAAU,CAAC,CAAA,IAAK;AAAA,GAC1B;AACJ;AAEA,SAAS,YAAY,OAAA,EAAyC;AAE1D,EAAA,MAAM,EAAE,GAAA,EAAK,KAAA,EAAO,MAAA,EAAQ,MAAK,GAAI,OAAA;AACrC,EAAA,OAAO,CAAC,GAAA,EAAK,KAAA,EAAO,MAAA,EAAQ,IAAI,CAAA;AACpC;;;;"}
1
+ {"version":3,"file":"MapContainer.js","sources":["MapContainer.tsx"],"sourcesContent":["// SPDX-FileCopyrightText: 2023-2025 Open Pioneer project (https://github.com/open-pioneer)\n// SPDX-License-Identifier: Apache-2.0\nimport { chakra } from \"@chakra-ui/react\";\nimport { Resource, createLogger } from \"@open-pioneer/core\";\nimport { CommonComponentProps, useCommonComponentProps } from \"@open-pioneer/react-utils\";\nimport type OlMap from \"ol/Map\";\nimport { Extent } from \"ol/extent\";\nimport { sourceId } from \"open-pioneer:source-info\";\nimport { ReactNode, useEffect, useMemo, useRef, useState } from \"react\";\nimport { MapModel, MapPadding } from \"../model/MapModel\";\nimport { MapContainerContextProvider, MapContainerContextType } from \"./MapContainerContext\";\nimport { MapModelProps, useMapModelValue } from \"./hooks/useMapModel\";\n\nconst LOG = createLogger(sourceId);\n\n/**\n * @group UI Components and Hooks\n */\nexport interface MapContainerProps extends CommonComponentProps, MapModelProps {\n /**\n * Sets the map's padding directly.\n * Do not use the view's padding property directly on the OL map.\n *\n * See: https://openlayers.org/en/latest/apidoc/module-ol_View-View.html#padding)\n */\n viewPadding?: MapPadding | undefined;\n\n /**\n * Behavior performed by the map when the view padding changes.\n *\n * - `none`: Do nothing.\n * - `preserve-center`: Ensures that the center point remains the same by animating the view.\n * - `preserve-extent`: Ensures that the extent remains the same by zooming.\n *\n * @default \"preserve-center\"\n */\n viewPaddingChangeBehavior?: \"none\" | \"preserve-center\" | \"preserve-extent\";\n\n children?: ReactNode;\n\n /**\n * Optional role property.\n *\n * This property is directly applied to the map's container div element.\n *\n * @default \"application\"\n */\n role?: string;\n\n /**\n * Optional aria-labelledby property.\n * Do not use together with aria-label.\n *\n * This property is directly applied to the map's container div element.\n */\n \"aria-labelledby\"?: string;\n\n /**\n * Optional aria-label property.\n * Do not use together with aria-label.\n *\n * This property is directly applied to the map's container div element.\n */\n \"aria-label\"?: string;\n}\n\n/**\n * Displays the map with the given id.\n *\n * There can only be at most one MapContainer for every map.\n *\n * @group UI Components and Hooks\n */\nexport function MapContainer(props: MapContainerProps) {\n const {\n viewPadding,\n viewPaddingChangeBehavior,\n children,\n role = \"application\",\n \"aria-label\": ariaLabel,\n \"aria-labelledby\": ariaLabelledBy\n } = props;\n const { containerProps } = useCommonComponentProps(\"map-container-root\", props);\n const mapContainer = useRef<HTMLDivElement>(null);\n const mapAnchorsHost = useRef<HTMLDivElement>(null);\n const map = useMapModelValue(props);\n\n const [ready, setReady] = useState(false);\n\n useEffect(() => {\n // Mount the map into the DOM\n if (mapContainer.current) {\n const resource = registerMapTarget(map, mapContainer.current);\n return () => resource?.destroy();\n }\n }, [map]);\n\n // Wait for mount to make sure that the map anchors host is available\n useEffect(() => {\n setReady(true);\n }, []);\n\n const styleProps = useMemo(() => {\n return {\n height: \"100%\",\n position: \"relative\",\n\n // set css variables according to view padding\n \"--map-padding-top\": `${viewPadding?.top ?? 0}px`,\n \"--map-padding-bottom\": `${viewPadding?.bottom ?? 0}px`,\n \"--map-padding-left\": `${viewPadding?.left ?? 0}px`,\n \"--map-padding-right\": `${viewPadding?.right ?? 0}px`\n };\n }, [viewPadding]);\n\n return (\n <chakra.div {...containerProps} css={styleProps}>\n {/* Used by open layers to mount the map. This node receives the keyboard focus when interacting with the map. */}\n <chakra.div\n className=\"map-container\"\n ref={mapContainer}\n role={role}\n aria-label={ariaLabel}\n aria-labelledby={ariaLabelledBy}\n h=\"100%\"\n w=\"100%\"\n tabIndex={0}\n />\n\n {/* Contains user widgets (map anchors and raw children). These are separate from the map so they don't interfere with mouse/keyboard events. */}\n <chakra.div ref={mapAnchorsHost} className=\"map-anchors\">\n {ready && map && (\n <MapContainerReady\n olMap={map.olMap}\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n mapAnchorsHost={mapAnchorsHost.current!}\n viewPadding={viewPadding}\n viewPaddingChangeBehavior={viewPaddingChangeBehavior}\n >\n {children}\n </MapContainerReady>\n )}\n </chakra.div>\n </chakra.div>\n );\n}\n\n/**\n * This inner component is rendered when the map has been loaded.\n *\n * It provides the map instance and additional properties down the component tree.\n */\nfunction MapContainerReady(\n props: { olMap: OlMap; mapAnchorsHost: HTMLElement } & Omit<\n MapContainerProps,\n \"mapId\" | \"map\" | \"className\"\n >\n): ReactNode {\n const {\n olMap,\n mapAnchorsHost,\n viewPadding: viewPaddingProp,\n viewPaddingChangeBehavior = \"preserve-center\",\n children\n } = props;\n\n const viewPadding = useMemo<Required<MapPadding>>(() => {\n return {\n left: viewPaddingProp?.left ?? 0,\n right: viewPaddingProp?.right ?? 0,\n top: viewPaddingProp?.top ?? 0,\n bottom: viewPaddingProp?.bottom ?? 0\n };\n }, [viewPaddingProp]);\n\n // Apply view padding\n useEffect(() => {\n const mapView = olMap?.getView();\n if (!olMap || !mapView) {\n return;\n }\n\n const oldCenter = mapView.getCenter();\n const oldPadding = fromOlPadding(mapView.padding);\n const oldExtent = extentIncludingPadding(olMap, oldPadding);\n\n mapView.padding = toOlPadding(viewPadding);\n switch (viewPaddingChangeBehavior) {\n case \"preserve-center\":\n mapView.animate({ center: oldCenter, duration: 300 });\n break;\n case \"preserve-extent\": {\n if (oldExtent) {\n mapView.animate({\n center: oldCenter,\n resolution: mapView.getResolutionForExtent(oldExtent),\n duration: 300\n });\n }\n break;\n }\n case \"none\":\n }\n }, [viewPadding, olMap, viewPaddingChangeBehavior]);\n\n const mapContext = useMemo((): MapContainerContextType => {\n return {\n mapAnchorsHost\n };\n }, [mapAnchorsHost]);\n return <MapContainerContextProvider value={mapContext}>{children}</MapContainerContextProvider>;\n}\n\nfunction registerMapTarget(mapModel: MapModel, target: HTMLDivElement): Resource | undefined {\n const mapId = mapModel.id;\n const olMap = mapModel.olMap;\n if (olMap.getTarget()) {\n LOG.error(\n `Failed to display the map: the map already has a target. There may be more than one <MapContainer />.`\n );\n return undefined;\n }\n\n LOG.isDebug() && LOG.debug(`Setting target of map '${mapId}':`, target);\n if (!(\"keyboardEventTarget_\" in olMap)) {\n throw new Error(\n \"Internal error: failed to override keyboard event target. The property is no longer present.\"\n );\n }\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n (olMap as any).keyboardEventTarget_ = target;\n olMap.setTarget(target);\n\n let unregistered = false;\n return {\n destroy() {\n if (!unregistered) {\n LOG.isDebug() && LOG.debug(`Removing target of map '${mapId}':`, target);\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n (olMap as any).keyboardEventTarget_ = undefined;\n olMap.setTarget(undefined);\n unregistered = true;\n }\n }\n };\n}\n\n/**\n * Returns the extent visible in the non-padded region of the map.\n */\nfunction extentIncludingPadding(map: OlMap, padding: Required<MapPadding>): Extent | undefined {\n const size = map.getSize();\n if (!size || size.length < 2) {\n return undefined;\n }\n\n const [width, height] = size as [number, number];\n const bottomLeft = map.getCoordinateFromPixel([padding.left, padding.bottom]);\n const topRight = map.getCoordinateFromPixel([\n Math.max(0, width - padding.right),\n Math.max(0, height - padding.top)\n ]);\n if (!bottomLeft || !topRight) {\n return undefined;\n }\n\n const [xmin, ymin] = bottomLeft;\n const [xmax, ymax] = topRight;\n return [xmin, ymin, xmax, ymax] as Extent;\n}\n\nfunction fromOlPadding(padding: number[] | undefined): Required<MapPadding> {\n // top, right, bottom, left\n return {\n top: padding?.[0] ?? 0,\n right: padding?.[1] ?? 0,\n bottom: padding?.[2] ?? 0,\n left: padding?.[3] ?? 0\n };\n}\n\nfunction toOlPadding(padding: Required<MapPadding>): number[] {\n // top, right, bottom, left\n const { top, right, bottom, left } = padding;\n return [top, right, bottom, left];\n}\n"],"names":[],"mappings":"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"}