项目中需要根据经纬度数据做出一个轨迹图,研究了一下使用了百度地图实现。
最终效果如下,如果满足你的需求,可以继续往下看一看。
本人非专业前端,做的不好,还希望指出问题所在。
说明因为收集数据的时候使用的是高精度经纬度数据收集器,所以收到的数据格式为:
[[北纬,东经],[北纬,东经]] 这样的数据结构。
[[东经,北纬],[东经,北纬,]] 这样的数据结构还没试,不知道是否好用。
首先在public中的index.html中引入如下ak后是你自己的密钥。
<!-- BMapGL 样式文件 -->
<link rel="stylesheet" type="text/css" href="https://api.map.baidu.com/api?v=1.0&type=webgl&ak=你的密钥"/>
<!-- BMapGL JavaScript 文件 -->
<script type="text/javascript" src="https://api.map.baidu.com/api?v=1.0&type=webgl&ak=你的密钥"></script>
代码如下 :
import React, { useEffect, useState } from "react";
import { useLocation, useNavigate } from "react-router-dom";
import { getTopographyData } from "../../api/trajectories";
import startPng from "./images/start.png";
import endPng from "./images/end.png";
import { Button } from "antd";
const BMapGL = window.BMapGL;
const TrackDetailMap = () => {
const location = useLocation();
const [coordinates, setCoordinates] = useState([]);
const navigate = useNavigate();
useEffect(() => {
console.log(location.state.record.id);
getTopographyData(location.state.record.id).then((res) => {
if (res.code === 0) {
// 将从后端获取的 WGS-84 坐标系的经纬度数据转换为 BD-09 坐标系
const convertCoordinates = res.data.map(coord => convertWGS84ToBD09(coord[1], coord[0]));
Promise.all(convertCoordinates).then(bd09Coordinates => {
setCoordinates(bd09Coordinates);
});
} else {
// 处理错误
}
});
}, [location]);
useEffect(() => {
if (coordinates.length === 0) return;
const pois = coordinates.map((coord) => new BMapGL.Point(coord.lng, coord.lat));
const map = new BMapGL.Map("allmap");
map.centerAndZoom(pois[0], 21);
map.enableScrollWheelZoom(true);
const polyline = new BMapGL.Polyline(pois, {
enableEditing: false,
enableClicking: true,
strokeWeight: 6,
strokeOpacity: 0.8,
strokeColor: "#f5c104",
});
map.addOverlay(polyline);
const startIcon = new BMapGL.Icon(startPng, new BMapGL.Size(35, 35), {
anchor: new BMapGL.Size(18, 28),
});
const startMarker = new BMapGL.Marker(pois[0], { icon: startIcon });
map.addOverlay(startMarker);
const endIcon = new BMapGL.Icon(endPng, new BMapGL.Size(35, 35), {
anchor: new BMapGL.Size(18, 25),
});
const endMarker = new BMapGL.Marker(pois[pois.length - 1], { icon: endIcon });
map.addOverlay(endMarker);
}, [coordinates]);
const handleBackClick = () => {
navigate(-1);
};
// 转换函数:将 WGS-84 坐标系的经纬度转换为 BD-09 坐标系
const convertWGS84ToBD09 = (lng, lat) => {
return new Promise((resolve, reject) => {
const point = new BMapGL.Point(lng, lat);
const convertor = new BMapGL.Convertor();
convertor.translate([point], 1, 5, (result) => {
if (result.status === 0) {
resolve({ lng: result.points[0].lng, lat: result.points[0].lat });
} else {
reject(new Error("坐标转换失败"));
}
});
});
};
return (
<div>
<div id="allmap" style={{ width: "100%", height: "500px" }}></div>
<Button
onClick={handleBackClick}
style={{
position: "absolute",
top: "68px",
left: "240px",
zIndex: "999",
margin: "10px",
}}
>
返回
</Button>
</div>
);
};
export default TrackDetailMap;
相关代码解释:
import startPng from "./images/start.png";
import endPng from "./images/end.png";
这两个是自定义的开始结束图标。
下图中的红框内控制图片偏移位置,可自定义设置。
下图中因为传入的经纬度数据不是百度需要的坐标系,所以转换一下,不转换位置偏差特别大。
下图中的map.centerAndZoom(pois[0], 21);表示地图显示的位置,我显示的位置是数组中的第一组数据,21表示地图放大倍数。
下图中的参数解释:
pois
: 这是一个包含了折线各个节点位置的数组。每个节点都是一个包含经纬度信息的对象,用于定义折线的形状。enableEditing: false
: 这个参数指定是否启用折线的编辑功能。当设置为true
时,用户可以在地图上编辑折线的节点位置,否则不能编辑。在这个例子中,折线的编辑功能被禁用。enableClicking: true
: 这个参数指定是否允许对折线进行点击。当设置为true
时,用户可以点击折线来触发相应的事件,例如点击事件。在这个例子中,允许对折线进行点击。strokeWeight: 6
: 这个参数指定了折线的线宽,即折线的粗细程度。在这个例子中,折线的线宽为6像素。strokeOpacity: 0.8
: 这个参数指定了折线的透明度,取值范围为0到1,其中0表示完全透明,1表示完全不透明。在这个例子中,折线的透明度为0.8。strokeColor: "#f5c104"
: 这个参数指定了折线的颜色。颜色值可以是十六进制格式的颜色代码,也可以是代表颜色的字符串。在这个例子中,折线的颜色为黄色 (#f5c104
)。
下图中表示开始图标喝结束图标的位置并设置了偏移量,开始图标位置是二维数组中的第一组数据的位置,结束位置是二维数组中最后一组的数据位置。