1. 程式人生 > >微信小程式開發(2)——地圖定位、地圖滑動、建立路線等

微信小程式開發(2)——地圖定位、地圖滑動、建立路線等

1.地圖的使用

在wxml檔案中使用地圖,動態設定中心點位置和地圖大小等資訊。

<map id="map" 
  longitude="{{longitude}}" 
  latitude="{{latitude}}" 
  scale="14" 
  controls="{{controls}}" 
  markers="{{markers}}" 
  polyline="{{polyline}}" 
  bindcontroltap="controltap" 
  bindmarkertap="markertap" 
  bindregionchange="regionchange" 
  show-location 
  style="width: {{map_width}}px; height: {{map_height}}px;"
  data-statu="open">
  </map>

2.地圖定位和設定地圖大小

可以使用小程式的定位介面實現當前位,在app.js中進行封裝獲取當前位置的方法,要在<map>中設定show-location屬性。

/**
   *@param {function} cb 處理地理位置
   */
  getLocationInfo: function(cb) {
    var that = this;
    if (this.globalData.locationInfo) {
      cb(this.globalData.locationInfo)
    } else {
      wx.getLocation({
        type: 'gcj02', // 預設為 wgs84 返回 gps 座標,gcj02 返回可用於 wx.openLocation 的座標
        success: function(res) {
          that.globalData.locationInfo = res;
          cb(that.globalData.locationInfo)
        },
        fail: function(res) {
          console.log(res);
        }
      })
    }
  },

 呼叫,onShow每次顯示頁面時呼叫一次,動態設定地圖大小,獲取當前位置資訊並且查詢當前位置周邊裝置資訊。

data: {
    showModalStatus: false, // 彈窗
    map_width: 0,
    map_height: 0,
    longitude: 0, // 經度
    latitude: 0, //緯度
    markers: [],
    polyline: [],
    distance: 0,  // 距離
    cost: 0,  // 花費時長
    clearShow: false,
    searchContent: ''
  },
// 每次顯示當前頁面都要重新請求一次
onShow: function() {
    let that = this;
    // 獲取定位,並把位置標示出來
    app.getLocationInfo(function(locationInfo) {
      that.setData({
        markers: [],
        longitude: locationInfo.longitude,
        latitude: locationInfo.latitude
      });
      app.showLoading('正在載入');
      let data = {
        'gisX': that.data.longitude,
        'gisY': that.data.latitude
      };
      that.loadData(data); // 載入周邊裝置資訊
    }),
    // 動態設定map的寬和高
    wx.getSystemInfo({
      success: function(res) {
        that.setData({
          map_width: res.windowWidth,
          map_height: res.windowHeight - 44,
          controls: [{
            id: 0,
            iconPath: '/images/btn.png',
            position: {
              left: res.windowWidth * 0.5 - 80,
              top: res.windowHeight * 0.65,
              width: 161,
              height: 161
            },
            clickable: true
          }]
        })
      }
    });
  },

3.點選Marker顯示詳細資訊並建立路線

在wxml中設定彈窗容器

<cover-view class="drawer_box" wx:if="{{showModalStatus}}" bindtap="powerDrawer" data-statu="close">
  <!--drawer content-->
  <cover-view class="drawer_title">
    <cover-image src='../../images/icon-xz.png' />
    <cover-view class="distance">{{cost}}分鐘. 離目的地{{distance}}米</cover-view>
  </cover-view>
</cover-view>

<map>標籤中也要有對應的bindmarkertap="markertap"屬性,在js中設定markertap方法

markertap(e) {
    let that = this;
    let currentStatu = e.currentTarget.dataset.statu; // 當前彈窗open狀態
    let marker = markersData.filter(function(marker) {
      return marker.id === e.markerId;
    });// 通過點選的marker的id在markerData中篩選出對應的資訊
    this.util(currentStatu, marker[0]);
  },

建立路線要用到高德地圖小程式SDK,這裡產品只需要計算走路用時,所以設定了走路所用的時間

