React H5中,高德地图API实战使用封装
一、定义封装 useDrawTraceMap:绘制轨迹地图,包括起点、终点、行车轨迹
import { useCallback, useEffect, useRef } from "react";
import AMapLoader from "@amap/amap-jsapi-loader";
import { nanoid } from "nanoid";
export interface TLatitudeLongitude {
lat: number | string;
lng: number | string;
}
export type TDrivingTrace = Partial<{
drive: TLatitudeLongitude[];
startPoint: TLatitudeLongitude;
endPoint: TLatitudeLongitude;
}>;
interface DrawTraceMapProps {
traceData: TDrivingTrace;
closePolyline?: boolean;
hideStartPoint?: boolean;
hideEndPoint?: boolean;
}
interface UseDrawTraceMapProps {
key: string;
}
const useDrawTraceMap = (props?: UseDrawTraceMapProps) => {
const DEFAULT_KEY = "you_apply_really_key";
const mapInstanceRef = useRef<any>(null);
const containerIdRef = useRef<string>(nanoid());
const drawTraceMap = useCallback(
async (drawProps: DrawTraceMapProps) => {
const {
traceData,
closePolyline = false,
hideStartPoint = false,
hideEndPoint = false,
} = drawProps;
if (!traceData) {
return;
}
await AMapLoader.load({
key: props?.key || DEFAULT_KEY,
version: "1.4.15",
plugins: ["AMap.Autocomplete"],
AMapUI: {
version: "1.1",
plugins: ["overlay/SimpleMarker"],
},
Loca: {
version: "1.3.2",
},
})
.then((AMap) => {
const startX = traceData.startPoint?.lng?.toString() || "";
const startY = traceData.startPoint?.lat?.toString() || "";
const startIcon = new AMap.Icon({
size: new AMap.Size(25, 34),
image:
"//a.amap.com/jsapi_demos/static/demo-center/icons/dir-marker.png",
imageSize: new AMap.Size(135, 40),
imageOffset: new AMap.Pixel(-9, -3),
});
const startMarker = new AMap.Marker({
position: new AMap.LngLat(
parseFloat(String(startX)),
parseFloat(String(startY))
),
icon: startIcon,
offset: new AMap.Pixel(-13, -30),
});
const endX = traceData.endPoint?.lng?.toString() || "";
const endY = traceData.endPoint?.lat?.toString() || "";
const endIcon = new AMap.Icon({
size: new AMap.Size(25, 34),
image:
"//a.amap.com/jsapi_demos/static/demo-center/icons/dir-marker.png",
imageSize: new AMap.Size(135, 40),
imageOffset: new AMap.Pixel(-95, -3),
});
const endMarker = new AMap.Marker({
position: new AMap.LngLat(
parseFloat(String(endX)),
parseFloat(String(endY))
),
icon: endIcon,
offset: new AMap.Pixel(-13, -30),
});
mapInstanceRef.current = new AMap.Map(containerIdRef.current, {
center: [parseFloat(String(startX)), parseFloat(String(startY))],
zoom: 12,
resizeEnable: true,
mapStyle: "amap://styles/macaron",
});
mapInstanceRef.current?.add([
hideStartPoint ? null : startMarker,
hideEndPoint ? null : endMarker,
]);
if (!closePolyline) {
const path = traceData?.drive?.map((item) => {
return [item.lng, item.lat];
});
new AMap.Polyline({
map: mapInstanceRef.current,
path,
showDir: true,
strokeColor: "#28F",
strokeWeight: 6,
});
}
mapInstanceRef.current.setFitView();
})
.catch((e) => {
console.error(e);
});
},
[props?.key]
);
const hasMapInstance = useCallback(() => {
return !!mapInstanceRef.current;
}, []);
useEffect(() => {
return () => {
if (mapInstanceRef.current) {
mapInstanceRef.current?.destroy?.();
}
};
}, []);
return {
containerId: containerIdRef.current,
drawTraceMap,
hasMapInstance,
} as {
containerId: string;
drawTraceMap: (drawProps: DrawTraceMapProps) => Promise<void>;
hasMapInstance: () => boolean;
};
};
export default useDrawTraceMap;
二、useDrawTraceMap的使用示例
import useDrawTraceMap from "@/hooks/useDrawTraceMap";
import { useEffect } from "react";
const traceData = {
drive: [
{
lat: 23.1291,
lng: 113.2644,
},
{
lat: 23.0,
lng: 113.5,
},
{
lat: 22.9,
lng: 113.7,
},
{
lat: 22.8,
lng: 113.9,
},
{
lat: 22.7,
lng: 114.1,
},
{
lat: 22.5431,
lng: 114.0579,
},
],
startPoint: {
lat: 23.1291,
lng: 113.2644,
},
endPoint: {
lat: 22.5431,
lng: 114.0579,
},
};
const TestMap = () => {
const { containerId, drawTraceMap } = useDrawTraceMap();
useEffect(() => {
drawTraceMap({
traceData,
});
}, [drawTraceMap]);
return (
<div
style={{
height: "100vh",
background: "rgb(221, 228, 235)",
padding: "24px",
}}
>
<div style={{ height: "300px" }} id={containerId} />
</div>
);
};
export default TestMap;
页面效果
![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/c791dea9df1b4b58b99e237f7ba627db.png)