@heycar/heycars-map 0.1.6 → 0.1.8
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/dist/business-components/PickupPoints/PickupPoints.d.ts +2 -2
- package/dist/business-components/WalkingRoute/WalkingRoute.d.ts +13 -0
- package/dist/business-components/WalkingRoute/index.d.ts +1 -0
- package/dist/components/Demo/HeycarDemo.d.ts +1 -0
- package/dist/components/Demo/SearchDemo.d.ts +1 -0
- package/dist/components/Demo/country.d.ts +5 -0
- package/dist/components/Demo/searchResult.d.ts +8 -0
- package/dist/hooks/useGeoLocation.d.ts +8 -4
- package/dist/hooks/useMapAutoComplete.d.ts +42 -0
- package/dist/hooks/useMapCityBound.d.ts +10 -0
- package/dist/hooks/useMapPlace.d.ts +3 -0
- package/dist/hooks/useMapRecomendPlace.d.ts +21 -0
- package/dist/hooks/useWalkingRoute.d.ts +9 -0
- package/dist/hooks-business/useBusinessMapAutoComplete.d.ts +18 -0
- package/dist/hooks-business/useBusinessMapRecomendPlace.d.ts +22 -2
- package/dist/index.cjs +52 -52
- package/dist/index.js +813 -792
- package/dist/types/interface.d.ts +14 -0
- package/dist/utils/transform.d.ts +1 -0
- package/package.json +2 -2
- package/src/App.tsx +1 -0
- package/src/business-components/PickupPoints/PickupPoints.tsx +5 -4
- package/src/business-components/WalkingRoute/WalkingRoute.tsx +48 -0
- package/src/business-components/WalkingRoute/index.ts +1 -0
- package/src/components/Demo/HeycarDemo.tsx +59 -10
- package/src/components/Demo/SearchDemo.tsx +167 -0
- package/src/components/Demo/country.ts +4179 -0
- package/src/components/Demo/searchResult.ts +8235 -0
- package/src/components/GmapAdvancedMarkerView/GmapAdvancedMarkerView.ts +0 -1
- package/src/hooks/useDrivingRoute.ts +1 -1
- package/src/hooks/useGeoLocation.ts +21 -17
- package/src/hooks/useMapAutoComplete.ts +116 -0
- package/src/hooks/useMapCityBound.ts +52 -0
- package/src/hooks/useMapPlace.ts +14 -11
- package/src/hooks/useMapRecomendPlace.ts +7 -9
- package/src/hooks/useWalkingRoute.ts +70 -0
- package/src/hooks-business/useBusinessMapAutoComplete.ts +16 -0
- package/src/hooks-business/useBusinessMapRecomendPlace.ts +47 -14
- package/src/types/amap/place.d.ts +1 -1
- package/src/types/amap/walking.d.ts +3 -1
- package/src/types/interface.ts +16 -0
- package/src/utils/transform.ts +13 -0
- package/todo.md +3 -0
|
@@ -6,4 +6,18 @@ export type Place = {
|
|
|
6
6
|
lng: number;
|
|
7
7
|
lat: number;
|
|
8
8
|
name: string;
|
|
9
|
+
cityName?: string;
|
|
10
|
+
};
|
|
11
|
+
export interface AutoCompletePlace extends Place {
|
|
12
|
+
placeId?: string;
|
|
13
|
+
description: string;
|
|
14
|
+
}
|
|
15
|
+
export type City = {
|
|
16
|
+
bound?: {
|
|
17
|
+
east: number;
|
|
18
|
+
north: number;
|
|
19
|
+
south: number;
|
|
20
|
+
west: number;
|
|
21
|
+
};
|
|
22
|
+
name: string;
|
|
9
23
|
};
|
|
@@ -12,3 +12,4 @@ export type VectorMapForeign = "style_en" | "style_local" | "style_zh_cn";
|
|
|
12
12
|
export declare const language2vectorMapForeign: (lang: "en" | "zh") => VectorMapForeign;
|
|
13
13
|
export declare const place2point: (place: Place) => Point;
|
|
14
14
|
export declare const pipeAsync: <P extends any[]>(fn?: ((...args: P) => any) | undefined) => (...args: P) => void;
|
|
15
|
+
export declare const geocoderResult2cityName: (value: google.maps.GeocoderResult) => string | undefined;
|
package/package.json
CHANGED
package/src/App.tsx
CHANGED
|
@@ -1,15 +1,16 @@
|
|
|
1
1
|
import { defineSetup } from "../../types/helper";
|
|
2
|
+
import type { Place } from "../../types/interface";
|
|
3
|
+
import { place2point } from "../../utils/transform";
|
|
2
4
|
import { PlaceCircle } from "../PlaceCircle";
|
|
3
5
|
|
|
4
6
|
export interface PickupPointsProps {
|
|
5
|
-
|
|
6
|
-
labels: string[];
|
|
7
|
+
places: Place[];
|
|
7
8
|
}
|
|
8
9
|
export const PickupPoints = defineSetup(function PickupPoints(props: PickupPointsProps) {
|
|
9
10
|
return () => (
|
|
10
11
|
<div>
|
|
11
|
-
{props.
|
|
12
|
-
<PlaceCircle position={
|
|
12
|
+
{props.places.map((place) => (
|
|
13
|
+
<PlaceCircle position={place2point(place)} label={place.name} textAlign="left" />
|
|
13
14
|
))}
|
|
14
15
|
</div>
|
|
15
16
|
);
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { reactive, VNodeData } from "vue-demi";
|
|
2
|
+
import { useAmap } from "../../components/Amap/useAmap";
|
|
3
|
+
import { useGmap } from "../../components/Gmap/useGmap";
|
|
4
|
+
import { useMapSupplier } from "../../components/MapProvider/useMapSupplier";
|
|
5
|
+
import { useAmapAngle, useGmapAngle } from "../../hooks/useMapAngle";
|
|
6
|
+
import {
|
|
7
|
+
useAWalkingRoute,
|
|
8
|
+
useGWalkingRoute,
|
|
9
|
+
UseWalkingRouteProps,
|
|
10
|
+
} from "../../hooks/useWalkingRoute";
|
|
11
|
+
import { createElement, defineSetup, VNodeChild } from "../../types/helper";
|
|
12
|
+
import type { Point } from "../../types/interface";
|
|
13
|
+
|
|
14
|
+
export type WalkingRouteRenderProps = {
|
|
15
|
+
path: Point[];
|
|
16
|
+
angle?: number;
|
|
17
|
+
};
|
|
18
|
+
export interface WalkingRouteProps extends UseWalkingRouteProps {
|
|
19
|
+
render?: (props: WalkingRouteRenderProps) => VNodeChild;
|
|
20
|
+
}
|
|
21
|
+
export const AWalkingRoute = defineSetup(function WalkingRoute(
|
|
22
|
+
props: WalkingRouteProps,
|
|
23
|
+
{ slots }
|
|
24
|
+
) {
|
|
25
|
+
const map = useAmap();
|
|
26
|
+
const path = useAWalkingRoute(props);
|
|
27
|
+
const angle = useAmapAngle(reactive({ path, map }));
|
|
28
|
+
return () => <div>{slots.render?.(reactive({ path, angle }))}</div>;
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
export const GWalkingRoute = defineSetup(function WalkingRoute(
|
|
32
|
+
props: WalkingRouteProps,
|
|
33
|
+
{ slots }
|
|
34
|
+
) {
|
|
35
|
+
const map = useGmap();
|
|
36
|
+
const path = useGWalkingRoute(props);
|
|
37
|
+
const angle = useGmapAngle(reactive({ path, map }));
|
|
38
|
+
return () => <div>{slots.render?.(reactive({ path, angle }))}</div>;
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
export const WalkingRoute = defineSetup(function WalkingRoute(props: WalkingRouteProps, { slots }) {
|
|
42
|
+
const { supplier } = useMapSupplier();
|
|
43
|
+
return () =>
|
|
44
|
+
createElement(supplier === "gmap" ? GWalkingRoute : AWalkingRoute, {
|
|
45
|
+
attrs: props,
|
|
46
|
+
scopedSlots: slots as VNodeData["scopedSlots"],
|
|
47
|
+
});
|
|
48
|
+
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from "./WalkingRoute";
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { AddressBox } from "../../business-components/AddressBox";
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
2
|
+
import { PickupPoints } from "../../business-components/PickupPoints";
|
|
3
|
+
import { WalkingLine } from "../../business-components/WalkingLine";
|
|
4
|
+
import { WalkingRoute } from "../../business-components/WalkingRoute";
|
|
5
|
+
import { useBusinessMapAutoComplete } from "../../hooks-business/useBusinessMapAutoComplete";
|
|
5
6
|
import {
|
|
6
7
|
useBusinessMapRecomendPlace,
|
|
7
8
|
UseBusinessMapRecomendPlaceProps,
|
|
@@ -23,14 +24,45 @@ export const HeycarDemo = defineSetup(function HeycarDemo() {
|
|
|
23
24
|
amapSecret={amapApiSecret}
|
|
24
25
|
gmapId={gmapId}
|
|
25
26
|
gmapKey={gmapApiKey}
|
|
26
|
-
supplier={"
|
|
27
|
+
supplier={"gmap"}
|
|
27
28
|
>
|
|
28
|
-
<
|
|
29
|
+
<SomeHomePage />
|
|
29
30
|
</MapProvider>
|
|
30
31
|
);
|
|
31
32
|
});
|
|
32
33
|
|
|
33
34
|
export const SomePage = defineSetup(function Hello() {
|
|
35
|
+
const { mapRef, setMap } = useHeycarMap();
|
|
36
|
+
const cityName = "上海市";
|
|
37
|
+
const { autoCompletePlaces, setKeyword, setCity } = useBusinessMapAutoComplete({
|
|
38
|
+
mapRef,
|
|
39
|
+
defaultCityName: cityName,
|
|
40
|
+
});
|
|
41
|
+
(window as any).setKeyword = setKeyword;
|
|
42
|
+
(window as any).setCity = setCity;
|
|
43
|
+
return () => {
|
|
44
|
+
const list = autoCompletePlaces.value.map((place) => (
|
|
45
|
+
<div>
|
|
46
|
+
{place.lng} | {place.lat} | {place.name} | {place.description}
|
|
47
|
+
</div>
|
|
48
|
+
));
|
|
49
|
+
return (
|
|
50
|
+
<div>
|
|
51
|
+
<div>{list}</div>
|
|
52
|
+
<HeycarMap
|
|
53
|
+
class={css.demo}
|
|
54
|
+
fallback={() => <div>error</div>}
|
|
55
|
+
loading={() => <div>loading</div>}
|
|
56
|
+
center={[131, 21]}
|
|
57
|
+
zoom={3}
|
|
58
|
+
mapRef={setMap}
|
|
59
|
+
></HeycarMap>
|
|
60
|
+
</div>
|
|
61
|
+
);
|
|
62
|
+
};
|
|
63
|
+
});
|
|
64
|
+
|
|
65
|
+
export const SomeHomePage = defineSetup(function Hello() {
|
|
34
66
|
const { mapRef, setMap, panTo } = useHeycarMap();
|
|
35
67
|
const getRecomendPlace: UseBusinessMapRecomendPlaceProps["getRecomendPlace"] = async (
|
|
36
68
|
place,
|
|
@@ -40,8 +72,17 @@ export const SomePage = defineSetup(function Hello() {
|
|
|
40
72
|
console.log("getRecomendPlace context?.source = ", context?.source);
|
|
41
73
|
return [{ lat: lat + 0.0001, lng: lng + 0.0001, name: "place name 1" }];
|
|
42
74
|
};
|
|
43
|
-
const {
|
|
75
|
+
const {
|
|
76
|
+
centerPlace,
|
|
77
|
+
centerPoint,
|
|
78
|
+
placeCandidates,
|
|
79
|
+
isDragging,
|
|
80
|
+
geoLoading,
|
|
81
|
+
geoPosition,
|
|
82
|
+
setCenterPlaceByRecomand,
|
|
83
|
+
} = useBusinessMapRecomendPlace({
|
|
44
84
|
mapRef,
|
|
85
|
+
defaultCenterPoint: [131, 31],
|
|
45
86
|
recomendPlaceGeoLimit: 300,
|
|
46
87
|
recomendPlaceDragLimit: 30,
|
|
47
88
|
getRecomendPlace,
|
|
@@ -49,13 +90,15 @@ export const SomePage = defineSetup(function Hello() {
|
|
|
49
90
|
onChangePlace: (v) => console.log("onChangePlace: ", v),
|
|
50
91
|
onChangeRecomandPlace: (v) => console.log("onChangeRecomandPlace: ", v),
|
|
51
92
|
});
|
|
52
|
-
(window as any).
|
|
93
|
+
(window as any).setCenterPlaceByRecomand = setCenterPlaceByRecomand;
|
|
53
94
|
return () => {
|
|
54
95
|
return (
|
|
55
96
|
<div>
|
|
56
|
-
|
|
97
|
+
geoLoading: {`${geoLoading.value}`} <br />
|
|
57
98
|
isDragging: {`${isDragging.value}`} <br />
|
|
58
|
-
|
|
99
|
+
geoPosition: {geoPosition.value[0]} | {geoPosition.value[1]} <br />
|
|
100
|
+
centerPlace: {centerPlace.lng} | {centerPlace.lat} | {centerPlace.name} |{" "}
|
|
101
|
+
{centerPlace.cityName} <br />
|
|
59
102
|
<HeycarMap
|
|
60
103
|
class={css.demo}
|
|
61
104
|
fallback={() => <div>error</div>}
|
|
@@ -64,6 +107,7 @@ export const SomePage = defineSetup(function Hello() {
|
|
|
64
107
|
zoom={15}
|
|
65
108
|
mapRef={setMap}
|
|
66
109
|
>
|
|
110
|
+
<PickupPoints places={placeCandidates.value} />
|
|
67
111
|
<AddressBox
|
|
68
112
|
type="box"
|
|
69
113
|
position={centerPoint.value}
|
|
@@ -78,13 +122,18 @@ export const SomePage = defineSetup(function Hello() {
|
|
|
78
122
|
]}
|
|
79
123
|
labels={["place name 1", "place name 2"]}
|
|
80
124
|
/> */}
|
|
81
|
-
<DrivingRoute
|
|
125
|
+
{/* <DrivingRoute
|
|
82
126
|
from={[121, 31]}
|
|
83
127
|
to={[121.6, 31.3]}
|
|
84
128
|
render={({ path, angle }) => [
|
|
85
129
|
<DrivingLine path={path} />,
|
|
86
130
|
<TaxiCar position={[121, 31]} angle={angle} />,
|
|
87
131
|
]}
|
|
132
|
+
/> */}
|
|
133
|
+
<WalkingRoute
|
|
134
|
+
from={centerPoint.value}
|
|
135
|
+
to={[centerPoint.value[0] + 0.1, centerPoint.value[1] + 0.1]}
|
|
136
|
+
render={({ path }) => <WalkingLine path={path} />}
|
|
88
137
|
/>
|
|
89
138
|
</HeycarMap>
|
|
90
139
|
</div>
|
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
import { watchPostEffect } from "vue-demi";
|
|
2
|
+
import { useHeycarMap } from "../../hooks/useHeycarMap";
|
|
3
|
+
import { defineSetup } from "../../types/helper";
|
|
4
|
+
import { HeycarMap, MapProvider } from "../MapProvider/MapProvider";
|
|
5
|
+
import { citiesWithCountry } from "./country";
|
|
6
|
+
import * as css from "./Demo.css";
|
|
7
|
+
import { searchResult } from "./searchResult";
|
|
8
|
+
|
|
9
|
+
const gmapApiKey = import.meta.env.VITE_GMAP_API_KEY;
|
|
10
|
+
const gmapId = import.meta.env.VITE_GMAP_MAP_ID;
|
|
11
|
+
const amapApiKey = import.meta.env.VITE_AMAP_API_KEY;
|
|
12
|
+
const amapApiSecret = import.meta.env.VITE_AMAP_API_SECRET;
|
|
13
|
+
|
|
14
|
+
export const SearchDemo = defineSetup(function HeycarDemo() {
|
|
15
|
+
return () => (
|
|
16
|
+
<MapProvider
|
|
17
|
+
amapKey={amapApiKey}
|
|
18
|
+
amapSecret={amapApiSecret}
|
|
19
|
+
gmapId={gmapId}
|
|
20
|
+
gmapKey={gmapApiKey}
|
|
21
|
+
supplier={"gmap"}
|
|
22
|
+
>
|
|
23
|
+
<SomePage />
|
|
24
|
+
</MapProvider>
|
|
25
|
+
);
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
const SomePage = defineSetup(function Hello() {
|
|
29
|
+
const { mapRef, setMap, panTo } = useHeycarMap();
|
|
30
|
+
(window as any).panTo = panTo;
|
|
31
|
+
watchPostEffect(() => {
|
|
32
|
+
const map = mapRef.value as google.maps.Map;
|
|
33
|
+
if (!map) return;
|
|
34
|
+
const searchName = async (idx: number, address: string, country: string) => {
|
|
35
|
+
const geocoder = new google.maps.Geocoder();
|
|
36
|
+
// const placeService = new google.maps.places.PlacesService(document.createElement("div"));
|
|
37
|
+
const { results } = await geocoder.geocode({
|
|
38
|
+
address,
|
|
39
|
+
componentRestrictions: {
|
|
40
|
+
country,
|
|
41
|
+
administrativeArea: "administrative_area_level_1",
|
|
42
|
+
},
|
|
43
|
+
language: "en",
|
|
44
|
+
});
|
|
45
|
+
if (results?.length === 2) {
|
|
46
|
+
const [result1, result2] = results;
|
|
47
|
+
const isResult1Admin = result1.types[0].startsWith("administrative_area_level_");
|
|
48
|
+
const isResult2Admin = result2.types[0].startsWith("administrative_area_level_");
|
|
49
|
+
if (isResult1Admin && !isResult2Admin) {
|
|
50
|
+
return result1.geometry.bounds?.toJSON();
|
|
51
|
+
}
|
|
52
|
+
if (isResult2Admin && !isResult1Admin) {
|
|
53
|
+
return result2.geometry.bounds?.toJSON();
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
if (results?.length !== 1) {
|
|
57
|
+
console.warn("length !== 1 by idx, keyword, results = ", idx, address, results);
|
|
58
|
+
return undefined;
|
|
59
|
+
}
|
|
60
|
+
const { geometry } = results[0];
|
|
61
|
+
return geometry.bounds?.toJSON() ?? geometry.viewport.toJSON();
|
|
62
|
+
|
|
63
|
+
// const autocompleteService = new google.maps.places.AutocompleteService();
|
|
64
|
+
// const placeService = new google.maps.places.PlacesService(map);
|
|
65
|
+
// const { predictions } = await autocompleteService.getPlacePredictions({
|
|
66
|
+
// input: "麦当劳",
|
|
67
|
+
// language: "zh",
|
|
68
|
+
// componentRestrictions: {
|
|
69
|
+
// country: "CN",
|
|
70
|
+
// },
|
|
71
|
+
// bounds: {
|
|
72
|
+
// // north: 122.3172401,
|
|
73
|
+
// // east: 31.8675299,
|
|
74
|
+
// // south: 120.8559198,
|
|
75
|
+
// // west: 30.6703899,
|
|
76
|
+
// north: 31.8675299,
|
|
77
|
+
// east: 122.3172401,
|
|
78
|
+
// south: 30.6703899,
|
|
79
|
+
// west: 120.8559198,
|
|
80
|
+
// },
|
|
81
|
+
// });
|
|
82
|
+
// console.log("predictions = ", predictions);
|
|
83
|
+
// if (results.length !== 1) {
|
|
84
|
+
// console.log("results = ", results);
|
|
85
|
+
// throw new Error("MyError, results.length !== 1");
|
|
86
|
+
// }
|
|
87
|
+
// const placeId = results[0].place_id;
|
|
88
|
+
// const { results: accurateResults } = await geocoder.geocode({ placeId });
|
|
89
|
+
// if (accurateResults.length !== 1) {
|
|
90
|
+
// console.log("results = ", accurateResults);
|
|
91
|
+
// throw new Error("MyError, accurateResults.length !== 1");
|
|
92
|
+
// }
|
|
93
|
+
// const detail = accurateResults[0];
|
|
94
|
+
// console.log("detail = ", detail);
|
|
95
|
+
|
|
96
|
+
// placeService.getDetails({ placeId }, (result, status) => {
|
|
97
|
+
// if (status !== google.maps.places.PlacesServiceStatus.OK) {
|
|
98
|
+
// console.log("result, status = ", result, status);
|
|
99
|
+
// throw new Error("My Error getDetails status !== ok");
|
|
100
|
+
// }
|
|
101
|
+
// console.log("detail = ", result);
|
|
102
|
+
// });
|
|
103
|
+
};
|
|
104
|
+
const wait = (seconds: number) => new Promise((r) => setTimeout(r, seconds * 1000));
|
|
105
|
+
const search = async (from: number, to: number) => {
|
|
106
|
+
const citiesSample = citiesWithCountry.slice(from, to);
|
|
107
|
+
const result: { name: string; country: string; bound: any }[] = [];
|
|
108
|
+
let idx = from;
|
|
109
|
+
try {
|
|
110
|
+
for (const city of citiesSample) {
|
|
111
|
+
if (idx % 10 === 0) {
|
|
112
|
+
console.log("start processing idx = ", idx);
|
|
113
|
+
}
|
|
114
|
+
const bound = await searchName(idx, city.name, city.country);
|
|
115
|
+
await wait(2);
|
|
116
|
+
result.push({ name: city.name, country: city.country, bound: bound ?? null });
|
|
117
|
+
idx += 1;
|
|
118
|
+
}
|
|
119
|
+
console.log("success search result = ");
|
|
120
|
+
console.log(JSON.stringify(result));
|
|
121
|
+
} catch (e) {
|
|
122
|
+
console.log("failed search break idx = ", idx);
|
|
123
|
+
console.log(JSON.stringify(result));
|
|
124
|
+
throw e;
|
|
125
|
+
}
|
|
126
|
+
};
|
|
127
|
+
|
|
128
|
+
const searchRest = async () => {
|
|
129
|
+
const notfound = searchResult.filter((item) => item.bound == null);
|
|
130
|
+
const result: { name: string; country: string; bound: any }[] = [];
|
|
131
|
+
try {
|
|
132
|
+
for (const city of notfound) {
|
|
133
|
+
try {
|
|
134
|
+
const bound = await searchName(0, city.name, city.country);
|
|
135
|
+
await wait(2);
|
|
136
|
+
result.push({ name: city.name, country: city.country, bound: bound ?? null });
|
|
137
|
+
} catch (e) {
|
|
138
|
+
console.warn("fail search name, country = ", city.name, city.country);
|
|
139
|
+
console.error(e);
|
|
140
|
+
continue;
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
console.log("success search result = ");
|
|
144
|
+
console.log(JSON.stringify(result));
|
|
145
|
+
} catch (e) {
|
|
146
|
+
console.log(JSON.stringify(result));
|
|
147
|
+
throw e;
|
|
148
|
+
}
|
|
149
|
+
};
|
|
150
|
+
(window as any).search = search;
|
|
151
|
+
(window as any).searchRest = searchRest;
|
|
152
|
+
});
|
|
153
|
+
return () => {
|
|
154
|
+
return (
|
|
155
|
+
<div>
|
|
156
|
+
<HeycarMap
|
|
157
|
+
class={css.demo}
|
|
158
|
+
fallback={() => <div>error</div>}
|
|
159
|
+
loading={() => <div>loading</div>}
|
|
160
|
+
center={[121, 31]}
|
|
161
|
+
zoom={15}
|
|
162
|
+
mapRef={setMap}
|
|
163
|
+
></HeycarMap>
|
|
164
|
+
</div>
|
|
165
|
+
);
|
|
166
|
+
};
|
|
167
|
+
});
|