背景:嵌套在微信小程序中的h5,需要展示两点之间的一条推荐路线图。
参考:1.腾讯位置服务-开发指南-画线&路线规划
3.csdn文章:vue - vue使用腾讯api进行定位获取,绘制地图、标点、搜索、路线规划_vue 腾讯地图-CSDN博客
遇到的困难:按照开发指南中的用jsonp请求路线各点的话,到处都在报错,而且页面中新插入一个script,获取到的都是空。所以转换了思路,去服务类库找有没有方法,即找到了TMap.service.Driving方法来获取路线规划。
代码实现如下:
//html中需要一个map容器
<div id="map" ref={mapRef} />;
const mapRef = useRef<HTMLDivElement>(null);//便于获取map容器
const [location, setLocation] = useState<{ lat: number; lng: number }>();
const [map, setMap] = useState<any>();
//初始化地图
useEffect(() => {
let this_map: any;
const timeoutTask = setTimeout(() => {
this_map = new TMap.Map(mapRef.current, {
center: new TMap.LatLng(30.910392, 121.888566), //设置地图中心点坐标
zoom: 11.4, //设置地图缩放级别
pitch: 0, //设置俯仰角
rotation: 45, //设置地图旋转角度
});
setMap(this_map);
this_map.removeControl(TMap.constants.DEFAULT_CONTROL_ID.SCALE);
}, 0);
//卸载时销毁
return () => {
clearTimeout(timeoutTask);
this_map.destroy();
};
}, []);
// 绘制路径折线--先把方法写在外面了,方便下面useEffect中调用
const polylineLayer = useRef(null);
const displayPolyline = useCallback(
(pl: any, num: number) => {
// 第一次进来这个判断是不成立的
if (polylineLayer.current) {
// updateGeometries 这个方法是更新图层
polylineLayer.current.updateGeometries([
{
id: `p_${num}`,
styleId: 'style_blue', //和下面的styleID一一对应
paths: pl,
},
]);
} else {
// TMap.MultiPolyline 此方法用来构建折线 (地图线路规划)
polylineLayer.current = new TMap.MultiPolyline({
id: 'polyline-layer',
map: map,
styles: {
style_blue: new TMap.PolylineStyle({
color: '#3777FF', //线填充色
width: 6, //折线宽度
borderWidth: 3, //边线宽度
borderColor: '#FFF', //边线颜色
lineCap: 'round', //线端头方式
}),
},
//折线数据定义
geometries: [
{
id: 'pl_1', //折线唯一标识,删除时使用
styleId: 'style_blue', //绑定样式名
paths: pl,
},
],
});
}
},
[map],
);
//标记起始点,并规划路线
useEffect(() => {
if (map) {
const bounds = new TMap.LatLngBounds();
const startPosition = new TMap.LatLng(31.29043, 121.44726); // 路线规划起点
const endPosition = new TMap.LatLng(30.901489, 121.84124);//终点
const markerArr = [
{
id: '1', //点标记唯一标识,后续如果有删除、修改位置等操作,都需要此id
styleId: 'myStyle', //指定样式id
position: startPosition, //点标记坐标位置
},
{
id: '2',
position: endPosition,
},
];
new TMap.MultiMarker({
map: map, //指定地图容器
//样式定义
styles: {
//创建一个styleId为"myStyle"的样式(styles的子属性名即为styleId)
myStyle: new TMap.MarkerStyle({
width: 20, // 点标记样式宽度(像素)
height: 30, // 点标记样式高度(像素)
src: 'https://mapapi.qq.com/web/lbs/javascriptGL/demo/img/markerDefault.png', //图片路径
//焦点在图片中的像素位置,一般大头针类似形式的图片以针尖位置做为焦点,圆形点以圆心位置为焦点
anchor: { x: 16, y: 32 },
}),
},
//点标记数据数组
geometries: markerArr,
});
markerArr.forEach(function (item) {
//若坐标点不在范围内,扩大bounds范围
if (bounds.isEmpty() || !bounds.contains(item.position)) {
bounds.extend(item.position);
}
});
//设置地图可视范围
map.fitBounds(bounds, {
padding: 100, // 自适应边距
});
//-------------规划路线-------------
const driveLine = new TMap.service.Driving({
mp: false, // 是否返回多方案
policy: 'PICKUP,NAV_POINT_FIRST', // 规划策略
});
driveLine.search({ from: startPosition, to: endPosition }).then(
(res: any) => {
res.result.routes.map((item: { polyline: any }, index: number) => {
displayPolyline(item.polyline, index);
});
},
() => {
Toast.show({
content: '获取路线失败',
});
},
);
}
}, [ map, displayPolyline]);
以上即可完成腾讯地图两点之间的路线规划,以作记录,有任何问题,欢迎随时交流。