@heycar/heycars-map 0.1.3 → 0.1.5
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 +6 -2
- package/dist/business-components/AddressBox/AddressBox.d.ts +1 -0
- package/dist/business-components/DrivingRoute/DrivingRoute.d.ts +5 -5
- package/dist/components/Amap/Amap.d.ts +3 -1
- package/dist/components/MapProvider/MapProvider.d.ts +1 -0
- package/dist/hooks/useGeoLocation.d.ts +22 -0
- package/dist/hooks/useMapAngle.d.ts +8 -9
- package/dist/hooks/useMapDrag.d.ts +10 -23
- package/dist/hooks/useMapPlace.d.ts +23 -0
- package/dist/hooks/useMapReady.d.ts +4 -0
- package/dist/hooks/useMapRecomendPlace.d.ts +27 -0
- package/dist/hooks-business/useBusinessMapRecomendPlace.d.ts +22 -0
- package/dist/index.cjs +48 -48
- package/dist/index.d.ts +4 -1
- package/dist/index.js +875 -710
- package/dist/style.css +1 -1
- package/dist/types/interface.d.ts +5 -0
- package/dist/utils/transform.d.ts +4 -0
- package/package.json +1 -1
- package/src/business-components/AddressBox/AddressBox.tsx +9 -3
- package/src/business-components/DrivingLine/DrivingLine.tsx +1 -0
- package/src/business-components/DrivingRoute/DrivingRoute.tsx +20 -15
- package/src/components/Amap/Amap.ts +15 -3
- package/src/components/AmapLoader/AmapLoader.ts +1 -1
- package/src/components/Demo/HeycarDemo.tsx +32 -8
- package/src/components/MapProvider/MapProvider.tsx +6 -2
- package/src/hooks/useDrivingRoute.ts +24 -22
- package/src/hooks/useGeoLocation.ts +44 -0
- package/src/hooks/useMapAngle.ts +12 -13
- package/src/hooks/useMapDrag.ts +30 -44
- package/src/hooks/useMapPlace.ts +66 -0
- package/src/hooks/useMapReady.ts +14 -0
- package/src/hooks/useMapRecomendPlace.ts +78 -0
- package/src/hooks-business/useBusinessMapRecomendPlace.ts +72 -0
- package/src/index.ts +4 -1
- package/src/types/interface.ts +5 -0
- package/src/utils/transform.ts +14 -0
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import { reactive, Ref, watchEffect } from "vue-demi";
|
|
2
|
+
import { useMapSupplier } from "../components/MapProvider/useMapSupplier";
|
|
3
|
+
import { LANGUAGE } from "../types/helper";
|
|
4
|
+
import type { MapShallowRef, Place, Point } from "../types/interface";
|
|
5
|
+
import { useMapReady } from "./useMapReady";
|
|
6
|
+
|
|
7
|
+
export interface UseMapPlaceProps<M = AMap.Map | google.maps.Map> {
|
|
8
|
+
pointRef: Ref<Point>;
|
|
9
|
+
mapRef: MapShallowRef<M>;
|
|
10
|
+
onChange?: (value: Place) => any;
|
|
11
|
+
}
|
|
12
|
+
export const useAmapPlace = (props: UseMapPlaceProps<AMap.Map>) => {
|
|
13
|
+
const { mapRef, pointRef, onChange } = props;
|
|
14
|
+
const { readyRef } = useMapReady(mapRef);
|
|
15
|
+
const place = reactive<Place>({ lng: pointRef.value[0], lat: pointRef.value[1], name: "" });
|
|
16
|
+
watchEffect(() => {
|
|
17
|
+
if (!readyRef.value) return;
|
|
18
|
+
const geocoder = new AMap.Geocoder({ lang: LANGUAGE });
|
|
19
|
+
const [lng, lat] = pointRef.value;
|
|
20
|
+
place.lng = lng;
|
|
21
|
+
place.lat = lat;
|
|
22
|
+
geocoder.getAddress(new AMap.LngLat(lng, lat), (status, result) => {
|
|
23
|
+
switch (status) {
|
|
24
|
+
case "complete": {
|
|
25
|
+
const name = (result as AMap.ReGeocoderResult).regeocode.formattedAddress;
|
|
26
|
+
place.name = name;
|
|
27
|
+
onChange?.({ lng, lat, name });
|
|
28
|
+
return;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
case "no_data":
|
|
32
|
+
place.name = "";
|
|
33
|
+
onChange?.({ lng, lat, name: "" });
|
|
34
|
+
return;
|
|
35
|
+
case "error":
|
|
36
|
+
throw result;
|
|
37
|
+
}
|
|
38
|
+
});
|
|
39
|
+
});
|
|
40
|
+
return place;
|
|
41
|
+
};
|
|
42
|
+
|
|
43
|
+
export const useGmapPlace = (props: UseMapPlaceProps<google.maps.Map>) => {
|
|
44
|
+
const { mapRef, pointRef, onChange } = props;
|
|
45
|
+
const { readyRef } = useMapReady(mapRef);
|
|
46
|
+
const place = reactive<Place>({ lng: pointRef.value[0], lat: pointRef.value[1], name: "" });
|
|
47
|
+
watchEffect(async () => {
|
|
48
|
+
if (!readyRef.value) return;
|
|
49
|
+
const geocoder = new google.maps.Geocoder();
|
|
50
|
+
const [lng, lat] = pointRef.value;
|
|
51
|
+
place.lng = lng;
|
|
52
|
+
place.lat = lat;
|
|
53
|
+
const { results } = await geocoder.geocode({ language: LANGUAGE, location: { lng, lat } });
|
|
54
|
+
const name = results[0].formatted_address;
|
|
55
|
+
place.name = name;
|
|
56
|
+
onChange?.({ lng, lat, name });
|
|
57
|
+
});
|
|
58
|
+
return place;
|
|
59
|
+
};
|
|
60
|
+
|
|
61
|
+
export const useMapPlace = (props: UseMapPlaceProps) => {
|
|
62
|
+
const { supplier } = useMapSupplier();
|
|
63
|
+
return supplier === "gmap"
|
|
64
|
+
? useGmapPlace(props as UseMapPlaceProps<google.maps.Map>)
|
|
65
|
+
: useAmapPlace(props as UseMapPlaceProps<AMap.Map>);
|
|
66
|
+
};
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { ref, watch } from "vue-demi";
|
|
2
|
+
import type { MapShallowRef } from "../types/interface";
|
|
3
|
+
|
|
4
|
+
export const useMapReady = (mapRef: MapShallowRef) => {
|
|
5
|
+
const readyRef = ref(!!mapRef.value);
|
|
6
|
+
watch(
|
|
7
|
+
() => mapRef.value,
|
|
8
|
+
(map) => {
|
|
9
|
+
if (!map) return;
|
|
10
|
+
readyRef.value = true;
|
|
11
|
+
}
|
|
12
|
+
);
|
|
13
|
+
return { readyRef };
|
|
14
|
+
};
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import { reactive, Ref, watchEffect } from "vue-demi";
|
|
2
|
+
import { useMapSupplier } from "../components/MapProvider/useMapSupplier";
|
|
3
|
+
import type { MapShallowRef, Place, Point } from "../types/interface";
|
|
4
|
+
import { place2point } from "../utils/transform";
|
|
5
|
+
import { useAmapPlace, useGmapPlace, UseMapPlaceProps } from "./useMapPlace";
|
|
6
|
+
import { useMapReady } from "./useMapReady";
|
|
7
|
+
|
|
8
|
+
const findAmapNearestPlace = (place: Place, candidates: Place[]) => {
|
|
9
|
+
let shortestDistance = Infinity;
|
|
10
|
+
let shortestPlace = place;
|
|
11
|
+
for (const candidate of candidates) {
|
|
12
|
+
const distance = AMap.GeometryUtil.distance(place2point(place), place2point(candidate));
|
|
13
|
+
if (distance >= shortestDistance) continue;
|
|
14
|
+
shortestPlace = candidate;
|
|
15
|
+
shortestDistance = distance;
|
|
16
|
+
}
|
|
17
|
+
return { shortestPlace, shortestDistance };
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
const findGmapNearestPlace = (place: Place, candidates: Place[]) => {
|
|
21
|
+
let shortestDistance = Infinity;
|
|
22
|
+
let shortestPlace = place;
|
|
23
|
+
for (const candidate of candidates) {
|
|
24
|
+
const distance = google.maps.geometry.spherical.computeDistanceBetween(place, candidate);
|
|
25
|
+
if (distance >= shortestDistance) continue;
|
|
26
|
+
shortestPlace = candidate;
|
|
27
|
+
shortestDistance = distance;
|
|
28
|
+
}
|
|
29
|
+
return { shortestPlace, shortestDistance };
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
export interface UseMapRecomendPlaceProps<M = AMap.Map | google.maps.Map> {
|
|
33
|
+
mapRef: MapShallowRef<M>;
|
|
34
|
+
pointRef: Ref<Point>;
|
|
35
|
+
limit: number;
|
|
36
|
+
getRecomendPlace: (place: Place) => Promise<Place[]>;
|
|
37
|
+
onChangePlace?: UseMapPlaceProps["onChange"];
|
|
38
|
+
onChange?: (place: Place) => any;
|
|
39
|
+
}
|
|
40
|
+
export const useAmapRecomendPlace = (props: UseMapRecomendPlaceProps<AMap.Map>) => {
|
|
41
|
+
const { pointRef, mapRef, getRecomendPlace, limit, onChange, onChangePlace } = props;
|
|
42
|
+
const { readyRef } = useMapReady(mapRef);
|
|
43
|
+
const place = useAmapPlace({ pointRef, mapRef, onChange: onChangePlace });
|
|
44
|
+
const recomendPlace = reactive<Place>({ ...place });
|
|
45
|
+
watchEffect(async () => {
|
|
46
|
+
if (!readyRef.value) return;
|
|
47
|
+
const placeCandidates = await getRecomendPlace({ ...place });
|
|
48
|
+
const { shortestPlace, shortestDistance } = findAmapNearestPlace(place, placeCandidates);
|
|
49
|
+
console.log("shortestPlace, shortestDistance = ", shortestPlace, shortestDistance);
|
|
50
|
+
const resultPlace = shortestDistance > limit ? place : shortestPlace;
|
|
51
|
+
Object.assign(recomendPlace, { ...resultPlace });
|
|
52
|
+
onChange?.({ ...resultPlace });
|
|
53
|
+
});
|
|
54
|
+
return recomendPlace;
|
|
55
|
+
};
|
|
56
|
+
|
|
57
|
+
export const useGmapRecomendPlace = (props: UseMapRecomendPlaceProps<google.maps.Map>) => {
|
|
58
|
+
const { pointRef, mapRef, getRecomendPlace, limit, onChange, onChangePlace } = props;
|
|
59
|
+
const { readyRef } = useMapReady(mapRef);
|
|
60
|
+
const place = useGmapPlace({ pointRef, mapRef, onChange: onChangePlace });
|
|
61
|
+
const recomendPlace = reactive<Place>({ ...place });
|
|
62
|
+
watchEffect(async () => {
|
|
63
|
+
if (!readyRef.value) return;
|
|
64
|
+
const placeCandidates = await getRecomendPlace({ ...place });
|
|
65
|
+
const { shortestPlace, shortestDistance } = findGmapNearestPlace(place, placeCandidates);
|
|
66
|
+
const resultPlace = shortestDistance > limit ? place : shortestPlace;
|
|
67
|
+
Object.assign(recomendPlace, { ...resultPlace });
|
|
68
|
+
onChange?.({ ...resultPlace });
|
|
69
|
+
});
|
|
70
|
+
return recomendPlace;
|
|
71
|
+
};
|
|
72
|
+
|
|
73
|
+
export const useMapRecomendPlace = (props: UseMapRecomendPlaceProps) => {
|
|
74
|
+
const { supplier } = useMapSupplier();
|
|
75
|
+
return supplier === "gmap"
|
|
76
|
+
? useGmapRecomendPlace(props as UseMapRecomendPlaceProps<google.maps.Map>)
|
|
77
|
+
: useAmapRecomendPlace(props as UseMapRecomendPlaceProps<AMap.Map>);
|
|
78
|
+
};
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import { computed, reactive } from "vue-demi";
|
|
2
|
+
import { useGeoLocation, UseGeoLocationProps } from "../hooks/useGeoLocation";
|
|
3
|
+
import { useMapDrag } from "../hooks/useMapDrag";
|
|
4
|
+
import type { UseMapPlaceProps } from "../hooks/useMapPlace";
|
|
5
|
+
import { useMapRecomendPlace, UseMapRecomendPlaceProps } from "../hooks/useMapRecomendPlace";
|
|
6
|
+
import type { Place, Point } from "../types/interface";
|
|
7
|
+
|
|
8
|
+
export interface UseBusinessMapRecomendPlaceProps
|
|
9
|
+
extends Pick<UseMapRecomendPlaceProps, "getRecomendPlace" | "mapRef"> {
|
|
10
|
+
recomendPlaceGeoLimit: number;
|
|
11
|
+
recomendPlaceDragLimit: number;
|
|
12
|
+
onChangeGeoLocation?: UseGeoLocationProps["onChange"];
|
|
13
|
+
onChangePlace?: UseMapPlaceProps["onChange"];
|
|
14
|
+
onChangeRecomandPlace?: UseMapRecomendPlaceProps["onChange"];
|
|
15
|
+
}
|
|
16
|
+
export const useBusinessMapRecomendPlace = (props: UseBusinessMapRecomendPlaceProps) => {
|
|
17
|
+
const centerPlace = reactive<Place>({ lng: 0, lat: 0, name: "" });
|
|
18
|
+
const centerPoint = computed<Point>(() => [centerPlace.lng, centerPlace.lat]);
|
|
19
|
+
const {
|
|
20
|
+
mapRef,
|
|
21
|
+
getRecomendPlace,
|
|
22
|
+
recomendPlaceDragLimit,
|
|
23
|
+
recomendPlaceGeoLimit,
|
|
24
|
+
onChangeGeoLocation,
|
|
25
|
+
onChangePlace,
|
|
26
|
+
onChangeRecomandPlace,
|
|
27
|
+
} = props;
|
|
28
|
+
const { positionRef, loading, errorRef } = useGeoLocation({
|
|
29
|
+
mapRef,
|
|
30
|
+
onChange: (value) => {
|
|
31
|
+
centerPlace.lng = value.position[0];
|
|
32
|
+
centerPlace.lat = value.position[1];
|
|
33
|
+
onChangeGeoLocation?.(value);
|
|
34
|
+
},
|
|
35
|
+
});
|
|
36
|
+
const { centerRef, isDragging } = useMapDrag({ mapRef });
|
|
37
|
+
useMapRecomendPlace({
|
|
38
|
+
pointRef: positionRef,
|
|
39
|
+
getRecomendPlace,
|
|
40
|
+
limit: recomendPlaceGeoLimit,
|
|
41
|
+
mapRef,
|
|
42
|
+
onChangePlace: (place) => {
|
|
43
|
+
Object.assign(centerPlace, { ...place });
|
|
44
|
+
onChangePlace?.(place);
|
|
45
|
+
},
|
|
46
|
+
onChange: (place) => {
|
|
47
|
+
Object.assign(centerPlace, { ...place });
|
|
48
|
+
onChangeRecomandPlace?.(place);
|
|
49
|
+
},
|
|
50
|
+
});
|
|
51
|
+
useMapRecomendPlace({
|
|
52
|
+
pointRef: centerRef,
|
|
53
|
+
getRecomendPlace,
|
|
54
|
+
limit: recomendPlaceDragLimit,
|
|
55
|
+
mapRef,
|
|
56
|
+
onChangePlace: (place) => {
|
|
57
|
+
Object.assign(centerPlace, { ...place });
|
|
58
|
+
onChangePlace?.(place);
|
|
59
|
+
},
|
|
60
|
+
onChange: (place) => {
|
|
61
|
+
Object.assign(centerPlace, { ...place });
|
|
62
|
+
onChangeRecomandPlace?.(place);
|
|
63
|
+
},
|
|
64
|
+
});
|
|
65
|
+
return {
|
|
66
|
+
isDragging,
|
|
67
|
+
isGeoLoading: loading,
|
|
68
|
+
geoError: errorRef,
|
|
69
|
+
centerPlace,
|
|
70
|
+
centerPoint,
|
|
71
|
+
};
|
|
72
|
+
};
|
package/src/index.ts
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import "./style.css";
|
|
2
2
|
export { AddressBox } from "./business-components/AddressBox";
|
|
3
|
-
export { AddressLocator } from "./business-components/AddressLocator";
|
|
4
3
|
export { DrivingLine } from "./business-components/DrivingLine";
|
|
5
4
|
export { DrivingRoute } from "./business-components/DrivingRoute";
|
|
6
5
|
export { PassengerCircle } from "./business-components/PassengerCircle";
|
|
@@ -11,8 +10,12 @@ export { TaxiCar } from "./business-components/TaxiCar";
|
|
|
11
10
|
export { WalkingLine } from "./business-components/WalkingLine";
|
|
12
11
|
export { WaveCircle } from "./business-components/WaveCircle";
|
|
13
12
|
export * from "./components/MapProvider";
|
|
13
|
+
export { useBusinessMapRecomendPlace } from "./hooks-business/useBusinessMapRecomendPlace";
|
|
14
14
|
export { useDrivingRoute } from "./hooks/useDrivingRoute";
|
|
15
|
+
export { useGeoLocation } from "./hooks/useGeoLocation";
|
|
15
16
|
export { useHeycarMap } from "./hooks/useHeycarMap";
|
|
16
17
|
export { useMapAngle } from "./hooks/useMapAngle";
|
|
17
18
|
export { useMapDrag } from "./hooks/useMapDrag";
|
|
19
|
+
export { useMapPlace } from "./hooks/useMapPlace";
|
|
20
|
+
export { useMapRecomendPlace } from "./hooks/useMapRecomendPlace";
|
|
18
21
|
export * from "./types/interface";
|
package/src/types/interface.ts
CHANGED
package/src/utils/transform.ts
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import type { Place, Point } from "../types/interface";
|
|
2
|
+
|
|
1
3
|
export const vec2lnglat = ([lng, lat]: [number, number]): google.maps.LatLngLiteral => ({
|
|
2
4
|
lng,
|
|
3
5
|
lat,
|
|
@@ -25,3 +27,15 @@ export const property2emitEventName = (propertyName: string) => {
|
|
|
25
27
|
export const property2mapEventName = (propertyName: string) => {
|
|
26
28
|
return propertyName.slice(2).toLowerCase();
|
|
27
29
|
};
|
|
30
|
+
|
|
31
|
+
export type VectorMapForeign = "style_en" | "style_local" | "style_zh_cn";
|
|
32
|
+
export const language2vectorMapForeign = (lang: "en" | "zh"): VectorMapForeign => {
|
|
33
|
+
switch (lang) {
|
|
34
|
+
case "en":
|
|
35
|
+
return "style_en";
|
|
36
|
+
case "zh":
|
|
37
|
+
return "style_zh_cn";
|
|
38
|
+
}
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
export const place2point = (place: Place): Point => [place.lng, place.lat];
|