@heycar/heycars-map 0.1.9 → 0.2.1

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 (87) hide show
  1. package/README.md +30 -7
  2. package/dist/business-components/StartEndPoint/StartEndPoint.d.ts +18309 -4
  3. package/dist/components/AmapLoader/AmapLoader.d.ts +5 -20
  4. package/dist/components/AmapMarker/AmapMarker.d.ts +3 -2
  5. package/dist/components/Demo/HeycarDemo.d.ts +3 -3
  6. package/dist/components/Demo/searchResult.d.ts +1 -1
  7. package/dist/components/GmapAdvancedMarkerView/GmapAdvancedMarkerView.d.ts +3 -2
  8. package/dist/components/GmapLoader/GmapLoader.d.ts +3 -35
  9. package/dist/components/GmapMarker/GmapMarker.d.ts +3 -2
  10. package/dist/components/MapProvider/MapProvider.d.ts +4 -5
  11. package/dist/hooks/useGeoLocation.d.ts +2 -2
  12. package/dist/hooks/useMap.d.ts +801 -0
  13. package/dist/hooks/useMapAutoComplete.d.ts +4 -6
  14. package/dist/hooks/useMapCityBound.d.ts +5 -6
  15. package/dist/hooks/useMapEventSource.d.ts +5 -0
  16. package/dist/hooks/useMapFitView.d.ts +4599 -0
  17. package/dist/hooks/useMapLoader.d.ts +67 -0
  18. package/dist/hooks/useMapPlace.d.ts +4 -6
  19. package/dist/hooks/useMapRecomendPlace.d.ts +5 -797
  20. package/dist/hooks/useMapSupplier.d.ts +8 -0
  21. package/dist/hooks/useOverlay.d.ts +12 -0
  22. package/dist/hooks-business/useBusinessMapAutoComplete.d.ts +5 -5
  23. package/dist/hooks-business/useBusinessMapRecomendPlace.d.ts +4 -3
  24. package/dist/index.cjs +52 -52
  25. package/dist/index.d.ts +2 -0
  26. package/dist/index.js +1366 -1165
  27. package/dist/types/interface.d.ts +4 -0
  28. package/package.json +1 -1
  29. package/src/App.tsx +1 -1
  30. package/src/api/place.ts +0 -2
  31. package/src/business-components/AddressBox/AddressBox.tsx +1 -1
  32. package/src/business-components/AddressLocator/AddressLocator.tsx +1 -1
  33. package/src/business-components/DrivingLine/DrivingLine.tsx +1 -1
  34. package/src/business-components/DrivingRoute/DrivingRoute.tsx +2 -3
  35. package/src/business-components/PassengerCircle/PassengerCircle.tsx +1 -1
  36. package/src/business-components/PlaceCircle/PlaceCircle.tsx +1 -1
  37. package/src/business-components/StartEndPoint/StartEndPoint.tsx +23 -7
  38. package/src/business-components/TaxiCar/TaxiCar.tsx +1 -1
  39. package/src/business-components/WalkingLine/WalkingLine.tsx +1 -1
  40. package/src/business-components/WalkingRoute/WalkingRoute.tsx +2 -3
  41. package/src/business-components/WaveCircle/WaveCircle.tsx +1 -1
  42. package/src/components/Amap/Amap.ts +1 -1
  43. package/src/components/AmapInfoWindow/AmapInfoWindow.ts +1 -1
  44. package/src/components/AmapLoader/AmapLoader.ts +6 -54
  45. package/src/components/AmapMarker/AmapMarker.ts +5 -2
  46. package/src/components/AmapPolygon/AmapPolygon.ts +1 -1
  47. package/src/components/AmapPolyline/AmapPolyline.ts +1 -1
  48. package/src/components/AmapText/AmapText.ts +1 -1
  49. package/src/components/Demo/Demo.css.ts +1 -1
  50. package/src/components/Demo/HeycarDemo.tsx +50 -33
  51. package/src/components/Demo/SearchDemo.tsx +40 -65
  52. package/src/components/Demo/searchResult.ts +12888 -1
  53. package/src/components/Gmap/Gmap.ts +17 -5
  54. package/src/components/GmapAdvancedMarkerView/GmapAdvancedMarkerView.ts +9 -4
  55. package/src/components/GmapInfoWindow/GmapInfoWindow.ts +1 -1
  56. package/src/components/GmapLoader/GmapLoader.ts +4 -62
  57. package/src/components/GmapMarker/GmapMarker.ts +5 -2
  58. package/src/components/GmapPolygon/GmapPolygon.ts +1 -1
  59. package/src/components/GmapPolyline/GmapPolyline.ts +1 -1
  60. package/src/components/MapProvider/MapProvider.tsx +33 -50
  61. package/src/hooks/useDrivingRoute.ts +1 -1
  62. package/src/hooks/useGeoLocation.ts +4 -2
  63. package/src/hooks/useHeycarMap.ts +1 -1
  64. package/src/hooks/useMap.ts +29 -0
  65. package/src/hooks/useMapAngle.ts +1 -1
  66. package/src/hooks/useMapAutoComplete.ts +16 -19
  67. package/src/hooks/useMapCityBound.ts +36 -24
  68. package/src/hooks/useMapDrag.ts +1 -1
  69. package/src/hooks/useMapEventSource.ts +20 -0
  70. package/src/hooks/useMapFitView.ts +127 -0
  71. package/src/hooks/useMapLoader.ts +164 -0
  72. package/src/hooks/useMapPlace.ts +20 -22
  73. package/src/hooks/useMapRecomendPlace.ts +18 -25
  74. package/src/{components/MapProvider → hooks}/useMapSupplier.ts +4 -7
  75. package/src/hooks/useOverlay.ts +22 -0
  76. package/src/hooks/useWalkingRoute.ts +1 -1
  77. package/src/hooks-business/useBusinessMapAutoComplete.ts +13 -7
  78. package/src/hooks-business/useBusinessMapRecomendPlace.ts +10 -10
  79. package/src/index.ts +2 -0
  80. package/src/types/interface.ts +5 -0
  81. package/dist/components/Amap/useAmap.d.ts +0 -399
  82. package/dist/components/Gmap/useGmap.d.ts +0 -5
  83. package/dist/components/MapProvider/useMapSupplier.d.ts +0 -11
  84. package/dist/hooks/useMapReady.d.ts +0 -4
  85. package/src/components/Amap/useAmap.ts +0 -9
  86. package/src/components/Gmap/useGmap.ts +0 -7
  87. package/src/hooks/useMapReady.ts +0 -14
