@open-pioneer/map 1.3.0-dev.20260225133423 → 1.3.0-dev.20260310142705

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # @open-pioneer/map
2
2
 
3
- ## 1.3.0-dev.20260225133423
3
+ ## 1.3.0-dev.20260310142705
4
4
 
5
5
  ### Minor Changes
6
6
 
@@ -11,7 +11,19 @@
11
11
  The property is based on OpenLayers `loadstart` and `loadend` events (see [Documentation](https://openlayers.org/en/latest/apidoc/module-ol_MapEvent-MapEvent.html#event:loadstart)).
12
12
  - 73453af: Update OpenLayers to 10.8.0
13
13
  - fcbd505: Sanitize HTML used for layer attributions.
14
+ - 33ab02f: Move highlight methods to `mapModel.highlights`.
15
+ - `mapModel.highlight()` -> `mapModel.highlights.add()`
16
+ - `mapModel.highlightAndZoom()` -> `mapModel.highlights.addAndZoom()`
17
+ - `mapModel.removeHighlights()` -> `mapModel.highlights.clear()`
18
+
19
+ The old methods on the Map Model have been deprecated and will be removed in a future major release.
20
+
14
21
  - d54ccfd: Update to Chakra UI 3.32.0
22
+ - 33ab02f: Add new `mapModel.overlays` API to render arbitrary React content on the map at certain coordinates.
23
+ This can be helpful for feature info, popups and for tooltips during map interactions.
24
+
25
+ Use `mapModel.overlay.add({ content: <SomeReactContent />, ...})` to create a new overlay.
26
+
15
27
  - 2ceb1ca: MapContainer: allow configuration of `rootProps` and `containerProps`.
16
28
  This can be used to set custom attributes on the respective DOM elements.
17
29
 
@@ -803,12 +815,6 @@
803
815
  - b5bb7a1: Adjusted name of Open Pioneer project to Open Pioneer Trails
804
816
  - 81bc7da: Update trails dependencies
805
817
  - 2c092dc: Update dependencies
806
- - Updated dependencies [4140646]
807
- - Updated dependencies [4140646]
808
- - Updated dependencies [81bc7da]
809
- - Updated dependencies [2c092dc]
810
- - Updated dependencies [4140646]
811
- - @open-pioneer/react-utils@0.2.3
812
818
 
813
819
  ## 0.5.0
814
820
 
@@ -831,8 +837,6 @@
831
837
  - 6162979: Update versions of core packages
832
838
  - ac7fdd1: Update documentation
833
839
  - 13ea342: Remove duplicate viewPadding application.
834
- - Updated dependencies [1a8ad89]
835
- - @open-pioneer/react-utils@0.2.2
836
840
 
837
841
  ## 0.3.1
838
842
 
@@ -850,8 +854,6 @@
850
854
  ### Patch Changes
851
855
 
852
856
  - a582e5e: Add property `viewPadding` to `HighlightOptions`.
853
- - Updated dependencies [762e7b9]
854
- - @open-pioneer/react-utils@0.2.1
855
857
 
856
858
  ## 0.2.0
857
859
 
@@ -859,11 +861,6 @@
859
861
 
860
862
  - 70349a8: Update to new core packages major versions
861
863
 
862
- ### Patch Changes
863
-
864
- - Updated dependencies [70349a8]
865
- - @open-pioneer/react-utils@0.2.0
866
-
867
864
  ## 0.1.1
868
865
 
869
866
  ### Patch Changes
@@ -878,8 +875,3 @@
878
875
  ### Minor Changes
879
876
 
880
877
  - bb2f27a: Initial release.
881
-
882
- ### Patch Changes
883
-
884
- - Updated dependencies [182da1c]
885
- - @open-pioneer/react-utils@0.1.0
package/MapRegistry.js CHANGED
@@ -1,7 +1,7 @@
1
1
  import { batch } from '@conterra/reactivity-core';
2
2
  import { on } from '@conterra/reactivity-events';
3
3
  import { createLogger } from '@open-pioneer/core';
4
- import { sourceId } from './_virtual/source-info.js';
4
+ import { sourceId$10 as sourceId } from './_virtual/source-info.js';
5
5
  import { createMapModel } from './model/createMapModel.js';
6
6
 
7
7
  const LOG = createLogger(sourceId);
package/README.md CHANGED
@@ -1060,6 +1060,69 @@ To access the map model instance, use the React hooks `useMapModel` or `useMapMo
1060
1060
  }
1061
1061
  ```
1062
1062
 
1063
+ #### Map overlays
1064
+
1065
+ Use the `mapModel.overlays` API to create overlays on the map.
1066
+
1067
+ An overlay is a UI element that is displayed over the map.
1068
+ Overlays are tied to coordinates on the map and not to a position on the screen.
1069
+ The rendered content of an overlay is a `ReactNode`: you can use either simple text or arbitrarily rich React components.
1070
+
1071
+ The new overlays API is implemented on top of the raw OpenLayers overlays and should be preferred for in most cases.
1072
+ You can access the raw `olOverlay` in advanced scenarios.
1073
+
1074
+ Example:
1075
+
1076
+ ```tsx
1077
+ import { Span } from "@chakra-ui/react";
1078
+ import { MapModel } from "@open-pioneer/map";
1079
+
1080
+ const map: MapModel = ... // the map model
1081
+
1082
+ // Add a new overlay to map and get overlay instance
1083
+ const myOverlay = map.overlays.add({
1084
+ content: <MyOverlayContent innerText="Initial Content!"></MyOverlayContent>, // initially rendered content
1085
+ tag: "my-overlay", // custom identifier
1086
+ position: [7.6, 52.0], // coordinates in map projection
1087
+ className: "overlay-css-class",
1088
+ positioning: "bottom-center"
1089
+ // mode: "follow-pointer" // overlay would automatically follow pointer movement (default "set-position")
1090
+ });
1091
+
1092
+ // Get all current overlays
1093
+ let currentOverlaysList = map.overlays.getAll();
1094
+ console.log(currentOverlaysList.length) // prints 1
1095
+
1096
+ myOverlay.setPosition([7.75, 52.25]); // manually change position in mode "set-position"
1097
+ myOverlay.setContent(<MyOverlayContent innerText="New Content!"></MyOverlayContent>); // render new content
1098
+
1099
+ // Remove and destroy overlay.
1100
+ // Destroyed overlays cannot be reused.
1101
+ myOverlay.destroy();
1102
+
1103
+ currentOverlaysList = map.overlays.getAll();
1104
+ console.log(currentOverlaysList.length) //prints 0
1105
+
1106
+ // React component that is rendered as overlay content
1107
+ function MyOverlayContent(props: { innerText: string }) {
1108
+ const { innerText } = props;
1109
+ return <Span>{innerText}</Span>;
1110
+ }
1111
+ ```
1112
+
1113
+ When within a plain TypeScript file, use React's `createElement` function instead of JSX:
1114
+
1115
+ ```ts
1116
+ import { createElement } from "react";
1117
+
1118
+ const myOverlay = map.overlays.add({
1119
+ content: createElement(MyOverlayContent, {
1120
+ // props ...
1121
+ })
1122
+ // ...
1123
+ });
1124
+ ```
1125
+
1063
1126
  ## License
1064
1127
 
1065
1128
  Apache-2.0 (see `LICENSE` file)
@@ -1,10 +1,12 @@
1
- const sourceId$9 = "@open-pioneer/map/ui/MapContainer";
1
+ const sourceId$a = "@open-pioneer/map/ui/MapContainer";
2
2
 
3
- const sourceId$8 = "@open-pioneer/map/model/MapModel";
3
+ const sourceId$9 = "@open-pioneer/map/model/MapModel";
4
4
 
5
- const sourceId$7 = "@open-pioneer/map/layers/AbstractLayer";
5
+ const sourceId$8 = "@open-pioneer/map/layers/AbstractLayer";
6
6
 
7
- const sourceId$6 = "@open-pioneer/map/model/LayerCollection";
7
+ const sourceId$7 = "@open-pioneer/map/model/LayerCollection";
8
+
9
+ const sourceId$6 = "@open-pioneer/map/model/Overlays";
8
10
 
9
11
  const sourceId$5 = "@open-pioneer/map/layers/WMSLayer";
10
12
 
@@ -18,5 +20,5 @@ const sourceId$1 = "@open-pioneer/map/MapRegistry";
18
20
 
19
21
  const sourceId = "@open-pioneer/map/model/createMapModel";
20
22
 
21
- export { sourceId$1 as sourceId, sourceId$7 as sourceId$1, sourceId$5 as sourceId$2, sourceId$3, sourceId$4, sourceId$2 as sourceId$5, sourceId$6, sourceId$8 as sourceId$7, sourceId as sourceId$8, sourceId$9 };
23
+ export { sourceId$8 as sourceId, sourceId$7 as sourceId$1, sourceId$1 as sourceId$10, sourceId$6 as sourceId$2, sourceId$9 as sourceId$3, sourceId$a as sourceId$4, sourceId$4 as sourceId$5, sourceId$5 as sourceId$6, sourceId$2 as sourceId$7, sourceId$3 as sourceId$8, sourceId as sourceId$9 };
22
24
  //# sourceMappingURL=source-info.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"source-info.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;"}
1
+ {"version":3,"file":"source-info.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;"}
package/index.d.ts CHANGED
@@ -45,8 +45,10 @@ export { type SublayersCollection } from "./layers/shared/SublayersCollection";
45
45
  export { type AddLayerOptions, type AddLayerOptionsAboveBelow, type AddLayerOptionsBase, type AddLayerOptionsTopBottom } from "./layers/shared/AddLayerOptions";
46
46
  export { type LayerRetrievalOptions, type RecursiveRetrievalOptions } from "./layers/shared/LayerRetrievalOptions";
47
47
  export { type CoordinateConfig, type ExtentConfig, type InitialExtentConfig, type InitialPositionConfig, type InitialViewConfig, type MapConfig, type OlMapOptions } from "./model/MapConfig";
48
- export { type MapModel, type DisplayTarget, type Highlight, type HighlightOptions, type HighlightStyle, type HighlightZoomOptions, type MapPadding, type ZoomOptions } from "./model/MapModel";
48
+ export { type MapModel, type DisplayTarget, type MapPadding, type ZoomOptions } from "./model/MapModel";
49
+ export { type Highlight, type Highlights, type HighlightOptions, type HighlightStyle, type HighlightZoomOptions } from "./model/Highlights";
49
50
  export { type LayerCollection } from "./model/LayerCollection";
51
+ export { type Overlay, type OverlayProperties, type OlOverlayOptions, type OverlayPositioning, type Overlays } from "./model/Overlays";
50
52
  export { type LayerFactory, type LayerCreateOptions } from "./LayerFactory";
51
53
  export { type MapConfigProvider, type MapConfigProviderOptions, type MapRegistry } from "./MapRegistry";
52
54
  export { calculateBufferedExtent } from "./utils/geometry-utils";
@@ -2,7 +2,7 @@ import { synchronized, reactive, computed } from '@conterra/reactivity-core';
2
2
  import { createLogger, destroyResource } from '@open-pioneer/core';
3
3
  import OlLayer from 'ol/layer/Layer.js';
4
4
  import { unByKey } from 'ol/Observable.js';
5
- import { sourceId$1 as sourceId } from '../_virtual/source-info.js';
5
+ import { sourceId } from '../_virtual/source-info.js';
6
6
  import { AbstractLayerBase } from './AbstractLayerBase.js';
7
7
  import { getLayerDependencies, SET_VISIBLE, ATTACH_TO_MAP, GET_DEPS, LAYER_DEPS } from './shared/internals.js';
8
8
 
@@ -3,7 +3,7 @@ import { createLogger, deprecated, destroyResource, isAbortError } from '@open-p
3
3
  import WMSCapabilities from 'ol/format/WMSCapabilities.js';
4
4
  import ImageLayer from 'ol/layer/Image.js';
5
5
  import ImageWMS from 'ol/source/ImageWMS.js';
6
- import { sourceId$2 as sourceId } from '../_virtual/source-info.js';
6
+ import { sourceId$6 as sourceId } from '../_virtual/source-info.js';
7
7
  import { fetchText } from '../utils/fetch.js';
8
8
  import { INTERNAL_CONSTRUCTOR_TAG } from '../utils/InternalConstructorTag.js';
9
9
  import { AbstractLayer } from './AbstractLayer.js';
@@ -5,7 +5,7 @@ import TileState from 'ol/TileState.js';
5
5
  import WMTSCapabilities from 'ol/format/WMTSCapabilities.js';
6
6
  import TileLayer from 'ol/layer/Tile.js';
7
7
  import WMTS, { optionsFromCapabilities } from 'ol/source/WMTS.js';
8
- import { sourceId$3 as sourceId } from '../_virtual/source-info.js';
8
+ import { sourceId$8 as sourceId } from '../_virtual/source-info.js';
9
9
  import { fetchText } from '../utils/fetch.js';
10
10
  import { AbstractLayer } from './AbstractLayer.js';
11
11
  import { ATTACH_TO_MAP, GET_DEPS } from './shared/internals.js';
@@ -1,5 +1,5 @@
1
1
  import { createLogger } from '@open-pioneer/core';
2
- import { sourceId$4 as sourceId } from '../../_virtual/source-info.js';
2
+ import { sourceId$5 as sourceId } from '../../_virtual/source-info.js';
3
3
 
4
4
  const LOG = createLogger(sourceId);
5
5
  function getLegendUrl(capabilities, layerName) {
@@ -1,5 +1,5 @@
1
1
  import { createLogger } from '@open-pioneer/core';
2
- import { sourceId$5 as sourceId } from '../../_virtual/source-info.js';
2
+ import { sourceId$7 as sourceId } from '../../_virtual/source-info.js';
3
3
 
4
4
  const LOG = createLogger(sourceId);
5
5
  function getLegendUrl(capabilities, activeLayerId, activeStyleId) {
@@ -1,47 +1,91 @@
1
+ import { Resource } from "@open-pioneer/core";
1
2
  import { Feature } from "ol";
2
3
  import { Geometry } from "ol/geom";
3
4
  import VectorLayer from "ol/layer/Vector";
4
5
  import VectorSource from "ol/source/Vector";
6
+ import { StyleLike } from "ol/style/Style";
5
7
  import { LayerDependencies } from "../layers/shared/internals";
6
- import { DisplayTarget, HighlightOptions, HighlightZoomOptions, MapModel, ZoomOptions } from "./MapModel";
8
+ import { DisplayTarget, MapModel, ZoomOptions } from "./MapModel";
9
+ export declare const DESTROY_HIGHLIGHTS: unique symbol;
10
+ export declare const GET_HIGHLIGHT_LAYER: unique symbol;
11
+ /**
12
+ * Style options supported when creating a new {@link Highlight}.
13
+ *
14
+ * @group Map Model
15
+ **/
16
+ export interface HighlightOptions {
17
+ /**
18
+ * Optional styles to override the default styles.
19
+ */
20
+ highlightStyle?: HighlightStyle;
21
+ }
22
+ /**
23
+ * Options supported by the map model's {@link MapModel.highlightAndZoom | highlightAndZoom} method.
24
+ *
25
+ * @group Map Model
26
+ **/
27
+ export interface HighlightZoomOptions extends HighlightOptions, ZoomOptions {
28
+ }
29
+ /**
30
+ * Custom styles when creating a new {@link Highlight}.
31
+ *
32
+ * @group Map Model
33
+ */
34
+ export type HighlightStyle = {
35
+ Point?: StyleLike;
36
+ LineString?: StyleLike;
37
+ Polygon?: StyleLike;
38
+ MultiPolygon?: StyleLike;
39
+ MultiPoint?: StyleLike;
40
+ MultiLineString?: StyleLike;
41
+ };
42
+ /**
43
+ * Represents the additional graphical representations of objects.
44
+ *
45
+ * See also {@link MapModel.highlight}.
46
+ *
47
+ * @group Map Model
48
+ */
49
+ export interface Highlight extends Resource {
50
+ readonly isActive: boolean;
51
+ }
52
+ /**
53
+ * Manages highlights on the map.
54
+ *
55
+ * @group Map Model
56
+ */
7
57
  export declare class Highlights {
8
- #private;
9
58
  private map;
10
- private olMap;
11
59
  private olLayer;
12
60
  private layer;
13
61
  private olSource;
14
62
  private activeHighlights;
15
63
  constructor(map: MapModel, layerDeps: LayerDependencies);
64
+ [DESTROY_HIGHLIGHTS](): void;
16
65
  /**
17
- * Returns the layer used for highlights.
66
+ * Creates a highlight at the given targets.
67
+ *
68
+ * A highlight is a temporary graphic on the map that calls attention to a point or an area.
69
+ *
70
+ * Call `destroy()` on the returned highlight object to remove the highlight.
18
71
  */
19
- getLayer(): VectorLayer<VectorSource<Feature<Geometry, {
20
- [x: string]: any;
21
- }>>, Feature<Geometry, {
22
- [x: string]: any;
23
- }>>;
24
- /**
25
- * This method removes all highlights before destroying the class
26
- */
27
- destroy(): void;
72
+ add(displayTargets: DisplayTarget[], options?: HighlightOptions | undefined): Highlight;
28
73
  /**
29
- * This method displays geometries or BaseFeatures with optional styling in the map
74
+ * Creates a highlight and zooms to the given targets.
75
+ *
76
+ * See also {@link add} and {@link MapModel.zoom}.
30
77
  */
31
- addHighlight(displayTarget: DisplayTarget[], highlightOptions: HighlightOptions | undefined): {
32
- readonly isActive: boolean;
33
- destroy(): void;
34
- };
78
+ addAndZoom(displayTarget: DisplayTarget[], options?: HighlightZoomOptions | undefined): Highlight;
35
79
  /**
36
- * This method zoom to geometries or BaseFeatures
80
+ * This method destroys all active Highlights.
37
81
  */
38
- zoomToHighlight(displayTarget: DisplayTarget[], options: ZoomOptions | undefined): void;
82
+ clear(): void;
39
83
  /**
40
- * This method displays geometries or BaseFeatures with optional styling in the map and executed a zoom
84
+ * Returns the layer used for highlights.
41
85
  */
42
- addHighlightAndZoom(displayTarget: DisplayTarget[], highlightZoomStyle: HighlightZoomOptions | undefined): {
43
- readonly isActive: boolean;
44
- destroy(): void;
45
- };
46
- clearHighlight(): void;
86
+ [GET_HIGHLIGHT_LAYER](): VectorLayer<VectorSource<Feature<Geometry, {
87
+ [x: string]: any;
88
+ }>>, Feature<Geometry, {
89
+ [x: string]: any;
90
+ }>>;
47
91
  }
@@ -1,5 +1,4 @@
1
1
  import { Feature } from 'ol';
2
- import { createEmpty, extend, getCenter, getArea } from 'ol/extent.js';
3
2
  import VectorLayer from 'ol/layer/Vector.js';
4
3
  import VectorSource from 'ol/source/Vector.js';
5
4
  import { Style, Stroke, Fill, Icon } from 'ol/style.js';
@@ -7,21 +6,18 @@ import { toFunction } from 'ol/style/Style.js';
7
6
  import mapMarkerUrl from '../assets/images/mapMarker.png?url';
8
7
  import { SimpleLayer } from '../layers/SimpleLayer.js';
9
8
  import { INTERNAL_CONSTRUCTOR_TAG } from '../utils/InternalConstructorTag.js';
10
- import { calculateBufferedExtent } from '../utils/geometry-utils.js';
9
+ import { getGeometries } from './getGeometries.js';
11
10
 
12
- const DEFAULT_OL_POINT_ZOOM_LEVEL = 17;
13
- const DEFAULT_OL_MAX_ZOOM_LEVEL = 20;
14
- const DEFAULT_VIEW_PADDING = { top: 50, right: 20, bottom: 10, left: 20 };
11
+ const DESTROY_HIGHLIGHTS = /* @__PURE__ */ Symbol("DESTROY_HIGHLIGHTS");
12
+ const GET_HIGHLIGHT_LAYER = /* @__PURE__ */ Symbol("GET_HIGHLIGHT_LAYER");
15
13
  class Highlights {
16
14
  map;
17
- olMap;
18
15
  olLayer;
19
16
  layer;
20
17
  olSource;
21
18
  activeHighlights;
22
19
  constructor(map, layerDeps) {
23
20
  this.map = map;
24
- this.olMap = this.map.olMap;
25
21
  this.olSource = new VectorSource({
26
22
  features: void 0
27
23
  });
@@ -44,34 +40,18 @@ class Highlights {
44
40
  map.layers.addLayer(this.layer, { at: "topmost" });
45
41
  this.activeHighlights = /* @__PURE__ */ new Set();
46
42
  }
47
- /**
48
- * Returns the layer used for highlights.
49
- */
50
- getLayer() {
51
- return this.olLayer;
52
- }
53
- /**
54
- * This method removes all highlights before destroying the class
55
- */
56
- destroy() {
57
- this.clearHighlight();
43
+ [DESTROY_HIGHLIGHTS]() {
44
+ this.clear();
58
45
  }
59
46
  /**
60
- * Method of filtering out objects that are not geometry or have no property geometry.
47
+ * Creates a highlight at the given targets.
48
+ *
49
+ * A highlight is a temporary graphic on the map that calls attention to a point or an area.
50
+ *
51
+ * Call `destroy()` on the returned highlight object to remove the highlight.
61
52
  */
62
- #filterGeoobjects(geoObjects) {
63
- const geometries = [];
64
- geoObjects.forEach((item) => {
65
- if ("getType" in item) geometries.push(item);
66
- if ("geometry" in item && item.geometry) geometries.push(item.geometry);
67
- });
68
- return geometries;
69
- }
70
- /**
71
- * This method displays geometries or BaseFeatures with optional styling in the map
72
- */
73
- addHighlight(displayTarget, highlightOptions) {
74
- const geometries = this.#filterGeoobjects(displayTarget);
53
+ add(displayTargets, options) {
54
+ const geometries = getGeometries(displayTargets);
75
55
  if (geometries.length === 0) {
76
56
  return {
77
57
  get isActive() {
@@ -87,7 +67,7 @@ class Highlights {
87
67
  type,
88
68
  geometry
89
69
  });
90
- feature.setStyle(getOwnStyle(type, highlightOptions?.highlightStyle));
70
+ feature.setStyle(getOwnStyle(type, options?.highlightStyle));
91
71
  return feature;
92
72
  });
93
73
  const source = this.olSource;
@@ -111,56 +91,28 @@ class Highlights {
111
91
  return highlight;
112
92
  }
113
93
  /**
114
- * This method zoom to geometries or BaseFeatures
94
+ * Creates a highlight and zooms to the given targets.
95
+ *
96
+ * See also {@link add} and {@link MapModel.zoom}.
115
97
  */
116
- zoomToHighlight(displayTarget, options) {
117
- const geometries = this.#filterGeoobjects(displayTarget);
118
- if (geometries.length === 0) {
119
- return;
120
- }
121
- let extent = createEmpty();
122
- for (const geometry of geometries) {
123
- extent = extend(extent, geometry.getExtent());
124
- }
125
- const bufferParameter = options?.buffer;
126
- if (typeof bufferParameter === "number") {
127
- extent = calculateBufferedExtent(extent, bufferParameter);
128
- }
129
- const center = getCenter(extent);
130
- const isPoint = getArea(extent) === 0;
131
- const zoomScale = isPoint ? options?.pointZoom ?? DEFAULT_OL_POINT_ZOOM_LEVEL : options?.maxZoom ?? DEFAULT_OL_MAX_ZOOM_LEVEL;
132
- setCenter(this.olMap, center);
133
- const {
134
- top = 0,
135
- right = 0,
136
- bottom = 0,
137
- left = 0
138
- } = options?.viewPadding ?? DEFAULT_VIEW_PADDING;
139
- const padding = [top, right, bottom, left];
140
- zoomTo(this.olMap, extent, zoomScale, padding);
98
+ addAndZoom(displayTarget, options) {
99
+ const result = this.add(displayTarget, options);
100
+ this.map.zoom(displayTarget, options);
101
+ return result;
141
102
  }
142
103
  /**
143
- * This method displays geometries or BaseFeatures with optional styling in the map and executed a zoom
104
+ * This method destroys all active Highlights.
144
105
  */
145
- addHighlightAndZoom(displayTarget, highlightZoomStyle) {
146
- const result = this.addHighlight(displayTarget, highlightZoomStyle);
147
- this.zoomToHighlight(displayTarget, highlightZoomStyle);
148
- return result;
149
- }
150
- clearHighlight() {
106
+ clear() {
151
107
  for (const highlight of this.activeHighlights) {
152
108
  highlight.destroy();
153
109
  }
154
110
  }
155
- }
156
- function setCenter(olMap, coordinates) {
157
- coordinates && coordinates.length && olMap.getView().setCenter(coordinates);
158
- }
159
- function zoomTo(olMap, extent, zoomLevel, padding) {
160
- if (extent) {
161
- olMap.getView().fit(extent, { maxZoom: zoomLevel, padding });
162
- } else {
163
- zoomLevel && olMap.getView().setZoom(zoomLevel);
111
+ /**
112
+ * Returns the layer used for highlights.
113
+ */
114
+ [GET_HIGHLIGHT_LAYER]() {
115
+ return this.olLayer;
164
116
  }
165
117
  }
166
118
  function resolveStyle(feature, resolution) {
@@ -262,5 +214,5 @@ const defaultHighlightStyle = {
262
214
  ]
263
215
  };
264
216
 
265
- export { Highlights };
217
+ export { DESTROY_HIGHLIGHTS, Highlights };
266
218
  //# sourceMappingURL=Highlights.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"Highlights.js","sources":["Highlights.ts"],"sourcesContent":["// SPDX-FileCopyrightText: 2023-2025 Open Pioneer project (https://github.com/open-pioneer)\n// SPDX-License-Identifier: Apache-2.0\nimport { Feature } from \"ol\";\nimport { FeatureLike } from \"ol/Feature\";\nimport OlMap from \"ol/Map\";\nimport { Coordinate } from \"ol/coordinate\";\nimport { createEmpty, extend, Extent, getArea, getCenter } from \"ol/extent\";\nimport { Geometry } from \"ol/geom\";\nimport { Type } from \"ol/geom/Geometry\";\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 mapMarkerUrl from \"../assets/images/mapMarker.png?url\";\nimport { SimpleLayer } from \"../layers/SimpleLayer\";\nimport { LayerDependencies } from \"../layers/shared/internals\";\nimport { INTERNAL_CONSTRUCTOR_TAG } from \"../utils/InternalConstructorTag\";\nimport { calculateBufferedExtent } from \"../utils/geometry-utils\";\nimport {\n DisplayTarget,\n Highlight,\n HighlightOptions,\n HighlightStyle,\n HighlightZoomOptions,\n MapModel,\n ZoomOptions\n} from \"./MapModel\";\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 map: MapModel;\n private olMap: OlMap;\n\n private olLayer: VectorLayer<VectorSource, Feature>;\n private layer: SimpleLayer;\n private olSource: VectorSource<Feature<Geometry>>;\n private activeHighlights: Set<Highlight>;\n\n constructor(map: MapModel, layerDeps: LayerDependencies) {\n this.map = map;\n this.olMap = this.map.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.layer = new SimpleLayer(\n {\n title: \"highlight-layer\",\n internal: true,\n olLayer: this.olLayer\n },\n layerDeps,\n INTERNAL_CONSTRUCTOR_TAG\n );\n map.layers.addLayer(this.layer, { at: \"topmost\" });\n\n this.activeHighlights = new Set();\n }\n\n /**\n * Returns the layer used for highlights.\n */\n getLayer() {\n return this.olLayer;\n }\n\n /**\n * This method removes all highlights before destroying the class\n */\n destroy() {\n this.clearHighlight();\n }\n\n /**\n * Method of filtering out objects that are not geometry or have no property geometry.\n */\n #filterGeoobjects(geoObjects: DisplayTarget[]): Geometry[] {\n const geometries: Geometry[] = [];\n geoObjects.forEach((item) => {\n if (\"getType\" in item) geometries.push(item);\n if (\"geometry\" in item && item.geometry) geometries.push(item.geometry);\n });\n return geometries;\n }\n\n /**\n * This method displays geometries or BaseFeatures with optional styling in the map\n */\n addHighlight(displayTarget: DisplayTarget[], highlightOptions: HighlightOptions | undefined) {\n const geometries = this.#filterGeoobjects(displayTarget);\n\n if (geometries.length === 0) {\n return {\n get isActive() {\n return false;\n },\n destroy() {}\n };\n }\n\n const features = geometries.map((geometry) => {\n const type = geometry.getType();\n const feature = new Feature({\n type: type,\n geometry: geometry\n });\n feature.setStyle(getOwnStyle(type, highlightOptions?.highlightStyle));\n return feature;\n });\n\n const source = this.olSource;\n const highlights = this.activeHighlights;\n const highlight: Highlight = {\n get isActive() {\n return highlights.has(highlight);\n },\n destroy() {\n if (!this.isActive) {\n return;\n }\n\n for (const feature of features) {\n source.removeFeature(feature);\n }\n highlights.delete(highlight);\n }\n };\n\n source.addFeatures(features);\n this.activeHighlights.add(highlight);\n return highlight;\n }\n\n /**\n * This method zoom to geometries or BaseFeatures\n */\n zoomToHighlight(displayTarget: DisplayTarget[], options: ZoomOptions | undefined) {\n const geometries = this.#filterGeoobjects(displayTarget);\n\n if (geometries.length === 0) {\n return;\n }\n\n let extent = createEmpty();\n for (const geometry of geometries) {\n extent = extend(extent, geometry.getExtent());\n }\n\n const bufferParameter = options?.buffer;\n if (typeof bufferParameter === \"number\") {\n extent = calculateBufferedExtent(extent, bufferParameter);\n }\n\n const center = getCenter(extent);\n const isPoint = getArea(extent) === 0;\n const zoomScale = isPoint\n ? (options?.pointZoom ?? DEFAULT_OL_POINT_ZOOM_LEVEL)\n : (options?.maxZoom ?? DEFAULT_OL_MAX_ZOOM_LEVEL);\n setCenter(this.olMap, center);\n\n const {\n top = 0,\n right = 0,\n bottom = 0,\n left = 0\n } = options?.viewPadding ?? DEFAULT_VIEW_PADDING;\n const padding = [top, right, bottom, left];\n zoomTo(this.olMap, extent, zoomScale, padding);\n }\n\n /**\n * This method displays geometries or BaseFeatures with optional styling in the map and executed a zoom\n */\n addHighlightAndZoom(\n displayTarget: DisplayTarget[],\n highlightZoomStyle: HighlightZoomOptions | undefined\n ) {\n const result = this.addHighlight(displayTarget, highlightZoomStyle);\n this.zoomToHighlight(displayTarget, highlightZoomStyle);\n return result;\n }\n\n clearHighlight() {\n for (const highlight of this.activeHighlights) {\n highlight.destroy();\n }\n }\n}\n\nfunction setCenter(olMap: OlMap, coordinates: Coordinate | undefined) {\n coordinates && coordinates.length && olMap.getView().setCenter(coordinates);\n}\n\nfunction zoomTo(\n olMap: OlMap,\n extent: Extent | undefined,\n zoomLevel: number | undefined,\n padding: number[]\n) {\n if (extent) {\n olMap.getView().fit(extent, { maxZoom: zoomLevel, padding: padding });\n } else {\n zoomLevel && olMap.getView().setZoom(zoomLevel);\n }\n}\n\n/**\n * Returns the appropriate style from the user's highlightStyle or falls back to the default style\n */\nfunction resolveStyle(feature: FeatureLike, resolution: number) {\n const type: keyof typeof defaultHighlightStyle = feature.get(\"type\");\n const style = toStyleFunction(getDefaultStyle(type));\n return style(feature, resolution);\n}\n\n/**\n * This method creates styling for a highlight based on the optional style information or the default style\n */\nfunction getOwnStyle(type: Type, highlightStyle: HighlightStyle | undefined) {\n if (highlightStyle && type in highlightStyle) {\n const supportedType = type as HighlightStyleType;\n const ownStyle = highlightStyle[supportedType];\n return ownStyle ? ownStyle : getDefaultStyle(type);\n } else {\n return getDefaultStyle(type);\n }\n}\n\n/**\n * This returns default styling for a highlight\n */\nfunction getDefaultStyle(type: Type) {\n if (type in defaultHighlightStyle) {\n const supportedType = type as HighlightStyleType;\n return defaultHighlightStyle[supportedType];\n } else {\n return defaultHighlightStyle.Polygon;\n }\n}\n\n/**\n * Default styling for highlights\n */\nconst defaultHighlightStyle = {\n \"Point\": new Style({\n image: new Icon({\n anchor: [0.5, 1],\n src: mapMarkerUrl\n })\n }),\n \"MultiPoint\": new Style({\n image: new Icon({\n anchor: [0.5, 1],\n src: mapMarkerUrl\n })\n }),\n \"LineString\": [\n new Style({\n stroke: new Stroke({\n color: \"#fff\",\n width: 5\n })\n }),\n new Style({\n stroke: new Stroke({\n color: \"#00ffff\",\n width: 3\n })\n })\n ],\n \"MultiLineString\": [\n new Style({\n stroke: new Stroke({\n color: \"#fff\",\n width: 5\n })\n }),\n new Style({\n stroke: new Stroke({\n color: \"#00ffff\",\n width: 3\n })\n })\n ],\n \"Polygon\": [\n new Style({\n stroke: new Stroke({\n color: \"#fff\",\n width: 5\n })\n }),\n new Style({\n stroke: new Stroke({\n color: \"#00ffff\",\n width: 3\n }),\n fill: new Fill({\n color: \"rgba(224,255,255,0.35)\"\n })\n })\n ],\n \"MultiPolygon\": [\n new Style({\n stroke: new Stroke({\n color: \"#fff\",\n width: 5\n })\n }),\n new Style({\n stroke: new Stroke({\n color: \"#00ffff\",\n width: 3\n }),\n fill: new Fill({\n color: \"rgba(224,255,255,0.35)\"\n })\n })\n ]\n};\n"],"names":["toStyleFunction"],"mappings":"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"}
1
+ {"version":3,"file":"Highlights.js","sources":["Highlights.ts"],"sourcesContent":["// SPDX-FileCopyrightText: 2023-2025 Open Pioneer project (https://github.com/open-pioneer)\n// SPDX-License-Identifier: Apache-2.0\nimport { Resource } from \"@open-pioneer/core\";\nimport { Feature } from \"ol\";\nimport { FeatureLike } from \"ol/Feature\";\nimport { Geometry } from \"ol/geom\";\nimport { Type } from \"ol/geom/Geometry\";\nimport VectorLayer from \"ol/layer/Vector\";\nimport VectorSource from \"ol/source/Vector\";\nimport { Fill, Icon, Stroke, Style } from \"ol/style\";\nimport { StyleLike, toFunction as toStyleFunction } from \"ol/style/Style\";\nimport mapMarkerUrl from \"../assets/images/mapMarker.png?url\";\nimport { SimpleLayer } from \"../layers/SimpleLayer\";\nimport { LayerDependencies } from \"../layers/shared/internals\";\nimport { INTERNAL_CONSTRUCTOR_TAG } from \"../utils/InternalConstructorTag\";\nimport { DisplayTarget, MapModel, ZoomOptions } from \"./MapModel\";\nimport { getGeometries } from \"./getGeometries\";\n\nexport const DESTROY_HIGHLIGHTS = Symbol(\"DESTROY_HIGHLIGHTS\");\nexport const GET_HIGHLIGHT_LAYER = Symbol(\"GET_HIGHLIGHT_LAYER\");\n\n/**\n * Style options supported when creating a new {@link Highlight}.\n *\n * @group Map Model\n **/\nexport interface HighlightOptions {\n /**\n * Optional styles to override the default styles.\n */\n highlightStyle?: HighlightStyle;\n}\n\n/**\n * Options supported by the map model's {@link MapModel.highlightAndZoom | highlightAndZoom} method.\n *\n * @group Map Model\n **/\nexport interface HighlightZoomOptions extends HighlightOptions, ZoomOptions {}\n\n/**\n * Custom styles when creating a new {@link Highlight}.\n *\n * @group Map Model\n */\nexport type HighlightStyle = {\n Point?: StyleLike;\n LineString?: StyleLike;\n Polygon?: StyleLike;\n MultiPolygon?: StyleLike;\n MultiPoint?: StyleLike;\n MultiLineString?: StyleLike;\n};\n\n/**\n * Represents the additional graphical representations of objects.\n *\n * See also {@link MapModel.highlight}.\n *\n * @group Map Model\n */\nexport interface Highlight extends Resource {\n readonly isActive: boolean;\n}\n\ntype HighlightStyleType = keyof HighlightStyle;\n\n/**\n * Manages highlights on the map.\n *\n * @group Map Model\n */\nexport class Highlights {\n private map: MapModel;\n\n private olLayer: VectorLayer<VectorSource, Feature>;\n private layer: SimpleLayer;\n private olSource: VectorSource<Feature<Geometry>>;\n private activeHighlights: Set<Highlight>;\n\n constructor(map: MapModel, layerDeps: LayerDependencies) {\n this.map = map;\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.layer = new SimpleLayer(\n {\n title: \"highlight-layer\",\n internal: true,\n olLayer: this.olLayer\n },\n layerDeps,\n INTERNAL_CONSTRUCTOR_TAG\n );\n map.layers.addLayer(this.layer, { at: \"topmost\" });\n\n this.activeHighlights = new Set();\n }\n\n [DESTROY_HIGHLIGHTS]() {\n this.clear();\n }\n\n /**\n * Creates a highlight at the given targets.\n *\n * A highlight is a temporary graphic on the map that calls attention to a point or an area.\n *\n * Call `destroy()` on the returned highlight object to remove the highlight.\n */\n add(displayTargets: DisplayTarget[], options?: HighlightOptions | undefined): Highlight {\n const geometries = getGeometries(displayTargets);\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, options?.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 * Creates a highlight and zooms to the given targets.\n *\n * See also {@link add} and {@link MapModel.zoom}.\n */\n addAndZoom(\n displayTarget: DisplayTarget[],\n options?: HighlightZoomOptions | undefined\n ): Highlight {\n const result = this.add(displayTarget, options);\n this.map.zoom(displayTarget, options);\n return result;\n }\n\n /**\n * This method destroys all active Highlights.\n */\n clear() {\n for (const highlight of this.activeHighlights) {\n highlight.destroy();\n }\n }\n\n /**\n * Returns the layer used for highlights.\n */\n [GET_HIGHLIGHT_LAYER]() {\n return this.olLayer;\n }\n}\n\n/**\n * Returns the appropriate style from the user's highlightStyle or falls back to the default style\n */\nfunction resolveStyle(feature: FeatureLike, resolution: number) {\n const type: keyof typeof defaultHighlightStyle = feature.get(\"type\");\n const style = toStyleFunction(getDefaultStyle(type));\n return style(feature, resolution);\n}\n\n/**\n * This method creates styling for a highlight based on the optional style information or the default style\n */\nfunction getOwnStyle(type: Type, highlightStyle: HighlightStyle | undefined) {\n if (highlightStyle && type in highlightStyle) {\n const supportedType = type as HighlightStyleType;\n const ownStyle = highlightStyle[supportedType];\n return ownStyle ? ownStyle : getDefaultStyle(type);\n } else {\n return getDefaultStyle(type);\n }\n}\n\n/**\n * This returns default styling for a highlight\n */\nfunction getDefaultStyle(type: Type) {\n if (type in defaultHighlightStyle) {\n const supportedType = type as HighlightStyleType;\n return defaultHighlightStyle[supportedType];\n } else {\n return defaultHighlightStyle.Polygon;\n }\n}\n\n/**\n * Default styling for highlights\n */\nconst defaultHighlightStyle = {\n \"Point\": new Style({\n image: new Icon({\n anchor: [0.5, 1],\n src: mapMarkerUrl\n })\n }),\n \"MultiPoint\": new Style({\n image: new Icon({\n anchor: [0.5, 1],\n src: mapMarkerUrl\n })\n }),\n \"LineString\": [\n new Style({\n stroke: new Stroke({\n color: \"#fff\",\n width: 5\n })\n }),\n new Style({\n stroke: new Stroke({\n color: \"#00ffff\",\n width: 3\n })\n })\n ],\n \"MultiLineString\": [\n new Style({\n stroke: new Stroke({\n color: \"#fff\",\n width: 5\n })\n }),\n new Style({\n stroke: new Stroke({\n color: \"#00ffff\",\n width: 3\n })\n })\n ],\n \"Polygon\": [\n new Style({\n stroke: new Stroke({\n color: \"#fff\",\n width: 5\n })\n }),\n new Style({\n stroke: new Stroke({\n color: \"#00ffff\",\n width: 3\n }),\n fill: new Fill({\n color: \"rgba(224,255,255,0.35)\"\n })\n })\n ],\n \"MultiPolygon\": [\n new Style({\n stroke: new Stroke({\n color: \"#fff\",\n width: 5\n })\n }),\n new Style({\n stroke: new Stroke({\n color: \"#00ffff\",\n width: 3\n }),\n fill: new Fill({\n color: \"rgba(224,255,255,0.35)\"\n })\n })\n ]\n};\n"],"names":["toStyleFunction"],"mappings":"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"}
@@ -1,6 +1,6 @@
1
1
  import { reactiveSet, reactiveMap, reactive, reactiveArray, effect, batch } from '@conterra/reactivity-core';
2
2
  import { createLogger } from '@open-pioneer/core';
3
- import { sourceId$6 as sourceId } from '../_virtual/source-info.js';
3
+ import { sourceId$1 as sourceId } from '../_virtual/source-info.js';
4
4
  import { AbstractLayer } from '../layers/AbstractLayer.js';
5
5
  import { getRecursiveLayers } from '../layers/shared/getRecursiveLayers.js';
6
6
  import { ATTACH_TO_MAP, DETACH_FROM_MAP, SET_VISIBLE, GET_RAW_LAYERS, GET_RAW_SUBLAYERS } from '../layers/shared/internals.js';