共计 5299 个字符,预计需要花费 14 分钟才能阅读完成。
页面初始化时,加载百度地图 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> |
正文完
发表至: javascript
2020-08-13