// 建立路線動畫
  util: function(currentStatu, marker) {
    let that = this;
    
    //關閉彈窗
    if (currentStatu == "close") {
     that.setData({
       showModalStatus: false,
       polyline: []
     });
    }

    // 顯示彈窗
    if (currentStatu == "open") {
      let markerLongitude = marker.gisX;
      let markerLatitude = marker.gisY;
      app.getLocationInfo(function(locationInfo) { // 呼叫app中的介面獲取當前位置資訊
        // 高德地圖key
        let amapFun = new amapFile.AMapWX({
          key: amapKey
        });
        amapFun.getWalkingRoute({
          origin: locationInfo.longitude + ',' + locationInfo.latitude, // 出發點,lon,lat
          destination: markerLongitude + ',' + markerLatitude, // 目的地
          success: function(data) {
            let points = [];
            if (data.paths && data.paths[0] && data.paths[0].steps) {
              let steps = data.paths[0].steps;
              for (let i = 0; i < steps.length; i++) {
                let poLen = steps[i].polyline.split(';');
                for (let j = 0; j < poLen.length; j++) {
                  points.push({
                    longitude: parseFloat(poLen[j].split(',')[0]),
                    latitude: parseFloat(poLen[j].split(',')[1])
                  })
                }
              }
            }
            that.setData({
              showModalStatus: true,
              polyline: [{
                points: points,
                color: "#5aad80",
                width: 5
              }]
            });
            if (data.paths[0] && data.paths[0].distance) {
              that.setData({
                distance: data.paths[0].distance
              });
            }
            if (data.paths[0] && data.paths[0].duration) {
              that.setData({
                cost: parseInt(data.paths[0].duration / 60) // 分鐘
              });
            }

          },
          fail: function(info) {
            console.log(info);
          }
        });
      });
    }
  },

 4.將地圖中心點移到當前位置

由於地圖是可以拖動的,當地圖中心點偏離當前位置的時候,可以設定按鈕,使當前位置為地圖中心點,使用mapCtx時要先建立

onReady: function(e) {
    // 使用 wx.createMapContext 獲取 map 上下文
    this.mapCtx = wx.createMapContext('map')
  },
 // 將地圖中心移動到當前位置
  moveToLocation: function() {
    this.mapCtx.moveToLocation()
  },

5.滑動地圖,動態獲取地圖中心點位置

這個功能找了很多方法,都沒有實現想要的效果,如果使用this.setData({marker})的方式會實現閃屏現象,而且各種bug,所以固定標記地圖中心點的方式,只有在wxml中使用<cover-view>標籤包裹中心點圖示來實現。要在<map>中設定bindregionchange="regionchange"屬性

// 地圖發生變化的時候,獲取中間點,也就是使用者選擇的位置
  regionchange(e) {
    // 會有兩次,一次start,一次end,一般情況下在移動結束後進行資料請求
    if (e.type == 'end') {
      app.showLoading('正在搜尋');
      this.getLngLat();
    }
  },
  // 獲取中間點的經緯度,並mark出來
  getLngLat: function() {
    var that = this;
    that.mapCtx = wx.createMapContext("map"); // 如果有初始化mapCtx,這裡可以省略
    that.mapCtx.getCenterLocation({
      success: function(res) {
        let curLatitude = res.latitude;
        let curLongitude = res.longitude;
        // 通過獲取的經緯度進行請求資料
        let data = {
          'gisX': curLongitude,
          'gisY': curLatitude
        };
        that.loadData(data);
      }
    })
  },

最後實現的效果圖

6.各大小程式地圖SDK功能對比

 路線規劃功能只有高德小程式地圖SDK才能實現,並且可以規劃步行、公交、駕車路線,還可以計算路線距離和時間

小程式地圖SDK 高德地圖 百度地圖 騰訊地圖
相同功能

獲取POI資料

獲取地址描述資料(逆地址編碼)

獲取輸入提示詞(熱詞聯想)

POI檢索

POI檢索熱詞聯想

逆地址解析

地點搜尋

關鍵詞輸入提示

逆地址解析(座標位置描述)

不同功能

獲取實時天氣資料

路線規劃

繪製靜態圖

天氣查詢

地址解析(地址轉座標)

距離計算

獲取城市列表

獲取城市區縣