@heycar/heycars-map 0.2.2 → 0.2.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/api/geometry.d.ts +3 -3
- package/dist/business-components/DrivingRoute/DrivingRoute.d.ts +2 -0
- package/dist/business-components/PassengerCircle/PassengerCircle.css.d.ts +14 -1
- package/dist/business-components/PassengerCircle/PassengerCircle.d.ts +1 -0
- package/dist/business-components/PlaceCircle/PlaceCircle.css.d.ts +8 -1
- package/dist/business-components/PlaceCircle/PlaceCircle.d.ts +1 -0
- package/dist/hooks/useDrivingRoute.d.ts +12 -5
- package/dist/hooks/useGeoLocation.d.ts +1 -1
- package/dist/hooks/useMapGeometry.d.ts +10 -0
- package/dist/index.cjs +45 -45
- package/dist/index.d.ts +1 -0
- package/dist/index.js +921 -817
- package/dist/style.css +1 -1
- package/dist/types/interface.d.ts +5 -0
- package/package.json +1 -1
- package/src/api/geometry.ts +3 -4
- package/src/business-components/DrivingRoute/DrivingRoute.tsx +7 -5
- package/src/business-components/PassengerCircle/PassengerCircle.css.ts +19 -6
- package/src/business-components/PassengerCircle/PassengerCircle.tsx +14 -8
- package/src/business-components/PlaceCircle/PlaceCircle.css.ts +14 -4
- package/src/business-components/PlaceCircle/PlaceCircle.tsx +35 -29
- package/src/business-components/WalkingLine/WalkingLine.tsx +6 -2
- package/src/business-components/WalkingRoute/WalkingRoute.tsx +2 -8
- package/src/components/Demo/HeycarDemo.tsx +22 -9
- package/src/hooks/useDrivingRoute.ts +55 -25
- package/src/hooks/useGeoLocation.ts +2 -2
- package/src/hooks/useMapGeometry.ts +27 -0
- package/src/hooks/useMapLoader.ts +1 -1
- package/src/hooks/useWalkingRoute.ts +24 -11
- package/src/index.ts +1 -0
- package/src/types/amap/plugin.d.ts +1 -1
- package/src/types/interface.ts +6 -0
- package/todo.md +10 -5
package/dist/style.css
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
.rgf09w0{width:7.1045vw;height:10.93vw;display:flex}._15rq2xn0{display:flex;flex-direction:column;align-items:center;margin-bottom:-1.6vw}._15rq2xn1{padding:2.13vw 4.5vw 2.67vw 4.27vw;display:flex;align-items:center;background:linear-gradient(90deg,#79AFFF 0%,#5C8DFF 32%,#507FFF 75%,#4471FF 100%);border-radius:3.2vw}._15rq2xn2{font-size:3.47vw;font-family:PingFangSC-Semibold,PingFang SC;font-weight:600;color:#fff;line-height:4.8vw;white-space:nowrap}._15rq2xn3{font-size:2.93vw;font-family:PingFangSC-Regular,PingFang SC;font-weight:400;color:#eafaf8;line-height:4.27vw;white-space:nowrap;opacity:.8}._15rq2xn4{margin-left:3.2vw;width:1.44vw;height:2.4vw}._15rq2xn5{width:.8vw;height:4vw;background:#4C80FF;border-radius:0vw 0vw 26.67vw 26.67vw;z-index:1}._15rq2xn6{margin-top:-1.5vw;width:3.2vw;height:3.2vw}._1l6offo0{display:flex;margin-bottom:-
|
|
1
|
+
.rgf09w0{width:7.1045vw;height:10.93vw;display:flex}._15rq2xn0{display:flex;flex-direction:column;align-items:center;margin-bottom:-1.6vw}._15rq2xn1{padding:2.13vw 4.5vw 2.67vw 4.27vw;display:flex;align-items:center;background:linear-gradient(90deg,#79AFFF 0%,#5C8DFF 32%,#507FFF 75%,#4471FF 100%);border-radius:3.2vw}._15rq2xn2{font-size:3.47vw;font-family:PingFangSC-Semibold,PingFang SC;font-weight:600;color:#fff;line-height:4.8vw;white-space:nowrap}._15rq2xn3{font-size:2.93vw;font-family:PingFangSC-Regular,PingFang SC;font-weight:400;color:#eafaf8;line-height:4.27vw;white-space:nowrap;opacity:.8}._15rq2xn4{margin-left:3.2vw;width:1.44vw;height:2.4vw}._15rq2xn5{width:.8vw;height:4vw;background:#4C80FF;border-radius:0vw 0vw 26.67vw 26.67vw;z-index:1}._15rq2xn6{margin-top:-1.5vw;width:3.2vw;height:3.2vw}._1l6offo0{display:flex}._1l6offo1{width:4.53vw;height:4.53vw;margin-bottom:-2.265vw}._1l6offo2{width:16.27vw;height:16.27vw;margin-bottom:-8.135vw}.fhyw80{display:flex;align-items:center}.fhyw81{flex-direction:row-reverse}.fhyw83{margin-right:-2.265vw}.fhyw84{margin-left:-2.265vw}.fhyw85{margin-bottom:-2.265vw}.fhyw86{margin-right:calc(50% - 2.265vw)}.fhyw87{margin-left:calc(50% - 2.265vw)}.fhyw88{display:flex;width:4.53vw;height:4.53vw}.fhyw89{opacity:0}.fhyw8b{font-size:3.47vw;font-family:PingFangSC-Semibold,PingFang SC;font-weight:600;color:#243e66;line-height:4.53vw;white-space:nowrap}._4a4ovk0{margin-bottom:-.4vw;display:flex;flex-direction:column;align-items:center}._4a4ovk1{padding:1.07vw 2.4vw 1.6vw 2.67vw;background:#FFFFFF;box-shadow:0 .53vw 2.4vw #3f3f3f33;border-radius:2.13vw}._4a4ovk2{padding:2.67vw 2.67vw 2.4vw 3.2vw;background:#FFFFFF;box-shadow:0 0 2.67vw #4e556c26;border-radius:4.8vw;font-size:3.2vw;font-family:PingFangSC-Medium,PingFang SC;font-weight:500;color:#1e1e1e;line-height:4.53vw;white-space:nowrap}._4a4ovk3{font-size:3.2vw;font-family:PingFangSC-Medium,PingFang SC;font-weight:500;color:#1e1e1e;line-height:4.53vw;white-space:nowrap}._4a4ovk4{font-size:2.4vw;font-family:PingFangSC-Regular,PingFang SC;font-weight:400;color:#7e7e7e;line-height:3.47vw;white-space:nowrap}._4a4ovk5{color:#4471ff;font-family:PingFangSC-Medium,PingFang SC;font-weight:500}._4a4ovk6{margin-top:1.33vw;width:6.192vw;height:7.998vw}._4a4ovk7{margin-top:2.4vw;width:6.192vw;height:7.998vw}._65j3sr1{margin-top:1.87vw;margin-bottom:-5.5vw;width:6vw;height:11vw}@keyframes rrvp0y0{0%{transform:scale(0);opacity:1}33.33%{transform:scale(.5);opacity:1}66.66%{transform:scale(1);opacity:0}to{transform:scale(1);opacity:0}}@keyframes rrvp0y1{0%{transform:scale(0);opacity:0}33.33%{transform:scale(0);opacity:1}66.66%{transform:scale(.5);opacity:1}to{transform:scale(1);opacity:0}}.rrvp0y2{display:flex;margin-bottom:-30.935vw;width:61.87vw;height:61.87vw;animation-name:rrvp0y0;animation-duration:3s;animation-iteration-count:infinite;animation-timing-function:linear}.rrvp0y3{animation-name:rrvp0y1}
|
package/package.json
CHANGED
package/src/api/geometry.ts
CHANGED
|
@@ -5,11 +5,10 @@ export interface ApiMapMeta {
|
|
|
5
5
|
}
|
|
6
6
|
|
|
7
7
|
const point2latlng = ([lng, lat]: Point): google.maps.LatLngLiteral => ({ lng, lat });
|
|
8
|
-
|
|
9
8
|
export interface DistanceOfLineProps extends ApiMapMeta {
|
|
10
9
|
path: Point[];
|
|
11
10
|
}
|
|
12
|
-
export function
|
|
11
|
+
export function apiMapDistanceOfLine(props: DistanceOfLineProps): number {
|
|
13
12
|
const { path, isGoogle } = props;
|
|
14
13
|
if (!isGoogle) {
|
|
15
14
|
return AMap.GeometryUtil.distanceOfLine(path);
|
|
@@ -21,7 +20,7 @@ export interface IsPointInRingProps extends ApiMapMeta {
|
|
|
21
20
|
point: Point;
|
|
22
21
|
path: Point[];
|
|
23
22
|
}
|
|
24
|
-
export function
|
|
23
|
+
export function apiMapIsPointInRing(props: IsPointInRingProps): boolean {
|
|
25
24
|
const { point, path, isGoogle } = props;
|
|
26
25
|
if (!isGoogle) {
|
|
27
26
|
return AMap.GeometryUtil.isPointInRing(point, path);
|
|
@@ -35,7 +34,7 @@ export interface IsPointInLineProps extends ApiMapMeta {
|
|
|
35
34
|
path: Point[];
|
|
36
35
|
tolerance: number;
|
|
37
36
|
}
|
|
38
|
-
export function
|
|
37
|
+
export function apiMapIsPointInLine(props: IsPointInLineProps): boolean {
|
|
39
38
|
const { point, path, tolerance, isGoogle } = props;
|
|
40
39
|
if (!isGoogle) {
|
|
41
40
|
return AMap.GeometryUtil.isPointOnLine(point, path, tolerance);
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { reactive, VNodeData } from "vue-demi";
|
|
1
|
+
import { reactive, toRefs, VNodeData } from "vue-demi";
|
|
2
2
|
import {
|
|
3
3
|
useADrivingRoute,
|
|
4
4
|
UseDrivingRouteProps,
|
|
@@ -13,6 +13,8 @@ import type { Point } from "../../types/interface";
|
|
|
13
13
|
export type DrivingRouteRenderProps = {
|
|
14
14
|
path: Point[];
|
|
15
15
|
angle?: number;
|
|
16
|
+
distance: number;
|
|
17
|
+
duration: number;
|
|
16
18
|
};
|
|
17
19
|
export interface DrivingRouteProps extends UseDrivingRouteProps {
|
|
18
20
|
render?: (props: DrivingRouteRenderProps) => VNodeChild;
|
|
@@ -22,9 +24,9 @@ export const ADrivingRoute = defineSetup(function DrivingRoute(
|
|
|
22
24
|
{ slots }
|
|
23
25
|
) {
|
|
24
26
|
const map = useAmap();
|
|
25
|
-
const path = useADrivingRoute(props);
|
|
27
|
+
const { path, distance, duration } = toRefs(useADrivingRoute(props));
|
|
26
28
|
const angle = useAmapAngle(reactive({ path, map }));
|
|
27
|
-
return () => <div>{slots.render?.(reactive({ path, angle }))}</div>;
|
|
29
|
+
return () => <div>{slots.render?.(reactive({ path, angle, distance, duration }))}</div>;
|
|
28
30
|
});
|
|
29
31
|
|
|
30
32
|
export const GDrivingRoute = defineSetup(function DrivingRoute(
|
|
@@ -32,9 +34,9 @@ export const GDrivingRoute = defineSetup(function DrivingRoute(
|
|
|
32
34
|
{ slots }
|
|
33
35
|
) {
|
|
34
36
|
const map = useGmap();
|
|
35
|
-
const path = useGDrivingRoute(props);
|
|
37
|
+
const { path, distance, duration } = toRefs(useGDrivingRoute(props));
|
|
36
38
|
const angle = useGmapAngle(reactive({ path, map }));
|
|
37
|
-
return () => <div>{slots.render?.(reactive({ path, angle }))}</div>;
|
|
39
|
+
return () => <div>{slots.render?.(reactive({ path, angle, distance, duration }))}</div>;
|
|
38
40
|
});
|
|
39
41
|
|
|
40
42
|
export const DrivingRoute = defineSetup(function DrivingRoute(props: DrivingRouteProps, { slots }) {
|
|
@@ -1,8 +1,21 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { recipe } from "@vanilla-extract/recipes";
|
|
2
2
|
|
|
3
|
-
export const passengerCircle =
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
3
|
+
export const passengerCircle = recipe({
|
|
4
|
+
base: {
|
|
5
|
+
display: "flex",
|
|
6
|
+
},
|
|
7
|
+
variants: {
|
|
8
|
+
size: {
|
|
9
|
+
small: {
|
|
10
|
+
width: "4.53vw",
|
|
11
|
+
height: "4.53vw",
|
|
12
|
+
marginBottom: "-2.265vw",
|
|
13
|
+
},
|
|
14
|
+
large: {
|
|
15
|
+
width: "16.27vw",
|
|
16
|
+
height: "16.27vw",
|
|
17
|
+
marginBottom: "-8.135vw",
|
|
18
|
+
},
|
|
19
|
+
},
|
|
20
|
+
},
|
|
8
21
|
});
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { computed } from "vue";
|
|
2
2
|
import imgPassengerCircle from "../../assets/icons/svg/passenger-circle.svg";
|
|
3
|
+
import imgPlaceCircle from "../../assets/icons/svg/place-circle.svg";
|
|
3
4
|
import { AmapMarker } from "../../components/AmapMarker";
|
|
4
5
|
import { GmapAdvancedMarkerView } from "../../components/GmapAdvancedMarkerView";
|
|
5
6
|
import { useMapSupplier } from "../../hooks/useMapSupplier";
|
|
@@ -11,22 +12,27 @@ import * as css from "./PassengerCircle.css";
|
|
|
11
12
|
|
|
12
13
|
interface PassengerCircleProps {
|
|
13
14
|
position: [number, number];
|
|
15
|
+
size?: "small" | "large";
|
|
14
16
|
}
|
|
15
17
|
export const APassengerCircle = defineSetup(function APassengerCircle(props: PassengerCircleProps) {
|
|
16
|
-
const contentRef = computed(
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
`
|
|
20
|
-
|
|
18
|
+
const contentRef = computed(() => {
|
|
19
|
+
const { size = "large" } = props;
|
|
20
|
+
const src = size === "large" ? imgPassengerCircle : imgPlaceCircle;
|
|
21
|
+
return `
|
|
22
|
+
<img src="${src}" class="${css.passengerCircle({ size })}">
|
|
23
|
+
`;
|
|
24
|
+
});
|
|
21
25
|
return () => (
|
|
22
26
|
<AmapMarker position={props.position} content={contentRef.value} anchor={"bottom-center"} />
|
|
23
27
|
);
|
|
24
28
|
});
|
|
25
29
|
|
|
26
30
|
export const GPassengerCircle = defineSetup(function GPassengerCircle(props: PassengerCircleProps) {
|
|
27
|
-
const contentRef = computed(() =>
|
|
28
|
-
|
|
29
|
-
|
|
31
|
+
const contentRef = computed(() => {
|
|
32
|
+
const { size = "large" } = props;
|
|
33
|
+
const src = size === "large" ? imgPassengerCircle : imgPlaceCircle;
|
|
34
|
+
return createDom("img", { class: css.passengerCircle({ size }), src });
|
|
35
|
+
});
|
|
30
36
|
return () => (
|
|
31
37
|
<GmapAdvancedMarkerView position={vec2lnglat(props.position)} content={contentRef.value} />
|
|
32
38
|
);
|
|
@@ -45,10 +45,20 @@ export const gmapPlaceIconLayout = recipe({
|
|
|
45
45
|
},
|
|
46
46
|
});
|
|
47
47
|
|
|
48
|
-
export const placeIcon =
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
48
|
+
export const placeIcon = recipe({
|
|
49
|
+
base: {
|
|
50
|
+
display: "flex",
|
|
51
|
+
width: "4.53vw",
|
|
52
|
+
height: "4.53vw",
|
|
53
|
+
},
|
|
54
|
+
variants: {
|
|
55
|
+
hideIcon: {
|
|
56
|
+
true: {
|
|
57
|
+
opacity: 0,
|
|
58
|
+
},
|
|
59
|
+
false: {},
|
|
60
|
+
},
|
|
61
|
+
},
|
|
52
62
|
});
|
|
53
63
|
|
|
54
64
|
export const label = style({
|
|
@@ -4,7 +4,7 @@ import { AmapMarker } from "../../components/AmapMarker";
|
|
|
4
4
|
import { GmapAdvancedMarkerView } from "../../components/GmapAdvancedMarkerView";
|
|
5
5
|
import { useMapSupplier } from "../../hooks/useMapSupplier";
|
|
6
6
|
import { AnchorType } from "../../types/amap/marker";
|
|
7
|
-
import { createElement, defineSetup } from "../../types/helper";
|
|
7
|
+
import { createElement, defineLagecySetup, defineSetup } from "../../types/helper";
|
|
8
8
|
import { createDom } from "../../utils/dom";
|
|
9
9
|
import { vec2lnglat } from "../../utils/transform";
|
|
10
10
|
import * as css from "./PlaceCircle.css";
|
|
@@ -13,25 +13,27 @@ export interface PlaceCircleProps {
|
|
|
13
13
|
position: [number, number];
|
|
14
14
|
label?: string;
|
|
15
15
|
textAlign?: "left" | "right";
|
|
16
|
+
hideIcon?: boolean;
|
|
16
17
|
}
|
|
17
|
-
export const APlaceCircle =
|
|
18
|
+
export const APlaceCircle = defineLagecySetup(function APlaceCircle(props: PlaceCircleProps) {
|
|
18
19
|
const textAlignRef = computed(() => props.textAlign ?? "right");
|
|
19
|
-
const contentRef = computed(
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
20
|
+
const contentRef = computed(() => {
|
|
21
|
+
const { hideIcon = false } = props;
|
|
22
|
+
return `
|
|
23
|
+
<div class="${css.placeCircleLayout({ textAlign: textAlignRef.value })}">
|
|
24
|
+
<img class="${css.placeIcon({ hideIcon })} ${css.amapPlaceIconLayout({
|
|
23
25
|
textAlign: textAlignRef.value,
|
|
24
26
|
})}" src="${imgPlaceCircle}">
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
);
|
|
29
|
-
const contentWithoutLabelRef = computed(
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
);
|
|
27
|
+
<div class="${css.label}">${props.label}</div>
|
|
28
|
+
</div>
|
|
29
|
+
`;
|
|
30
|
+
});
|
|
31
|
+
const contentWithoutLabelRef = computed(() => {
|
|
32
|
+
const { hideIcon = false } = props;
|
|
33
|
+
return `<img class="${css.placeIcon({ hideIcon })} ${css.amapPlaceIconLayout({
|
|
34
|
+
textAlign: textAlignRef.value,
|
|
35
|
+
})}" src="${imgPlaceCircle}">`;
|
|
36
|
+
});
|
|
35
37
|
return () => (
|
|
36
38
|
<AmapMarker
|
|
37
39
|
position={props.position}
|
|
@@ -39,12 +41,13 @@ export const APlaceCircle = defineSetup(function APlaceCircle(props: PlaceCircle
|
|
|
39
41
|
anchor={textAlignRef.value === "left" ? AnchorType.middleRight : AnchorType.middleLeft}
|
|
40
42
|
/>
|
|
41
43
|
);
|
|
42
|
-
});
|
|
44
|
+
}).props(["hideIcon", "label", "position", "textAlign"]);
|
|
43
45
|
|
|
44
|
-
export const GPlaceCircle =
|
|
46
|
+
export const GPlaceCircle = defineLagecySetup(function GPlaceCircle(props: PlaceCircleProps) {
|
|
45
47
|
const textAlignRef = computed(() => props.textAlign ?? "right");
|
|
46
|
-
const contentRef = computed(() =>
|
|
47
|
-
|
|
48
|
+
const contentRef = computed(() => {
|
|
49
|
+
const { hideIcon = false } = props;
|
|
50
|
+
return createDom(
|
|
48
51
|
"div",
|
|
49
52
|
{
|
|
50
53
|
class: `${css.placeCircleLayout({
|
|
@@ -52,24 +55,27 @@ export const GPlaceCircle = defineSetup(function GPlaceCircle(props: PlaceCircle
|
|
|
52
55
|
})} ${css.gmapPlaceIconLayout({ textAlign: textAlignRef.value })}`,
|
|
53
56
|
},
|
|
54
57
|
`
|
|
55
|
-
<img class="${css.placeIcon}" src="${imgPlaceCircle}">
|
|
58
|
+
<img class="${css.placeIcon({ hideIcon })}" src="${imgPlaceCircle}">
|
|
56
59
|
<div class="${css.label}">${props.label}</div>
|
|
57
60
|
`
|
|
58
|
-
)
|
|
59
|
-
);
|
|
60
|
-
const contentWithoutLabelRef = computed(() =>
|
|
61
|
-
|
|
62
|
-
|
|
61
|
+
);
|
|
62
|
+
});
|
|
63
|
+
const contentWithoutLabelRef = computed(() => {
|
|
64
|
+
const { hideIcon = false } = props;
|
|
65
|
+
return createDom("img", {
|
|
66
|
+
class: `${css.placeIcon({ hideIcon })} ${css.gmapPlaceIconLayout({
|
|
67
|
+
textAlign: textAlignRef.value,
|
|
68
|
+
})}`,
|
|
63
69
|
src: imgPlaceCircle,
|
|
64
|
-
})
|
|
65
|
-
);
|
|
70
|
+
});
|
|
71
|
+
});
|
|
66
72
|
return () => (
|
|
67
73
|
<GmapAdvancedMarkerView
|
|
68
74
|
position={vec2lnglat(props.position)}
|
|
69
75
|
content={props.label ? contentRef.value : contentWithoutLabelRef.value}
|
|
70
76
|
/>
|
|
71
77
|
);
|
|
72
|
-
});
|
|
78
|
+
}).props(["hideIcon", "label", "position", "textAlign"]);
|
|
73
79
|
|
|
74
80
|
export const PlaceCircle = defineSetup(function PlaceCircle(props: PlaceCircleProps) {
|
|
75
81
|
const payload = useMapSupplier();
|
|
@@ -10,11 +10,13 @@ export interface WalkingLineProps {
|
|
|
10
10
|
}
|
|
11
11
|
export const AWalkingLine = defineSetup(function AWalkingLine(props: WalkingLineProps) {
|
|
12
12
|
return () => {
|
|
13
|
+
const { path } = props;
|
|
14
|
+
if (path.length === 0) return null;
|
|
13
15
|
const vw = window.innerWidth * 0.01;
|
|
14
16
|
const strokeWidth = 2 * vw;
|
|
15
17
|
return (
|
|
16
18
|
<AmapPolyline
|
|
17
|
-
path={
|
|
19
|
+
path={path}
|
|
18
20
|
strokeWeight={strokeWidth}
|
|
19
21
|
strokeOpacity={1}
|
|
20
22
|
strokeColor={"#38A3FE"}
|
|
@@ -30,12 +32,14 @@ export const AWalkingLine = defineSetup(function AWalkingLine(props: WalkingLine
|
|
|
30
32
|
export const GWalkingLine = defineSetup(function GWalkingLine(props: WalkingLineProps) {
|
|
31
33
|
const pathRef = computed(() => props.path.map(vec2lnglat));
|
|
32
34
|
return () => {
|
|
35
|
+
const path = pathRef.value;
|
|
36
|
+
if (path.length === 0) return null;
|
|
33
37
|
const vw = window.innerWidth * 0.01;
|
|
34
38
|
const strokeWidth = 2 * vw;
|
|
35
39
|
const r = strokeWidth / 4;
|
|
36
40
|
return (
|
|
37
41
|
<GmapPolyline
|
|
38
|
-
path={
|
|
42
|
+
path={path}
|
|
39
43
|
strokeWeight={strokeWidth}
|
|
40
44
|
strokeOpacity={1}
|
|
41
45
|
strokeColor={"transparent"}
|
|
@@ -1,6 +1,4 @@
|
|
|
1
1
|
import { reactive, VNodeData } from "vue-demi";
|
|
2
|
-
import { useAmap, useGmap } from "../../hooks/useMap";
|
|
3
|
-
import { useAmapAngle, useGmapAngle } from "../../hooks/useMapAngle";
|
|
4
2
|
import { useMapSupplier } from "../../hooks/useMapSupplier";
|
|
5
3
|
import {
|
|
6
4
|
useAWalkingRoute,
|
|
@@ -21,20 +19,16 @@ export const AWalkingRoute = defineSetup(function WalkingRoute(
|
|
|
21
19
|
props: WalkingRouteProps,
|
|
22
20
|
{ slots }
|
|
23
21
|
) {
|
|
24
|
-
const map = useAmap();
|
|
25
22
|
const path = useAWalkingRoute(props);
|
|
26
|
-
|
|
27
|
-
return () => <div>{slots.render?.(reactive({ path, angle }))}</div>;
|
|
23
|
+
return () => <div>{slots.render?.(reactive({ path }))}</div>;
|
|
28
24
|
});
|
|
29
25
|
|
|
30
26
|
export const GWalkingRoute = defineSetup(function WalkingRoute(
|
|
31
27
|
props: WalkingRouteProps,
|
|
32
28
|
{ slots }
|
|
33
29
|
) {
|
|
34
|
-
const map = useGmap();
|
|
35
30
|
const path = useGWalkingRoute(props);
|
|
36
|
-
|
|
37
|
-
return () => <div>{slots.render?.(reactive({ path, angle }))}</div>;
|
|
31
|
+
return () => <div>{slots.render?.(reactive({ path }))}</div>;
|
|
38
32
|
});
|
|
39
33
|
|
|
40
34
|
export const WalkingRoute = defineSetup(function WalkingRoute(props: WalkingRouteProps, { slots }) {
|
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
import { computed } from "vue-demi";
|
|
2
|
-
import {
|
|
2
|
+
import { DrivingLine } from "../../business-components/DrivingLine";
|
|
3
|
+
import { DrivingRoute } from "../../business-components/DrivingRoute";
|
|
4
|
+
import { PlaceCircle } from "../../business-components/PlaceCircle";
|
|
5
|
+
import { TaxiCar } from "../../business-components/TaxiCar";
|
|
3
6
|
import { useBusinessMapAutoComplete } from "../../hooks-business/useBusinessMapAutoComplete";
|
|
4
7
|
import {
|
|
5
8
|
useBusinessMapRecomendPlace,
|
|
@@ -7,6 +10,7 @@ import {
|
|
|
7
10
|
} from "../../hooks-business/useBusinessMapRecomendPlace";
|
|
8
11
|
import { useHeycarMap } from "../../hooks/useHeycarMap";
|
|
9
12
|
import { useMapFitView } from "../../hooks/useMapFitView";
|
|
13
|
+
import { useMapGeometry } from "../../hooks/useMapGeometry";
|
|
10
14
|
import { defineSetup } from "../../types/helper";
|
|
11
15
|
import { HeycarMap, MapProvider } from "../MapProvider/MapProvider";
|
|
12
16
|
import * as css from "./Demo.css";
|
|
@@ -23,7 +27,7 @@ export const HeycarDemo = defineSetup(function HeycarDemo() {
|
|
|
23
27
|
amapSecret={amapApiSecret}
|
|
24
28
|
gmapId={gmapId}
|
|
25
29
|
gmapKey={gmapApiKey}
|
|
26
|
-
supplier={"
|
|
30
|
+
supplier={"gmap"}
|
|
27
31
|
>
|
|
28
32
|
<SomeHomePage />
|
|
29
33
|
</MapProvider>
|
|
@@ -94,11 +98,18 @@ export const SomeHomePage = defineSetup(function SomeHomePage() {
|
|
|
94
98
|
padding: [15, 15, 5, 15],
|
|
95
99
|
autoFitTimeout: 5000,
|
|
96
100
|
});
|
|
101
|
+
const { apiMapDistance } = useMapGeometry();
|
|
97
102
|
(window as any).setCenterPlaceByRecomand = setCenterPlaceByRecomand;
|
|
98
103
|
(window as any).setFitView = setFitView;
|
|
99
104
|
return () => {
|
|
100
105
|
return (
|
|
101
106
|
<div>
|
|
107
|
+
distance:{" "}
|
|
108
|
+
{apiMapDistance(centerPoint.value, [
|
|
109
|
+
centerPoint.value[0] + 0.01,
|
|
110
|
+
centerPoint.value[1] + 0.01,
|
|
111
|
+
])}{" "}
|
|
112
|
+
<br />
|
|
102
113
|
geoLoading: {`${geoLoading.value}`} <br />
|
|
103
114
|
isDragging: {`${isDragging.value}`} <br />
|
|
104
115
|
geoPosition: {geoPosition.value[0]} | {geoPosition.value[1]} <br />
|
|
@@ -112,18 +123,18 @@ export const SomeHomePage = defineSetup(function SomeHomePage() {
|
|
|
112
123
|
zoom={centerPoint.value[0] === 0 ? 3 : 13}
|
|
113
124
|
mapRef={setMap}
|
|
114
125
|
>
|
|
115
|
-
<StartEndPoint
|
|
126
|
+
{/* <StartEndPoint
|
|
116
127
|
registerOverlay={registerFitVeiw}
|
|
117
128
|
position={[121.4897065, 31.0842552]}
|
|
118
129
|
title={"start point"}
|
|
119
130
|
type="start"
|
|
120
|
-
/>
|
|
121
|
-
<StartEndPoint
|
|
131
|
+
/> */}
|
|
132
|
+
{/* <StartEndPoint
|
|
122
133
|
registerOverlay={registerFitVeiw}
|
|
123
134
|
position={[centerPoint.value[0] + 0.01, centerPoint.value[1] + 0.01]}
|
|
124
135
|
title={"end point"}
|
|
125
136
|
type="end"
|
|
126
|
-
/>
|
|
137
|
+
/> */}
|
|
127
138
|
{/* <PickupPoints places={placeCandidates.value} /> */}
|
|
128
139
|
{/* <AddressBox
|
|
129
140
|
type="box"
|
|
@@ -139,17 +150,19 @@ export const SomeHomePage = defineSetup(function SomeHomePage() {
|
|
|
139
150
|
]}
|
|
140
151
|
labels={["place name 1", "place name 2"]}
|
|
141
152
|
/> */}
|
|
142
|
-
|
|
153
|
+
<DrivingRoute
|
|
143
154
|
from={[121, 31]}
|
|
144
155
|
to={[121.6, 31.3]}
|
|
145
156
|
render={({ path, angle }) => [
|
|
146
157
|
<DrivingLine path={path} />,
|
|
147
158
|
<TaxiCar position={[121, 31]} angle={angle} />,
|
|
148
159
|
]}
|
|
149
|
-
/>
|
|
160
|
+
/>
|
|
161
|
+
{/* <PassengerCircle position={centerPoint.value} size="small" /> */}
|
|
162
|
+
<PlaceCircle position={centerPoint.value} label={"some place"} hideIcon />
|
|
150
163
|
{/* <WalkingRoute
|
|
151
164
|
from={centerPoint.value}
|
|
152
|
-
to={[centerPoint.value[0] + 0.
|
|
165
|
+
to={[centerPoint.value[0] + 0.01, centerPoint.value[1] + 0.01]}
|
|
153
166
|
render={({ path }) => <WalkingLine path={path} />}
|
|
154
167
|
/> */}
|
|
155
168
|
</HeycarMap>
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import type { Point } from "../types/interface";
|
|
1
|
+
import { reactive } from "vue-demi";
|
|
2
|
+
import type { Point, Route } from "../types/interface";
|
|
3
3
|
import { watchPostEffectForDeepOption } from "../utils/compare";
|
|
4
4
|
import { useMapSupplier } from "./useMapSupplier";
|
|
5
5
|
|
|
@@ -9,7 +9,7 @@ export interface UseDrivingRouteProps {
|
|
|
9
9
|
}
|
|
10
10
|
|
|
11
11
|
export const useADrivingRoute = (props: UseDrivingRouteProps) => {
|
|
12
|
-
const
|
|
12
|
+
const outputRoute = reactive<Route>({ path: [], distance: 0, duration: 0 });
|
|
13
13
|
const amapDriving = new AMap.Driving({});
|
|
14
14
|
watchPostEffectForDeepOption(
|
|
15
15
|
() => ({ ...props }),
|
|
@@ -23,17 +23,22 @@ export const useADrivingRoute = (props: UseDrivingRouteProps) => {
|
|
|
23
23
|
case "complete": {
|
|
24
24
|
let path: Point[] = [];
|
|
25
25
|
const drivingResult = result as AMap.DrivingResult;
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
26
|
+
// todo 多条导航路线的情况
|
|
27
|
+
const firstRoute = drivingResult.routes[0];
|
|
28
|
+
for (const step of firstRoute.steps) {
|
|
29
|
+
const basicStep = step as AMap.DriveStepBasic;
|
|
30
|
+
const stepPath = basicStep.path.map<Point>(({ lng, lat }) => [lng, lat]);
|
|
31
|
+
path = path.concat(stepPath);
|
|
32
32
|
}
|
|
33
|
-
|
|
33
|
+
outputRoute.path = path;
|
|
34
|
+
outputRoute.distance = firstRoute.distance;
|
|
35
|
+
outputRoute.duration = firstRoute.time;
|
|
34
36
|
return;
|
|
35
37
|
}
|
|
36
38
|
case "no_data":
|
|
39
|
+
outputRoute.path = [];
|
|
40
|
+
outputRoute.distance = 0;
|
|
41
|
+
outputRoute.duration = 0;
|
|
37
42
|
return;
|
|
38
43
|
default:
|
|
39
44
|
throw result;
|
|
@@ -42,35 +47,60 @@ export const useADrivingRoute = (props: UseDrivingRouteProps) => {
|
|
|
42
47
|
);
|
|
43
48
|
}
|
|
44
49
|
);
|
|
45
|
-
return
|
|
50
|
+
return outputRoute;
|
|
46
51
|
};
|
|
47
52
|
|
|
48
53
|
export const useGDrivingRoute = (props: UseDrivingRouteProps) => {
|
|
49
|
-
const
|
|
54
|
+
const outputRoute = reactive<Route>({ path: [], distance: 0, duration: 0 });
|
|
50
55
|
const gmapDirectionsService = new google.maps.DirectionsService();
|
|
51
56
|
watchPostEffectForDeepOption(
|
|
52
57
|
() => ({ ...props }),
|
|
53
58
|
({ from, to }) => {
|
|
54
|
-
gmapDirectionsService
|
|
55
|
-
|
|
59
|
+
gmapDirectionsService.route(
|
|
60
|
+
{
|
|
56
61
|
origin: { lng: from[0], lat: from[1] },
|
|
57
62
|
destination: { lng: to[0], lat: to[1] },
|
|
58
63
|
travelMode: google.maps.TravelMode.DRIVING,
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
64
|
+
},
|
|
65
|
+
(result, status) => {
|
|
66
|
+
switch (status) {
|
|
67
|
+
case google.maps.DirectionsStatus.OK: {
|
|
68
|
+
let path: Point[] = [];
|
|
69
|
+
let distance = 0;
|
|
70
|
+
let duration = 0;
|
|
71
|
+
const firstRoute = result!.routes[0];
|
|
72
|
+
const stepPath = firstRoute.overview_path.map<Point>((item) => [
|
|
73
|
+
item.lng(),
|
|
74
|
+
item.lat(),
|
|
75
|
+
]);
|
|
76
|
+
path = path.concat(stepPath);
|
|
77
|
+
for (const leg of firstRoute.legs) {
|
|
78
|
+
distance += leg.distance?.value ?? 0;
|
|
79
|
+
// todo 考虑用 duration_in_traffic 但这个字段上有条件的
|
|
80
|
+
duration += leg.duration?.value ?? 0;
|
|
81
|
+
}
|
|
82
|
+
outputRoute.path = path;
|
|
83
|
+
outputRoute.distance = distance;
|
|
84
|
+
outputRoute.duration = duration;
|
|
85
|
+
return;
|
|
86
|
+
}
|
|
87
|
+
case google.maps.DirectionsStatus.ZERO_RESULTS:
|
|
88
|
+
case google.maps.DirectionsStatus.NOT_FOUND:
|
|
89
|
+
outputRoute.path = [];
|
|
90
|
+
outputRoute.distance = 0;
|
|
91
|
+
outputRoute.duration = 0;
|
|
92
|
+
return;
|
|
93
|
+
default:
|
|
94
|
+
throw new Error(status);
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
);
|
|
68
98
|
}
|
|
69
99
|
);
|
|
70
|
-
return
|
|
100
|
+
return outputRoute;
|
|
71
101
|
};
|
|
72
102
|
|
|
73
|
-
export const useDrivingRoute = (props: UseDrivingRouteProps):
|
|
103
|
+
export const useDrivingRoute = (props: UseDrivingRouteProps): Route => {
|
|
74
104
|
const { supplier } = useMapSupplier();
|
|
75
105
|
return supplier === "gmap" ? useGDrivingRoute(props) : useADrivingRoute(props);
|
|
76
106
|
};
|
|
@@ -5,8 +5,8 @@ export interface UseGeoLocationProps {
|
|
|
5
5
|
onChange?: (value: { position: Point; coordinate: GeolocationCoordinates }) => any;
|
|
6
6
|
onLoad?: (value: { position: Point; coordinate: GeolocationCoordinates }) => any;
|
|
7
7
|
}
|
|
8
|
-
export const useGeoLocation = (props
|
|
9
|
-
const { onChange, onLoad } = props;
|
|
8
|
+
export const useGeoLocation = (props?: UseGeoLocationProps) => {
|
|
9
|
+
const { onChange, onLoad } = props ?? {};
|
|
10
10
|
const loading = ref(false);
|
|
11
11
|
const readyRef = ref(false);
|
|
12
12
|
const errorRef = ref<GeolocationPositionError>();
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import type { Point } from "../types/interface";
|
|
2
|
+
import { vec2lnglat } from "../utils/transform";
|
|
3
|
+
import { Status } from "./useMapLoader";
|
|
4
|
+
import { useMapSupplier } from "./useMapSupplier";
|
|
5
|
+
|
|
6
|
+
export const useAmapGeometry = () => {
|
|
7
|
+
const { status } = useMapSupplier();
|
|
8
|
+
const apiMapDistance = (from: Point, to: Point) => {
|
|
9
|
+
if (status !== Status.SUCCESS) return undefined;
|
|
10
|
+
return AMap.GeometryUtil.distance(from, to);
|
|
11
|
+
};
|
|
12
|
+
return { apiMapDistance };
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
export const useGmapGeometry = () => {
|
|
16
|
+
const { status } = useMapSupplier();
|
|
17
|
+
const apiMapDistance = (from: Point, to: Point) => {
|
|
18
|
+
if (status !== Status.SUCCESS) return undefined;
|
|
19
|
+
return google.maps.geometry.spherical.computeDistanceBetween(vec2lnglat(from), vec2lnglat(to));
|
|
20
|
+
};
|
|
21
|
+
return { apiMapDistance };
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
export const useMapGeometry = () => {
|
|
25
|
+
const { supplier } = useMapSupplier();
|
|
26
|
+
return supplier === "gmap" ? useGmapGeometry() : useAmapGeometry();
|
|
27
|
+
};
|
|
@@ -9,7 +9,7 @@ export const DEFAULT_AMAP_PLUGINS: AmapLoaderProps["plugins"] = [
|
|
|
9
9
|
"AMap.Geocoder",
|
|
10
10
|
"AMap.PlaceSearch",
|
|
11
11
|
"AMap.Driving",
|
|
12
|
-
"AMap.
|
|
12
|
+
"AMap.Walking",
|
|
13
13
|
];
|
|
14
14
|
export const DEFAULT_GMAP_LIBRARIES: LoaderOptions["libraries"] = ["marker", "places", "geometry"];
|
|
15
15
|
|