@open-pioneer/map 0.7.0 → 0.8.0-dev.20241120115147

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (53) hide show
  1. package/CHANGELOG.md +133 -0
  2. package/README.md +116 -12
  3. package/api/MapModel.d.ts +48 -15
  4. package/api/layers/GroupLayer.d.ts +50 -0
  5. package/api/layers/GroupLayer.js +6 -0
  6. package/api/layers/GroupLayer.js.map +1 -0
  7. package/api/layers/SimpleLayer.d.ts +1 -0
  8. package/api/layers/SimpleLayer.js.map +1 -1
  9. package/api/layers/WMSLayer.d.ts +1 -0
  10. package/api/layers/WMSLayer.js.map +1 -1
  11. package/api/layers/WMTSLayer.d.ts +1 -0
  12. package/api/layers/WMTSLayer.js.map +1 -1
  13. package/api/layers/base.d.ts +35 -14
  14. package/api/layers/base.js.map +1 -1
  15. package/api/layers/index.d.ts +1 -0
  16. package/index.js +1 -0
  17. package/index.js.map +1 -1
  18. package/model/AbstractLayer.d.ts +2 -2
  19. package/model/AbstractLayer.js +16 -23
  20. package/model/AbstractLayer.js.map +1 -1
  21. package/model/AbstractLayerBase.d.ts +19 -4
  22. package/model/AbstractLayerBase.js +48 -35
  23. package/model/AbstractLayerBase.js.map +1 -1
  24. package/model/Highlights.d.ts +2 -1
  25. package/model/Highlights.js +2 -0
  26. package/model/Highlights.js.map +1 -1
  27. package/model/LayerCollectionImpl.d.ts +5 -3
  28. package/model/LayerCollectionImpl.js +27 -29
  29. package/model/LayerCollectionImpl.js.map +1 -1
  30. package/model/MapModelImpl.d.ts +12 -2
  31. package/model/MapModelImpl.js +94 -25
  32. package/model/MapModelImpl.js.map +1 -1
  33. package/model/SublayersCollectionImpl.d.ts +6 -3
  34. package/model/SublayersCollectionImpl.js +6 -4
  35. package/model/SublayersCollectionImpl.js.map +1 -1
  36. package/model/layers/GroupLayerImpl.d.ts +39 -0
  37. package/model/layers/GroupLayerImpl.js +88 -0
  38. package/model/layers/GroupLayerImpl.js.map +1 -0
  39. package/model/layers/SimpleLayerImpl.d.ts +1 -0
  40. package/model/layers/SimpleLayerImpl.js +3 -0
  41. package/model/layers/SimpleLayerImpl.js.map +1 -1
  42. package/model/layers/WMSLayerImpl.d.ts +9 -7
  43. package/model/layers/WMSLayerImpl.js +58 -51
  44. package/model/layers/WMSLayerImpl.js.map +1 -1
  45. package/model/layers/WMTSLayerImpl.d.ts +3 -5
  46. package/model/layers/WMTSLayerImpl.js +13 -13
  47. package/model/layers/WMTSLayerImpl.js.map +1 -1
  48. package/package.json +9 -8
  49. package/ui/hooks.d.ts +10 -0
  50. package/ui/hooks.js.map +1 -1
  51. package/util/defer.d.ts +0 -18
  52. package/util/defer.js +0 -21
  53. package/util/defer.js.map +0 -1
@@ -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 { WMTSLayer } from \"./WMTSLayer\";\n\n/** Events emitted by the {@link Layer} and other layer types. */\nexport interface LayerBaseEvents {\n \"changed\": void;\n \"changed:title\": void;\n \"changed:legend\": void;\n \"changed:description\": void;\n \"changed:visible\": void;\n \"changed:attributes\": void;\n \"changed:loadState\": void;\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 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 * LegendURL from the service capabilities, if available.\n */\n readonly legend: string | undefined;\n\n /**\n * The collection of child sublayers for this layer.\n *\n * Layers that can never have any sublayers may not have a `sublayers` collection.\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 * Events emitted by the {@link SublayersCollection}.\n */\nexport interface SublayersCollectionEvents {\n changed: void;\n}\n\n/**\n * Contains the sublayers that belong to a {@link Layer} or {@link Sublayer}.\n */\nexport interface SublayersCollection<SublayerType = Sublayer>\n extends EventSource<SublayersCollectionEvents> {\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;\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":"AAiQO,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;;;;"}
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 * LegendURL from the service capabilities, if available.\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":"AAyRO,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;;;;"}
@@ -2,3 +2,4 @@ export * from "./base";
2
2
  export * from "./SimpleLayer";
3
3
  export * from "./WMSLayer";
4
4
  export * from "./WMTSLayer";
5
+ export * from "./GroupLayer";
package/index.js CHANGED
@@ -2,6 +2,7 @@ export { isLayer, isSublayer } from './api/layers/base.js';
2
2
  export { SimpleLayer } from './api/layers/SimpleLayer.js';
3
3
  export { WMSLayer } from './api/layers/WMSLayer.js';
4
4
  export { WMTSLayer } from './api/layers/WMTSLayer.js';
5
+ export { GroupLayer } from './api/layers/GroupLayer.js';
5
6
  export { getProjection, registerProjections } from './projections.js';
6
7
  export { BkgTopPlusOpen } from './layers/BkgTopPlusOpen.js';
7
8
  export { useCenter, useProjection, useResolution, useScale, useView } from './ui/hooks.js';
package/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;"}
1
+ {"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;"}
@@ -18,8 +18,8 @@ export declare abstract class AbstractLayer<AdditionalEvents = {}> extends Abstr
18
18
  /**
19
19
  * Called by the map model when the layer is added to the map.
20
20
  */
21
- __attach(map: MapModelImpl): void;
21
+ __attachToMap(map: MapModelImpl): void;
22
22
  setVisible(newVisibility: boolean): void;
23
23
  __setVisible(newVisibility: boolean): void;
24
- abstract readonly type: "simple" | "wms" | "wmts";
24
+ abstract readonly type: "simple" | "wms" | "wmts" | "group";
25
25
  }
@@ -1,4 +1,5 @@
1
- import { createLogger } from '@open-pioneer/core';
1
+ import { external, reactive } from '@conterra/reactivity-core';
2
+ import { createLogger, destroyResource } from '@open-pioneer/core';
2
3
  import { unByKey } from 'ol/Observable.js';
3
4
  import OlLayer from 'ol/layer/Layer.js';
4
5
  import { AbstractLayerBase } from './AbstractLayerBase.js';
