百度地图定位和导航

页面初始化时,加载百度地图JS,加载完成后执行回调函数开始定位,定位成功后初始化地图对象,计算导航路线,然后展示。

支持IP定位需要在页面标签引入的JS:
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)
    }
  }
}

你可能感兴趣的:(javascript)