微信小程序——定位、地圖顯示、線路規劃導航

一、地圖API選擇

1、查看微信小程序自帶的api和相關其他的api,微信團隊自帶的map組件理解不深,高德地圖的api簡明易理解使用。
2、原app開發採用的是高德地圖組件,爲了和app能夠保持一致性,採取高德地圖開發工具作爲本次地圖開發首選。

微信小程序地圖map組件開發文檔
微信小程序MapContext開發文檔
高德地圖開發文檔

二、高德地圖相關資料下載

2.1、js下載

amap-wx.js

2.2、高德key申請

key的申請

2.3、相關配置

高德官方配置

三、手寫一個demo

3.1、再全局apps.js中註冊全局key

App({
  d: {
	.....
  },
  gdMapProperties:{
    key:"xxxxxx"
  },
  ....

3.2、創建指定的頁面和地圖操作

創建指定的頁面,並進行路由設置,要求能夠跳轉進頁面。

3.2.1、在地圖頁面的js中,引入全局的js配置和高德自己的amap-wx.js文件。

var amapFile = require("../../../utils/amap-wx.js");
const apps = getApp();

3.2.2、在獲取位置信息前,需要優先判斷小程序是否開啓了位置權限信息

app.json中,標識權限信息

 "permission": {
    "scope.userLocation": {
      "desc": "您的位置信息將用於設備定位和藍牙操作"
    }
  },

在獲取位置信息前,判斷權限信息。

使用高德地圖獲取位置信息,失敗時則判斷是否具有權限信息

onLoad: function () {
    var that = this;
    this.data.myAmapFun = new amapFile.AMapWX({ key: apps.gdMapProperties.key });
    //授權檢測
    getPermission(this);
  },
//授權檢測函數封裝
function getPermission(obj) {
  obj.data.myAmapFun.getPoiAround({
    success: function (data) {
      console.log("獲取poi數據成功回調:" + JSON.stringify(data));
      markersData = data.markers;
      //判斷獲取的位置信息數
      if(markersData.length > 0){
        //存在數據  取第一條數據作爲當前用戶的位置信息值
        obj.setData({
          latitude: markersData[0].latitude,
          longitude: markersData[0].longitude,
        });
      }else{
        //不存在位置信息時,採取微信自帶地圖實現定位效果
        wx.getLocation({
          type: 'gcj02',
          success: function(res) {
            //顯示經緯度信息
            obj.setData({
              latitude: res.latitude,
              longitude: res.longitude
            });
          },
          fail: function () {
            //失敗則採取中國北京作爲地圖顯示
            obj.setData({
              latitude: 39.909729,
              longitude: 116.398419
            });
          }
        })
      }

    },
    fail: function (info) {
      console.log("獲取poi數據失敗回調:" + info);
      //如果失敗 則先檢測權限是否給予
      wx.getSetting({
        success: function (res) {
          var statu = res.authSetting;
          if (!statu['scope.userLocation']) {
            wx.showModal({
              title: '是否授權當前位置',
              content: '需要獲取您的地理位置,請確認授權,否則地圖功能將無法使用',
              success: function (tip) {
                if (tip.confirm) {
                  wx.openSetting({
                    success: function (data) {
                      if (data.authSetting["scope.userLocation"] === true) {
                        wx.showToast({
                          title: '授權成功',
                          icon: 'success',
                          duration: 1000
                        })
                        //授權成功之後,再調用定位進行位置獲取
                        getPermission(obj);
                      } else {
                        wx.showToast({
                          title: '授權失敗',
                          icon: 'success',
                          duration: 1000
                        })
                      }
                    }
                  })
                }
              }
            })
          }
        },
        fail: function (res) {
          wx.showToast({
            title: '調用授權窗口失敗',
            icon: 'success',
            duration: 1000
          })
        }
      })

    }
  })
}

3.2.3、marker顯示

<view class="map_container">
  <map class="map" id="map" 
  longitude="{{longitude}}" 
  latitude="{{latitude}}" 
  scale="18" 
  show-location="true" 
  markers="{{markers}}" 
  bindmarkertap="makertap" 
  bindtap='onclickMap'>
  </map>
</view>
data: {
    myAmapFun: null,//高德地圖對象
    //marker 設備位置信息
    markers: [{ id: "1", latitude: "30.499488", longitude:"114.342586"}],
    latitude: '',
    longitude: '',
    textData: {}
  }

當自定義data屬性中的marker屬性時,採取微信 map 組件實現地圖顯示,能夠將marker信息顯示在地圖指定的區域內。

如果是公司自己的開發設備,需要在地圖上顯示設備信息時,則可以在onload 頁面加載完成時,請求服務器獲取相關的設備的經緯度信息。

注意:

此處採取的是 微信的 map組件marker標識 組件信息,所以設定信息,需要採取微信官方文檔的要求來,比如marker需要給定不同的id,可以提升響應速率等。

微信map組件和marker組件文檔

3.2.4、線路規劃操作

此時需求爲:點擊地圖對應的marker標識時,需要在地圖上顯示對應的線路規劃信息。

線路規劃有很多種類,包括 步行、駕車、打車、乘騎等,我們目前只考慮兩種方式,步行和駕車出行。

<view class="gotoView">
    <view class="gotobyDriver" bindtap="gotobyDriver">駕車</view>
    <view class="gotobywalk" bindtap="gotobywalk" >步行</view>
  </view>

1、採取駕車出行方式顯示線路規劃

gotobyDriver:function(){
    console.log("駕車出行");
    //通過api  獲取線路點數
    var that = this;
    this.data.myAmapFun.getDrivingRoute({
      origin:that.data.longitude+","+that.data.latitude,
      destination: that.data.markers[0].longitude + "," + that.data.markers[0].latitude,
      success:function(data){
        //獲取當前經緯度信息到目標經緯度信息間無數個經緯度點位
        var points = [];
        if (data.paths && data.paths[0] && data.paths[0].steps) {
          var steps = data.paths[0].steps;
          //保存信息詳情
          that.setData({
            detailSteps: steps
          });
          for (var i = 0; i < steps.length; i++) {
            var poLen = steps[i].polyline.split(';');
            for (var j = 0; j < poLen.length; j++) {
              points.push({
                longitude: parseFloat(poLen[j].split(',')[0]),
                latitude: parseFloat(poLen[j].split(',')[1])
              })
            }
          }
        }
        that.setData({
          polyline: [{
            points: points,
            color: "#0091ff",
            width: 6
          }]
        });
      },
      fail: function (info) {

      }
    });
  },

2、選擇步行的出行方式線路規劃

//步行出行
  gotobywalk:function(){
    console.log("步行出行");
    //通過api  獲取線路點數
    var that = this;
    this.data.myAmapFun.getWalkingRoute({
      origin: that.data.longitude + "," + that.data.latitude,
      destination: that.data.markers[0].longitude + "," + that.data.markers[0].latitude,
      success: function (data) {
        //獲取當前經緯度信息到目標經緯度信息間無數個經緯度點位
        var points = [];
        if (data.paths && data.paths[0] && data.paths[0].steps) {
          var steps = data.paths[0].steps;
          console.log(JSON.stringify(steps));
          //保存信息詳情
          that.setData({
            detailSteps: steps
          });
          for (var i = 0; i < steps.length; i++) {
            var poLen = steps[i].polyline.split(';');
            for (var j = 0; j < poLen.length; j++) {
              points.push({
                longitude: parseFloat(poLen[j].split(',')[0]),
                latitude: parseFloat(poLen[j].split(',')[1])
              })
            }
          }
        }
        that.setData({
          polyline: [{
            points: points,
            color: "#0091ff",
            width: 6
          }]
        });
      },
      fail: function (info) {

      }
    });
  },

四、整體完整代碼

github小程序定位、地圖顯示、線路規劃完整demo

五、2019.10.31 對定位代碼進行修改操作

昨晚用微信開發者工具測試,地圖都能正常顯示,也能進行相應的線路規劃操作,但採取微信最新版本+小米8se實現真機實測時,卻出現了定位到了非洲西邊的海域,通過查詢日誌發現:

1、obj.data.myAmapFun.getPoiAround 無成功和失敗回調,但有時也有回調信息,具體問題還在分析。
2、map組件出現位置點位是 show-location設置爲true時,自動顯示的,但依舊無經緯度信息(注意點)

當無當前手機所在區域的位置信息時,線路規劃是無法正常進行的,設置初始的經緯度信息測試發現,可以進行線路規劃操作,證明此時的想法是正確的。
我們的小程序開發,客戶的使用範圍是全國各地都有,我們的初始經緯度信息不可能寫死吧,所以我們還得繼續死磕,如何獲取動態的、具體的經緯度信息!!

通過閱讀文檔發現:
在微信api 位置 中,有一個接口,wx.getLocation(Object object),在微信給予的demo中,並未寫明fail回調信息,通過我的測試發現,當未授予位置信息獲取權限時,此接口會進入失敗回調。那如何能夠具體實現動態的定位呢?我們修改 getPermission(obj) 函數。

function getPermission(obj) {
  console.log("getPermission");
  wx.getLocation({
    type: 'gcj02',
    success: function (res) {
      console.log("success  === "+JSON.stringify(res));
      //顯示經緯度信息
      obj.setData({
        latitude: res.latitude,
        longitude: res.longitude
      });
    },
    fail: function (res) {
      console.log("fail == "+JSON.stringify(res));
      //獲取位置信息失敗,判斷是否存在位置權限未給予,造成的影響
      if (!obj.data.getLocationFailAgain){
        console.log("首次失敗  查詢位置權限的授權情況");
        obj.setData({
          getLocationFailAgain:true
        });
        wx.getSetting({
          success: function (res) {
            var statu = res.authSetting;
            if (!statu['scope.userLocation']) {
              wx.showModal({
                title: '是否授權當前位置',
                content: '需要獲取您的地理位置,請確認授權,否則地圖功能將無法使用',
                success: function (tip) {
                  if (tip.confirm) {
                    wx.openSetting({
                      success: function (data) {
                        if (data.authSetting["scope.userLocation"] === true) {
                          wx.showToast({
                            title: '授權成功',
                            icon: 'success',
                            duration: 1000
                          })
                          //授權成功之後,再調用定位進行位置獲取
                          getPermission(obj);
                        } else {
                          wx.showToast({
                            title: '授權失敗',
                            icon: 'success',
                            duration: 1000
                          });
                          obj.setData({
                            latitude: 39.909729,
                            longitude: 116.398419
                          });
                        }
                      }
                    })
                  }else{
                    //點擊取消操作
                    wx.showToast({
                      title: '授權失敗',
                      icon: 'success',
                      duration: 1000
                    });
                    obj.setData({
                      latitude: 39.909729,
                      longitude: 116.398419
                    });
                  }
                }
              })
            }
          },
          fail: function (res) {
            wx.showToast({
              title: '調用授權窗口失敗',
              icon: 'success',
              duration: 1000
            })
            //失敗則採取中國北京作爲地圖顯示
            obj.setData({
              latitude: 39.909729,
              longitude: 116.398419
            });
          }
        })
      }
      
    }
  })
}

修改後的函數判斷相對簡單,爲了防止不斷進入死循環,所以在全局data中加入了一個標識,如果請求了設置信息接口,則表示不會繼續走權限獲取操作流程。

具體的代碼還是去看我的github代碼吧。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章