目录
准备工作
需求1:根据地址中文或者经纬度在地图显示对应的坐标点
需求2:搜索地址然后在地图上显示对应的大致路线
需求3:根据地址跳转到本机安装的对应地图APP中,并显示目标位置
由于项目中需要用到地图展示,之前也没用到过地图展示,所以记录一下自己的探索过程,共同成长,互勉!
引用地图功能需要引用对应的js包,可以到对应官方文档查看例子,这里就不做多说明。附上链接(https://lbs.qq.com/),然后在官网注册一个账号,创建项目,生成对应的key值,这个时候就可以把对应的key值写在刚才引入的js包链接上,我们项目用到的是umi框架,引入js文件的地方是document.ejs,如果是别的项目自行百度引入的位置。
可以考虑把这个地图封装成组件,然后在需要的地方进引用即可,地图的组件需要用到一个对象TMap。首先,你需要在页面上编写一个div,然后创建地图对象的时候初始在对应的div上,即可展现地图。
// 初始化地图
function setMap() {
//初始化地图
map = new TMap.Map(document.getElementById('addressMap'), {
viewMode: '2D',
});
//初始化蒙层
markerLayer = new TMap.MultiMarker({
map: map, // 指定地图容器
// 样式定义
styles: {
myStyle: new TMap.MarkerStyle({
width: 18, // 点标记样式宽度(像素)
height: 26, // 点标记样式高度(像素)
anchor: { x: 16, y: 32 }
}),
startMarker: new TMap.MarkerStyle({
width: 25,
height: 35,
anchor: { x: 16, y: 32 },
src: start
}),
endMarker: new TMap.MarkerStyle({
width: 25,
height: 35,
anchor: { x: 16, y: 32 },
src: end
})
}
});
}
现在你打开页面,已经可以在页面上看到地图了。自此,准备工作已经完成。
这个需求需要根据地址中文查询出对应的坐标值,然后在地图上标注出来,我们需要编写一个函数用来在地图上标注出对应的点,点的展示需要坐标值,所以我们还需要调用响应的接口,进行坐标值转换,可查看官方文档,这里就不做多介绍。
根据这个接口,会对应返回中文地址的坐标值。而后,我们还需要一个函数来在地图上描点,描点的样式在初始化的时候已经定义好了样式,直接引用即可,这个函数会先清除掉之前的标注点,如果你不想清除,则直接添加即可。
// 加载标注点
const setMarkerlayer =(item)=> {
const _wait_to_clear_ = markerLayer.getGeometries();
if (_wait_to_clear_.length > 0) {
// 先清除旧标注点
const str = _wait_to_clear_.map((item) => item.id);
markerLayer.remove(str);
}
//设置对应的地图中心点
map.setCenter({ lat: current.lat, lng: current.lng });
//增加标注点
markerLayer.add({
styleId: 'endMarker', //之前初始地图定义的样式
id: item.id | 'endmarker',
position: new TMap.LatLng(item.lat || 0, item.lng || 0)
});
}
这个需求根据你搜索的地点,然后在地图上描绘出当前位置到搜索地点的大致路线,我们需要做的有两个,定位当前所在位置,然后将其标注成起点,把搜索的地点标注成终点,然后描绘出起点和终点的路线。根据官方文档的api,即可定位当前位置,并返回对应的坐标值。
function getLocationIp() {
let url = `/map/ws/location/v1/ip?key=${window.mapkey}`;
io.get(url).then(res=> {
addMarkerlayer(res.result.location, 'startMarker'); //增加标注点
})
}
描绘路线根据你传入的两个坐标位置,返回对应的路线。然后根据官方给出的方法,即可描绘出路线。
//初始化描线图层
const setPolylineLayer = () => {
polylineLayer = new TMap.MultiPolyline({
id: 'polyline-layer', //图层唯一标识
map: map,//绘制到目标地图
//折线样式定义
styles: {
'style_blue': new TMap.PolylineStyle({
'color': '#3777FF', //线填充色
'width': 6, //折线宽度
'borderWidth': 5, //边线宽度
'borderColor': '#FFF', //边线颜色
'lineCap': 'round' //线端头方式
})
}
})
}
//查询路线
const direcationPlan =() => {
const copyCurrent = current;
const copyPurpose = purpose;
let url = '/map/ws/direction/v1/driving/' +
'?from=' + current.lat + ',' + current.lng + '&to=' + purpose.lat + ',' + purpose.lng +
'&output=json&callback=cb' +
'&key=' + window.mapkey;
io.get(url).then(res=>{
cb(res);
}).catch()
}
//定义请求回调函数
const cb =(ret) => {
let coors = ret.result.routes[0].polyline, pl = [];
//坐标解压(返回的点串坐标,通过前向差分进行压缩,因此需要解压)
let kr = 1000000;
for (let i = 2; i < coors.length; i++) {
coors[i] = Number(coors[i - 2]) + Number(coors[i]) / kr;
}
//将解压后的坐标生成LatLng数组
for (let i = 0; i < coors.length; i += 2) {
pl.push(new TMap.LatLng(coors[i], coors[i+1]));
}
setMarkerPolyline(pl)//显示路线
}
// 增加描线点
const setMarkerPolyline =(p1)=> {
const _wait_to_clear_ = polylineLayer.getGeometries();
if (_wait_to_clear_.length > 0) {
// 先清除旧标注点
const str = _wait_to_clear_.map((item) => item.id);
polylineLayer.remove(str);
}
polylineLayer.add({
'id': 'pl_1',//折线唯一标识,删除时使用
'styleId': 'style_blue',//绑定样式名
'paths': p1
})
}
效果如图:
目前找不到检测移动端是否有安装对应的APP,所以把市面上主流的三大地图软件都做了点击跳转,效果如图:
如果本机有安装对应的地图APP,则直接跳转到对应软件,如果有安装,则跳转到对应的下载页面。各自地图的跳转链接附上:
打开安卓高德地图
打开iOS高德地图
打开百度地图
打开腾讯地图
实现的具体代码如下:
const toMoblieMap =(item)=> {
if(item.label == '取消') {
setIsShow(!isShow);
return ;
}
if (navigator.userAgent.match(/(iPhone|iPod|iPad);?/i)) {
var loadDateTime = new Date();
window.location = (item?.openUrl1 || item?.openUrl) + address;//schema链接或者universal link
window.setTimeout(function() { //如果没有安装app,便会执行setTimeout跳转下载页
var timeOutDateTime = new Date();
if (timeOutDateTime - loadDateTime < 5000) {
let hidden = window.document.hidden || window.document.mozHidden || window.document.msHidden ||window.document.webkitHidden
if(typeof hidden =="undefined" || hidden ==false) {
window.location = item.download2; //ios下载地址
}
} else {
window.close();
}
}, 4000);
} else if (navigator.userAgent.match(/android/i)) {
var state = null;
try {
window.location = item.openUrl + address; //schema链接或者universal link
window.setTimeout(function() {
let hidden = window.document.hidden || window.document.mozHidden || window.document.msHidden ||window.document.webkitHidden
if(typeof hidden =="undefined" || hidden ==false) {
window.location = item.download1; //android下载地址
}
}, 4000);
} catch (e) {}
}
}
至此,基本的功能已经完成,有很多需要完善的地方,比如如何检测到本机安装的地图软件等,很多细节也处理的不是很好,希望各位指正,互相交流进步!!!