@@ -10,18 +11,20 @@ class AbstractLayer extends AbstractLayerBase {
10
11
  #healthCheck;
11
12
  #visible;
12
13
  #loadState;
14
+ #visibilityWatchKey;
13
15
  #stateWatchResource;
14
16
  constructor(config) {
15
17
  super(config);
16
18
  this.#olLayer = config.olLayer;
17
19
  this.#isBaseLayer = config.isBaseLayer ?? false;
18
20
  this.#healthCheck = config.healthCheck;
19
- this.#visible = config.visible ?? true;
20
- this.#loadState = getSourceState(getSource(this.#olLayer));
21
- this.__setVisible(this.#visible);
21
+ this.#visible = external(() => this.#olLayer.getVisible());
22
+ this.#visibilityWatchKey = this.#olLayer.on("change:visible", this.#visible.trigger);
23
+ this.#loadState = reactive(getSourceState(getSource(this.#olLayer)));
24
+ this.__setVisible(config.visible ?? true);
22
25
  }
23
26
  get visible() {
24
- return this.#visible;
27
+ return this.#visible.value;
25
28
  }
26
29
  get olLayer() {
27
30
  return this.#olLayer;
@@ -30,30 +33,32 @@ class AbstractLayer extends AbstractLayerBase {
30
33
  return this.#isBaseLayer;
31
34
  }
32
35
  get loadState() {
33
- return this.#loadState;
36
+ return this.#loadState.value;
34
37
  }
35
38
  destroy() {
36
39
  if (this.__destroyed) {
37
40
  return;
38
41
  }
39
- this.#stateWatchResource?.destroy();
42
+ this.#stateWatchResource = destroyResource(this.#stateWatchResource);
43
+ this.#visibilityWatchKey && unByKey(this.#visibilityWatchKey);
44
+ this.#visibilityWatchKey = void 0;
40
45
  this.olLayer.dispose();
41
46
  super.destroy();
42
47
  }
43
48
  /**
44
49
  * Called by the map model when the layer is added to the map.
45
50
  */
46
- __attach(map) {
51
+ __attachToMap(map) {
47
52
  super.__attachToMap(map);
48
53
  const { initial: initialState, resource: stateWatchResource } = watchLoadState(
49
54
  this,
50
55
  this.#healthCheck,
51
56
  (state) => {
52
- this.#setLoadState(state);
57
+ this.#loadState.value = state;
53
58
  }
54
59
  );
55
60
  this.#stateWatchResource = stateWatchResource;
56
- this.#setLoadState(initialState);
61
+ this.#loadState.value = initialState;
57
62
  }
58
63
  setVisible(newVisibility) {
59
64
  if (this.isBaseLayer) {
@@ -65,21 +70,9 @@ class AbstractLayer extends AbstractLayerBase {
65
70
  this.__setVisible(newVisibility);
66
71
  }
67
72
  __setVisible(newVisibility) {
68
- let changed = false;
69
- if (this.#visible !== newVisibility) {
70
- this.#visible = newVisibility;
71
- changed = true;
72
- }
73
- if (this.#olLayer.getVisible() != this.#visible) {
73
+ if (this.#olLayer.getVisible() !== newVisibility) {
74
74
  this.#olLayer.setVisible(newVisibility);
75
75
  }
76
- changed && this.__emitChangeEvent("changed:visible");
77
- }
78
- #setLoadState(loadState) {
79
- if (loadState !== this.#loadState) {
80
- this.#loadState = loadState;
81
- this.__emitChangeEvent("changed:loadState");
82
- }
83
76
  }
84
77
  }
85
78
  function watchLoadState(layer, healthCheck, onChange) {
@@ -1 +1 @@
1
- {"version":3,"file":"AbstractLayer.js","sources":["AbstractLayer.ts"],"sourcesContent":["// SPDX-FileCopyrightText: 2023 Open Pioneer project (https://github.com/open-pioneer)\n// SPDX-License-Identifier: Apache-2.0\nimport { Resource, createLogger } from \"@open-pioneer/core\";\nimport { unByKey } from \"ol/Observable\";\nimport { EventsKey } from \"ol/events\";\nimport OlBaseLayer from \"ol/layer/Base\";\nimport OlLayer from \"ol/layer/Layer\";\nimport OlSource from \"ol/source/Source\";\nimport {\n HealthCheckFunction,\n Layer,\n LayerBaseType,\n LayerConfig,\n LayerLoadState,\n SimpleLayerConfig\n} from \"../api\";\nimport { AbstractLayerBase } from \"./AbstractLayerBase\";\nimport { MapModelImpl } from \"./MapModelImpl\";\n\nconst LOG = createLogger(\"map:AbstractLayer\");\n\n/**\n * Base class for normal layer types.\n *\n * These layers always have an associated OpenLayers layer.\n */\nexport abstract class AbstractLayer<AdditionalEvents = {}>\n extends AbstractLayerBase<AdditionalEvents>\n implements LayerBaseType\n{\n #olLayer: OlBaseLayer;\n #isBaseLayer: boolean;\n #healthCheck?: string | HealthCheckFunction;\n #visible: boolean;\n\n #loadState: LayerLoadState;\n #stateWatchResource: Resource | undefined;\n\n constructor(config: SimpleLayerConfig) {\n super(config);\n this.#olLayer = config.olLayer;\n this.#isBaseLayer = config.isBaseLayer ?? false;\n this.#healthCheck = config.healthCheck;\n\n this.#visible = config.visible ?? true;\n this.#loadState = getSourceState(getSource(this.#olLayer));\n\n this.__setVisible(this.#visible); // apply initial visibility\n }\n\n get visible(): boolean {\n return this.#visible;\n }\n\n get olLayer(): OlBaseLayer {\n return this.#olLayer;\n }\n\n get isBaseLayer(): boolean {\n return this.#isBaseLayer;\n }\n\n get loadState(): LayerLoadState {\n return this.#loadState;\n }\n\n destroy() {\n if (this.__destroyed) {\n return;\n }\n\n this.#stateWatchResource?.destroy();\n this.olLayer.dispose();\n super.destroy();\n }\n\n /**\n * Called by the map model when the layer is added to the map.\n */\n __attach(map: MapModelImpl): void {\n super.__attachToMap(map);\n\n const { initial: initialState, resource: stateWatchResource } = watchLoadState(\n this,\n this.#healthCheck,\n (state) => {\n this.#setLoadState(state);\n }\n );\n this.#stateWatchResource = stateWatchResource;\n this.#setLoadState(initialState);\n }\n\n 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.__setVisible(newVisibility);\n }\n\n __setVisible(newVisibility: boolean): void {\n let changed = false;\n if (this.#visible !== newVisibility) {\n this.#visible = newVisibility;\n changed = true;\n }\n\n // Improvement: actual map sync?\n if (this.#olLayer.getVisible() != this.#visible) {\n this.#olLayer.setVisible(newVisibility);\n }\n changed && this.__emitChangeEvent(\"changed:visible\");\n }\n\n #setLoadState(loadState: LayerLoadState) {\n if (loadState !== this.#loadState) {\n this.#loadState = loadState;\n this.__emitChangeEvent(\"changed:loadState\");\n }\n }\n\n abstract readonly type: \"simple\" | \"wms\" | \"wmts\";\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.map.__sharedDependencies.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":";;;;;AAmBA,MAAM,GAAA,GAAM,aAAa,mBAAmB,CAAA,CAAA;AAOrC,MAAe,sBACV,iBAEZ,CAAA;AAAA,EACI,QAAA,CAAA;AAAA,EACA,YAAA,CAAA;AAAA,EACA,YAAA,CAAA;AAAA,EACA,QAAA,CAAA;AAAA,EAEA,UAAA,CAAA;AAAA,EACA,mBAAA,CAAA;AAAA,EAEA,YAAY,MAA2B,EAAA;AACnC,IAAA,KAAA,CAAM,MAAM,CAAA,CAAA;AACZ,IAAA,IAAA,CAAK,WAAW,MAAO,CAAA,OAAA,CAAA;AACvB,IAAK,IAAA,CAAA,YAAA,GAAe,OAAO,WAAe,IAAA,KAAA,CAAA;AAC1C,IAAA,IAAA,CAAK,eAAe,MAAO,CAAA,WAAA,CAAA;AAE3B,IAAK,IAAA,CAAA,QAAA,GAAW,OAAO,OAAW,IAAA,IAAA,CAAA;AAClC,IAAA,IAAA,CAAK,UAAa,GAAA,cAAA,CAAe,SAAU,CAAA,IAAA,CAAK,QAAQ,CAAC,CAAA,CAAA;AAEzD,IAAK,IAAA,CAAA,YAAA,CAAa,KAAK,QAAQ,CAAA,CAAA;AAAA,GACnC;AAAA,EAEA,IAAI,OAAmB,GAAA;AACnB,IAAA,OAAO,IAAK,CAAA,QAAA,CAAA;AAAA,GAChB;AAAA,EAEA,IAAI,OAAuB,GAAA;AACvB,IAAA,OAAO,IAAK,CAAA,QAAA,CAAA;AAAA,GAChB;AAAA,EAEA,IAAI,WAAuB,GAAA;AACvB,IAAA,OAAO,IAAK,CAAA,YAAA,CAAA;AAAA,GAChB;AAAA,EAEA,IAAI,SAA4B,GAAA;AAC5B,IAAA,OAAO,IAAK,CAAA,UAAA,CAAA;AAAA,GAChB;AAAA,EAEA,OAAU,GAAA;AACN,IAAA,IAAI,KAAK,WAAa,EAAA;AAClB,MAAA,OAAA;AAAA,KACJ;AAEA,IAAA,IAAA,CAAK,qBAAqB,OAAQ,EAAA,CAAA;AAClC,IAAA,IAAA,CAAK,QAAQ,OAAQ,EAAA,CAAA;AACrB,IAAA,KAAA,CAAM,OAAQ,EAAA,CAAA;AAAA,GAClB;AAAA;AAAA;AAAA;AAAA,EAKA,SAAS,GAAyB,EAAA;AAC9B,IAAA,KAAA,CAAM,cAAc,GAAG,CAAA,CAAA;AAEvB,IAAA,MAAM,EAAE,OAAA,EAAS,YAAc,EAAA,QAAA,EAAU,oBAAuB,GAAA,cAAA;AAAA,MAC5D,IAAA;AAAA,MACA,IAAK,CAAA,YAAA;AAAA,MACL,CAAC,KAAU,KAAA;AACP,QAAA,IAAA,CAAK,cAAc,KAAK,CAAA,CAAA;AAAA,OAC5B;AAAA,KACJ,CAAA;AACA,IAAA,IAAA,CAAK,mBAAsB,GAAA,kBAAA,CAAA;AAC3B,IAAA,IAAA,CAAK,cAAc,YAAY,CAAA,CAAA;AAAA,GACnC;AAAA,EAEA,WAAW,aAA8B,EAAA;AACrC,IAAA,IAAI,KAAK,WAAa,EAAA;AAClB,MAAI,GAAA,CAAA,IAAA;AAAA,QACA,CAAA,wCAAA,EAA2C,KAAK,EAAE,CAAA,gEAAA,CAAA;AAAA,OACtD,CAAA;AACA,MAAA,OAAA;AAAA,KACJ;AAEA,IAAA,IAAA,CAAK,aAAa,aAAa,CAAA,CAAA;AAAA,GACnC;AAAA,EAEA,aAAa,aAA8B,EAAA;AACvC,IAAA,IAAI,OAAU,GAAA,KAAA,CAAA;AACd,IAAI,IAAA,IAAA,CAAK,aAAa,aAAe,EAAA;AACjC,MAAA,IAAA,CAAK,QAAW,GAAA,aAAA,CAAA;AAChB,MAAU,OAAA,GAAA,IAAA,CAAA;AAAA,KACd;AAGA,IAAA,IAAI,IAAK,CAAA,QAAA,CAAS,UAAW,EAAA,IAAK,KAAK,QAAU,EAAA;AAC7C,MAAK,IAAA,CAAA,QAAA,CAAS,WAAW,aAAa,CAAA,CAAA;AAAA,KAC1C;AACA,IAAW,OAAA,IAAA,IAAA,CAAK,kBAAkB,iBAAiB,CAAA,CAAA;AAAA,GACvD;AAAA,EAEA,cAAc,SAA2B,EAAA;AACrC,IAAI,IAAA,SAAA,KAAc,KAAK,UAAY,EAAA;AAC/B,MAAA,IAAA,CAAK,UAAa,GAAA,SAAA,CAAA;AAClB,MAAA,IAAA,CAAK,kBAAkB,mBAAmB,CAAA,CAAA;AAAA,KAC9C;AAAA,GACJ;AAGJ,CAAA;AAEA,SAAS,cAAA,CACL,KACA,EAAA,WAAA,EACA,QAC+C,EAAA;AAC/C,EAAA,MAAM,UAAU,KAAM,CAAA,OAAA,CAAA;AAEtB,EAAI,IAAA,EAAE,mBAAmB,OAAU,CAAA,EAAA;AAE/B,IAAO,OAAA;AAAA,MACH,OAAS,EAAA,QAAA;AAAA,MACT,QAAU,EAAA;AAAA,QACN,OAAU,GAAA;AAAA,SAEV;AAAA,OACJ;AAAA,KACJ,CAAA;AAAA,GACJ;AAEA,EAAI,IAAA,aAAA,GAAgB,UAAU,OAAO,CAAA,CAAA;AACrC,EAAM,MAAA,mBAAA,GAAsB,eAAe,aAAa,CAAA,CAAA;AAExD,EAAA,IAAI,gBAAmC,GAAA,mBAAA,CAAA;AACvC,EAAA,IAAI,kBAAqB,GAAA,SAAA,CAAA;AAGzB,EAAA,IAAI,wBAAwB,OAAS,EAAA;AAEjC,IAAA,aAAA,CAAc,KAAO,EAAA,WAAW,CAAE,CAAA,IAAA,CAAK,CAAC,KAA0B,KAAA;AAC9D,MAAqB,kBAAA,GAAA,KAAA,CAAA;AACrB,MAAY,WAAA,EAAA,CAAA;AAAA,KACf,CAAA,CAAA;AAAA,GACL;AAEA,EAAA,MAAM,cAAc,MAAM;AACtB,IAAM,MAAA,YAAA,GAAe,eAAe,aAAa,CAAA,CAAA;AACjD,IAAM,MAAA,aAAA,GACF,kBAAuB,KAAA,OAAA,GAAU,OAAU,GAAA,YAAA,CAAA;AAE/C,IAAA,IAAI,qBAAqB,aAAe,EAAA;AACpC,MAAmB,gBAAA,GAAA,aAAA,CAAA;AACnB,MAAA,QAAA,CAAS,gBAAgB,CAAA,CAAA;AAAA,KAC7B;AAAA,GACJ,CAAA;AAEA,EAAI,IAAA,WAAA,CAAA;AACJ,EAAc,WAAA,GAAA,aAAA,EAAe,EAAG,CAAA,QAAA,EAAU,MAAM;AAC5C,IAAY,WAAA,EAAA,CAAA;AAAA,GACf,CAAA,CAAA;AAED,EAAA,MAAM,YAAe,GAAA,OAAA,CAAQ,EAAG,CAAA,eAAA,EAAiB,MAAM;AAEnD,IAAA,WAAA,IAAe,QAAQ,WAAW,CAAA,CAAA;AAClC,IAAc,WAAA,GAAA,KAAA,CAAA,CAAA;AAGd,IAAA,aAAA,GAAgB,UAAU,OAAO,CAAA,CAAA;AACjC,IAAc,WAAA,GAAA,aAAA,EAAe,EAAG,CAAA,QAAA,EAAU,MAAM;AAC5C,MAAY,WAAA,EAAA,CAAA;AAAA,KACf,CAAA,CAAA;AACD,IAAY,WAAA,EAAA,CAAA;AAAA,GACf,CAAA,CAAA;AACD,EAAO,OAAA;AAAA,IACH,OAAS,EAAA,gBAAA;AAAA,IACT,QAAU,EAAA;AAAA,MACN,OAAU,GAAA;AACN,QAAA,WAAA,IAAe,QAAQ,WAAW,CAAA,CAAA;AAClC,QAAA,OAAA,CAAQ,YAAY,CAAA,CAAA;AAAA,OACxB;AAAA,KACJ;AAAA,GACJ,CAAA;AACJ,CAAA;AAEA,eAAe,aAAA,CACX,OACA,WACuB,EAAA;AACvB,EAAA,IAAI,eAAe,IAAM,EAAA;AACrB,IAAO,OAAA,QAAA,CAAA;AAAA,GACX;AAEA,EAAI,IAAA,aAAA,CAAA;AACJ,EAAI,IAAA,OAAO,gBAAgB,UAAY,EAAA;AACnC,IAAgB,aAAA,GAAA,WAAA,CAAA;AAAA,GACpB,MAAA,IAAW,OAAO,WAAA,KAAgB,QAAU,EAAA;AACxC,IAAA,aAAA,GAAgB,YAAY;AACxB,MAAM,MAAA,WAAA,GAAc,KAAM,CAAA,GAAA,CAAI,oBAAqB,CAAA,WAAA,CAAA;AACnD,MAAA,MAAM,QAAW,GAAA,MAAM,WAAY,CAAA,KAAA,CAAM,WAAW,CAAA,CAAA;AACpD,MAAA,IAAI,SAAS,EAAI,EAAA;AACb,QAAO,OAAA,QAAA,CAAA;AAAA,OACX;AACA,MAAI,GAAA,CAAA,IAAA;AAAA,QACA,CAAkC,+BAAA,EAAA,KAAA,CAAM,EAAE,CAAA,eAAA,EAAkB,SAAS,MAAM,CAAA,CAAA,CAAA;AAAA,OAC/E,CAAA;AACA,MAAO,OAAA,OAAA,CAAA;AAAA,KACX,CAAA;AAAA,GACG,MAAA;AACH,IAAI,GAAA,CAAA,KAAA;AAAA,MACA,CAAA,wDAAA,EAA2D,MAAM,EAAE,CAAA,CAAA,CAAA;AAAA,MACnE,WAAA;AAAA,KACJ,CAAA;AACA,IAAO,OAAA,OAAA,CAAA;AAAA,GACX;AAEA,EAAI,IAAA;AACA,IAAO,OAAA,MAAM,cAAc,KAAc,CAAA,CAAA;AAAA,WACpC,CAAG,EAAA;AACR,IAAA,GAAA,CAAI,IAAK,CAAA,CAAA,+BAAA,EAAkC,KAAM,CAAA,EAAE,KAAK,CAAC,CAAA,CAAA;AACzD,IAAO,OAAA,OAAA,CAAA;AAAA,GACX;AACJ,CAAA;AAEA,SAAS,UAAU,OAAgC,EAAA;AAC/C,EAAI,IAAA,EAAE,mBAAmB,OAAU,CAAA,EAAA;AAC/B,IAAO,OAAA,KAAA,CAAA,CAAA;AAAA,GACX;AACA,EAAQ,OAAA,OAAA,EAAS,WAAmC,IAAA,KAAA,CAAA,CAAA;AACxD,CAAA;AAEA,SAAS,eAAe,QAAgC,EAAA;AACpD,EAAM,MAAA,KAAA,GAAQ,UAAU,QAAS,EAAA,CAAA;AACjC,EAAA,QAAQ,KAAO;AAAA,IACX,KAAK,KAAA,CAAA;AACD,MAAO,OAAA,QAAA,CAAA;AAAA,IACX,KAAK,WAAA;AACD,MAAO,OAAA,YAAA,CAAA;AAAA,IACX,KAAK,SAAA;AACD,MAAO,OAAA,SAAA,CAAA;AAAA,IACX,KAAK,OAAA;AACD,MAAO,OAAA,QAAA,CAAA;AAAA,IACX,KAAK,OAAA;AACD,MAAO,OAAA,OAAA,CAAA;AAAA,GACf;AACJ;;;;"}
1
+ {"version":3,"file":"AbstractLayer.js","sources":["AbstractLayer.ts"],"sourcesContent":["// SPDX-FileCopyrightText: 2023 Open Pioneer project (https://github.com/open-pioneer)\n// SPDX-License-Identifier: Apache-2.0\nimport { ExternalReactive, reactive, external, Reactive } from \"@conterra/reactivity-core\";\nimport { createLogger, destroyResource, Resource } from \"@open-pioneer/core\";\nimport { unByKey } from \"ol/Observable\";\nimport { EventsKey } from \"ol/events\";\nimport OlBaseLayer from \"ol/layer/Base\";\nimport OlLayer from \"ol/layer/Layer\";\nimport OlSource from \"ol/source/Source\";\nimport {\n HealthCheckFunction,\n Layer,\n LayerBaseType,\n LayerConfig,\n LayerLoadState,\n SimpleLayerConfig\n} from \"../api\";\nimport { AbstractLayerBase } from \"./AbstractLayerBase\";\nimport { MapModelImpl } from \"./MapModelImpl\";\n\nconst LOG = createLogger(\"map:AbstractLayer\");\n\n/**\n * Base class for normal layer types.\n *\n * These layers always have an associated OpenLayers layer.\n */\nexport abstract class AbstractLayer<AdditionalEvents = {}>\n extends AbstractLayerBase<AdditionalEvents>\n implements LayerBaseType\n{\n #olLayer: OlBaseLayer;\n #isBaseLayer: boolean;\n #healthCheck?: string | HealthCheckFunction;\n\n #visible: ExternalReactive<boolean>;\n #loadState: Reactive<LayerLoadState>;\n\n #visibilityWatchKey: EventsKey | undefined;\n #stateWatchResource: Resource | undefined;\n\n constructor(config: SimpleLayerConfig) {\n super(config);\n this.#olLayer = config.olLayer;\n this.#isBaseLayer = config.isBaseLayer ?? false;\n this.#healthCheck = config.healthCheck;\n\n this.#visible = external(() => this.#olLayer.getVisible());\n this.#visibilityWatchKey = this.#olLayer.on(\"change:visible\", this.#visible.trigger);\n\n this.#loadState = reactive(getSourceState(getSource(this.#olLayer)));\n this.__setVisible(config.visible ?? true); // apply initial visibility\n }\n\n get visible(): boolean {\n return this.#visible.value;\n }\n\n get olLayer(): OlBaseLayer {\n return this.#olLayer;\n }\n\n get isBaseLayer(): boolean {\n return this.#isBaseLayer;\n }\n\n get loadState(): LayerLoadState {\n return this.#loadState.value;\n }\n\n destroy() {\n if (this.__destroyed) {\n return;\n }\n\n this.#stateWatchResource = destroyResource(this.#stateWatchResource);\n this.#visibilityWatchKey && unByKey(this.#visibilityWatchKey);\n this.#visibilityWatchKey = undefined;\n this.olLayer.dispose();\n super.destroy();\n }\n\n /**\n * Called by the map model when the layer is added to the map.\n */\n __attachToMap(map: MapModelImpl): void {\n super.__attachToMap(map);\n\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 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.__setVisible(newVisibility);\n }\n\n __setVisible(newVisibility: boolean): void {\n if (this.#olLayer.getVisible() !== newVisibility) {\n this.#olLayer.setVisible(newVisibility);\n }\n }\n\n abstract readonly type: \"simple\" | \"wms\" | \"wmts\" | \"group\";\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.map.__sharedDependencies.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,5 +1,7 @@
1
- import { EventEmitter, EventNames } from "@open-pioneer/core";
2
- import { AnyLayerBaseType, AnyLayerTypes, LayerBaseEvents, Sublayer } from "../api";
1
+ import { EventEmitter } from "@open-pioneer/core";
2
+ import { AnyLayer, AnyLayerBaseType, AnyLayerTypes, ChildrenCollection, LayerBaseEvents, Sublayer } from "../api";
3
+ import { GroupLayer } from "../api/layers/GroupLayer";
4
+ import { GroupLayerCollectionImpl } from "./layers/GroupLayerImpl";
3
5
  import { MapModelImpl } from "./MapModelImpl";
4
6
  import { SublayersCollectionImpl } from "./SublayersCollectionImpl";
5
7
  export interface AbstractLayerBaseOptions {
@@ -21,19 +23,32 @@ export declare abstract class AbstractLayerBase<AdditionalEvents = {}> extends E
21
23
  get title(): string;
22
24
  get description(): string;
23
25
  get attributes(): Record<string | symbol, unknown>;
26
+ get parent(): AnyLayer | undefined;
27
+ get children(): ChildrenCollection<AnyLayer & AbstractLayerBase> | undefined;
24
28
  abstract get type(): AnyLayerTypes;
25
29
  abstract get visible(): boolean;
30
+ abstract get layers(): GroupLayerCollectionImpl | undefined;
26
31
  abstract get sublayers(): SublayersCollectionImpl<Sublayer & AbstractLayerBase> | undefined;
27
32
  abstract get legend(): string | undefined;
28
33
  destroy(): void;
29
34
  /**
30
35
  * Attaches the layer to its owning map.
31
36
  */
32
- protected __attachToMap(map: MapModelImpl): void;
37
+ __attachToMap(map: MapModelImpl): void;
38
+ /**
39
+ * Attach group layers to its parent group layer.
40
+ * Called by the parent layer.
41
+ */
42
+ __attachToGroup(parent: GroupLayer): void;
43
+ /**
44
+ * Detach layer from parent group layer.
45
+ *
46
+ * Called by the parent group layer when destroyed or the layer gets removed.
47
+ */
48
+ __detachFromGroup(): void;
33
49
  setTitle(newTitle: string): void;
34
50
  setDescription(newDescription: string): void;
35
51
  updateAttributes(newAttributes: Record<string | symbol, unknown>): void;
36
52
  deleteAttribute(deleteAttribute: string | symbol): void;
37
53
  abstract setVisible(newVisibility: boolean): void;
38
- protected __emitChangeEvent<Name extends EventNames<LayerBaseEvents & AdditionalEvents>>(event: Name): void;
39
54
  }
@@ -1,20 +1,28 @@
1
+ import { reactiveMap, computed, reactive, batch } from '@conterra/reactivity-core';
1
2
  import { createLogger, EventEmitter } from '@open-pioneer/core';
2
3
  import { v4 } from 'uuid';
3
4
 
4
5
  const LOG = createLogger("map:AbstractLayerModel");
5
6
  class AbstractLayerBase extends EventEmitter {
6
7
  #map;
8
+ #parent;
7
9
  #id;
8
10
  #title;
9
11
  #description;
12
+ #attributesMap = reactiveMap();
10
13
  #attributes;
11
14
  #destroyed = false;
12
15
  constructor(config) {
13
16
  super();
14
17
  this.#id = config.id ?? v4();
15
- this.#attributes = config.attributes ?? {};
16
- this.#title = config.title;
17
- this.#description = config.description ?? "";
18
+ this.#attributes = computed(() => {
19
+ return Object.fromEntries(this.#attributesMap.entries());
20
+ });
21
+ this.#title = reactive(config.title);
22
+ this.#description = reactive(config.description ?? "");
23
+ if (config.attributes) {
24
+ this.updateAttributes(config.attributes);
25
+ }
18
26
  }
19
27
  get __destroyed() {
20
28
  return this.#destroyed;
@@ -30,13 +38,19 @@ class AbstractLayerBase extends EventEmitter {
30
38
  return this.#id;
31
39
  }
32
40
  get title() {
33
- return this.#title;
41
+ return this.#title.value;
34
42
  }
35
43
  get description() {
36
- return this.#description;
44
+ return this.#description.value;
37
45
  }
38
46
  get attributes() {
39
- return this.#attributes;
47
+ return this.#attributes.value;
48
+ }
49
+ get parent() {
50
+ return this.#parent;
51
+ }
52
+ get children() {
53
+ return this.layers ?? this.sublayers ?? void 0;
40
54
  }
41
55
  destroy() {
42
56
  if (this.#destroyed) {
@@ -44,6 +58,7 @@ class AbstractLayerBase extends EventEmitter {
44
58
  }
45
59
  this.#destroyed = true;
46
60
  this.sublayers?.destroy();
61
+ this.layers?.destroy();
47
62
  try {
48
63
  this.emit("destroy");
49
64
  } catch (e) {
@@ -61,44 +76,42 @@ class AbstractLayerBase extends EventEmitter {
61
76
  }
62
77
  this.#map = map;
63
78
  }
64
- setTitle(newTitle) {
65
- if (newTitle !== this.#title) {
66
- this.#title = newTitle;
67
- this.__emitChangeEvent("changed:title");
79
+ /**
80
+ * Attach group layers to its parent group layer.
81
+ * Called by the parent layer.
82
+ */
83
+ __attachToGroup(parent) {
84
+ if (this.#parent) {
85
+ throw new Error(
86
+ `Layer '${this.id}' has already been attached to the group layer '${this.#parent.id}'`
87
+ );
68
88
  }
89
+ this.#parent = parent;
90
+ }
91
+ /**
92
+ * Detach layer from parent group layer.
93
+ *
94
+ * Called by the parent group layer when destroyed or the layer gets removed.
95
+ */
96
+ __detachFromGroup() {
97
+ this.#parent = void 0;
98
+ }
99
+ setTitle(newTitle) {
100
+ this.#title.value = newTitle;
69
101
  }
70
102
  setDescription(newDescription) {
71
- if (newDescription !== this.#description) {
72
- this.#description = newDescription;
73
- this.__emitChangeEvent("changed:description");
74
- }
103
+ this.#description.value = newDescription;
75
104
  }
76
105
  updateAttributes(newAttributes) {
77
- const attributes = this.#attributes;
78
106
  const keys = Reflect.ownKeys(newAttributes);
79
- let changed = false;
80
- for (const key of keys) {
81
- const existing = attributes[key];
82
- const value = newAttributes[key];
83
- if (existing !== value) {
84
- attributes[key] = value;
85
- changed = true;
107
+ batch(() => {
108
+ for (const key of keys) {
109
+ this.#attributesMap.set(key, newAttributes[key]);
86
110
  }
87
- }
88
- if (changed) {
89
- this.__emitChangeEvent("changed:attributes");
90
- }
111
+ });
91
112
  }
92
113
  deleteAttribute(deleteAttribute) {
93
- const attributes = this.#attributes;
94
- if (attributes[deleteAttribute]) {
95
- delete attributes[deleteAttribute];
96
- this.__emitChangeEvent("changed:attributes");
97
- }
98
- }
99
- __emitChangeEvent(event) {
100
- this.emit(event);
101
- this.emit("changed");
114
+ this.#attributesMap.delete(deleteAttribute);
102
115
  }
103
116
  }
104
117
 
@@ -1 +1 @@
1
- {"version":3,"file":"AbstractLayerBase.js","sources":["AbstractLayerBase.ts"],"sourcesContent":["// SPDX-FileCopyrightText: 2023 Open Pioneer project (https://github.com/open-pioneer)\n// SPDX-License-Identifier: Apache-2.0\nimport { EventEmitter, EventNames, createLogger } from \"@open-pioneer/core\";\nimport { v4 as uuid4v } from \"uuid\";\nimport { AnyLayerBaseType, AnyLayerTypes, LayerBaseEvents, Sublayer } from \"../api\";\nimport { MapModelImpl } from \"./MapModelImpl\";\nimport { SublayersCollectionImpl } from \"./SublayersCollectionImpl\";\n\nconst LOG = createLogger(\"map:AbstractLayerModel\");\n\nexport interface AbstractLayerBaseOptions {\n id?: string;\n title: string;\n description?: string;\n attributes?: Record<string, unknown>;\n}\n\n/**\n * Base class for \"normal\" layers and sublayers alike to implement common properties\n * such as id, title and attributes.\n */\nexport abstract class AbstractLayerBase<AdditionalEvents = {}>\n extends EventEmitter<LayerBaseEvents & AdditionalEvents>\n implements AnyLayerBaseType\n{\n #map: MapModelImpl | undefined;\n\n #id: string;\n #title: string;\n #description: string;\n #attributes: Record<string | symbol, unknown>;\n #destroyed = false;\n\n constructor(config: AbstractLayerBaseOptions) {\n super();\n this.#id = config.id ?? uuid4v();\n this.#attributes = config.attributes ?? {};\n this.#title = config.title;\n this.#description = config.description ?? \"\";\n }\n\n protected get __destroyed(): boolean {\n return this.#destroyed;\n }\n\n get map(): MapModelImpl {\n const map = this.#map;\n if (!map) {\n throw new Error(`Layer '${this.id}' has not been attached to a map yet.`);\n }\n return map;\n }\n\n get id(): string {\n return this.#id;\n }\n\n get title(): string {\n return this.#title;\n }\n\n get description(): string {\n return this.#description;\n }\n\n get attributes(): Record<string | symbol, unknown> {\n return this.#attributes;\n }\n\n abstract get type(): AnyLayerTypes;\n\n abstract get visible(): boolean;\n\n abstract get sublayers(): SublayersCollectionImpl<Sublayer & AbstractLayerBase> | undefined;\n\n abstract get legend(): string | undefined;\n\n destroy() {\n if (this.#destroyed) {\n return;\n }\n\n this.#destroyed = true;\n this.sublayers?.destroy();\n try {\n this.emit(\"destroy\");\n } catch (e) {\n LOG.warn(`Unexpected error from event listener during layer destruction:`, e);\n }\n }\n\n /**\n * Attaches the layer to its owning map.\n */\n protected __attachToMap(map: MapModelImpl): void {\n if (this.#map) {\n throw new Error(\n `Layer '${this.id}' has already been attached to the map '${this.map.id}'`\n );\n }\n this.#map = map;\n }\n\n setTitle(newTitle: string): void {\n if (newTitle !== this.#title) {\n this.#title = newTitle;\n this.__emitChangeEvent(\"changed:title\");\n }\n }\n\n setDescription(newDescription: string): void {\n if (newDescription !== this.#description) {\n this.#description = newDescription;\n this.__emitChangeEvent(\"changed:description\");\n }\n }\n\n updateAttributes(newAttributes: Record<string | symbol, unknown>): void {\n const attributes = this.#attributes;\n const keys = Reflect.ownKeys(newAttributes);\n\n let changed = false;\n for (const key of keys) {\n const existing = attributes[key];\n const value = newAttributes[key];\n if (existing !== value) {\n attributes[key] = value;\n changed = true;\n }\n }\n\n if (changed) {\n this.__emitChangeEvent(\"changed:attributes\");\n }\n }\n\n deleteAttribute(deleteAttribute: string | symbol): void {\n const attributes = this.#attributes;\n if (attributes[deleteAttribute]) {\n delete attributes[deleteAttribute];\n this.__emitChangeEvent(\"changed:attributes\");\n }\n }\n\n abstract setVisible(newVisibility: boolean): void;\n\n protected __emitChangeEvent<Name extends EventNames<LayerBaseEvents & AdditionalEvents>>(\n event: Name\n ) {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n (this as any).emit(event);\n this.emit(\"changed\");\n }\n}\n"],"names":["uuid4v"],"mappings":"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"}
1
+ {"version":3,"file":"AbstractLayerBase.js","sources":["AbstractLayerBase.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 reactiveMap,\n ReadonlyReactive\n} from \"@conterra/reactivity-core\";\nimport { createLogger, EventEmitter } from \"@open-pioneer/core\";\nimport { v4 as uuid4v } from \"uuid\";\nimport {\n AnyLayer,\n AnyLayerBaseType,\n AnyLayerTypes,\n ChildrenCollection,\n LayerBaseEvents,\n Sublayer\n} from \"../api\";\nimport { GroupLayer } from \"../api/layers/GroupLayer\";\nimport { GroupLayerCollectionImpl } from \"./layers/GroupLayerImpl\";\nimport { MapModelImpl } from \"./MapModelImpl\";\nimport { SublayersCollectionImpl } from \"./SublayersCollectionImpl\";\n\nconst LOG = createLogger(\"map:AbstractLayerModel\");\n\nexport interface AbstractLayerBaseOptions {\n id?: string;\n title: string;\n description?: string;\n attributes?: Record<string, unknown>;\n}\n\n/**\n * Base class for \"normal\" layers and sublayers alike to implement common properties\n * such as id, title and attributes.\n */\nexport abstract class AbstractLayerBase<AdditionalEvents = {}>\n extends EventEmitter<LayerBaseEvents & AdditionalEvents>\n implements AnyLayerBaseType\n{\n #map: MapModelImpl | undefined;\n #parent: AnyLayer | undefined;\n\n #id: string;\n #title: Reactive<string>;\n #description: Reactive<string>;\n #attributesMap = reactiveMap<string | symbol, unknown>();\n #attributes: ReadonlyReactive<Record<string | symbol, unknown>>;\n #destroyed = false;\n\n constructor(config: AbstractLayerBaseOptions) {\n super();\n this.#id = config.id ?? uuid4v();\n this.#attributes = computed(() => {\n return Object.fromEntries(this.#attributesMap.entries());\n });\n this.#title = reactive(config.title);\n this.#description = reactive(config.description ?? \"\");\n\n if (config.attributes) {\n this.updateAttributes(config.attributes);\n }\n }\n\n protected get __destroyed(): boolean {\n return this.#destroyed;\n }\n\n get map(): MapModelImpl {\n const map = this.#map;\n if (!map) {\n throw new Error(`Layer '${this.id}' has not been attached to a map yet.`);\n }\n return map;\n }\n\n get id(): string {\n return this.#id;\n }\n\n get title(): string {\n return this.#title.value;\n }\n\n get description(): string {\n return this.#description.value;\n }\n\n get attributes(): Record<string | symbol, unknown> {\n return this.#attributes.value;\n }\n\n get parent(): AnyLayer | undefined {\n return this.#parent;\n }\n\n get children(): ChildrenCollection<AnyLayer & AbstractLayerBase> | undefined {\n return this.layers ?? this.sublayers ?? undefined;\n }\n\n abstract get type(): AnyLayerTypes;\n\n abstract get visible(): boolean;\n\n abstract get layers(): GroupLayerCollectionImpl | undefined;\n\n abstract get sublayers(): SublayersCollectionImpl<Sublayer & AbstractLayerBase> | undefined;\n\n abstract get legend(): string | undefined;\n\n destroy() {\n if (this.#destroyed) {\n return;\n }\n\n this.#destroyed = true;\n this.sublayers?.destroy();\n this.layers?.destroy();\n try {\n this.emit(\"destroy\");\n } catch (e) {\n LOG.warn(`Unexpected error from event listener during layer destruction:`, e);\n }\n }\n\n /**\n * Attaches the layer to its owning map.\n */\n __attachToMap(map: MapModelImpl): void {\n if (this.#map) {\n throw new Error(\n `Layer '${this.id}' has already been attached to the map '${this.map.id}'`\n );\n }\n this.#map = map;\n }\n\n /**\n * Attach group layers to its parent group layer.\n * Called by the parent layer.\n */\n __attachToGroup(parent: GroupLayer): void {\n if (this.#parent) {\n throw new Error(\n `Layer '${this.id}' has already been attached to the group layer '${this.#parent.id}'`\n );\n }\n this.#parent = parent;\n }\n\n /**\n * Detach layer from parent group layer.\n *\n * Called by the parent group layer when destroyed or the layer gets removed.\n */\n __detachFromGroup(): void {\n this.#parent = undefined;\n }\n\n setTitle(newTitle: string): void {\n this.#title.value = newTitle;\n }\n\n setDescription(newDescription: string): void {\n this.#description.value = newDescription;\n }\n\n updateAttributes(newAttributes: Record<string | symbol, unknown>): void {\n const keys = Reflect.ownKeys(newAttributes);\n batch(() => {\n for (const key of keys) {\n this.#attributesMap.set(key, newAttributes[key]);\n }\n });\n }\n\n deleteAttribute(deleteAttribute: string | symbol): void {\n this.#attributesMap.delete(deleteAttribute);\n }\n\n abstract setVisible(newVisibility: boolean): void;\n}\n"],"names":["uuid4v"],"mappings":";;;;AAyBA,MAAM,GAAA,GAAM,aAAa,wBAAwB,CAAA,CAAA;AAa1C,MAAe,0BACV,YAEZ,CAAA;AAAA,EACI,IAAA,CAAA;AAAA,EACA,OAAA,CAAA;AAAA,EAEA,GAAA,CAAA;AAAA,EACA,MAAA,CAAA;AAAA,EACA,YAAA,CAAA;AAAA,EACA,iBAAiB,WAAsC,EAAA,CAAA;AAAA,EACvD,WAAA,CAAA;AAAA,EACA,UAAa,GAAA,KAAA,CAAA;AAAA,EAEb,YAAY,MAAkC,EAAA;AAC1C,IAAM,KAAA,EAAA,CAAA;AACN,IAAK,IAAA,CAAA,GAAA,GAAM,MAAO,CAAA,EAAA,IAAMA,EAAO,EAAA,CAAA;AAC/B,IAAK,IAAA,CAAA,WAAA,GAAc,SAAS,MAAM;AAC9B,MAAA,OAAO,MAAO,CAAA,WAAA,CAAY,IAAK,CAAA,cAAA,CAAe,SAAS,CAAA,CAAA;AAAA,KAC1D,CAAA,CAAA;AACD,IAAK,IAAA,CAAA,MAAA,GAAS,QAAS,CAAA,MAAA,CAAO,KAAK,CAAA,CAAA;AACnC,IAAA,IAAA,CAAK,YAAe,GAAA,QAAA,CAAS,MAAO,CAAA,WAAA,IAAe,EAAE,CAAA,CAAA;AAErD,IAAA,IAAI,OAAO,UAAY,EAAA;AACnB,MAAK,IAAA,CAAA,gBAAA,CAAiB,OAAO,UAAU,CAAA,CAAA;AAAA,KAC3C;AAAA,GACJ;AAAA,EAEA,IAAc,WAAuB,GAAA;AACjC,IAAA,OAAO,IAAK,CAAA,UAAA,CAAA;AAAA,GAChB;AAAA,EAEA,IAAI,GAAoB,GAAA;AACpB,IAAA,MAAM,MAAM,IAAK,CAAA,IAAA,CAAA;AACjB,IAAA,IAAI,CAAC,GAAK,EAAA;AACN,MAAA,MAAM,IAAI,KAAA,CAAM,CAAU,OAAA,EAAA,IAAA,CAAK,EAAE,CAAuC,qCAAA,CAAA,CAAA,CAAA;AAAA,KAC5E;AACA,IAAO,OAAA,GAAA,CAAA;AAAA,GACX;AAAA,EAEA,IAAI,EAAa,GAAA;AACb,IAAA,OAAO,IAAK,CAAA,GAAA,CAAA;AAAA,GAChB;AAAA,EAEA,IAAI,KAAgB,GAAA;AAChB,IAAA,OAAO,KAAK,MAAO,CAAA,KAAA,CAAA;AAAA,GACvB;AAAA,EAEA,IAAI,WAAsB,GAAA;AACtB,IAAA,OAAO,KAAK,YAAa,CAAA,KAAA,CAAA;AAAA,GAC7B;AAAA,EAEA,IAAI,UAA+C,GAAA;AAC/C,IAAA,OAAO,KAAK,WAAY,CAAA,KAAA,CAAA;AAAA,GAC5B;AAAA,EAEA,IAAI,MAA+B,GAAA;AAC/B,IAAA,OAAO,IAAK,CAAA,OAAA,CAAA;AAAA,GAChB;AAAA,EAEA,IAAI,QAAyE,GAAA;AACzE,IAAO,OAAA,IAAA,CAAK,MAAU,IAAA,IAAA,CAAK,SAAa,IAAA,KAAA,CAAA,CAAA;AAAA,GAC5C;AAAA,EAYA,OAAU,GAAA;AACN,IAAA,IAAI,KAAK,UAAY,EAAA;AACjB,MAAA,OAAA;AAAA,KACJ;AAEA,IAAA,IAAA,CAAK,UAAa,GAAA,IAAA,CAAA;AAClB,IAAA,IAAA,CAAK,WAAW,OAAQ,EAAA,CAAA;AACxB,IAAA,IAAA,CAAK,QAAQ,OAAQ,EAAA,CAAA;AACrB,IAAI,IAAA;AACA,MAAA,IAAA,CAAK,KAAK,SAAS,CAAA,CAAA;AAAA,aACd,CAAG,EAAA;AACR,MAAI,GAAA,CAAA,IAAA,CAAK,kEAAkE,CAAC,CAAA,CAAA;AAAA,KAChF;AAAA,GACJ;AAAA;AAAA;AAAA;AAAA,EAKA,cAAc,GAAyB,EAAA;AACnC,IAAA,IAAI,KAAK,IAAM,EAAA;AACX,MAAA,MAAM,IAAI,KAAA;AAAA,QACN,UAAU,IAAK,CAAA,EAAE,CAA2C,wCAAA,EAAA,IAAA,CAAK,IAAI,EAAE,CAAA,CAAA,CAAA;AAAA,OAC3E,CAAA;AAAA,KACJ;AACA,IAAA,IAAA,CAAK,IAAO,GAAA,GAAA,CAAA;AAAA,GAChB;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,gBAAgB,MAA0B,EAAA;AACtC,IAAA,IAAI,KAAK,OAAS,EAAA;AACd,MAAA,MAAM,IAAI,KAAA;AAAA,QACN,UAAU,IAAK,CAAA,EAAE,CAAmD,gDAAA,EAAA,IAAA,CAAK,QAAQ,EAAE,CAAA,CAAA,CAAA;AAAA,OACvF,CAAA;AAAA,KACJ;AACA,IAAA,IAAA,CAAK,OAAU,GAAA,MAAA,CAAA;AAAA,GACnB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,iBAA0B,GAAA;AACtB,IAAA,IAAA,CAAK,OAAU,GAAA,KAAA,CAAA,CAAA;AAAA,GACnB;AAAA,EAEA,SAAS,QAAwB,EAAA;AAC7B,IAAA,IAAA,CAAK,OAAO,KAAQ,GAAA,QAAA,CAAA;AAAA,GACxB;AAAA,EAEA,eAAe,cAA8B,EAAA;AACzC,IAAA,IAAA,CAAK,aAAa,KAAQ,GAAA,cAAA,CAAA;AAAA,GAC9B;AAAA,EAEA,iBAAiB,aAAuD,EAAA;AACpE,IAAM,MAAA,IAAA,GAAO,OAAQ,CAAA,OAAA,CAAQ,aAAa,CAAA,CAAA;AAC1C,IAAA,KAAA,CAAM,MAAM;AACR,MAAA,KAAA,MAAW,OAAO,IAAM,EAAA;AACpB,QAAA,IAAA,CAAK,cAAe,CAAA,GAAA,CAAI,GAAK,EAAA,aAAA,CAAc,GAAG,CAAC,CAAA,CAAA;AAAA,OACnD;AAAA,KACH,CAAA,CAAA;AAAA,GACL;AAAA,EAEA,gBAAgB,eAAwC,EAAA;AACpD,IAAK,IAAA,CAAA,cAAA,CAAe,OAAO,eAAe,CAAA,CAAA;AAAA,GAC9C;AAGJ;;;;"}
@@ -2,6 +2,7 @@ import { Feature } from "ol";
2
2
  import OlMap from "ol/Map";
3
3
  import { Geometry } from "ol/geom";
4
4
  import VectorLayer from "ol/layer/Vector";
5
+ import VectorSource from "ol/source/Vector";
5
6
  import { DisplayTarget, HighlightOptions, HighlightZoomOptions, ZoomOptions } from "../api/MapModel";
6
7
  export declare class Highlights {
7
8
  #private;
@@ -14,7 +15,7 @@ export declare class Highlights {
14
15
  * Getter for Hightlightlayer
15
16
  * @returns Highlights.olLayer
16
17
  */
17
- getLayer(): VectorLayer<Feature<Geometry>>;
18
+ getLayer(): VectorLayer<VectorSource<Feature<Geometry>>, Feature<Geometry>>;
18
19
  /**
19
20
  * This method removes all highlights before destroying the class
20
21
  */
@@ -8,6 +8,8 @@ import mapMarkerUrl from '../assets/images/mapMarker.png?url';
8
8
  import './AbstractLayer.js';
9
9
  import './layers/WMSLayerImpl.js';
10
10
  import './layers/WMTSLayerImpl.js';
11
+ import 'ol/layer.js';
12
+ import './AbstractLayerBase.js';
11
13
  import 'ol/proj/proj4.js';
12
14
  import 'proj4';
13
15
  import 'ol/source/WMTS.js';
@@ -1 +1 @@
1
- {"version":3,"file":"Highlights.js","sources":["Highlights.ts"],"sourcesContent":["// SPDX-FileCopyrightText: 2023 Open Pioneer project (https://github.com/open-pioneer)\n// SPDX-License-Identifier: Apache-2.0\n\nimport { Feature } from \"ol\";\nimport OlMap from \"ol/Map\";\nimport { Coordinate } from \"ol/coordinate\";\nimport { Extent, createEmpty, extend, getArea, getCenter } from \"ol/extent\";\nimport { Geometry } from \"ol/geom\";\nimport VectorLayer from \"ol/layer/Vector\";\nimport VectorSource from \"ol/source/Vector\";\nimport { Fill, Icon, Stroke, Style } from \"ol/style\";\nimport { toFunction as toStyleFunction } from \"ol/style/Style\";\nimport {\n DisplayTarget,\n Highlight,\n HighlightOptions,\n HighlightStyle,\n HighlightZoomOptions,\n ZoomOptions\n} from \"../api/MapModel\";\nimport mapMarkerUrl from \"../assets/images/mapMarker.png?url\";\nimport { FeatureLike } from \"ol/Feature\";\nimport { TOPMOST_LAYER_Z } from \"../api\";\nimport { Type } from \"ol/geom/Geometry\";\n\ntype HighlightStyleType = keyof HighlightStyle;\n\nconst DEFAULT_OL_POINT_ZOOM_LEVEL = 17;\nconst DEFAULT_OL_MAX_ZOOM_LEVEL = 20;\nconst DEFAULT_VIEW_PADDING = { top: 50, right: 20, bottom: 10, left: 20 };\n\nexport class Highlights {\n private olMap: OlMap;\n\n private olLayer: VectorLayer<Feature>;\n private olSource: VectorSource<Feature<Geometry>>;\n private activeHighlights: Set<Highlight>;\n\n constructor(olMap: OlMap) {\n this.olMap = olMap;\n this.olSource = new VectorSource({\n features: undefined\n });\n this.olLayer = new VectorLayer({\n className: \"highlight-layer\",\n source: this.olSource,\n style: function (feature, resolution) {\n return resolveStyle(feature, resolution);\n }\n });\n this.activeHighlights = new Set();\n this.olLayer.setZIndex(TOPMOST_LAYER_Z);\n this.olMap.addLayer(this.olLayer);\n }\n\n /**\n * Getter for Hightlightlayer\n * @returns Highlights.olLayer\n */\n getLayer() {\n return this.olLayer;\n }\n\n /**\n * This method removes all highlights before destroying the class\n */\n destroy() {\n this.clearHighlight();\n }\n\n /**\n * Method of filtering out objects that are not geometry or have no property geometry.\n */\n #filterGeoobjects(geoObjects: DisplayTarget[]): Geometry[] {\n const geometries: Geometry[] = [];\n geoObjects.forEach((item) => {\n if (\"getType\" in item) geometries.push(item);\n if (\"geometry\" in item && item.geometry) geometries.push(item.geometry);\n });\n return geometries;\n }\n\n /**\n * This method displays geometries or BaseFeatures with optional styling in the map\n */\n addHighlight(displayTarget: DisplayTarget[], highlightOptions: HighlightOptions | undefined) {\n const geometries = this.#filterGeoobjects(displayTarget);\n\n if (geometries.length === 0) {\n return {\n get isActive() {\n return false;\n },\n destroy() {}\n };\n }\n\n const features = geometries.map((geometry) => {\n const type = geometry.getType();\n const feature = new Feature({\n type: type,\n geometry: geometry\n });\n feature.setStyle(getOwnStyle(type, highlightOptions?.highlightStyle));\n return feature;\n });\n\n const source = this.olSource;\n const highlights = this.activeHighlights;\n const highlight: Highlight = {\n get isActive() {\n return highlights.has(highlight);\n },\n destroy() {\n if (!this.isActive) {\n return;\n }\n\n for (const feature of features) {\n source.removeFeature(feature);\n }\n highlights.delete(highlight);\n }\n };\n\n source.addFeatures(features);\n this.activeHighlights.add(highlight);\n return highlight;\n }\n\n /**\n * This method zoom to geometries or BaseFeatures\n */\n zoomToHighlight(displayTarget: DisplayTarget[], options: ZoomOptions | undefined) {\n const geometries = this.#filterGeoobjects(displayTarget);\n\n if (geometries.length === 0) {\n return;\n }\n\n let extent = createEmpty();\n for (const geometry of geometries) {\n extent = extend(extent, geometry!.getExtent());\n }\n\n const center = getCenter(extent);\n const isPoint = getArea(extent) === 0;\n const zoomScale = isPoint\n ? (options?.pointZoom ?? DEFAULT_OL_POINT_ZOOM_LEVEL)\n : (options?.maxZoom ?? DEFAULT_OL_MAX_ZOOM_LEVEL);\n setCenter(this.olMap, center);\n\n const {\n top = 0,\n right = 0,\n bottom = 0,\n left = 0\n } = options?.viewPadding ?? DEFAULT_VIEW_PADDING;\n const padding = [top, right, bottom, left];\n zoomTo(this.olMap, extent, zoomScale, padding);\n }\n\n /**\n * This method displays geometries or BaseFeatures with optional styling in the map and executed a zoom\n */\n addHighlightAndZoom(\n displayTarget: DisplayTarget[],\n highlightZoomStyle: HighlightZoomOptions | undefined\n ) {\n const result = this.addHighlight(displayTarget, highlightZoomStyle);\n this.zoomToHighlight(displayTarget, highlightZoomStyle);\n return result;\n }\n\n clearHighlight() {\n for (const highlight of this.activeHighlights) {\n highlight.destroy();\n }\n }\n}\n\nfunction setCenter(olMap: OlMap, coordinates: Coordinate | undefined) {\n coordinates && coordinates.length && olMap.getView().setCenter(coordinates);\n}\n\nfunction zoomTo(\n olMap: OlMap,\n extent: Extent | undefined,\n zoomLevel: number | undefined,\n padding: number[]\n) {\n if (extent) {\n olMap.getView().fit(extent, { maxZoom: zoomLevel, padding: padding });\n } else {\n zoomLevel && olMap.getView().setZoom(zoomLevel);\n }\n}\n\n/**\n * Returns the appropriate style from the user's highlightStyle or falls back to the default style\n */\nfunction resolveStyle(feature: FeatureLike, resolution: number) {\n const type: keyof typeof defaultHighlightStyle = feature.get(\"type\");\n const style = toStyleFunction(getDefaultStyle(type));\n return style(feature, resolution);\n}\n\n/**\n * This method creates styling for a highlight based on the optional style information or the default style\n */\nfunction getOwnStyle(type: Type, highlightStyle: HighlightStyle | undefined) {\n if (highlightStyle && type in highlightStyle) {\n const supportedType = type as HighlightStyleType;\n const ownStyle = highlightStyle[supportedType];\n return ownStyle ? ownStyle : getDefaultStyle(type);\n } else {\n return getDefaultStyle(type);\n }\n}\n\n/**\n * This returns default styling for a highlight\n */\nfunction getDefaultStyle(type: Type) {\n if (type in defaultHighlightStyle) {\n const supportedType = type as HighlightStyleType;\n return defaultHighlightStyle[supportedType];\n } else {\n return defaultHighlightStyle.Polygon;\n }\n}\n\n/**\n * Default styling for highlights\n */\nconst defaultHighlightStyle = {\n \"Point\": new Style({\n image: new Icon({\n anchor: [0.5, 1],\n src: mapMarkerUrl\n })\n }),\n \"MultiPoint\": new Style({\n image: new Icon({\n anchor: [0.5, 1],\n src: mapMarkerUrl\n })\n }),\n \"LineString\": [\n new Style({\n stroke: new Stroke({\n color: \"#fff\",\n width: 5\n })\n }),\n new Style({\n stroke: new Stroke({\n color: \"#00ffff\",\n width: 3\n })\n })\n ],\n \"MultiLineString\": [\n new Style({\n stroke: new Stroke({\n color: \"#fff\",\n width: 5\n })\n }),\n new Style({\n stroke: new Stroke({\n color: \"#00ffff\",\n width: 3\n })\n })\n ],\n \"Polygon\": [\n new Style({\n stroke: new Stroke({\n color: \"#fff\",\n width: 5\n })\n }),\n new Style({\n stroke: new Stroke({\n color: \"#00ffff\",\n width: 3\n }),\n fill: new Fill({\n color: \"rgba(224,255,255,0.35)\"\n })\n })\n ],\n \"MultiPolygon\": [\n new Style({\n stroke: new Stroke({\n color: \"#fff\",\n width: 5\n })\n }),\n new Style({\n stroke: new Stroke({\n color: \"#00ffff\",\n width: 3\n }),\n fill: new Fill({\n color: \"rgba(224,255,255,0.35)\"\n })\n })\n ]\n};\n"],"names":["toStyleFunction"],"mappings":"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"}
1
+ {"version":3,"file":"Highlights.js","sources":["Highlights.ts"],"sourcesContent":["// SPDX-FileCopyrightText: 2023 Open Pioneer project (https://github.com/open-pioneer)\n// SPDX-License-Identifier: Apache-2.0\n\nimport { Feature } from \"ol\";\nimport OlMap from \"ol/Map\";\nimport { Coordinate } from \"ol/coordinate\";\nimport { Extent, createEmpty, extend, getArea, getCenter } from \"ol/extent\";\nimport { Geometry } from \"ol/geom\";\nimport VectorLayer from \"ol/layer/Vector\";\nimport VectorSource from \"ol/source/Vector\";\nimport { Fill, Icon, Stroke, Style } from \"ol/style\";\nimport { toFunction as toStyleFunction } from \"ol/style/Style\";\nimport {\n DisplayTarget,\n Highlight,\n HighlightOptions,\n HighlightStyle,\n HighlightZoomOptions,\n ZoomOptions\n} from \"../api/MapModel\";\nimport mapMarkerUrl from \"../assets/images/mapMarker.png?url\";\nimport { FeatureLike } from \"ol/Feature\";\nimport { TOPMOST_LAYER_Z } from \"../api\";\nimport { Type } from \"ol/geom/Geometry\";\n\ntype HighlightStyleType = keyof HighlightStyle;\n\nconst DEFAULT_OL_POINT_ZOOM_LEVEL = 17;\nconst DEFAULT_OL_MAX_ZOOM_LEVEL = 20;\nconst DEFAULT_VIEW_PADDING = { top: 50, right: 20, bottom: 10, left: 20 };\n\nexport class Highlights {\n private olMap: OlMap;\n\n private olLayer: VectorLayer<VectorSource, Feature>;\n private olSource: VectorSource<Feature<Geometry>>;\n private activeHighlights: Set<Highlight>;\n\n constructor(olMap: OlMap) {\n this.olMap = olMap;\n this.olSource = new VectorSource({\n features: undefined\n });\n this.olLayer = new VectorLayer({\n className: \"highlight-layer\",\n source: this.olSource,\n style: function (feature, resolution) {\n return resolveStyle(feature, resolution);\n }\n });\n this.activeHighlights = new Set();\n this.olLayer.setZIndex(TOPMOST_LAYER_Z);\n this.olMap.addLayer(this.olLayer);\n }\n\n /**\n * Getter for Hightlightlayer\n * @returns Highlights.olLayer\n */\n getLayer() {\n return this.olLayer;\n }\n\n /**\n * This method removes all highlights before destroying the class\n */\n destroy() {\n this.clearHighlight();\n }\n\n /**\n * Method of filtering out objects that are not geometry or have no property geometry.\n */\n #filterGeoobjects(geoObjects: DisplayTarget[]): Geometry[] {\n const geometries: Geometry[] = [];\n geoObjects.forEach((item) => {\n if (\"getType\" in item) geometries.push(item);\n if (\"geometry\" in item && item.geometry) geometries.push(item.geometry);\n });\n return geometries;\n }\n\n /**\n * This method displays geometries or BaseFeatures with optional styling in the map\n */\n addHighlight(displayTarget: DisplayTarget[], highlightOptions: HighlightOptions | undefined) {\n const geometries = this.#filterGeoobjects(displayTarget);\n\n if (geometries.length === 0) {\n return {\n get isActive() {\n return false;\n },\n destroy() {}\n };\n }\n\n const features = geometries.map((geometry) => {\n const type = geometry.getType();\n const feature = new Feature({\n type: type,\n geometry: geometry\n });\n feature.setStyle(getOwnStyle(type, highlightOptions?.highlightStyle));\n return feature;\n });\n\n const source = this.olSource;\n const highlights = this.activeHighlights;\n const highlight: Highlight = {\n get isActive() {\n return highlights.has(highlight);\n },\n destroy() {\n if (!this.isActive) {\n return;\n }\n\n for (const feature of features) {\n source.removeFeature(feature);\n }\n highlights.delete(highlight);\n }\n };\n\n source.addFeatures(features);\n this.activeHighlights.add(highlight);\n return highlight;\n }\n\n /**\n * This method zoom to geometries or BaseFeatures\n */\n zoomToHighlight(displayTarget: DisplayTarget[], options: ZoomOptions | undefined) {\n const geometries = this.#filterGeoobjects(displayTarget);\n\n if (geometries.length === 0) {\n return;\n }\n\n let extent = createEmpty();\n for (const geometry of geometries) {\n extent = extend(extent, geometry!.getExtent());\n }\n\n const center = getCenter(extent);\n const isPoint = getArea(extent) === 0;\n const zoomScale = isPoint\n ? (options?.pointZoom ?? DEFAULT_OL_POINT_ZOOM_LEVEL)\n : (options?.maxZoom ?? DEFAULT_OL_MAX_ZOOM_LEVEL);\n setCenter(this.olMap, center);\n\n const {\n top = 0,\n right = 0,\n bottom = 0,\n left = 0\n } = options?.viewPadding ?? DEFAULT_VIEW_PADDING;\n const padding = [top, right, bottom, left];\n zoomTo(this.olMap, extent, zoomScale, padding);\n }\n\n /**\n * This method displays geometries or BaseFeatures with optional styling in the map and executed a zoom\n */\n addHighlightAndZoom(\n displayTarget: DisplayTarget[],\n highlightZoomStyle: HighlightZoomOptions | undefined\n ) {\n const result = this.addHighlight(displayTarget, highlightZoomStyle);\n this.zoomToHighlight(displayTarget, highlightZoomStyle);\n return result;\n }\n\n clearHighlight() {\n for (const highlight of this.activeHighlights) {\n highlight.destroy();\n }\n }\n}\n\nfunction setCenter(olMap: OlMap, coordinates: Coordinate | undefined) {\n coordinates && coordinates.length && olMap.getView().setCenter(coordinates);\n}\n\nfunction zoomTo(\n olMap: OlMap,\n extent: Extent | undefined,\n zoomLevel: number | undefined,\n padding: number[]\n) {\n if (extent) {\n olMap.getView().fit(extent, { maxZoom: zoomLevel, padding: padding });\n } else {\n zoomLevel && olMap.getView().setZoom(zoomLevel);\n }\n}\n\n/**\n * Returns the appropriate style from the user's highlightStyle or falls back to the default style\n */\nfunction resolveStyle(feature: FeatureLike, resolution: number) {\n const type: keyof typeof defaultHighlightStyle = feature.get(\"type\");\n const style = toStyleFunction(getDefaultStyle(type));\n return style(feature, resolution);\n}\n\n/**\n * This method creates styling for a highlight based on the optional style information or the default style\n */\nfunction getOwnStyle(type: Type, highlightStyle: HighlightStyle | undefined) {\n if (highlightStyle && type in highlightStyle) {\n const supportedType = type as HighlightStyleType;\n const ownStyle = highlightStyle[supportedType];\n return ownStyle ? ownStyle : getDefaultStyle(type);\n } else {\n return getDefaultStyle(type);\n }\n}\n\n/**\n * This returns default styling for a highlight\n */\nfunction getDefaultStyle(type: Type) {\n if (type in defaultHighlightStyle) {\n const supportedType = type as HighlightStyleType;\n return defaultHighlightStyle[supportedType];\n } else {\n return defaultHighlightStyle.Polygon;\n }\n}\n\n/**\n * Default styling for highlights\n */\nconst defaultHighlightStyle = {\n \"Point\": new Style({\n image: new Icon({\n anchor: [0.5, 1],\n src: mapMarkerUrl\n })\n }),\n \"MultiPoint\": new Style({\n image: new Icon({\n anchor: [0.5, 1],\n src: mapMarkerUrl\n })\n }),\n \"LineString\": [\n new Style({\n stroke: new Stroke({\n color: \"#fff\",\n width: 5\n })\n }),\n new Style({\n stroke: new Stroke({\n color: \"#00ffff\",\n width: 3\n })\n })\n ],\n \"MultiLineString\": [\n new Style({\n stroke: new Stroke({\n color: \"#fff\",\n width: 5\n })\n }),\n new Style({\n stroke: new Stroke({\n color: \"#00ffff\",\n width: 3\n })\n })\n ],\n \"Polygon\": [\n new Style({\n stroke: new Stroke({\n color: \"#fff\",\n width: 5\n })\n }),\n new Style({\n stroke: new Stroke({\n color: \"#00ffff\",\n width: 3\n }),\n fill: new Fill({\n color: \"rgba(224,255,255,0.35)\"\n })\n })\n ],\n \"MultiPolygon\": [\n new Style({\n stroke: new Stroke({\n color: \"#fff\",\n width: 5\n })\n }),\n new Style({\n stroke: new Stroke({\n color: \"#00ffff\",\n width: 3\n }),\n fill: new Fill({\n color: \"rgba(224,255,255,0.35)\"\n })\n })\n ]\n};\n"],"names":["toStyleFunction"],"mappings":"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"}
@@ -1,6 +1,5 @@
1
- import { EventEmitter } from "@open-pioneer/core";
2
1
  import OlBaseLayer from "ol/layer/Base";
3
- import { LayerCollection, LayerCollectionEvents, Layer, LayerRetrievalOptions, AnyLayer } from "../api";
2
+ import { Layer, LayerCollection, LayerRetrievalOptions, AnyLayer } from "../api";
4
3
  import { MapModelImpl } from "./MapModelImpl";
5
4
  /**
6
5
  * Z index for layers that should always be rendered on top of all other layers.
@@ -9,7 +8,10 @@ import { MapModelImpl } from "./MapModelImpl";
9
8
  * @internal
10
9
  */
11
10
  export declare const TOPMOST_LAYER_Z = 9999999;
12
- export declare class LayerCollectionImpl extends EventEmitter<LayerCollectionEvents> implements LayerCollection {
11
+ /**
12
+ * Manages the (top-level) content of the map.
13
+ */
14
+ export declare class LayerCollectionImpl implements LayerCollection {
13
15
  #private;
14
16
  constructor(map: MapModelImpl);
15
17
  destroy(): void;