@open-pioneer/map 1.5.0-dev.20260911123645 → 1.5.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.
Files changed (49) hide show
  1. package/CHANGELOG.md +529 -520
  2. package/LayerFactory.js.map +1 -1
  3. package/MapRegistry.js.map +1 -1
  4. package/README.md +37 -1
  5. package/_virtual/hooks.js.map +1 -1
  6. package/_virtual/source-info.js.map +1 -1
  7. package/layers/AbstractLayer.js.map +1 -1
  8. package/layers/AbstractLayerBase.js.map +1 -1
  9. package/layers/GroupLayer.js.map +1 -1
  10. package/layers/SimpleLayer.js.map +1 -1
  11. package/layers/WMSLayer.js.map +1 -1
  12. package/layers/WMTSLayer.js.map +1 -1
  13. package/layers/group/GroupLayerCollection.js.map +1 -1
  14. package/layers/shared/SublayersCollection.js.map +1 -1
  15. package/layers/shared/getRecursiveLayers.js.map +1 -1
  16. package/layers/shared/internals.js.map +1 -1
  17. package/layers/unions.js.map +1 -1
  18. package/layers/wms/WMSSublayer.js.map +1 -1
  19. package/layers/wms/getAttributions.js.map +1 -1
  20. package/layers/wms/getLegendUrl.js.map +1 -1
  21. package/layers/wmts/getAttributions.js.map +1 -1
  22. package/layers/wmts/getLegendUrl.js.map +1 -1
  23. package/model/Highlights.js.map +1 -1
  24. package/model/LayerCollection.js.map +1 -1
  25. package/model/MapAttributions.js.map +1 -1
  26. package/model/MapModel.d.ts +2 -1
  27. package/model/MapModel.js +16 -12
  28. package/model/MapModel.js.map +1 -1
  29. package/model/Overlays.js.map +1 -1
  30. package/model/createMapModel.js +10 -22
  31. package/model/createMapModel.js.map +1 -1
  32. package/model/getGeometries.js.map +1 -1
  33. package/package.json +8 -8
  34. package/ui/DefaultMapProvider.js.map +1 -1
  35. package/ui/MapAnchor.js.map +1 -1
  36. package/ui/MapContainer.js +3 -2
  37. package/ui/MapContainer.js.map +1 -1
  38. package/ui/MapContainerContext.js.map +1 -1
  39. package/ui/OverlaysRenderer.js.map +1 -1
  40. package/ui/computeMapAnchorStyles.js.map +1 -1
  41. package/ui/hooks/useMapModel.js.map +1 -1
  42. package/ui/styles.css +0 -1
  43. package/ui/styles.css.map +1 -1
  44. package/utils/InternalConstructorTag.js.map +1 -1
  45. package/utils/fetch.js.map +1 -1
  46. package/utils/geometry-utils.js.map +1 -1
  47. package/utils/ol-test-support.js.map +1 -1
  48. package/utils/projections.js.map +1 -1
  49. package/utils/sanitize.js.map +1 -1
package/CHANGELOG.md CHANGED
@@ -1,49 +1,58 @@
1
1
  # @open-pioneer/map
2
2
 
3
- ## 1.5.0-dev.20260911123645
3
+ ## 1.5.0
4
4
 
5
5
  ### Minor Changes
6
6
 
7
7
  - f790fda: Update to Chakra 3.37.0
8
8
  - 38658ce: Add `setStyle` method to `Highlight` to change the style of existing highlights.
9
9
  - ebda251: The `addLayer` method now also accepts `at: "base"` to add a base layer.
10
+ - 0d9a9d0: The map initialization has been adjusted to fix the map view initialization if initial view is configured with extent.
11
+ This change affects the order and timing of the map's initialization.
12
+
13
+ The timing changes might affect early map interactions or tests:
14
+ To wait until the map is actually being rendered (and thus fully initialized), you can use the map model's existing `whenDisplayed()` method.
15
+ The new test helper function `waitForMapRender` is provided from (`@open-pioneer/map-test-utils`) to wait in tests for the map view to be completely initialized.
16
+
17
+ - a186f5d: Update core packages to 4.8.0.
10
18
  - ebda251: Add new properties for topmost layers and base layers in `MapConfig`.
11
19
 
12
- - With `MapConfig.topmostLayers` topmost layers can now be defined in the initial map setup.
13
- - Base layers can now be defined in the initial map setup with the `MapConfig.baseLayers` property
14
-
15
- We recommend using the `baseLayers` property instead of `isBaseLayer: true` for new apps.
16
-
17
- ```typescript
18
- export class MapConfigProviderImpl implements MapConfigProvider {
19
- mapId = MAP_ID;
20
-
21
- async getMapConfig({ layerFactory }: MapConfigProviderOptions): Promise<MapConfig> {
22
- return {
23
- initialView: {...},
24
- projection: "EPSG:25832",
25
- baseLayers: [
26
- //all base layers
27
- layerFactory.create(...)
28
- ],
29
- layers: [
30
- //all other operational layers
31
- layerFactory.create(...),
32
- layerFactory.create(...)
33
- ],
34
- topmostLayers: [
35
- //all operational highlight layers
36
- layerFactory.create(...)
37
- ]
38
- };
39
- }
40
- }
41
- ```
20
+ - With `MapConfig.topmostLayers` topmost layers can now be defined in the initial map setup.
21
+ - Base layers can now be defined in the initial map setup with the `MapConfig.baseLayers` property
22
+
23
+ We recommend using the `baseLayers` property instead of `isBaseLayer: true` for new apps.
24
+
25
+ ```typescript
26
+ export class MapConfigProviderImpl implements MapConfigProvider {
27
+ mapId = MAP_ID;
28
+
29
+ async getMapConfig({ layerFactory }: MapConfigProviderOptions): Promise<MapConfig> {
30
+ return {
31
+ initialView: {...},
32
+ projection: "EPSG:25832",
33
+ baseLayers: [
34
+ //all base layers
35
+ layerFactory.create(...)
36
+ ],
37
+ layers: [
38
+ //all other operational layers
39
+ layerFactory.create(...),
40
+ layerFactory.create(...)
41
+ ],
42
+ topmostLayers: [
43
+ //all operational highlight layers
44
+ layerFactory.create(...)
45
+ ]
46
+ };
47
+ }
48
+ }
49
+ ```
42
50
 
43
51
  ### Patch Changes
44
52
 
45
53
  - 3203815: Update code to match new react linting rules from oxlint.
46
54
  - 09ec7c7: Updated dependencies
55
+ - 0d9a9d0: Do not mock layer rendering when vitest browser mode is detected.
47
56
 
48
57
  ## 1.4.0
49
58
 
@@ -52,16 +61,16 @@
52
61
  - c30396d: Update Chakra to 3.36.1
53
62
  - 690a892: A layer's loadState is now a derived from three different channels:
54
63
 
55
- - source — the OpenLayers source state (undefined/loading/ready/error).
56
- - health — the result of the optional healthCheck (run once on attach).
57
- - metadata — the result of a layer's own capabilities request (if any).
64
+ - source — the OpenLayers source state (undefined/loading/ready/error).
65
+ - health — the result of the optional healthCheck (run once on attach).
66
+ - metadata — the result of a layer's own capabilities request (if any).
58
67
 
59
- Additionally, a new property `loadError` has been added to the layer class.
68
+ Additionally, a new property `loadError` has been added to the layer class.
60
69
 
