@open-pioneer/geolocation 0.4.2 → 0.4.4

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,5 +1,28 @@
1
1
  # @open-pioneer/geolocation
2
2
 
3
+ ## 0.4.4
4
+
5
+ ### Patch Changes
6
+
7
+ - 3e7d978: Refactor implementation (internal state management now based on the reactivity API)
8
+ - b152428: Update trails dependencies
9
+ - Updated dependencies [b152428]
10
+ - Updated dependencies [291ccb6]
11
+ - @open-pioneer/map-ui-components@0.1.1
12
+ - @open-pioneer/map@0.6.1
13
+
14
+ ## 0.4.3
15
+
16
+ ### Patch Changes
17
+
18
+ - 28e092a: Update dependencies
19
+ - Updated dependencies [28e092a]
20
+ - Updated dependencies [0d51d2f]
21
+ - Updated dependencies [2090e72]
22
+ - Updated dependencies [76f8863]
23
+ - @open-pioneer/map-ui-components@0.1.0
24
+ - @open-pioneer/map@0.6.0
25
+
3
26
  ## 0.4.2
4
27
 
5
28
  ### Patch Changes
package/Geolocation.js CHANGED
@@ -1,6 +1,8 @@
1
1
  import { jsx } from 'react/jsx-runtime';
2
2
  import { useMapModel } from '@open-pioneer/map';
3
- import { useCommonComponentProps, ToolButton } from '@open-pioneer/react-utils';
3
+ import { ToolButton } from '@open-pioneer/map-ui-components';
4
+ import { useCommonComponentProps } from '@open-pioneer/react-utils';
5
+ import { useReactiveSnapshot } from '@open-pioneer/reactivity';
4
6
  import { useIntl, useService } from './_virtual/_virtual-pioneer-module_react-hooks.js';
5
7
  import { forwardRef, useState, useEffect } from 'react';
6
8
  import { MdMyLocation } from 'react-icons/md';
@@ -8,13 +10,7 @@ import { GeolocationController } from './GeolocationController.js';
8
10
 