@@ -0,0 +1,127 @@
1
+ import { debounce } from "lodash-es";
2
+ import type { MapShallowRef, RegisterOverlay } from "../types/interface";
3
+ import type { MapEventHandler } from "../types/mapHelper";
4
+ import { watchPostEffectForAMapEvent, watchPostEffectForGMapEvent } from "../utils/compare";
5
+ import { getMapEvnetSource, useMapEventSource } from "./useMapEventSource";
6
+ import { useMapSupplier } from "./useMapSupplier";
7
+ import type { AmapOverlay, GmapOverlay } from "./useOverlay";
8
+
9
+ const GOOGLE_MAP_ZOOM_CHANGE_DEBOUNCE_TIMEOUT = 20;
10
+
11
+ type UseAmapFitViewPropsForListeners = {
12
+ onDragEnd?: MapEventHandler<AMap.Map>;
13
+ // onZoomEnd?: MapEventHandler<AMap.Map>;
14
+ };
15
+
16
+ export interface UseMapFitViewProps<M = AMap.Map | google.maps.Map> {
17
+ mapRef: MapShallowRef<M>;
18
+ padding?: [number, number, number, number];
19
+ autoFitTimeout?: number;
20
+ }
21
+ export const useAmapFitView = (props: UseMapFitViewProps<AMap.Map>) => {
22
+ const { mapRef, autoFitTimeout } = props;
23
+ const overlayGroup: Set<AmapOverlay> = new Set();
24
+ let timer: number | undefined = undefined;
25
+ const registerFitVeiw: RegisterOverlay<AmapOverlay> = {
26
+ add: (overlay: AmapOverlay) => {
27
+ overlayGroup.add(overlay);
28
+ },
29
+ remove: (overlay: AmapOverlay) => {
30
+ overlayGroup.delete(overlay);
31
+ },
32
+ };
33
+ const setFitView = () => {
34
+ const map = mapRef.value;
35
+ if (!map) return;
36
+ const vw = window.innerWidth / 100;
37
+ const [top, right, bottom, left] = props.padding ?? [0, 0, 0, 0];
38
+ console.log([...overlayGroup]);
39
+ map.setFitView([...overlayGroup], false, [top * vw, bottom * vw, left * vw, right * vw]);
40
+ };
41
+ const handleMoveEndOrZomEnd = () => {
42
+ if (!autoFitTimeout) return;
43
+ if (timer) clearTimeout(timer);
44
+ timer = setTimeout(() => {
45
+ timer = undefined;
46
+ setFitView();
47
+ }, autoFitTimeout);
48
+ };
49
+ watchPostEffectForAMapEvent(
50
+ mapRef,
51
+ {} as UseAmapFitViewPropsForListeners,
52
+ handleMoveEndOrZomEnd,
53
+ ["onDragEnd"]
54
+ );
55
+ return { registerFitVeiw, setFitView };
56
+ };
57
+
58
+ // 目前需求暂时只需要 marker
59
+ class SimpleGmapOverLayerGroup extends Set<GmapOverlay> {
60
+ getBound() {
61
+ const bound = new google.maps.LatLngBounds();
62
+ for (const overlay of this.values()) {
63
+ const position =
64
+ overlay instanceof google.maps.Marker ? overlay.getPosition() : overlay.position;
65
+ if (position) bound.extend(position);
66
+ }
67
+ return bound;
68
+ }
69
+ }
70
+
71
+ type UseGmapFitViewPropsForListeners = {
72
+ onDragEnd?: MapEventHandler<AMap.Map>;
73
+ onZoom_changed?: MapEventHandler<AMap.Map>;
74
+ };
75
+ export const useGmapFitView = (props: UseMapFitViewProps<google.maps.Map>) => {
76
+ const { mapRef, autoFitTimeout } = props;
77
+ const { executeMapApi } = useMapEventSource();
78
+ const overlayGroup = new SimpleGmapOverLayerGroup();
79
+ let timer: number | undefined = undefined;
80
+ const registerFitVeiw: RegisterOverlay<GmapOverlay> = {
81
+ add: (overlay: GmapOverlay) => {
82
+ overlayGroup.add(overlay);
83
+ },
84
+ remove: (overlay: GmapOverlay) => {
85
+ overlayGroup.delete(overlay);
86
+ },
87
+ };
88
+ const setFitView = () => {
89
+ const map = mapRef.value;
90
+ if (!map) return;
91
+ const vw = window.innerWidth / 100;
92
+ const [top, right, bottom, left] = props.padding ?? [0, 0, 0, 0];
93
+ executeMapApi(() =>
94
+ map.fitBounds(overlayGroup.getBound(), {
95
+ top: top * vw,
96
+ right: right * vw,
97
+ bottom: bottom * vw,
98
+ left: left * vw,
99
+ })
100
+ );
101
+ };
102
+ const handleMoveEnd = (name: string) => {
103
+ const eventSource = getMapEvnetSource();
104
+ console.log("handleMoveEndOrZomEnd name, eventSource = ", name, eventSource);
105
+ if (!autoFitTimeout || eventSource !== "user") return;
106
+ if (timer) clearTimeout(timer);
107
+ timer = setTimeout(() => {
108
+ timer = undefined;
109
+ setFitView();
110
+ }, autoFitTimeout);
111
+ };
112
+ const handleZoomChange = debounce(handleMoveEnd, GOOGLE_MAP_ZOOM_CHANGE_DEBOUNCE_TIMEOUT);
113
+ watchPostEffectForGMapEvent(mapRef, {} as UseGmapFitViewPropsForListeners, handleMoveEnd, [
114
+ "onDragEnd",
115
+ ]);
116
+ watchPostEffectForGMapEvent(mapRef, {} as UseGmapFitViewPropsForListeners, handleZoomChange, [
117
+ "onZoom_changed",
118
+ ]);
119
+ return { registerFitVeiw, setFitView };
120
+ };
121
+
122
+ export const useMapFitView = (props: UseMapFitViewProps) => {
123
+ const { supplier } = useMapSupplier();
124
+ return supplier === "gmap"
125
+ ? useGmapFitView(props as UseMapFitViewProps<google.maps.Map>)
126
+ : useAmapFitView(props as UseMapFitViewProps<AMap.Map>);
127
+ };
@@ -0,0 +1,164 @@
1
+ import { load as loadAmap } from "@amap/amap-jsapi-loader";
2
+ import { Loader, LoaderOptions } from "@googlemaps/js-api-loader";
3
+ import { computed, Ref, shallowRef } from "vue-demi";
4
+ import type { VueNode } from "../types/helper";
5
+ import { watchPostEffectForDeepOption } from "../utils/compare";
6
+
7
+ export const DEFAULT_AMAP_PLUGINS: AmapLoaderProps["plugins"] = [
8
+ "AMap.Geolocation",
9
+ "AMap.Geocoder",
10
+ "AMap.PlaceSearch",
11
+ "AMap.Driving",
12
+ "AMap.Walker",
13
+ ];
14
+ export const DEFAULT_GMAP_LIBRARIES: LoaderOptions["libraries"] = ["marker", "places", "geometry"];
15
+
16
+ export enum Status {
17
+ LOADING = "LOADING",
18
+ FAILURE = "FAILURE",
19
+ SUCCESS = "SUCCESS",
20
+ }
21
+ type AMapLoaderOptions = Parameters<typeof loadAmap>[0];
22
+ declare global {
23
+ interface Window {
24
+ _AMapSecurityConfig: {
25
+ securityJsCode?: string;
26
+ serviceHost?: string;
27
+ };
28
+ }
29
+ }
30
+ export interface AmapLoaderProps
31
+ extends Pick<GmapLoaderProps, "fallback" | "loading" | "onChange">,
32
+ Omit<AMapLoaderOptions, "key" | "version" | "plugins"> {
33
+ apiKey: string;
34
+ apiSecret?: string;
35
+ apiServiceHost?: string;
36
+ version?: string;
37
+ plugins?: `AMap.${AMap.PluginName}`[];
38
+ }
39
+
40
+ export const useAmapLoader = (props: AmapLoaderProps) => {
41
+ const { onChange } = props;
42
+ let resolveLoader: () => void;
43
+ let rejectLoader: () => void;
44
+ const readyPromise = new Promise<undefined>((resolve, reject) => {
45
+ resolveLoader = resolve as () => void;
46
+ rejectLoader = reject;
47
+ });
48
+ const statusRef = shallowRef(Status.LOADING);
49
+ const optionsRef = computed(() => {
50
+ const { onChange, loading, fallback, apiKey, apiSecret, apiServiceHost, version, ...options } =
51
+ props;
52
+ return { ...options, key: apiKey, version: version ?? "2.0.5.16" };
53
+ });
54
+ watchPostEffectForDeepOption(
55
+ () => optionsRef.value,
56
+ (options) => {
57
+ const setStatusAndExecuteCallback = (status: Status) => {
58
+ statusRef.value = status;
59
+ if (status === Status.SUCCESS) resolveLoader();
60
+ if (status === Status.FAILURE) rejectLoader();
61
+ onChange?.(statusRef.value);
62
+ };
63
+ setStatusAndExecuteCallback(Status.LOADING);
64
+
65
+ window._AMapSecurityConfig = props.apiServiceHost
66
+ ? {
67
+ serviceHost: props.apiServiceHost,
68
+ }
69
+ : { securityJsCode: props.apiSecret };
70
+
71
+ loadAmap(options).then(
72
+ () => setStatusAndExecuteCallback(Status.SUCCESS),
73
+ () => setStatusAndExecuteCallback(Status.FAILURE)
74
+ );
75
+ }
76
+ );
77
+ return { statusRef, readyPromise };
78
+ };
79
+
80
+ export interface GmapLoaderProps extends LoaderOptions {
81
+ /**
82
+ * Render prop used to switch to loading component.
83
+ */
84
+ loading?: () => VueNode;
85
+ /**
86
+ * Render prop used to switch to error fallback component.
87
+ */
88
+ fallback?: () => VueNode;
89
+ /**
90
+ * Callback prop used to access `@googlemaps/js-api-loader` and `Status`.
91
+ *
92
+ * Note: The callback be executed multiple times in the lifecycle of the component.
93
+ */
94
+ onChange?: (status: Status) => void;
95
+ }
96
+
97
+ export const useGmapLoader = (props: GmapLoaderProps) => {
98
+ const { onChange } = props;
99
+ let resolveLoader: () => void;
100
+ let rejectLoader: () => void;
101
+ const readyPromise = new Promise<undefined>((resolve, reject) => {
102
+ resolveLoader = resolve as () => void;
103
+ rejectLoader = reject;
104
+ });
105
+ const statusRef = shallowRef(Status.LOADING);
106
+ const options = computed(() => {
107
+ const { onChange, fallback, loading, ...options } = props;
108
+ return options;
109
+ });
110
+ watchPostEffectForDeepOption(
111
+ () => options.value,
112
+ (options) => {
113
+ const loader = new Loader(options);
114
+
115
+ const setStatusAndExecuteCallback = (status: Status) => {
116
+ statusRef.value = status;
117
+ if (status === Status.SUCCESS) resolveLoader();
118
+ if (status === Status.FAILURE) rejectLoader();
119
+ onChange?.(statusRef.value);
120
+ };
121
+
122
+ setStatusAndExecuteCallback(Status.LOADING);
123
+
124
+ loader.load().then(
125
+ () => setStatusAndExecuteCallback(Status.SUCCESS),
126
+ () => setStatusAndExecuteCallback(Status.FAILURE)
127
+ );
128
+ }
129
+ );
130
+ return { statusRef, readyPromise };
131
+ };
132
+
133
+ export type MapSupplier = "gmap" | "amap";
134
+ export interface UseMapLoaderOutput {
135
+ statusRef: Ref<Status>;
136
+ readyPromise: Promise<undefined>;
137
+ }
138
+ export interface UseMapLoaderProps {
139
+ gmapKey: string;
140
+ amapKey: string;
141
+ amapSecret?: string;
142
+ amapServiceHost?: string;
143
+ supplier: MapSupplier;
144
+ language?: "en" | "zh";
145
+ onChange?: (status: Status) => any;
146
+ }
147
+ export const useMapLoader = (props: UseMapLoaderProps): UseMapLoaderOutput => {
148
+ const { gmapKey, amapKey, amapSecret, amapServiceHost, supplier, language, onChange } = props;
149
+ return supplier === "gmap"
150
+ ? useGmapLoader({
151
+ apiKey: gmapKey,
152
+ language,
153
+ version: "beta",
154
+ libraries: DEFAULT_GMAP_LIBRARIES,
155
+ onChange,
156
+ })
157
+ : useAmapLoader({
158
+ apiKey: amapKey,
159
+ apiSecret: amapSecret,
160
+ apiServiceHost: amapServiceHost,
161
+ plugins: DEFAULT_AMAP_PLUGINS,
162
+ onChange,
163
+ });
164
+ };
@@ -1,19 +1,17 @@
1
1
  import { reactive, Ref, watch } from "vue-demi";
