乐趣区

关于javascript:百度地图定位和导航

页面初始化时,加载百度地图 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>
退出移动版