@open-pioneer/map 0.3.0 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +24 -0
- package/README.md +7 -6
- package/api/BaseFeature.d.ts +31 -0
- package/api/MapModel.d.ts +42 -10
- package/api/index.d.ts +2 -1
- package/api/layers/WMTSLayer.d.ts +8 -4
- package/api/layers/WMTSLayer.js.map +1 -1
- package/index.js +1 -1
- package/model/Highlights.d.ts +27 -7
- package/model/Highlights.js +156 -37
- package/model/Highlights.js.map +1 -1
- package/model/MapModelImpl.d.ts +6 -4
- package/model/MapModelImpl.js +8 -2
- package/model/MapModelImpl.js.map +1 -1
- package/model/layers/WMTSLayerImpl.d.ts +0 -1
- package/model/layers/WMTSLayerImpl.js +3 -4
- package/model/layers/WMTSLayerImpl.js.map +1 -1
- package/package.json +15 -5
- package/ui/MapContainer.js +2 -10
- package/ui/MapContainer.js.map +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,29 @@
|
|
|
1
1
|
# @open-pioneer/map
|
|
2
2
|
|
|
3
|
+
## 0.4.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- a11bf72: Additional helpers for highlight and zoom
|
|
8
|
+
- 9334e81: Update to OpenLayers 9
|
|
9
|
+
|
|
10
|
+
### Patch Changes
|
|
11
|
+
|
|
12
|
+
- 1a8ad89: Update package.json metadata
|
|
13
|
+
- fc6bf82: introduce sourceOptions parameter to WMTS layer
|
|
14
|
+
- a0d8882: hide help texts during map export
|
|
15
|
+
- 6162979: Update versions of core packages
|
|
16
|
+
- ac7fdd1: Update documentation
|
|
17
|
+
- 13ea342: Remove duplicate viewPadding application.
|
|
18
|
+
- Updated dependencies [1a8ad89]
|
|
19
|
+
- @open-pioneer/react-utils@0.2.2
|
|
20
|
+
|
|
21
|
+
## 0.3.1
|
|
22
|
+
|
|
23
|
+
### Patch Changes
|
|
24
|
+
|
|
25
|
+
- 611ddb9: Export interface `BaseFeature` from Map API and use it correctly in base packages `selection` and `search`.
|
|
26
|
+
|
|
3
27
|
## 0.3.0
|
|
4
28
|
|
|
5
29
|
### Minor Changes
|
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# @open-pioneer/map
|
|
2
2
|
|
|
3
|
-
This package integrates [OpenLayers](https://openlayers.org/) maps into
|
|
3
|
+
This package integrates [OpenLayers](https://openlayers.org/) maps into an open pioneer trails application.
|
|
4
4
|
APIs provided by this package can be used to configure, embed and access the map and its contents.
|
|
5
5
|
|
|
6
6
|
## Usage
|
|
@@ -83,7 +83,7 @@ Such a provider is typically located in an app.
|
|
|
83
83
|
Example: Configuration to register a service providing `map.MapConfigProvider`.
|
|
84
84
|
|
|
85
85
|
```js
|
|
86
|
-
//
|
|
86
|
+
// build.config.mjs
|
|
87
87
|
import { defineBuildConfig } from "@open-pioneer/build-support";
|
|
88
88
|
|
|
89
89
|
export default defineBuildConfig({
|
|
@@ -350,12 +350,13 @@ export class MapConfigProviderImpl implements MapConfigProvider {
|
|
|
350
350
|
zoom: 13
|
|
351
351
|
},
|
|
352
352
|
layers: [
|
|
353
|
-
{
|
|
353
|
+
new SimpleLayer({
|
|
354
354
|
title: "Abschnitte/Äste mit Unfällen (Mapbox Style)",
|
|
355
|
-
|
|
356
|
-
styleUrl:
|
|
355
|
+
olLayer: new MapboxVectorLayer({
|
|
356
|
+
styleUrl:
|
|
357
|
+
"https://sgx.geodatenzentrum.de/gdz_basemapde_vektor/styles/bm_web_top.json"
|
|
357
358
|
})
|
|
358
|
-
}
|
|
359
|
+
})
|
|
359
360
|
]
|
|
360
361
|
};
|
|
361
362
|
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { Geometry } from "ol/geom";
|
|
2
|
+
import { Style } from "ol/style";
|
|
3
|
+
/**
|
|
4
|
+
* Base interface for all feature objects with geometry and / or attribute information.
|
|
5
|
+
*/
|
|
6
|
+
export interface BaseFeature {
|
|
7
|
+
/**
|
|
8
|
+
* Identifier for the feature object. Must be unique within all features of one source/layer.
|
|
9
|
+
*
|
|
10
|
+
* If your source cannot provide a useful id on its own, another strategy to generate unique ids is to
|
|
11
|
+
* generate a [UUID](https://www.npmjs.com/package/uuid#uuidv4options-buffer-offset) instead.
|
|
12
|
+
*/
|
|
13
|
+
id: number | string;
|
|
14
|
+
/**
|
|
15
|
+
* Geometry of the feature.
|
|
16
|
+
* Also specify the {@link projection} if geometry is set.
|
|
17
|
+
*/
|
|
18
|
+
geometry?: Geometry;
|
|
19
|
+
/**
|
|
20
|
+
* The projection of the {@link geometry}.
|
|
21
|
+
*/
|
|
22
|
+
projection?: string;
|
|
23
|
+
/**
|
|
24
|
+
* Properties of the feature.
|
|
25
|
+
*/
|
|
26
|
+
properties?: Readonly<Record<string, unknown>>;
|
|
27
|
+
/**
|
|
28
|
+
* Additional style information for displaying the feature on the map.
|
|
29
|
+
*/
|
|
30
|
+
style?: Style;
|
|
31
|
+
}
|
package/api/MapModel.d.ts
CHANGED
|
@@ -1,11 +1,12 @@
|
|
|
1
|
-
import type { EventSource } from "@open-pioneer/core";
|
|
1
|
+
import type { EventSource, Resource } from "@open-pioneer/core";
|
|
2
2
|
import type OlMap from "ol/Map";
|
|
3
3
|
import type OlBaseLayer from "ol/layer/Base";
|
|
4
4
|
import type { ExtentConfig } from "./MapConfig";
|
|
5
5
|
import type { Layer, LayerBase } from "./layers";
|
|
6
6
|
import type { LayerRetrievalOptions } from "./shared";
|
|
7
7
|
import type { Geometry } from "ol/geom";
|
|
8
|
-
import
|
|
8
|
+
import { BaseFeature } from "./BaseFeature";
|
|
9
|
+
import { StyleLike } from "ol/style/Style";
|
|
9
10
|
/** Events emitted by the {@link MapModel}. */
|
|
10
11
|
export interface MapModelEvents {
|
|
11
12
|
"changed": void;
|
|
@@ -13,12 +14,15 @@ export interface MapModelEvents {
|
|
|
13
14
|
"changed:initialExtent": void;
|
|
14
15
|
"destroy": void;
|
|
15
16
|
}
|
|
16
|
-
/** Options supported
|
|
17
|
+
/** Options supported when creating a new {@link Highlight}. */
|
|
17
18
|
export interface HighlightOptions {
|
|
18
19
|
/**
|
|
19
20
|
* Optional styles to override the default styles.
|
|
20
21
|
*/
|
|
21
22
|
highlightStyle?: HighlightStyle;
|
|
23
|
+
}
|
|
24
|
+
/** Options supported by the map model's {@link MapModel.highlightAndZoom | highlightAndZoom} method. */
|
|
25
|
+
export interface HighlightZoomOptions extends HighlightOptions {
|
|
22
26
|
/**
|
|
23
27
|
* The zoom-level used if there is no valid extend (such as for single points).
|
|
24
28
|
*/
|
|
@@ -32,12 +36,17 @@ export interface HighlightOptions {
|
|
|
32
36
|
*/
|
|
33
37
|
viewPadding?: MapPadding;
|
|
34
38
|
}
|
|
35
|
-
|
|
39
|
+
/**
|
|
40
|
+
* Custom styles when creating a new {@link Highlight}.
|
|
41
|
+
*/
|
|
42
|
+
export type HighlightStyle = {
|
|
36
43
|
Point?: StyleLike;
|
|
37
44
|
LineString?: StyleLike;
|
|
38
45
|
Polygon?: StyleLike;
|
|
39
46
|
MultiPolygon?: StyleLike;
|
|
40
|
-
|
|
47
|
+
MultiPoint?: StyleLike;
|
|
48
|
+
MultiLineString?: StyleLike;
|
|
49
|
+
};
|
|
41
50
|
/**
|
|
42
51
|
* Map padding, all values are pixels.
|
|
43
52
|
*
|
|
@@ -49,6 +58,18 @@ export interface MapPadding {
|
|
|
49
58
|
top?: number;
|
|
50
59
|
bottom?: number;
|
|
51
60
|
}
|
|
61
|
+
/**
|
|
62
|
+
* Represents the additional graphical representations of objects.
|
|
63
|
+
*
|
|
64
|
+
* See also {@link MapModel.highlight}.
|
|
65
|
+
*/
|
|
66
|
+
export interface Highlight extends Resource {
|
|
67
|
+
readonly isActive: boolean;
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Represents a Object
|
|
71
|
+
*/
|
|
72
|
+
export type DisplayTarget = BaseFeature | Geometry;
|
|
52
73
|
/**
|
|
53
74
|
* Represents a map.
|
|
54
75
|
*/
|
|
@@ -91,16 +112,27 @@ export interface MapModel extends EventSource<MapModelEvents> {
|
|
|
91
112
|
*/
|
|
92
113
|
whenDisplayed(): Promise<void>;
|
|
93
114
|
/**
|
|
94
|
-
*
|
|
95
|
-
*
|
|
115
|
+
* Creates a highlight at the given targets.
|
|
116
|
+
*
|
|
117
|
+
* A highlight is a temporary graphic on the map that calls attention to a point or an area.
|
|
118
|
+
*
|
|
119
|
+
* Call `destroy()` on the returned highlight object to remove the highlight again.
|
|
120
|
+
*/
|
|
121
|
+
highlight(geometries: DisplayTarget[], options?: HighlightOptions): Highlight;
|
|
122
|
+
/**
|
|
123
|
+
* Zooms to to the given targets.
|
|
124
|
+
*/
|
|
125
|
+
zoom(geometries: DisplayTarget[], options?: HighlightZoomOptions): void;
|
|
126
|
+
/**
|
|
127
|
+
* Creates a highlight and zooms to the given targets.
|
|
96
128
|
*
|
|
97
|
-
*
|
|
129
|
+
* See also {@link highlight} and {@link zoom}.
|
|
98
130
|
*/
|
|
99
|
-
highlightAndZoom(geometries:
|
|
131
|
+
highlightAndZoom(geometries: DisplayTarget[], options?: HighlightZoomOptions): Highlight;
|
|
100
132
|
/**
|
|
101
133
|
* Removes any existing highlights from the map.
|
|
102
134
|
*/
|
|
103
|
-
|
|
135
|
+
removeHighlights(): void;
|
|
104
136
|
}
|
|
105
137
|
/** Events emitted by the {@link LayerCollection}. */
|
|
106
138
|
export interface LayerCollectionEvents {
|
package/api/index.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
export * from "./BaseFeature";
|
|
1
2
|
export * from "./MapConfig";
|
|
2
3
|
export * from "./MapModel";
|
|
3
4
|
export * from "./MapRegistry";
|
|
@@ -5,7 +6,7 @@ export * from "./layers";
|
|
|
5
6
|
export * from "./shared";
|
|
6
7
|
export { getProjection, registerProjections, type ProjectionDefinition } from "../projections";
|
|
7
8
|
export { BkgTopPlusOpen, type BkgTopPlusOpenProps } from "../layers/BkgTopPlusOpen";
|
|
8
|
-
export {
|
|
9
|
+
export { useView, useProjection, useResolution, useCenter, useScale } from "../ui/hooks";
|
|
9
10
|
export { MapAnchor, type MapAnchorProps, type MapAnchorPosition } from "../ui/MapAnchor";
|
|
10
11
|
export { MapContainer, type MapContainerProps } from "../ui/MapContainer";
|
|
11
12
|
export { useMapModel, type UseMapModelResult, type UseMapModelLoading, type UseMapModelResolved, type UseMapModelRejected } from "../ui/useMapModel";
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { Options as WMSSourceOptions } from "ol/source/ImageWMS";
|
|
1
2
|
import { Layer, LayerConfig } from "./base";
|
|
2
3
|
export interface WMTSLayerConfig extends LayerConfig {
|
|
3
4
|
/** URL of the WMTS service. */
|
|
@@ -6,8 +7,13 @@ export interface WMTSLayerConfig extends LayerConfig {
|
|
|
6
7
|
name: string;
|
|
7
8
|
/** The name of the tile matrix set in the service's capabilities. */
|
|
8
9
|
matrixSet: string;
|
|
9
|
-
/**
|
|
10
|
-
|
|
10
|
+
/**
|
|
11
|
+
* Additional source options for the layer's WMTS source.
|
|
12
|
+
*
|
|
13
|
+
* NOTE: These options are intended for advanced configuration:
|
|
14
|
+
* the WMTS Layer manages some of the OpenLayers source options itself.
|
|
15
|
+
*/
|
|
16
|
+
sourceOptions?: Partial<WMSSourceOptions>;
|
|
11
17
|
}
|
|
12
18
|
export interface WMTSLayer extends Layer {
|
|
13
19
|
/** URL of the WMTS service. */
|
|
@@ -16,8 +22,6 @@ export interface WMTSLayer extends Layer {
|
|
|
16
22
|
readonly name: string;
|
|
17
23
|
/** The name of the tile matrix set in the service's capabilities. */
|
|
18
24
|
readonly matrixSet: string;
|
|
19
|
-
/**Optional license note or source references*/
|
|
20
|
-
readonly attributions?: string;
|
|
21
25
|
}
|
|
22
26
|
export interface WMTSLayerConstructor {
|
|
23
27
|
prototype: WMTSLayer;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"WMTSLayer.js","sources":["WMTSLayer.ts"],"sourcesContent":["// SPDX-FileCopyrightText: 2023 Open Pioneer project (https://github.com/open-pioneer)\n// SPDX-License-Identifier: Apache-2.0\nimport { Layer, LayerConfig } from \"./base\";\nimport { WMTSLayerImpl } from \"../../model/layers/WMTSLayerImpl\";\nexport interface WMTSLayerConfig extends LayerConfig {\n /** URL of the WMTS service. */\n url: string;\n\n /** The name of the WMTS layer in the service's capabilities. */\n name: string;\n\n /** The name of the tile matrix set in the service's capabilities. */\n matrixSet: string;\n\n
|
|
1
|
+
{"version":3,"file":"WMTSLayer.js","sources":["WMTSLayer.ts"],"sourcesContent":["// SPDX-FileCopyrightText: 2023 Open Pioneer project (https://github.com/open-pioneer)\n// SPDX-License-Identifier: Apache-2.0\nimport type { Options as WMSSourceOptions } from \"ol/source/ImageWMS\";\nimport { Layer, LayerConfig } from \"./base\";\nimport { WMTSLayerImpl } from \"../../model/layers/WMTSLayerImpl\";\nexport interface WMTSLayerConfig extends LayerConfig {\n /** URL of the WMTS service. */\n url: string;\n\n /** The name of the WMTS layer in the service's capabilities. */\n name: string;\n\n /** The name of the tile matrix set in the service's capabilities. */\n matrixSet: string;\n\n /**\n * Additional source options for the layer's WMTS source.\n *\n * NOTE: These options are intended for advanced configuration:\n * the WMTS Layer manages some of the OpenLayers source options itself.\n */\n sourceOptions?: Partial<WMSSourceOptions>;\n}\nexport interface WMTSLayer extends Layer {\n /** URL of the WMTS service. */\n readonly url: string;\n\n /** The name of the WMTS layer in the service's capabilities. */\n readonly name: string;\n\n /** The name of the tile matrix set in the service's capabilities. */\n readonly matrixSet: string;\n}\nexport interface WMTSLayerConstructor {\n prototype: WMTSLayer;\n\n /** Creates a new {@link WMTSLayer}. */\n new (config: WMTSLayerConfig): WMTSLayer;\n}\n\nexport const WMTSLayer: WMTSLayerConstructor = WMTSLayerImpl;\n"],"names":[],"mappings":";;AAwCO,MAAM,SAAkC,GAAA;;;;"}
|
package/index.js
CHANGED
|
@@ -3,7 +3,7 @@ export { WMSLayer } from './api/layers/WMSLayer.js';
|
|
|
3
3
|
export { WMTSLayer } from './api/layers/WMTSLayer.js';
|
|
4
4
|
export { getProjection, registerProjections } from './projections.js';
|
|
5
5
|
export { BkgTopPlusOpen } from './layers/BkgTopPlusOpen.js';
|
|
6
|
-
export { useCenter, useProjection, useResolution, useScale } from './ui/hooks.js';
|
|
6
|
+
export { useCenter, useProjection, useResolution, useScale, useView } from './ui/hooks.js';
|
|
7
7
|
export { MapAnchor } from './ui/MapAnchor.js';
|
|
8
8
|
export { MapContainer } from './ui/MapContainer.js';
|
|
9
9
|
export { useMapModel } from './ui/useMapModel.js';
|
package/model/Highlights.d.ts
CHANGED
|
@@ -1,16 +1,36 @@
|
|
|
1
|
+
import { Feature } from "ol";
|
|
1
2
|
import OlMap from "ol/Map";
|
|
2
|
-
import {
|
|
3
|
-
import
|
|
3
|
+
import { Geometry } from "ol/geom";
|
|
4
|
+
import VectorLayer from "ol/layer/Vector";
|
|
5
|
+
import VectorSource from "ol/source/Vector";
|
|
6
|
+
import { DisplayTarget, Highlight, HighlightOptions, HighlightZoomOptions } from "../api/MapModel";
|
|
4
7
|
export declare class Highlights {
|
|
8
|
+
#private;
|
|
5
9
|
private olMap;
|
|
6
|
-
private
|
|
10
|
+
private olLayer;
|
|
11
|
+
private olSource;
|
|
12
|
+
private activeHighlights;
|
|
7
13
|
constructor(olMap: OlMap);
|
|
14
|
+
/**
|
|
15
|
+
* Getter for Hightlightlayer
|
|
16
|
+
* @returns Highlights.olLayer
|
|
17
|
+
*/
|
|
18
|
+
getLayer(): VectorLayer<VectorSource<Feature<Geometry>>>;
|
|
19
|
+
/**
|
|
20
|
+
* This method removes all highlights before destroying the class
|
|
21
|
+
*/
|
|
8
22
|
destroy(): void;
|
|
9
23
|
/**
|
|
10
|
-
* This method
|
|
24
|
+
* This method displays geometries or BaseFeatures with optional styling in the map
|
|
25
|
+
*/
|
|
26
|
+
addHighlight(displayTarget: DisplayTarget[], highlightOptions: HighlightOptions | undefined): Highlight;
|
|
27
|
+
/**
|
|
28
|
+
* This method zoom to geometries or BaseFeatures
|
|
29
|
+
*/
|
|
30
|
+
zoomToHighlight(displayTarget: DisplayTarget[], options: HighlightZoomOptions | undefined): void;
|
|
31
|
+
/**
|
|
32
|
+
* This method displays geometries or BaseFeatures with optional styling in the map and executed a zoom
|
|
11
33
|
*/
|
|
12
|
-
|
|
34
|
+
addHighlightAndZoom(displayTarget: DisplayTarget[], highlightZoomStyle: HighlightZoomOptions | undefined): Highlight;
|
|
13
35
|
clearHighlight(): void;
|
|
14
|
-
private zoomAndAddMarkers;
|
|
15
|
-
private createAndAddLayer;
|
|
16
36
|
}
|
package/model/Highlights.js
CHANGED
|
@@ -5,6 +5,24 @@ import VectorSource from 'ol/source/Vector';
|
|
|
5
5
|
import { Style, Icon, Stroke, Fill } from 'ol/style';
|
|
6
6
|
import { toFunction } from 'ol/style/Style';
|
|
7
7
|
import mapMarkerUrl from '../assets/images/mapMarker.png?url';
|
|
8
|
+
import './AbstractLayer.js';
|
|
9
|
+
import './layers/WMSLayerImpl.js';
|
|
10
|
+
import './layers/WMTSLayerImpl.js';
|
|
11
|
+
import 'ol/proj/proj4';
|
|
12
|
+
import 'proj4';
|
|
13
|
+
import 'ol/source/WMTS';
|
|
14
|
+
import 'ol/tilegrid/WMTS';
|
|
15
|
+
import 'ol/Observable';
|
|
16
|
+
import 'ol/proj';
|
|
17
|
+
import 'react';
|
|
18
|
+
import 'react/jsx-runtime';
|
|
19
|
+
import '@open-pioneer/chakra-integration';
|
|
20
|
+
import '@open-pioneer/react-utils';
|
|
21
|
+
import 'react-dom';
|
|
22
|
+
import '../ui/MapContext.js';
|
|
23
|
+
import '../ui/MapContainer.js';
|
|
24
|
+
import '@open-pioneer/runtime/react-integration';
|
|
25
|
+
import 'react-use';
|
|
8
26
|
import { TOPMOST_LAYER_Z } from './LayerCollectionImpl.js';
|
|
9
27
|
|
|
10
28
|
const DEFAULT_OL_POINT_ZOOM_LEVEL = 17;
|
|
@@ -12,33 +30,105 @@ const DEFAULT_OL_MAX_ZOOM_LEVEL = 20;
|
|
|
12
30
|
const DEFAULT_VIEW_PADDING = { top: 50, right: 20, bottom: 10, left: 20 };
|
|
13
31
|
class Highlights {
|
|
14
32
|
olMap;
|
|
15
|
-
|
|
33
|
+
olLayer;
|
|
34
|
+
olSource;
|
|
35
|
+
activeHighlights;
|
|
16
36
|
constructor(olMap) {
|
|
17
37
|
this.olMap = olMap;
|
|
38
|
+
this.olSource = new VectorSource({
|
|
39
|
+
features: void 0
|
|
40
|
+
});
|
|
41
|
+
this.olLayer = new VectorLayer({
|
|
42
|
+
className: "highlight-layer",
|
|
43
|
+
source: this.olSource,
|
|
44
|
+
style: function(feature, resolution) {
|
|
45
|
+
return resolveStyle(feature, resolution);
|
|
46
|
+
}
|
|
47
|
+
});
|
|
48
|
+
this.activeHighlights = /* @__PURE__ */ new Set();
|
|
49
|
+
this.olLayer.setZIndex(TOPMOST_LAYER_Z);
|
|
50
|
+
this.olMap.addLayer(this.olLayer);
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Getter for Hightlightlayer
|
|
54
|
+
* @returns Highlights.olLayer
|
|
55
|
+
*/
|
|
56
|
+
getLayer() {
|
|
57
|
+
return this.olLayer;
|
|
18
58
|
}
|
|
59
|
+
/**
|
|
60
|
+
* This method removes all highlights before destroying the class
|
|
61
|
+
*/
|
|
19
62
|
destroy() {
|
|
20
63
|
this.clearHighlight();
|
|
21
64
|
}
|
|
22
65
|
/**
|
|
23
|
-
*
|
|
66
|
+
* Method of filtering out objects that are not geometry or have no property geometry.
|
|
24
67
|
*/
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
68
|
+
#filterGeoobjects(geoObjects) {
|
|
69
|
+
const geometries = [];
|
|
70
|
+
geoObjects.forEach((item) => {
|
|
71
|
+
if ("getType" in item)
|
|
72
|
+
geometries.push(item);
|
|
73
|
+
if ("geometry" in item && item.geometry)
|
|
74
|
+
geometries.push(item.geometry);
|
|
75
|
+
});
|
|
76
|
+
return geometries;
|
|
31
77
|
}
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
78
|
+
/**
|
|
79
|
+
* This method displays geometries or BaseFeatures with optional styling in the map
|
|
80
|
+
*/
|
|
81
|
+
addHighlight(displayTarget, highlightOptions) {
|
|
82
|
+
const geometries = this.#filterGeoobjects(displayTarget);
|
|
83
|
+
if (geometries.length === 0) {
|
|
84
|
+
return {
|
|
85
|
+
get isActive() {
|
|
86
|
+
return false;
|
|
87
|
+
},
|
|
88
|
+
destroy() {
|
|
89
|
+
}
|
|
90
|
+
};
|
|
36
91
|
}
|
|
92
|
+
const features = geometries.map((geometry) => {
|
|
93
|
+
const type = geometry.getType();
|
|
94
|
+
const feature = new Feature({
|
|
95
|
+
type,
|
|
96
|
+
geometry
|
|
97
|
+
});
|
|
98
|
+
feature.setStyle(getOwnStyle(type, highlightOptions?.highlightStyle));
|
|
99
|
+
return feature;
|
|
100
|
+
});
|
|
101
|
+
const source = this.olSource;
|
|
102
|
+
const highlights = this.activeHighlights;
|
|
103
|
+
const highlight = {
|
|
104
|
+
get isActive() {
|
|
105
|
+
return highlights.has(highlight);
|
|
106
|
+
},
|
|
107
|
+
destroy() {
|
|
108
|
+
if (!this.isActive) {
|
|
109
|
+
return;
|
|
110
|
+
}
|
|
111
|
+
for (const feature of features) {
|
|
112
|
+
source.removeFeature(feature);
|
|
113
|
+
}
|
|
114
|
+
highlights.delete(highlight);
|
|
115
|
+
}
|
|
116
|
+
};
|
|
117
|
+
source.addFeatures(features);
|
|
118
|
+
this.activeHighlights.add(highlight);
|
|
119
|
+
return highlight;
|
|
37
120
|
}
|
|
38
|
-
|
|
121
|
+
/**
|
|
122
|
+
* This method zoom to geometries or BaseFeatures
|
|
123
|
+
*/
|
|
124
|
+
zoomToHighlight(displayTarget, options) {
|
|
125
|
+
const geometries = this.#filterGeoobjects(displayTarget);
|
|
126
|
+
if (geometries.length === 0) {
|
|
127
|
+
return;
|
|
128
|
+
}
|
|
39
129
|
let extent = createEmpty();
|
|
40
|
-
for (const
|
|
41
|
-
extent = extend(extent,
|
|
130
|
+
for (const geometry of geometries) {
|
|
131
|
+
extent = extend(extent, geometry.getExtent());
|
|
42
132
|
}
|
|
43
133
|
const center = getCenter(extent);
|
|
44
134
|
const isPoint = getArea(extent) === 0;
|
|
@@ -52,27 +142,19 @@ class Highlights {
|
|
|
52
142
|
} = options?.viewPadding ?? DEFAULT_VIEW_PADDING;
|
|
53
143
|
const padding = [top, right, bottom, left];
|
|
54
144
|
zoomTo(this.olMap, extent, zoomScale, padding);
|
|
55
|
-
this.createAndAddLayer(geometries, options?.highlightStyle);
|
|
56
145
|
}
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
style: function(feature, resolution) {
|
|
70
|
-
return resolveStyle(feature, resolution, highlightStyle);
|
|
71
|
-
}
|
|
72
|
-
});
|
|
73
|
-
layer.setZIndex(TOPMOST_LAYER_Z);
|
|
74
|
-
this.olMap.addLayer(layer);
|
|
75
|
-
this.currentHighlight = layer;
|
|
146
|
+
/**
|
|
147
|
+
* This method displays geometries or BaseFeatures with optional styling in the map and executed a zoom
|
|
148
|
+
*/
|
|
149
|
+
addHighlightAndZoom(displayTarget, highlightZoomStyle) {
|
|
150
|
+
const result = this.addHighlight(displayTarget, highlightZoomStyle);
|
|
151
|
+
this.zoomToHighlight(displayTarget, highlightZoomStyle);
|
|
152
|
+
return result;
|
|
153
|
+
}
|
|
154
|
+
clearHighlight() {
|
|
155
|
+
for (const highlight of this.activeHighlights) {
|
|
156
|
+
highlight.destroy();
|
|
157
|
+
}
|
|
76
158
|
}
|
|
77
159
|
}
|
|
78
160
|
function setCenter(olMap, coordinates) {
|
|
@@ -85,11 +167,28 @@ function zoomTo(olMap, extent, zoomLevel, padding) {
|
|
|
85
167
|
zoomLevel && olMap.getView().setZoom(zoomLevel);
|
|
86
168
|
}
|
|
87
169
|
}
|
|
88
|
-
function resolveStyle(feature, resolution
|
|
170
|
+
function resolveStyle(feature, resolution) {
|
|
89
171
|
const type = feature.get("type");
|
|
90
|
-
const style = toFunction(
|
|
172
|
+
const style = toFunction(getDefaultStyle(type));
|
|
91
173
|
return style(feature, resolution);
|
|
92
174
|
}
|
|
175
|
+
function getOwnStyle(type, highlightStyle) {
|
|
176
|
+
if (highlightStyle && type in highlightStyle) {
|
|
177
|
+
const supportedType = type;
|
|
178
|
+
const ownStyle = highlightStyle[supportedType];
|
|
179
|
+
return ownStyle ? ownStyle : getDefaultStyle(type);
|
|
180
|
+
} else {
|
|
181
|
+
return getDefaultStyle(type);
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
function getDefaultStyle(type) {
|
|
185
|
+
if (type in defaultHighlightStyle) {
|
|
186
|
+
const supportedType = type;
|
|
187
|
+
return defaultHighlightStyle[supportedType];
|
|
188
|
+
} else {
|
|
189
|
+
return defaultHighlightStyle.Polygon;
|
|
190
|
+
}
|
|
191
|
+
}
|
|
93
192
|
const defaultHighlightStyle = {
|
|
94
193
|
"Point": new Style({
|
|
95
194
|
image: new Icon({
|
|
@@ -97,6 +196,12 @@ const defaultHighlightStyle = {
|
|
|
97
196
|
src: mapMarkerUrl
|
|
98
197
|
})
|
|
99
198
|
}),
|
|
199
|
+
"MultiPoint": new Style({
|
|
200
|
+
image: new Icon({
|
|
201
|
+
anchor: [0.5, 1],
|
|
202
|
+
src: mapMarkerUrl
|
|
203
|
+
})
|
|
204
|
+
}),
|
|
100
205
|
"LineString": [
|
|
101
206
|
new Style({
|
|
102
207
|
stroke: new Stroke({
|
|
@@ -111,6 +216,20 @@ const defaultHighlightStyle = {
|
|
|
111
216
|
})
|
|
112
217
|
})
|
|
113
218
|
],
|
|
219
|
+
"MultiLineString": [
|
|
220
|
+
new Style({
|
|
221
|
+
stroke: new Stroke({
|
|
222
|
+
color: "#fff",
|
|
223
|
+
width: 5
|
|
224
|
+
})
|
|
225
|
+
}),
|
|
226
|
+
new Style({
|
|
227
|
+
stroke: new Stroke({
|
|
228
|
+
color: "#00ffff",
|
|
229
|
+
width: 3
|
|
230
|
+
})
|
|
231
|
+
})
|
|
232
|
+
],
|
|
114
233
|
"Polygon": [
|
|
115
234
|
new Style({
|
|
116
235
|
stroke: new Stroke({
|
package/model/Highlights.js.map
CHANGED
|
@@ -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, LineString, Point, Polygon } 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 { HighlightOptions, HighlightStyle } from \"../api/MapModel\";\nimport mapMarkerUrl from \"../assets/images/mapMarker.png?url\";\nimport { FeatureLike } from \"ol/Feature\";\nimport { TOPMOST_LAYER_Z } from \"./LayerCollectionImpl\";\nimport { Layer as OlLayer } from \"ol/layer\";\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 private currentHighlight: OlLayer | undefined;\n\n constructor(olMap: OlMap) {\n this.olMap = olMap;\n }\n\n destroy() {\n this.clearHighlight();\n }\n\n /**\n * This method shows the position of a text search result zoomed to and marked or highlighted in the map.\n */\n addHighlightOrMarkerAndZoom(\n geometries: Point[] | LineString[] | Polygon[],\n options: HighlightOptions\n ) {\n // Cleanup existing highlight\n this.clearHighlight();\n\n if (!geometries || !geometries.length) {\n return;\n }\n this.zoomAndAddMarkers(geometries, options);\n }\n\n clearHighlight() {\n if (this.currentHighlight) {\n this.olMap.removeLayer(this.currentHighlight);\n this.currentHighlight = undefined;\n }\n }\n\n private zoomAndAddMarkers(geometries: Geometry[], options: HighlightOptions | undefined) {\n let extent = createEmpty();\n for (const geom of geometries) {\n extent = extend(extent, geom.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 this.createAndAddLayer(geometries, options?.highlightStyle);\n }\n\n private createAndAddLayer(geometries: Geometry[], highlightStyle: HighlightStyle | undefined) {\n const features = geometries.map((geometry) => {\n return new Feature({\n type: geometry.getType(),\n geometry: geometry\n });\n });\n const layer = new VectorLayer({\n className: \"highlight-layer\",\n source: new VectorSource({\n features: features\n }),\n style: function (feature, resolution) {\n return resolveStyle(feature, resolution, highlightStyle);\n }\n });\n // Ensure layer is rendered on top of operational layers\n layer.setZIndex(TOPMOST_LAYER_Z);\n this.olMap.addLayer(layer);\n this.currentHighlight = layer;\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/** Returns the appropriate style from the user's highlightStyle or falls back to the default style. */\nfunction resolveStyle(\n feature: FeatureLike,\n resolution: number,\n highlightStyle: HighlightStyle | undefined\n) {\n const type: keyof typeof defaultHighlightStyle = feature.get(\"type\");\n const style = toStyleFunction(highlightStyle?.[type] ?? defaultHighlightStyle[type]);\n return style(feature, resolution);\n}\n\nconst defaultHighlightStyle = {\n \"Point\": 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 \"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":";;;;;;;;;AAkBA,MAAM,2BAA8B,GAAA,EAAA,CAAA;AACpC,MAAM,yBAA4B,GAAA,EAAA,CAAA;AAClC,MAAM,oBAAA,GAAuB,EAAE,GAAK,EAAA,EAAA,EAAI,OAAO,EAAI,EAAA,MAAA,EAAQ,EAAI,EAAA,IAAA,EAAM,EAAG,EAAA,CAAA;AAEjE,MAAM,UAAW,CAAA;AAAA,EACZ,KAAA,CAAA;AAAA,EACA,gBAAA,CAAA;AAAA,EAER,YAAY,KAAc,EAAA;AACtB,IAAA,IAAA,CAAK,KAAQ,GAAA,KAAA,CAAA;AAAA,GACjB;AAAA,EAEA,OAAU,GAAA;AACN,IAAA,IAAA,CAAK,cAAe,EAAA,CAAA;AAAA,GACxB;AAAA;AAAA;AAAA;AAAA,EAKA,2BAAA,CACI,YACA,OACF,EAAA;AAEE,IAAA,IAAA,CAAK,cAAe,EAAA,CAAA;AAEpB,IAAA,IAAI,CAAC,UAAA,IAAc,CAAC,UAAA,CAAW,MAAQ,EAAA;AACnC,MAAA,OAAA;AAAA,KACJ;AACA,IAAK,IAAA,CAAA,iBAAA,CAAkB,YAAY,OAAO,CAAA,CAAA;AAAA,GAC9C;AAAA,EAEA,cAAiB,GAAA;AACb,IAAA,IAAI,KAAK,gBAAkB,EAAA;AACvB,MAAK,IAAA,CAAA,KAAA,CAAM,WAAY,CAAA,IAAA,CAAK,gBAAgB,CAAA,CAAA;AAC5C,MAAA,IAAA,CAAK,gBAAmB,GAAA,KAAA,CAAA,CAAA;AAAA,KAC5B;AAAA,GACJ;AAAA,EAEQ,iBAAA,CAAkB,YAAwB,OAAuC,EAAA;AACrF,IAAA,IAAI,SAAS,WAAY,EAAA,CAAA;AACzB,IAAA,KAAA,MAAW,QAAQ,UAAY,EAAA;AAC3B,MAAA,MAAA,GAAS,MAAO,CAAA,MAAA,EAAQ,IAAK,CAAA,SAAA,EAAW,CAAA,CAAA;AAAA,KAC5C;AAEA,IAAM,MAAA,MAAA,GAAS,UAAU,MAAM,CAAA,CAAA;AAC/B,IAAM,MAAA,OAAA,GAAU,OAAQ,CAAA,MAAM,CAAM,KAAA,CAAA,CAAA;AACpC,IAAA,MAAM,YAAY,OACZ,GAAA,OAAA,EAAS,SAAa,IAAA,2BAAA,GACtB,SAAS,OAAW,IAAA,yBAAA,CAAA;AAC1B,IAAU,SAAA,CAAA,IAAA,CAAK,OAAO,MAAM,CAAA,CAAA;AAE5B,IAAM,MAAA;AAAA,MACF,GAAM,GAAA,CAAA;AAAA,MACN,KAAQ,GAAA,CAAA;AAAA,MACR,MAAS,GAAA,CAAA;AAAA,MACT,IAAO,GAAA,CAAA;AAAA,KACX,GAAI,SAAS,WAAe,IAAA,oBAAA,CAAA;AAC5B,IAAA,MAAM,OAAU,GAAA,CAAC,GAAK,EAAA,KAAA,EAAO,QAAQ,IAAI,CAAA,CAAA;AACzC,IAAA,MAAA,CAAO,IAAK,CAAA,KAAA,EAAO,MAAQ,EAAA,SAAA,EAAW,OAAO,CAAA,CAAA;AAE7C,IAAK,IAAA,CAAA,iBAAA,CAAkB,UAAY,EAAA,OAAA,EAAS,cAAc,CAAA,CAAA;AAAA,GAC9D;AAAA,EAEQ,iBAAA,CAAkB,YAAwB,cAA4C,EAAA;AAC1F,IAAA,MAAM,QAAW,GAAA,UAAA,CAAW,GAAI,CAAA,CAAC,QAAa,KAAA;AAC1C,MAAA,OAAO,IAAI,OAAQ,CAAA;AAAA,QACf,IAAA,EAAM,SAAS,OAAQ,EAAA;AAAA,QACvB,QAAA;AAAA,OACH,CAAA,CAAA;AAAA,KACJ,CAAA,CAAA;AACD,IAAM,MAAA,KAAA,GAAQ,IAAI,WAAY,CAAA;AAAA,MAC1B,SAAW,EAAA,iBAAA;AAAA,MACX,MAAA,EAAQ,IAAI,YAAa,CAAA;AAAA,QACrB,QAAA;AAAA,OACH,CAAA;AAAA,MACD,KAAA,EAAO,SAAU,OAAA,EAAS,UAAY,EAAA;AAClC,QAAO,OAAA,YAAA,CAAa,OAAS,EAAA,UAAA,EAAY,cAAc,CAAA,CAAA;AAAA,OAC3D;AAAA,KACH,CAAA,CAAA;AAED,IAAA,KAAA,CAAM,UAAU,eAAe,CAAA,CAAA;AAC/B,IAAK,IAAA,CAAA,KAAA,CAAM,SAAS,KAAK,CAAA,CAAA;AACzB,IAAA,IAAA,CAAK,gBAAmB,GAAA,KAAA,CAAA;AAAA,GAC5B;AACJ,CAAA;AAEA,SAAS,SAAA,CAAU,OAAc,WAAqC,EAAA;AAClE,EAAA,WAAA,IAAe,YAAY,MAAU,IAAA,KAAA,CAAM,OAAQ,EAAA,CAAE,UAAU,WAAW,CAAA,CAAA;AAC9E,CAAA;AAEA,SAAS,MACL,CAAA,KAAA,EACA,MACA,EAAA,SAAA,EACA,OACF,EAAA;AACE,EAAA,IAAI,MAAQ,EAAA;AACR,IAAM,KAAA,CAAA,OAAA,GAAU,GAAI,CAAA,MAAA,EAAQ,EAAE,OAAS,EAAA,SAAA,EAAW,SAAkB,CAAA,CAAA;AAAA,GACjE,MAAA;AACH,IAAA,SAAA,IAAa,KAAM,CAAA,OAAA,EAAU,CAAA,OAAA,CAAQ,SAAS,CAAA,CAAA;AAAA,GAClD;AACJ,CAAA;AAGA,SAAS,YAAA,CACL,OACA,EAAA,UAAA,EACA,cACF,EAAA;AACE,EAAM,MAAA,IAAA,GAA2C,OAAQ,CAAA,GAAA,CAAI,MAAM,CAAA,CAAA;AACnE,EAAA,MAAM,QAAQA,UAAgB,CAAA,cAAA,GAAiB,IAAI,CAAK,IAAA,qBAAA,CAAsB,IAAI,CAAC,CAAA,CAAA;AACnF,EAAO,OAAA,KAAA,CAAM,SAAS,UAAU,CAAA,CAAA;AACpC,CAAA;AAEA,MAAM,qBAAwB,GAAA;AAAA,EAC1B,OAAA,EAAS,IAAI,KAAM,CAAA;AAAA,IACf,KAAA,EAAO,IAAI,IAAK,CAAA;AAAA,MACZ,MAAA,EAAQ,CAAC,GAAA,EAAK,CAAC,CAAA;AAAA,MACf,GAAK,EAAA,YAAA;AAAA,KACR,CAAA;AAAA,GACJ,CAAA;AAAA,EACD,YAAc,EAAA;AAAA,IACV,IAAI,KAAM,CAAA;AAAA,MACN,MAAA,EAAQ,IAAI,MAAO,CAAA;AAAA,QACf,KAAO,EAAA,MAAA;AAAA,QACP,KAAO,EAAA,CAAA;AAAA,OACV,CAAA;AAAA,KACJ,CAAA;AAAA,IACD,IAAI,KAAM,CAAA;AAAA,MACN,MAAA,EAAQ,IAAI,MAAO,CAAA;AAAA,QACf,KAAO,EAAA,SAAA;AAAA,QACP,KAAO,EAAA,CAAA;AAAA,OACV,CAAA;AAAA,KACJ,CAAA;AAAA,GACL;AAAA,EACA,SAAW,EAAA;AAAA,IACP,IAAI,KAAM,CAAA;AAAA,MACN,MAAA,EAAQ,IAAI,MAAO,CAAA;AAAA,QACf,KAAO,EAAA,MAAA;AAAA,QACP,KAAO,EAAA,CAAA;AAAA,OACV,CAAA;AAAA,KACJ,CAAA;AAAA,IACD,IAAI,KAAM,CAAA;AAAA,MACN,MAAA,EAAQ,IAAI,MAAO,CAAA;AAAA,QACf,KAAO,EAAA,SAAA;AAAA,QACP,KAAO,EAAA,CAAA;AAAA,OACV,CAAA;AAAA,MACD,IAAA,EAAM,IAAI,IAAK,CAAA;AAAA,QACX,KAAO,EAAA,wBAAA;AAAA,OACV,CAAA;AAAA,KACJ,CAAA;AAAA,GACL;AAAA,EACA,cAAgB,EAAA;AAAA,IACZ,IAAI,KAAM,CAAA;AAAA,MACN,MAAA,EAAQ,IAAI,MAAO,CAAA;AAAA,QACf,KAAO,EAAA,MAAA;AAAA,QACP,KAAO,EAAA,CAAA;AAAA,OACV,CAAA;AAAA,KACJ,CAAA;AAAA,IACD,IAAI,KAAM,CAAA;AAAA,MACN,MAAA,EAAQ,IAAI,MAAO,CAAA;AAAA,QACf,KAAO,EAAA,SAAA;AAAA,QACP,KAAO,EAAA,CAAA;AAAA,OACV,CAAA;AAAA,MACD,IAAA,EAAM,IAAI,IAAK,CAAA;AAAA,QACX,KAAO,EAAA,wBAAA;AAAA,OACV,CAAA;AAAA,KACJ,CAAA;AAAA,GACL;AACJ,CAAA;;;;"}
|
|
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} 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>;\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: HighlightZoomOptions | 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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"}
|
package/model/MapModelImpl.d.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { EventEmitter } from "@open-pioneer/core";
|
|
2
2
|
import OlMap from "ol/Map";
|
|
3
|
-
import { ExtentConfig, HighlightOptions, MapModel, MapModelEvents } from "../api";
|
|
3
|
+
import { ExtentConfig, Highlight, HighlightOptions, HighlightZoomOptions, MapModel, MapModelEvents } from "../api";
|
|
4
4
|
import { LayerCollectionImpl } from "./LayerCollectionImpl";
|
|
5
|
-
import {
|
|
5
|
+
import { Geometry } from "ol/geom";
|
|
6
6
|
import { HttpService } from "@open-pioneer/http";
|
|
7
7
|
/**
|
|
8
8
|
* Shared services or other entities propagated from the map model to all layer instances.
|
|
@@ -25,7 +25,9 @@ export declare class MapModelImpl extends EventEmitter<MapModelEvents> implement
|
|
|
25
25
|
get container(): HTMLElement | undefined;
|
|
26
26
|
get initialExtent(): ExtentConfig | undefined;
|
|
27
27
|
get __sharedDependencies(): SharedDependencies;
|
|
28
|
-
|
|
29
|
-
|
|
28
|
+
highlight(geometries: Geometry[], options?: HighlightOptions | undefined): Highlight;
|
|
29
|
+
zoom(geometries: Geometry[], options?: HighlightZoomOptions | undefined): void;
|
|
30
|
+
highlightAndZoom(geometries: Geometry[], options?: HighlightZoomOptions): Highlight;
|
|
31
|
+
removeHighlights(): void;
|
|
30
32
|
whenDisplayed(): Promise<void>;
|
|
31
33
|
}
|
package/model/MapModelImpl.js
CHANGED
|
@@ -85,10 +85,16 @@ class MapModelImpl extends EventEmitter {
|
|
|
85
85
|
get __sharedDependencies() {
|
|
86
86
|
return this.#sharedDeps;
|
|
87
87
|
}
|
|
88
|
+
highlight(geometries, options) {
|
|
89
|
+
return this.#highlights.addHighlight(geometries, options);
|
|
90
|
+
}
|
|
91
|
+
zoom(geometries, options) {
|
|
92
|
+
this.#highlights.zoomToHighlight(geometries, options);
|
|
93
|
+
}
|
|
88
94
|
highlightAndZoom(geometries, options) {
|
|
89
|
-
this.#highlights.
|
|
95
|
+
return this.#highlights.addHighlightAndZoom(geometries, options ?? {});
|
|
90
96
|
}
|
|
91
|
-
|
|
97
|
+
removeHighlights() {
|
|
92
98
|
this.#highlights.clearHighlight();
|
|
93
99
|
}
|
|
94
100
|
whenDisplayed() {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MapModelImpl.js","sources":["MapModelImpl.ts"],"sourcesContent":["// SPDX-FileCopyrightText: 2023 Open Pioneer project (https://github.com/open-pioneer)\n// SPDX-License-Identifier: Apache-2.0\nimport {\n EventEmitter,\n ManualPromise,\n createAbortError,\n createLogger,\n createManualPromise,\n isAbortError\n} from \"@open-pioneer/core\";\nimport OlMap from \"ol/Map\";\nimport { unByKey } from \"ol/Observable\";\nimport { EventsKey } from \"ol/events\";\nimport { getCenter } from \"ol/extent\";\nimport { ExtentConfig, HighlightOptions, MapModel, MapModelEvents } from \"../api\";\nimport { LayerCollectionImpl } from \"./LayerCollectionImpl\";\nimport { LineString, Point, Polygon } from \"ol/geom\";\nimport { Highlights } from \"./Highlights\";\nimport { HttpService } from \"@open-pioneer/http\";\n\nconst LOG = createLogger(\"map:MapModel\");\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 #layers = new LayerCollectionImpl(this);\n readonly #highlights: Highlights;\n readonly #sharedDeps: SharedDependencies;\n\n #destroyed = false;\n #container: HTMLElement | undefined;\n #initialExtent: ExtentConfig | undefined;\n #targetWatchKey: EventsKey | 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.#initialExtent = 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 this.#targetWatchKey = this.#olMap.on(\"change:target\", () => {\n this.#onTargetChanged();\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 if (this.#targetWatchKey) {\n unByKey(this.#targetWatchKey);\n }\n this.#targetWatchKey = undefined;\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 layers(): LayerCollectionImpl {\n return this.#layers;\n }\n\n get container(): HTMLElement | undefined {\n return this.#container;\n }\n\n get initialExtent(): ExtentConfig | undefined {\n return this.#initialExtent;\n }\n\n get __sharedDependencies(): SharedDependencies {\n return this.#sharedDeps;\n }\n\n highlightAndZoom(geometries: Point[] | LineString[] | Polygon[], options?: HighlightOptions) {\n this.#highlights.addHighlightOrMarkerAndZoom(geometries, options ?? {});\n }\n\n removeHighlight() {\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) {\n // Initial extent was set from the outside. We simply ensure that it gets displayed by the map.\n const extent = this.#initialExtent;\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 = extent;\n this.emit(\"changed:initialExtent\");\n this.emit(\"changed\");\n }\n } catch (e) {\n throw new Error(`Failed to apply the initial extent.`, { cause: e });\n }\n }\n\n #onTargetChanged() {\n const newContainer: HTMLElement | undefined = this.#olMap.getTargetElement() ?? undefined;\n if (this.#container !== newContainer) {\n this.#container = newContainer;\n this.emit(\"changed:container\");\n this.emit(\"changed\");\n }\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":";;;;;;AAoBA,MAAM,GAAA,GAAM,aAAa,cAAc,CAAA,CAAA;AAShC,MAAM,qBAAqB,YAAiD,CAAA;AAAA,EACtE,GAAA,CAAA;AAAA,EACA,MAAA,CAAA;AAAA,EACA,OAAA,GAAU,IAAI,mBAAA,CAAoB,IAAI,CAAA,CAAA;AAAA,EACtC,WAAA,CAAA;AAAA,EACA,WAAA,CAAA;AAAA,EAET,UAAa,GAAA,KAAA,CAAA;AAAA,EACb,UAAA,CAAA;AAAA,EACA,cAAA,CAAA;AAAA,EACA,eAAA,CAAA;AAAA,EAES,gBAAA,GAAmB,IAAI,eAAgB,EAAA,CAAA;AAAA,EAChD,cAAA,CAAA;AAAA,EACA,cAAA,CAAA;AAAA,EAEA,YAAY,UAKT,EAAA;AACC,IAAM,KAAA,EAAA,CAAA;AACN,IAAA,IAAA,CAAK,MAAM,UAAW,CAAA,EAAA,CAAA;AACtB,IAAA,IAAA,CAAK,SAAS,UAAW,CAAA,KAAA,CAAA;AACzB,IAAA,IAAA,CAAK,iBAAiB,UAAW,CAAA,aAAA,CAAA;AACjC,IAAA,IAAA,CAAK,WAAc,GAAA;AAAA,MACf,aAAa,UAAW,CAAA,WAAA;AAAA,KAC5B,CAAA;AACA,IAAA,IAAA,CAAK,WAAc,GAAA,IAAI,UAAW,CAAA,IAAA,CAAK,MAAM,CAAA,CAAA;AAE7C,IAAA,IAAA,CAAK,cAAiB,GAAA,SAAA,CAAA;AACtB,IAAA,IAAA,CAAK,iBAAkB,CAAA,IAAA;AAAA,MACnB,MAAM;AACF,QAAA,IAAA,CAAK,cAAiB,GAAA,OAAA,CAAA;AACtB,QAAA,IAAA,CAAK,gBAAgB,OAAQ,EAAA,CAAA;AAC7B,QAAA,IAAA,CAAK,cAAiB,GAAA,KAAA,CAAA,CAAA;AAAA,OAC1B;AAAA,MACA,CAAC,KAAU,KAAA;AACP,QAAI,IAAA,CAAC,YAAa,CAAA,KAAK,CAAG,EAAA;AACtB,UAAI,GAAA,CAAA,KAAA,CAAM,4BAA4B,KAAK,CAAA,CAAA;AAAA,SAC/C;AAEA,QAAA,IAAA,CAAK,cAAiB,GAAA,OAAA,CAAA;AACtB,QAAA,IAAA,CAAK,cAAgB,EAAA,MAAA,CAAO,IAAI,KAAA,CAAM,2BAA2B,CAAC,CAAA,CAAA;AAClE,QAAA,IAAA,CAAK,cAAiB,GAAA,KAAA,CAAA,CAAA;AAAA,OAC1B;AAAA,KACJ,CAAA;AACA,IAAA,IAAA,CAAK,eAAkB,GAAA,IAAA,CAAK,MAAO,CAAA,EAAA,CAAG,iBAAiB,MAAM;AACzD,MAAA,IAAA,CAAK,gBAAiB,EAAA,CAAA;AAAA,KACzB,CAAA,CAAA;AAAA,GACL;AAAA,EAEA,OAAU,GAAA;AACN,IAAA,IAAI,KAAK,UAAY,EAAA;AACjB,MAAA,OAAA;AAAA,KACJ;AAEA,IAAA,IAAA,CAAK,UAAa,GAAA,IAAA,CAAA;AAClB,IAAI,IAAA;AACA,MAAA,IAAA,CAAK,KAAK,SAAS,CAAA,CAAA;AAAA,aACd,CAAG,EAAA;AACR,MAAI,GAAA,CAAA,IAAA,CAAK,sEAAsE,CAAC,CAAA,CAAA;AAAA,KACpF;AAEA,IAAA,IAAI,KAAK,eAAiB,EAAA;AACtB,MAAA,OAAA,CAAQ,KAAK,eAAe,CAAA,CAAA;AAAA,KAChC;AACA,IAAA,IAAA,CAAK,eAAkB,GAAA,KAAA,CAAA,CAAA;AACvB,IAAA,IAAA,CAAK,iBAAiB,KAAM,EAAA,CAAA;AAC5B,IAAA,IAAA,CAAK,cAAgB,EAAA,MAAA,CAAO,IAAI,KAAA,CAAM,0BAA0B,CAAC,CAAA,CAAA;AACjE,IAAA,IAAA,CAAK,QAAQ,OAAQ,EAAA,CAAA;AACrB,IAAA,IAAA,CAAK,YAAY,OAAQ,EAAA,CAAA;AACzB,IAAA,IAAA,CAAK,OAAO,OAAQ,EAAA,CAAA;AAAA,GACxB;AAAA,EAEA,IAAI,EAAa,GAAA;AACb,IAAA,OAAO,IAAK,CAAA,GAAA,CAAA;AAAA,GAChB;AAAA,EAEA,IAAI,KAAe,GAAA;AACf,IAAA,OAAO,IAAK,CAAA,MAAA,CAAA;AAAA,GAChB;AAAA,EAEA,IAAI,MAA8B,GAAA;AAC9B,IAAA,OAAO,IAAK,CAAA,OAAA,CAAA;AAAA,GAChB;AAAA,EAEA,IAAI,SAAqC,GAAA;AACrC,IAAA,OAAO,IAAK,CAAA,UAAA,CAAA;AAAA,GAChB;AAAA,EAEA,IAAI,aAA0C,GAAA;AAC1C,IAAA,OAAO,IAAK,CAAA,cAAA,CAAA;AAAA,GAChB;AAAA,EAEA,IAAI,oBAA2C,GAAA;AAC3C,IAAA,OAAO,IAAK,CAAA,WAAA,CAAA;AAAA,GAChB;AAAA,EAEA,gBAAA,CAAiB,YAAgD,OAA4B,EAAA;AACzF,IAAA,IAAA,CAAK,WAAY,CAAA,2BAAA,CAA4B,UAAY,EAAA,OAAA,IAAW,EAAE,CAAA,CAAA;AAAA,GAC1E;AAAA,EAEA,eAAkB,GAAA;AACd,IAAA,IAAA,CAAK,YAAY,cAAe,EAAA,CAAA;AAAA,GACpC;AAAA,EAEA,aAA+B,GAAA;AAC3B,IAAA,IAAI,KAAK,UAAY,EAAA;AACjB,MAAA,OAAO,OAAQ,CAAA,MAAA,CAAO,IAAI,KAAA,CAAM,0BAA0B,CAAC,CAAA,CAAA;AAAA,KAC/D;AACA,IAAI,IAAA,IAAA,CAAK,mBAAmB,OAAS,EAAA;AACjC,MAAA,OAAO,OAAQ,CAAA,MAAA,CAAO,IAAI,KAAA,CAAM,2BAA2B,CAAC,CAAA,CAAA;AAAA,KAChE;AACA,IAAI,IAAA,IAAA,CAAK,mBAAmB,OAAS,EAAA;AACjC,MAAA,OAAO,QAAQ,OAAQ,EAAA,CAAA;AAAA,KAC3B;AACA,IAAQ,OAAA,CAAA,IAAA,CAAK,cAAmB,KAAA,mBAAA,EAAuB,EAAA,OAAA,CAAA;AAAA,GAC3D;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,MAAM,eAAiC,GAAA;AACnC,IAAI,IAAA;AACA,MAAA,MAAM,cAAe,CAAA,IAAA,CAAK,KAAO,EAAA,IAAA,CAAK,iBAAiB,MAAM,CAAA,CAAA;AAAA,aACxD,CAAG,EAAA;AACR,MAAI,IAAA,YAAA,CAAa,CAAC,CAAG,EAAA;AACjB,QAAM,MAAA,CAAA,CAAA;AAAA,OACV;AACA,MAAA,MAAM,IAAI,KAAM,CAAA,CAAA,2CAAA,CAAA,EAA+C,EAAE,KAAA,EAAO,GAAG,CAAA,CAAA;AAAA,KAC/E;AAEA,IAAI,IAAA;AACA,MAAA,MAAM,QAAQ,IAAK,CAAA,MAAA,CAAA;AACnB,MAAM,MAAA,IAAA,GAAO,MAAM,OAAQ,EAAA,CAAA;AAE3B,MAAA,IAAI,KAAK,cAAgB,EAAA;AAErB,QAAA,MAAM,SAAS,IAAK,CAAA,cAAA,CAAA;AACpB,QAAM,MAAA,QAAA,GAAW,CAAC,MAAO,CAAA,IAAA,EAAM,OAAO,IAAM,EAAA,MAAA,CAAO,IAAM,EAAA,MAAA,CAAO,IAAI,CAAA,CAAA;AAEpE,QAAM,MAAA,QAAA,GAAW,UAAU,QAAQ,CAAA,CAAA;AACnC,QAAM,MAAA,UAAA,GAAa,IAAK,CAAA,sBAAA,CAAuB,QAAQ,CAAA,CAAA;AACvD,QAAI,GAAA,CAAA,KAAA,CAAM,2BAA2B,MAAM,CAAA,CAAA;AAC3C,QAAI,GAAA,CAAA,KAAA,CAAM,sBAAsB,QAAQ,CAAA,CAAA;AACxC,QAAI,GAAA,CAAA,KAAA,CAAM,0BAA0B,UAAU,CAAA,CAAA;AAE9C,QAAA,IAAA,CAAK,UAAU,QAAQ,CAAA,CAAA;AACvB,QAAA,IAAA,CAAK,cAAc,UAAU,CAAA,CAAA;AAAA,OAC1B,MAAA;AAGH,QAAM,MAAA,QAAA,GAAW,KAAK,eAAgB,EAAA,CAAA;AACtC,QAAM,MAAA,CAAC,OAAO,CAAG,EAAA,IAAA,GAAO,GAAG,IAAO,GAAA,CAAA,EAAG,IAAO,GAAA,CAAC,CAAI,GAAA,QAAA,CAAA;AACjD,QAAA,MAAM,MAAuB,GAAA,EAAE,IAAM,EAAA,IAAA,EAAM,MAAM,IAAK,EAAA,CAAA;AACtD,QAAI,GAAA,CAAA,KAAA,CAAM,2BAA2B,MAAM,CAAA,CAAA;AAE3C,QAAA,IAAA,CAAK,cAAiB,GAAA,MAAA,CAAA;AACtB,QAAA,IAAA,CAAK,KAAK,uBAAuB,CAAA,CAAA;AACjC,QAAA,IAAA,CAAK,KAAK,SAAS,CAAA,CAAA;AAAA,OACvB;AAAA,aACK,CAAG,EAAA;AACR,MAAA,MAAM,IAAI,KAAM,CAAA,CAAA,mCAAA,CAAA,EAAuC,EAAE,KAAA,EAAO,GAAG,CAAA,CAAA;AAAA,KACvE;AAAA,GACJ;AAAA,EAEA,gBAAmB,GAAA;AACf,IAAA,MAAM,YAAwC,GAAA,IAAA,CAAK,MAAO,CAAA,gBAAA,EAAsB,IAAA,KAAA,CAAA,CAAA;AAChF,IAAI,IAAA,IAAA,CAAK,eAAe,YAAc,EAAA;AAClC,MAAA,IAAA,CAAK,UAAa,GAAA,YAAA,CAAA;AAClB,MAAA,IAAA,CAAK,KAAK,mBAAmB,CAAA,CAAA;AAC7B,MAAA,IAAA,CAAK,KAAK,SAAS,CAAA,CAAA;AAAA,KACvB;AAAA,GACJ;AACJ,CAAA;AAEA,SAAS,cAAA,CAAe,OAAc,MAAoC,EAAA;AACtE,EAAA,MAAM,OAAU,GAAA,IAAI,OAAc,CAAA,CAAC,SAAS,MAAW,KAAA;AACnD,IAAI,IAAA,QAAA,CAAA;AAEJ,IAAA,SAAS,SAAY,GAAA;AACjB,MAAA,MAAM,WAAc,GAAA,KAAA,CAAM,OAAQ,EAAA,IAAK,EAAC,CAAA;AACxC,MAAA,MAAM,CAAC,KAAA,GAAQ,CAAG,EAAA,MAAA,GAAS,CAAC,CAAI,GAAA,WAAA,CAAA;AAChC,MAAA,IAAI,WAAe,IAAA,KAAA,GAAQ,CAAK,IAAA,MAAA,GAAS,CAAG,EAAA;AACxC,QAAO,MAAA,EAAA,CAAA;AAAA,OACX;AAAA,KACJ;AAEA,IAAA,SAAS,OAAU,GAAA;AACf,MAAA,MAAA,CAAO,kBAAkB,CAAA,CAAA;AAAA,KAC7B;AAEA,IAAA,SAAS,OAAO,KAA2B,EAAA;AACvC,MAAA,IAAI,QAAU,EAAA;AACV,QAAA,OAAA,CAAQ,QAAQ,CAAA,CAAA;AAChB,QAAW,QAAA,GAAA,KAAA,CAAA,CAAA;AAAA,OACf;AACA,MAAO,MAAA,CAAA,mBAAA,CAAoB,SAAS,OAAO,CAAA,CAAA;AAE3C,MAAA,IAAI,KAAO,EAAA;AACP,QAAA,MAAA,CAAO,KAAK,CAAA,CAAA;AAAA,OACT,MAAA;AACH,QAAQ,OAAA,CAAA,IAAA,CAAK,EAAE,CAAC,CAAA,CAAA;AAAA,OACpB;AAAA,KACJ;AAEA,IAAA,IAAI,OAAO,OAAS,EAAA;AAChB,MAAA,MAAA,CAAO,kBAAkB,CAAA,CAAA;AACzB,MAAA,OAAA;AAAA,KACJ;AAEA,IAAO,MAAA,CAAA,gBAAA,CAAiB,SAAS,OAAO,CAAA,CAAA;AACxC,IAAW,QAAA,GAAA,KAAA,CAAM,EAAG,CAAA,aAAA,EAAe,SAAS,CAAA,CAAA;AAAA,GAC/C,CAAA,CAAA;AACD,EAAO,OAAA,OAAA,CAAA;AACX,CAAA;AAEA,SAAS,KAAK,YAAqC,EAAA;AAC/C,EAAA,OAAO,IAAI,OAAQ,CAAA,CAAC,YAAY,UAAW,CAAA,OAAA,EAAS,YAAY,CAAC,CAAA,CAAA;AACrE;;;;"}
|
|
1
|
+
{"version":3,"file":"MapModelImpl.js","sources":["MapModelImpl.ts"],"sourcesContent":["// SPDX-FileCopyrightText: 2023 Open Pioneer project (https://github.com/open-pioneer)\n// SPDX-License-Identifier: Apache-2.0\nimport {\n EventEmitter,\n ManualPromise,\n createAbortError,\n createLogger,\n createManualPromise,\n isAbortError\n} from \"@open-pioneer/core\";\nimport OlMap from \"ol/Map\";\nimport { unByKey } from \"ol/Observable\";\nimport { EventsKey } from \"ol/events\";\nimport { getCenter } from \"ol/extent\";\nimport {\n ExtentConfig,\n Highlight,\n HighlightOptions,\n HighlightZoomOptions,\n MapModel,\n MapModelEvents\n} from \"../api\";\nimport { LayerCollectionImpl } from \"./LayerCollectionImpl\";\nimport { Geometry } from \"ol/geom\";\nimport { Highlights } from \"./Highlights\";\nimport { HttpService } from \"@open-pioneer/http\";\n\nconst LOG = createLogger(\"map:MapModel\");\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 #layers = new LayerCollectionImpl(this);\n readonly #highlights: Highlights;\n readonly #sharedDeps: SharedDependencies;\n\n #destroyed = false;\n #container: HTMLElement | undefined;\n #initialExtent: ExtentConfig | undefined;\n #targetWatchKey: EventsKey | 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.#initialExtent = 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 this.#targetWatchKey = this.#olMap.on(\"change:target\", () => {\n this.#onTargetChanged();\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 if (this.#targetWatchKey) {\n unByKey(this.#targetWatchKey);\n }\n this.#targetWatchKey = undefined;\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 layers(): LayerCollectionImpl {\n return this.#layers;\n }\n\n get container(): HTMLElement | undefined {\n return this.#container;\n }\n\n get initialExtent(): ExtentConfig | undefined {\n return this.#initialExtent;\n }\n\n get __sharedDependencies(): SharedDependencies {\n return this.#sharedDeps;\n }\n\n highlight(geometries: Geometry[], options?: HighlightOptions | undefined): Highlight {\n return this.#highlights.addHighlight(geometries, options);\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) {\n // Initial extent was set from the outside. We simply ensure that it gets displayed by the map.\n const extent = this.#initialExtent;\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 = extent;\n this.emit(\"changed:initialExtent\");\n this.emit(\"changed\");\n }\n } catch (e) {\n throw new Error(`Failed to apply the initial extent.`, { cause: e });\n }\n }\n\n #onTargetChanged() {\n const newContainer: HTMLElement | undefined = this.#olMap.getTargetElement() ?? undefined;\n if (this.#container !== newContainer) {\n this.#container = newContainer;\n this.emit(\"changed:container\");\n this.emit(\"changed\");\n }\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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"}
|
|
@@ -13,7 +13,6 @@ export declare class WMTSLayerImpl extends AbstractLayer implements WMTSLayer {
|
|
|
13
13
|
get url(): string;
|
|
14
14
|
get name(): string;
|
|
15
15
|
get matrixSet(): string;
|
|
16
|
-
get attributions(): string | undefined;
|
|
17
16
|
get sublayers(): undefined;
|
|
18
17
|
}
|
|
19
18
|
export declare function getWMTSLegendUrl(capabilities: Record<string, any>, activeLayerId: string | undefined, activeStyleId: string | undefined): string | undefined;
|
|
@@ -12,10 +12,10 @@ class WMTSLayerImpl extends AbstractLayer {
|
|
|
12
12
|
#url;
|
|
13
13
|
#name;
|
|
14
14
|
#matrixSet;
|
|
15
|
-
#attributions;
|
|
16
15
|
#layer;
|
|
17
16
|
#source;
|
|
18
17
|
#legend;
|
|
18
|
+
#sourceOptions;
|
|
19
19
|
#abortController = new AbortController();
|
|
20
20
|
constructor(config) {
|
|
21
21
|
const layer = new TileLayer();
|
|
@@ -27,6 +27,7 @@ class WMTSLayerImpl extends AbstractLayer {
|
|
|
27
27
|
this.#name = config.name;
|
|
28
28
|
this.#layer = layer;
|
|
29
29
|
this.#matrixSet = config.matrixSet;
|
|
30
|
+
this.#sourceOptions = config.sourceOptions;
|
|
30
31
|
}
|
|
31
32
|
destroy() {
|
|
32
33
|
super.destroy();
|
|
@@ -49,6 +50,7 @@ class WMTSLayerImpl extends AbstractLayer {
|
|
|
49
50
|
}
|
|
50
51
|
const source = new WMTS({
|
|
51
52
|
...options,
|
|
53
|
+
...this.#sourceOptions,
|
|
52
54
|
tileLoadFunction: (tile, tileUrl) => {
|
|
53
55
|
this.#loadTile(tile, tileUrl);
|
|
54
56
|
}
|
|
@@ -79,9 +81,6 @@ class WMTSLayerImpl extends AbstractLayer {
|
|
|
79
81
|
get matrixSet() {
|
|
80
82
|
return this.#matrixSet;
|
|
81
83
|
}
|
|
82
|
-
get attributions() {
|
|
83
|
-
return this.#attributions;
|
|
84
|
-
}
|
|
85
84
|
get sublayers() {
|
|
86
85
|
return void 0;
|
|
87
86
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"WMTSLayerImpl.js","sources":["WMTSLayerImpl.ts"],"sourcesContent":["// SPDX-FileCopyrightText: 2023 Open Pioneer project (https://github.com/open-pioneer)\n// SPDX-License-Identifier: Apache-2.0\nimport { createLogger, isAbortError } from \"@open-pioneer/core\";\nimport Tile from \"ol/Tile\";\nimport TileState from \"ol/TileState\";\nimport WMTSCapabilities from \"ol/format/WMTSCapabilities\";\nimport TileLayer from \"ol/layer/Tile\";\nimport type TileSourceType from \"ol/source/Tile\";\nimport WMTS, { optionsFromCapabilities } from \"ol/source/WMTS\";\nimport { WMTSLayer, WMTSLayerConfig } from \"../../api\";\nimport { fetchCapabilities } from \"../../util/capabilities-utils\";\nimport { AbstractLayer } from \"../AbstractLayer\";\nimport { MapModelImpl } from \"../MapModelImpl\";\nimport { ImageTile } from \"ol\";\n\nconst LOG = createLogger(\"map:WMTSLayer\");\n\nexport class WMTSLayerImpl extends AbstractLayer implements WMTSLayer {\n #url: string;\n #name: string;\n #matrixSet: string;\n #attributions?: string | undefined;\n #layer: TileLayer<TileSourceType>;\n #source: WMTS | undefined;\n #legend: string | undefined;\n readonly #abortController = new AbortController();\n\n constructor(config: WMTSLayerConfig) {\n const layer = new TileLayer();\n super({\n ...config,\n olLayer: layer\n });\n this.#url = config.url;\n this.#name = config.name;\n this.#layer = layer;\n this.#matrixSet = config.matrixSet;\n }\n\n destroy(): void {\n super.destroy();\n this.#abortController.abort();\n }\n\n get legend(): string | undefined {\n return this.#legend;\n }\n\n __attach(map: MapModelImpl): void {\n super.__attach(map);\n this.#fetchWMTSCapabilities()\n .then((result: string) => {\n const parser = new WMTSCapabilities();\n const capabilities = parser.read(result);\n const options = optionsFromCapabilities(capabilities, {\n layer: this.#name,\n matrixSet: this.#matrixSet\n });\n if (!options) {\n throw new Error(\"Layer was not found in capabilities\");\n }\n const source = new WMTS({\n ...options,\n tileLoadFunction: (tile, tileUrl) => {\n this.#loadTile(tile, tileUrl);\n }\n });\n this.#source = source;\n this.#layer.setSource(this.#source);\n const activeStyleId = source.getStyle();\n const legendUrl = getWMTSLegendUrl(capabilities, this.name, activeStyleId);\n this.#legend = legendUrl;\n this.__emitChangeEvent(\"changed:legend\");\n })\n .catch((error) => {\n if (isAbortError(error)) {\n LOG.error(`Layer ${this.name} has been destroyed before fetching the data`);\n return;\n }\n LOG.error(`Failed fetching WMTS capabilities for Layer ${this.name}`, error);\n });\n }\n\n get layer() {\n return this.#layer;\n }\n\n get url() {\n return this.#url;\n }\n\n get name() {\n return this.#name;\n }\n\n get matrixSet() {\n return this.#matrixSet;\n }\n\n get attributions() {\n return this.#attributions;\n }\n\n get sublayers(): undefined {\n return undefined;\n }\n\n async #fetchWMTSCapabilities(): Promise<string> {\n const httpService = this.map.__sharedDependencies.httpService;\n return fetchCapabilities(this.#url, httpService, this.#abortController.signal);\n }\n\n async #loadTile(tile: Tile, tileUrl: string): Promise<void> {\n const httpService = this.map.__sharedDependencies.httpService;\n try {\n if (!(tile instanceof ImageTile)) {\n throw new Error(\"Only 'ImageTile' is supported for now.\");\n }\n\n const image = tile.getImage();\n if (!isHtmlImage(image)) {\n // Could also be canvas or video\n throw new Error(\"Only <img> tags are supported as tiles for now.\");\n }\n\n const response = await httpService.fetch(tileUrl);\n if (!response.ok) {\n throw new Error(`Tile request failed with status ${response.status}.`);\n }\n\n const blob = await response.blob();\n const objectUrl = URL.createObjectURL(blob);\n const finish = () => {\n // Cleanup object URL after load to prevent memory leaks.\n // https://stackoverflow.com/questions/62473876/openlayers-6-settileloadfunction-documented-example-uses-url-createobjecturld\n URL.revokeObjectURL(objectUrl);\n image.removeEventListener(\"load\", finish);\n image.removeEventListener(\"error\", finish);\n };\n image.addEventListener(\"load\", finish);\n image.addEventListener(\"error\", finish);\n image.src = objectUrl;\n } catch (e) {\n tile.setState(TileState.ERROR);\n if (!isAbortError(e)) {\n LOG.error(\"Failed to load tile\", e);\n }\n }\n }\n}\n\nfunction isHtmlImage(htmlElement: HTMLElement): htmlElement is HTMLImageElement {\n return htmlElement.tagName === \"IMG\";\n}\n/* eslint-disable @typescript-eslint/no-explicit-any */\nexport function getWMTSLegendUrl(\n capabilities: Record<string, any>,\n activeLayerId: string | undefined,\n activeStyleId: string | undefined\n): string | undefined {\n const content = capabilities?.Contents;\n const layers = content?.Layer;\n\n let activeLayer = layers?.find((layer: any) => layer?.Identifier === activeLayerId);\n if (!activeLayer) {\n LOG.debug(\"Failed to find the active layer in WMTS layer capabilities.\");\n activeLayer = layers?.[0];\n if (!activeLayer) {\n LOG.debug(\"No layer in WMTS capabilities - giving up.\");\n return undefined;\n }\n }\n\n const styles = activeLayer.Style;\n let activeStyle = styles?.find((style: any) => style?.Identifier === activeStyleId);\n if (!activeStyle) {\n LOG.debug(\"Failed to find active style in WMTS layer.\");\n activeStyle = styles?.[0];\n if (!activeStyle) {\n LOG.debug(\"No style in WMTS layer capabilities - giving up.\");\n return undefined;\n }\n }\n\n const legendUrl = activeStyle.LegendURL?.[0]?.href;\n return legendUrl as string | undefined;\n}\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"WMTSLayerImpl.js","sources":["WMTSLayerImpl.ts"],"sourcesContent":["// SPDX-FileCopyrightText: 2023 Open Pioneer project (https://github.com/open-pioneer)\n// SPDX-License-Identifier: Apache-2.0\nimport { createLogger, isAbortError } from \"@open-pioneer/core\";\nimport Tile from \"ol/Tile\";\nimport TileState from \"ol/TileState\";\nimport WMTSCapabilities from \"ol/format/WMTSCapabilities\";\nimport TileLayer from \"ol/layer/Tile\";\nimport type TileSourceType from \"ol/source/Tile\";\nimport WMTS, { optionsFromCapabilities } from \"ol/source/WMTS\";\nimport { WMTSLayer, WMTSLayerConfig } from \"../../api\";\nimport { fetchCapabilities } from \"../../util/capabilities-utils\";\nimport { AbstractLayer } from \"../AbstractLayer\";\nimport { MapModelImpl } from \"../MapModelImpl\";\nimport { ImageTile } from \"ol\";\nimport type { Options as WMSSourceOptions } from \"ol/source/ImageWMS\";\n\nconst LOG = createLogger(\"map:WMTSLayer\");\n\nexport class WMTSLayerImpl extends AbstractLayer implements WMTSLayer {\n #url: string;\n #name: string;\n #matrixSet: string;\n #layer: TileLayer<TileSourceType>;\n #source: WMTS | undefined;\n #legend: string | undefined;\n #sourceOptions?: Partial<WMSSourceOptions>;\n readonly #abortController = new AbortController();\n\n constructor(config: WMTSLayerConfig) {\n const layer = new TileLayer();\n super({\n ...config,\n olLayer: layer\n });\n this.#url = config.url;\n this.#name = config.name;\n this.#layer = layer;\n this.#matrixSet = config.matrixSet;\n this.#sourceOptions = config.sourceOptions;\n }\n\n destroy(): void {\n super.destroy();\n this.#abortController.abort();\n }\n\n get legend(): string | undefined {\n return this.#legend;\n }\n\n __attach(map: MapModelImpl): void {\n super.__attach(map);\n this.#fetchWMTSCapabilities()\n .then((result: string) => {\n const parser = new WMTSCapabilities();\n const capabilities = parser.read(result);\n const options = optionsFromCapabilities(capabilities, {\n layer: this.#name,\n matrixSet: this.#matrixSet\n });\n if (!options) {\n throw new Error(\"Layer was not found in capabilities\");\n }\n const source = new WMTS({\n ...options,\n ...this.#sourceOptions,\n tileLoadFunction: (tile, tileUrl) => {\n this.#loadTile(tile, tileUrl);\n }\n });\n this.#source = source;\n this.#layer.setSource(this.#source);\n const activeStyleId = source.getStyle();\n const legendUrl = getWMTSLegendUrl(capabilities, this.name, activeStyleId);\n this.#legend = legendUrl;\n this.__emitChangeEvent(\"changed:legend\");\n })\n .catch((error) => {\n if (isAbortError(error)) {\n LOG.error(`Layer ${this.name} has been destroyed before fetching the data`);\n return;\n }\n LOG.error(`Failed fetching WMTS capabilities for Layer ${this.name}`, error);\n });\n }\n\n get layer() {\n return this.#layer;\n }\n\n get url() {\n return this.#url;\n }\n\n get name() {\n return this.#name;\n }\n\n get matrixSet() {\n return this.#matrixSet;\n }\n\n get sublayers(): undefined {\n return undefined;\n }\n\n async #fetchWMTSCapabilities(): Promise<string> {\n const httpService = this.map.__sharedDependencies.httpService;\n return fetchCapabilities(this.#url, httpService, this.#abortController.signal);\n }\n\n async #loadTile(tile: Tile, tileUrl: string): Promise<void> {\n const httpService = this.map.__sharedDependencies.httpService;\n try {\n if (!(tile instanceof ImageTile)) {\n throw new Error(\"Only 'ImageTile' is supported for now.\");\n }\n\n const image = tile.getImage();\n if (!isHtmlImage(image)) {\n // Could also be canvas or video\n throw new Error(\"Only <img> tags are supported as tiles for now.\");\n }\n\n const response = await httpService.fetch(tileUrl);\n if (!response.ok) {\n throw new Error(`Tile request failed with status ${response.status}.`);\n }\n\n const blob = await response.blob();\n const objectUrl = URL.createObjectURL(blob);\n const finish = () => {\n // Cleanup object URL after load to prevent memory leaks.\n // https://stackoverflow.com/questions/62473876/openlayers-6-settileloadfunction-documented-example-uses-url-createobjecturld\n URL.revokeObjectURL(objectUrl);\n image.removeEventListener(\"load\", finish);\n image.removeEventListener(\"error\", finish);\n };\n image.addEventListener(\"load\", finish);\n image.addEventListener(\"error\", finish);\n image.src = objectUrl;\n } catch (e) {\n tile.setState(TileState.ERROR);\n if (!isAbortError(e)) {\n LOG.error(\"Failed to load tile\", e);\n }\n }\n }\n}\n\nfunction isHtmlImage(htmlElement: HTMLElement): htmlElement is HTMLImageElement {\n return htmlElement.tagName === \"IMG\";\n}\n/* eslint-disable @typescript-eslint/no-explicit-any */\nexport function getWMTSLegendUrl(\n capabilities: Record<string, any>,\n activeLayerId: string | undefined,\n activeStyleId: string | undefined\n): string | undefined {\n const content = capabilities?.Contents;\n const layers = content?.Layer;\n\n let activeLayer = layers?.find((layer: any) => layer?.Identifier === activeLayerId);\n if (!activeLayer) {\n LOG.debug(\"Failed to find the active layer in WMTS layer capabilities.\");\n activeLayer = layers?.[0];\n if (!activeLayer) {\n LOG.debug(\"No layer in WMTS capabilities - giving up.\");\n return undefined;\n }\n }\n\n const styles = activeLayer.Style;\n let activeStyle = styles?.find((style: any) => style?.Identifier === activeStyleId);\n if (!activeStyle) {\n LOG.debug(\"Failed to find active style in WMTS layer.\");\n activeStyle = styles?.[0];\n if (!activeStyle) {\n LOG.debug(\"No style in WMTS layer capabilities - giving up.\");\n return undefined;\n }\n }\n\n const legendUrl = activeStyle.LegendURL?.[0]?.href;\n return legendUrl as string | undefined;\n}\n"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,23 +1,33 @@
|
|
|
1
1
|
{
|
|
2
2
|
"type": "module",
|
|
3
3
|
"name": "@open-pioneer/map",
|
|
4
|
-
"version": "0.
|
|
4
|
+
"version": "0.4.0",
|
|
5
|
+
"description": "This package integrates OpenLayers maps into an open pioneer trails application.",
|
|
6
|
+
"keywords": [
|
|
7
|
+
"open-pioneer-trails"
|
|
8
|
+
],
|
|
9
|
+
"homepage": "https://github.com/open-pioneer",
|
|
5
10
|
"license": "Apache-2.0",
|
|
11
|
+
"repository": {
|
|
12
|
+
"type": "git",
|
|
13
|
+
"url": "https://github.com/open-pioneer/trails-openlayers-base-packages",
|
|
14
|
+
"directory": "src/packages/map"
|
|
15
|
+
},
|
|
6
16
|
"dependencies": {
|
|
7
17
|
"uuid": "^9.0.1"
|
|
8
18
|
},
|
|
9
19
|
"peerDependencies": {
|
|
10
20
|
"@open-pioneer/chakra-integration": "^1.1.1",
|
|
11
21
|
"@open-pioneer/core": "^1.2.1",
|
|
12
|
-
"@open-pioneer/http": "^2.1.
|
|
13
|
-
"@open-pioneer/runtime": "^2.1.
|
|
22
|
+
"@open-pioneer/http": "^2.1.4",
|
|
23
|
+
"@open-pioneer/runtime": "^2.1.2",
|
|
14
24
|
"@types/proj4": "^2.5.2",
|
|
15
|
-
"ol": "^
|
|
25
|
+
"ol": "^9.0.0",
|
|
16
26
|
"proj4": "^2.9.0",
|
|
17
27
|
"react": "^18.2.0",
|
|
18
28
|
"react-dom": "^18.2.0",
|
|
19
29
|
"react-use": "^17.4.2",
|
|
20
|
-
"@open-pioneer/react-utils": "^0.2.
|
|
30
|
+
"@open-pioneer/react-utils": "^0.2.2"
|
|
21
31
|
},
|
|
22
32
|
"exports": {
|
|
23
33
|
"./package.json": "./package.json",
|
package/ui/MapContainer.js
CHANGED
|
@@ -37,17 +37,9 @@ function MapContainer(props) {
|
|
|
37
37
|
return () => resource?.destroy();
|
|
38
38
|
}
|
|
39
39
|
}, [modelState, mapModel, mapId]);
|
|
40
|
-
useEffect(() => {
|
|
41
|
-
const mapView = mapModel?.olMap.getView();
|
|
42
|
-
if (viewPadding && mapView) {
|
|
43
|
-
const center = mapView.getCenter();
|
|
44
|
-
const { top = 0, right = 0, bottom = 0, left = 0 } = viewPadding;
|
|
45
|
-
mapView.padding = [top, right, bottom, left];
|
|
46
|
-
mapView.animate({ center, duration: 300 });
|
|
47
|
-
}
|
|
48
|
-
}, [viewPadding, mapModel]);
|
|
49
40
|
const mapContainerStyle = {
|
|
50
|
-
height: "100%"
|
|
41
|
+
height: "100%",
|
|
42
|
+
position: "relative"
|
|
51
43
|
};
|
|
52
44
|
return /* @__PURE__ */ jsx(
|
|
53
45
|
"div",
|
package/ui/MapContainer.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MapContainer.js","sources":["MapContainer.tsx"],"sourcesContent":["// SPDX-FileCopyrightText: 2023 Open Pioneer project (https://github.com/open-pioneer)\n// SPDX-License-Identifier: Apache-2.0\nimport { Resource, createLogger } from \"@open-pioneer/core\";\nimport { CommonComponentProps, useCommonComponentProps } from \"@open-pioneer/react-utils\";\nimport type OlMap from \"ol/Map\";\nimport { Extent } from \"ol/extent\";\nimport { ReactNode, useEffect, useMemo, useRef } from \"react\";\nimport { useMapModel } from \"./useMapModel\";\nimport { MapModel, MapPadding } from \"../api\";\nimport { MapContextProvider, MapContextType } from \"./MapContext\";\nconst LOG = createLogger(\"map:MapContainer\");\n\nexport interface MapContainerProps extends CommonComponentProps {\n /** The id of the map to display. */\n mapId: string;\n\n /**\n * Sets the map's padding directly.\n *\n * See: https://openlayers.org/en/latest/apidoc/module-ol_View-View.html#padding)\n */\n viewPadding?: MapPadding | undefined;\n\n /**\n * Behavior performed by the map when the view padding changes.\n *\n * - `none`: Do nothing.\n * - `preserve-center`: Ensures that the center point remains the same by animating the view.\n * - `preserve-extent`: Ensures that the extent remains the same by zooming.\n *\n * @default \"preserve-center\"\n */\n viewPaddingChangeBehavior?: \"none\" | \"preserve-center\" | \"preserve-extent\";\n\n children?: ReactNode;\n\n /**\n * Optional role property.\n *\n * This property is directly applied to the map's container div element.\n */\n role?: string;\n\n /**\n * Optional aria-labelledby property.\n * Do not use together with aria-label.\n *\n * This property is directly applied to the map's container div element.\n */\n \"aria-labelledby\"?: string;\n\n /**\n * Optional aria-label property.\n * Do not use together with aria-label.\n *\n * This property is directly applied to the map's container div element.\n */\n \"aria-label\"?: string;\n}\n\n/**\n * Displays the map with the given id.\n *\n * There can only be at most one MapContainer for every map.\n */\nexport function MapContainer(props: MapContainerProps) {\n const {\n mapId,\n viewPadding,\n viewPaddingChangeBehavior,\n children,\n role,\n \"aria-label\": ariaLabel,\n \"aria-labelledby\": ariaLabelledBy\n } = props;\n const { containerProps } = useCommonComponentProps(\"map-container\", props);\n const mapElement = useRef<HTMLDivElement>(null);\n const modelState = useMapModel(mapId);\n const mapModel = modelState.map;\n\n useEffect(() => {\n if (modelState.kind === \"loading\") {\n return;\n }\n\n if (modelState.kind === \"rejected\") {\n LOG.error(`Cannot display the map. Caused by `, modelState.error);\n return;\n }\n\n if (!mapModel) {\n LOG.error(`No configuration available for map with id '${mapId}'.`);\n return;\n }\n\n // Mount the map into the DOM\n if (mapElement.current) {\n const resource = registerMapTarget(mapModel, mapElement.current);\n return () => resource?.destroy();\n }\n }, [modelState, mapModel, mapId]);\n\n useEffect(() => {\n const mapView = mapModel?.olMap.getView();\n if (viewPadding && mapView) {\n const center = mapView.getCenter();\n const { top = 0, right = 0, bottom = 0, left = 0 } = viewPadding;\n mapView.padding = [top, right, bottom, left];\n mapView.animate({ center, duration: 300 });\n }\n }, [viewPadding, mapModel]);\n\n const mapContainerStyle: React.CSSProperties = {\n height: \"100%\"\n };\n return (\n <div\n {...containerProps}\n role={role}\n aria-label={ariaLabel}\n aria-labelledby={ariaLabelledBy}\n ref={mapElement}\n style={mapContainerStyle}\n //eslint-disable-next-line jsx-a11y/no-noninteractive-tabindex\n tabIndex={0}\n >\n {mapModel && (\n <MapContainerReady\n map={mapModel.olMap}\n viewPadding={viewPadding}\n viewPaddingChangeBehavior={viewPaddingChangeBehavior}\n >\n {children}\n </MapContainerReady>\n )}\n </div>\n );\n}\n\nfunction registerMapTarget(mapModel: MapModel, target: HTMLDivElement): Resource | undefined {\n const mapId = mapModel.id;\n const olMap = mapModel.olMap;\n if (olMap.getTarget()) {\n LOG.error(\n `Failed to display the map: the map already has a target. There may be more than one <MapContainer />.`\n );\n return undefined;\n }\n\n LOG.isDebug() && LOG.debug(`Setting target of map '${mapId}':`, target);\n olMap.setTarget(target);\n\n let unregistered = false;\n return {\n destroy() {\n if (!unregistered) {\n LOG.isDebug() && LOG.debug(`Removing target of map '${mapId}':`, target);\n olMap.setTarget(undefined);\n unregistered = true;\n }\n }\n };\n}\n\n/**\n * This inner component is rendered when the map has been loaded.\n *\n * It provides the map instance and additional properties down the component tree.\n */\nfunction MapContainerReady(\n props: { map: OlMap } & Omit<MapContainerProps, \"mapId\" | \"className\">\n): JSX.Element {\n const {\n map,\n viewPadding: viewPaddingProp,\n viewPaddingChangeBehavior = \"preserve-center\",\n children\n } = props;\n\n const mapAnchorsHost = useMapAnchorsHost(map);\n\n const viewPadding = useMemo<Required<MapPadding>>(() => {\n return {\n left: viewPaddingProp?.left ?? 0,\n right: viewPaddingProp?.right ?? 0,\n top: viewPaddingProp?.top ?? 0,\n bottom: viewPaddingProp?.bottom ?? 0\n };\n }, [viewPaddingProp]);\n\n // Apply view padding\n useEffect(() => {\n const mapView = map?.getView();\n if (!map || !mapView) {\n return;\n }\n\n const oldCenter = mapView.getCenter();\n const oldPadding = fromOlPadding(mapView.padding);\n const oldExtent = extentIncludingPadding(map, oldPadding);\n\n mapView.padding = toOlPadding(viewPadding);\n switch (viewPaddingChangeBehavior) {\n case \"preserve-center\":\n mapView.animate({ center: oldCenter, duration: 300 });\n break;\n case \"preserve-extent\": {\n if (oldExtent) {\n mapView.animate({\n center: oldCenter,\n resolution: mapView.getResolutionForExtent(oldExtent),\n duration: 300\n });\n }\n break;\n }\n case \"none\":\n }\n }, [viewPadding, map, viewPaddingChangeBehavior]);\n\n const mapContext = useMemo((): MapContextType => {\n return {\n map,\n mapAnchorsHost,\n padding: viewPadding\n };\n }, [map, viewPadding, mapAnchorsHost]);\n return <MapContextProvider value={mapContext}>{children}</MapContextProvider>;\n}\n\n/**\n * Creates a div to host the map anchors and mounts it as the first child\n * of the map's overlay container.\n *\n * The purpose of this wrapper div is only to ensure the correct tab order:\n * the map anchors should be focussed before the builtin attribution widget.\n */\nfunction useMapAnchorsHost(olMap: OlMap): HTMLDivElement {\n const div = useRef<HTMLDivElement>();\n if (!div.current) {\n div.current = document.createElement(\"div\");\n div.current.classList.add(\"map-anchors\");\n }\n\n useEffect(() => {\n const child = div.current!;\n const overlayContainer = olMap.getOverlayContainerStopEvent();\n overlayContainer.insertBefore(child, overlayContainer.firstChild);\n return () => child.remove();\n }, [olMap]);\n\n return div.current;\n}\n\n/**\n * Returns the extent visible in the non-padded region of the map.\n */\nfunction extentIncludingPadding(map: OlMap, padding: Required<MapPadding>): Extent | undefined {\n const size = map.getSize();\n if (!size || size.length < 2) {\n return undefined;\n }\n\n const [width, height] = size as [number, number];\n const bottomLeft = map.getCoordinateFromPixel([padding.left, padding.bottom]);\n const topRight = map.getCoordinateFromPixel([\n Math.max(0, width - padding.right),\n Math.max(0, height - padding.top)\n ]);\n if (!bottomLeft || !topRight) {\n return undefined;\n }\n\n const [xmin, ymin] = bottomLeft;\n const [xmax, ymax] = topRight;\n return [xmin, ymin, xmax, ymax] as Extent;\n}\n\nfunction fromOlPadding(padding: number[] | undefined): Required<MapPadding> {\n // top, right, bottom, left\n return {\n top: padding?.[0] ?? 0,\n right: padding?.[1] ?? 0,\n bottom: padding?.[2] ?? 0,\n left: padding?.[3] ?? 0\n };\n}\n\nfunction toOlPadding(padding: Required<MapPadding>): number[] {\n // top, right, bottom, left\n const { top, right, bottom, left } = padding;\n return [top, right, bottom, left];\n}\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"MapContainer.js","sources":["MapContainer.tsx"],"sourcesContent":["// SPDX-FileCopyrightText: 2023 Open Pioneer project (https://github.com/open-pioneer)\n// SPDX-License-Identifier: Apache-2.0\nimport { Resource, createLogger } from \"@open-pioneer/core\";\nimport { CommonComponentProps, useCommonComponentProps } from \"@open-pioneer/react-utils\";\nimport type OlMap from \"ol/Map\";\nimport { Extent } from \"ol/extent\";\nimport { ReactNode, useEffect, useMemo, useRef } from \"react\";\nimport { useMapModel } from \"./useMapModel\";\nimport { MapModel, MapPadding } from \"../api\";\nimport { MapContextProvider, MapContextType } from \"./MapContext\";\nconst LOG = createLogger(\"map:MapContainer\");\n\nexport interface MapContainerProps extends CommonComponentProps {\n /** The id of the map to display. */\n mapId: string;\n\n /**\n * Sets the map's padding directly.\n *\n * See: https://openlayers.org/en/latest/apidoc/module-ol_View-View.html#padding)\n */\n viewPadding?: MapPadding | undefined;\n\n /**\n * Behavior performed by the map when the view padding changes.\n *\n * - `none`: Do nothing.\n * - `preserve-center`: Ensures that the center point remains the same by animating the view.\n * - `preserve-extent`: Ensures that the extent remains the same by zooming.\n *\n * @default \"preserve-center\"\n */\n viewPaddingChangeBehavior?: \"none\" | \"preserve-center\" | \"preserve-extent\";\n\n children?: ReactNode;\n\n /**\n * Optional role property.\n *\n * This property is directly applied to the map's container div element.\n */\n role?: string;\n\n /**\n * Optional aria-labelledby property.\n * Do not use together with aria-label.\n *\n * This property is directly applied to the map's container div element.\n */\n \"aria-labelledby\"?: string;\n\n /**\n * Optional aria-label property.\n * Do not use together with aria-label.\n *\n * This property is directly applied to the map's container div element.\n */\n \"aria-label\"?: string;\n}\n\n/**\n * Displays the map with the given id.\n *\n * There can only be at most one MapContainer for every map.\n */\nexport function MapContainer(props: MapContainerProps) {\n const {\n mapId,\n viewPadding,\n viewPaddingChangeBehavior,\n children,\n role,\n \"aria-label\": ariaLabel,\n \"aria-labelledby\": ariaLabelledBy\n } = props;\n const { containerProps } = useCommonComponentProps(\"map-container\", props);\n const mapElement = useRef<HTMLDivElement>(null);\n const modelState = useMapModel(mapId);\n const mapModel = modelState.map;\n\n useEffect(() => {\n if (modelState.kind === \"loading\") {\n return;\n }\n\n if (modelState.kind === \"rejected\") {\n LOG.error(`Cannot display the map. Caused by `, modelState.error);\n return;\n }\n\n if (!mapModel) {\n LOG.error(`No configuration available for map with id '${mapId}'.`);\n return;\n }\n\n // Mount the map into the DOM\n if (mapElement.current) {\n const resource = registerMapTarget(mapModel, mapElement.current);\n return () => resource?.destroy();\n }\n }, [modelState, mapModel, mapId]);\n\n const mapContainerStyle: React.CSSProperties = {\n height: \"100%\",\n position: \"relative\"\n };\n return (\n <div\n {...containerProps}\n role={role}\n aria-label={ariaLabel}\n aria-labelledby={ariaLabelledBy}\n ref={mapElement}\n style={mapContainerStyle}\n //eslint-disable-next-line jsx-a11y/no-noninteractive-tabindex\n tabIndex={0}\n >\n {mapModel && (\n <MapContainerReady\n map={mapModel.olMap}\n viewPadding={viewPadding}\n viewPaddingChangeBehavior={viewPaddingChangeBehavior}\n >\n {children}\n </MapContainerReady>\n )}\n </div>\n );\n}\n\nfunction registerMapTarget(mapModel: MapModel, target: HTMLDivElement): Resource | undefined {\n const mapId = mapModel.id;\n const olMap = mapModel.olMap;\n if (olMap.getTarget()) {\n LOG.error(\n `Failed to display the map: the map already has a target. There may be more than one <MapContainer />.`\n );\n return undefined;\n }\n\n LOG.isDebug() && LOG.debug(`Setting target of map '${mapId}':`, target);\n olMap.setTarget(target);\n\n let unregistered = false;\n return {\n destroy() {\n if (!unregistered) {\n LOG.isDebug() && LOG.debug(`Removing target of map '${mapId}':`, target);\n olMap.setTarget(undefined);\n unregistered = true;\n }\n }\n };\n}\n\n/**\n * This inner component is rendered when the map has been loaded.\n *\n * It provides the map instance and additional properties down the component tree.\n */\nfunction MapContainerReady(\n props: { map: OlMap } & Omit<MapContainerProps, \"mapId\" | \"className\">\n): JSX.Element {\n const {\n map,\n viewPadding: viewPaddingProp,\n viewPaddingChangeBehavior = \"preserve-center\",\n children\n } = props;\n\n const mapAnchorsHost = useMapAnchorsHost(map);\n\n const viewPadding = useMemo<Required<MapPadding>>(() => {\n return {\n left: viewPaddingProp?.left ?? 0,\n right: viewPaddingProp?.right ?? 0,\n top: viewPaddingProp?.top ?? 0,\n bottom: viewPaddingProp?.bottom ?? 0\n };\n }, [viewPaddingProp]);\n\n // Apply view padding\n useEffect(() => {\n const mapView = map?.getView();\n if (!map || !mapView) {\n return;\n }\n\n const oldCenter = mapView.getCenter();\n const oldPadding = fromOlPadding(mapView.padding);\n const oldExtent = extentIncludingPadding(map, oldPadding);\n\n mapView.padding = toOlPadding(viewPadding);\n switch (viewPaddingChangeBehavior) {\n case \"preserve-center\":\n mapView.animate({ center: oldCenter, duration: 300 });\n break;\n case \"preserve-extent\": {\n if (oldExtent) {\n mapView.animate({\n center: oldCenter,\n resolution: mapView.getResolutionForExtent(oldExtent),\n duration: 300\n });\n }\n break;\n }\n case \"none\":\n }\n }, [viewPadding, map, viewPaddingChangeBehavior]);\n\n const mapContext = useMemo((): MapContextType => {\n return {\n map,\n mapAnchorsHost,\n padding: viewPadding\n };\n }, [map, viewPadding, mapAnchorsHost]);\n return <MapContextProvider value={mapContext}>{children}</MapContextProvider>;\n}\n\n/**\n * Creates a div to host the map anchors and mounts it as the first child\n * of the map's overlay container.\n *\n * The purpose of this wrapper div is only to ensure the correct tab order:\n * the map anchors should be focussed before the builtin attribution widget.\n */\nfunction useMapAnchorsHost(olMap: OlMap): HTMLDivElement {\n const div = useRef<HTMLDivElement>();\n if (!div.current) {\n div.current = document.createElement(\"div\");\n div.current.classList.add(\"map-anchors\");\n }\n\n useEffect(() => {\n const child = div.current!;\n const overlayContainer = olMap.getOverlayContainerStopEvent();\n overlayContainer.insertBefore(child, overlayContainer.firstChild);\n return () => child.remove();\n }, [olMap]);\n\n return div.current;\n}\n\n/**\n * Returns the extent visible in the non-padded region of the map.\n */\nfunction extentIncludingPadding(map: OlMap, padding: Required<MapPadding>): Extent | undefined {\n const size = map.getSize();\n if (!size || size.length < 2) {\n return undefined;\n }\n\n const [width, height] = size as [number, number];\n const bottomLeft = map.getCoordinateFromPixel([padding.left, padding.bottom]);\n const topRight = map.getCoordinateFromPixel([\n Math.max(0, width - padding.right),\n Math.max(0, height - padding.top)\n ]);\n if (!bottomLeft || !topRight) {\n return undefined;\n }\n\n const [xmin, ymin] = bottomLeft;\n const [xmax, ymax] = topRight;\n return [xmin, ymin, xmax, ymax] as Extent;\n}\n\nfunction fromOlPadding(padding: number[] | undefined): Required<MapPadding> {\n // top, right, bottom, left\n return {\n top: padding?.[0] ?? 0,\n right: padding?.[1] ?? 0,\n bottom: padding?.[2] ?? 0,\n left: padding?.[3] ?? 0\n };\n}\n\nfunction toOlPadding(padding: Required<MapPadding>): number[] {\n // top, right, bottom, left\n const { top, right, bottom, left } = padding;\n return [top, right, bottom, left];\n}\n"],"names":[],"mappings":";;;;;;;AAUA,MAAM,GAAA,GAAM,aAAa,kBAAkB,CAAA,CAAA;AAuDpC,SAAS,aAAa,KAA0B,EAAA;AACnD,EAAM,MAAA;AAAA,IACF,KAAA;AAAA,IACA,WAAA;AAAA,IACA,yBAAA;AAAA,IACA,QAAA;AAAA,IACA,IAAA;AAAA,IACA,YAAc,EAAA,SAAA;AAAA,IACd,iBAAmB,EAAA,cAAA;AAAA,GACnB,GAAA,KAAA,CAAA;AACJ,EAAA,MAAM,EAAE,cAAA,EAAmB,GAAA,uBAAA,CAAwB,iBAAiB,KAAK,CAAA,CAAA;AACzE,EAAM,MAAA,UAAA,GAAa,OAAuB,IAAI,CAAA,CAAA;AAC9C,EAAM,MAAA,UAAA,GAAa,YAAY,KAAK,CAAA,CAAA;AACpC,EAAA,MAAM,WAAW,UAAW,CAAA,GAAA,CAAA;AAE5B,EAAA,SAAA,CAAU,MAAM;AACZ,IAAI,IAAA,UAAA,CAAW,SAAS,SAAW,EAAA;AAC/B,MAAA,OAAA;AAAA,KACJ;AAEA,IAAI,IAAA,UAAA,CAAW,SAAS,UAAY,EAAA;AAChC,MAAI,GAAA,CAAA,KAAA,CAAM,CAAsC,kCAAA,CAAA,EAAA,UAAA,CAAW,KAAK,CAAA,CAAA;AAChE,MAAA,OAAA;AAAA,KACJ;AAEA,IAAA,IAAI,CAAC,QAAU,EAAA;AACX,MAAI,GAAA,CAAA,KAAA,CAAM,CAA+C,4CAAA,EAAA,KAAK,CAAI,EAAA,CAAA,CAAA,CAAA;AAClE,MAAA,OAAA;AAAA,KACJ;AAGA,IAAA,IAAI,WAAW,OAAS,EAAA;AACpB,MAAA,MAAM,QAAW,GAAA,iBAAA,CAAkB,QAAU,EAAA,UAAA,CAAW,OAAO,CAAA,CAAA;AAC/D,MAAO,OAAA,MAAM,UAAU,OAAQ,EAAA,CAAA;AAAA,KACnC;AAAA,GACD,EAAA,CAAC,UAAY,EAAA,QAAA,EAAU,KAAK,CAAC,CAAA,CAAA;AAEhC,EAAA,MAAM,iBAAyC,GAAA;AAAA,IAC3C,MAAQ,EAAA,MAAA;AAAA,IACR,QAAU,EAAA,UAAA;AAAA,GACd,CAAA;AACA,EACI,uBAAA,GAAA;AAAA,IAAC,KAAA;AAAA,IAAA;AAAA,MACI,GAAG,cAAA;AAAA,MACJ,IAAA;AAAA,MACA,YAAY,EAAA,SAAA;AAAA,MACZ,iBAAiB,EAAA,cAAA;AAAA,MACjB,GAAK,EAAA,UAAA;AAAA,MACL,KAAO,EAAA,iBAAA;AAAA,MAEP,QAAU,EAAA,CAAA;AAAA,MAET,QACG,EAAA,QAAA,oBAAA,GAAA;AAAA,QAAC,iBAAA;AAAA,QAAA;AAAA,UACG,KAAK,QAAS,CAAA,KAAA;AAAA,UACd,WAAA;AAAA,UACA,yBAAA;AAAA,UAEC,QAAA;AAAA,SAAA;AAAA,OACL;AAAA,KAAA;AAAA,GAER,CAAA;AAER,CAAA;AAEA,SAAS,iBAAA,CAAkB,UAAoB,MAA8C,EAAA;AACzF,EAAA,MAAM,QAAQ,QAAS,CAAA,EAAA,CAAA;AACvB,EAAA,MAAM,QAAQ,QAAS,CAAA,KAAA,CAAA;AACvB,EAAI,IAAA,KAAA,CAAM,WAAa,EAAA;AACnB,IAAI,GAAA,CAAA,KAAA;AAAA,MACA,CAAA,qGAAA,CAAA;AAAA,KACJ,CAAA;AACA,IAAO,OAAA,KAAA,CAAA,CAAA;AAAA,GACX;AAEA,EAAA,GAAA,CAAI,SAAa,IAAA,GAAA,CAAI,MAAM,CAA0B,uBAAA,EAAA,KAAK,MAAM,MAAM,CAAA,CAAA;AACtE,EAAA,KAAA,CAAM,UAAU,MAAM,CAAA,CAAA;AAEtB,EAAA,IAAI,YAAe,GAAA,KAAA,CAAA;AACnB,EAAO,OAAA;AAAA,IACH,OAAU,GAAA;AACN,MAAA,IAAI,CAAC,YAAc,EAAA;AACf,QAAA,GAAA,CAAI,SAAa,IAAA,GAAA,CAAI,MAAM,CAA2B,wBAAA,EAAA,KAAK,MAAM,MAAM,CAAA,CAAA;AACvE,QAAA,KAAA,CAAM,UAAU,KAAS,CAAA,CAAA,CAAA;AACzB,QAAe,YAAA,GAAA,IAAA,CAAA;AAAA,OACnB;AAAA,KACJ;AAAA,GACJ,CAAA;AACJ,CAAA;AAOA,SAAS,kBACL,KACW,EAAA;AACX,EAAM,MAAA;AAAA,IACF,GAAA;AAAA,IACA,WAAa,EAAA,eAAA;AAAA,IACb,yBAA4B,GAAA,iBAAA;AAAA,IAC5B,QAAA;AAAA,GACA,GAAA,KAAA,CAAA;AAEJ,EAAM,MAAA,cAAA,GAAiB,kBAAkB,GAAG,CAAA,CAAA;AAE5C,EAAM,MAAA,WAAA,GAAc,QAA8B,MAAM;AACpD,IAAO,OAAA;AAAA,MACH,IAAA,EAAM,iBAAiB,IAAQ,IAAA,CAAA;AAAA,MAC/B,KAAA,EAAO,iBAAiB,KAAS,IAAA,CAAA;AAAA,MACjC,GAAA,EAAK,iBAAiB,GAAO,IAAA,CAAA;AAAA,MAC7B,MAAA,EAAQ,iBAAiB,MAAU,IAAA,CAAA;AAAA,KACvC,CAAA;AAAA,GACJ,EAAG,CAAC,eAAe,CAAC,CAAA,CAAA;AAGpB,EAAA,SAAA,CAAU,MAAM;AACZ,IAAM,MAAA,OAAA,GAAU,KAAK,OAAQ,EAAA,CAAA;AAC7B,IAAI,IAAA,CAAC,GAAO,IAAA,CAAC,OAAS,EAAA;AAClB,MAAA,OAAA;AAAA,KACJ;AAEA,IAAM,MAAA,SAAA,GAAY,QAAQ,SAAU,EAAA,CAAA;AACpC,IAAM,MAAA,UAAA,GAAa,aAAc,CAAA,OAAA,CAAQ,OAAO,CAAA,CAAA;AAChD,IAAM,MAAA,SAAA,GAAY,sBAAuB,CAAA,GAAA,EAAK,UAAU,CAAA,CAAA;AAExD,IAAQ,OAAA,CAAA,OAAA,GAAU,YAAY,WAAW,CAAA,CAAA;AACzC,IAAA,QAAQ,yBAA2B;AAAA,MAC/B,KAAK,iBAAA;AACD,QAAA,OAAA,CAAQ,QAAQ,EAAE,MAAA,EAAQ,SAAW,EAAA,QAAA,EAAU,KAAK,CAAA,CAAA;AACpD,QAAA,MAAA;AAAA,MACJ,KAAK,iBAAmB,EAAA;AACpB,QAAA,IAAI,SAAW,EAAA;AACX,UAAA,OAAA,CAAQ,OAAQ,CAAA;AAAA,YACZ,MAAQ,EAAA,SAAA;AAAA,YACR,UAAA,EAAY,OAAQ,CAAA,sBAAA,CAAuB,SAAS,CAAA;AAAA,YACpD,QAAU,EAAA,GAAA;AAAA,WACb,CAAA,CAAA;AAAA,SACL;AACA,QAAA,MAAA;AAAA,OACJ;AACK,KACT;AAAA,GACD,EAAA,CAAC,WAAa,EAAA,GAAA,EAAK,yBAAyB,CAAC,CAAA,CAAA;AAEhD,EAAM,MAAA,UAAA,GAAa,QAAQ,MAAsB;AAC7C,IAAO,OAAA;AAAA,MACH,GAAA;AAAA,MACA,cAAA;AAAA,MACA,OAAS,EAAA,WAAA;AAAA,KACb,CAAA;AAAA,GACD,EAAA,CAAC,GAAK,EAAA,WAAA,EAAa,cAAc,CAAC,CAAA,CAAA;AACrC,EAAA,uBAAQ,GAAA,CAAA,kBAAA,EAAA,EAAmB,KAAO,EAAA,UAAA,EAAa,QAAS,EAAA,CAAA,CAAA;AAC5D,CAAA;AASA,SAAS,kBAAkB,KAA8B,EAAA;AACrD,EAAA,MAAM,MAAM,MAAuB,EAAA,CAAA;AACnC,EAAI,IAAA,CAAC,IAAI,OAAS,EAAA;AACd,IAAI,GAAA,CAAA,OAAA,GAAU,QAAS,CAAA,aAAA,CAAc,KAAK,CAAA,CAAA;AAC1C,IAAI,GAAA,CAAA,OAAA,CAAQ,SAAU,CAAA,GAAA,CAAI,aAAa,CAAA,CAAA;AAAA,GAC3C;AAEA,EAAA,SAAA,CAAU,MAAM;AACZ,IAAA,MAAM,QAAQ,GAAI,CAAA,OAAA,CAAA;AAClB,IAAM,MAAA,gBAAA,GAAmB,MAAM,4BAA6B,EAAA,CAAA;AAC5D,IAAiB,gBAAA,CAAA,YAAA,CAAa,KAAO,EAAA,gBAAA,CAAiB,UAAU,CAAA,CAAA;AAChE,IAAO,OAAA,MAAM,MAAM,MAAO,EAAA,CAAA;AAAA,GAC9B,EAAG,CAAC,KAAK,CAAC,CAAA,CAAA;AAEV,EAAA,OAAO,GAAI,CAAA,OAAA,CAAA;AACf,CAAA;AAKA,SAAS,sBAAA,CAAuB,KAAY,OAAmD,EAAA;AAC3F,EAAM,MAAA,IAAA,GAAO,IAAI,OAAQ,EAAA,CAAA;AACzB,EAAA,IAAI,CAAC,IAAA,IAAQ,IAAK,CAAA,MAAA,GAAS,CAAG,EAAA;AAC1B,IAAO,OAAA,KAAA,CAAA,CAAA;AAAA,GACX;AAEA,EAAM,MAAA,CAAC,KAAO,EAAA,MAAM,CAAI,GAAA,IAAA,CAAA;AACxB,EAAM,MAAA,UAAA,GAAa,IAAI,sBAAuB,CAAA,CAAC,QAAQ,IAAM,EAAA,OAAA,CAAQ,MAAM,CAAC,CAAA,CAAA;AAC5E,EAAM,MAAA,QAAA,GAAW,IAAI,sBAAuB,CAAA;AAAA,IACxC,IAAK,CAAA,GAAA,CAAI,CAAG,EAAA,KAAA,GAAQ,QAAQ,KAAK,CAAA;AAAA,IACjC,IAAK,CAAA,GAAA,CAAI,CAAG,EAAA,MAAA,GAAS,QAAQ,GAAG,CAAA;AAAA,GACnC,CAAA,CAAA;AACD,EAAI,IAAA,CAAC,UAAc,IAAA,CAAC,QAAU,EAAA;AAC1B,IAAO,OAAA,KAAA,CAAA,CAAA;AAAA,GACX;AAEA,EAAM,MAAA,CAAC,IAAM,EAAA,IAAI,CAAI,GAAA,UAAA,CAAA;AACrB,EAAM,MAAA,CAAC,IAAM,EAAA,IAAI,CAAI,GAAA,QAAA,CAAA;AACrB,EAAA,OAAO,CAAC,IAAA,EAAM,IAAM,EAAA,IAAA,EAAM,IAAI,CAAA,CAAA;AAClC,CAAA;AAEA,SAAS,cAAc,OAAqD,EAAA;AAExE,EAAO,OAAA;AAAA,IACH,GAAA,EAAK,OAAU,GAAA,CAAC,CAAK,IAAA,CAAA;AAAA,IACrB,KAAA,EAAO,OAAU,GAAA,CAAC,CAAK,IAAA,CAAA;AAAA,IACvB,MAAA,EAAQ,OAAU,GAAA,CAAC,CAAK,IAAA,CAAA;AAAA,IACxB,IAAA,EAAM,OAAU,GAAA,CAAC,CAAK,IAAA,CAAA;AAAA,GAC1B,CAAA;AACJ,CAAA;AAEA,SAAS,YAAY,OAAyC,EAAA;AAE1D,EAAA,MAAM,EAAE,GAAA,EAAK,KAAO,EAAA,MAAA,EAAQ,MAAS,GAAA,OAAA,CAAA;AACrC,EAAA,OAAO,CAAC,GAAA,EAAK,KAAO,EAAA,MAAA,EAAQ,IAAI,CAAA,CAAA;AACpC;;;;"}
|