@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.
- package/README.md +30 -7
- package/dist/business-components/StartEndPoint/StartEndPoint.d.ts +18309 -4
- package/dist/components/AmapLoader/AmapLoader.d.ts +5 -20
- package/dist/components/AmapMarker/AmapMarker.d.ts +3 -2
- package/dist/components/Demo/HeycarDemo.d.ts +3 -3
- package/dist/components/Demo/searchResult.d.ts +1 -1
- package/dist/components/GmapAdvancedMarkerView/GmapAdvancedMarkerView.d.ts +3 -2
- package/dist/components/GmapLoader/GmapLoader.d.ts +3 -35
- package/dist/components/GmapMarker/GmapMarker.d.ts +3 -2
- package/dist/components/MapProvider/MapProvider.d.ts +4 -5
- package/dist/hooks/useGeoLocation.d.ts +2 -2
- package/dist/hooks/useMap.d.ts +801 -0
- package/dist/hooks/useMapAutoComplete.d.ts +4 -6
- package/dist/hooks/useMapCityBound.d.ts +5 -6
- package/dist/hooks/useMapEventSource.d.ts +5 -0
- package/dist/hooks/useMapFitView.d.ts +4599 -0
- package/dist/hooks/useMapLoader.d.ts +67 -0
- package/dist/hooks/useMapPlace.d.ts +4 -6
- package/dist/hooks/useMapRecomendPlace.d.ts +5 -797
- package/dist/hooks/useMapSupplier.d.ts +8 -0
- package/dist/hooks/useOverlay.d.ts +12 -0
- package/dist/hooks-business/useBusinessMapAutoComplete.d.ts +5 -5
- package/dist/hooks-business/useBusinessMapRecomendPlace.d.ts +4 -3
- package/dist/index.cjs +52 -52
- package/dist/index.d.ts +2 -0
- package/dist/index.js +1366 -1165
- package/dist/types/interface.d.ts +4 -0
- package/package.json +1 -1
- package/src/App.tsx +1 -1
- package/src/api/place.ts +0 -2
- package/src/business-components/AddressBox/AddressBox.tsx +1 -1
- package/src/business-components/AddressLocator/AddressLocator.tsx +1 -1
- package/src/business-components/DrivingLine/DrivingLine.tsx +1 -1
- package/src/business-components/DrivingRoute/DrivingRoute.tsx +2 -3
- package/src/business-components/PassengerCircle/PassengerCircle.tsx +1 -1
- package/src/business-components/PlaceCircle/PlaceCircle.tsx +1 -1
- package/src/business-components/StartEndPoint/StartEndPoint.tsx +23 -7
- package/src/business-components/TaxiCar/TaxiCar.tsx +1 -1
- package/src/business-components/WalkingLine/WalkingLine.tsx +1 -1
- package/src/business-components/WalkingRoute/WalkingRoute.tsx +2 -3
- package/src/business-components/WaveCircle/WaveCircle.tsx +1 -1
- package/src/components/Amap/Amap.ts +1 -1
- package/src/components/AmapInfoWindow/AmapInfoWindow.ts +1 -1
- package/src/components/AmapLoader/AmapLoader.ts +6 -54
- package/src/components/AmapMarker/AmapMarker.ts +5 -2
- package/src/components/AmapPolygon/AmapPolygon.ts +1 -1
- package/src/components/AmapPolyline/AmapPolyline.ts +1 -1
- package/src/components/AmapText/AmapText.ts +1 -1
- package/src/components/Demo/Demo.css.ts +1 -1
- package/src/components/Demo/HeycarDemo.tsx +50 -33
- package/src/components/Demo/SearchDemo.tsx +40 -65
- package/src/components/Demo/searchResult.ts +12888 -1
- package/src/components/Gmap/Gmap.ts +17 -5
- package/src/components/GmapAdvancedMarkerView/GmapAdvancedMarkerView.ts +9 -4
- package/src/components/GmapInfoWindow/GmapInfoWindow.ts +1 -1
- package/src/components/GmapLoader/GmapLoader.ts +4 -62
- package/src/components/GmapMarker/GmapMarker.ts +5 -2
- package/src/components/GmapPolygon/GmapPolygon.ts +1 -1
- package/src/components/GmapPolyline/GmapPolyline.ts +1 -1
- package/src/components/MapProvider/MapProvider.tsx +33 -50
- package/src/hooks/useDrivingRoute.ts +1 -1
- package/src/hooks/useGeoLocation.ts +4 -2
- package/src/hooks/useHeycarMap.ts +1 -1
- package/src/hooks/useMap.ts +29 -0
- package/src/hooks/useMapAngle.ts +1 -1
- package/src/hooks/useMapAutoComplete.ts +16 -19
- package/src/hooks/useMapCityBound.ts +36 -24
- package/src/hooks/useMapDrag.ts +1 -1
- package/src/hooks/useMapEventSource.ts +20 -0
- package/src/hooks/useMapFitView.ts +127 -0
- package/src/hooks/useMapLoader.ts +164 -0
- package/src/hooks/useMapPlace.ts +20 -22
- package/src/hooks/useMapRecomendPlace.ts +18 -25
- package/src/{components/MapProvider → hooks}/useMapSupplier.ts +4 -7
- package/src/hooks/useOverlay.ts +22 -0
- package/src/hooks/useWalkingRoute.ts +1 -1
- package/src/hooks-business/useBusinessMapAutoComplete.ts +13 -7
- package/src/hooks-business/useBusinessMapRecomendPlace.ts +10 -10
- package/src/index.ts +2 -0
- package/src/types/interface.ts +5 -0
- package/dist/components/Amap/useAmap.d.ts +0 -399
- package/dist/components/Gmap/useGmap.d.ts +0 -5
- package/dist/components/MapProvider/useMapSupplier.d.ts +0 -11
- package/dist/hooks/useMapReady.d.ts +0 -4
- package/src/components/Amap/useAmap.ts +0 -9
- package/src/components/Gmap/useGmap.ts +0 -7
- 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
|
+
};
|
package/src/hooks/useMapPlace.ts
CHANGED
|
@@ -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 {
|
|
5
|
-
import { geocoderResult2cityName
|
|
6
|
-
import {
|
|
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
|
|
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
|
|
15
|
-
const {
|
|
16
|
-
const {
|
|
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
|
-
|
|
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
|
|
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
|
-
|
|
40
|
+
onChange?.({ lng, lat, name, cityName });
|
|
41
41
|
return;
|
|
42
42
|
}
|
|
43
43
|
|
|
44
44
|
case "no_data":
|
|
45
45
|
place.name = "";
|
|
46
|
-
|
|
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
|
|
58
|
-
const {
|
|
59
|
-
const {
|
|
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
|
-
|
|
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
|
-
|
|
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 {
|
|
3
|
-
import
|
|
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 {
|
|
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<
|
|
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<
|
|
43
|
-
const { pointRef,
|
|
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 {
|
|
47
|
-
const { place, updatePlace } = useAmapPlace({ pointRef,
|
|
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
|
-
|
|
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
|
-
|
|
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<
|
|
67
|
-
const { pointRef,
|
|
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 {
|
|
71
|
-
const { place, updatePlace } = useGmapPlace({ pointRef,
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
4
|
-
export interface MapSupplierPayolad {
|
|
5
|
-
gmapKey: string;
|
|
4
|
+
export interface MapSupplierPayolad extends UseMapLoaderProps {
|
|
6
5
|
gmapId: string;
|
|
7
|
-
|
|
8
|
-
|
|
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
|
-
|
|
7
|
-
defaultCityName: string;
|
|
6
|
+
cityNameRef: Ref<string>;
|
|
8
7
|
}
|
|
9
8
|
|
|
10
9
|
export const useBusinessMapAutoComplete = (props: UseBusinessMapAutoCompleteProps) => {
|
|
11
|
-
const {
|
|
12
|
-
const city = useMapBoundCity({
|
|
13
|
-
|
|
14
|
-
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
54
|
+
readyPromise.then(() => {
|
|
55
55
|
centerSource.source = "default";
|
|
56
56
|
updatePlace();
|
|
57
57
|
});
|
|
58
58
|
}
|
|
59
|
-
const { geoLoading, geoError, geoPosition, geoCoordinate } = useGeoLocation({
|
|
60
|
-
|
|
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";
|