61
70
  - e4b47f1: `useMapModel` now prints an error message if the map model could not be created.
62
71
  This error was previously returned and was easy to silently ignore.
63
72
 
64
- Use the option `quiet: true` to suppress this error message.
73
+ Use the option `quiet: true` to suppress this error message.
65
74
 
66
75
  - c9b3ced: Provide reactive rotation in MapModel
67
76
  - 690a892: WMS Layer: add validation that configured sublayers actually exist in the service's capabilities.
@@ -90,17 +99,17 @@
90
99
  - fcbd505: Sanitize HTML used for layer attributions.
91
100
  - 33ab02f: Move highlight methods to `mapModel.highlights`.
92
101
 
93
- - `mapModel.highlight()` -> `mapModel.highlights.add()`
94
- - `mapModel.highlightAndZoom()` -> `mapModel.highlights.addAndZoom()`
95
- - `mapModel.removeHighlights()` -> `mapModel.highlights.clear()`
102
+ - `mapModel.highlight()` -> `mapModel.highlights.add()`
103
+ - `mapModel.highlightAndZoom()` -> `mapModel.highlights.addAndZoom()`
104
+ - `mapModel.removeHighlights()` -> `mapModel.highlights.clear()`
96
105
 
97
- The old methods on the Map Model have been deprecated and will be removed in a future major release.
106
+ The old methods on the Map Model have been deprecated and will be removed in a future major release.
98
107
 
99
108
  - d54ccfd: Update to Chakra UI 3.35.0
100
109
  - 33ab02f: Add new `mapModel.overlays` API to render arbitrary React content on the map at certain coordinates.
101
110
  This can be helpful for feature info, popups and for tooltips during map interactions.
102
111
 
103
- Use `mapModel.overlay.add({ content: <SomeReactContent />, ...})` to create a new overlay.
112
+ Use `mapModel.overlay.add({ content: <SomeReactContent />, ...})` to create a new overlay.
104
113
 
105
114
  - 206b397: Update to trails core packages 4.6.0
106
115
  - 2ceb1ca: MapContainer: allow configuration of `rootProps` and `containerProps`.
@@ -139,22 +148,22 @@
139
148
  Using only a minimum or maximum limit is possible.
140
149
  Missing properties are considered as no limitation.
141
150
 
142
- ```js
143
- layerFactory.create({
144
- type: WMTSLayer,
145
- isBaseLayer: true,
146
- title: "Basemap",
147
- name: "basemap",
148
- minZoom: 10,
149
- maxZoom: 16,
150
- });
151
- ```
151
+ ```js
152
+ layerFactory.create({
153
+ type: WMTSLayer,
154
+ isBaseLayer: true,
155
+ title: "Basemap",
156
+ name: "basemap",
157
+ minZoom: 10,
158
+ maxZoom: 16
159
+ });
160
+ ```
152
161
 
153
- The boolean property `visibleInScale` of a layer indicates the visibility of this layer depending on the current resolution of the map.
162
+ The boolean property `visibleInScale` of a layer indicates the visibility of this layer depending on the current resolution of the map.
154
163
 
155
- Restrictions of a `GroupLayer` are inherited to child layers.
156
- If no restrictions are configured for a child layer, its visibility limitations are equal to the parent `GroupLayer`.
157
- By configuring additional limits for the child layer, its visibility can be further restricted.
164
+ Restrictions of a `GroupLayer` are inherited to child layers.
165
+ If no restrictions are configured for a child layer, its visibility limitations are equal to the parent `GroupLayer`.
166
+ By configuring additional limits for the child layer, its visibility can be further restricted.
158
167
 
159
168
  ### Patch Changes
160
169
 
@@ -167,233 +176,233 @@
167
176
  - b3709f1: **Breaking:** Remove layer constructor types from public API (e.g. `SimpleLayerConstructor`).
168
177
  - 9e9bc6e: **Breaking**: Internal layers are no longer returned from getters such as `getItems()` or `getRecursiveLayers()` by default.
169
178
 
170
- A new option `includeInternalLayers` has been implemented to opt-in into internal layers.
171
- By default, internal layers are not returned by functions like `getItems()` or `getRecursiveLayers()`.
172
- If internal layer should be returned this must be specified explicitly with the `includeInternalLayers` option.
179
+ A new option `includeInternalLayers` has been implemented to opt-in into internal layers.
180
+ By default, internal layers are not returned by functions like `getItems()` or `getRecursiveLayers()`.
181
+ If internal layer should be returned this must be specified explicitly with the `includeInternalLayers` option.
173
182
 
174
- ```js
175
- import { MapModel } from "@open-pioneer/map";
183
+ ```js
184
+ import { MapModel } from "@open-pioneer/map";
176
185
 
177
- //internal layers are not included
178
- const layers = myMapModel.layers.getItems();
179
- //include internal layers
180
- const allLayers = myMapModel.layers.getItems({ includeInternalLayers: true });
181
- ```
186
+ //internal layers are not included
187
+ const layers = myMapModel.layers.getItems();
188
+ //include internal layers
189
+ const allLayers = myMapModel.layers.getItems({ includeInternalLayers: true });
190
+ ```
182
191
 
183
- Note that if internal layers are returned this includes system layers (e.g. for highlights or geolocation) that were not explicitly added to the map.
184
- The described behavior is aligned for the functions `getItems()`, `getLayers()`, `getAllLayers()` and `getRecursiveLayers()` in `LayerCollection`, `WMSLayer` and `GroupLayer`.
185
- The function `getRecursiveLayers()` does not return non-internal child layers of an internal layer.
192
+ Note that if internal layers are returned this includes system layers (e.g. for highlights or geolocation) that were not explicitly added to the map.
193
+ The described behavior is aligned for the functions `getItems()`, `getLayers()`, `getAllLayers()` and `getRecursiveLayers()` in `LayerCollection`, `WMSLayer` and `GroupLayer`.
194
+ The function `getRecursiveLayers()` does not return non-internal child layers of an internal layer.
186
195
 
187
196
  - b3709f1: **Breaking:** Remove old event API from layer types and the map model.
188
197
 
189
- These were only used for the `"destroy"` event.
198
+ These were only used for the `"destroy"` event.
190
199
 
191
- ```ts
192
- // OLD, removed API:
193
- const layer = ...;
194
- layer.on("destroyed", () => {
195
- console.debug("layer was destroyed");
196
- });
197
- ```
200
+ ```ts
201
+ // OLD, removed API:
202
+ const layer = ...;
203
+ layer.on("destroyed", () => {
204
+ console.debug("layer was destroyed");
205
+ });
206
+ ```
198
207
 
