@open-pioneer/map 0.11.0 → 0.12.0-dev.20250905090001
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 +101 -5
- package/MapRegistryImpl.js.map +1 -1
- package/README.md +32 -20
- package/api/MapModel.d.ts +5 -0
- package/api/index.d.ts +1 -1
- package/api/layers/GroupLayer.js.map +1 -1
- package/api/layers/SimpleLayer.js.map +1 -1
- package/api/layers/WMSLayer.js.map +1 -1
- package/api/layers/WMTSLayer.js.map +1 -1
- package/api/layers/base.d.ts +17 -0
- package/api/layers/base.js.map +1 -1
- package/api/shared.d.ts +6 -4
- package/index.js +1 -1
- package/model/AbstractLayer.js.map +1 -1
- package/model/AbstractLayerBase.d.ts +3 -0
- package/model/AbstractLayerBase.js +8 -0
- package/model/AbstractLayerBase.js.map +1 -1
- package/model/Highlights.js +9 -1
- package/model/Highlights.js.map +1 -1
- package/model/LayerCollectionImpl.js +52 -24
- package/model/LayerCollectionImpl.js.map +1 -1
- package/model/MapModelImpl.js.map +1 -1
- package/model/SublayersCollectionImpl.js.map +1 -1
- package/model/createMapModel.js.map +1 -1
- package/model/getRecursiveLayers.js.map +1 -1
- package/model/layers/GroupLayerImpl.js.map +1 -1
- package/model/layers/SimpleLayerImpl.js.map +1 -1
- package/model/layers/WMSLayerImpl.js.map +1 -1
- package/model/layers/WMTSLayerImpl.js.map +1 -1
- package/package.json +6 -7
- package/projections.d.ts +3 -1
- package/projections.js.map +1 -1
- package/ui/DefaultMapProvider.d.ts +3 -2
- package/ui/DefaultMapProvider.js +7 -13
- package/ui/DefaultMapProvider.js.map +1 -1
- package/ui/MapAnchor.js.map +1 -1
- package/ui/MapContainer.d.ts +2 -0
- package/ui/MapContainer.js +4 -16
- package/ui/MapContainer.js.map +1 -1
- package/ui/MapContainerContext.js.map +1 -1
- package/ui/computeMapAnchorStyles.js.map +1 -1
- package/ui/useMapModel.d.ts +28 -22
- package/ui/useMapModel.js +31 -29
- package/ui/useMapModel.js.map +1 -1
- package/util/capabilities-utils.js.map +1 -1
- package/util/geometry-utils.js.map +1 -1
- package/util/ol-test-support.js.map +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AbstractLayerBase.js","sources":["AbstractLayerBase.ts"],"sourcesContent":["// SPDX-FileCopyrightText: 2023-2025 Open Pioneer project (https://github.com/open-pioneer)\n// SPDX-License-Identifier: Apache-2.0\nimport {\n batch,\n computed,\n reactive,\n Reactive,\n reactiveMap,\n ReadonlyReactive\n} from \"@conterra/reactivity-core\";\nimport { 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;
|
|
1
|
+
{"version":3,"file":"AbstractLayerBase.js","sources":["AbstractLayerBase.ts"],"sourcesContent":["// SPDX-FileCopyrightText: 2023-2025 Open Pioneer project (https://github.com/open-pioneer)\n// SPDX-License-Identifier: Apache-2.0\nimport {\n batch,\n computed,\n reactive,\n Reactive,\n reactiveMap,\n ReadonlyReactive\n} from \"@conterra/reactivity-core\";\nimport { 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 internal?: boolean;\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 #internal: Reactive<boolean>;\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 this.#internal = reactive(config.internal ?? false);\n\n if (config.attributes) {\n this.updateAttributes(config.attributes);\n }\n }\n\n get internal(): boolean {\n return this.#internal.value;\n }\n\n setInternal(newIsInternal: boolean): void {\n this.#internal.value = newIsInternal;\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":"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"}
|
package/model/Highlights.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Feature } from 'ol';
|
|
2
|
-
import { createEmpty, extend, getCenter, getArea } from 'ol/extent.js';
|
|
2
|
+
import { createEmpty, extend, buffer, getCenter, getArea } from 'ol/extent.js';
|
|
3
3
|
import VectorLayer from 'ol/layer/Vector.js';
|
|
4
4
|
import VectorSource from 'ol/source/Vector.js';
|
|
5
5
|
import { Style, Stroke, Fill, Icon } from 'ol/style.js';
|
|
@@ -128,6 +128,14 @@ class Highlights {
|
|
|
128
128
|
for (const geometry of geometries) {
|
|
129
129
|
extent = extend(extent, geometry.getExtent());
|
|
130
130
|
}
|
|
131
|
+
const bufferParameter = options?.buffer;
|
|
132
|
+
if (typeof bufferParameter === "number" && extent.length === 4) {
|
|
133
|
+
const width = extent[2] && extent[0] ? extent[2] - extent[0] : 0;
|
|
134
|
+
const height = extent[3] && extent[1] ? extent[3] - extent[1] : 0;
|
|
135
|
+
const maxDim = Math.max(width, height);
|
|
136
|
+
const bufferSize = maxDim * bufferParameter;
|
|
137
|
+
extent = buffer(extent, bufferSize);
|
|
138
|
+
}
|
|
131
139
|
const center = getCenter(extent);
|
|
132
140
|
const isPoint = getArea(extent) === 0;
|
|
133
141
|
const zoomScale = isPoint ? options?.pointZoom ?? DEFAULT_OL_POINT_ZOOM_LEVEL : options?.maxZoom ?? DEFAULT_OL_MAX_ZOOM_LEVEL;
|
package/model/Highlights.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Highlights.js","sources":["Highlights.ts"],"sourcesContent":["// SPDX-FileCopyrightText: 2023-2025 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
|
+
{"version":3,"file":"Highlights.js","sources":["Highlights.ts"],"sourcesContent":["// SPDX-FileCopyrightText: 2023-2025 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\";\nimport { buffer } from \"ol/extent\";\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 bufferParameter = options?.buffer;\n if (typeof bufferParameter === \"number\" && extent.length === 4) {\n // calculate the buffer size based on the maximum dimension of the extent\n const width = extent[2] && extent[0] ? extent[2] - extent[0] : 0;\n const height = extent[3] && extent[1] ? extent[3] - extent[1] : 0;\n const maxDim = Math.max(width, height);\n const bufferSize = maxDim * bufferParameter; //bufferSize in map units for ol buffer function\n extent = buffer(extent, bufferSize);\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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"}
|
|
@@ -18,8 +18,11 @@ class LayerCollectionImpl {
|
|
|
18
18
|
/**
|
|
19
19
|
* Defines the relative order of operational layers.
|
|
20
20
|
* Lower index -> layer is below its successors.
|
|
21
|
+
* Excluding {@link #topMostOperationalLayers}
|
|
21
22
|
*/
|
|
22
23
|
#operationalLayerOrder = reactiveArray();
|
|
24
|
+
/** Operational layers that are always displayed at the top above all other layers (e.g. a highlight layer) */
|
|
25
|
+
#topMostOperationalLayers = reactiveArray();
|
|
23
26
|
#syncHandle;
|
|
24
27
|
constructor(map) {
|
|
25
28
|
this.#map = map;
|
|
@@ -85,7 +88,8 @@ class LayerCollectionImpl {
|
|
|
85
88
|
if (options?.sortByDisplayOrder) {
|
|
86
89
|
const baseLayers = this.getBaseLayers();
|
|
87
90
|
const order = Array.from(this.#operationalLayerOrder);
|
|
88
|
-
|
|
91
|
+
const topMost = Array.from(this.#topMostOperationalLayers);
|
|
92
|
+
return [...baseLayers, ...order, ...topMost];
|
|
89
93
|
} else {
|
|
90
94
|
return Array.from(this.#topLevelLayers.values());
|
|
91
95
|
}
|
|
@@ -136,9 +140,9 @@ class LayerCollectionImpl {
|
|
|
136
140
|
* Adds the given layer to the map and all relevant indices.
|
|
137
141
|
*/
|
|
138
142
|
#addLayer(model, options) {
|
|
139
|
-
const
|
|
143
|
+
const pos = this.#getInsertionPos(model, options);
|
|
140
144
|
this.#indexLayer(model);
|
|
141
|
-
if (
|
|
145
|
+
if (pos.which === "base") {
|
|
142
146
|
if (!this.#activeBaseLayer.value && model.visible) {
|
|
143
147
|
this.#updateBaseLayer(model);
|
|
144
148
|
} else {
|
|
@@ -146,45 +150,42 @@ class LayerCollectionImpl {
|
|
|
146
150
|
}
|
|
147
151
|
} else {
|
|
148
152
|
model.__setVisible(model.visible);
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
"Internal error: insertion index is undefined for operational layer."
|
|
152
|
-
);
|
|
153
|
-
}
|
|
154
|
-
this.#operationalLayerOrder.splice(operationalLayerIndex, 0, model);
|
|
153
|
+
const layerList = this.#getLayerList(pos);
|
|
154
|
+
layerList.splice(pos.index, 0, model);
|
|
155
155
|
}
|
|
156
156
|
this.#topLevelLayers.add(model);
|
|
157
157
|
this.#map.olMap.addLayer(model.olLayer);
|
|
158
158
|
}
|
|
159
|
-
#
|
|
159
|
+
#getInsertionPos(model, options) {
|
|
160
160
|
if (model.isBaseLayer) {
|
|
161
161
|
if (options?.at) {
|
|
162
162
|
throw new Error(
|
|
163
163
|
`Cannot add base layer '${model.id}' at a specific position: only operational layers can be added at a specific position.`
|
|
164
164
|
);
|
|
165
165
|
}
|
|
166
|
-
return
|
|
166
|
+
return { which: "base" };
|
|
167
167
|
}
|
|
168
168
|
switch (options?.at) {
|
|
169
169
|
case void 0:
|
|
170
170
|
case null:
|
|
171
171
|
case "top":
|
|
172
|
-
return this.#operationalLayerOrder.length;
|
|
172
|
+
return { which: "normal", index: this.#operationalLayerOrder.length };
|
|
173
|
+
case "topmost":
|
|
174
|
+
return { which: "topmost", index: this.#topMostOperationalLayers.length };
|
|
173
175
|
case "bottom":
|
|
174
|
-
return 0;
|
|
176
|
+
return { which: "normal", index: 0 };
|
|
175
177
|
case "above":
|
|
176
178
|
case "below": {
|
|
177
179
|
const reference = this.#getReference(options.reference);
|
|
178
|
-
|
|
179
|
-
if (
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
);
|
|
180
|
+
const pos = this.#findOpOrTopmost(reference);
|
|
181
|
+
if (!pos) {
|
|
182
|
+
const errorMessage = this.#getInsertErrorMessage(model, reference);
|
|
183
|
+
throw new Error(errorMessage);
|
|
183
184
|
}
|
|
184
185
|
if (options.at === "above") {
|
|
185
|
-
index++;
|
|
186
|
+
pos.index++;
|
|
186
187
|
}
|
|
187
|
-
return
|
|
188
|
+
return pos;
|
|
188
189
|
}
|
|
189
190
|
}
|
|
190
191
|
assertNever();
|
|
@@ -222,10 +223,9 @@ class LayerCollectionImpl {
|
|
|
222
223
|
this.#map.olMap.removeLayer(model.olLayer);
|
|
223
224
|
this.#topLevelLayers.delete(model);
|
|
224
225
|
if (!model.isBaseLayer) {
|
|
225
|
-
const
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
}
|
|
226
|
+
const pos = this.#findOpOrTopmost(model);
|
|
227
|
+
const layerList = this.#getLayerList(pos);
|
|
228
|
+
layerList.splice(pos.index, 1);
|
|
229
229
|
}
|
|
230
230
|
this.#unIndexLayer(model);
|
|
231
231
|
if (this.#activeBaseLayer.value === model) {
|
|
@@ -313,6 +313,34 @@ class LayerCollectionImpl {
|
|
|
313
313
|
};
|
|
314
314
|
visit(model);
|
|
315
315
|
}
|
|
316
|
+
#getLayerList(pos) {
|
|
317
|
+
switch (pos.which) {
|
|
318
|
+
case "topmost":
|
|
319
|
+
return this.#topMostOperationalLayers;
|
|
320
|
+
case "normal":
|
|
321
|
+
return this.#operationalLayerOrder;
|
|
322
|
+
}
|
|
323
|
+
}
|
|
324
|
+
#findOpOrTopmost(layer) {
|
|
325
|
+
let index = this.#operationalLayerOrder.indexOf(layer);
|
|
326
|
+
if (index !== -1) {
|
|
327
|
+
return { which: "normal", index };
|
|
328
|
+
}
|
|
329
|
+
index = this.#topMostOperationalLayers.indexOf(layer);
|
|
330
|
+
if (index !== -1) {
|
|
331
|
+
return { which: "topmost", index };
|
|
332
|
+
}
|
|
333
|
+
return void 0;
|
|
334
|
+
}
|
|
335
|
+
#getInsertErrorMessage(layer, reference) {
|
|
336
|
+
let message = `Cannot add layer '${layer.id}'. Reference layer '${reference.id}' is not a top level operational layer.`;
|
|
337
|
+
if (reference.isBaseLayer) {
|
|
338
|
+
message += " Reference layer is a base layer.";
|
|
339
|
+
} else if (reference.parent) {
|
|
340
|
+
message += " Reference layer is child layer of a group.";
|
|
341
|
+
}
|
|
342
|
+
return message;
|
|
343
|
+
}
|
|
316
344
|
}
|
|
317
345
|
function checkLayerInstance(object) {
|
|
318
346
|
if (!(object instanceof AbstractLayer)) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"LayerCollectionImpl.js","sources":["LayerCollectionImpl.ts"],"sourcesContent":["// SPDX-FileCopyrightText: 2023-2025 Open Pioneer project (https://github.com/open-pioneer)\n// SPDX-License-Identifier: Apache-2.0\nimport {\n batch,\n effect,\n reactive,\n reactiveArray,\n reactiveMap,\n reactiveSet\n} from \"@conterra/reactivity-core\";\nimport { createLogger, Resource } from \"@open-pioneer/core\";\nimport OlBaseLayer from \"ol/layer/Base\";\nimport {\n AddLayerOptions,\n AnyLayer,\n Layer,\n LayerCollection,\n LayerRetrievalOptions,\n Sublayer\n} from \"../api\";\nimport { AbstractLayer } from \"./AbstractLayer\";\nimport { AbstractLayerBase } from \"./AbstractLayerBase\";\nimport { MapModelImpl } from \"./MapModelImpl\";\nimport { getRecursiveLayers } from \"./getRecursiveLayers\";\n\nconst LOG = createLogger(\"map:LayerCollection\");\n\ntype LayerType = AbstractLayer & Layer;\ntype LayerBaseType = (AbstractLayerBase & Layer) | (AbstractLayerBase & Sublayer);\n\n/**\n * Z index for layers that should always be rendered on top of all other layers.\n * Note that this is an internal, unstable property!\n *\n * @internal\n */\nexport const TOPMOST_LAYER_Z = 9999999;\n\n/**\n * Manages the (top-level) content of the map.\n */\nexport class LayerCollectionImpl implements LayerCollection {\n #map: MapModelImpl;\n\n /** Top level layers (base layers, operational layers). No sublayers. */\n #topLevelLayers = reactiveSet<LayerType>();\n\n /** Index of _all_ layer instances, including sublayers. */\n #layersById = reactiveMap<string, LayerBaseType>();\n\n /** Reverse index of _all_ layers that have an associated OpenLayers layer. */\n #layersByOlLayer: WeakMap<OlBaseLayer, LayerType> = new WeakMap();\n\n /** Currently active base layer. */\n #activeBaseLayer = reactive<LayerType>();\n\n /**\n * Defines the relative order of operational layers.\n * Lower index -> layer is below its successors.\n */\n #operationalLayerOrder = reactiveArray<LayerType>();\n\n #syncHandle: Resource | undefined;\n\n constructor(map: MapModelImpl) {\n this.#map = map;\n this.#syncHandle = effect(() => {\n const orderedLayers = this.getLayers({ sortByDisplayOrder: true });\n\n // Simply reassign all z-indices whenever the order changes.\n let index = 0;\n for (const layer of orderedLayers) {\n LOG.isDebug() && LOG.debug(\"Assigning z-index\", layer.id, index);\n layer.olLayer.setZIndex(index);\n index++;\n }\n });\n }\n\n destroy() {\n // Collection is destroyed together with the map, there is no need to clean up the olMap\n for (const layer of this.#layersById.values()) {\n layer.destroy();\n }\n this.#topLevelLayers.clear();\n this.#layersById.clear();\n this.#operationalLayerOrder.splice(0, this.#operationalLayerOrder.length);\n this.#activeBaseLayer.value = undefined;\n this.#syncHandle?.destroy();\n this.#syncHandle = undefined;\n }\n\n addLayer(layer: Layer, options?: AddLayerOptions): void {\n checkLayerInstance(layer);\n\n layer.__attachToMap(this.#map);\n this.#addLayer(layer, options);\n }\n\n getBaseLayers(): Layer[] {\n // Slightly inefficient, but we don't need a separate index for base layers right now.\n return Array.from(this.#topLevelLayers).filter((layer) => layer.isBaseLayer);\n }\n\n getActiveBaseLayer(): Layer | undefined {\n return this.#activeBaseLayer.value;\n }\n\n activateBaseLayer(id: string | undefined): boolean {\n let newBaseLayer = undefined;\n if (id != null) {\n newBaseLayer = this.#layersById.get(id);\n if (!(newBaseLayer instanceof AbstractLayer)) {\n LOG.warn(`Cannot activate base layer '${id}: layer has an invalid type.'`);\n return false;\n }\n if (!newBaseLayer) {\n LOG.warn(`Cannot activate base layer '${id}': layer is unknown.`);\n return false;\n }\n if (!newBaseLayer.isBaseLayer) {\n LOG.warn(`Cannot activate base layer '${id}': layer is not a base layer.`);\n return false;\n }\n }\n\n this.#updateBaseLayer(newBaseLayer);\n return true;\n }\n\n getOperationalLayers(options?: LayerRetrievalOptions): Layer[] {\n return this.getLayers(options).filter((layer) => !layer.isBaseLayer);\n }\n\n getItems(options?: LayerRetrievalOptions): Layer[] {\n return this.getLayers(options);\n }\n\n getLayers(options?: LayerRetrievalOptions): Layer[] {\n if (options?.sortByDisplayOrder) {\n const baseLayers = this.getBaseLayers();\n const order = Array.from(this.#operationalLayerOrder);\n return [...baseLayers, ...order];\n } else {\n return Array.from(this.#topLevelLayers.values());\n }\n }\n\n getAllLayers(options?: LayerRetrievalOptions): Layer[] {\n return this.getLayers(options);\n }\n\n getRecursiveLayers({\n filter,\n sortByDisplayOrder\n }: LayerRetrievalOptions & {\n filter?: \"base\" | \"operational\" | ((layer: AnyLayer) => boolean);\n } = {}): AnyLayer[] {\n let filterFunc;\n if (typeof filter === \"function\") {\n filterFunc = filter;\n } else if (typeof filter === \"string\") {\n const filterType = filter;\n const topLevelFilter = (layer: Layer) => {\n return filterType === \"base\" ? layer.isBaseLayer : !layer.isBaseLayer;\n };\n filterFunc = (layer: AnyLayer) => {\n if (!layer.parent && \"isBaseLayer\" in layer) {\n return topLevelFilter(layer);\n }\n // For nested children, include them all.\n return true;\n };\n }\n\n return getRecursiveLayers({\n from: this,\n filter: filterFunc,\n sortByDisplayOrder\n });\n }\n\n getLayerById(id: string): AnyLayer | undefined {\n return this.#layersById.get(id);\n }\n\n removeLayerById(id: string): void {\n const model = this.#layersById.get(id);\n if (!model) {\n LOG.isDebug() && LOG.debug(`Cannot remove layer '${id}': layer is unknown.`);\n return;\n }\n\n this.#removeLayer(model);\n }\n\n getLayerByRawInstance(layer: OlBaseLayer): Layer | undefined {\n return this.#layersByOlLayer?.get(layer);\n }\n\n /**\n * Adds the given layer to the map and all relevant indices.\n */\n #addLayer(model: LayerType, options: AddLayerOptions | undefined) {\n // Throws; do this before manipulating the data structures\n const operationalLayerIndex = this.#getInsertionIndex(model, options);\n this.#indexLayer(model);\n\n // Everything below this line should not fail.\n if (model.isBaseLayer) {\n if (!this.#activeBaseLayer.value && model.visible) {\n this.#updateBaseLayer(model);\n } else {\n model.__setVisible(false);\n }\n } else {\n model.__setVisible(model.visible);\n\n if (operationalLayerIndex == null) {\n throw new Error(\n \"Internal error: insertion index is undefined for operational layer.\"\n );\n }\n this.#operationalLayerOrder.splice(operationalLayerIndex, 0, model);\n }\n\n this.#topLevelLayers.add(model);\n this.#map.olMap.addLayer(model.olLayer);\n }\n\n #getInsertionIndex(model: LayerType, options: AddLayerOptions | undefined): number | undefined {\n if (model.isBaseLayer) {\n if (options?.at) {\n throw new Error(\n `Cannot add base layer '${model.id}' at a specific position: only operational layers can be added at a specific position.`\n );\n }\n return undefined;\n }\n\n switch (options?.at) {\n case undefined:\n case null:\n case \"top\":\n return this.#operationalLayerOrder.length;\n case \"bottom\":\n return 0;\n case \"above\":\n case \"below\": {\n const reference = this.#getReference(options.reference);\n let index = this.#operationalLayerOrder.indexOf(reference);\n if (index === -1) {\n throw new Error(\n `Reference layer '${reference.id}' not found in operation layers.`\n );\n }\n if (options.at === \"above\") {\n index++;\n }\n return index;\n }\n }\n assertNever(options);\n }\n\n #getReference(reference: Layer | string): LayerType {\n let layer: AnyLayer;\n if (typeof reference === \"string\") {\n const refLayer = this.getLayerById(reference);\n if (!refLayer) {\n throw new Error(`Unknown reference layer '${reference}'.`);\n }\n layer = refLayer;\n } else {\n layer = reference;\n }\n checkLayerInstance(layer);\n return layer;\n }\n\n /**\n * Removes the given layer from the map and all relevant indices.\n * The layer will be destroyed.\n */\n #removeLayer(model: LayerType | LayerBaseType) {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n if (!this.#topLevelLayers.has(model as any)) {\n LOG.warn(\n `Cannot remove layer '${model.id}': only top level layers can be removed at this time.`\n );\n return;\n }\n\n if (!(model instanceof AbstractLayer)) {\n throw new Error(\n `Internal error: expected top level layer to be an instance of AbstractLayer.`\n );\n }\n\n this.#map.olMap.removeLayer(model.olLayer);\n this.#topLevelLayers.delete(model);\n if (!model.isBaseLayer) {\n const index = this.#operationalLayerOrder.indexOf(model);\n if (index !== -1) {\n this.#operationalLayerOrder.splice(index, 1);\n }\n }\n\n this.#unIndexLayer(model);\n if (this.#activeBaseLayer.value === model) {\n const newBaseLayer = this.getBaseLayers()[0];\n if (newBaseLayer) {\n checkLayerInstance(newBaseLayer);\n }\n this.#updateBaseLayer(newBaseLayer);\n }\n model.destroy();\n }\n\n #updateBaseLayer(model: LayerType | undefined) {\n if (this.#activeBaseLayer.value === model) {\n return;\n }\n\n if (LOG.isDebug()) {\n const getId = (model: AbstractLayer | undefined) => {\n return model ? `'${model.id}'` : undefined;\n };\n\n LOG.debug(\n `Switching active base layer from ${getId(this.#activeBaseLayer.value)} to ${getId(model)}`\n );\n }\n\n batch(() => {\n this.#activeBaseLayer.value?.__setVisible(false);\n this.#activeBaseLayer.value = model;\n model?.__setVisible(true);\n });\n }\n\n /**\n * Index the layer and all its children.\n */\n #indexLayer(model: LayerType) {\n // layer id -> layer (or sublayer)\n const registrations: [string, OlBaseLayer | undefined][] = [];\n const visit = (model: LayerType | (AbstractLayerBase & Sublayer)) => {\n const id = model.id;\n const olLayer = \"olLayer\" in model ? model.olLayer : undefined;\n if (this.#layersById.has(id)) {\n throw new Error(\n `Layer id '${id}' is not unique. Either assign a unique id yourself ` +\n `or skip configuring 'id' for an automatically generated id.`\n );\n }\n if (olLayer && this.#layersByOlLayer.has(olLayer)) {\n throw new Error(`OlLayer used by layer '${id}' has already been used in map.`);\n }\n\n // Register this layer with the maps.\n this.#layersById.set(id, model);\n if (olLayer) {\n this.#layersByOlLayer.set(olLayer, model as LayerType); // ol is present --> not a sublayer\n }\n registrations.push([id, olLayer]);\n\n // Recurse into nested children.\n for (const layer of model.layers?.__getRawLayers() ?? []) {\n visit(layer);\n }\n for (const sublayer of model.sublayers?.__getRawSublayers() ?? []) {\n visit(sublayer);\n }\n };\n\n try {\n visit(model);\n } catch (e) {\n // If any error happens, undo the indexing.\n // This way we don't leave a partially indexed layer tree behind.\n for (const [id, olLayer] of registrations) {\n this.#layersById.delete(id);\n if (olLayer) {\n this.#layersByOlLayer.delete(olLayer);\n }\n }\n throw e;\n }\n }\n\n /**\n * Removes index entries for the given layer and all its children.\n */\n #unIndexLayer(model: AbstractLayer) {\n const visit = (model: AbstractLayer | AbstractLayerBase) => {\n if (\"olLayer\" in model) {\n this.#layersByOlLayer.delete(model.olLayer);\n }\n this.#layersById.delete(model.id);\n\n for (const layer of model.layers?.__getRawLayers() ?? []) {\n visit(layer);\n }\n\n for (const sublayer of model.sublayers?.__getRawSublayers() ?? []) {\n visit(sublayer);\n }\n };\n visit(model);\n }\n}\n\nfunction checkLayerInstance(object: AnyLayer): asserts object is Layer & AbstractLayer {\n if (!(object instanceof AbstractLayer)) {\n throw new Error(\n `Layer is not a valid layer instance. Use one of the classes provided by the map package instead.`\n );\n }\n}\n\nfunction assertNever(_arg: never): never {\n throw new Error(`Internal error: unhandled option.`);\n}\n"],"names":["model"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"LayerCollectionImpl.js","sources":["LayerCollectionImpl.ts"],"sourcesContent":["// SPDX-FileCopyrightText: 2023-2025 Open Pioneer project (https://github.com/open-pioneer)\n// SPDX-License-Identifier: Apache-2.0\nimport {\n batch,\n effect,\n reactive,\n ReactiveArray,\n reactiveArray,\n reactiveMap,\n reactiveSet\n} from \"@conterra/reactivity-core\";\nimport { createLogger, Resource } from \"@open-pioneer/core\";\nimport OlBaseLayer from \"ol/layer/Base\";\nimport {\n AddLayerOptions,\n AnyLayer,\n Layer,\n LayerCollection,\n LayerRetrievalOptions,\n Sublayer\n} from \"../api\";\nimport { AbstractLayer } from \"./AbstractLayer\";\nimport { AbstractLayerBase } from \"./AbstractLayerBase\";\nimport { MapModelImpl } from \"./MapModelImpl\";\nimport { getRecursiveLayers } from \"./getRecursiveLayers\";\n\nconst LOG = createLogger(\"map:LayerCollection\");\n\ntype LayerType = AbstractLayer & Layer;\ntype LayerBaseType = (AbstractLayerBase & Layer) | (AbstractLayerBase & Sublayer);\n\ninterface OpOrTopmostLayerPos {\n which: \"normal\" | \"topmost\";\n index: number;\n}\n\ninterface BaseLayerPos {\n which: \"base\";\n}\n\ntype LayerPos = OpOrTopmostLayerPos | BaseLayerPos;\n\n/**\n * Z index for layers that should always be rendered on top of all other layers.\n * Note that this is an internal, unstable property!\n *\n * @internal\n */\nexport const TOPMOST_LAYER_Z = 9999999;\n\n/**\n * Manages the (top-level) content of the map.\n */\nexport class LayerCollectionImpl implements LayerCollection {\n #map: MapModelImpl;\n\n /** Top level layers (base layers, operational layers). No sublayers. */\n #topLevelLayers = reactiveSet<LayerType>();\n\n /** Index of _all_ layer instances, including sublayers. */\n #layersById = reactiveMap<string, LayerBaseType>();\n\n /** Reverse index of _all_ layers that have an associated OpenLayers layer. */\n #layersByOlLayer: WeakMap<OlBaseLayer, LayerType> = new WeakMap();\n\n /** Currently active base layer. */\n #activeBaseLayer = reactive<LayerType>();\n\n /**\n * Defines the relative order of operational layers.\n * Lower index -> layer is below its successors.\n * Excluding {@link #topMostOperationalLayers}\n */\n #operationalLayerOrder = reactiveArray<LayerType>();\n\n /** Operational layers that are always displayed at the top above all other layers (e.g. a highlight layer) */\n #topMostOperationalLayers = reactiveArray<LayerType>();\n\n #syncHandle: Resource | undefined;\n\n constructor(map: MapModelImpl) {\n this.#map = map;\n this.#syncHandle = effect(() => {\n // Contains base layers, normal operational layers, topmost layers in bottom-to-top order.\n const orderedLayers = this.getLayers({ sortByDisplayOrder: true });\n\n // Simply reassign all z-indices whenever the order changes.\n let index = 0;\n for (const layer of orderedLayers) {\n LOG.isDebug() && LOG.debug(\"Assigning z-index\", layer.id, index);\n layer.olLayer.setZIndex(index);\n index++;\n }\n });\n }\n\n destroy() {\n // Collection is destroyed together with the map, there is no need to clean up the olMap\n for (const layer of this.#layersById.values()) {\n layer.destroy();\n }\n this.#topLevelLayers.clear();\n this.#layersById.clear();\n this.#operationalLayerOrder.splice(0, this.#operationalLayerOrder.length);\n this.#activeBaseLayer.value = undefined;\n this.#syncHandle?.destroy();\n this.#syncHandle = undefined;\n }\n\n addLayer(layer: Layer, options?: AddLayerOptions): void {\n checkLayerInstance(layer);\n\n layer.__attachToMap(this.#map);\n this.#addLayer(layer, options);\n }\n\n getBaseLayers(): Layer[] {\n // Slightly inefficient, but we don't need a separate index for base layers right now.\n return Array.from(this.#topLevelLayers).filter((layer) => layer.isBaseLayer);\n }\n\n getActiveBaseLayer(): Layer | undefined {\n return this.#activeBaseLayer.value;\n }\n\n activateBaseLayer(id: string | undefined): boolean {\n let newBaseLayer = undefined;\n if (id != null) {\n newBaseLayer = this.#layersById.get(id);\n if (!(newBaseLayer instanceof AbstractLayer)) {\n LOG.warn(`Cannot activate base layer '${id}: layer has an invalid type.'`);\n return false;\n }\n if (!newBaseLayer) {\n LOG.warn(`Cannot activate base layer '${id}': layer is unknown.`);\n return false;\n }\n if (!newBaseLayer.isBaseLayer) {\n LOG.warn(`Cannot activate base layer '${id}': layer is not a base layer.`);\n return false;\n }\n }\n\n this.#updateBaseLayer(newBaseLayer);\n return true;\n }\n\n getOperationalLayers(options?: LayerRetrievalOptions): Layer[] {\n return this.getLayers(options).filter((layer) => !layer.isBaseLayer);\n }\n\n getItems(options?: LayerRetrievalOptions): Layer[] {\n return this.getLayers(options);\n }\n\n getLayers(options?: LayerRetrievalOptions): Layer[] {\n if (options?.sortByDisplayOrder) {\n const baseLayers = this.getBaseLayers();\n const order = Array.from(this.#operationalLayerOrder);\n const topMost = Array.from(this.#topMostOperationalLayers);\n return [...baseLayers, ...order, ...topMost];\n } else {\n return Array.from(this.#topLevelLayers.values());\n }\n }\n\n getAllLayers(options?: LayerRetrievalOptions): Layer[] {\n return this.getLayers(options);\n }\n\n getRecursiveLayers({\n filter,\n sortByDisplayOrder\n }: LayerRetrievalOptions & {\n filter?: \"base\" | \"operational\" | ((layer: AnyLayer) => boolean);\n } = {}): AnyLayer[] {\n let filterFunc;\n if (typeof filter === \"function\") {\n filterFunc = filter;\n } else if (typeof filter === \"string\") {\n const filterType = filter;\n const topLevelFilter = (layer: Layer) => {\n return filterType === \"base\" ? layer.isBaseLayer : !layer.isBaseLayer;\n };\n filterFunc = (layer: AnyLayer) => {\n if (!layer.parent && \"isBaseLayer\" in layer) {\n return topLevelFilter(layer);\n }\n // For nested children, include them all.\n return true;\n };\n }\n\n return getRecursiveLayers({\n from: this,\n filter: filterFunc,\n sortByDisplayOrder\n });\n }\n\n getLayerById(id: string): AnyLayer | undefined {\n return this.#layersById.get(id);\n }\n\n removeLayerById(id: string): void {\n const model = this.#layersById.get(id);\n if (!model) {\n LOG.isDebug() && LOG.debug(`Cannot remove layer '${id}': layer is unknown.`);\n return;\n }\n\n this.#removeLayer(model);\n }\n\n getLayerByRawInstance(layer: OlBaseLayer): Layer | undefined {\n return this.#layersByOlLayer?.get(layer);\n }\n\n /**\n * Adds the given layer to the map and all relevant indices.\n */\n #addLayer(model: LayerType, options: AddLayerOptions | undefined) {\n // Throws; do this before manipulating the data structures\n const pos = this.#getInsertionPos(model, options);\n this.#indexLayer(model);\n\n // Everything below this line should not fail.\n if (pos.which === \"base\") {\n if (!this.#activeBaseLayer.value && model.visible) {\n this.#updateBaseLayer(model);\n } else {\n model.__setVisible(false);\n }\n } else {\n model.__setVisible(model.visible);\n\n const layerList = this.#getLayerList(pos);\n layerList.splice(pos.index, 0, model); // insert new layer at insertion index\n }\n this.#topLevelLayers.add(model);\n this.#map.olMap.addLayer(model.olLayer);\n }\n\n #getInsertionPos(model: LayerType, options: AddLayerOptions | undefined): LayerPos {\n if (model.isBaseLayer) {\n if (options?.at) {\n throw new Error(\n `Cannot add base layer '${model.id}' at a specific position: only operational layers can be added at a specific position.`\n );\n }\n return { which: \"base\" };\n }\n\n switch (options?.at) {\n case undefined:\n case null:\n case \"top\":\n return { which: \"normal\", index: this.#operationalLayerOrder.length };\n case \"topmost\":\n return { which: \"topmost\", index: this.#topMostOperationalLayers.length };\n case \"bottom\":\n return { which: \"normal\", index: 0 };\n case \"above\":\n case \"below\": {\n const reference = this.#getReference(options.reference);\n const pos = this.#findOpOrTopmost(reference);\n if (!pos) {\n // reference is not a top level operational layer -> throw error\n const errorMessage = this.#getInsertErrorMessage(model, reference);\n throw new Error(errorMessage);\n }\n\n if (options.at === \"above\") {\n pos.index++;\n }\n return pos;\n }\n }\n assertNever(options);\n }\n\n #getReference(reference: Layer | string): LayerType {\n let layer: AnyLayer;\n if (typeof reference === \"string\") {\n const refLayer = this.getLayerById(reference);\n if (!refLayer) {\n throw new Error(`Unknown reference layer '${reference}'.`);\n }\n layer = refLayer;\n } else {\n layer = reference;\n }\n checkLayerInstance(layer);\n return layer;\n }\n\n /**\n * Removes the given layer from the map and all relevant indices.\n * The layer will be destroyed.\n */\n #removeLayer(model: LayerType | LayerBaseType) {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n if (!this.#topLevelLayers.has(model as any)) {\n LOG.warn(\n `Cannot remove layer '${model.id}': only top level layers can be removed at this time.`\n );\n return;\n }\n\n if (!(model instanceof AbstractLayer)) {\n throw new Error(\n `Internal error: expected top level layer to be an instance of AbstractLayer.`\n );\n }\n\n this.#map.olMap.removeLayer(model.olLayer);\n this.#topLevelLayers.delete(model);\n if (!model.isBaseLayer) {\n const pos = this.#findOpOrTopmost(model)!;\n const layerList = this.#getLayerList(pos);\n layerList.splice(pos.index, 1);\n }\n\n this.#unIndexLayer(model);\n if (this.#activeBaseLayer.value === model) {\n const newBaseLayer = this.getBaseLayers()[0];\n if (newBaseLayer) {\n checkLayerInstance(newBaseLayer);\n }\n this.#updateBaseLayer(newBaseLayer);\n }\n\n model.destroy();\n }\n\n #updateBaseLayer(model: LayerType | undefined) {\n if (this.#activeBaseLayer.value === model) {\n return;\n }\n\n if (LOG.isDebug()) {\n const getId = (model: AbstractLayer | undefined) => {\n return model ? `'${model.id}'` : undefined;\n };\n\n LOG.debug(\n `Switching active base layer from ${getId(this.#activeBaseLayer.value)} to ${getId(model)}`\n );\n }\n\n batch(() => {\n this.#activeBaseLayer.value?.__setVisible(false);\n this.#activeBaseLayer.value = model;\n model?.__setVisible(true);\n });\n }\n\n /**\n * Index the layer and all its children.\n */\n #indexLayer(model: LayerType) {\n // layer id -> layer (or sublayer)\n const registrations: [string, OlBaseLayer | undefined][] = [];\n const visit = (model: LayerType | (AbstractLayerBase & Sublayer)) => {\n const id = model.id;\n const olLayer = \"olLayer\" in model ? model.olLayer : undefined;\n if (this.#layersById.has(id)) {\n throw new Error(\n `Layer id '${id}' is not unique. Either assign a unique id yourself ` +\n `or skip configuring 'id' for an automatically generated id.`\n );\n }\n if (olLayer && this.#layersByOlLayer.has(olLayer)) {\n throw new Error(`OlLayer used by layer '${id}' has already been used in map.`);\n }\n\n // Register this layer with the maps.\n this.#layersById.set(id, model);\n if (olLayer) {\n this.#layersByOlLayer.set(olLayer, model as LayerType); // ol is present --> not a sublayer\n }\n registrations.push([id, olLayer]);\n\n // Recurse into nested children.\n for (const layer of model.layers?.__getRawLayers() ?? []) {\n visit(layer);\n }\n for (const sublayer of model.sublayers?.__getRawSublayers() ?? []) {\n visit(sublayer);\n }\n };\n\n try {\n visit(model);\n } catch (e) {\n // If any error happens, undo the indexing.\n // This way we don't leave a partially indexed layer tree behind.\n for (const [id, olLayer] of registrations) {\n this.#layersById.delete(id);\n if (olLayer) {\n this.#layersByOlLayer.delete(olLayer);\n }\n }\n throw e;\n }\n }\n\n /**\n * Removes index entries for the given layer and all its children.\n */\n #unIndexLayer(model: AbstractLayer) {\n const visit = (model: AbstractLayer | AbstractLayerBase) => {\n if (\"olLayer\" in model) {\n this.#layersByOlLayer.delete(model.olLayer);\n }\n this.#layersById.delete(model.id);\n\n for (const layer of model.layers?.__getRawLayers() ?? []) {\n visit(layer);\n }\n\n for (const sublayer of model.sublayers?.__getRawSublayers() ?? []) {\n visit(sublayer);\n }\n };\n visit(model);\n }\n\n #getLayerList(pos: OpOrTopmostLayerPos): ReactiveArray<LayerType> {\n switch (pos.which) {\n case \"topmost\":\n return this.#topMostOperationalLayers;\n case \"normal\":\n return this.#operationalLayerOrder;\n }\n }\n\n #findOpOrTopmost(layer: LayerType): OpOrTopmostLayerPos | undefined {\n let index = this.#operationalLayerOrder.indexOf(layer);\n if (index !== -1) {\n return { which: \"normal\", index };\n }\n\n index = this.#topMostOperationalLayers.indexOf(layer);\n if (index !== -1) {\n return { which: \"topmost\", index };\n }\n return undefined;\n }\n\n #getInsertErrorMessage(layer: LayerType, reference: LayerType) {\n let message: string = `Cannot add layer '${layer.id}'. Reference layer '${reference.id}' is not a top level operational layer.`;\n\n if (reference.isBaseLayer) {\n //is base layer\n message += \" Reference layer is a base layer.\";\n } else if (reference.parent) {\n //is child layer\n message += \" Reference layer is child layer of a group.\";\n }\n\n return message;\n }\n}\n\nfunction checkLayerInstance(object: AnyLayer): asserts object is Layer & AbstractLayer {\n if (!(object instanceof AbstractLayer)) {\n throw new Error(\n `Layer is not a valid layer instance. Use one of the classes provided by the map package instead.`\n );\n }\n}\n\nfunction assertNever(_arg: never): never {\n throw new Error(`Internal error: unhandled option.`);\n}\n"],"names":["model"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MapModelImpl.js","sources":["MapModelImpl.ts"],"sourcesContent":["// SPDX-FileCopyrightText: 2023-2025 Open Pioneer project (https://github.com/open-pioneer)\n// SPDX-License-Identifier: Apache-2.0\nimport { computed, reactive, ReadonlyReactive, synchronized } from \"@conterra/reactivity-core\";\nimport {\n createAbortError,\n createLogger,\n createManualPromise,\n EventEmitter,\n isAbortError,\n ManualPromise\n} from \"@open-pioneer/core\";\nimport { HttpService } from \"@open-pioneer/http\";\nimport OlMap from \"ol/Map\";\nimport { unByKey } from \"ol/Observable\";\nimport OlView from \"ol/View\";\nimport { Coordinate } from \"ol/coordinate\";\nimport { EventsKey } from \"ol/events\";\nimport { getCenter } from \"ol/extent\";\nimport { Geometry } from \"ol/geom\";\nimport { getPointResolution, Projection } from \"ol/proj\";\nimport {\n ExtentConfig,\n Highlight,\n HighlightOptions,\n HighlightZoomOptions,\n MapModel,\n MapModelEvents\n} from \"../api\";\nimport { Highlights } from \"./Highlights\";\nimport { LayerCollectionImpl } from \"./LayerCollectionImpl\";\n\nconst LOG = createLogger(\"map:MapModel\");\n\nconst DEFAULT_DPI = 25.4 / 0.28;\nconst INCHES_PER_METRE = 39.37;\n\n/**\n * Shared services or other entities propagated from the map model to all layer instances.\n */\nexport interface SharedDependencies {\n httpService: HttpService;\n}\n\nexport class MapModelImpl extends EventEmitter<MapModelEvents> implements MapModel {\n readonly #id: string;\n readonly #olMap: OlMap;\n readonly #olView: ReadonlyReactive<OlView>;\n readonly #layers = new LayerCollectionImpl(this);\n readonly #highlights: Highlights;\n readonly #sharedDeps: SharedDependencies;\n\n #destroyed = false;\n #container: ReadonlyReactive<HTMLElement | undefined>;\n #initialExtent = reactive<ExtentConfig>();\n #viewBindings: ReadonlyReactive<ViewBindings>;\n #scale: ReadonlyReactive<number | undefined>;\n\n readonly #abortController = new AbortController();\n #displayStatus: \"waiting\" | \"ready\" | \"error\";\n #displayWaiter: ManualPromise<void> | undefined;\n\n constructor(properties: {\n id: string;\n olMap: OlMap;\n initialExtent: ExtentConfig | undefined;\n httpService: HttpService;\n }) {\n super();\n this.#id = properties.id;\n this.#olMap = properties.olMap;\n this.#olView = synchronized(\n () => this.#olMap.getView(),\n (cb) => {\n const key = this.#olMap.on(\"change:view\", cb);\n return () => unByKey(key);\n }\n );\n this.#initialExtent.value = properties.initialExtent;\n this.#sharedDeps = {\n httpService: properties.httpService\n };\n this.#highlights = new Highlights(this.#olMap);\n\n this.#displayStatus = \"waiting\";\n this.#initializeView().then(\n () => {\n this.#displayStatus = \"ready\";\n this.#displayWaiter?.resolve();\n this.#displayWaiter = undefined;\n },\n (error) => {\n if (!isAbortError(error)) {\n LOG.error(`Failed to initialize map`, error);\n }\n\n this.#displayStatus = \"error\";\n this.#displayWaiter?.reject(new Error(`Failed to initialize map.`));\n this.#displayWaiter = undefined;\n }\n );\n\n this.#container = synchronized(\n () => this.#olMap.getTargetElement() ?? undefined,\n (cb) => {\n const key = this.#olMap.on(\"change:target\", cb);\n return () => unByKey(key);\n }\n );\n\n this.#viewBindings = computed(() => createViewBindings(this.#olView.value));\n this.#scale = computed(() => {\n const { projection, resolution, center } = this;\n if (projection == null || resolution == null || center == null) {\n return undefined;\n }\n\n /**\n * Returns the appropriate scale for the given resolution and units, see OpenLayers function getScaleForResolution()\n * https://github.com/openlayers/openlayers/blob/7fa9df03431e9e1bc517e6c414565d9f848a3132/src/ol/control/ScaleLine.js#L454C3-L454C24\n */\n const pointResolution = getPointResolution(projection, resolution, center, \"m\"); //point resolution in meter per pixel\n const scale = Math.round(pointResolution * INCHES_PER_METRE * DEFAULT_DPI);\n return scale;\n });\n }\n\n destroy() {\n if (this.#destroyed) {\n return;\n }\n\n this.#destroyed = true;\n try {\n this.emit(\"destroy\");\n } catch (e) {\n LOG.warn(`Unexpected error from event listener during map model destruction:`, e);\n }\n\n this.#abortController.abort();\n this.#displayWaiter?.reject(new Error(\"Map model was destroyed.\"));\n this.#layers.destroy();\n this.#highlights.destroy();\n this.#olMap.dispose();\n }\n\n get id(): string {\n return this.#id;\n }\n\n get olMap(): OlMap {\n return this.#olMap;\n }\n\n get olView(): OlView {\n return this.#olView.value;\n }\n\n get projection(): Projection {\n return this.#viewBindings.value.projection;\n }\n\n get center(): Coordinate | undefined {\n return this.#viewBindings.value.center.value;\n }\n\n get resolution(): number | undefined {\n return this.#viewBindings.value.resolution.value;\n }\n\n get zoomLevel(): number | undefined {\n return this.#viewBindings.value.zoom.value;\n }\n\n get scale(): number | undefined {\n return this.#scale.value;\n }\n\n get layers(): LayerCollectionImpl {\n return this.#layers;\n }\n\n get container(): HTMLElement | undefined {\n return this.#container.value;\n }\n\n get initialExtent(): ExtentConfig | undefined {\n return this.#initialExtent.value;\n }\n\n get __sharedDependencies(): SharedDependencies {\n return this.#sharedDeps;\n }\n\n setScale(newScale: number): void {\n const view = this.olView;\n const projection = this.projection;\n const center = this.center;\n if (!center) {\n return;\n }\n\n const mpu = projection.getMetersPerUnit() ?? 1;\n const resolution = INCHES_PER_METRE * DEFAULT_DPI * mpu;\n const pointResolution = newScale / getPointResolution(projection, resolution, center);\n view.setResolution(pointResolution);\n }\n\n highlight(geometries: Geometry[], options?: HighlightOptions | undefined): Highlight {\n return this.#highlights.addHighlight(geometries, options);\n }\n\n zoom(geometries: Geometry[], options?: HighlightZoomOptions | undefined): void {\n this.#highlights.zoomToHighlight(geometries, options);\n }\n\n highlightAndZoom(geometries: Geometry[], options?: HighlightZoomOptions) {\n return this.#highlights.addHighlightAndZoom(geometries, options ?? {});\n }\n\n removeHighlights() {\n this.#highlights.clearHighlight();\n }\n\n whenDisplayed(): Promise<void> {\n if (this.#destroyed) {\n return Promise.reject(new Error(\"Map model was destroyed.\"));\n }\n if (this.#displayStatus === \"error\") {\n return Promise.reject(new Error(`Failed to initialize map.`));\n }\n if (this.#displayStatus === \"ready\") {\n return Promise.resolve();\n }\n return (this.#displayWaiter ??= createManualPromise()).promise;\n }\n\n /**\n * Waits for the map to be displayed and then initializes the view (if necessary).\n *\n * May simply resolve when done, or throw an error when a problem occurs.\n * AbortError is thrown when cancelled via `this.#abortController`, for example\n * when the map model is destroyed before it has ever been displayed.\n */\n async #initializeView(): Promise<void> {\n try {\n await waitForMapSize(this.olMap, this.#abortController.signal); // may throw on cancel\n } catch (e) {\n if (isAbortError(e)) {\n throw e;\n }\n throw new Error(`Failed to wait for the map to be displayed.`, { cause: e });\n }\n\n try {\n const olMap = this.#olMap;\n const view = olMap.getView();\n\n if (this.#initialExtent.value) {\n // Initial extent was set from the outside. We simply ensure that it gets displayed by the map.\n const extent = this.#initialExtent.value;\n const olExtent = [extent.xMin, extent.yMin, extent.xMax, extent.yMax];\n\n const olCenter = getCenter(olExtent);\n const resolution = view.getResolutionForExtent(olExtent);\n LOG.debug(`Applying initial extent`, extent);\n LOG.debug(` Computed center:`, olCenter);\n LOG.debug(` Computed resolution:`, resolution);\n\n view.setCenter(olCenter);\n view.setResolution(resolution);\n } else {\n // Initial extent was NOT set from the outside.\n // We detect whatever the view is displaying and consider it to be the initial extent.\n const olExtent = view.calculateExtent();\n const [xMin = 0, yMin = 0, xMax = 0, yMax = 0] = olExtent;\n const extent: ExtentConfig = { xMin, yMin, xMax, yMax };\n LOG.debug(`Detected initial extent`, extent);\n\n this.#initialExtent.value = extent;\n }\n } catch (e) {\n throw new Error(`Failed to apply the initial extent.`, { cause: e });\n }\n }\n}\n\ninterface ViewBindings {\n resolution: ReadonlyReactive<number | undefined>;\n center: ReadonlyReactive<Coordinate | undefined>;\n zoom: ReadonlyReactive<number | undefined>;\n projection: Projection; // not reactive (change view to change projection)\n}\n\nfunction createViewBindings(view: OlView): ViewBindings {\n return {\n resolution: synchronized(\n () => view.getResolution(),\n (cb) => {\n const key = view.on(\"change:resolution\", cb);\n return () => unByKey(key);\n }\n ),\n center: synchronized(\n () => view.getCenter(),\n (cb) => {\n const key = view.on(\"change:center\", cb);\n return () => unByKey(key);\n }\n ),\n zoom: synchronized(\n () => view.getZoom(),\n (cb) => {\n const key = view.on(\"change:resolution\", cb);\n return () => unByKey(key);\n }\n ),\n projection: view.getProjection()\n };\n}\n\nfunction waitForMapSize(olMap: OlMap, signal: AbortSignal): Promise<void> {\n const promise = new Promise<void>((resolve, reject) => {\n let eventKey: EventsKey | undefined;\n\n function checkSize() {\n const currentSize = olMap.getSize() ?? [];\n const [width = 0, height = 0] = currentSize;\n if (currentSize && width > 0 && height > 0) {\n finish();\n }\n }\n\n function onAbort() {\n finish(createAbortError());\n }\n\n function finish(error?: Error | undefined) {\n if (eventKey) {\n unByKey(eventKey);\n eventKey = undefined;\n }\n signal.removeEventListener(\"abort\", onAbort);\n\n if (error) {\n reject(error);\n } else {\n resolve(wait(25)); // Give the map some time to render\n }\n }\n\n if (signal.aborted) {\n finish(createAbortError());\n return;\n }\n\n signal.addEventListener(\"abort\", onAbort);\n eventKey = olMap.on(\"change:size\", checkSize);\n });\n return promise;\n}\n\nfunction wait(milliseconds: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, milliseconds));\n}\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"MapModelImpl.js","sources":["MapModelImpl.ts"],"sourcesContent":["// SPDX-FileCopyrightText: 2023-2025 Open Pioneer project (https://github.com/open-pioneer)\n// SPDX-License-Identifier: Apache-2.0\nimport { computed, reactive, ReadonlyReactive, synchronized } from \"@conterra/reactivity-core\";\nimport {\n createAbortError,\n createLogger,\n createManualPromise,\n EventEmitter,\n isAbortError,\n ManualPromise\n} from \"@open-pioneer/core\";\nimport { HttpService } from \"@open-pioneer/http\";\nimport OlMap from \"ol/Map\";\nimport { unByKey } from \"ol/Observable\";\nimport OlView from \"ol/View\";\nimport { Coordinate } from \"ol/coordinate\";\nimport { EventsKey } from \"ol/events\";\nimport { getCenter } from \"ol/extent\";\nimport { Geometry } from \"ol/geom\";\nimport { getPointResolution, Projection } from \"ol/proj\";\nimport {\n ExtentConfig,\n Highlight,\n HighlightOptions,\n HighlightZoomOptions,\n MapModel,\n MapModelEvents\n} from \"../api\";\nimport { Highlights } from \"./Highlights\";\nimport { LayerCollectionImpl } from \"./LayerCollectionImpl\";\n\nconst LOG = createLogger(\"map:MapModel\");\n\nconst DEFAULT_DPI = 25.4 / 0.28;\nconst INCHES_PER_METRE = 39.37;\n\n/**\n * Shared services or other entities propagated from the map model to all layer instances.\n */\nexport interface SharedDependencies {\n httpService: HttpService;\n}\n\nexport class MapModelImpl extends EventEmitter<MapModelEvents> implements MapModel {\n readonly #id: string;\n readonly #olMap: OlMap;\n readonly #olView: ReadonlyReactive<OlView>;\n readonly #layers = new LayerCollectionImpl(this);\n readonly #highlights: Highlights;\n readonly #sharedDeps: SharedDependencies;\n\n #destroyed = false;\n #container: ReadonlyReactive<HTMLElement | undefined>;\n #initialExtent = reactive<ExtentConfig>();\n #viewBindings: ReadonlyReactive<ViewBindings>;\n #scale: ReadonlyReactive<number | undefined>;\n\n readonly #abortController = new AbortController();\n #displayStatus: \"waiting\" | \"ready\" | \"error\";\n #displayWaiter: ManualPromise<void> | undefined;\n\n constructor(properties: {\n id: string;\n olMap: OlMap;\n initialExtent: ExtentConfig | undefined;\n httpService: HttpService;\n }) {\n super();\n this.#id = properties.id;\n this.#olMap = properties.olMap;\n this.#olView = synchronized(\n () => this.#olMap.getView(),\n (cb) => {\n const key = this.#olMap.on(\"change:view\", cb);\n return () => unByKey(key);\n }\n );\n this.#initialExtent.value = properties.initialExtent;\n this.#sharedDeps = {\n httpService: properties.httpService\n };\n this.#highlights = new Highlights(this.#olMap);\n\n this.#displayStatus = \"waiting\";\n this.#initializeView().then(\n () => {\n this.#displayStatus = \"ready\";\n this.#displayWaiter?.resolve();\n this.#displayWaiter = undefined;\n },\n (error) => {\n if (!isAbortError(error)) {\n LOG.error(`Failed to initialize map`, error);\n }\n\n this.#displayStatus = \"error\";\n this.#displayWaiter?.reject(new Error(`Failed to initialize map.`));\n this.#displayWaiter = undefined;\n }\n );\n\n this.#container = synchronized(\n () => this.#olMap.getTargetElement() ?? undefined,\n (cb) => {\n const key = this.#olMap.on(\"change:target\", cb);\n return () => unByKey(key);\n }\n );\n\n this.#viewBindings = computed(() => createViewBindings(this.#olView.value));\n this.#scale = computed(() => {\n const { projection, resolution, center } = this;\n if (projection == null || resolution == null || center == null) {\n return undefined;\n }\n\n /**\n * Returns the appropriate scale for the given resolution and units, see OpenLayers function getScaleForResolution()\n * https://github.com/openlayers/openlayers/blob/7fa9df03431e9e1bc517e6c414565d9f848a3132/src/ol/control/ScaleLine.js#L454C3-L454C24\n */\n const pointResolution = getPointResolution(projection, resolution, center, \"m\"); //point resolution in meter per pixel\n const scale = Math.round(pointResolution * INCHES_PER_METRE * DEFAULT_DPI);\n return scale;\n });\n }\n\n destroy() {\n if (this.#destroyed) {\n return;\n }\n\n this.#destroyed = true;\n try {\n this.emit(\"destroy\");\n } catch (e) {\n LOG.warn(`Unexpected error from event listener during map model destruction:`, e);\n }\n\n this.#abortController.abort();\n this.#displayWaiter?.reject(new Error(\"Map model was destroyed.\"));\n this.#layers.destroy();\n this.#highlights.destroy();\n this.#olMap.dispose();\n }\n\n get id(): string {\n return this.#id;\n }\n\n get olMap(): OlMap {\n return this.#olMap;\n }\n\n get olView(): OlView {\n return this.#olView.value;\n }\n\n get projection(): Projection {\n return this.#viewBindings.value.projection;\n }\n\n get center(): Coordinate | undefined {\n return this.#viewBindings.value.center.value;\n }\n\n get resolution(): number | undefined {\n return this.#viewBindings.value.resolution.value;\n }\n\n get zoomLevel(): number | undefined {\n return this.#viewBindings.value.zoom.value;\n }\n\n get scale(): number | undefined {\n return this.#scale.value;\n }\n\n get layers(): LayerCollectionImpl {\n return this.#layers;\n }\n\n get container(): HTMLElement | undefined {\n return this.#container.value;\n }\n\n get initialExtent(): ExtentConfig | undefined {\n return this.#initialExtent.value;\n }\n\n get __sharedDependencies(): SharedDependencies {\n return this.#sharedDeps;\n }\n\n setScale(newScale: number): void {\n const view = this.olView;\n const projection = this.projection;\n const center = this.center;\n if (!center) {\n return;\n }\n\n const mpu = projection.getMetersPerUnit() ?? 1;\n const resolution = INCHES_PER_METRE * DEFAULT_DPI * mpu;\n const pointResolution = newScale / getPointResolution(projection, resolution, center);\n view.setResolution(pointResolution);\n }\n\n highlight(geometries: Geometry[], options?: HighlightOptions | undefined): Highlight {\n return this.#highlights.addHighlight(geometries, options);\n }\n\n zoom(geometries: Geometry[], options?: HighlightZoomOptions | undefined): void {\n this.#highlights.zoomToHighlight(geometries, options);\n }\n\n highlightAndZoom(geometries: Geometry[], options?: HighlightZoomOptions) {\n return this.#highlights.addHighlightAndZoom(geometries, options ?? {});\n }\n\n removeHighlights() {\n this.#highlights.clearHighlight();\n }\n\n whenDisplayed(): Promise<void> {\n if (this.#destroyed) {\n return Promise.reject(new Error(\"Map model was destroyed.\"));\n }\n if (this.#displayStatus === \"error\") {\n return Promise.reject(new Error(`Failed to initialize map.`));\n }\n if (this.#displayStatus === \"ready\") {\n return Promise.resolve();\n }\n return (this.#displayWaiter ??= createManualPromise()).promise;\n }\n\n /**\n * Waits for the map to be displayed and then initializes the view (if necessary).\n *\n * May simply resolve when done, or throw an error when a problem occurs.\n * AbortError is thrown when cancelled via `this.#abortController`, for example\n * when the map model is destroyed before it has ever been displayed.\n */\n async #initializeView(): Promise<void> {\n try {\n await waitForMapSize(this.olMap, this.#abortController.signal); // may throw on cancel\n } catch (e) {\n if (isAbortError(e)) {\n throw e;\n }\n throw new Error(`Failed to wait for the map to be displayed.`, { cause: e });\n }\n\n try {\n const olMap = this.#olMap;\n const view = olMap.getView();\n\n if (this.#initialExtent.value) {\n // Initial extent was set from the outside. We simply ensure that it gets displayed by the map.\n const extent = this.#initialExtent.value;\n const olExtent = [extent.xMin, extent.yMin, extent.xMax, extent.yMax];\n\n const olCenter = getCenter(olExtent);\n const resolution = view.getResolutionForExtent(olExtent);\n LOG.debug(`Applying initial extent`, extent);\n LOG.debug(` Computed center:`, olCenter);\n LOG.debug(` Computed resolution:`, resolution);\n\n view.setCenter(olCenter);\n view.setResolution(resolution);\n } else {\n // Initial extent was NOT set from the outside.\n // We detect whatever the view is displaying and consider it to be the initial extent.\n const olExtent = view.calculateExtent();\n const [xMin = 0, yMin = 0, xMax = 0, yMax = 0] = olExtent;\n const extent: ExtentConfig = { xMin, yMin, xMax, yMax };\n LOG.debug(`Detected initial extent`, extent);\n\n this.#initialExtent.value = extent;\n }\n } catch (e) {\n throw new Error(`Failed to apply the initial extent.`, { cause: e });\n }\n }\n}\n\ninterface ViewBindings {\n resolution: ReadonlyReactive<number | undefined>;\n center: ReadonlyReactive<Coordinate | undefined>;\n zoom: ReadonlyReactive<number | undefined>;\n projection: Projection; // not reactive (change view to change projection)\n}\n\nfunction createViewBindings(view: OlView): ViewBindings {\n return {\n resolution: synchronized(\n () => view.getResolution(),\n (cb) => {\n const key = view.on(\"change:resolution\", cb);\n return () => unByKey(key);\n }\n ),\n center: synchronized(\n () => view.getCenter(),\n (cb) => {\n const key = view.on(\"change:center\", cb);\n return () => unByKey(key);\n }\n ),\n zoom: synchronized(\n () => view.getZoom(),\n (cb) => {\n const key = view.on(\"change:resolution\", cb);\n return () => unByKey(key);\n }\n ),\n projection: view.getProjection()\n };\n}\n\nfunction waitForMapSize(olMap: OlMap, signal: AbortSignal): Promise<void> {\n const promise = new Promise<void>((resolve, reject) => {\n let eventKey: EventsKey | undefined;\n\n function checkSize() {\n const currentSize = olMap.getSize() ?? [];\n const [width = 0, height = 0] = currentSize;\n if (currentSize && width > 0 && height > 0) {\n finish();\n }\n }\n\n function onAbort() {\n finish(createAbortError());\n }\n\n function finish(error?: Error | undefined) {\n if (eventKey) {\n unByKey(eventKey);\n eventKey = undefined;\n }\n signal.removeEventListener(\"abort\", onAbort);\n\n if (error) {\n reject(error);\n } else {\n resolve(wait(25)); // Give the map some time to render\n }\n }\n\n if (signal.aborted) {\n finish(createAbortError());\n return;\n }\n\n signal.addEventListener(\"abort\", onAbort);\n eventKey = olMap.on(\"change:size\", checkSize);\n });\n return promise;\n}\n\nfunction wait(milliseconds: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, milliseconds));\n}\n"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SublayersCollectionImpl.js","sources":["SublayersCollectionImpl.ts"],"sourcesContent":["// SPDX-FileCopyrightText: 2023-2025 Open Pioneer project (https://github.com/open-pioneer)\n// SPDX-License-Identifier: Apache-2.0\nimport {\n LayerRetrievalOptions,\n RecursiveRetrievalOptions,\n Sublayer,\n SublayerBaseType,\n SublayersCollection\n} from \"../api\";\nimport { AbstractLayerBase } from \"./AbstractLayerBase\";\nimport { getRecursiveLayers } from \"./getRecursiveLayers\";\n\n/**\n * Manages the sublayers of a layer.\n */\n// NOTE: adding / removing sublayers currently not supported\n/* eslint-disable indent */\nexport class SublayersCollectionImpl<SublayerType extends SublayerBaseType & AbstractLayerBase>\n implements SublayersCollection<SublayerType>\n{\n /* eslint-enable indent */\n #sublayers: SublayerType[];\n\n constructor(sublayers: SublayerType[]) {\n this.#sublayers = sublayers;\n }\n\n destroy() {\n for (const layer of this.#sublayers) {\n layer.destroy();\n }\n this.#sublayers = [];\n }\n\n // Generic method name for consistent interface\n getItems(options?: LayerRetrievalOptions): SublayerType[] {\n return this.getSublayers(options);\n }\n\n getSublayers(_options?: LayerRetrievalOptions | undefined): SublayerType[] {\n // NOTE: options are ignored because layers are always ordered at this time.\n return this.#sublayers.slice();\n }\n\n getRecursiveLayers(_options?: RecursiveRetrievalOptions): Sublayer[] {\n return getRecursiveLayers({\n // NOTE: This is safe (but not elegant) because this class does not know about the entire type hierarchy (unions).\n // _Might_ be possible to refactor this class to use the Sublayer union instead in the generic type parameters,\n // but then we might also introduce a cycle in the type definitions, which could be bad (?).\n from: this as unknown as SublayersCollection<Sublayer>,\n sortByDisplayOrder: _options?.sortByDisplayOrder,\n filter: _options?.filter\n }) as Sublayer[]; // we know for sure that all children are sublayers: sublayers do not point to layers\n }\n\n /**\n * Returns a reference to the internal sublayers array.\n *\n * NOTE: Do not modify directly!\n */\n __getRawSublayers(): SublayerType[] {\n return this.#sublayers;\n }\n}\n"],"names":[],"mappings":";;AAiBO,MAAM,
|
|
1
|
+
{"version":3,"file":"SublayersCollectionImpl.js","sources":["SublayersCollectionImpl.ts"],"sourcesContent":["// SPDX-FileCopyrightText: 2023-2025 Open Pioneer project (https://github.com/open-pioneer)\n// SPDX-License-Identifier: Apache-2.0\nimport {\n LayerRetrievalOptions,\n RecursiveRetrievalOptions,\n Sublayer,\n SublayerBaseType,\n SublayersCollection\n} from \"../api\";\nimport { AbstractLayerBase } from \"./AbstractLayerBase\";\nimport { getRecursiveLayers } from \"./getRecursiveLayers\";\n\n/**\n * Manages the sublayers of a layer.\n */\n// NOTE: adding / removing sublayers currently not supported\n/* eslint-disable indent */\nexport class SublayersCollectionImpl<SublayerType extends SublayerBaseType & AbstractLayerBase>\n implements SublayersCollection<SublayerType>\n{\n /* eslint-enable indent */\n #sublayers: SublayerType[];\n\n constructor(sublayers: SublayerType[]) {\n this.#sublayers = sublayers;\n }\n\n destroy() {\n for (const layer of this.#sublayers) {\n layer.destroy();\n }\n this.#sublayers = [];\n }\n\n // Generic method name for consistent interface\n getItems(options?: LayerRetrievalOptions): SublayerType[] {\n return this.getSublayers(options);\n }\n\n getSublayers(_options?: LayerRetrievalOptions | undefined): SublayerType[] {\n // NOTE: options are ignored because layers are always ordered at this time.\n return this.#sublayers.slice();\n }\n\n getRecursiveLayers(_options?: RecursiveRetrievalOptions): Sublayer[] {\n return getRecursiveLayers({\n // NOTE: This is safe (but not elegant) because this class does not know about the entire type hierarchy (unions).\n // _Might_ be possible to refactor this class to use the Sublayer union instead in the generic type parameters,\n // but then we might also introduce a cycle in the type definitions, which could be bad (?).\n from: this as unknown as SublayersCollection<Sublayer>,\n sortByDisplayOrder: _options?.sortByDisplayOrder,\n filter: _options?.filter\n }) as Sublayer[]; // we know for sure that all children are sublayers: sublayers do not point to layers\n }\n\n /**\n * Returns a reference to the internal sublayers array.\n *\n * NOTE: Do not modify directly!\n */\n __getRawSublayers(): SublayerType[] {\n return this.#sublayers;\n }\n}\n"],"names":[],"mappings":";;AAiBO,MAAM,uBAAA,CAEb;AAAA;AAAA,EAEI,UAAA;AAAA,EAEA,YAAY,SAAA,EAA2B;AACnC,IAAA,IAAA,CAAK,UAAA,GAAa,SAAA;AAAA,EACtB;AAAA,EAEA,OAAA,GAAU;AACN,IAAA,KAAA,MAAW,KAAA,IAAS,KAAK,UAAA,EAAY;AACjC,MAAA,KAAA,CAAM,OAAA,EAAQ;AAAA,IAClB;AACA,IAAA,IAAA,CAAK,aAAa,EAAC;AAAA,EACvB;AAAA;AAAA,EAGA,SAAS,OAAA,EAAiD;AACtD,IAAA,OAAO,IAAA,CAAK,aAAa,OAAO,CAAA;AAAA,EACpC;AAAA,EAEA,aAAa,QAAA,EAA8D;AAEvE,IAAA,OAAO,IAAA,CAAK,WAAW,KAAA,EAAM;AAAA,EACjC;AAAA,EAEA,mBAAmB,QAAA,EAAkD;AACjE,IAAA,OAAO,kBAAA,CAAmB;AAAA;AAAA;AAAA;AAAA,MAItB,IAAA,EAAM,IAAA;AAAA,MACN,oBAAoB,QAAA,EAAU,kBAAA;AAAA,MAC9B,QAAQ,QAAA,EAAU;AAAA,KACrB,CAAA;AAAA,EACL;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,iBAAA,GAAoC;AAChC,IAAA,OAAO,IAAA,CAAK,UAAA;AAAA,EAChB;AACJ;;;;"}
|