@open-pioneer/map 0.8.0-dev.20241120115147 → 0.9.0-dev.20250217152428
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 +10 -2
- package/api/MapModel.d.ts +6 -2
- package/api/layers/WMSLayer.d.ts +7 -0
- package/api/layers/WMSLayer.js.map +1 -1
- package/api/layers/base.d.ts +3 -1
- package/api/layers/base.js.map +1 -1
- package/model/layers/WMSLayerImpl.js +5 -0
- package/model/layers/WMSLayerImpl.js.map +1 -1
- package/package.json +7 -7
- package/ui/MapContainer.js +7 -0
- package/ui/MapContainer.js.map +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,11 +1,17 @@
|
|
|
1
1
|
# @open-pioneer/map
|
|
2
2
|
|
|
3
|
-
## 0.
|
|
3
|
+
## 0.9.0-dev.20250217152428
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- 209eb8e: Added a configuration option to disable fetching of WMS service capabilities.
|
|
8
|
+
|
|
9
|
+
## 0.8.0
|
|
4
10
|
|
|
5
11
|
### Minor Changes
|
|
6
12
|
|
|
7
13
|
- b717121: Update from OL 9 to OL 10.
|
|
8
|
-
- e7978a8:
|
|
14
|
+
- e7978a8: **Breaking:** Remove most events from the map model and the layer interfaces.
|
|
9
15
|
All events that were merely used to synchronized state (e.g. `changed:title` etc.) have been removed.
|
|
10
16
|
|
|
11
17
|
The map model and related objects (layers, layer collections, etc.) are now based on the [Reactivity API](https://github.com/conterra/reactivity/blob/main/packages/reactivity-core/README.md).
|
|
@@ -131,6 +137,8 @@
|
|
|
131
137
|
|
|
132
138
|
### Patch Changes
|
|
133
139
|
|
|
140
|
+
- 7a5f1e1: Fix keyboard events from map anchors after update to OpenLayers 10.
|
|
141
|
+
- 49f0207: Update trails core packages to version 2.4.0
|
|
134
142
|
- b2127df: Improve documentation of layers in README
|
|
135
143
|
|
|
136
144
|
## 0.7.0
|
package/api/MapModel.d.ts
CHANGED
|
@@ -133,8 +133,12 @@ export interface MapModel extends EventSource<MapModelEvents> {
|
|
|
133
133
|
/**
|
|
134
134
|
* Returns the current scale of the map.
|
|
135
135
|
*
|
|
136
|
-
*
|
|
137
|
-
*
|
|
136
|
+
* The scale is a value derived from the current `center`, `resolution` and `projection` of the map.
|
|
137
|
+
* The scale will change when the map is zoomed in our out, but depending on the projection, it may also
|
|
138
|
+
* change when the map is _panned_.
|
|
139
|
+
*
|
|
140
|
+
* > NOTE: Technically, this is the _denominator_ of the current scale.
|
|
141
|
+
* > In order to display it, use a format like `1:${scale}`.
|
|
138
142
|
*/
|
|
139
143
|
readonly scale: number | undefined;
|
|
140
144
|
/**
|
package/api/layers/WMSLayer.d.ts
CHANGED
|
@@ -15,6 +15,13 @@ export interface WMSLayerConfig extends LayerConfig {
|
|
|
15
15
|
* the WMS Layer manages some of the OpenLayers source options itself.
|
|
16
16
|
*/
|
|
17
17
|
sourceOptions?: Partial<WMSSourceOptions>;
|
|
18
|
+
/**
|
|
19
|
+
* Whether to automatically fetch capabilities from the service when needed (default: `true`).
|
|
20
|
+
*
|
|
21
|
+
* Setting this to `false` can be useful as a performance optimization when capabilities are not really required by the application.
|
|
22
|
+
* Note that this will disable some features of the WMS layer: for example, the legend URL will not be available.
|
|
23
|
+
*/
|
|
24
|
+
fetchCapabilities?: boolean;
|
|
18
25
|
}
|
|
19
26
|
/**
|
|
20
27
|
* Configuration options to construct the sublayers of a WMS layer.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"WMSLayer.js","sources":["WMSLayer.ts"],"sourcesContent":["// SPDX-FileCopyrightText: 2023 Open Pioneer project (https://github.com/open-pioneer)\n// SPDX-License-Identifier: Apache-2.0\nimport type { Options as WMSSourceOptions } from \"ol/source/ImageWMS\";\nimport { WMSLayerImpl } from \"../../model/layers/WMSLayerImpl\";\nimport type {\n LayerBaseConfig,\n SublayersCollection,\n LayerConfig,\n LayerBaseType,\n SublayerBaseType\n} from \"./base\";\n\n/**\n * Configuration options to construct a WMS layer.\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/**\n * Configuration options to construct the sublayers of a WMS layer.\n */\nexport interface WMSSublayerConfig extends LayerBaseConfig {\n /**\n * The name of the WMS sublayer in the service's capabilities.\n * Not mandatory, e.g. for WMS group layer. See [WMS spec](https://www.ogc.org/standard/wms/).\n */\n name?: string;\n\n /** Configuration for nested sublayers. */\n sublayers?: WMSSublayerConfig[];\n}\n\n/** Represents a WMS layer. */\nexport interface WMSLayer extends LayerBaseType {\n readonly type: \"wms\";\n\n readonly sublayers: SublayersCollection<WMSSublayer>;\n readonly layers: undefined;\n\n /** The URL of the WMS service that was used during layer construction. */\n readonly url: string;\n}\n\n/** Represents a WMS sublayer */\nexport interface WMSSublayer extends SublayerBaseType {\n readonly type: \"wms-sublayer\";\n /**\n * The name of the WMS sublayer in the service's capabilities.\n *\n * Is optional as a WMS group layer in a WMS service does not need to have a name.\n */\n readonly name: string | undefined;\n}\n\n/**\n * Constructor for {@link WMSLayer}.\n */\nexport interface WMSLayerConstructor {\n prototype: WMSLayer;\n\n /** Creates a new {@link WMSLayer}. */\n new (config: WMSLayerConfig): WMSLayer;\n}\n\nexport const WMSLayer: WMSLayerConstructor = WMSLayerImpl;\n"],"names":[],"mappings":";;
|
|
1
|
+
{"version":3,"file":"WMSLayer.js","sources":["WMSLayer.ts"],"sourcesContent":["// SPDX-FileCopyrightText: 2023 Open Pioneer project (https://github.com/open-pioneer)\n// SPDX-License-Identifier: Apache-2.0\nimport type { Options as WMSSourceOptions } from \"ol/source/ImageWMS\";\nimport { WMSLayerImpl } from \"../../model/layers/WMSLayerImpl\";\nimport type {\n LayerBaseConfig,\n SublayersCollection,\n LayerConfig,\n LayerBaseType,\n SublayerBaseType\n} from \"./base\";\n\n/**\n * Configuration options to construct a WMS layer.\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\n/**\n * Configuration options to construct the sublayers of a WMS layer.\n */\nexport interface WMSSublayerConfig extends LayerBaseConfig {\n /**\n * The name of the WMS sublayer in the service's capabilities.\n * Not mandatory, e.g. for WMS group layer. See [WMS spec](https://www.ogc.org/standard/wms/).\n */\n name?: string;\n\n /** Configuration for nested sublayers. */\n sublayers?: WMSSublayerConfig[];\n}\n\n/** Represents a WMS layer. */\nexport interface WMSLayer extends LayerBaseType {\n readonly type: \"wms\";\n\n readonly sublayers: SublayersCollection<WMSSublayer>;\n readonly layers: undefined;\n\n /** The URL of the WMS service that was used during layer construction. */\n readonly url: string;\n}\n\n/** Represents a WMS sublayer */\nexport interface WMSSublayer extends SublayerBaseType {\n readonly type: \"wms-sublayer\";\n /**\n * The name of the WMS sublayer in the service's capabilities.\n *\n * Is optional as a WMS group layer in a WMS service does not need to have a name.\n */\n readonly name: string | undefined;\n}\n\n/**\n * Constructor for {@link WMSLayer}.\n */\nexport interface WMSLayerConstructor {\n prototype: WMSLayer;\n\n /** Creates a new {@link WMSLayer}. */\n new (config: WMSLayerConfig): WMSLayer;\n}\n\nexport const WMSLayer: WMSLayerConstructor = WMSLayerImpl;\n"],"names":[],"mappings":";;AAqFO,MAAM,QAAgC,GAAA;;;;"}
|
package/api/layers/base.d.ts
CHANGED
|
@@ -81,7 +81,9 @@ export interface AnyLayerBaseType<AdditionalEvents = {}> extends EventSource<Lay
|
|
|
81
81
|
*/
|
|
82
82
|
readonly visible: boolean;
|
|
83
83
|
/**
|
|
84
|
-
*
|
|
84
|
+
* Legend URL from the service capabilities, if available.
|
|
85
|
+
*
|
|
86
|
+
* Note: this property may be expanded upon in the future, e.g. to support more variants than just image URLs.
|
|
85
87
|
*/
|
|
86
88
|
readonly legend: string | undefined;
|
|
87
89
|
/**
|
package/api/layers/base.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"base.js","sources":["base.ts"],"sourcesContent":["// SPDX-FileCopyrightText: 2023 Open Pioneer project (https://github.com/open-pioneer)\n// SPDX-License-Identifier: Apache-2.0\nimport type { EventSource } from \"@open-pioneer/core\";\nimport type OlBaseLayer from \"ol/layer/Base\";\nimport type { MapModel } from \"../MapModel\";\nimport type { LayerRetrievalOptions } from \"../shared\";\nimport type { SimpleLayer } from \"./SimpleLayer\";\nimport type { WMSLayer, WMSSublayer } from \"./WMSLayer\";\nimport type { WMTSLayer } from \"./WMTSLayer\";\nimport type { GroupLayer, GroupLayerCollection } from \"./GroupLayer\";\n\n/** Events emitted by the {@link Layer} and other layer types. */\nexport interface LayerBaseEvents {\n \"destroy\": void;\n}\n\n/** The load state of a layer. */\nexport type LayerLoadState = \"not-loaded\" | \"loading\" | \"loaded\" | \"error\";\n\n/** Custom function to check the state of a layer and returning a \"loaded\" or \"error\". */\nexport type HealthCheckFunction = (layer: Layer) => Promise<\"loaded\" | \"error\">;\n\n/**\n * Configuration options supported by all layer types (layers and sublayers).\n */\nexport interface LayerBaseConfig {\n /**\n * The unique id of this layer.\n * Defaults to a generated id.\n */\n id?: string;\n\n /**\n * The human-readable title of this layer.\n */\n title: string;\n\n /**\n * The human-readable description of this layer.\n * Defaults to an empty string.\n */\n description?: string;\n\n /**\n * Whether this layer should initially be visible.\n * Defaults to `true`.\n */\n visible?: boolean;\n\n /**\n * Additional attributes for this layer.\n * These can be arbitrary values.\n */\n attributes?: Record<string | symbol, unknown>;\n}\n\n/**\n * Interface shared by all layer types (operational layers and sublayers).\n *\n * Instances of this interface cannot be constructed directly; use a real layer\n * class such as {@link SimpleLayer} instead.\n */\nexport interface AnyLayerBaseType<AdditionalEvents = {}>\n extends EventSource<LayerBaseEvents & AdditionalEvents> {\n /**\n * Identifies the type of this layer.\n */\n readonly type: AnyLayerTypes;\n\n /** The map this layer belongs to. */\n readonly map: MapModel;\n\n /**\n * The direct parent of this layer instance, used for sublayers or for layers in a group layer.\n *\n * The property shall be undefined if the layer is not a sublayer or member of a group layer.\n */\n readonly parent: AnyLayer | undefined;\n\n /**\n * The unique id of this layer within its map model.\n *\n * NOTE: layer ids may not be globally unique: layers that belong\n * to different map models may have the same id.\n */\n readonly id: string;\n\n /** The human-readable title of this layer. */\n readonly title: string;\n\n /** The human-readable description of this layer. May be empty. */\n readonly description: string;\n\n /**\n * Whether the layer is visible or not.\n *\n * NOTE: The model's visible state may do more than influence the raw OpenLayers's visibility property.\n * Future versions may completely remove invisible layers from the OpenLayer's map under some circumstances.\n */\n readonly visible: boolean;\n\n /**\n *
|
|
1
|
+
{"version":3,"file":"base.js","sources":["base.ts"],"sourcesContent":["// SPDX-FileCopyrightText: 2023 Open Pioneer project (https://github.com/open-pioneer)\n// SPDX-License-Identifier: Apache-2.0\nimport type { EventSource } from \"@open-pioneer/core\";\nimport type OlBaseLayer from \"ol/layer/Base\";\nimport type { MapModel } from \"../MapModel\";\nimport type { LayerRetrievalOptions } from \"../shared\";\nimport type { SimpleLayer } from \"./SimpleLayer\";\nimport type { WMSLayer, WMSSublayer } from \"./WMSLayer\";\nimport type { WMTSLayer } from \"./WMTSLayer\";\nimport type { GroupLayer, GroupLayerCollection } from \"./GroupLayer\";\n\n/** Events emitted by the {@link Layer} and other layer types. */\nexport interface LayerBaseEvents {\n \"destroy\": void;\n}\n\n/** The load state of a layer. */\nexport type LayerLoadState = \"not-loaded\" | \"loading\" | \"loaded\" | \"error\";\n\n/** Custom function to check the state of a layer and returning a \"loaded\" or \"error\". */\nexport type HealthCheckFunction = (layer: Layer) => Promise<\"loaded\" | \"error\">;\n\n/**\n * Configuration options supported by all layer types (layers and sublayers).\n */\nexport interface LayerBaseConfig {\n /**\n * The unique id of this layer.\n * Defaults to a generated id.\n */\n id?: string;\n\n /**\n * The human-readable title of this layer.\n */\n title: string;\n\n /**\n * The human-readable description of this layer.\n * Defaults to an empty string.\n */\n description?: string;\n\n /**\n * Whether this layer should initially be visible.\n * Defaults to `true`.\n */\n visible?: boolean;\n\n /**\n * Additional attributes for this layer.\n * These can be arbitrary values.\n */\n attributes?: Record<string | symbol, unknown>;\n}\n\n/**\n * Interface shared by all layer types (operational layers and sublayers).\n *\n * Instances of this interface cannot be constructed directly; use a real layer\n * class such as {@link SimpleLayer} instead.\n */\nexport interface AnyLayerBaseType<AdditionalEvents = {}>\n extends EventSource<LayerBaseEvents & AdditionalEvents> {\n /**\n * Identifies the type of this layer.\n */\n readonly type: AnyLayerTypes;\n\n /** The map this layer belongs to. */\n readonly map: MapModel;\n\n /**\n * The direct parent of this layer instance, used for sublayers or for layers in a group layer.\n *\n * The property shall be undefined if the layer is not a sublayer or member of a group layer.\n */\n readonly parent: AnyLayer | undefined;\n\n /**\n * The unique id of this layer within its map model.\n *\n * NOTE: layer ids may not be globally unique: layers that belong\n * to different map models may have the same id.\n */\n readonly id: string;\n\n /** The human-readable title of this layer. */\n readonly title: string;\n\n /** The human-readable description of this layer. May be empty. */\n readonly description: string;\n\n /**\n * Whether the layer is visible or not.\n *\n * NOTE: The model's visible state may do more than influence the raw OpenLayers's visibility property.\n * Future versions may completely remove invisible layers from the OpenLayer's map under some circumstances.\n */\n readonly visible: boolean;\n\n /**\n * Legend URL from the service capabilities, if available.\n *\n * Note: this property may be expanded upon in the future, e.g. to support more variants than just image URLs.\n */\n readonly legend: string | undefined;\n\n /**\n * The direct children of this layer.\n *\n * The children may either be a set of operational layers (e.g. for a group layer) or a set of sublayers, or `undefined`.\n *\n * See also {@link layers} and {@link sublayers}.\n */\n readonly children: ChildrenCollection<AnyLayer> | undefined;\n\n /**\n * If this layer is a group layer this property contains a collection of all layers that a members to the group.\n *\n * The property shall be `undefined` if it is not a group layer.\n *\n * The properties `layers` and `sublayers` are mutually exclusive.\n */\n readonly layers: GroupLayerCollection | undefined;\n\n /**\n * The collection of child sublayers for this layer. Sublayers are layers that cannot exist without an appropriate parent layer.\n *\n * Layers that can never have any sublayers may not have a `sublayers` collection.\n *\n * The properties `layers` and `sublayers` are mutually exclusive.\n */\n readonly sublayers: SublayersCollection | undefined;\n\n /**\n * Additional attributes associated with this layer.\n */\n readonly attributes: Readonly<Record<string | symbol, unknown>>;\n\n /**\n * Updates the title of this layer.\n */\n setTitle(newTitle: string): void;\n\n /**\n * Updates the description of this layer.\n */\n setDescription(newDescription: string): void;\n\n /**\n * Updates the visibility of this layer to the new value.\n *\n * NOTE: The visibility of base layers cannot be changed through this method.\n * Call {@link LayerCollection.activateBaseLayer} instead.\n */\n setVisible(newVisibility: boolean): void;\n\n /**\n * Updates the attributes of this layer.\n * Values in `newAttributes` are merged into the existing ones (i.e. via `Object.assign`).\n */\n updateAttributes(newAttributes: Record<string | symbol, unknown>): void;\n\n /**\n * Deletes the attribute of this layer.\n */\n deleteAttribute(deleteAttribute: string | symbol): void;\n}\n\n/**\n * Configuration options supported by all operational layer types.\n */\nexport interface LayerConfig extends LayerBaseConfig {\n /**\n * Whether this layer is a base layer or not.\n * Only one base layer can be active at a time.\n *\n * Defaults to `false`.\n */\n isBaseLayer?: boolean;\n\n /**\n * Optional property to check the availability of the layer.\n * It is possible to provide either a URL which indicates the state of the service (2xx response meaning \"ok\")\n * or a {@link HealthCheckFunction} performing a custom check and returning the state.\n */\n healthCheck?: string | HealthCheckFunction;\n}\n\n/**\n * Represents an operational layer in the map.\n *\n * Instances of this interface cannot be constructed directly; use a real layer\n * class such as {@link SimpleLayer} instead.\n */\nexport interface LayerBaseType<AdditionalEvents = {}> extends AnyLayerBaseType<AdditionalEvents> {\n /**\n * Identifies the type of this layer.\n */\n readonly type: LayerTypes;\n\n /**\n * The load state of a layer.\n */\n readonly loadState: LayerLoadState;\n\n /**\n * The raw OpenLayers layer.\n */\n readonly olLayer: OlBaseLayer;\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 readonly isBaseLayer: boolean;\n}\n\n/**\n * Represents a sublayer of another layer.\n */\nexport interface SublayerBaseType extends AnyLayerBaseType {\n /**\n * Identifies the type of this sublayer.\n */\n readonly type: SublayerTypes;\n\n /**\n * The direct parent of this layer instance.\n * This can either be the parent layer or another sublayer.\n */\n readonly parent: AnyLayer;\n\n /**\n * The parent layer that owns this sublayer.\n */\n readonly parentLayer: Layer;\n}\n\n/**\n * Contains the children of a layer.\n */\nexport interface ChildrenCollection<LayerType> {\n /**\n * Returns the items in this collection.\n */\n getItems(options?: LayerRetrievalOptions): LayerType[];\n}\n\n/**\n * Contains the sublayers that belong to a {@link Layer} or {@link Sublayer}.\n */\nexport interface SublayersCollection<SublayerType = Sublayer>\n extends ChildrenCollection<SublayerType> {\n /**\n * Returns the child sublayers in this collection.\n */\n getSublayers(options?: LayerRetrievalOptions): SublayerType[];\n}\n\n/**\n * Union type for all layers (extending {@link LayerBaseType})\n */\nexport type Layer = SimpleLayer | WMSLayer | WMTSLayer | GroupLayer;\nexport type LayerTypes = Layer[\"type\"];\n\n/**\n * Union type for all sublayers (extending {@link SublayerBaseType}\n */\nexport type Sublayer = WMSSublayer;\nexport type SublayerTypes = Sublayer[\"type\"];\n\n/**\n * Union for all types of layers\n */\nexport type AnyLayer = Layer | Sublayer;\nexport type AnyLayerTypes = AnyLayer[\"type\"];\n\n/**\n * Type guard for checking if the layer is a {@link Sublayer}.\n */\nexport function isSublayer(layer: AnyLayer): layer is Sublayer {\n return \"parentLayer\" in layer;\n}\n\n/**\n * Type guard for checking if the layer is a {@link Layer} (and not a {@link Sublayer}).\n */\nexport function isLayer(layer: AnyLayer): layer is Layer {\n return \"olLayer\" in layer;\n}\n"],"names":[],"mappings":"AA2RO,SAAS,WAAW,KAAoC,EAAA;AAC3D,EAAA,OAAO,aAAiB,IAAA,KAAA,CAAA;AAC5B,CAAA;AAKO,SAAS,QAAQ,KAAiC,EAAA;AACrD,EAAA,OAAO,SAAa,IAAA,KAAA,CAAA;AACxB;;;;"}
|
|
@@ -14,6 +14,7 @@ class WMSLayerImpl extends AbstractLayer {
|
|
|
14
14
|
#sublayers;
|
|
15
15
|
#layer;
|
|
16
16
|
#source;
|
|
17
|
+
#fetchCapabilities;
|
|
17
18
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
18
19
|
#capabilities;
|
|
19
20
|
#abortController = new AbortController();
|
|
@@ -39,6 +40,7 @@ class WMSLayerImpl extends AbstractLayer {
|
|
|
39
40
|
}
|
|
40
41
|
});
|
|
41
42
|
this.#url = config.url;
|
|
43
|
+
this.#fetchCapabilities = config.fetchCapabilities ?? true;
|
|
42
44
|
this.#source = source;
|
|
43
45
|
this.#layer = layer;
|
|
44
46
|
this.#sublayers = new SublayersCollectionImpl(constructSublayers(config.sublayers));
|
|
@@ -97,6 +99,9 @@ class WMSLayerImpl extends AbstractLayer {
|
|
|
97
99
|
}
|
|
98
100
|
}
|
|
99
101
|
};
|
|
102
|
+
if (!this.#fetchCapabilities) {
|
|
103
|
+
return;
|
|
104
|
+
}
|
|
100
105
|
this.#fetchWMSCapabilities().then((result) => {
|
|
101
106
|
batch(() => {
|
|
102
107
|
const parser = new WMSCapabilities();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"WMSLayerImpl.js","sources":["WMSLayerImpl.ts"],"sourcesContent":["// SPDX-FileCopyrightText: 2023 Open Pioneer project (https://github.com/open-pioneer)\n// SPDX-License-Identifier: Apache-2.0\nimport {\n batch,\n computed,\n Reactive,\n reactive,\n ReadonlyReactive,\n watch\n} from \"@conterra/reactivity-core\";\nimport { createLogger, destroyResource, isAbortError, Resource } from \"@open-pioneer/core\";\nimport { ImageWrapper } from \"ol\";\nimport WMSCapabilities from \"ol/format/WMSCapabilities\";\nimport ImageLayer from \"ol/layer/Image\";\nimport type ImageSource from \"ol/source/Image\";\nimport ImageWMS from \"ol/source/ImageWMS\";\nimport { WMSLayer, WMSLayerConfig, WMSSublayer, WMSSublayerConfig } from \"../../api\";\nimport { fetchCapabilities } from \"../../util/capabilities-utils\";\nimport { AbstractLayer } from \"../AbstractLayer\";\nimport { AbstractLayerBase } from \"../AbstractLayerBase\";\nimport { MapModelImpl } from \"../MapModelImpl\";\nimport { SublayersCollectionImpl } from \"../SublayersCollectionImpl\";\n\nconst LOG = createLogger(\"map:WMSLayer\");\n\nexport class WMSLayerImpl extends AbstractLayer implements WMSLayer {\n #url: string;\n #sublayers: SublayersCollectionImpl<WMSSublayerImpl>;\n #layer: ImageLayer<ImageSource>;\n #source: ImageWMS;\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n #capabilities: Record<string, any> | undefined;\n readonly #abortController = new AbortController();\n\n #visibleSublayers: ReadonlyReactive<string[]>;\n #sublayersWatch: Resource | undefined;\n\n constructor(config: WMSLayerConfig) {\n const layer = new ImageLayer();\n super({\n ...config,\n olLayer: layer\n });\n const source = new ImageWMS({\n ...config.sourceOptions,\n url: config.url,\n params: {\n ...config.sourceOptions?.params\n },\n // Use http service to load tiles; needed for authentication etc.\n imageLoadFunction: (wrapper, url) => {\n return this.#loadImage(wrapper, url).catch((error) => {\n LOG.error(`Failed to load tile at '${url}'`, error);\n });\n }\n });\n this.#url = config.url;\n this.#source = source;\n this.#layer = layer;\n this.#sublayers = new SublayersCollectionImpl(constructSublayers(config.sublayers));\n this.#visibleSublayers = computed(() => this.#getVisibleLayerNames(), {\n equal(a, b) {\n return a.length === b.length && a.every((v, i) => v === b[i]);\n }\n });\n\n this.#sublayersWatch = watch(\n () => [this.#visibleSublayers.value],\n ([layers]) => {\n this.#updateLayersParam(layers);\n },\n {\n immediate: true\n }\n );\n }\n\n destroy() {\n this.#abortController.abort();\n this.#sublayersWatch = destroyResource(this.#sublayersWatch);\n super.destroy();\n }\n\n get type() {\n return \"wms\" as const;\n }\n\n get legend() {\n return undefined;\n }\n\n get url(): string {\n return this.#url;\n }\n\n get layers(): undefined {\n return undefined;\n }\n\n get sublayers(): SublayersCollectionImpl<WMSSublayerImpl> {\n return this.#sublayers;\n }\n\n get capabilities() {\n return this.#capabilities;\n }\n\n __attachToMap(map: MapModelImpl): void {\n super.__attachToMap(map);\n for (const sublayer of this.#sublayers.getSublayers()) {\n sublayer.__attach(map, this, this);\n }\n\n /** Find all leaf nodes representing a layer in the structure */\n const getNestedSublayer = (sublayers: WMSSublayerImpl[], layers: WMSSublayerImpl[]) => {\n for (const sublayer of sublayers) {\n const nested = sublayer.sublayers.getSublayers();\n if (nested.length) {\n getNestedSublayer(nested, layers);\n } else {\n if (sublayer.name) {\n layers.push(sublayer);\n }\n }\n }\n };\n\n this.#fetchWMSCapabilities()\n .then((result: string) => {\n batch(() => {\n const parser = new WMSCapabilities();\n const capabilities = parser.read(result);\n this.#capabilities = capabilities;\n\n const layers: WMSSublayerImpl[] = [];\n getNestedSublayer(this.#sublayers.getSublayers(), layers);\n\n for (const layer of layers) {\n const legendUrl = getWMSLegendUrl(capabilities, layer.name!);\n layer.__setLegend(legendUrl);\n }\n });\n })\n .catch((error) => {\n if (isAbortError(error)) {\n LOG.debug(`Layer ${this.id} has been destroyed before fetching capabilities`);\n return;\n }\n LOG.error(`Failed to fetch WMS capabilities for layer ${this.id}`, error);\n });\n }\n\n /**\n * Gathers the visibility of _all_ sublayers and assembles the 'layers' WMS parameter.\n * The parameters are then applied to the WMS source.\n */\n #updateLayersParam(layers: string[]) {\n this.#source.updateParams({\n \"LAYERS\": layers\n });\n\n // only set source if there are visible sublayers, otherwise\n // we send an invalid http request\n const source = layers.length === 0 ? null : this.#source;\n if (this.#layer.getSource() !== source) {\n this.#layer.setSource(source);\n }\n }\n\n #getVisibleLayerNames() {\n const layers: string[] = [];\n const visitSublayer = (sublayer: WMSSublayerImpl) => {\n if (!sublayer.visible) {\n return;\n }\n\n const nestedSublayers = sublayer.sublayers.__getRawSublayers();\n if (nestedSublayers.length) {\n for (const nestedSublayer of nestedSublayers) {\n visitSublayer(nestedSublayer);\n }\n } else {\n /**\n * Push sublayer only, if layer name is not an empty string | undefined | ...\n */\n if (sublayer.name) {\n layers.push(sublayer.name);\n }\n }\n };\n\n for (const sublayer of this.sublayers.__getRawSublayers()) {\n visitSublayer(sublayer);\n }\n return layers;\n }\n\n async #fetchWMSCapabilities(): Promise<string> {\n const httpService = this.map.__sharedDependencies.httpService;\n const url = `${this.#url}?LANGUAGE=ger&SERVICE=WMS&REQUEST=GetCapabilities`;\n return fetchCapabilities(url, httpService, this.#abortController.signal);\n }\n\n async #loadImage(imageWrapper: ImageWrapper, imageUrl: string): Promise<void> {\n const httpService = this.map.__sharedDependencies.httpService;\n const image = imageWrapper.getImage() as HTMLImageElement;\n\n const response = await httpService.fetch(imageUrl);\n if (!response.ok) {\n throw new Error(`Request failed with status ${response.status}.`);\n }\n\n const blob = await response.blob();\n const objectUrl = URL.createObjectURL(blob);\n const finish = () => {\n // Cleanup object URL after load to prevent memory leaks.\n // https://stackoverflow.com/questions/62473876/openlayers-6-settileloadfunction-documented-example-uses-url-createobjecturld\n URL.revokeObjectURL(objectUrl);\n image.removeEventListener(\"load\", finish);\n image.removeEventListener(\"error\", finish);\n };\n\n image.addEventListener(\"load\", finish);\n image.addEventListener(\"error\", finish);\n image.src = objectUrl;\n }\n}\n\nclass WMSSublayerImpl extends AbstractLayerBase implements WMSSublayer {\n #parent: WMSSublayerImpl | WMSLayerImpl | undefined;\n #parentLayer: WMSLayerImpl | undefined;\n #name: string | undefined;\n #legend = reactive<string | undefined>();\n #sublayers: SublayersCollectionImpl<WMSSublayerImpl>;\n #visible: Reactive<boolean>;\n\n constructor(config: WMSSublayerConfig) {\n super(config);\n this.#name = config.name;\n this.#visible = reactive(config.visible ?? true);\n this.#sublayers = new SublayersCollectionImpl(constructSublayers(config.sublayers));\n }\n\n get type() {\n return \"wms-sublayer\" as const;\n }\n\n get name(): string | undefined {\n return this.#name;\n }\n\n get layers(): undefined {\n return undefined;\n }\n\n get sublayers(): SublayersCollectionImpl<WMSSublayerImpl> {\n return this.#sublayers;\n }\n\n get parent(): WMSSublayerImpl | WMSLayerImpl {\n const parent = this.#parent;\n if (!parent) {\n throw new Error(`WMS sublayer ${this.id} has not been attached to its parent yet.`);\n }\n return parent;\n }\n\n get parentLayer(): WMSLayerImpl {\n const parentLayer = this.#parentLayer;\n if (!parentLayer) {\n throw new Error(`WMS sublayer ${this.id} has not been attached to its parent yet.`);\n }\n return parentLayer;\n }\n\n get legend(): string | undefined {\n return this.#legend.value;\n }\n\n get visible(): boolean {\n return this.#visible.value;\n }\n\n /**\n * Called by the parent layer when it is attached to the map to attach all sublayers.\n */\n __attach(\n map: MapModelImpl,\n parentLayer: WMSLayerImpl,\n parent: WMSLayerImpl | WMSSublayerImpl\n ): void {\n super.__attachToMap(map);\n if (this.#parent) {\n throw new Error(\n `WMS sublayer '${this.id}' has already been attached to parent '${this.#parent.id}'`\n );\n }\n this.#parent = parent;\n if (this.#parentLayer) {\n throw new Error(\n `WMS sublayer '${this.id}' has already been attached to parent layer '${this.#parentLayer.id}'`\n );\n }\n this.#parentLayer = parentLayer;\n\n // Recurse into nested sublayers\n for (const sublayer of this.sublayers.__getRawSublayers()) {\n sublayer.__attach(map, parentLayer, this);\n }\n }\n\n /**\n * Called by the parent layer to update the legend on load.\n */\n __setLegend(legendUrl: string | undefined) {\n this.#legend.value = legendUrl;\n }\n\n setVisible(newVisibility: boolean): void {\n this.#visible.value = newVisibility;\n }\n}\n\nfunction constructSublayers(sublayerConfigs: WMSSublayerConfig[] = []): WMSSublayerImpl[] {\n const sublayers: WMSSublayerImpl[] = [];\n try {\n for (const sublayerConfig of sublayerConfigs) {\n sublayers.push(new WMSSublayerImpl(sublayerConfig));\n }\n return sublayers;\n } catch (e) {\n // Ensure previous sublayers are destroyed if a single constructor throws\n while (sublayers.length) {\n const layer = sublayers.pop()!;\n layer?.destroy();\n }\n throw new Error(\"Failed to construct sublayers.\", { cause: e });\n }\n}\n\n/** extract the legend url from the service capabilities */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport function getWMSLegendUrl(capabilities: Record<string, any>, layerName: string) {\n const capabilitiesContent = capabilities?.Capability;\n const rootLayerCapabilities = capabilitiesContent?.Layer;\n let url: string | undefined = undefined;\n\n /** Recurse search for the currrent layer within the parsed capabilities service*/\n //eslint-disable-next-line @typescript-eslint/no-explicit-any\n const searchNestedLayer = (layer: Record<string, any>[]) => {\n for (const currentLayer of layer) {\n // spec. if, a layer has a <Name>, then it is a map layer\n if (currentLayer?.Name === layerName) {\n const activeLayer = currentLayer;\n const styles = activeLayer.Style;\n if (!styles || !styles.length) {\n LOG.debug(\"No style in WMS layer capabilities - giving up.\");\n return;\n }\n // by parsing of the service capabilities, every child inherits the parent's legend\n // theorfore, extract the legendURL from the first style object in the array (its own legend)\n const activeStyle = styles[0];\n url = activeStyle.LegendURL?.[0]?.OnlineResource;\n } else if (currentLayer.Layer) {\n searchNestedLayer(currentLayer.Layer);\n }\n }\n };\n if (rootLayerCapabilities) {\n searchNestedLayer(rootLayerCapabilities.Layer);\n }\n return url;\n}\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"WMSLayerImpl.js","sources":["WMSLayerImpl.ts"],"sourcesContent":["// SPDX-FileCopyrightText: 2023 Open Pioneer project (https://github.com/open-pioneer)\n// SPDX-License-Identifier: Apache-2.0\nimport {\n batch,\n computed,\n Reactive,\n reactive,\n ReadonlyReactive,\n watch\n} from \"@conterra/reactivity-core\";\nimport { createLogger, destroyResource, isAbortError, Resource } from \"@open-pioneer/core\";\nimport { ImageWrapper } from \"ol\";\nimport WMSCapabilities from \"ol/format/WMSCapabilities\";\nimport ImageLayer from \"ol/layer/Image\";\nimport type ImageSource from \"ol/source/Image\";\nimport ImageWMS from \"ol/source/ImageWMS\";\nimport { WMSLayer, WMSLayerConfig, WMSSublayer, WMSSublayerConfig } from \"../../api\";\nimport { fetchCapabilities } from \"../../util/capabilities-utils\";\nimport { AbstractLayer } from \"../AbstractLayer\";\nimport { AbstractLayerBase } from \"../AbstractLayerBase\";\nimport { MapModelImpl } from \"../MapModelImpl\";\nimport { SublayersCollectionImpl } from \"../SublayersCollectionImpl\";\n\nconst LOG = createLogger(\"map:WMSLayer\");\n\nexport class WMSLayerImpl extends AbstractLayer implements WMSLayer {\n #url: string;\n #sublayers: SublayersCollectionImpl<WMSSublayerImpl>;\n #layer: ImageLayer<ImageSource>;\n #source: ImageWMS;\n #fetchCapabilities: boolean;\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n #capabilities: Record<string, any> | undefined;\n readonly #abortController = new AbortController();\n\n #visibleSublayers: ReadonlyReactive<string[]>;\n #sublayersWatch: Resource | undefined;\n\n constructor(config: WMSLayerConfig) {\n const layer = new ImageLayer();\n super({\n ...config,\n olLayer: layer\n });\n const source = new ImageWMS({\n ...config.sourceOptions,\n url: config.url,\n params: {\n ...config.sourceOptions?.params\n },\n // Use http service to load tiles; needed for authentication etc.\n imageLoadFunction: (wrapper, url) => {\n return this.#loadImage(wrapper, url).catch((error) => {\n LOG.error(`Failed to load tile at '${url}'`, error);\n });\n }\n });\n this.#url = config.url;\n this.#fetchCapabilities = config.fetchCapabilities ?? true;\n this.#source = source;\n this.#layer = layer;\n this.#sublayers = new SublayersCollectionImpl(constructSublayers(config.sublayers));\n this.#visibleSublayers = computed(() => this.#getVisibleLayerNames(), {\n equal(a, b) {\n return a.length === b.length && a.every((v, i) => v === b[i]);\n }\n });\n\n this.#sublayersWatch = watch(\n () => [this.#visibleSublayers.value],\n ([layers]) => {\n this.#updateLayersParam(layers);\n },\n {\n immediate: true\n }\n );\n }\n\n destroy() {\n this.#abortController.abort();\n this.#sublayersWatch = destroyResource(this.#sublayersWatch);\n super.destroy();\n }\n\n get type() {\n return \"wms\" as const;\n }\n\n get legend() {\n return undefined;\n }\n\n get url(): string {\n return this.#url;\n }\n\n get layers(): undefined {\n return undefined;\n }\n\n get sublayers(): SublayersCollectionImpl<WMSSublayerImpl> {\n return this.#sublayers;\n }\n\n get capabilities() {\n return this.#capabilities;\n }\n\n __attachToMap(map: MapModelImpl): void {\n super.__attachToMap(map);\n for (const sublayer of this.#sublayers.getSublayers()) {\n sublayer.__attach(map, this, this);\n }\n\n /** Find all leaf nodes representing a layer in the structure */\n const getNestedSublayer = (sublayers: WMSSublayerImpl[], layers: WMSSublayerImpl[]) => {\n for (const sublayer of sublayers) {\n const nested = sublayer.sublayers.getSublayers();\n if (nested.length) {\n getNestedSublayer(nested, layers);\n } else {\n if (sublayer.name) {\n layers.push(sublayer);\n }\n }\n }\n };\n\n if (!this.#fetchCapabilities) {\n return;\n }\n\n this.#fetchWMSCapabilities()\n .then((result: string) => {\n batch(() => {\n const parser = new WMSCapabilities();\n const capabilities = parser.read(result);\n this.#capabilities = capabilities;\n\n const layers: WMSSublayerImpl[] = [];\n getNestedSublayer(this.#sublayers.getSublayers(), layers);\n\n for (const layer of layers) {\n const legendUrl = getWMSLegendUrl(capabilities, layer.name!);\n layer.__setLegend(legendUrl);\n }\n });\n })\n .catch((error) => {\n if (isAbortError(error)) {\n LOG.debug(`Layer ${this.id} has been destroyed before fetching capabilities`);\n return;\n }\n LOG.error(`Failed to fetch WMS capabilities for layer ${this.id}`, error);\n });\n }\n\n /**\n * Gathers the visibility of _all_ sublayers and assembles the 'layers' WMS parameter.\n * The parameters are then applied to the WMS source.\n */\n #updateLayersParam(layers: string[]) {\n this.#source.updateParams({\n \"LAYERS\": layers\n });\n\n // only set source if there are visible sublayers, otherwise\n // we send an invalid http request\n const source = layers.length === 0 ? null : this.#source;\n if (this.#layer.getSource() !== source) {\n this.#layer.setSource(source);\n }\n }\n\n #getVisibleLayerNames() {\n const layers: string[] = [];\n const visitSublayer = (sublayer: WMSSublayerImpl) => {\n if (!sublayer.visible) {\n return;\n }\n\n const nestedSublayers = sublayer.sublayers.__getRawSublayers();\n if (nestedSublayers.length) {\n for (const nestedSublayer of nestedSublayers) {\n visitSublayer(nestedSublayer);\n }\n } else {\n /**\n * Push sublayer only, if layer name is not an empty string | undefined | ...\n */\n if (sublayer.name) {\n layers.push(sublayer.name);\n }\n }\n };\n\n for (const sublayer of this.sublayers.__getRawSublayers()) {\n visitSublayer(sublayer);\n }\n return layers;\n }\n\n async #fetchWMSCapabilities(): Promise<string> {\n const httpService = this.map.__sharedDependencies.httpService;\n const url = `${this.#url}?LANGUAGE=ger&SERVICE=WMS&REQUEST=GetCapabilities`;\n return fetchCapabilities(url, httpService, this.#abortController.signal);\n }\n\n async #loadImage(imageWrapper: ImageWrapper, imageUrl: string): Promise<void> {\n const httpService = this.map.__sharedDependencies.httpService;\n const image = imageWrapper.getImage() as HTMLImageElement;\n\n const response = await httpService.fetch(imageUrl);\n if (!response.ok) {\n throw new Error(`Request failed with status ${response.status}.`);\n }\n\n const blob = await response.blob();\n const objectUrl = URL.createObjectURL(blob);\n const finish = () => {\n // Cleanup object URL after load to prevent memory leaks.\n // https://stackoverflow.com/questions/62473876/openlayers-6-settileloadfunction-documented-example-uses-url-createobjecturld\n URL.revokeObjectURL(objectUrl);\n image.removeEventListener(\"load\", finish);\n image.removeEventListener(\"error\", finish);\n };\n\n image.addEventListener(\"load\", finish);\n image.addEventListener(\"error\", finish);\n image.src = objectUrl;\n }\n}\n\nclass WMSSublayerImpl extends AbstractLayerBase implements WMSSublayer {\n #parent: WMSSublayerImpl | WMSLayerImpl | undefined;\n #parentLayer: WMSLayerImpl | undefined;\n #name: string | undefined;\n #legend = reactive<string | undefined>();\n #sublayers: SublayersCollectionImpl<WMSSublayerImpl>;\n #visible: Reactive<boolean>;\n\n constructor(config: WMSSublayerConfig) {\n super(config);\n this.#name = config.name;\n this.#visible = reactive(config.visible ?? true);\n this.#sublayers = new SublayersCollectionImpl(constructSublayers(config.sublayers));\n }\n\n get type() {\n return \"wms-sublayer\" as const;\n }\n\n get name(): string | undefined {\n return this.#name;\n }\n\n get layers(): undefined {\n return undefined;\n }\n\n get sublayers(): SublayersCollectionImpl<WMSSublayerImpl> {\n return this.#sublayers;\n }\n\n get parent(): WMSSublayerImpl | WMSLayerImpl {\n const parent = this.#parent;\n if (!parent) {\n throw new Error(`WMS sublayer ${this.id} has not been attached to its parent yet.`);\n }\n return parent;\n }\n\n get parentLayer(): WMSLayerImpl {\n const parentLayer = this.#parentLayer;\n if (!parentLayer) {\n throw new Error(`WMS sublayer ${this.id} has not been attached to its parent yet.`);\n }\n return parentLayer;\n }\n\n get legend(): string | undefined {\n return this.#legend.value;\n }\n\n get visible(): boolean {\n return this.#visible.value;\n }\n\n /**\n * Called by the parent layer when it is attached to the map to attach all sublayers.\n */\n __attach(\n map: MapModelImpl,\n parentLayer: WMSLayerImpl,\n parent: WMSLayerImpl | WMSSublayerImpl\n ): void {\n super.__attachToMap(map);\n if (this.#parent) {\n throw new Error(\n `WMS sublayer '${this.id}' has already been attached to parent '${this.#parent.id}'`\n );\n }\n this.#parent = parent;\n if (this.#parentLayer) {\n throw new Error(\n `WMS sublayer '${this.id}' has already been attached to parent layer '${this.#parentLayer.id}'`\n );\n }\n this.#parentLayer = parentLayer;\n\n // Recurse into nested sublayers\n for (const sublayer of this.sublayers.__getRawSublayers()) {\n sublayer.__attach(map, parentLayer, this);\n }\n }\n\n /**\n * Called by the parent layer to update the legend on load.\n */\n __setLegend(legendUrl: string | undefined) {\n this.#legend.value = legendUrl;\n }\n\n setVisible(newVisibility: boolean): void {\n this.#visible.value = newVisibility;\n }\n}\n\nfunction constructSublayers(sublayerConfigs: WMSSublayerConfig[] = []): WMSSublayerImpl[] {\n const sublayers: WMSSublayerImpl[] = [];\n try {\n for (const sublayerConfig of sublayerConfigs) {\n sublayers.push(new WMSSublayerImpl(sublayerConfig));\n }\n return sublayers;\n } catch (e) {\n // Ensure previous sublayers are destroyed if a single constructor throws\n while (sublayers.length) {\n const layer = sublayers.pop()!;\n layer?.destroy();\n }\n throw new Error(\"Failed to construct sublayers.\", { cause: e });\n }\n}\n\n/** extract the legend url from the service capabilities */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport function getWMSLegendUrl(capabilities: Record<string, any>, layerName: string) {\n const capabilitiesContent = capabilities?.Capability;\n const rootLayerCapabilities = capabilitiesContent?.Layer;\n let url: string | undefined = undefined;\n\n /** Recurse search for the currrent layer within the parsed capabilities service*/\n //eslint-disable-next-line @typescript-eslint/no-explicit-any\n const searchNestedLayer = (layer: Record<string, any>[]) => {\n for (const currentLayer of layer) {\n // spec. if, a layer has a <Name>, then it is a map layer\n if (currentLayer?.Name === layerName) {\n const activeLayer = currentLayer;\n const styles = activeLayer.Style;\n if (!styles || !styles.length) {\n LOG.debug(\"No style in WMS layer capabilities - giving up.\");\n return;\n }\n // by parsing of the service capabilities, every child inherits the parent's legend\n // theorfore, extract the legendURL from the first style object in the array (its own legend)\n const activeStyle = styles[0];\n url = activeStyle.LegendURL?.[0]?.OnlineResource;\n } else if (currentLayer.Layer) {\n searchNestedLayer(currentLayer.Layer);\n }\n }\n };\n if (rootLayerCapabilities) {\n searchNestedLayer(rootLayerCapabilities.Layer);\n }\n return url;\n}\n"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"type": "module",
|
|
3
3
|
"name": "@open-pioneer/map",
|
|
4
|
-
"version": "0.
|
|
4
|
+
"version": "0.9.0-dev.20250217152428",
|
|
5
5
|
"description": "This package integrates OpenLayers maps into an open pioneer trails application.",
|
|
6
6
|
"keywords": [
|
|
7
7
|
"open-pioneer-trails"
|
|
@@ -14,13 +14,13 @@
|
|
|
14
14
|
"directory": "src/packages/map"
|
|
15
15
|
},
|
|
16
16
|
"dependencies": {
|
|
17
|
-
"@open-pioneer/chakra-integration": "^2.4.0
|
|
18
|
-
"@open-pioneer/core": "^2.4.0
|
|
19
|
-
"@open-pioneer/http": "^2.4.0
|
|
20
|
-
"@open-pioneer/react-utils": "^2.4.0
|
|
21
|
-
"@open-pioneer/runtime": "^2.4.0
|
|
17
|
+
"@open-pioneer/chakra-integration": "^2.4.0",
|
|
18
|
+
"@open-pioneer/core": "^2.4.0",
|
|
19
|
+
"@open-pioneer/http": "^2.4.0",
|
|
20
|
+
"@open-pioneer/react-utils": "^2.4.0",
|
|
21
|
+
"@open-pioneer/runtime": "^2.4.0",
|
|
22
22
|
"@types/proj4": "^2.5.2",
|
|
23
|
-
"ol": "^10.
|
|
23
|
+
"ol": "^10.3.0",
|
|
24
24
|
"proj4": "^2.12.1",
|
|
25
25
|
"react": "^18.3.1",
|
|
26
26
|
"react-dom": "^18.3.1",
|
package/ui/MapContainer.js
CHANGED
|
@@ -144,12 +144,19 @@ function registerMapTarget(mapModel, target) {
|
|
|
144
144
|
return void 0;
|
|
145
145
|
}
|
|
146
146
|
LOG.isDebug() && LOG.debug(`Setting target of map '${mapId}':`, target);
|
|
147
|
+
if (!("keyboardEventTarget_" in olMap)) {
|
|
148
|
+
throw new Error(
|
|
149
|
+
"Internal error: failed to override keyboard event target. The property is no longer present."
|
|
150
|
+
);
|
|
151
|
+
}
|
|
152
|
+
olMap.keyboardEventTarget_ = target;
|
|
147
153
|
olMap.setTarget(target);
|
|
148
154
|
let unregistered = false;
|
|
149
155
|
return {
|
|
150
156
|
destroy() {
|
|
151
157
|
if (!unregistered) {
|
|
152
158
|
LOG.isDebug() && LOG.debug(`Removing target of map '${mapId}':`, target);
|
|
159
|
+
olMap.keyboardEventTarget_ = void 0;
|
|
153
160
|
olMap.setTarget(void 0);
|
|
154
161
|
unregistered = true;
|
|
155
162
|
}
|
package/ui/MapContainer.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MapContainer.js","sources":["MapContainer.tsx"],"sourcesContent":["// SPDX-FileCopyrightText: 2023 Open Pioneer project (https://github.com/open-pioneer)\n// SPDX-License-Identifier: Apache-2.0\nimport { chakra } from \"@open-pioneer/chakra-integration\";\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, CSSProperties } from \"react\";\nimport { MapModel, MapPadding } from \"../api\";\nimport { MapContainerContextProvider, MapContainerContextType } from \"./MapContainerContext\";\nimport { MapModelProps, useMapModel } from \"./useMapModel\";\nimport { PADDING_BOTTOM, PADDING_LEFT, PADDING_RIGHT, PADDING_TOP } from \"./CssProps\";\nconst LOG = createLogger(\"map:MapContainer\");\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 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 */\nexport function MapContainer(props: MapContainerProps) {\n const {\n viewPadding,\n viewPaddingChangeBehavior,\n children,\n role,\n \"aria-label\": ariaLabel,\n \"aria-labelledby\": ariaLabelledBy\n } = props;\n const { containerProps } = useCommonComponentProps(\"map-container\", props);\n const mapContainer = useRef<HTMLDivElement>(null);\n const mapAnchorsHost = useRef<HTMLDivElement>(null);\n const modelState = useMapModel(props);\n const map = modelState.map;\n\n const [ready, setReady] = useState(false);\n\n useEffect(() => {\n if (modelState.kind === \"loading\") {\n return;\n }\n\n if (modelState.kind === \"rejected\") {\n LOG.error(`Cannot display the map. Caused by `, modelState.error);\n return;\n }\n\n if (!map) {\n LOG.error(`No configuration available for the configured map.`);\n return;\n }\n\n // Mount the map into the DOM\n if (mapContainer.current) {\n const resource = registerMapTarget(map, mapContainer.current);\n return () => resource?.destroy();\n }\n }, [modelState, 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 [PADDING_TOP.definition]:\n viewPadding?.top != undefined ? viewPadding.top + \"px\" : \"0px\",\n [PADDING_BOTTOM.definition]:\n viewPadding?.bottom != undefined ? viewPadding.bottom + \"px\" : \"0px\",\n [PADDING_LEFT.definition]:\n viewPadding?.left != undefined ? viewPadding.left + \"px\" : \"0px\",\n [PADDING_RIGHT.definition]:\n viewPadding?.right != undefined ? viewPadding.right + \"px\" : \"0px\"\n } as CSSProperties;\n }, [viewPadding]);\n\n return (\n <chakra.div\n {...containerProps}\n role={role}\n aria-label={ariaLabel}\n aria-labelledby={ariaLabelledBy}\n ref={mapContainer}\n style={styleProps}\n //eslint-disable-next-line jsx-a11y/no-noninteractive-tabindex\n tabIndex={0}\n >\n {ready && map && (\n <MapContainerReady\n olMap={map.olMap}\n mapAnchorsHost={mapAnchorsHost.current!}\n viewPadding={viewPadding}\n viewPaddingChangeBehavior={viewPaddingChangeBehavior}\n >\n {children}\n </MapContainerReady>\n )}\n <chakra.div\n ref={mapAnchorsHost}\n className=\"map-anchors\"\n /* note: zero sized, children have a size and are positioned relative to the map-container */\n >\n {/* Map anchors will be mounted here via portal */}\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): JSX.Element {\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 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 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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"}
|
|
1
|
+
{"version":3,"file":"MapContainer.js","sources":["MapContainer.tsx"],"sourcesContent":["// SPDX-FileCopyrightText: 2023 Open Pioneer project (https://github.com/open-pioneer)\n// SPDX-License-Identifier: Apache-2.0\nimport { chakra } from \"@open-pioneer/chakra-integration\";\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, CSSProperties } from \"react\";\nimport { MapModel, MapPadding } from \"../api\";\nimport { MapContainerContextProvider, MapContainerContextType } from \"./MapContainerContext\";\nimport { MapModelProps, useMapModel } from \"./useMapModel\";\nimport { PADDING_BOTTOM, PADDING_LEFT, PADDING_RIGHT, PADDING_TOP } from \"./CssProps\";\nconst LOG = createLogger(\"map:MapContainer\");\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 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 */\nexport function MapContainer(props: MapContainerProps) {\n const {\n viewPadding,\n viewPaddingChangeBehavior,\n children,\n role,\n \"aria-label\": ariaLabel,\n \"aria-labelledby\": ariaLabelledBy\n } = props;\n const { containerProps } = useCommonComponentProps(\"map-container\", props);\n const mapContainer = useRef<HTMLDivElement>(null);\n const mapAnchorsHost = useRef<HTMLDivElement>(null);\n const modelState = useMapModel(props);\n const map = modelState.map;\n\n const [ready, setReady] = useState(false);\n\n useEffect(() => {\n if (modelState.kind === \"loading\") {\n return;\n }\n\n if (modelState.kind === \"rejected\") {\n LOG.error(`Cannot display the map. Caused by `, modelState.error);\n return;\n }\n\n if (!map) {\n LOG.error(`No configuration available for the configured map.`);\n return;\n }\n\n // Mount the map into the DOM\n if (mapContainer.current) {\n const resource = registerMapTarget(map, mapContainer.current);\n return () => resource?.destroy();\n }\n }, [modelState, 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 [PADDING_TOP.definition]:\n viewPadding?.top != undefined ? viewPadding.top + \"px\" : \"0px\",\n [PADDING_BOTTOM.definition]:\n viewPadding?.bottom != undefined ? viewPadding.bottom + \"px\" : \"0px\",\n [PADDING_LEFT.definition]:\n viewPadding?.left != undefined ? viewPadding.left + \"px\" : \"0px\",\n [PADDING_RIGHT.definition]:\n viewPadding?.right != undefined ? viewPadding.right + \"px\" : \"0px\"\n } as CSSProperties;\n }, [viewPadding]);\n\n return (\n <chakra.div\n {...containerProps}\n role={role}\n aria-label={ariaLabel}\n aria-labelledby={ariaLabelledBy}\n ref={mapContainer}\n style={styleProps}\n //eslint-disable-next-line jsx-a11y/no-noninteractive-tabindex\n tabIndex={0}\n >\n {ready && map && (\n <MapContainerReady\n olMap={map.olMap}\n mapAnchorsHost={mapAnchorsHost.current!}\n viewPadding={viewPadding}\n viewPaddingChangeBehavior={viewPaddingChangeBehavior}\n >\n {children}\n </MapContainerReady>\n )}\n <chakra.div\n ref={mapAnchorsHost}\n className=\"map-anchors\"\n /* note: zero sized, children have a size and are positioned relative to the map-container */\n >\n {/* Map anchors will be mounted here via portal */}\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): JSX.Element {\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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"}
|