199
- The destroy event still exists, but is now based on the event system of the [reactivity API](https://github.com/conterra/reactivity/tree/main/packages/reactivity-events):
208
+ The destroy event still exists, but is now based on the event system of the [reactivity API](https://github.com/conterra/reactivity/tree/main/packages/reactivity-events):
200
209
 
201
- ```ts
202
- // NEW
203
- import { on } from "@conterra/reactivity-events";
210
+ ```ts
211
+ // NEW
212
+ import { on } from "@conterra/reactivity-events";
204
213
 
205
- const layer = ...;
206
- on(layer.destroyed, () => {
207
- console.debug("layer was destroyed");
208
- });
214
+ const layer = ...;
215
+ on(layer.destroyed, () => {
216
+ console.debug("layer was destroyed");
217
+ });
209
218
 
210
- const mapModel = ...;
211
- on(mapModel.destroyed, () => {
212
- console.debug("layer was destroyed");
213
- });
214
- ```
219
+ const mapModel = ...;
220
+ on(mapModel.destroyed, () => {
221
+ console.debug("layer was destroyed");
222
+ });
223
+ ```
215
224
 
216
225
  - a1614de: **Breaking**: Remove support for `mapId` in all React components.
217
226
 
218
- To configure the map for a component (for example: `Legend`), either pass the `map`
219
- as an explicit parameter or use the `DefaultMapProvider`:
227
+ To configure the map for a component (for example: `Legend`), either pass the `map`
228
+ as an explicit parameter or use the `DefaultMapProvider`:
220
229
 
221
- ```ts
222
- // Explicit API
223
- <Legend map={map} />
230
+ ```ts
231
+ // Explicit API
232
+ <Legend map={map} />
224
233
 
225
- // All children of the DefaultMapProvider can use the configured map
226
- <DefaultMapProvider map={map}>
227
- <MapContainer />
228
- <Legend />
229
- <SomeOtherComponent />
230
- </DefaultMapProvider>;
231
- ```
234
+ // All children of the DefaultMapProvider can use the configured map
235
+ <DefaultMapProvider map={map}>
236
+ <MapContainer />
237
+ <Legend />
238
+ <SomeOtherComponent />
239
+ </DefaultMapProvider>;
240
+ ```
232
241
 
233
- Support for `mapId` was removed in [PR #486](https://github.com/open-pioneer/trails-openlayers-base-packages/pull/486).
242
+ Support for `mapId` was removed in [PR #486](https://github.com/open-pioneer/trails-openlayers-base-packages/pull/486).
234
243
 
235
244
  ### Minor Changes
236
245
 
237
246
  - 29a10df: Support buffer for zoom geometries.
238
247
  Use the `buffer` option to specify the size increase. E.g. `0.1` for 10% size increase.
239
248
 
240
- We use the already existing `calculateBufferedExtent` function to compute the buffer.
249
+ We use the already existing `calculateBufferedExtent` function to compute the buffer.
241
250
 
242
- For example:
251
+ For example:
243
252
 
244
- ```ts
245
- const map: MapModel = ...;
246
- const highlight = map.highlightAndZoom(someGeometries, {
247
- // Grows extent by 10%
248
- buffer: 0.1
249
- });
250
- ```
253
+ ```ts
254
+ const map: MapModel = ...;
255
+ const highlight = map.highlightAndZoom(someGeometries, {
256
+ // Grows extent by 10%
257
+ buffer: 0.1
258
+ });
259
+ ```
251
260
 
252
261
  - 2702df4: Introduce `internal` property for all layer types (including sublayers).
253
262
  If `internal` is `true` (default: `false`) the layer is not considered by any UI widget (e.g. Legend and Toc).
254
263
  The `internal` state of a layer is not to be confused with the layer's visibility on the map which is determined by the `visible` property.
255
264
 
256
- ```typescript
257
- //internal layer is visible on the map but hidden in UI elements like legend and Toc
258
- const internalLayer = new SimpleLayer({
259
- id: "layer1",
260
- title: "layer 1",
261
- olLayer: myOlLayer,
262
- visible: true,
263
- internal: true,
264
- });
265
- ```
265
+ ```typescript
266
+ //internal layer is visible on the map but hidden in UI elements like legend and Toc
267
+ const internalLayer = new SimpleLayer({
268
+ id: "layer1",
269
+ title: "layer 1",
270
+ olLayer: myOlLayer,
271
+ visible: true,
272
+ internal: true
273
+ });
274
+ ```
266
275
 
267
276
  - 5df900f: Add a new hook `useMapModelValue(props?)`.
268
277
  The hook returns either the directly configured `map` (via props) or the default map from a parent `DefaultMapProvider`.
269
278
  If neither is present, an error will be thrown.
270
279
 
271
- This hook is used in all components that work with the map.
272
- The typical usage works like this:
280
+ This hook is used in all components that work with the map.
281
+ The typical usage works like this:
273
282
 
274
- ```ts
275
- import { MapModelProps, useMapModelValue } from "@open-pioneer/map";
283
+ ```ts
284
+ import { MapModelProps, useMapModelValue } from "@open-pioneer/map";
276
285
 
277
- // optional `map` property inherited from `MapModelProps`
278
- export interface MyComponentProps extends MapModelProps {
279
- // ... other properties
280
- }
286
+ // optional `map` property inherited from `MapModelProps`
287
+ export interface MyComponentProps extends MapModelProps {
288
+ // ... other properties
289
+ }
281
290
 
282
- export function MyComponent(props) {
283
- const map = useMapModelValue(props); // looks up the map
284
- }
285
- ```
291
+ export function MyComponent(props) {
292
+ const map = useMapModelValue(props); // looks up the map
293
+ }
294
+ ```
286
295
 
287
- You can also call this hook without any arguments:
296
+ You can also call this hook without any arguments:
288
297
 
289
- ```ts
290
- // Map model from DefaultMapProvider or an error.
291
- const mapModel = useMapModelValue();
292
- ```
298
+ ```ts
299
+ // Map model from DefaultMapProvider or an error.
300
+ const mapModel = useMapModelValue();
301
+ ```
293
302
 
294
- This hook should replace _most_ usages `useMapModel`, which can't return the map model directly since it may not have finished construction yet.
303
+ This hook should replace _most_ usages `useMapModel`, which can't return the map model directly since it may not have finished construction yet.
295
304
 
296
305
  - 14c484e: Introduce the `LayerFactory` service (interface `"map.LayerFactory"`).
297
306
 
298
- The layer factory should be used to construct new layer instances, instead of calling the layer constructor directly.
299
- Calling the constructor directly (e.g. `new SimpleLayer`) is deprecated (but still fully supported).
300
-
301
- For example:
302
-
303
- ```ts
304
- // OLD
305
- new SimpleLayer({
306
- title: "OSM",
307
- isBaseLayer: true,
308
- olLayer: new TileLayer({
309
- source: new OSM(),
310
- }),
311
- });
312
- ```
313
-
314
- ```ts
315
- // NEW
316
- const layerFactory = ...; // injected
317
- layerFactory.create({
318
- type: SimpleLayer,
319
- title: "OSM",
320
- isBaseLayer: true,
321
- olLayer: new TileLayer({
322
- source: new OSM()
323
- })
324
- });
325
- ```
326
-
327
- This was done to support passing hidden dependencies from the layer factory to the layer instance (such as the `HttpService`),
328
- without forcing the user to supply these dependencies manually.
329
-
330
- The `MapConfigProvider` has been updated as well.
331
- The `getMapConfig` method will now receive the layer factory as an option.
332
- This makes it easy to migrate to the new API:
333
-
334
- ```diff
335
- # Example MapConfigProvider
336
- export class MapConfigProviderImpl implements MapConfigProvider {
337
- mapId = MAP_ID;
338
-
339
- - async getMapConfig(): Promise<MapConfig> {
340
- + async getMapConfig({ layerFactory }: MapConfigProviderOptions): Promise<MapConfig> {
341
- return {
342
- initialView: {
343
- kind: "position",
344
- center: { x: 404747, y: 5757920 },
345
- zoom: 14
346
- },
347
- layers: [
348
- - new SimpleLayer({
349
- + layerFactory.create({
350
- + type: SimpleLayer,
351
- title: "OSM",
352
- isBaseLayer: true,
353
- olLayer: new TileLayer({
354
- source: new OSM()
355
- })
356
- })
357
- ]
358
- };
359
- }
360
- }
361
- ```
307
+ The layer factory should be used to construct new layer instances, instead of calling the layer constructor directly.
308
+ Calling the constructor directly (e.g. `new SimpleLayer`) is deprecated (but still fully supported).
309
+
310
+ For example:
311
+
312
+ ```ts
313
+ // OLD
314
+ new SimpleLayer({
315
+ title: "OSM",
316
+ isBaseLayer: true,
317
+ olLayer: new TileLayer({
318
+ source: new OSM()
319
+ })
320
+ });
321
+ ```
322
+
323
+ ```ts
324
+ // NEW
325
+ const layerFactory = ...; // injected
326
+ layerFactory.create({
327
+ type: SimpleLayer,
328
+ title: "OSM",
329
+ isBaseLayer: true,
330
+ olLayer: new TileLayer({
331
+ source: new OSM()
332
+ })
333
+ });
334
+ ```
335
+
336
+ This was done to support passing hidden dependencies from the layer factory to the layer instance (such as the `HttpService`),
337
+ without forcing the user to supply these dependencies manually.
338
+
339
+ The `MapConfigProvider` has been updated as well.
340
+ The `getMapConfig` method will now receive the layer factory as an option.
341
+ This makes it easy to migrate to the new API:
342
+
343
+ ```diff
344
+ # Example MapConfigProvider
345
+ export class MapConfigProviderImpl implements MapConfigProvider {
346
+ mapId = MAP_ID;
347
+
348
+ - async getMapConfig(): Promise<MapConfig> {
349
+ + async getMapConfig({ layerFactory }: MapConfigProviderOptions): Promise<MapConfig> {
350
+ return {
351
+ initialView: {
352
+ kind: "position",
353
+ center: { x: 404747, y: 5757920 },
354
+ zoom: 14
355
+ },
356
+ layers: [
357
+ - new SimpleLayer({
358
+ + layerFactory.create({
359
+ + type: SimpleLayer,
360
+ title: "OSM",
361
+ isBaseLayer: true,
362
+ olLayer: new TileLayer({
363
+ source: new OSM()
364
+ })
365
+ })
366
+ ]
367
+ };
368
+ }
369
+ }
370
+ ```
362
371
 
363
372
  - aeb9000: Add new `"topmost"` option to add layers that are always displayed on top (above all other layers).
364
373
 
365
- A new layers can be added at `topmost` to ensure that this layer will always be displayed on top of the other layers.
366
- This can be used, for example, to implement highlights or to draw graphics.
367
- Layers added at `"topmost"` will always be shown above layers at `"top"`.
374
+ A new layers can be added at `topmost` to ensure that this layer will always be displayed on top of the other layers.
375
+ This can be used, for example, to implement highlights or to draw graphics.
376
+ Layers added at `"topmost"` will always be shown above layers at `"top"`.
368
377
 
369
- When using the `"above"` or `"below"` options with a `"topmost"` reference layer, that layer becomes `"topmost"` as well.
378
+ When using the `"above"` or `"below"` options with a `"topmost"` reference layer, that layer becomes `"topmost"` as well.
370
379
 
371
- ```typescript
372
- import { MapModel, SimpleLayer } from "@open-pioneer/map";
380
+ ```typescript
381
+ import { MapModel, SimpleLayer } from "@open-pioneer/map";
373
382
 
374
- const highlightLayer = new SimpleLayer({
375
- title: "highlights",
376
- olLayer: myOlLayer,
377
- });
378
- //always displayed at the top
379
- myMapModel.layers.addLayer(highlightLayer, { at: "topmost" });
380
- ```
383
+ const highlightLayer = new SimpleLayer({
384
+ title: "highlights",
385
+ olLayer: myOlLayer
386
+ });
387
+ //always displayed at the top
388
+ myMapModel.layers.addLayer(highlightLayer, { at: "topmost" });
389
+ ```
381
390
 
382
391
  - 5df900f: Deprecate the parameter-less signature of `useMapModel()`:
383
392
 
384
- ```ts
385
- // Returns the DefaultMapProvider's map, but wrapped in a result value (loading/resolved/rejected)
386
- const result = useMapModel();
387
- ```
393
+ ```ts
394
+ // Returns the DefaultMapProvider's map, but wrapped in a result value (loading/resolved/rejected)
395
+ const result = useMapModel();
396
+ ```
388
397
 
389
- Use `useMapModelValue()` instead:
398
+ Use `useMapModelValue()` instead:
390
399
 
391
- ```ts
392
- // Returns the map model directly.
393
- const mapModel = useMapModelValue();
394
- ```
400
+ ```ts
401
+ // Returns the map model directly.
402
+ const mapModel = useMapModelValue();
403
+ ```
395
404
 
396
- All other signatures of `useMapModel()` are still fully supported.
405
+ All other signatures of `useMapModel()` are still fully supported.
397
406
 
398
407
  - 773fa2d: The map now has an appropriate focus outline style by default, which respects the map view's padding.
399
408
  For information on disabling this behavior, see the map package documentation.
@@ -411,8 +420,8 @@
411
420
  - 4f1e7bd: The internal constant `TOPMOST_LAYER_Z` has been removed.
412
421
  To configure a layer that is always on top:
413
422
 
414
- - Create a layer using the `LayerFactory`
415
- - Add it to the map model and specify the `at: "topmost"` option
423
+ - Create a layer using the `LayerFactory`
424
+ - Add it to the map model and specify the `at: "topmost"` option
416
425
 
417
426
  - 2c8b617: Introduce `MapRegistry.createMapModel` method to create a `MapModel` without a `MapConfigProvider`.
418
427
  For more details, see [PR](https://github.com/open-pioneer/trails-openlayers-base-packages/pull/499) and [issue](https://github.com/open-pioneer/trails-openlayers-base-packages/issues/483).
@@ -427,13 +436,13 @@
427
436
  - 66179bc: Update to core-packages v4.0.0
428
437
  - acd5115: **Breaking:** Remove the following hooks, which were deprecated since version 0.8.0:
429
438
 
430
- - useView
431
- - useProjection
432
- - useResolution
433
- - useCenter
434
- - useScale
439
+ - useView
440
+ - useProjection
441
+ - useResolution
442
+ - useCenter
443
+ - useScale
435
444
 
436
- Use reactive properties on the map model instead, e.g. `mapModel.scale`.
445
+ Use reactive properties on the map model instead, e.g. `mapModel.scale`.
437
446
 
438
447
  - 738390e: Update to Chakra v3
439
448
 
@@ -441,30 +450,30 @@
441
450
 
442
451
  - 738390e: Fix an issue with "raw" map container children that are not wrapped in a map anchor.
443
452
 
444
- Consider, for example, the following snippet:
453
+ Consider, for example, the following snippet:
445
454
 
446
- ```tsx
447
- <MapContainer>
448
- {/* .custom-content does absolute positioning relative to map container */}
449
- <div className="custom-content">Hi</div>
450
- </MapContainer>
451
- ```
455
+ ```tsx
456
+ <MapContainer>
457
+ {/* .custom-content does absolute positioning relative to map container */}
458
+ <div className="custom-content">Hi</div>
459
+ </MapContainer>
460
+ ```
452
461
 
453
- Previously, the `div` was rendered relative to the map container div but did _not_ respect the map's view padding.
454
- Now the `div` will move according to the map padding as well.
462
+ Previously, the `div` was rendered relative to the map container div but did _not_ respect the map's view padding.
463
+ Now the `div` will move according to the map padding as well.
455
464
 
456
465
  - 0a8ff71: The default attribution widget created for the map now has `role="region"` and an `aria-label` for improved screen reader support.
457
466
 
458
- ```html
459
- <div
460
- style="pointer-events: auto;"
461
- class="ol-attribution ol-unselectable ol-control ol-uncollapsible"
462
- role="region"
463
- aria-label="Quellenangaben"
464
- >
465
- <!-- Attributions -->
466
- </div>
467
- ```
467
+ ```html
468
+ <div
469
+ style="pointer-events: auto;"
470
+ class="ol-attribution ol-unselectable ol-control ol-uncollapsible"
471
+ role="region"
472
+ aria-label="Quellenangaben"
473
+ >
474
+ <!-- Attributions -->
475
+ </div>
476
+ ```
468
477
 
469
478
  ## 0.10.0
470
479
 
@@ -473,82 +482,82 @@
473
482
  - 193068a: Deprecate the `mapId` property on React components.
474
483
  Use the `MapModel` directly instead to pass a reference to the map.
475
484
 
476
- Example:
485
+ Example:
477
486
 
478
- ```tsx
479
- // Default map for entire component tree
480
- <DefaultMapProvider map={mapModel}>
481
- <Toc />
482
- </DefaultMapProvider>
487
+ ```tsx
488
+ // Default map for entire component tree
489
+ <DefaultMapProvider map={mapModel}>
490
+ <Toc />
491
+ </DefaultMapProvider>
483
492
 
484
- // Map for specific component
485
- <Toc map={mapModel} />
486
- ```
493
+ // Map for specific component
494
+ <Toc map={mapModel} />
495
+ ```
487
496
 
488
497
  ### Patch Changes
489
498
 
490
499
  - 2bafdad: Top level operational layers can now be inserted at an arbitrary position.
491
500
 
492
- ```ts
493
- const mapModel = ...;
494
- const newLayer = new SimpleLayer({
495
- title: "New layer",
496
- // ...
497
- });
501
+ ```ts
502
+ const mapModel = ...;
503
+ const newLayer = new SimpleLayer({
504
+ title: "New layer",
505
+ // ...
506
+ });
498
507
 
499
- mapModel.layers.addLayer(newLayer, { at: "top" }); // Same as default: on top of all existing operational layers
500
- mapModel.layers.addLayer(newLayer, { at: "bottom" }); // Below all other operational layers
508
+ mapModel.layers.addLayer(newLayer, { at: "top" }); // Same as default: on top of all existing operational layers
509
+ mapModel.layers.addLayer(newLayer, { at: "bottom" }); // Below all other operational layers
501
510
 
502
- const otherLayer = ...; // Eiter a valid layer id or a layer instance. Must be from the same collection.
503
- mapModel.layers.addLayer(newLayer, { at: "above", reference: otherLayer }); // Above the reference layer
504
- mapModel.layers.addLayer(newLayer, { at: "below", reference: otherLayer }); // Below the reference layer
505
- ```
511
+ const otherLayer = ...; // Eiter a valid layer id or a layer instance. Must be from the same collection.
512
+ mapModel.layers.addLayer(newLayer, { at: "above", reference: otherLayer }); // Above the reference layer
513
+ mapModel.layers.addLayer(newLayer, { at: "below", reference: otherLayer }); // Below the reference layer
514
+ ```
506
515
 
507
516
  - cd1435b: Update ol to 10.5.0
508
517
  - 032eed7: Bump dependencies.
509
518
  - cd1435b: Update to react 19.1.0
510
519
  - 7558df4: Add new map anchor positioning options.
511
520
 
512
- The following positions are now supported:
513
-
514
- ```ts
515
- export type MapAnchorPosition =
516
- | "manual"
517
- | "top-left"
518
- | "top-right"
519
- | "top-center"
520
- | "bottom-left"
521
- | "bottom-right"
522
- | "bottom-center"
523
- | "left-center"
524
- | "right-center"
525
- | "center";
526
- ```
527
-
528
- You can use `manual` positioning to position an anchor using CSS.
529
- For example:
530
-
531
- ```tsx
532
- <MapAnchor className="manual-position" position="manual">
533
- <Box
534
- backgroundColor="whiteAlpha.800"
535
- borderWidth="1px"
536
- borderRadius="lg"
537
- padding={2}
538
- boxShadow="lg"
539
- >
540
- Manually positioned anchor
541
- </Box>
542
- ```
543
-
544
- Combined with css:
545
-
546
- ```css
547
- .manual-position {
548
- left: 200px;
549
- top: 200px;
550
- }
551
- ```
521
+ The following positions are now supported:
522
+
523
+ ```ts
524
+ export type MapAnchorPosition =
525
+ | "manual"
526
+ | "top-left"
527
+ | "top-right"
528
+ | "top-center"
529
+ | "bottom-left"
530
+ | "bottom-right"
531
+ | "bottom-center"
532
+ | "left-center"
533
+ | "right-center"
534
+ | "center";
535
+ ```
536
+
537
+ You can use `manual` positioning to position an anchor using CSS.
538
+ For example:
539
+
540
+ ```tsx
541
+ <MapAnchor className="manual-position" position="manual">
542
+ <Box
543
+ backgroundColor="whiteAlpha.800"
544
+ borderWidth="1px"
545
+ borderRadius="lg"
546
+ padding={2}
547
+ boxShadow="lg"
548
+ >
549
+ Manually positioned anchor
550
+ </Box>
551
+ ```
552
+
553
+ Combined with css:
554
+
555
+ ```css
556
+ .manual-position {
557
+ left: 200px;
558
+ top: 200px;
559
+ }
560
+ ```
552
561
 
553
562
  ## 0.9.0
554
563
 
@@ -556,8 +565,8 @@
556
565
 
557
566
  - e7fdc5d: improve scale calculation for none-metric projections
558
567
 
559
- Fix scale calculation for projections with none-metric units (e.g. EPSG:4326).
560
- Note: The calculated scale (`useScale`) still may deviate from the desired scale (`setScale`) for non-metric projections. This is due to limitiations in the [getPointResolution](https://openlayers.org/en/latest/apidoc/module-ol_proj.html#.getPointResolution) function from OL.
568
+ Fix scale calculation for projections with none-metric units (e.g. EPSG:4326).
569
+ Note: The calculated scale (`useScale`) still may deviate from the desired scale (`setScale`) for non-metric projections. This is due to limitiations in the [getPointResolution](https://openlayers.org/en/latest/apidoc/module-ol_proj.html#.getPointResolution) function from OL.
561
570
 
562
571
  - cb94c75: update dependencies
563
572
  - f327eec: Deprecate `mapModel.layers.getAllLayers()`.
@@ -565,43 +574,43 @@
565
574
  The name of `getAllLayers()` is misleading because it does not recurse into nested layers.
566
575
  - f327eec: Add function `getRecursiveLayers()` to `LayerCollection`, `SublayerCollection` and `GroupLayerCollection` in `@open-pioneer/map`
567
576
 
568
- Compared to `getLayers` and `getOperationalLayers`, `getRecursiveLayer` returns all (nested) child and sub layers of a collection.
569
- The property `options.filter` can be used to exclude layers (and their child layers) from the result. For `LayerCollection`, `getRecursiveLayers()` provides the predefined filters `base` and `operational` to return either base layers or operation layers only.
570
-
571
- The function might be costly if the hierarchy of layers is deeply nested because the layer tree has to be traversed recursively.
572
- In some scenarios using `options.filter` could be used to improve the performance because it is not necessary to traverse the layer tree completely if some layers are excluded.
573
-
574
- Example (using GroupLayerCollection):
575
-
576
- ```typescript
577
- const grouplayer = new GroupLayer({
578
- id: "group",
579
- title: "group test",
580
- layers: [
581
- new SimpleLayer({
582
- id: "member",
583
- title: "group member",
584
- olLayer: olLayer1,
585
- }),
586
- new GroupLayer({
587
- id: "subgroup",
588
- title: "subgroup test",
577
+ Compared to `getLayers` and `getOperationalLayers`, `getRecursiveLayer` returns all (nested) child and sub layers of a collection.
578
+ The property `options.filter` can be used to exclude layers (and their child layers) from the result. For `LayerCollection`, `getRecursiveLayers()` provides the predefined filters `base` and `operational` to return either base layers or operation layers only.
579
+
580
+ The function might be costly if the hierarchy of layers is deeply nested because the layer tree has to be traversed recursively.
581
+ In some scenarios using `options.filter` could be used to improve the performance because it is not necessary to traverse the layer tree completely if some layers are excluded.
582
+
583
+ Example (using GroupLayerCollection):
584
+
585
+ ```typescript
586
+ const grouplayer = new GroupLayer({
587
+ id: "group",
588
+ title: "group test",
589
589
  layers: [
590
- new SimpleLayer({
591
- id: "subgroupmember",
592
- title: "subgroup member",
593
- olLayer: olLayer2,
594
- }),
595
- ],
596
- }),
597
- ],
598
- });
599
-
600
- // Returns only the layer "member" because the provided filter function excludes "subgroup" and (implicitly) its child "subgroupmember".
601
- const layers = grouplayer.layers.getRecursiveLayers({
602
- filter: (layer) => layer.id !== "subgroup",
603
- });
604
- ```
590
+ new SimpleLayer({
591
+ id: "member",
592
+ title: "group member",
593
+ olLayer: olLayer1
594
+ }),
595
+ new GroupLayer({
596
+ id: "subgroup",
597
+ title: "subgroup test",
598
+ layers: [
599
+ new SimpleLayer({
600
+ id: "subgroupmember",
601
+ title: "subgroup member",
602
+ olLayer: olLayer2
603
+ })
604
+ ]
605
+ })
606
+ ]
607
+ });
608
+
609
+ // Returns only the layer "member" because the provided filter function excludes "subgroup" and (implicitly) its child "subgroupmember".
610
+ const layers = grouplayer.layers.getRecursiveLayers({
611
+ filter: (layer) => layer.id !== "subgroup"
612
+ });
613
+ ```
605
614
 
606
615
  ### Patch Changes
607
616
 
@@ -609,23 +618,23 @@
609
618
  This allows specifying the type of the `properties` attribute.
610
619
  The default type is `Readonly<Record<string, unknown>>` for backwards compatibility.
611
620
 
612
- Example:
621
+ Example:
613
622
 
614
- ```ts
615
- interface MyFeatureProperties {
616
- name: string;
617
- }
623
+ ```ts
624
+ interface MyFeatureProperties {
625
+ name: string;
626
+ }
618
627
 
619
- const feature: BaseFeature<MyFeatureProperties> = {
620
- id: 123,
621
- properties: {
622
- name: "Example Feature",
623
- },
624
- };
628
+ const feature: BaseFeature<MyFeatureProperties> = {
629
+ id: 123,
630
+ properties: {
631
+ name: "Example Feature"
632
+ }
633
+ };
625
634
 
626
- // string | undefined instead of `unknown`
627
- const name = feature.properties?.name;
628
- ```
635
+ // string | undefined instead of `unknown`
636
+ const name = feature.properties?.name;
637
+ ```
629
638
 
630
639
  - 32ed2cd: Fix `mapModel.layers.getLayerById()` not being reactive (#400).
631
640
  - 209eb8e: Added a configuration option to disable fetching of WMS service capabilities.
@@ -639,126 +648,126 @@
639
648
  - e7978a8: **Breaking:** Remove most events from the map model and the layer interfaces.
640
649
  All events that were merely used to synchronized state (e.g. `changed:title` etc.) have been removed.
641
650
 
642
- The map model and related objects (layers, layer collections, etc.) are now based on the [Reactivity API](https://github.com/conterra/reactivity/blob/main/packages/reactivity-core/README.md).
643
- This change greatly simplifies the code that is necessary to access up-to-date values and to react to changes.
651
+ The map model and related objects (layers, layer collections, etc.) are now based on the [Reactivity API](https://github.com/conterra/reactivity/blob/main/packages/reactivity-core/README.md).
652
+ This change greatly simplifies the code that is necessary to access up-to-date values and to react to changes.
644
653
 
645
- For example, from inside a React component, you can now write:
654
+ For example, from inside a React component, you can now write:
646
655
 
647
- ```jsx
648
- import { useReactiveSnapshot } from "@open-pioneer/reactivity";
656
+ ```jsx
657
+ import { useReactiveSnapshot } from "@open-pioneer/reactivity";
649
658
 
650
- function YourComponent() {
651
- // Always up to date, even if the layer's title changes.
652
- // No more need to listen to events.
653
- const title = useReactiveSnapshot(() => layer.title, [layer]);
654
- return <div>{title}</div>;
655
- }
656
- ```
659
+ function YourComponent() {
660
+ // Always up to date, even if the layer's title changes.
661
+ // No more need to listen to events.
662
+ const title = useReactiveSnapshot(() => layer.title, [layer]);
663
+ return <div>{title}</div>;
664
+ }
665
+ ```
657
666
 
658
- And inside a normal JavaScript function, you can watch for changes like this:
667
+ And inside a normal JavaScript function, you can watch for changes like this:
659
668
 
660
- ```js
661
- import { watch } from "@conterra/reactivity-core";
669
+ ```js
670
+ import { watch } from "@conterra/reactivity-core";
662
671
 
663
- const watchHandle = watch(
664
- () => [layer.title],
665
- ([newTitle]) => {
666
- console.log("The title changed to", newTitle);
667
- }
668
- );
672
+ const watchHandle = watch(
673
+ () => [layer.title],
674
+ ([newTitle]) => {
675
+ console.log("The title changed to", newTitle);
676
+ }
677
+ );
669
678
 
670
- // Later, cleanup:
671
- watchHandle.destroy();
672
- ```
679
+ // Later, cleanup:
680
+ watchHandle.destroy();
681
+ ```
673
682
 
674
- For more details, check the [Reactivity API documentation](https://github.com/conterra/reactivity/blob/main/packages/reactivity-core/README.md).
683
+ For more details, check the [Reactivity API documentation](https://github.com/conterra/reactivity/blob/main/packages/reactivity-core/README.md).
675
684
 
676
685
  - 7ae9f90: Add new `children` property to all layers.
677
686
  This property makes it possible to handle any layer children in a generic fashion, regardless of the layer's actual type.
678
687
 
679
- `layer.children` is either an alias of `layer.sublayers` (if the layer has sublayers), `layer.layers` (if it's a `GroupLayer`) or undefined, if the layer does not have any children.
688
+ `layer.children` is either an alias of `layer.sublayers` (if the layer has sublayers), `layer.layers` (if it's a `GroupLayer`) or undefined, if the layer does not have any children.
680
689
 
681
690
  - d8337a6: The following hooks are deprecated and will be removed in a future release:
682
691
 
683
- - `useView`
684
- - `useProjection`
685
- - `useResolution`
686
- - `useCenter`
687
- - `useScale`
692
+ - `useView`
693
+ - `useProjection`
694
+ - `useResolution`
695
+ - `useCenter`
696
+ - `useScale`
688
697
 
689
- They can all be replaced by using the new reactive properties on the `MapModel`, for example:
698
+ They can all be replaced by using the new reactive properties on the `MapModel`, for example:
690
699
 
691
- ```javascript
692
- // old:
693
- const center = useCenter(olMap);
700
+ ```javascript
701
+ // old:
702
+ const center = useCenter(olMap);
694
703
 
695
- // new:
696
- const center = useReactiveSnapshot(() => mapModel.center, [mapModel]);
697
- ```
704
+ // new:
705
+ const center = useReactiveSnapshot(() => mapModel.center, [mapModel]);
706
+ ```
698
707
 
699
708
  - 2fa8020: Update trails core package dependencies.
700
709
 
701
- - Also updates Chakra UI to the latest 2.x version and Chakra React Select to version 5.
702
- - Removes any obsolete references to `@chakra-ui/system`.
703
- This dependency seems to be no longer required and may lead to duplicate packages in your dependency tree.
710
+ - Also updates Chakra UI to the latest 2.x version and Chakra React Select to version 5.
711
+ - Removes any obsolete references to `@chakra-ui/system`.
712
+ This dependency seems to be no longer required and may lead to duplicate packages in your dependency tree.
704
713
 
705
714
  - 7ae9f90: Add new layer type `GroupLayer` to to the Map API.
706
715
 
707
- A `GroupLayer` contains a list of `Layer` (e.g. `SimpleLayer` or `WMSLayer`). Because `GroupLayer` is a `Layer` as well nested groups are supported.
708
- The child layers of a `GroupLayer` can be accessed with the `layers` property - `layers` is `undefined` if it is not a group.
709
- The parent `GroupLayer` of a child layer can be accessed with the `parent` property - `parent` is `undefined` if this layer is not part of a group (or not a sublayer).
710
-
711
- ```js
712
- const olLayer1 = new TileLayer({
713
- source: new OSM(),
714
- });
715
- const olLayer2 = new TileLayer({
716
- source: new BkgTopPlusOpen(),
717
- });
718
-
719
- // Create group layer with nested sub group
720
- const group = new GroupLayer({
721
- id: "group",
722
- title: "a group layer",
723
- layers: [
724
- new SimpleLayer({
725
- id: "member",
726
- title: "group member",
727
- olLayer: olLayer1,
728
- }),
729
- new GroupLayer({
730
- id: "subgroup",
731
- title: "a nested group layer",
732
- layers: [
733
- new SimpleLayer({
734
- id: "submember",
735
- title: "subgroup member",
736
- olLayer: olLayer2,
737
- }),
738
- ],
739
- }),
740
- ],
741
- });
742
-
743
- const childLayers: GroupLayerCollection = group.layers; // Access child layers
744
- ```
745
-
746
- Layers can only be added to a single group or map.
747
- Sublayers (e.g. `WMSSublayer`) cannot be added to a group directly.
716
+ A `GroupLayer` contains a list of `Layer` (e.g. `SimpleLayer` or `WMSLayer`). Because `GroupLayer` is a `Layer` as well nested groups are supported.
717
+ The child layers of a `GroupLayer` can be accessed with the `layers` property - `layers` is `undefined` if it is not a group.
718
+ The parent `GroupLayer` of a child layer can be accessed with the `parent` property - `parent` is `undefined` if this layer is not part of a group (or not a sublayer).
719
+
720
+ ```js
721
+ const olLayer1 = new TileLayer({
722
+ source: new OSM(),
723
+ });
724
+ const olLayer2 = new TileLayer({
725
+ source: new BkgTopPlusOpen(),
726
+ });
727
+
728
+ // Create group layer with nested sub group
729
+ const group = new GroupLayer({
730
+ id: "group",
731
+ title: "a group layer",
732
+ layers: [
733
+ new SimpleLayer({
734
+ id: "member",
735
+ title: "group member",
736
+ olLayer: olLayer1,
737
+ }),
738
+ new GroupLayer({
739
+ id: "subgroup",
740
+ title: "a nested group layer",
741
+ layers: [
742
+ new SimpleLayer({
743
+ id: "submember",
744
+ title: "subgroup member",
745
+ olLayer: olLayer2,
746
+ }),
747
+ ],
748
+ }),
749
+ ],
750
+ });
751
+
752
+ const childLayers: GroupLayerCollection = group.layers; // Access child layers
753
+ ```
754
+
755
+ Layers can only be added to a single group or map.
756
+ Sublayers (e.g. `WMSSublayer`) cannot be added to a group directly.
748
757
 
749
758
  - d8337a6: Provide new reactive properties on the `MapModel` type.
750
759
 
751
- - `olView` (-> `olMap.getView()`)
752
- - `projection` (-> `olMap.getView().getProjection()`)
753
- - `resolution` (-> `olMap.getView().getResolution()`)
754
- - `zoomLevel` (-> `olMap.getView().getZoom()`)
755
- - `center` (-> `olMap.getView().getCenter()`)
756
- - `scale` (derived from center and resolution)
760
+ - `olView` (-> `olMap.getView()`)
761
+ - `projection` (-> `olMap.getView().getProjection()`)
762
+ - `resolution` (-> `olMap.getView().getResolution()`)
763
+ - `zoomLevel` (-> `olMap.getView().getZoom()`)
764
+ - `center` (-> `olMap.getView().getCenter()`)
765
+ - `scale` (derived from center and resolution)
757
766
 
758
- Most of the listed properties are already available on raw OpenLayers objects (see code in parentheses above).
759
- However, those OpenLayers properties require manual work for synchronization, whereas the new properties are reactive (and can be watched, for example, using `useReactiveSnapshot()`).
767
+ Most of the listed properties are already available on raw OpenLayers objects (see code in parentheses above).
768
+ However, those OpenLayers properties require manual work for synchronization, whereas the new properties are reactive (and can be watched, for example, using `useReactiveSnapshot()`).
760
769
 
761
- A new method `setScale()` has also been added to the model.
770
+ A new method `setScale()` has also been added to the model.
762
771
 
763
772
  ### Patch Changes
764
773
 
@@ -772,45 +781,45 @@
772
781
 
773
782
  - 2502050: Introduce union types and `type` attributes for layers. This allows TypeScript narrowing for layers and determining a layer's type.
774
783
 
775
- The `Layer` and `Sublayer` types for layers remain, but are unions of the corresponding concrete layer types now.
776
- The layer type `LayerBase` has been removed and is replaced by `AnyLayerType`
777
- to clarify that this type represents a union of all types of layer (currently `Layer` and `Sublayer`).
784
+ The `Layer` and `Sublayer` types for layers remain, but are unions of the corresponding concrete layer types now.
785
+ The layer type `LayerBase` has been removed and is replaced by `AnyLayerType`
786
+ to clarify that this type represents a union of all types of layer (currently `Layer` and `Sublayer`).
778
787
 
779
- Two type guards have been implemented that allow to check if a layer instance is a `Layer` or `Sublayer`: `isLayer()`and `isSublayer()` (see example below).
788
+ Two type guards have been implemented that allow to check if a layer instance is a `Layer` or `Sublayer`: `isLayer()`and `isSublayer()` (see example below).
780
789
 
781
- The following `type` attribute values have been implemented at the layers:
790
+ The following `type` attribute values have been implemented at the layers:
782
791
 
783
- - SimpleLayer: `simple`
784
- - WMSLayer: `wms`
785
- - WMSSubLayer: `wms-sublayer`
786
- - WMTSLayer: `wmts`
792
+ - SimpleLayer: `simple`
793
+ - WMSLayer: `wms`
794
+ - WMSSubLayer: `wms-sublayer`
795
+ - WMTSLayer: `wmts`
787
796
 
788
- Example of usage:
797
+ Example of usage:
789
798
 
790
- ```ts
791
- import { AnyLayer, WMTSLayer, isSublayer } from "@open-pioneer/map";
799
+ ```ts
800
+ import { AnyLayer, WMTSLayer, isSublayer } from "@open-pioneer/map";
792
801
 
793
- export class ExampleClass {
794
- //...
802
+ export class ExampleClass {
803
+ //...
795
804
 
796
- exampleFunction(layer: AnyLayer) {
797
- // prop may be a layer of any type
805
+ exampleFunction(layer: AnyLayer) {
806
+ // prop may be a layer of any type
798
807
 
799
- // use layers type attribute to check layer type
800
- if (layer.type === "wmts") {
801
- layer.matrixSet; // prop only available on WMTSLayer
808
+ // use layers type attribute to check layer type
809
+ if (layer.type === "wmts") {
810
+ layer.matrixSet; // prop only available on WMTSLayer
802
811
 
803
- const wmtsLayer: WMTSLayer = layer; // type of layer is now narrowed to `WMTSLayer`
804
- }
812
+ const wmtsLayer: WMTSLayer = layer; // type of layer is now narrowed to `WMTSLayer`
813
+ }
805
814
 
806
- // use new type guard to check if layer is a Sublayer
807
- if (isSublayer(layer)) {
808
- // type of layer is now narrowed to `WMSSublayer` (as it is currently the only type of Sublayer existing)
809
- layer.parentLayer; // prop only available on Sublayers
810
- }
815
+ // use new type guard to check if layer is a Sublayer
816
+ if (isSublayer(layer)) {
817
+ // type of layer is now narrowed to `WMSSublayer` (as it is currently the only type of Sublayer existing)
818
+ layer.parentLayer; // prop only available on Sublayers
819
+ }
820
+ }
811
821
  }
812
- }
813
- ```
822
+ ```
814
823
 
815
824
  - 310800c: Switch from `peerDependencies` to normal `dependencies`. Peer dependencies have some usability problems when used at scale.
816
825
 
@@ -820,7 +829,7 @@
820
829
  - 583f1d6: The `mapId` or `map` properties are now optional on individual components.
821
830
  You can use the `DefaultMapProvider` to configure an implicit default value.
822
831
 
823
- Note that configuring _neither_ a default _nor_ an explicit `map` or `mapId` will trigger a runtime error.
832
+ Note that configuring _neither_ a default _nor_ an explicit `map` or `mapId` will trigger a runtime error.
824
833
 
825
834
  - 583f1d6: All UI components in this project now accept the `mapId` (a `string`) _or_ the `map` (a `MapModel`) directly.
826
835
  - 397d617: Reimplement computation of map anchor positioning using new css props.
@@ -830,20 +839,20 @@
830
839
  - 583f1d6: The new component `DefaultMapProvider` allows you to configure the _default map_ for its children.
831
840
  If `DefaultMapProvider` is used, you can omit the explicit `mapId` (or `map`) property on the individual UI components.
832
841
 
833
- For many applications, `DefaultMapProvider` can be used to surround all (or most of) the application's UI.
842
+ For many applications, `DefaultMapProvider` can be used to surround all (or most of) the application's UI.
834
843
 
835
- Example:
844
+ Example:
836
845
 
837
- ```tsx
838
- import { DefaultMapProvider } from "@open-pioneer/map";
846
+ ```tsx
847
+ import { DefaultMapProvider } from "@open-pioneer/map";
839
848
 
840
- <DefaultMapProvider mapId={MAP_ID}>
841
- {/* no need to repeat the map id in this subtree, unless you want to use a different one */}
842
- <MapContainer />
843
- <Toc />
844
- <ComplexChild />
845
- </DefaultMapProvider>;
846
- ```
849
+ <DefaultMapProvider mapId={MAP_ID}>
850
+ {/* no need to repeat the map id in this subtree, unless you want to use a different one */}
851
+ <MapContainer />
852
+ <Toc />
853
+ <ComplexChild />
854
+ </DefaultMapProvider>;
855
+ ```
847
856
 
848
857
  - 397d617: Move attribution of OL map according to the map view's padding.
849
858
 
@@ -860,36 +869,36 @@
860
869
 
861
870
  - 0d51d2f: Change how map anchors are positioned in the DOM.
862
871
 
863
- Previously, map anchor divs were children of the OpenLayers map viewport:
872
+ Previously, map anchor divs were children of the OpenLayers map viewport:
864
873
 
865
- ```
866
- .map-container
867
- └── .ol-viewport
868
- └── .ol-overlaycontainer-stopevent
869
- └── .map-anchors
870
- └── .map-anchor
871
- └── ... children ...
872
- ```
874
+ ```
875
+ .map-container
876
+ └── .ol-viewport
877
+ └── .ol-overlaycontainer-stopevent
878
+ └── .map-anchors
879
+ └── .map-anchor
880
+ └── ... children ...
881
+ ```
873
882
 
874
- This interfered with browser event handling, especially if the map anchor's content was interactive.
875
- The workarounds to stop events from map-anchors to bubble into the map caused surprising behavior (e.g. https://github.com/open-pioneer/trails-openlayers-base-packages/issues/312).
883
+ This interfered with browser event handling, especially if the map anchor's content was interactive.
884
+ The workarounds to stop events from map-anchors to bubble into the map caused surprising behavior (e.g. https://github.com/open-pioneer/trails-openlayers-base-packages/issues/312).
876
885
 
877
- Now, the DOM looks like this:
886
+ Now, the DOM looks like this:
878
887
 
879
- ```
880
- .map-container
881
- ├── .map-anchors
882
- │ └── .map-anchor
883
- │ └── ... children ...
884
- └── .ol-viewport
885
- ```
888
+ ```
889
+ .map-container
890
+ ├── .map-anchors
891
+ │ └── .map-anchor
892
+ │ └── ... children ...
893
+ └── .ol-viewport
894
+ ```
886
895
 
887
- Which means that the map-anchors are no longer children of the map.
896
+ Which means that the map-anchors are no longer children of the map.
888
897
 
889
- You may have to update your custom styles if you relied on the previous DOM hierarchy.
898
+ You may have to update your custom styles if you relied on the previous DOM hierarchy.
890
899
 
891
- The `MapAnchor`'s prop `stopEvents` has been deleted as it is no longer needed.
892
- Browser events happening inside a map anchor or its children will no longer affect the map.
900
+ The `MapAnchor`'s prop `stopEvents` has been deleted as it is no longer needed.
901
+ Browser events happening inside a map anchor or its children will no longer affect the map.
893
902
 
894
903
  ### Patch Changes
895
904