@open-pioneer/map 0.9.0-dev.20250224083536 → 0.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,9 +1,14 @@
1
1
  # @open-pioneer/map
2
2
 
3
- ## 0.9.0-dev.20250224083536
3
+ ## 0.9.0
4
4
 
5
5
  ### Minor Changes
6
6
 
7
+ - e7fdc5d: improve scale calculation for none-metric projections
8
+
9
+ Fix scale calculation for projections with none-metric units (e.g. EPSG:4326).
10
+ 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.
11
+
7
12
  - cb94c75: update dependencies
8
13
  - f327eec: Deprecate `mapModel.layers.getAllLayers()`.
9
14
  Use `mapModel.layers.getLayers()` instead.
@@ -69,7 +69,7 @@ class MapModelImpl extends EventEmitter {
69
69
  if (projection == null || resolution == null || center == null) {
70
70
  return void 0;
71
71
  }
72
- const pointResolution = getPointResolution(projection, resolution, center);
72
+ const pointResolution = getPointResolution(projection, resolution, center, "m");
73
73
  const scale = Math.round(pointResolution * INCHES_PER_METRE * DEFAULT_DPI);
74
74
  return scale;
75
75
  });
@@ -1 +1 @@
1
- {"version":3,"file":"MapModelImpl.js","sources":["MapModelImpl.ts"],"sourcesContent":["// SPDX-FileCopyrightText: 2023-2025 Open Pioneer project (https://github.com/open-pioneer)\n// SPDX-License-Identifier: Apache-2.0\nimport { computed, reactive, ReadonlyReactive, synchronized } from \"@conterra/reactivity-core\";\nimport {\n createAbortError,\n createLogger,\n createManualPromise,\n EventEmitter,\n isAbortError,\n ManualPromise\n} from \"@open-pioneer/core\";\nimport { HttpService } from \"@open-pioneer/http\";\nimport OlMap from \"ol/Map\";\nimport { unByKey } from \"ol/Observable\";\nimport OlView from \"ol/View\";\nimport { Coordinate } from \"ol/coordinate\";\nimport { EventsKey } from \"ol/events\";\nimport { getCenter } from \"ol/extent\";\nimport { Geometry } from \"ol/geom\";\nimport { getPointResolution, Projection } from \"ol/proj\";\nimport {\n ExtentConfig,\n Highlight,\n HighlightOptions,\n HighlightZoomOptions,\n MapModel,\n MapModelEvents\n} from \"../api\";\nimport { Highlights } from \"./Highlights\";\nimport { LayerCollectionImpl } from \"./LayerCollectionImpl\";\n\nconst LOG = createLogger(\"map:MapModel\");\n\nconst DEFAULT_DPI = 25.4 / 0.28;\nconst INCHES_PER_METRE = 39.37;\n\n/**\n * Shared services or other entities propagated from the map model to all layer instances.\n */\nexport interface SharedDependencies {\n httpService: HttpService;\n}\n\nexport class MapModelImpl extends EventEmitter<MapModelEvents> implements MapModel {\n readonly #id: string;\n readonly #olMap: OlMap;\n readonly #olView: ReadonlyReactive<OlView>;\n readonly #layers = new LayerCollectionImpl(this);\n readonly #highlights: Highlights;\n readonly #sharedDeps: SharedDependencies;\n\n #destroyed = false;\n #container: ReadonlyReactive<HTMLElement | undefined>;\n #initialExtent = reactive<ExtentConfig>();\n #viewBindings: ReadonlyReactive<ViewBindings>;\n #scale: ReadonlyReactive<number | undefined>;\n\n readonly #abortController = new AbortController();\n #displayStatus: \"waiting\" | \"ready\" | \"error\";\n #displayWaiter: ManualPromise<void> | undefined;\n\n constructor(properties: {\n id: string;\n olMap: OlMap;\n initialExtent: ExtentConfig | undefined;\n httpService: HttpService;\n }) {\n super();\n this.#id = properties.id;\n this.#olMap = properties.olMap;\n this.#olView = synchronized(\n () => this.#olMap.getView(),\n (cb) => {\n const key = this.#olMap.on(\"change:view\", cb);\n return () => unByKey(key);\n }\n );\n this.#initialExtent.value = properties.initialExtent;\n this.#sharedDeps = {\n httpService: properties.httpService\n };\n this.#highlights = new Highlights(this.#olMap);\n\n this.#displayStatus = \"waiting\";\n this.#initializeView().then(\n () => {\n this.#displayStatus = \"ready\";\n this.#displayWaiter?.resolve();\n this.#displayWaiter = undefined;\n },\n (error) => {\n if (!isAbortError(error)) {\n LOG.error(`Failed to initialize map`, error);\n }\n\n this.#displayStatus = \"error\";\n this.#displayWaiter?.reject(new Error(`Failed to initialize map.`));\n this.#displayWaiter = undefined;\n }\n );\n\n this.#container = synchronized(\n () => this.#olMap.getTargetElement() ?? undefined,\n (cb) => {\n const key = this.#olMap.on(\"change:target\", cb);\n return () => unByKey(key);\n }\n );\n\n this.#viewBindings = computed(() => createViewBindings(this.#olView.value));\n this.#scale = computed(() => {\n const { projection, resolution, center } = this;\n if (projection == null || resolution == null || center == null) {\n return undefined;\n }\n\n /**\n * Returns the appropriate scale for the given resolution and units, see OpenLayers function getScaleForResolution()\n * https://github.com/openlayers/openlayers/blob/7fa9df03431e9e1bc517e6c414565d9f848a3132/src/ol/control/ScaleLine.js#L454C3-L454C24\n */\n const pointResolution = getPointResolution(projection, resolution, center);\n const scale = Math.round(pointResolution * INCHES_PER_METRE * DEFAULT_DPI);\n return scale;\n });\n }\n\n destroy() {\n if (this.#destroyed) {\n return;\n }\n\n this.#destroyed = true;\n try {\n this.emit(\"destroy\");\n } catch (e) {\n LOG.warn(`Unexpected error from event listener during map model destruction:`, e);\n }\n\n this.#abortController.abort();\n this.#displayWaiter?.reject(new Error(\"Map model was destroyed.\"));\n this.#layers.destroy();\n this.#highlights.destroy();\n this.#olMap.dispose();\n }\n\n get id(): string {\n return this.#id;\n }\n\n get olMap(): OlMap {\n return this.#olMap;\n }\n\n get olView(): OlView {\n return this.#olView.value;\n }\n\n get projection(): Projection {\n return this.#viewBindings.value.projection;\n }\n\n get center(): Coordinate | undefined {\n return this.#viewBindings.value.center.value;\n }\n\n get resolution(): number | undefined {\n return this.#viewBindings.value.resolution.value;\n }\n\n get zoomLevel(): number | undefined {\n return this.#viewBindings.value.zoom.value;\n }\n\n get scale(): number | undefined {\n return this.#scale.value;\n }\n\n get layers(): LayerCollectionImpl {\n return this.#layers;\n }\n\n get container(): HTMLElement | undefined {\n return this.#container.value;\n }\n\n get initialExtent(): ExtentConfig | undefined {\n return this.#initialExtent.value;\n }\n\n get __sharedDependencies(): SharedDependencies {\n return this.#sharedDeps;\n }\n\n setScale(newScale: number): void {\n const view = this.olView;\n const projection = this.projection;\n const center = this.center;\n if (!center) {\n return;\n }\n\n const mpu = projection.getMetersPerUnit() ?? 1;\n const resolution = INCHES_PER_METRE * DEFAULT_DPI * mpu;\n const pointResolution = newScale / getPointResolution(projection, resolution, center);\n view.setResolution(pointResolution);\n }\n\n highlight(geometries: Geometry[], options?: HighlightOptions | undefined): Highlight {\n return this.#highlights.addHighlight(geometries, options);\n }\n\n zoom(geometries: Geometry[], options?: HighlightZoomOptions | undefined): void {\n this.#highlights.zoomToHighlight(geometries, options);\n }\n\n highlightAndZoom(geometries: Geometry[], options?: HighlightZoomOptions) {\n return this.#highlights.addHighlightAndZoom(geometries, options ?? {});\n }\n\n removeHighlights() {\n this.#highlights.clearHighlight();\n }\n\n whenDisplayed(): Promise<void> {\n if (this.#destroyed) {\n return Promise.reject(new Error(\"Map model was destroyed.\"));\n }\n if (this.#displayStatus === \"error\") {\n return Promise.reject(new Error(`Failed to initialize map.`));\n }\n if (this.#displayStatus === \"ready\") {\n return Promise.resolve();\n }\n return (this.#displayWaiter ??= createManualPromise()).promise;\n }\n\n /**\n * Waits for the map to be displayed and then initializes the view (if necessary).\n *\n * May simply resolve when done, or throw an error when a problem occurs.\n * AbortError is thrown when cancelled via `this.#abortController`, for example\n * when the map model is destroyed before it has ever been displayed.\n */\n async #initializeView(): Promise<void> {\n try {\n await waitForMapSize(this.olMap, this.#abortController.signal); // may throw on cancel\n } catch (e) {\n if (isAbortError(e)) {\n throw e;\n }\n throw new Error(`Failed to wait for the map to be displayed.`, { cause: e });\n }\n\n try {\n const olMap = this.#olMap;\n const view = olMap.getView();\n\n if (this.#initialExtent.value) {\n // Initial extent was set from the outside. We simply ensure that it gets displayed by the map.\n const extent = this.#initialExtent.value;\n const olExtent = [extent.xMin, extent.yMin, extent.xMax, extent.yMax];\n\n const olCenter = getCenter(olExtent);\n const resolution = view.getResolutionForExtent(olExtent);\n LOG.debug(`Applying initial extent`, extent);\n LOG.debug(` Computed center:`, olCenter);\n LOG.debug(` Computed resolution:`, resolution);\n\n view.setCenter(olCenter);\n view.setResolution(resolution);\n } else {\n // Initial extent was NOT set from the outside.\n // We detect whatever the view is displaying and consider it to be the initial extent.\n const olExtent = view.calculateExtent();\n const [xMin = 0, yMin = 0, xMax = 0, yMax = 0] = olExtent;\n const extent: ExtentConfig = { xMin, yMin, xMax, yMax };\n LOG.debug(`Detected initial extent`, extent);\n\n this.#initialExtent.value = extent;\n }\n } catch (e) {\n throw new Error(`Failed to apply the initial extent.`, { cause: e });\n }\n }\n}\n\ninterface ViewBindings {\n resolution: ReadonlyReactive<number | undefined>;\n center: ReadonlyReactive<Coordinate | undefined>;\n zoom: ReadonlyReactive<number | undefined>;\n projection: Projection; // not reactive (change view to change projection)\n}\n\nfunction createViewBindings(view: OlView): ViewBindings {\n return {\n resolution: synchronized(\n () => view.getResolution(),\n (cb) => {\n const key = view.on(\"change:resolution\", cb);\n return () => unByKey(key);\n }\n ),\n center: synchronized(\n () => view.getCenter(),\n (cb) => {\n const key = view.on(\"change:center\", cb);\n return () => unByKey(key);\n }\n ),\n zoom: synchronized(\n () => view.getZoom(),\n (cb) => {\n const key = view.on(\"change:resolution\", cb);\n return () => unByKey(key);\n }\n ),\n projection: view.getProjection()\n };\n}\n\nfunction waitForMapSize(olMap: OlMap, signal: AbortSignal): Promise<void> {\n const promise = new Promise<void>((resolve, reject) => {\n let eventKey: EventsKey | undefined;\n\n function checkSize() {\n const currentSize = olMap.getSize() ?? [];\n const [width = 0, height = 0] = currentSize;\n if (currentSize && width > 0 && height > 0) {\n finish();\n }\n }\n\n function onAbort() {\n finish(createAbortError());\n }\n\n function finish(error?: Error | undefined) {\n if (eventKey) {\n unByKey(eventKey);\n eventKey = undefined;\n }\n signal.removeEventListener(\"abort\", onAbort);\n\n if (error) {\n reject(error);\n } else {\n resolve(wait(25)); // Give the map some time to render\n }\n }\n\n if (signal.aborted) {\n finish(createAbortError());\n return;\n }\n\n signal.addEventListener(\"abort\", onAbort);\n eventKey = olMap.on(\"change:size\", checkSize);\n });\n return promise;\n}\n\nfunction wait(milliseconds: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, milliseconds));\n}\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"MapModelImpl.js","sources":["MapModelImpl.ts"],"sourcesContent":["// SPDX-FileCopyrightText: 2023-2025 Open Pioneer project (https://github.com/open-pioneer)\n// SPDX-License-Identifier: Apache-2.0\nimport { computed, reactive, ReadonlyReactive, synchronized } from \"@conterra/reactivity-core\";\nimport {\n createAbortError,\n createLogger,\n createManualPromise,\n EventEmitter,\n isAbortError,\n ManualPromise\n} from \"@open-pioneer/core\";\nimport { HttpService } from \"@open-pioneer/http\";\nimport OlMap from \"ol/Map\";\nimport { unByKey } from \"ol/Observable\";\nimport OlView from \"ol/View\";\nimport { Coordinate } from \"ol/coordinate\";\nimport { EventsKey } from \"ol/events\";\nimport { getCenter } from \"ol/extent\";\nimport { Geometry } from \"ol/geom\";\nimport { getPointResolution, Projection } from \"ol/proj\";\nimport {\n ExtentConfig,\n Highlight,\n HighlightOptions,\n HighlightZoomOptions,\n MapModel,\n MapModelEvents\n} from \"../api\";\nimport { Highlights } from \"./Highlights\";\nimport { LayerCollectionImpl } from \"./LayerCollectionImpl\";\n\nconst LOG = createLogger(\"map:MapModel\");\n\nconst DEFAULT_DPI = 25.4 / 0.28;\nconst INCHES_PER_METRE = 39.37;\n\n/**\n * Shared services or other entities propagated from the map model to all layer instances.\n */\nexport interface SharedDependencies {\n httpService: HttpService;\n}\n\nexport class MapModelImpl extends EventEmitter<MapModelEvents> implements MapModel {\n readonly #id: string;\n readonly #olMap: OlMap;\n readonly #olView: ReadonlyReactive<OlView>;\n readonly #layers = new LayerCollectionImpl(this);\n readonly #highlights: Highlights;\n readonly #sharedDeps: SharedDependencies;\n\n #destroyed = false;\n #container: ReadonlyReactive<HTMLElement | undefined>;\n #initialExtent = reactive<ExtentConfig>();\n #viewBindings: ReadonlyReactive<ViewBindings>;\n #scale: ReadonlyReactive<number | undefined>;\n\n readonly #abortController = new AbortController();\n #displayStatus: \"waiting\" | \"ready\" | \"error\";\n #displayWaiter: ManualPromise<void> | undefined;\n\n constructor(properties: {\n id: string;\n olMap: OlMap;\n initialExtent: ExtentConfig | undefined;\n httpService: HttpService;\n }) {\n super();\n this.#id = properties.id;\n this.#olMap = properties.olMap;\n this.#olView = synchronized(\n () => this.#olMap.getView(),\n (cb) => {\n const key = this.#olMap.on(\"change:view\", cb);\n return () => unByKey(key);\n }\n );\n this.#initialExtent.value = properties.initialExtent;\n this.#sharedDeps = {\n httpService: properties.httpService\n };\n this.#highlights = new Highlights(this.#olMap);\n\n this.#displayStatus = \"waiting\";\n this.#initializeView().then(\n () => {\n this.#displayStatus = \"ready\";\n this.#displayWaiter?.resolve();\n this.#displayWaiter = undefined;\n },\n (error) => {\n if (!isAbortError(error)) {\n LOG.error(`Failed to initialize map`, error);\n }\n\n this.#displayStatus = \"error\";\n this.#displayWaiter?.reject(new Error(`Failed to initialize map.`));\n this.#displayWaiter = undefined;\n }\n );\n\n this.#container = synchronized(\n () => this.#olMap.getTargetElement() ?? undefined,\n (cb) => {\n const key = this.#olMap.on(\"change:target\", cb);\n return () => unByKey(key);\n }\n );\n\n this.#viewBindings = computed(() => createViewBindings(this.#olView.value));\n this.#scale = computed(() => {\n const { projection, resolution, center } = this;\n if (projection == null || resolution == null || center == null) {\n return undefined;\n }\n\n /**\n * Returns the appropriate scale for the given resolution and units, see OpenLayers function getScaleForResolution()\n * https://github.com/openlayers/openlayers/blob/7fa9df03431e9e1bc517e6c414565d9f848a3132/src/ol/control/ScaleLine.js#L454C3-L454C24\n */\n const pointResolution = getPointResolution(projection, resolution, center, \"m\"); //point resolution in meter per pixel\n const scale = Math.round(pointResolution * INCHES_PER_METRE * DEFAULT_DPI);\n return scale;\n });\n }\n\n destroy() {\n if (this.#destroyed) {\n return;\n }\n\n this.#destroyed = true;\n try {\n this.emit(\"destroy\");\n } catch (e) {\n LOG.warn(`Unexpected error from event listener during map model destruction:`, e);\n }\n\n this.#abortController.abort();\n this.#displayWaiter?.reject(new Error(\"Map model was destroyed.\"));\n this.#layers.destroy();\n this.#highlights.destroy();\n this.#olMap.dispose();\n }\n\n get id(): string {\n return this.#id;\n }\n\n get olMap(): OlMap {\n return this.#olMap;\n }\n\n get olView(): OlView {\n return this.#olView.value;\n }\n\n get projection(): Projection {\n return this.#viewBindings.value.projection;\n }\n\n get center(): Coordinate | undefined {\n return this.#viewBindings.value.center.value;\n }\n\n get resolution(): number | undefined {\n return this.#viewBindings.value.resolution.value;\n }\n\n get zoomLevel(): number | undefined {\n return this.#viewBindings.value.zoom.value;\n }\n\n get scale(): number | undefined {\n return this.#scale.value;\n }\n\n get layers(): LayerCollectionImpl {\n return this.#layers;\n }\n\n get container(): HTMLElement | undefined {\n return this.#container.value;\n }\n\n get initialExtent(): ExtentConfig | undefined {\n return this.#initialExtent.value;\n }\n\n get __sharedDependencies(): SharedDependencies {\n return this.#sharedDeps;\n }\n\n setScale(newScale: number): void {\n const view = this.olView;\n const projection = this.projection;\n const center = this.center;\n if (!center) {\n return;\n }\n\n const mpu = projection.getMetersPerUnit() ?? 1;\n const resolution = INCHES_PER_METRE * DEFAULT_DPI * mpu;\n const pointResolution = newScale / getPointResolution(projection, resolution, center);\n view.setResolution(pointResolution);\n }\n\n highlight(geometries: Geometry[], options?: HighlightOptions | undefined): Highlight {\n return this.#highlights.addHighlight(geometries, options);\n }\n\n zoom(geometries: Geometry[], options?: HighlightZoomOptions | undefined): void {\n this.#highlights.zoomToHighlight(geometries, options);\n }\n\n highlightAndZoom(geometries: Geometry[], options?: HighlightZoomOptions) {\n return this.#highlights.addHighlightAndZoom(geometries, options ?? {});\n }\n\n removeHighlights() {\n this.#highlights.clearHighlight();\n }\n\n whenDisplayed(): Promise<void> {\n if (this.#destroyed) {\n return Promise.reject(new Error(\"Map model was destroyed.\"));\n }\n if (this.#displayStatus === \"error\") {\n return Promise.reject(new Error(`Failed to initialize map.`));\n }\n if (this.#displayStatus === \"ready\") {\n return Promise.resolve();\n }\n return (this.#displayWaiter ??= createManualPromise()).promise;\n }\n\n /**\n * Waits for the map to be displayed and then initializes the view (if necessary).\n *\n * May simply resolve when done, or throw an error when a problem occurs.\n * AbortError is thrown when cancelled via `this.#abortController`, for example\n * when the map model is destroyed before it has ever been displayed.\n */\n async #initializeView(): Promise<void> {\n try {\n await waitForMapSize(this.olMap, this.#abortController.signal); // may throw on cancel\n } catch (e) {\n if (isAbortError(e)) {\n throw e;\n }\n throw new Error(`Failed to wait for the map to be displayed.`, { cause: e });\n }\n\n try {\n const olMap = this.#olMap;\n const view = olMap.getView();\n\n if (this.#initialExtent.value) {\n // Initial extent was set from the outside. We simply ensure that it gets displayed by the map.\n const extent = this.#initialExtent.value;\n const olExtent = [extent.xMin, extent.yMin, extent.xMax, extent.yMax];\n\n const olCenter = getCenter(olExtent);\n const resolution = view.getResolutionForExtent(olExtent);\n LOG.debug(`Applying initial extent`, extent);\n LOG.debug(` Computed center:`, olCenter);\n LOG.debug(` Computed resolution:`, resolution);\n\n view.setCenter(olCenter);\n view.setResolution(resolution);\n } else {\n // Initial extent was NOT set from the outside.\n // We detect whatever the view is displaying and consider it to be the initial extent.\n const olExtent = view.calculateExtent();\n const [xMin = 0, yMin = 0, xMax = 0, yMax = 0] = olExtent;\n const extent: ExtentConfig = { xMin, yMin, xMax, yMax };\n LOG.debug(`Detected initial extent`, extent);\n\n this.#initialExtent.value = extent;\n }\n } catch (e) {\n throw new Error(`Failed to apply the initial extent.`, { cause: e });\n }\n }\n}\n\ninterface ViewBindings {\n resolution: ReadonlyReactive<number | undefined>;\n center: ReadonlyReactive<Coordinate | undefined>;\n zoom: ReadonlyReactive<number | undefined>;\n projection: Projection; // not reactive (change view to change projection)\n}\n\nfunction createViewBindings(view: OlView): ViewBindings {\n return {\n resolution: synchronized(\n () => view.getResolution(),\n (cb) => {\n const key = view.on(\"change:resolution\", cb);\n return () => unByKey(key);\n }\n ),\n center: synchronized(\n () => view.getCenter(),\n (cb) => {\n const key = view.on(\"change:center\", cb);\n return () => unByKey(key);\n }\n ),\n zoom: synchronized(\n () => view.getZoom(),\n (cb) => {\n const key = view.on(\"change:resolution\", cb);\n return () => unByKey(key);\n }\n ),\n projection: view.getProjection()\n };\n}\n\nfunction waitForMapSize(olMap: OlMap, signal: AbortSignal): Promise<void> {\n const promise = new Promise<void>((resolve, reject) => {\n let eventKey: EventsKey | undefined;\n\n function checkSize() {\n const currentSize = olMap.getSize() ?? [];\n const [width = 0, height = 0] = currentSize;\n if (currentSize && width > 0 && height > 0) {\n finish();\n }\n }\n\n function onAbort() {\n finish(createAbortError());\n }\n\n function finish(error?: Error | undefined) {\n if (eventKey) {\n unByKey(eventKey);\n eventKey = undefined;\n }\n signal.removeEventListener(\"abort\", onAbort);\n\n if (error) {\n reject(error);\n } else {\n resolve(wait(25)); // Give the map some time to render\n }\n }\n\n if (signal.aborted) {\n finish(createAbortError());\n return;\n }\n\n signal.addEventListener(\"abort\", onAbort);\n eventKey = olMap.on(\"change:size\", checkSize);\n });\n return promise;\n}\n\nfunction wait(milliseconds: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, milliseconds));\n}\n"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "type": "module",
3
3
  "name": "@open-pioneer/map",
4
- "version": "0.9.0-dev.20250224083536",
4
+ "version": "0.9.0",
5
5
  "description": "This package integrates OpenLayers maps into an open pioneer trails application.",
6
6
  "keywords": [
7
7
  "open-pioneer-trails"
@@ -14,11 +14,11 @@
14
14
  "directory": "src/packages/map"
15
15
  },
16
16
  "dependencies": {
17
- "@open-pioneer/chakra-integration": "3.0.0-dev.20250221111321",
18
- "@open-pioneer/core": "3.0.0-dev.20250221111321",
19
- "@open-pioneer/http": "3.0.0-dev.20250221111321",
20
- "@open-pioneer/react-utils": "3.0.0-dev.20250221111321",
21
- "@open-pioneer/runtime": "3.0.0-dev.20250221111321",
17
+ "@open-pioneer/chakra-integration": "^3.0.0",
18
+ "@open-pioneer/core": "^3.0.0",
19
+ "@open-pioneer/http": "^3.0.0",
20
+ "@open-pioneer/react-utils": "^3.0.0",
21
+ "@open-pioneer/runtime": "^3.0.0",
22
22
  "@types/proj4": "^2.5.2",
23
23
  "ol": "^10.4.0",
24
24
  "proj4": "^2.12.1",
package/ui/hooks.js CHANGED
@@ -45,7 +45,7 @@ function useScale(map) {
45
45
  if (projection == null || resolution == null || center == null) {
46
46
  return void 0;
47
47
  }
48
- const pointResolution = getPointResolution(projection, resolution, center);
48
+ const pointResolution = getPointResolution(projection, resolution, center, "m");
49
49
  const scale2 = Math.round(pointResolution * INCHES_PER_METRE * DEFAULT_DPI);
50
50
  return scale2;
51
51
  }, [projection, resolution, center]);
package/ui/hooks.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"hooks.js","sources":["hooks.ts"],"sourcesContent":["// SPDX-FileCopyrightText: 2023-2025 Open Pioneer project (https://github.com/open-pioneer)\n// SPDX-License-Identifier: Apache-2.0\nimport OlMap from \"ol/Map\";\nimport OlView from \"ol/View\";\nimport { unByKey } from \"ol/Observable\";\nimport { Projection, getPointResolution } from \"ol/proj\";\nimport { Coordinate } from \"ol/coordinate\";\nimport { EventsKey } from \"ol/events\";\nimport { useCallback, useMemo, useSyncExternalStore } from \"react\";\n\n/**\n * From Web Map Server Implementation Specification -> 7.2.4.6.9 Scale denominators\n *\n * For the purposes of this International Standard, the common pixel size is defined to be 0,28 mm × 0,28 mm.\n * Because arbitrary clients can request maps from a server, the true pixel size of the final rendering device is\n * unknown to the server.\n */\nconst DEFAULT_DPI = 25.4 / 0.28;\nconst INCHES_PER_METRE = 39.37;\n\n/**\n * Returns the current view of the given map.\n *\n * @deprecated Use `mapModel.olView` instead.\n */\nexport function useView(map: OlMap | undefined): OlView | undefined {\n return useOlProperty(map, getView, watchView);\n}\n\nfunction getView(map: OlMap) {\n return map.getView();\n}\n\nfunction watchView(map: OlMap, cb: Callback) {\n return map.on(\"change:view\", cb);\n}\n\n/**\n * Returns the current projection of the map.\n *\n * @deprecated Use `mapModel.projection` instead.\n */\nexport function useProjection(map: OlMap | undefined): Projection | undefined {\n const view = useView(map);\n return view?.getProjection();\n}\n\n/**\n * Returns the current resolution of the map.\n *\n * @deprecated Use `mapModel.resolution` instead.\n */\nexport function useResolution(map: OlMap | undefined): number | undefined {\n const view = useView(map);\n return useOlProperty(view, getResolution, watchResolution);\n}\n\nfunction getResolution(view: OlView): number | undefined {\n return view.getResolution();\n}\n\nfunction watchResolution(view: OlView, cb: Callback) {\n return view.on(\"change:resolution\", cb);\n}\n\n/**\n * Returns the current center coordinates of the map.\n *\n * @deprecated Use `mapModel.center` instead.\n */\nexport function useCenter(map: OlMap | undefined): Coordinate | undefined {\n const view = useView(map);\n return useOlProperty(view, getCenter, watchCenter);\n}\n\nfunction getCenter(view: OlView): Coordinate | undefined {\n return view.getCenter();\n}\n\nfunction watchCenter(view: OlView, cb: Callback) {\n return view.on(\"change:center\", cb);\n}\n\n/**\n * Returns the current scale of the map.\n *\n * @deprecated Use `mapModel.scale` instead.\n */\nexport function useScale(map: OlMap | undefined): number | undefined {\n const center = useCenter(map);\n const resolution = useResolution(map);\n const projection = useProjection(map);\n const scale = useMemo(() => {\n if (projection == null || resolution == null || center == null) {\n return undefined;\n }\n\n /**\n * Returns the appropriate scale for the given resolution and units, see OpenLayers function getScaleForResolution()\n * https://github.com/openlayers/openlayers/blob/7fa9df03431e9e1bc517e6c414565d9f848a3132/src/ol/control/ScaleLine.js#L454C3-L454C24\n */\n const pointResolution = getPointResolution(projection, resolution, center);\n const scale = Math.round(pointResolution * INCHES_PER_METRE * DEFAULT_DPI);\n return scale;\n }, [projection, resolution, center]);\n return scale;\n}\n\ntype Callback = () => void;\n\n/**\n * Returns the value of an observable ol property.\n *\n * Make sure to keep `accessor` and `watcher` stable to reduce re-subscriptions:\n * either use global functions or wrap the functions into `useCallback`.\n */\nfunction useOlProperty<T, R>(\n object: T | undefined,\n accessor: (object: T) => R,\n watcher: (object: T, cb: Callback) => EventsKey\n): R | undefined {\n const getSnapshot = useCallback(\n () => (object ? accessor(object) : undefined),\n [object, accessor]\n );\n const subscribe = useCallback(\n (cb: Callback) => {\n if (!object) {\n return () => undefined;\n }\n\n const key = watcher(object, cb);\n return () => unByKey(key);\n },\n [object, watcher]\n );\n return useSyncExternalStore(subscribe, getSnapshot);\n}\n"],"names":["scale"],"mappings":"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"}
1
+ {"version":3,"file":"hooks.js","sources":["hooks.ts"],"sourcesContent":["// SPDX-FileCopyrightText: 2023-2025 Open Pioneer project (https://github.com/open-pioneer)\n// SPDX-License-Identifier: Apache-2.0\nimport OlMap from \"ol/Map\";\nimport OlView from \"ol/View\";\nimport { unByKey } from \"ol/Observable\";\nimport { Projection, getPointResolution } from \"ol/proj\";\nimport { Coordinate } from \"ol/coordinate\";\nimport { EventsKey } from \"ol/events\";\nimport { useCallback, useMemo, useSyncExternalStore } from \"react\";\n\n/**\n * From Web Map Server Implementation Specification -> 7.2.4.6.9 Scale denominators\n *\n * For the purposes of this International Standard, the common pixel size is defined to be 0,28 mm × 0,28 mm.\n * Because arbitrary clients can request maps from a server, the true pixel size of the final rendering device is\n * unknown to the server.\n */\nconst DEFAULT_DPI = 25.4 / 0.28;\nconst INCHES_PER_METRE = 39.37;\n\n/**\n * Returns the current view of the given map.\n *\n * @deprecated Use `mapModel.olView` instead.\n */\nexport function useView(map: OlMap | undefined): OlView | undefined {\n return useOlProperty(map, getView, watchView);\n}\n\nfunction getView(map: OlMap) {\n return map.getView();\n}\n\nfunction watchView(map: OlMap, cb: Callback) {\n return map.on(\"change:view\", cb);\n}\n\n/**\n * Returns the current projection of the map.\n *\n * @deprecated Use `mapModel.projection` instead.\n */\nexport function useProjection(map: OlMap | undefined): Projection | undefined {\n const view = useView(map);\n return view?.getProjection();\n}\n\n/**\n * Returns the current resolution of the map.\n *\n * @deprecated Use `mapModel.resolution` instead.\n */\nexport function useResolution(map: OlMap | undefined): number | undefined {\n const view = useView(map);\n return useOlProperty(view, getResolution, watchResolution);\n}\n\nfunction getResolution(view: OlView): number | undefined {\n return view.getResolution();\n}\n\nfunction watchResolution(view: OlView, cb: Callback) {\n return view.on(\"change:resolution\", cb);\n}\n\n/**\n * Returns the current center coordinates of the map.\n *\n * @deprecated Use `mapModel.center` instead.\n */\nexport function useCenter(map: OlMap | undefined): Coordinate | undefined {\n const view = useView(map);\n return useOlProperty(view, getCenter, watchCenter);\n}\n\nfunction getCenter(view: OlView): Coordinate | undefined {\n return view.getCenter();\n}\n\nfunction watchCenter(view: OlView, cb: Callback) {\n return view.on(\"change:center\", cb);\n}\n\n/**\n * Returns the current scale of the map.\n *\n * @deprecated Use `mapModel.scale` instead.\n */\nexport function useScale(map: OlMap | undefined): number | undefined {\n const center = useCenter(map);\n const resolution = useResolution(map);\n const projection = useProjection(map);\n const scale = useMemo(() => {\n if (projection == null || resolution == null || center == null) {\n return undefined;\n }\n\n /**\n * Returns the appropriate scale for the given resolution and units, see OpenLayers function getScaleForResolution()\n * https://github.com/openlayers/openlayers/blob/7fa9df03431e9e1bc517e6c414565d9f848a3132/src/ol/control/ScaleLine.js#L454C3-L454C24\n */\n const pointResolution = getPointResolution(projection, resolution, center, \"m\"); //point resolution in meter per pixel\n const scale = Math.round(pointResolution * INCHES_PER_METRE * DEFAULT_DPI);\n return scale;\n }, [projection, resolution, center]);\n return scale;\n}\n\ntype Callback = () => void;\n\n/**\n * Returns the value of an observable ol property.\n *\n * Make sure to keep `accessor` and `watcher` stable to reduce re-subscriptions:\n * either use global functions or wrap the functions into `useCallback`.\n */\nfunction useOlProperty<T, R>(\n object: T | undefined,\n accessor: (object: T) => R,\n watcher: (object: T, cb: Callback) => EventsKey\n): R | undefined {\n const getSnapshot = useCallback(\n () => (object ? accessor(object) : undefined),\n [object, accessor]\n );\n const subscribe = useCallback(\n (cb: Callback) => {\n if (!object) {\n return () => undefined;\n }\n\n const key = watcher(object, cb);\n return () => unByKey(key);\n },\n [object, watcher]\n );\n return useSyncExternalStore(subscribe, getSnapshot);\n}\n"],"names":["scale"],"mappings":"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"}