9
11
  const Geolocation = forwardRef(function Geolocation2(props, ref) {
10
12
  const { mapId, maxZoom, positionFeatureStyle, accuracyFeatureStyle, trackingOptions } = props;
11
- const { containerProps } = useCommonComponentProps("geolocation", props);
12
- const supportsGeolocation = !!navigator.geolocation;
13
- const [isActive, setActive] = useState(false);
14
- const [isLoading, setLoading] = useState(false);
15
13
  const { map } = useMapModel(mapId);
16
- const intl = useIntl();
17
- const notificationService = useService("notifier.NotificationService");
18
14
  const controller = useController(
19
15
  map,
20
16
  maxZoom,
@@ -22,8 +18,20 @@ const Geolocation = forwardRef(function Geolocation2(props, ref) {
22
18
  positionFeatureStyle,
23
19
  accuracyFeatureStyle
24
20
  );
21
+ return controller && /* @__PURE__ */ jsx(GeolocationImpl, { ...props, controller, ref });
22
+ });
23
+ const GeolocationImpl = forwardRef(function GeolocationImpl2(props, ref) {
24
+ const { controller } = props;
25
+ const { containerProps } = useCommonComponentProps("geolocation", props);
26
+ const { isLoading, isActive } = useReactiveSnapshot(() => {
27
+ return {
28
+ isLoading: controller.loading,
29
+ isActive: controller.active
30
+ };
31
+ }, [controller]);
32
+ const intl = useIntl();
25
33
  const label = (() => {
26
- if (!supportsGeolocation) {
34
+ if (!controller.supported) {
27
35
  return intl.formatMessage({ id: "locateNotSupported" });
28
36
  }
29
37
  if (isActive) {
@@ -32,57 +40,12 @@ const Geolocation = forwardRef(function Geolocation2(props, ref) {
32
40
  return intl.formatMessage({ id: "locateMeStart" });
33
41
  }
34
42
  })();
35
- useEffect(() => {
36
- if (controller === void 0) {
37
- return;
38
- }
39
- const eventsKey = controller.on("error", function(error) {
40
- const title = intl.formatMessage({ id: "error" });
41
- const description = (() => {
42
- switch (error) {
43
- case "permission-denied":
44
- return intl.formatMessage({ id: "permissionDenied" });
45
- case "position-unavailable":
46
- return intl.formatMessage({ id: "positionUnavailable" });
47
- case "timeout":
48
- return intl.formatMessage({ id: "timeout" });
49
- case "unknown":
50
- return intl.formatMessage({ id: "unknownError" });
51
- }
52
- })();
53
- setLoading(false);
54
- setActive(false);
55
- notificationService.notify({
56
- level: "error",
57
- title,
58
- message: description
59
- });
60
- });
61
- return () => {
62
- eventsKey.destroy();
63
- };
64
- }, [controller, intl, notificationService]);
65
- useEffect(() => {
66
- if (!controller) {
67
- setLoading(false);
68
- return;
69
- }
70
- if (isActive) {
71
- setLoading(true);
72
- controller.startGeolocation().then(() => {
73
- setLoading(false);
74
- });
75
- }
76
- return () => {
77
- controller?.stopGeolocation();
78
- setLoading(false);
79
- };
80
- }, [controller, isActive]);
81
43
  const toggleActiveState = () => {
82
- if (!map) {
83
- return;
44
+ if (controller.active) {
45
+ controller.stopGeolocation();
46
+ } else {
47
+ controller.startGeolocation();
84
48
  }
85
- setActive(!isActive);
86
49
  };
87
50
  return /* @__PURE__ */ jsx(
88
51
  ToolButton,
@@ -93,24 +56,50 @@ const Geolocation = forwardRef(function Geolocation2(props, ref) {
93
56
  onClick: () => toggleActiveState(),
94
57
  isActive,
95
58
  isLoading,
96
- isDisabled: !supportsGeolocation,
59
+ isDisabled: !controller.supported,
97
60
  ...containerProps
98
61
  }
99
62
  );
100
63
  });
101
64
  function useController(map, maxZoom, trackingOptions, positionFeatureStyle, accuracyFeatureStyle) {
65
+ const intl = useIntl();
66
+ const notificationService = useService("notifier.NotificationService");
102
67
  const [controller, setController] = useState();
103
68
  useEffect(() => {
104
69
  if (!map) {
105
70
  return;
106
71
  }
107
- const geolocationController = new GeolocationController(map.olMap, trackingOptions);
72
+ const onError = (error) => {
73
+ const title = intl.formatMessage({ id: "error" });
74
+ const description = (() => {
75
+ switch (error) {
76
+ case "permission-denied":
77
+ return intl.formatMessage({ id: "permissionDenied" });
78
+ case "position-unavailable":
79
+ return intl.formatMessage({ id: "positionUnavailable" });
80
+ case "timeout":
81
+ return intl.formatMessage({ id: "timeout" });
82
+ case "unknown":
83
+ return intl.formatMessage({ id: "unknownError" });
84
+ }
85
+ })();
86
+ notificationService.notify({
87
+ level: "error",
88
+ title,
89
+ message: description
90
+ });
91
+ };
92
+ const geolocationController = new GeolocationController(
93
+ map.olMap,
94
+ onError,
95
+ trackingOptions
96
+ );
108
97
  setController(geolocationController);
109
98
  return () => {
110
99
  geolocationController.destroy();
111
100
  setController(void 0);
112
101
  };
113
- }, [map, trackingOptions]);
102
+ }, [map, trackingOptions, intl, notificationService]);
114
103
  useEffect(() => {
115
104
  controller?.setPositionFeatureStyle(positionFeatureStyle);
116
105
  }, [controller, positionFeatureStyle]);
@@ -1 +1 @@
1
- {"version":3,"file":"Geolocation.js","sources":["Geolocation.tsx"],"sourcesContent":["// SPDX-FileCopyrightText: 2023 Open Pioneer project (https://github.com/open-pioneer)\n// SPDX-License-Identifier: Apache-2.0\nimport { MapModel, useMapModel } from \"@open-pioneer/map\";\nimport { NotificationService } from \"@open-pioneer/notifier\";\nimport {\n CommonComponentProps,\n ToolButton,\n useCommonComponentProps\n} from \"@open-pioneer/react-utils\";\nimport { StyleLike } from \"ol/style/Style\";\nimport { useIntl, useService } from \"open-pioneer:react-hooks\";\nimport { FC, ForwardedRef, RefAttributes, forwardRef, useEffect, useState } from \"react\";\nimport { MdMyLocation } from \"react-icons/md\";\nimport { GeolocationController } from \"./GeolocationController\";\n\n/**\n * These are properties supported by the {@link Geolocation} component.\n */\nexport interface GeolocationProps extends CommonComponentProps, RefAttributes<HTMLButtonElement> {\n /**\n * The id of the map.\n */\n mapId: string;\n /**\n * The default maximal zoom level\n */\n maxZoom?: number;\n /**\n * Style to be applied for the positioning highlight feature.\n */\n positionFeatureStyle?: StyleLike;\n /**\n * Style to be applied for the accuracy highlight of the positioning feature.\n */\n accuracyFeatureStyle?: StyleLike;\n /**\n * Position options for the Geolocation-Object.\n * See [PositionOptions](https://www.w3.org/TR/geolocation/#position_options_interface) for more details.\n *\n * NOTE: Changing the tracking options at runtime will reset the component's state.\n */\n trackingOptions?: PositionOptions;\n}\n\nexport const Geolocation: FC<GeolocationProps> = forwardRef(function Geolocation(\n props: GeolocationProps,\n ref: ForwardedRef<HTMLButtonElement>\n) {\n const { mapId, maxZoom, positionFeatureStyle, accuracyFeatureStyle, trackingOptions } = props;\n const { containerProps } = useCommonComponentProps(\"geolocation\", props);\n\n const supportsGeolocation = !!navigator.geolocation;\n const [isActive, setActive] = useState<boolean>(false);\n const [isLoading, setLoading] = useState<boolean>(false);\n const { map } = useMapModel(mapId);\n const intl = useIntl();\n const notificationService = useService<NotificationService>(\"notifier.NotificationService\");\n\n const controller = useController(\n map,\n maxZoom,\n trackingOptions,\n positionFeatureStyle,\n accuracyFeatureStyle\n );\n\n const label = (() => {\n if (!supportsGeolocation) {\n return intl.formatMessage({ id: \"locateNotSupported\" });\n }\n\n if (isActive) {\n return intl.formatMessage({ id: \"locateMeEnd\" });\n } else {\n return intl.formatMessage({ id: \"locateMeStart\" });\n }\n })();\n\n useEffect(() => {\n if (controller === undefined) {\n return;\n }\n\n const eventsKey = controller.on(\"error\", function (error) {\n const title = intl.formatMessage({ id: \"error\" });\n const description = (() => {\n switch (error) {\n case \"permission-denied\":\n return intl.formatMessage({ id: \"permissionDenied\" });\n case \"position-unavailable\":\n return intl.formatMessage({ id: \"positionUnavailable\" });\n case \"timeout\":\n return intl.formatMessage({ id: \"timeout\" });\n case \"unknown\":\n return intl.formatMessage({ id: \"unknownError\" });\n }\n })();\n\n setLoading(false);\n setActive(false);\n\n notificationService.notify({\n level: \"error\",\n title: title,\n message: description\n });\n });\n return () => {\n eventsKey.destroy();\n };\n }, [controller, intl, notificationService]);\n\n useEffect(() => {\n if (!controller) {\n setLoading(false);\n return;\n }\n if (isActive) {\n setLoading(true);\n controller.startGeolocation().then(() => {\n setLoading(false);\n });\n }\n return () => {\n controller?.stopGeolocation();\n setLoading(false);\n };\n }, [controller, isActive]);\n\n const toggleActiveState = () => {\n if (!map) {\n return;\n }\n setActive(!isActive);\n };\n\n return (\n <ToolButton\n ref={ref}\n label={label}\n icon={<MdMyLocation />}\n onClick={() => toggleActiveState()}\n isActive={isActive}\n isLoading={isLoading}\n isDisabled={!supportsGeolocation}\n {...containerProps}\n />\n );\n});\n\nfunction useController(\n map: MapModel | undefined,\n maxZoom: number | undefined,\n trackingOptions: PositionOptions | undefined,\n positionFeatureStyle: StyleLike | undefined,\n accuracyFeatureStyle: StyleLike | undefined\n): GeolocationController | undefined {\n const [controller, setController] = useState<GeolocationController>();\n useEffect(() => {\n if (!map) {\n return;\n }\n const geolocationController = new GeolocationController(map.olMap, trackingOptions);\n setController(geolocationController);\n\n return () => {\n geolocationController.destroy();\n setController(undefined);\n };\n }, [map, trackingOptions]);\n useEffect(() => {\n controller?.setPositionFeatureStyle(positionFeatureStyle);\n }, [controller, positionFeatureStyle]);\n useEffect(() => {\n controller?.setAccuracyFeatureStyle(accuracyFeatureStyle);\n }, [controller, accuracyFeatureStyle]);\n useEffect(() => {\n controller?.setMaxZoom(maxZoom);\n }, [controller, maxZoom]);\n return controller;\n}\n"],"names":["Geolocation"],"mappings":"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"}
1
+ {"version":3,"file":"Geolocation.js","sources":["Geolocation.tsx"],"sourcesContent":["// SPDX-FileCopyrightText: 2023 Open Pioneer project (https://github.com/open-pioneer)\n// SPDX-License-Identifier: Apache-2.0\nimport { MapModel, useMapModel } from \"@open-pioneer/map\";\nimport { ToolButton } from \"@open-pioneer/map-ui-components\";\nimport { NotificationService } from \"@open-pioneer/notifier\";\nimport { CommonComponentProps, useCommonComponentProps } from \"@open-pioneer/react-utils\";\nimport { useReactiveSnapshot } from \"@open-pioneer/reactivity\";\nimport { StyleLike } from \"ol/style/Style\";\nimport { useIntl, useService } from \"open-pioneer:react-hooks\";\nimport { FC, ForwardedRef, RefAttributes, forwardRef, useEffect, useState } from \"react\";\nimport { MdMyLocation } from \"react-icons/md\";\nimport { GeolocationController, OnErrorCallback } from \"./GeolocationController\";\n\n/**\n * These are properties supported by the {@link Geolocation} component.\n */\nexport interface GeolocationProps extends CommonComponentProps, RefAttributes<HTMLButtonElement> {\n /**\n * The id of the map.\n */\n mapId: string;\n /**\n * The default maximal zoom level\n */\n maxZoom?: number;\n /**\n * Style to be applied for the positioning highlight feature.\n */\n positionFeatureStyle?: StyleLike;\n /**\n * Style to be applied for the accuracy highlight of the positioning feature.\n */\n accuracyFeatureStyle?: StyleLike;\n /**\n * Position options for the Geolocation-Object.\n * See [PositionOptions](https://www.w3.org/TR/geolocation/#position_options_interface) for more details.\n *\n * NOTE: Changing the tracking options at runtime will reset the component's state.\n */\n trackingOptions?: PositionOptions;\n}\n\nexport const Geolocation: FC<GeolocationProps> = forwardRef(function Geolocation(\n props: GeolocationProps,\n ref: ForwardedRef<HTMLButtonElement>\n) {\n const { mapId, maxZoom, positionFeatureStyle, accuracyFeatureStyle, trackingOptions } = props;\n const { map } = useMapModel(mapId);\n const controller = useController(\n map,\n maxZoom,\n trackingOptions,\n positionFeatureStyle,\n accuracyFeatureStyle\n );\n return controller && <GeolocationImpl {...props} controller={controller} ref={ref} />;\n});\n\n// This is a separate component so we can act like the controller is always present.\n// This is the case in practice (except for the initial loading phase where the component is not-yet-mounted).\nconst GeolocationImpl = forwardRef(function GeolocationImpl(\n props: GeolocationProps & { controller: GeolocationController },\n ref: ForwardedRef<HTMLButtonElement>\n) {\n const { controller } = props;\n const { containerProps } = useCommonComponentProps(\"geolocation\", props);\n const { isLoading, isActive } = useReactiveSnapshot(() => {\n return {\n isLoading: controller.loading,\n isActive: controller.active\n };\n }, [controller]);\n\n const intl = useIntl();\n const label = (() => {\n if (!controller.supported) {\n return intl.formatMessage({ id: \"locateNotSupported\" });\n }\n\n if (isActive) {\n return intl.formatMessage({ id: \"locateMeEnd\" });\n } else {\n return intl.formatMessage({ id: \"locateMeStart\" });\n }\n })();\n\n const toggleActiveState = () => {\n if (controller.active) {\n controller.stopGeolocation();\n } else {\n controller.startGeolocation();\n }\n };\n\n return (\n <ToolButton\n ref={ref}\n label={label}\n icon={<MdMyLocation />}\n onClick={() => toggleActiveState()}\n isActive={isActive}\n isLoading={isLoading}\n isDisabled={!controller.supported}\n {...containerProps}\n />\n );\n});\n\nfunction useController(\n map: MapModel | undefined,\n maxZoom: number | undefined,\n trackingOptions: PositionOptions | undefined,\n positionFeatureStyle: StyleLike | undefined,\n accuracyFeatureStyle: StyleLike | undefined\n): GeolocationController | undefined {\n const intl = useIntl();\n const notificationService = useService<NotificationService>(\"notifier.NotificationService\");\n const [controller, setController] = useState<GeolocationController>();\n useEffect(() => {\n if (!map) {\n return;\n }\n\n const onError: OnErrorCallback = (error) => {\n const title = intl.formatMessage({ id: \"error\" });\n const description = (() => {\n switch (error) {\n case \"permission-denied\":\n return intl.formatMessage({ id: \"permissionDenied\" });\n case \"position-unavailable\":\n return intl.formatMessage({ id: \"positionUnavailable\" });\n case \"timeout\":\n return intl.formatMessage({ id: \"timeout\" });\n case \"unknown\":\n return intl.formatMessage({ id: \"unknownError\" });\n }\n })();\n\n notificationService.notify({\n level: \"error\",\n title: title,\n message: description\n });\n };\n\n const geolocationController = new GeolocationController(\n map.olMap,\n onError,\n trackingOptions\n );\n setController(geolocationController);\n\n return () => {\n geolocationController.destroy();\n setController(undefined);\n };\n }, [map, trackingOptions, intl, notificationService]);\n useEffect(() => {\n controller?.setPositionFeatureStyle(positionFeatureStyle);\n }, [controller, positionFeatureStyle]);\n useEffect(() => {\n controller?.setAccuracyFeatureStyle(accuracyFeatureStyle);\n }, [controller, accuracyFeatureStyle]);\n useEffect(() => {\n controller?.setMaxZoom(maxZoom);\n }, [controller, maxZoom]);\n return controller;\n}\n"],"names":["Geolocation","GeolocationImpl"],"mappings":"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"}
@@ -1,35 +1,42 @@
1
- import { EventEmitter } from "@open-pioneer/core";
2
1
  import Feature from "ol/Feature";
3
2
  import olGeolocation from "ol/Geolocation";
4
3
  import OlMap from "ol/Map";
5
4
  import { Style } from "ol/style";
6
5
  import { StyleLike } from "ol/style/Style";
7
- type ErrorEvent = "permission-denied" | "position-unavailable" | "timeout" | "unknown";
8
- interface Events {
9
- error: ErrorEvent;
10
- }
11
- export declare class GeolocationController extends EventEmitter<Events> {
6
+ export type ErrorEvent = "permission-denied" | "position-unavailable" | "timeout" | "unknown";
7
+ export type OnErrorCallback = (errorEvent: ErrorEvent) => void;
8
+ export declare class GeolocationController {
9
+ #private;
10
+ /** True if location tracking is supported by the browser. */
11
+ readonly supported = true;
12
12
  private readonly olMap;
13
13
  private readonly positionHighlightLayer;
14
14
  private readonly geolocation;
15
+ private readonly onError;
15
16
  private maxZoom;
16
17
  private accuracyFeature;
17
18
  private positionFeature;
18
19
  private changeHandlers;
19
- private isCurrentlyActive;
20
20
  private setMapToPosition;
21
21
  private trackingOptions;
22
22
  private isInitialZoom;
23
- constructor(olMap: OlMap, trackingOptions?: PositionOptions);
23
+ constructor(olMap: OlMap, onError: OnErrorCallback, trackingOptions?: PositionOptions);
24
24
  destroy(): void;
25
- startGeolocation(): Promise<void>;
25
+ startGeolocation(): void;
26
26
  stopGeolocation(): void;
27
+ /** True if the position is being tracked. */
28
+ get active(): boolean;
29
+ /**
30
+ * True if loading (active but no position available yet).
31
+ * Use this to show a progress indicator.
32
+ */
33
+ get loading(): boolean;
27
34
  setPositionFeatureStyle(styleLike: StyleLike | undefined): void;
28
35
  setAccuracyFeatureStyle(styleLike: StyleLike | undefined): void;
29
36
  setMaxZoom(maxZoom: number | undefined): void;
30
37
  getMaxZoom(): number;
31
- getPositionFeature(): Feature<import("ol/geom/Geometry").default> | undefined;
32
- getAccuracyFeature(): Feature<import("ol/geom/Geometry").default> | undefined;
38
+ getPositionFeature(): Feature<import("ol/geom").Geometry> | undefined;
39
+ getAccuracyFeature(): Feature<import("ol/geom").Geometry> | undefined;
33
40
  getTrackingOptions(): PositionOptions;
34
41
  getGeolocation(): olGeolocation;
35
42
  private handleGeolocationError;
@@ -37,4 +44,3 @@ export declare class GeolocationController extends EventEmitter<Events> {
37
44
  export declare const getDefaultPositionStyle: () => Style;
38
45
  export declare const getDefaultAccuracyStyle: () => Style;
39
46
  export declare const getDefaultTrackingOptions: () => PositionOptions;
40
- export {};
@@ -1,30 +1,35 @@
1
- import { createLogger, EventEmitter } from '@open-pioneer/core';
1
+ import { reactive } from '@conterra/reactivity-core';
2
+ import { createLogger } from '@open-pioneer/core';
2
3
  import { TOPMOST_LAYER_Z, calculateBufferedExtent } from '@open-pioneer/map';
3
- import Feature from 'ol/Feature';
4
- import olGeolocation from 'ol/Geolocation';
5
- import { unByKey } from 'ol/Observable';
6
- import Point from 'ol/geom/Point';
7
- import VectorLayer from 'ol/layer/Vector';
8
- import VectorSource from 'ol/source/Vector';
9
- import { Style, Circle, Fill, Stroke } from 'ol/style';
4
+ import Feature from 'ol/Feature.js';
5
+ import olGeolocation from 'ol/Geolocation.js';
6
+ import { unByKey } from 'ol/Observable.js';
7
+ import Point from 'ol/geom/Point.js';
8
+ import VectorLayer from 'ol/layer/Vector.js';
9
+ import VectorSource from 'ol/source/Vector.js';
10
+ import { Style, Circle, Fill, Stroke } from 'ol/style.js';
10
11
 
11
12
  const LOG = createLogger("geolocation:GeolocationController");
12
13
  const DEFAULT_MAX_ZOOM = 17;
13
- class GeolocationController extends EventEmitter {
14
+ class GeolocationController {
15
+ /** True if location tracking is supported by the browser. */
16
+ supported = !!navigator.geolocation;
14
17
  olMap;
15
18
  positionHighlightLayer;
16
19
  geolocation;
20
+ onError;
17
21
  maxZoom = DEFAULT_MAX_ZOOM;
18
22
  accuracyFeature;
19
23
  positionFeature;
20
24
  changeHandlers = [];
21
- isCurrentlyActive = false;
22
25
  setMapToPosition = true;
23
26
  trackingOptions = {};
24
27
  isInitialZoom = true;
25
- constructor(olMap, trackingOptions) {
26
- super();
28
+ #loading = reactive(false);
29
+ #active = reactive(false);
30
+ constructor(olMap, onError, trackingOptions) {
27
31
  this.olMap = olMap;
32
+ this.onError = onError;
28
33
  this.isInitialZoom = true;
29
34
  this.accuracyFeature = new Feature();
30
35
  this.accuracyFeature.setStyle(getDefaultAccuracyStyle());
@@ -54,12 +59,13 @@ class GeolocationController extends EventEmitter {
54
59
  this.positionHighlightLayer.dispose();
55
60
  }
56
61
  startGeolocation() {
57
- if (this.isCurrentlyActive) {
58
- return Promise.resolve();
62
+ if (this.#active.value) {
63
+ return;
59
64
  }
60
65
  const olMap = this.olMap;
61
66
  const geolocationPromise = new Promise((resolve) => {
62
- this.isCurrentlyActive = true;
67
+ this.#active.value = true;
68
+ this.#loading.value = true;
63
69
  this.geolocation?.setProjection(olMap.getView()?.getProjection());
64
70
  this.geolocation?.setTracking(true);
65
71
  const accuracyChangeHandler = this.geolocation.on(
@@ -113,13 +119,16 @@ class GeolocationController extends EventEmitter {
113
119
  );
114
120
  olMap.addLayer(this.positionHighlightLayer);
115
121
  });
116
- return geolocationPromise.catch((error) => {
122
+ geolocationPromise.then(() => {
123
+ this.#loading.value = false;
124
+ }).catch((error) => {
117
125
  LOG.error("Failed to determine location", error);
118
126
  });
119
127
  }
120
128
  stopGeolocation() {
121
129
  this.geolocation?.setTracking(false);
122
- this.isCurrentlyActive = false;
130
+ this.#active.value = false;
131
+ this.#loading.value = false;
123
132
  this.trackingOptions = {};
124
133
  this.setMapToPosition = true;
125
134
  this.isInitialZoom = true;
@@ -131,6 +140,17 @@ class GeolocationController extends EventEmitter {
131
140
  this.positionFeature?.setGeometry(void 0);
132
141
  this.olMap.removeLayer(this.positionHighlightLayer);
133
142
  }
143
+ /** True if the position is being tracked. */
144
+ get active() {
145
+ return this.#active.value;
146
+ }
147
+ /**
148
+ * True if loading (active but no position available yet).
149
+ * Use this to show a progress indicator.
150
+ */
151
+ get loading() {
152
+ return this.#loading.value;
153
+ }
134
154
  setPositionFeatureStyle(styleLike) {
135
155
  this.positionFeature?.setStyle(styleLike ?? getDefaultPositionStyle());
136
156
  }
@@ -157,6 +177,7 @@ class GeolocationController extends EventEmitter {
157
177
  }
158
178
  handleGeolocationError(event) {
159
179
  LOG.error("Error from geolocation API:", event.message);
180
+ this.stopGeolocation();
160
181
  const error = (() => {
161
182
  switch (event.code) {
162
183
  case 1:
@@ -169,7 +190,7 @@ class GeolocationController extends EventEmitter {
169
190
  return "unknown";
170
191
  }
171
192
  })();
172
- this.emit("error", error);
193
+ this.onError(error);
173
194
  }
174
195
  }
175
196
  const getDefaultPositionStyle = () => {
@@ -1 +1 @@
1
- {"version":3,"file":"GeolocationController.js","sources":["GeolocationController.ts"],"sourcesContent":["// SPDX-FileCopyrightText: 2023 Open Pioneer project (https://github.com/open-pioneer)\n// SPDX-License-Identifier: Apache-2.0\nimport { EventEmitter, createLogger } from \"@open-pioneer/core\";\nimport { TOPMOST_LAYER_Z, calculateBufferedExtent } from \"@open-pioneer/map\";\nimport Feature from \"ol/Feature\";\nimport olGeolocation, { GeolocationError } from \"ol/Geolocation\";\nimport OlMap from \"ol/Map\";\nimport { unByKey } from \"ol/Observable\";\nimport { Coordinate } from \"ol/coordinate\";\nimport type { EventsKey } from \"ol/events\";\nimport { Extent } from \"ol/extent\";\nimport { Polygon } from \"ol/geom\";\nimport Point from \"ol/geom/Point\";\nimport VectorLayer from \"ol/layer/Vector\";\nimport VectorSource from \"ol/source/Vector\";\nimport { Circle as CircleStyle, Fill, Stroke, Style } from \"ol/style\";\nimport { StyleLike } from \"ol/style/Style\";\n\nconst LOG = createLogger(\"geolocation:GeolocationController\");\nconst DEFAULT_MAX_ZOOM = 17;\n\ntype ErrorEvent = \"permission-denied\" | \"position-unavailable\" | \"timeout\" | \"unknown\";\n\ninterface Events {\n error: ErrorEvent;\n}\n\nexport class GeolocationController extends EventEmitter<Events> {\n private readonly olMap: OlMap;\n private readonly positionHighlightLayer: VectorLayer<VectorSource>;\n private readonly geolocation: olGeolocation;\n private maxZoom: number = DEFAULT_MAX_ZOOM;\n private accuracyFeature: Feature | undefined;\n private positionFeature: Feature | undefined;\n private changeHandlers: EventsKey[] = [];\n private isCurrentlyActive: boolean = false;\n private setMapToPosition: boolean = true;\n private trackingOptions: PositionOptions = {};\n private isInitialZoom: boolean = true;\n\n constructor(olMap: OlMap, trackingOptions?: PositionOptions) {\n super();\n this.olMap = olMap;\n this.isInitialZoom = true;\n\n this.accuracyFeature = new Feature();\n this.accuracyFeature.setStyle(getDefaultAccuracyStyle());\n\n this.positionFeature = new Feature();\n this.positionFeature.setStyle(getDefaultPositionStyle());\n\n this.positionHighlightLayer = new VectorLayer({\n source: new VectorSource({\n features: [this.accuracyFeature, this.positionFeature]\n })\n });\n this.positionHighlightLayer.setZIndex(TOPMOST_LAYER_Z);\n\n const geolocationTrackingOptions: PositionOptions =\n trackingOptions || getDefaultTrackingOptions();\n\n this.geolocation = new olGeolocation({\n tracking: false,\n trackingOptions: geolocationTrackingOptions,\n projection: olMap.getView()?.getProjection()\n });\n\n this.trackingOptions = geolocationTrackingOptions;\n this.geolocation.on(\"error\", (event) => this.handleGeolocationError(event));\n }\n\n destroy() {\n this.stopGeolocation();\n this.geolocation?.setTracking(false);\n this.geolocation.dispose();\n this.accuracyFeature = undefined;\n this.positionFeature = undefined;\n this.positionHighlightLayer.dispose();\n }\n\n startGeolocation(): Promise<void> {\n if (this.isCurrentlyActive) {\n return Promise.resolve();\n }\n\n const olMap = this.olMap;\n const geolocationPromise = new Promise<void>((resolve) => {\n this.isCurrentlyActive = true;\n this.geolocation?.setProjection(olMap.getView()?.getProjection());\n this.geolocation?.setTracking(true);\n\n const accuracyChangeHandler: EventsKey = this.geolocation.on(\n \"change:accuracyGeometry\",\n () => {\n const accuracyGeometry: Polygon | undefined =\n this.geolocation.getAccuracyGeometry() || undefined;\n this.accuracyFeature?.setGeometry(accuracyGeometry);\n if (this.accuracyFeature?.getGeometry() !== undefined) {\n resolve();\n }\n if (this.isInitialZoom) {\n const accuracyGeometryExtent: Extent | undefined = this?.accuracyFeature\n ?.getGeometry()\n ?.getExtent();\n if (accuracyGeometryExtent) {\n const bufferedExtent = calculateBufferedExtent(accuracyGeometryExtent);\n if (!bufferedExtent) {\n return;\n }\n olMap.getView().fit(bufferedExtent, {\n maxZoom: this.maxZoom\n });\n this.isInitialZoom = false;\n }\n }\n }\n );\n\n const positionChangeHandler: EventsKey = this.geolocation.on(\"change:position\", () => {\n const coordinates: Coordinate | undefined = this.geolocation.getPosition();\n if (coordinates && (coordinates[0] || coordinates[1]) !== undefined) {\n this.positionFeature?.setGeometry(new Point(coordinates));\n if (this.setMapToPosition) {\n olMap.getView().setCenter(coordinates);\n }\n if (this.positionFeature?.getGeometry() !== undefined) {\n resolve();\n }\n }\n });\n\n // zoom changes\n const resolutionChangeHandler: EventsKey = olMap\n .getView()\n .on(\"change:resolution\", () => {\n this.setMapToPosition = this.isInitialZoom;\n });\n\n // pointermove is triggered when a pointer is moved.\n // Note that on touch devices this is triggered when the map is panned,\n // so is not the same as mousemove.\n const draggingHandler: EventsKey = olMap.on(\"pointermove\", (evt) => {\n if (evt.dragging) {\n this.setMapToPosition = false;\n }\n });\n\n this.changeHandlers.push(\n accuracyChangeHandler,\n positionChangeHandler,\n resolutionChangeHandler,\n draggingHandler\n );\n\n olMap.addLayer(this.positionHighlightLayer);\n });\n\n return geolocationPromise.catch((error: Error) => {\n LOG.error(\"Failed to determine location\", error);\n });\n }\n\n stopGeolocation() {\n this.geolocation?.setTracking(false);\n this.isCurrentlyActive = false;\n this.trackingOptions = {};\n this.setMapToPosition = true;\n this.isInitialZoom = true;\n\n this.changeHandlers.forEach((handler) => {\n unByKey(handler);\n });\n this.changeHandlers = [];\n this.accuracyFeature?.setGeometry(undefined);\n this.positionFeature?.setGeometry(undefined);\n this.olMap.removeLayer(this.positionHighlightLayer);\n }\n\n setPositionFeatureStyle(styleLike: StyleLike | undefined) {\n this.positionFeature?.setStyle(styleLike ?? getDefaultPositionStyle());\n }\n\n setAccuracyFeatureStyle(styleLike: StyleLike | undefined) {\n this.accuracyFeature?.setStyle(styleLike ?? getDefaultAccuracyStyle());\n }\n\n setMaxZoom(maxZoom: number | undefined) {\n this.maxZoom = maxZoom ?? DEFAULT_MAX_ZOOM;\n }\n\n getMaxZoom() {\n return this.maxZoom;\n }\n\n getPositionFeature() {\n return this.positionFeature;\n }\n\n getAccuracyFeature() {\n return this.accuracyFeature;\n }\n\n getTrackingOptions() {\n return this.trackingOptions;\n }\n\n getGeolocation() {\n return this.geolocation;\n }\n\n private handleGeolocationError(event: GeolocationError) {\n LOG.error(\"Error from geolocation API:\", event.message);\n\n const error: ErrorEvent = (() => {\n switch (event.code) {\n case 1:\n return \"permission-denied\";\n case 2:\n return \"position-unavailable\";\n case 3:\n return \"timeout\";\n default:\n return \"unknown\";\n }\n })();\n this.emit(\"error\", error);\n }\n}\n\nexport const getDefaultPositionStyle = () => {\n return new Style({\n image: new CircleStyle({\n radius: 6,\n fill: new Fill({\n color: \"#3399CC\"\n }),\n stroke: new Stroke({\n color: \"#fff\",\n width: 2\n })\n })\n });\n};\n\nexport const getDefaultAccuracyStyle = () => {\n return new Style({\n stroke: new Stroke({\n color: \"#3399CC\",\n width: 3\n }),\n fill: new Fill({\n color: \"rgba(0, 0, 255, 0.05)\"\n })\n });\n};\n\nexport const getDefaultTrackingOptions = (): PositionOptions => {\n return {\n \"enableHighAccuracy\": true,\n \"timeout\": 60000,\n \"maximumAge\": 600000\n };\n};\n"],"names":["CircleStyle"],"mappings":"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"}
1
+ {"version":3,"file":"GeolocationController.js","sources":["GeolocationController.ts"],"sourcesContent":["// SPDX-FileCopyrightText: 2023 Open Pioneer project (https://github.com/open-pioneer)\n// SPDX-License-Identifier: Apache-2.0\nimport { reactive } from \"@conterra/reactivity-core\";\nimport { createLogger } from \"@open-pioneer/core\";\nimport { TOPMOST_LAYER_Z, calculateBufferedExtent } from \"@open-pioneer/map\";\nimport Feature from \"ol/Feature\";\nimport olGeolocation, { GeolocationError } from \"ol/Geolocation\";\nimport OlMap from \"ol/Map\";\nimport { unByKey } from \"ol/Observable\";\nimport { Coordinate } from \"ol/coordinate\";\nimport type { EventsKey } from \"ol/events\";\nimport { Extent } from \"ol/extent\";\nimport { Polygon } from \"ol/geom\";\nimport Point from \"ol/geom/Point\";\nimport VectorLayer from \"ol/layer/Vector\";\nimport VectorSource from \"ol/source/Vector\";\nimport { Circle as CircleStyle, Fill, Stroke, Style } from \"ol/style\";\nimport { StyleLike } from \"ol/style/Style\";\n\nconst LOG = createLogger(\"geolocation:GeolocationController\");\nconst DEFAULT_MAX_ZOOM = 17;\n\nexport type ErrorEvent = \"permission-denied\" | \"position-unavailable\" | \"timeout\" | \"unknown\";\n\nexport type OnErrorCallback = (errorEvent: ErrorEvent) => void;\n\nexport class GeolocationController {\n /** True if location tracking is supported by the browser. */\n public readonly supported = !!navigator.geolocation;\n\n private readonly olMap: OlMap;\n private readonly positionHighlightLayer: VectorLayer<Feature>;\n private readonly geolocation: olGeolocation;\n private readonly onError: OnErrorCallback;\n\n private maxZoom: number = DEFAULT_MAX_ZOOM;\n private accuracyFeature: Feature | undefined;\n private positionFeature: Feature | undefined;\n private changeHandlers: EventsKey[] = [];\n private setMapToPosition: boolean = true;\n private trackingOptions: PositionOptions = {};\n private isInitialZoom: boolean = true;\n\n #loading = reactive(false);\n #active = reactive(false);\n\n constructor(olMap: OlMap, onError: OnErrorCallback, trackingOptions?: PositionOptions) {\n this.olMap = olMap;\n this.onError = onError;\n this.isInitialZoom = true;\n\n this.accuracyFeature = new Feature();\n this.accuracyFeature.setStyle(getDefaultAccuracyStyle());\n\n this.positionFeature = new Feature();\n this.positionFeature.setStyle(getDefaultPositionStyle());\n\n this.positionHighlightLayer = new VectorLayer({\n source: new VectorSource({\n features: [this.accuracyFeature, this.positionFeature]\n })\n });\n this.positionHighlightLayer.setZIndex(TOPMOST_LAYER_Z);\n\n const geolocationTrackingOptions: PositionOptions =\n trackingOptions || getDefaultTrackingOptions();\n\n this.geolocation = new olGeolocation({\n tracking: false,\n trackingOptions: geolocationTrackingOptions,\n projection: olMap.getView()?.getProjection()\n });\n\n this.trackingOptions = geolocationTrackingOptions;\n this.geolocation.on(\"error\", (event) => this.handleGeolocationError(event));\n }\n\n destroy() {\n this.stopGeolocation();\n this.geolocation?.setTracking(false);\n this.geolocation.dispose();\n this.accuracyFeature = undefined;\n this.positionFeature = undefined;\n this.positionHighlightLayer.dispose();\n }\n\n startGeolocation() {\n if (this.#active.value) {\n return;\n }\n\n const olMap = this.olMap;\n const geolocationPromise = new Promise<void>((resolve) => {\n this.#active.value = true;\n this.#loading.value = true;\n\n this.geolocation?.setProjection(olMap.getView()?.getProjection());\n this.geolocation?.setTracking(true);\n\n const accuracyChangeHandler: EventsKey = this.geolocation.on(\n \"change:accuracyGeometry\",\n () => {\n const accuracyGeometry: Polygon | undefined =\n this.geolocation.getAccuracyGeometry() || undefined;\n this.accuracyFeature?.setGeometry(accuracyGeometry);\n if (this.accuracyFeature?.getGeometry() !== undefined) {\n resolve();\n }\n if (this.isInitialZoom) {\n const accuracyGeometryExtent: Extent | undefined = this?.accuracyFeature\n ?.getGeometry()\n ?.getExtent();\n if (accuracyGeometryExtent) {\n const bufferedExtent = calculateBufferedExtent(accuracyGeometryExtent);\n if (!bufferedExtent) {\n return;\n }\n olMap.getView().fit(bufferedExtent, {\n maxZoom: this.maxZoom\n });\n this.isInitialZoom = false;\n }\n }\n }\n );\n\n const positionChangeHandler: EventsKey = this.geolocation.on(\"change:position\", () => {\n const coordinates: Coordinate | undefined = this.geolocation.getPosition();\n if (coordinates && (coordinates[0] || coordinates[1]) !== undefined) {\n this.positionFeature?.setGeometry(new Point(coordinates));\n if (this.setMapToPosition) {\n olMap.getView().setCenter(coordinates);\n }\n if (this.positionFeature?.getGeometry() !== undefined) {\n resolve();\n }\n }\n });\n\n // zoom changes\n const resolutionChangeHandler: EventsKey = olMap\n .getView()\n .on(\"change:resolution\", () => {\n this.setMapToPosition = this.isInitialZoom;\n });\n\n // pointermove is triggered when a pointer is moved.\n // Note that on touch devices this is triggered when the map is panned,\n // so is not the same as mousemove.\n const draggingHandler: EventsKey = olMap.on(\"pointermove\", (evt) => {\n if (evt.dragging) {\n this.setMapToPosition = false;\n }\n });\n\n this.changeHandlers.push(\n accuracyChangeHandler,\n positionChangeHandler,\n resolutionChangeHandler,\n draggingHandler\n );\n\n olMap.addLayer(this.positionHighlightLayer);\n });\n\n geolocationPromise\n .then(() => {\n // Promise resolves once we have a position\n this.#loading.value = false;\n })\n .catch((error: Error) => {\n LOG.error(\"Failed to determine location\", error);\n });\n }\n\n stopGeolocation() {\n this.geolocation?.setTracking(false);\n this.#active.value = false;\n this.#loading.value = false;\n this.trackingOptions = {};\n this.setMapToPosition = true;\n this.isInitialZoom = true;\n\n this.changeHandlers.forEach((handler) => {\n unByKey(handler);\n });\n this.changeHandlers = [];\n this.accuracyFeature?.setGeometry(undefined);\n this.positionFeature?.setGeometry(undefined);\n this.olMap.removeLayer(this.positionHighlightLayer);\n }\n\n /** True if the position is being tracked. */\n get active(): boolean {\n return this.#active.value;\n }\n\n /**\n * True if loading (active but no position available yet).\n * Use this to show a progress indicator.\n */\n get loading(): boolean {\n return this.#loading.value;\n }\n\n setPositionFeatureStyle(styleLike: StyleLike | undefined) {\n this.positionFeature?.setStyle(styleLike ?? getDefaultPositionStyle());\n }\n\n setAccuracyFeatureStyle(styleLike: StyleLike | undefined) {\n this.accuracyFeature?.setStyle(styleLike ?? getDefaultAccuracyStyle());\n }\n\n setMaxZoom(maxZoom: number | undefined) {\n this.maxZoom = maxZoom ?? DEFAULT_MAX_ZOOM;\n }\n\n getMaxZoom() {\n return this.maxZoom;\n }\n\n getPositionFeature() {\n return this.positionFeature;\n }\n\n getAccuracyFeature() {\n return this.accuracyFeature;\n }\n\n getTrackingOptions() {\n return this.trackingOptions;\n }\n\n getGeolocation() {\n return this.geolocation;\n }\n\n private handleGeolocationError(event: GeolocationError) {\n LOG.error(\"Error from geolocation API:\", event.message);\n\n this.stopGeolocation();\n const error: ErrorEvent = (() => {\n switch (event.code) {\n case 1:\n return \"permission-denied\";\n case 2:\n return \"position-unavailable\";\n case 3:\n return \"timeout\";\n default:\n return \"unknown\";\n }\n })();\n this.onError(error);\n }\n}\n\nexport const getDefaultPositionStyle = () => {\n return new Style({\n image: new CircleStyle({\n radius: 6,\n fill: new Fill({\n color: \"#3399CC\"\n }),\n stroke: new Stroke({\n color: \"#fff\",\n width: 2\n })\n })\n });\n};\n\nexport const getDefaultAccuracyStyle = () => {\n return new Style({\n stroke: new Stroke({\n color: \"#3399CC\",\n width: 3\n }),\n fill: new Fill({\n color: \"rgba(0, 0, 255, 0.05)\"\n })\n });\n};\n\nexport const getDefaultTrackingOptions = (): PositionOptions => {\n return {\n \"enableHighAccuracy\": true,\n \"timeout\": 60000,\n \"maximumAge\": 600000\n };\n};\n"],"names":["CircleStyle"],"mappings":";;;;;;;;;;;AAmBA,MAAM,GAAA,GAAM,aAAa,mCAAmC,CAAA,CAAA;AAC5D,MAAM,gBAAmB,GAAA,EAAA,CAAA;AAMlB,MAAM,qBAAsB,CAAA;AAAA;AAAA,EAEf,SAAA,GAAY,CAAC,CAAC,SAAU,CAAA,WAAA,CAAA;AAAA,EAEvB,KAAA,CAAA;AAAA,EACA,sBAAA,CAAA;AAAA,EACA,WAAA,CAAA;AAAA,EACA,OAAA,CAAA;AAAA,EAET,OAAkB,GAAA,gBAAA,CAAA;AAAA,EAClB,eAAA,CAAA;AAAA,EACA,eAAA,CAAA;AAAA,EACA,iBAA8B,EAAC,CAAA;AAAA,EAC/B,gBAA4B,GAAA,IAAA,CAAA;AAAA,EAC5B,kBAAmC,EAAC,CAAA;AAAA,EACpC,aAAyB,GAAA,IAAA,CAAA;AAAA,EAEjC,QAAA,GAAW,SAAS,KAAK,CAAA,CAAA;AAAA,EACzB,OAAA,GAAU,SAAS,KAAK,CAAA,CAAA;AAAA,EAExB,WAAA,CAAY,KAAc,EAAA,OAAA,EAA0B,eAAmC,EAAA;AACnF,IAAA,IAAA,CAAK,KAAQ,GAAA,KAAA,CAAA;AACb,IAAA,IAAA,CAAK,OAAU,GAAA,OAAA,CAAA;AACf,IAAA,IAAA,CAAK,aAAgB,GAAA,IAAA,CAAA;AAErB,IAAK,IAAA,CAAA,eAAA,GAAkB,IAAI,OAAQ,EAAA,CAAA;AACnC,IAAK,IAAA,CAAA,eAAA,CAAgB,QAAS,CAAA,uBAAA,EAAyB,CAAA,CAAA;AAEvD,IAAK,IAAA,CAAA,eAAA,GAAkB,IAAI,OAAQ,EAAA,CAAA;AACnC,IAAK,IAAA,CAAA,eAAA,CAAgB,QAAS,CAAA,uBAAA,EAAyB,CAAA,CAAA;AAEvD,IAAK,IAAA,CAAA,sBAAA,GAAyB,IAAI,WAAY,CAAA;AAAA,MAC1C,MAAA,EAAQ,IAAI,YAAa,CAAA;AAAA,QACrB,QAAU,EAAA,CAAC,IAAK,CAAA,eAAA,EAAiB,KAAK,eAAe,CAAA;AAAA,OACxD,CAAA;AAAA,KACJ,CAAA,CAAA;AACD,IAAK,IAAA,CAAA,sBAAA,CAAuB,UAAU,eAAe,CAAA,CAAA;AAErD,IAAM,MAAA,0BAAA,GACF,mBAAmB,yBAA0B,EAAA,CAAA;AAEjD,IAAK,IAAA,CAAA,WAAA,GAAc,IAAI,aAAc,CAAA;AAAA,MACjC,QAAU,EAAA,KAAA;AAAA,MACV,eAAiB,EAAA,0BAAA;AAAA,MACjB,UAAY,EAAA,KAAA,CAAM,OAAQ,EAAA,EAAG,aAAc,EAAA;AAAA,KAC9C,CAAA,CAAA;AAED,IAAA,IAAA,CAAK,eAAkB,GAAA,0BAAA,CAAA;AACvB,IAAK,IAAA,CAAA,WAAA,CAAY,GAAG,OAAS,EAAA,CAAC,UAAU,IAAK,CAAA,sBAAA,CAAuB,KAAK,CAAC,CAAA,CAAA;AAAA,GAC9E;AAAA,EAEA,OAAU,GAAA;AACN,IAAA,IAAA,CAAK,eAAgB,EAAA,CAAA;AACrB,IAAK,IAAA,CAAA,WAAA,EAAa,YAAY,KAAK,CAAA,CAAA;AACnC,IAAA,IAAA,CAAK,YAAY,OAAQ,EAAA,CAAA;AACzB,IAAA,IAAA,CAAK,eAAkB,GAAA,KAAA,CAAA,CAAA;AACvB,IAAA,IAAA,CAAK,eAAkB,GAAA,KAAA,CAAA,CAAA;AACvB,IAAA,IAAA,CAAK,uBAAuB,OAAQ,EAAA,CAAA;AAAA,GACxC;AAAA,EAEA,gBAAmB,GAAA;AACf,IAAI,IAAA,IAAA,CAAK,QAAQ,KAAO,EAAA;AACpB,MAAA,OAAA;AAAA,KACJ;AAEA,IAAA,MAAM,QAAQ,IAAK,CAAA,KAAA,CAAA;AACnB,IAAA,MAAM,kBAAqB,GAAA,IAAI,OAAc,CAAA,CAAC,OAAY,KAAA;AACtD,MAAA,IAAA,CAAK,QAAQ,KAAQ,GAAA,IAAA,CAAA;AACrB,MAAA,IAAA,CAAK,SAAS,KAAQ,GAAA,IAAA,CAAA;AAEtB,MAAA,IAAA,CAAK,aAAa,aAAc,CAAA,KAAA,CAAM,OAAQ,EAAA,EAAG,eAAe,CAAA,CAAA;AAChE,MAAK,IAAA,CAAA,WAAA,EAAa,YAAY,IAAI,CAAA,CAAA;AAElC,MAAM,MAAA,qBAAA,GAAmC,KAAK,WAAY,CAAA,EAAA;AAAA,QACtD,yBAAA;AAAA,QACA,MAAM;AACF,UAAA,MAAM,gBACF,GAAA,IAAA,CAAK,WAAY,CAAA,mBAAA,EAAyB,IAAA,KAAA,CAAA,CAAA;AAC9C,UAAK,IAAA,CAAA,eAAA,EAAiB,YAAY,gBAAgB,CAAA,CAAA;AAClD,UAAA,IAAI,IAAK,CAAA,eAAA,EAAiB,WAAY,EAAA,KAAM,KAAW,CAAA,EAAA;AACnD,YAAQ,OAAA,EAAA,CAAA;AAAA,WACZ;AACA,UAAA,IAAI,KAAK,aAAe,EAAA;AACpB,YAAA,MAAM,sBAA6C,GAAA,IAAA,EAAM,eACnD,EAAA,WAAA,IACA,SAAU,EAAA,CAAA;AAChB,YAAA,IAAI,sBAAwB,EAAA;AACxB,cAAM,MAAA,cAAA,GAAiB,wBAAwB,sBAAsB,CAAA,CAAA;AACrE,cAAA,IAAI,CAAC,cAAgB,EAAA;AACjB,gBAAA,OAAA;AAAA,eACJ;AACA,cAAM,KAAA,CAAA,OAAA,EAAU,CAAA,GAAA,CAAI,cAAgB,EAAA;AAAA,gBAChC,SAAS,IAAK,CAAA,OAAA;AAAA,eACjB,CAAA,CAAA;AACD,cAAA,IAAA,CAAK,aAAgB,GAAA,KAAA,CAAA;AAAA,aACzB;AAAA,WACJ;AAAA,SACJ;AAAA,OACJ,CAAA;AAEA,MAAA,MAAM,qBAAmC,GAAA,IAAA,CAAK,WAAY,CAAA,EAAA,CAAG,mBAAmB,MAAM;AAClF,QAAM,MAAA,WAAA,GAAsC,IAAK,CAAA,WAAA,CAAY,WAAY,EAAA,CAAA;AACzE,QAAA,IAAI,gBAAgB,WAAY,CAAA,CAAC,KAAK,WAAY,CAAA,CAAC,OAAO,KAAW,CAAA,EAAA;AACjE,UAAA,IAAA,CAAK,eAAiB,EAAA,WAAA,CAAY,IAAI,KAAA,CAAM,WAAW,CAAC,CAAA,CAAA;AACxD,UAAA,IAAI,KAAK,gBAAkB,EAAA;AACvB,YAAM,KAAA,CAAA,OAAA,EAAU,CAAA,SAAA,CAAU,WAAW,CAAA,CAAA;AAAA,WACzC;AACA,UAAA,IAAI,IAAK,CAAA,eAAA,EAAiB,WAAY,EAAA,KAAM,KAAW,CAAA,EAAA;AACnD,YAAQ,OAAA,EAAA,CAAA;AAAA,WACZ;AAAA,SACJ;AAAA,OACH,CAAA,CAAA;AAGD,MAAA,MAAM,0BAAqC,KACtC,CAAA,OAAA,EACA,CAAA,EAAA,CAAG,qBAAqB,MAAM;AAC3B,QAAA,IAAA,CAAK,mBAAmB,IAAK,CAAA,aAAA,CAAA;AAAA,OAChC,CAAA,CAAA;AAKL,MAAA,MAAM,eAA6B,GAAA,KAAA,CAAM,EAAG,CAAA,aAAA,EAAe,CAAC,GAAQ,KAAA;AAChE,QAAA,IAAI,IAAI,QAAU,EAAA;AACd,UAAA,IAAA,CAAK,gBAAmB,GAAA,KAAA,CAAA;AAAA,SAC5B;AAAA,OACH,CAAA,CAAA;AAED,MAAA,IAAA,CAAK,cAAe,CAAA,IAAA;AAAA,QAChB,qBAAA;AAAA,QACA,qBAAA;AAAA,QACA,uBAAA;AAAA,QACA,eAAA;AAAA,OACJ,CAAA;AAEA,MAAM,KAAA,CAAA,QAAA,CAAS,KAAK,sBAAsB,CAAA,CAAA;AAAA,KAC7C,CAAA,CAAA;AAED,IAAA,kBAAA,CACK,KAAK,MAAM;AAER,MAAA,IAAA,CAAK,SAAS,KAAQ,GAAA,KAAA,CAAA;AAAA,KACzB,CAAA,CACA,KAAM,CAAA,CAAC,KAAiB,KAAA;AACrB,MAAI,GAAA,CAAA,KAAA,CAAM,gCAAgC,KAAK,CAAA,CAAA;AAAA,KAClD,CAAA,CAAA;AAAA,GACT;AAAA,EAEA,eAAkB,GAAA;AACd,IAAK,IAAA,CAAA,WAAA,EAAa,YAAY,KAAK,CAAA,CAAA;AACnC,IAAA,IAAA,CAAK,QAAQ,KAAQ,GAAA,KAAA,CAAA;AACrB,IAAA,IAAA,CAAK,SAAS,KAAQ,GAAA,KAAA,CAAA;AACtB,IAAA,IAAA,CAAK,kBAAkB,EAAC,CAAA;AACxB,IAAA,IAAA,CAAK,gBAAmB,GAAA,IAAA,CAAA;AACxB,IAAA,IAAA,CAAK,aAAgB,GAAA,IAAA,CAAA;AAErB,IAAK,IAAA,CAAA,cAAA,CAAe,OAAQ,CAAA,CAAC,OAAY,KAAA;AACrC,MAAA,OAAA,CAAQ,OAAO,CAAA,CAAA;AAAA,KAClB,CAAA,CAAA;AACD,IAAA,IAAA,CAAK,iBAAiB,EAAC,CAAA;AACvB,IAAK,IAAA,CAAA,eAAA,EAAiB,YAAY,KAAS,CAAA,CAAA,CAAA;AAC3C,IAAK,IAAA,CAAA,eAAA,EAAiB,YAAY,KAAS,CAAA,CAAA,CAAA;AAC3C,IAAK,IAAA,CAAA,KAAA,CAAM,WAAY,CAAA,IAAA,CAAK,sBAAsB,CAAA,CAAA;AAAA,GACtD;AAAA;AAAA,EAGA,IAAI,MAAkB,GAAA;AAClB,IAAA,OAAO,KAAK,OAAQ,CAAA,KAAA,CAAA;AAAA,GACxB;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,IAAI,OAAmB,GAAA;AACnB,IAAA,OAAO,KAAK,QAAS,CAAA,KAAA,CAAA;AAAA,GACzB;AAAA,EAEA,wBAAwB,SAAkC,EAAA;AACtD,IAAA,IAAA,CAAK,eAAiB,EAAA,QAAA,CAAS,SAAa,IAAA,uBAAA,EAAyB,CAAA,CAAA;AAAA,GACzE;AAAA,EAEA,wBAAwB,SAAkC,EAAA;AACtD,IAAA,IAAA,CAAK,eAAiB,EAAA,QAAA,CAAS,SAAa,IAAA,uBAAA,EAAyB,CAAA,CAAA;AAAA,GACzE;AAAA,EAEA,WAAW,OAA6B,EAAA;AACpC,IAAA,IAAA,CAAK,UAAU,OAAW,IAAA,gBAAA,CAAA;AAAA,GAC9B;AAAA,EAEA,UAAa,GAAA;AACT,IAAA,OAAO,IAAK,CAAA,OAAA,CAAA;AAAA,GAChB;AAAA,EAEA,kBAAqB,GAAA;AACjB,IAAA,OAAO,IAAK,CAAA,eAAA,CAAA;AAAA,GAChB;AAAA,EAEA,kBAAqB,GAAA;AACjB,IAAA,OAAO,IAAK,CAAA,eAAA,CAAA;AAAA,GAChB;AAAA,EAEA,kBAAqB,GAAA;AACjB,IAAA,OAAO,IAAK,CAAA,eAAA,CAAA;AAAA,GAChB;AAAA,EAEA,cAAiB,GAAA;AACb,IAAA,OAAO,IAAK,CAAA,WAAA,CAAA;AAAA,GAChB;AAAA,EAEQ,uBAAuB,KAAyB,EAAA;AACpD,IAAI,GAAA,CAAA,KAAA,CAAM,6BAA+B,EAAA,KAAA,CAAM,OAAO,CAAA,CAAA;AAEtD,IAAA,IAAA,CAAK,eAAgB,EAAA,CAAA;AACrB,IAAA,MAAM,SAAqB,MAAM;AAC7B,MAAA,QAAQ,MAAM,IAAM;AAAA,QAChB,KAAK,CAAA;AACD,UAAO,OAAA,mBAAA,CAAA;AAAA,QACX,KAAK,CAAA;AACD,UAAO,OAAA,sBAAA,CAAA;AAAA,QACX,KAAK,CAAA;AACD,UAAO,OAAA,SAAA,CAAA;AAAA,QACX;AACI,UAAO,OAAA,SAAA,CAAA;AAAA,OACf;AAAA,KACD,GAAA,CAAA;AACH,IAAA,IAAA,CAAK,QAAQ,KAAK,CAAA,CAAA;AAAA,GACtB;AACJ,CAAA;AAEO,MAAM,0BAA0B,MAAM;AACzC,EAAA,OAAO,IAAI,KAAM,CAAA;AAAA,IACb,KAAA,EAAO,IAAIA,MAAY,CAAA;AAAA,MACnB,MAAQ,EAAA,CAAA;AAAA,MACR,IAAA,EAAM,IAAI,IAAK,CAAA;AAAA,QACX,KAAO,EAAA,SAAA;AAAA,OACV,CAAA;AAAA,MACD,MAAA,EAAQ,IAAI,MAAO,CAAA;AAAA,QACf,KAAO,EAAA,MAAA;AAAA,QACP,KAAO,EAAA,CAAA;AAAA,OACV,CAAA;AAAA,KACJ,CAAA;AAAA,GACJ,CAAA,CAAA;AACL,EAAA;AAEO,MAAM,0BAA0B,MAAM;AACzC,EAAA,OAAO,IAAI,KAAM,CAAA;AAAA,IACb,MAAA,EAAQ,IAAI,MAAO,CAAA;AAAA,MACf,KAAO,EAAA,SAAA;AAAA,MACP,KAAO,EAAA,CAAA;AAAA,KACV,CAAA;AAAA,IACD,IAAA,EAAM,IAAI,IAAK,CAAA;AAAA,MACX,KAAO,EAAA,uBAAA;AAAA,KACV,CAAA;AAAA,GACJ,CAAA,CAAA;AACL,EAAA;AAEO,MAAM,4BAA4B,MAAuB;AAC5D,EAAO,OAAA;AAAA,IACH,oBAAsB,EAAA,IAAA;AAAA,IACtB,SAAW,EAAA,GAAA;AAAA,IACX,YAAc,EAAA,GAAA;AAAA,GAClB,CAAA;AACJ;;;;"}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "type": "module",
3
3
  "name": "@open-pioneer/geolocation",
4
- "version": "0.4.2",
4
+ "version": "0.4.4",
5
5
  "description": "This package provides a component to locate a user's position.",
6
6
  "keywords": [
7
7
  "open-pioneer-trails"
@@ -14,15 +14,18 @@
14
14
  "directory": "src/packages/geolocation"
15
15
  },
16
16
  "peerDependencies": {
17
- "@open-pioneer/chakra-integration": "^1.1.3",
18
- "@open-pioneer/runtime": "^2.1.5",
19
- "@open-pioneer/core": "^1.2.3",
20
- "@open-pioneer/notifier": "^0.3.4",
21
- "ol": "^9.0.0",
17
+ "@conterra/reactivity-core": "^0.4.2",
18
+ "@open-pioneer/chakra-integration": "^1.1.4",
19
+ "@open-pioneer/core": "^1.3.0",
20
+ "@open-pioneer/notifier": "^0.3.6",
21
+ "@open-pioneer/react-utils": "^1.0.1",
22
+ "@open-pioneer/reactivity": "^0.1.0",
23
+ "@open-pioneer/runtime": "^2.1.7",
24
+ "ol": "^9.2.4",
22
25
  "react": "^18.3.1",
23
- "react-icons": "^4.12.0",
24
- "@open-pioneer/react-utils": "^0.2.3",
25
- "@open-pioneer/map": "^0.5.1"
26
+ "react-icons": "^5.2.1",
27
+ "@open-pioneer/map-ui-components": "^0.1.1",
28
+ "@open-pioneer/map": "^0.6.1"
26
29
  },
27
30
  "exports": {
28
31
  "./package.json": "./package.json",