页面初始化时,加载百度地图 JS,加载实现后执行回调函数开始定位,定位胜利后初始化地图对象,计算导航路线,而后展现。
反对 IP 定位须要在页面 <head> 标签引入的 JS:<script src="https://pv.sohu.com/cityjson?ie=utf-8"></script>
vue 单文件组件:mounted () {this.loadBaiduMapAsync()
},
methods: {
/**
* 初始化百度地图并定位用户以后地位
*/
loadBaiduMapAsync() {
// 加载百度地图 js
let script = document.createElement('script')
script.src = 'https://api.map.baidu.com/api?v=2.0&ak= 申请的 key&callback=initMap'
document.body.appendChild(script)
script.onload = (data) => { // 地图 js 加载胜利
console.log('百度地图 JS 加载胜利,开始定位')
window.initMap = this.startLocate
}
script.onerror = (data) => { // 地图 js 加载失败
console.log('百度地图 JS 加载失败,无奈定位')
common.showConfirm('舒适提醒','地图加载出错,请重试!', () => {this.loadBaiduMapAsync() }, null, '从新加载')
}
},
/**
* 获取用户以后定位 -- APP 端端
*/
startLocate() {if (this.isApp) { // APP 端
this.getPositionByAPP().then(point => {console.log('APP 定位胜利 -- 地位:', point);
this.currPos = point
this.showMapAndGuide() // 展现地图及导航}).catch(msg => {
this.status = 0
console.log(msg);
// common.showToast(msg, CONSTANTS.ERR_TOAST_TIME)
this.showDestination() // 展现地图和目的地})
} else { // 浏览器端
this.getPositionByH5().then(point => {console.log('浏览器定位胜利 -- 地位:', point);
this.currPos = point
this.showMapAndGuide() // 展现地图及导航}).catch(msg => {
this.status = 0
console.log(msg);
// common.showToast(msg, CONSTANTS.ERR_TOAST_TIME)
this.showDestination() // 展现地图和目的地})
}
},
/**
* 获取用户以后定位 -- APP 端端
*/
getPositionByAPP() {return new Promise(function(resolve, reject) {const cb = (err, data) => {if (err) {if (err.code === '001') { // 未开启定位服务
reject('请查看您的定位服务是否开启')
} else if (err.code === '002') { // 未受权利用拜访定位性能
reject('请受权 APP 拜访您的地位信息')
} else {console.warn(err);
reject('定位失败, 地位信息不可用')
}
} else { // app 定位胜利
let point = {
longitude: data.Longitude,
latitude: data.Latitude
}
if (this.isiOS) { // IOS 坐标转换
console.log('IOS 坐标转换')
const convertor = new BMap.Convertor()
convertor.translate([new BMap.Point(point.longitude, point.latitude)], 1, 5, res => { // 经纬度转换,否则会定位不准
if (res.status === 0) {point.latitude = res.points[0].lat
point.longitude = res.points[0].lng
resolve(point)
}
})
} else { // Andorid 坐标
resolve(point)
}
}
}
app.getCurrentLocation(cb)
})
},
/**
* 获取用户以后定位 -- 浏览器端
*/
getPositionByH5() {return new Promise(function(resolve, reject) {const locateByIP = function () {if (window.returnCitySN && window.returnCitySN.cip) { // 依据 IP,通过百度 api 取得经纬度
console.log('returnCitySN:', window.returnCitySN);
$.getJSON("https://api.map.baidu.com/location/ip?callback=?", {
'ak' : '申请的百度地图 key',
'coor' : 'bd09ll', // 百度经纬度坐标
'ip' : window.returnCitySN.cip // {cip: "116.77.145.35", cid: "440300", cname: "广东省深圳市"}
}, function(data) {if (data && data.content) {
resolve({
longitude: data.content.point.x,
latitude: data.content.point.y
})
} else {reject('定位失败, 地位信息不可用')
}
})
}
}
if (navigator.geolocation) {navigator.geolocation.getCurrentPosition(function(pos) {
resolve({
longitude: pos.coords.longitude,
latitude: pos.coords.latitude
})
}, function(error) {
let msg = ''
switch(error.code) {
case error.PERMISSION_DENIED:
msg="用户回绝对获取地理位置的申请。"
break;
case error.POSITION_UNAVAILABLE:
msg="地位信息是不可用的。"
break;
case error.TIMEOUT:
msg="申请用户地理位置超时。"
break;
case error.UNKNOWN_ERROR:
msg="未知谬误。"
break;
}
reject(msg)
// console.warn('浏览器端 (geolocation 定位失败)- 依据 IP 定位');
// locateByIP()}, {
enableHighAccuracy: true, // 批示浏览器获取高精度的地位,默认为 false
timeout: 5000, // 指定获取地理位置的超时工夫,默认不限时,单位为毫秒
maximumAge: 2000 // 最长有效期,在反复获取地理位置时,此参数指定多久再次获取地位。})
} else {reject('定位失败, 以后浏览器不反对定位!')
// console.warn('浏览器端 (geolocation 定位不反对)- 依据 IP 定位');
// locateByIP()}
})
},
/**
* 展现指标地位
*/
showDestination() {if (Number.isNaN(this.lng)|| Number.isNaN(this.lat)) {common.showAlert('地址参数谬误!', CONSTANTS.ERR_TOAST_TIME)
return
}
// 展现地图
const map = new BMap.Map("allmap")
const endPos = new BMap.Point(this.urlParams.lng, this.urlParams.lat)
// 展现指标地位
this.status = 2
map.centerAndZoom(endPos, 16)
map.addOverlay(new BMap.Marker(endPos))
map.enableScrollWheelZoom(true)
// 在右上角增加缩放控件
const zoom = new BMap.NavigationControl({
anchor: BMAP_ANCHOR_TOP_RIGHT,
type: BMAP_NAVIGATION_CONTROL_LARGE,
enableGeolocation: true
})
map.addControl(zoom)
},
/**
* 展现地图并导航
*/
showMapAndGuide() {if (Number.isNaN(this.lng)|| Number.isNaN(this.lat)) {common.showAlert('页面地址参数谬误!', CONSTANTS.ERR_TOAST_TIME)
return
}
// 展现地图
const map = new BMap.Map("allmap")
const startPos = new BMap.Point(this.currPos.longitude, this.currPos.latitude) // {lng: 114.02597366, lat: 22.54605355}
const endPos = new BMap.Point(this.lng, this.lat)
// 逆地址解析用户以后所在地址
const geoc = new BMap.Geocoder()
geoc.getLocation(startPos, res => {
const currCity = res.addressComponents.city // 用户以后定位所在城市
console.log(` 定位城市:${currCity} -- 球场地址:${this.address}`);
if (this.cityName && this.cityName.indexOf(currCity) > -1) { // 用户和指标球场在同一城市
this.status = 1
map.centerAndZoom(startPos, 16)
this.driveRoute(map, startPos, endPos, true)
} else { // 用户和指标球场不在同一城市
this.status = 2
map.centerAndZoom(endPos, 16)
map.addOverlay(new BMap.Marker(endPos))
// this.driveRoute(map, startPos, endPos, true)
}
})
map.enableScrollWheelZoom(true)
// 在右上角增加缩放控件
const zoom = new BMap.NavigationControl({
anchor: BMAP_ANCHOR_TOP_RIGHT,
type: BMAP_NAVIGATION_CONTROL_LARGE,
enableGeolocation: true
})
map.addControl(zoom)
},
/**
* 计算驾驶路线
* @param startPos BMap.Point 终点地位
* @param endPos BMap.Point 起点地位
* @param show Boolean
*/
driveRoute(map, startPos, endPos, show) {
const DRIVE = new BMap.DrivingRoute(map, {
renderOptions: {
map: map,
autoViewport: show,
},
onSearchComplete: res => {let plan = res.getPlan(0)
console.warn('查问驾车计划后果:', plan);
if (plan) {this.driveDistance = plan.getDistance(true)
this.driveTime = plan.getDuration(true)
}
},
onMarkersSet: routes => {// map.removeOverlay(routes[0].marker)
// map.removeOverlay(routes[1].marker)
// 解决百度地图起始点图标重叠问题
const eles = $('.BMap_Marker img')
if (eles.length > 0) {
eles.forEach(v => {
v.style.maxWidth = 'none'
v.style.width = '94px'
})
}
}
})
DRIVE.search(startPos, endPos)
}
}
}
</script>