2
- import { useMapSupplier } from "../components/MapProvider/useMapSupplier";
3
2
  import { LANGUAGE } from "../types/helper";
4
- import type { MapShallowRef, Place, Point } from "../types/interface";
5
- import { geocoderResult2cityName, pipeAsync } from "../utils/transform";
6
- import { useMapReady } from "./useMapReady";
3
+ import type { Place, Point } from "../types/interface";
4
+ import { geocoderResult2cityName } from "../utils/transform";
5
+ import { useMapSupplier } from "./useMapSupplier";
7
6
  import { useUpdate } from "./useUdate";
8
7
 
9
- export interface UseMapPlaceProps<M = AMap.Map | google.maps.Map> {
8
+ export interface UseMapPlaceProps {
10
9
  pointRef: Ref<Point>;
11
- mapRef: MapShallowRef<M>;
12
10
  onChange?: (value: Place) => any;
13
11
  }
14
- export const useAmapPlace = (props: UseMapPlaceProps<AMap.Map>) => {
15
- const { mapRef, pointRef, onChange } = props;
16
- const { readyRef } = useMapReady(mapRef);
12
+ export const useAmapPlace = (props: UseMapPlaceProps) => {
13
+ const { pointRef, onChange } = props;
14
+ const { readyPromise } = useMapSupplier();
17
15
  const { idx: placeKey, update: updatePlace } = useUpdate();
18
16
  const place = reactive<Place>({
19
17
  lng: pointRef.value[0],
@@ -23,8 +21,8 @@ export const useAmapPlace = (props: UseMapPlaceProps<AMap.Map>) => {
23
21
  });
24
22
  watch(
25
23
  () => placeKey.value,
26
- () => {
27
- if (!readyRef.value) return;
24
+ async () => {
25
+ await readyPromise;
28
26
  const geocoder = new AMap.Geocoder({ lang: LANGUAGE });
29
27
  const [lng, lat] = pointRef.value;
30
28
  geocoder.getAddress(new AMap.LngLat(lng, lat), (status, result) => {
@@ -32,18 +30,20 @@ export const useAmapPlace = (props: UseMapPlaceProps<AMap.Map>) => {
32
30
  case "complete": {
33
31
  const { formattedAddress: name, addressComponent } = (result as AMap.ReGeocoderResult)
34
32
  .regeocode;
35
- const cityName = addressComponent.city ?? addressComponent.province;
33
+ const cityName = addressComponent.city
34
+ ? addressComponent.city
35
+ : addressComponent.province;
36
36
  place.name = name;
37
37
  place.lng = lng;
38
38
  place.lat = lat;
39
39
  place.cityName = cityName;
40
- pipeAsync(onChange)?.({ lng, lat, name, cityName });
40
+ onChange?.({ lng, lat, name, cityName });
41
41
  return;
42
42
  }
43
43
 
44
44
  case "no_data":
45
45
  place.name = "";
46
- pipeAsync(onChange)?.({ lng, lat, name: "" });
46
+ onChange?.({ lng, lat, name: "" });
47
47
  return;
48
48
  case "error":
49
49
  throw result;
@@ -54,15 +54,15 @@ export const useAmapPlace = (props: UseMapPlaceProps<AMap.Map>) => {
54
54
  return { place, updatePlace };
55
55
  };
56
56
 
57
- export const useGmapPlace = (props: UseMapPlaceProps<google.maps.Map>) => {
58
- const { mapRef, pointRef, onChange } = props;
59
- const { readyRef } = useMapReady(mapRef);
57
+ export const useGmapPlace = (props: UseMapPlaceProps) => {
58
+ const { pointRef, onChange } = props;
59
+ const { readyPromise } = useMapSupplier();
60
60
  const { idx: placeKey, update: updatePlace } = useUpdate();
61
61
  const place = reactive<Place>({ lng: pointRef.value[0], lat: pointRef.value[1], name: "" });
62
62
  watch(
63
63
  () => placeKey.value,
64
64
  async () => {
65
- if (!readyRef.value) return;
65
+ await readyPromise;
66
66
  const geocoder = new google.maps.Geocoder();
67
67
  const [lng, lat] = pointRef.value;
68
68
  const { results } = await geocoder.geocode({ language: LANGUAGE, location: { lng, lat } });
@@ -71,7 +71,7 @@ export const useGmapPlace = (props: UseMapPlaceProps<google.maps.Map>) => {
71
71
  place.name = name;
72
72
  place.lng = lng;
73
73
  place.lat = lat;
74
- pipeAsync(onChange)?.({ lng, lat, name, cityName });
74
+ onChange?.({ lng, lat, name, cityName });
75
75
  }
76
76
  );
77
77
  return { place, updatePlace };
@@ -79,7 +79,5 @@ export const useGmapPlace = (props: UseMapPlaceProps<google.maps.Map>) => {
79
79
 
80
80
  export const useMapPlace = (props: UseMapPlaceProps) => {
81
81
  const { supplier } = useMapSupplier();
82
- return supplier === "gmap"
83
- ? useGmapPlace(props as UseMapPlaceProps<google.maps.Map>)
84
- : useAmapPlace(props as UseMapPlaceProps<AMap.Map>);
82
+ return supplier === "gmap" ? useGmapPlace(props) : useAmapPlace(props);
85
83
  };
@@ -1,9 +1,8 @@
1
1
  import { reactive, ref, Ref, watch } from "vue-demi";
2
- import { useMapSupplier } from "../components/MapProvider/useMapSupplier";
3
- import type { MapShallowRef, Place, Point } from "../types/interface";
4
- import { pipeAsync, place2point } from "../utils/transform";
2
+ import type { Place, Point } from "../types/interface";
3
+ import { place2point } from "../utils/transform";
5
4
  import { useAmapPlace, useGmapPlace, UseMapPlaceProps } from "./useMapPlace";
6
- import { useMapReady } from "./useMapReady";
5
+ import { useMapSupplier } from "./useMapSupplier";
7
6
  import { useUpdate } from "./useUdate";
8
7
 
9
8
  const findAmapNearestPlace = (place: Place, candidates: Place[]) => {
@@ -30,8 +29,7 @@ const findGmapNearestPlace = (place: Place, candidates: Place[]) => {
30
29
  return { shortestPlace, shortestDistance };
31
30
  };
32
31
 
33
- export interface UseMapRecomendPlaceProps<M = AMap.Map | google.maps.Map, C = Record<string, any>> {
34
- mapRef: MapShallowRef<M>;
32
+ export interface UseMapRecomendPlaceProps<C = Record<string, any>> {
35
33
  pointRef: Ref<Point>;
36
34
  context?: C;
37
35
  getLimit: (context?: C) => number;
@@ -39,58 +37,53 @@ export interface UseMapRecomendPlaceProps<M = AMap.Map | google.maps.Map, C = Re
39
37
  onChangePlace?: UseMapPlaceProps["onChange"];
40
38
  onChange?: (place: Place) => any;
41
39
  }
42
- export const useAmapRecomendPlace = <C>(props: UseMapRecomendPlaceProps<AMap.Map, C>) => {
43
- const { pointRef, mapRef, getRecomendPlace, getLimit, context, onChange, onChangePlace } = props;
40
+ export const useAmapRecomendPlace = <C>(props: UseMapRecomendPlaceProps<C>) => {
41
+ const { pointRef, getRecomendPlace, getLimit, context, onChange, onChangePlace } = props;
44
42
  const placeCandidatesRef = ref<Place[]>([]);
45
43
  const { idx: recomendPlaceKey, update: updateRecomandPlace } = useUpdate();
46
- const { readyRef } = useMapReady(mapRef);
47
- const { place, updatePlace } = useAmapPlace({ pointRef, mapRef, onChange: onChangePlace });
44
+ const { readyPromise } = useMapSupplier();
45
+ const { place, updatePlace } = useAmapPlace({ pointRef, onChange: onChangePlace });
48
46
  const recomendPlace = reactive<Place>({ ...place });
49
47
  watch(
50
48
  () => recomendPlaceKey.value,
51
49
  async () => {
52
- if (!readyRef.value) return;
50
+ await readyPromise;
53
51
  const placeCandidates = await getRecomendPlace({ ...place }, context);
54
52
  const { shortestPlace, shortestDistance } = findAmapNearestPlace(place, placeCandidates);
55
- console.log("shortestPlace, shortestDistance = ", shortestPlace, shortestDistance);
56
53
  const limit = getLimit(context);
57
54
  const resultPlace = shortestDistance > limit ? place : shortestPlace;
58
55
  placeCandidatesRef.value = placeCandidates;
59
56
  Object.assign(recomendPlace, { ...resultPlace });
60
- pipeAsync(onChange)?.({ ...resultPlace });
57
+ onChange?.({ ...resultPlace });
61
58
  }
62
59
  );
63
60
  return { recomendPlace, placeCandidates: placeCandidatesRef, updateRecomandPlace, updatePlace };
64
61
  };
65
62
 
66
- export const useGmapRecomendPlace = <C>(props: UseMapRecomendPlaceProps<google.maps.Map, C>) => {
67
- const { pointRef, mapRef, getRecomendPlace, getLimit, context, onChange, onChangePlace } = props;
63
+ export const useGmapRecomendPlace = <C>(props: UseMapRecomendPlaceProps<C>) => {
64
+ const { pointRef, getRecomendPlace, getLimit, context, onChange, onChangePlace } = props;
68
65
  const placeCandidatesRef = ref<Place[]>([]);
69
66
  const { idx: recomendPlaceKey, update: updateRecomandPlace } = useUpdate();
70
- const { readyRef } = useMapReady(mapRef);
71
- const { place, updatePlace } = useGmapPlace({ pointRef, mapRef, onChange: onChangePlace });
67
+ const { readyPromise } = useMapSupplier();
68
+ const { place, updatePlace } = useGmapPlace({ pointRef, onChange: onChangePlace });
72
69
  const recomendPlace = reactive<Place>({ ...place });
73
70
  watch(
74
71
  () => recomendPlaceKey.value,
75
72
  async () => {
76
- if (!readyRef.value) return;
73
+ await readyPromise;
77
74
  const placeCandidates = await getRecomendPlace({ ...place }, context);
78
75
  const { shortestPlace, shortestDistance } = findGmapNearestPlace(place, placeCandidates);
79
76
  const limit = getLimit(context);
80
77
  const resultPlace = shortestDistance > limit ? place : shortestPlace;
81
78
  placeCandidatesRef.value = placeCandidates;
82
79
  Object.assign(recomendPlace, { ...resultPlace });
83
- pipeAsync(onChange)?.({ ...resultPlace });
80
+ onChange?.({ ...resultPlace });
84
81
  }
85
82
  );
86
83
  return { recomendPlace, placeCandidates: placeCandidatesRef, updateRecomandPlace, updatePlace };
87
84
  };
88
85
 
89
- export const useMapRecomendPlace = <C>(
90
- props: UseMapRecomendPlaceProps<AMap.Map | google.maps.Map, C>
91
- ) => {
86
+ export const useMapRecomendPlace = <C>(props: UseMapRecomendPlaceProps<C>) => {
92
87
  const { supplier } = useMapSupplier();
93
- return supplier === "gmap"
94
- ? useGmapRecomendPlace(props as UseMapRecomendPlaceProps<google.maps.Map>)
95
- : useAmapRecomendPlace(props as UseMapRecomendPlaceProps<AMap.Map>);
88
+ return supplier === "gmap" ? useGmapRecomendPlace(props) : useAmapRecomendPlace(props);
96
89
  };
@@ -1,13 +1,10 @@
1
1
  import { inject, provide } from "vue-demi";
2
+ import type { Status, UseMapLoaderOutput, UseMapLoaderProps } from "./useMapLoader";
2
3
 
3
- export type MapSupplier = "gmap" | "amap";
4
- export interface MapSupplierPayolad {
5
- gmapKey: string;
4
+ export interface MapSupplierPayolad extends UseMapLoaderProps {
6
5
  gmapId: string;
7
- amapKey: string;
8
- amapSecret?: string;
9
- amapServiceHost?: string;
10
- supplier: MapSupplier;
6
+ readyPromise: UseMapLoaderOutput["readyPromise"];
7
+ status: Status;
11
8
  }
12
9
  const context = Symbol();
13
10
 
@@ -0,0 +1,22 @@
1
+ import { ShallowRef, watch } from "vue-demi";
2
+ import type { RegisterOverlay } from "../types/interface";
3
+
4
+ export interface MapRegisterOverlayProps<T> {
5
+ registerOverlay?: RegisterOverlay<T>;
6
+ }
7
+ export type AmapOverlay = Parameters<AMap.OverlayGroup["addOverlay"]>[0];
8
+ export type GmapOverlay = google.maps.Marker | google.maps.marker.AdvancedMarkerView;
9
+ export interface UseMapOverlayProps<T> extends MapRegisterOverlayProps<T> {
10
+ overlayRef: ShallowRef<T | undefined>;
11
+ }
12
+ export const useMapOverlay = <T>(props: UseMapOverlayProps<T>) => {
13
+ const { registerOverlay, overlayRef } = props;
14
+ watch(
15
+ () => overlayRef.value,
16
+ (overlay, prevOverlay) => {
17
+ if (!registerOverlay) return;
18
+ if (prevOverlay) registerOverlay.remove(prevOverlay);
19
+ if (overlay) registerOverlay.add(overlay);
20
+ }
21
+ );
22
+ };
@@ -1,7 +1,7 @@
1
1
  import { ShallowRef, shallowRef } from "vue-demi";
2
- import { useMapSupplier } from "../components/MapProvider/useMapSupplier";
3
2
  import type { Point } from "../types/interface";
4
3
  import { watchPostEffectForDeepOption } from "../utils/compare";
4
+ import { useMapSupplier } from "./useMapSupplier";
5
5
 
6
6
  export interface UseWalkingRouteProps {
7
7
  from: Point;
@@ -1,15 +1,21 @@
1
+ import type { Ref } from "vue-demi";
1
2
  import { useMapAutoComplete } from "../hooks/useMapAutoComplete";
2
3
  import { useMapBoundCity } from "../hooks/useMapCityBound";
3
- import type { MapShallowRef } from "../types/interface";
4
4
 
5
5
  export interface UseBusinessMapAutoCompleteProps {
6
- mapRef: MapShallowRef;
7
- defaultCityName: string;
6
+ cityNameRef: Ref<string>;
8
7
  }
9
8
 
10
9
  export const useBusinessMapAutoComplete = (props: UseBusinessMapAutoCompleteProps) => {
11
- const { mapRef, defaultCityName } = props;
12
- const city = useMapBoundCity({ mapRef, cityName: defaultCityName, onChange: (v) => setCity(v) });
13
- const { autoCompletePlaces, setKeyword, setCity } = useMapAutoComplete({ mapRef, city });
14
- return { autoCompletePlaces, setKeyword, setCity };
10
+ const { cityNameRef } = props;
11
+ const city = useMapBoundCity({
12
+ cityNameRef,
13
+ onChange: (v) => setCity(v),
14
+ });
15
+ const { autoCompletePlaces, setKeyword, setCity } = useMapAutoComplete({ city });
16
+ const handleKeywordInput = (e: Event) => {
17
+ const target = e.target as HTMLInputElement;
18
+ setKeyword(target.value);
19
+ };
20
+ return { autoCompletePlaces, setKeyword, setCity, handleKeywordInput };
15
21
  };
@@ -3,16 +3,15 @@ import { useGeoLocation, UseGeoLocationProps } from "../hooks/useGeoLocation";
3
3
  import { useMapDrag, UseMapDragProps } from "../hooks/useMapDrag";
4
4
  import type { UseMapPlaceProps } from "../hooks/useMapPlace";
5
5
  import { useMapRecomendPlace, UseMapRecomendPlaceProps } from "../hooks/useMapRecomendPlace";
6
- import type { Place, Point } from "../types/interface";
6
+ import { useMapSupplier } from "../hooks/useMapSupplier";
7
+ import type { MapShallowRef, Place, Point } from "../types/interface";
7
8
 
8
9
  interface CenterPlaceSource {
9
10
  source: "default" | "geo" | "drag" | "recomend" | "api";
10
11
  }
11
12
  export interface UseBusinessMapRecomendPlaceProps
12
- extends Pick<
13
- UseMapRecomendPlaceProps<AMap.Map | google.maps.Map, CenterPlaceSource>,
14
- "getRecomendPlace" | "mapRef"
15
- > {
13
+ extends Pick<UseMapRecomendPlaceProps<CenterPlaceSource>, "getRecomendPlace"> {
14
+ mapRef: MapShallowRef;
16
15
  defaultCenterPoint?: Point;
17
16
  recomendPlaceGeoLimit: number;
18
17
  recomendPlaceDragLimit: number;
@@ -35,6 +34,7 @@ export const useBusinessMapRecomendPlace = (props: UseBusinessMapRecomendPlacePr
35
34
  onChangePlace,
36
35
  onChangeRecomandPlace,
37
36
  } = props;
37
+ const { readyPromise } = useMapSupplier();
38
38
  const centerPlace = reactive<Place>({
39
39
  lng: defaultCenterPoint?.[0] ?? 0,
40
40
  lat: defaultCenterPoint?.[1] ?? 0,
@@ -51,17 +51,17 @@ export const useBusinessMapRecomendPlace = (props: UseBusinessMapRecomendPlacePr
51
51
  };
52
52
  if (defaultCenterPoint) {
53
53
  // default 主入口
54
- Promise.resolve().then(() => {
54
+ readyPromise.then(() => {
55
55
  centerSource.source = "default";
56
56
  updatePlace();
57
57
  });
58
58
  }
59
- const { geoLoading, geoError, geoPosition, geoCoordinate } = useGeoLocation({
60
- mapRef,
61
- onLoad: (value) => {
59
+ const { geoLoading, geoError, geoPosition, geoCoordinate, geoReady } = useGeoLocation({
60
+ onLoad: async (value) => {
62
61
  // geo 主入口
63
62
  // 如果设置了默认位置,就不在拿 gps 作为默认位置
64
63
  if (!defaultCenterPoint) {
64
+ await readyPromise;
65
65
  centerSource.source = "geo";
66
66
  centerPlace.lng = value.position[0];
67
67
  centerPlace.lat = value.position[1];
@@ -98,7 +98,6 @@ export const useBusinessMapRecomendPlace = (props: UseBusinessMapRecomendPlacePr
98
98
  throw new Error(`MyError: should not call getLimit on source: ${source}`);
99
99
  }
100
100
  },
101
- mapRef,
102
101
  onChangePlace: (place) => {
103
102
  Object.assign(centerPlace, { ...place });
104
103
  if (centerSource.source !== "recomend") {
@@ -119,6 +118,7 @@ export const useBusinessMapRecomendPlace = (props: UseBusinessMapRecomendPlacePr
119
118
  geoError,
120
119
  geoPosition,
121
120
  geoCoordinate,
121
+ geoReady,
122
122
  centerPlace,
123
123
  centerPoint,
124
124
  placeCandidates,
package/src/index.ts CHANGED
@@ -18,6 +18,8 @@ export { useGeoLocation } from "./hooks/useGeoLocation";
18
18
  export { useHeycarMap } from "./hooks/useHeycarMap";
19
19
  export { useMapAngle } from "./hooks/useMapAngle";
20
20
  export { useMapDrag } from "./hooks/useMapDrag";
21
+ export { useMapFitView } from "./hooks/useMapFitView";
21
22
  export { useMapPlace } from "./hooks/useMapPlace";
22
23
  export { useMapRecomendPlace } from "./hooks/useMapRecomendPlace";
24
+ export { useWalkingRoute } from "./hooks/useWalkingRoute";
23
25
  export * from "./types/interface";
@@ -23,3 +23,8 @@ export type City = {
23
23
  };
24
24
  name: string;
25
25
  };
26
+
27
+ export interface RegisterOverlay<T> {
28
+ add: (overlay: T) => void;
29
+ remove: (overlay: T) => void;
30
+ }