bing Map 在vue專案中的使用

LucaLJX發表於2018-04-07

a (10).jpg

寫在最前面

擁有全球資料庫國內好像就只有百度地圖有,高德、搜狗、騰訊的都不行,但是由於百度地圖的資料更新不及時,所以在做相關專案要用到國外資料的時候,最好還是推薦使用bingMap。

bing Map 使用教程(基礎)

參考文件: bing Map 官方教程

bing Map 初始化

  • 引入bing map資源
<script type='text/javascript' src='http://www.bing.com/api/maps/mapcontrol?callback=GetMap&key=[YOUR_BING_MAPS_KEY]' async defer></script>
複製程式碼
  • 初始化地圖
<div id="myMap"></div>

<script type='text/javascript'>
  function GetMap()
  {
    var map = new Microsoft.Maps.Map('#myMap');
    //Add your post map load code here.
  }
</script>
複製程式碼
  • 設定地圖控制引數

    • 常用控制引數
      • branch
        • 載入地圖sdk的哪個分支:release(預設)、experimental
      • callback
        • 地圖控制指令碼載入完成後的回撥(預設:GetMap)
      • key
        • 使用者使用的userKey(詳情
      • setLang
        • 指定用於地圖示籤和導航控制元件的語言
        • 常用:中國大陸(zh-CN)、中國香港(zh-HK)、簡體中文(zh-Hans)、台灣(zh-TW)、英文-英國(en-GB)、英文-美國(en-US)
      • setMkt(詳情
      • UR(詳情
  • 給bing map新增地圖事件(參考

  //  核心程式碼-demo
  Microsoft.Maps.Events.addHandler(你的地圖名稱, 觸發地圖事件名稱, function() { 觸發的事件 });

  // 常用例項
  //Add view change events to the map.
  // 檢視更改事件
  Microsoft.Maps.Events.addHandler(map, 'viewchangestart', function () { highlight('mapViewChangeStart'); });
  Microsoft.Maps.Events.addHandler(map, 'viewchange', function () { highlight('mapViewChange'); });
  Microsoft.Maps.Events.addHandler(map, 'viewchangeend', function () { highlight('mapViewChangEnd'); });

  //Add mouse events to the map.
  // 滑鼠事件
  Microsoft.Maps.Events.addHandler(map, 'click', function () { highlight('mapClick'); });
  Microsoft.Maps.Events.addHandler(map, 'dblclick', function () { highlight('mapDblClick'); });
  Microsoft.Maps.Events.addHandler(map, 'rightclick', function () { highlight('mapRightClick'); });
  Microsoft.Maps.Events.addHandler(map, 'mousedown', function () { highlight('mapMousedown'); });
  Microsoft.Maps.Events.addHandler(map, 'mouseout', function () { highlight('mapMouseout'); });
  Microsoft.Maps.Events.addHandler(map, 'mouseover', function () { highlight('mapMouseover'); });
  Microsoft.Maps.Events.addHandler(map, 'mouseup', function () { highlight('mapMouseup'); });
  Microsoft.Maps.Events.addHandler(map, 'mousewheel', function () { highlight('mapMousewheel'); });

  //Add addition map event handlers
  Microsoft.Maps.Events.addHandler(map, 'maptypechanged', function () { highlight('maptypechanged'); });
複製程式碼

bing Map 新增圖釘(詳情

基本圖釘示例

function GetMap() {
  var map = new Microsoft.Maps.Map('#myMap', {
    credentials: 'Your Bing Maps Key',
    center: new Microsoft.Maps.Location(47.6149, -122.1941)
  });

  var center = map.getCenter();

  //Create custom Pushpin
  //  建立一個圖釘
  var pin = new Microsoft.Maps.Pushpin(center, {
    // demo_1
    title: 'Microsoft', // 圖釘的標題
    subTitle: 'City Center', // 圖釘主體文字
    text: '1' // 圖釘內的文字
    // demo_2
    color: 'red', // 純色圖釘
  });

  //Add the pushpin to the map
  map.entities.push(pin);
}
複製程式碼

demo_1

Pushpin_1.png

demo_2

Pushpin_2.png

新增自定義圖片圖釘(詳情

function GetMap() {
  var map = new Microsoft.Maps.Map('#myMap',
  {
    credentials: 'You Bing Maps Key'
  });

  var center = map.getCenter();

  //Create custom Pushpin
  var pin = new Microsoft.Maps.Pushpin(center, {
    icon: 'images/poi_custom.png', // 自定義圖片路徑
    anchor: new Microsoft.Maps.Point(12, 39)
  });

  //Add the pushpin to the map
  map.entities.push(pin);
}
複製程式碼

自定義圖示的圖釘

Pushpin_3.png

bing Map 給圖釘新增事件

  • 核心程式碼
//Create a pushpin.
  var pushpin = new Microsoft.Maps.Pushpin(map.getCenter());
  map.entities.push(pushpin);

  //Add mouse events to the pushpin.
  // 將自定義方法及滑鼠事件新增到圖釘上面
  Microsoft.Maps.Events.addHandler(pushpin, 'click', function () { highlight('pushpinClick'); });
  Microsoft.Maps.Events.addHandler(pushpin, 'mousedown', function () { highlight('pushpinMousedown'); });
  Microsoft.Maps.Events.addHandler(pushpin, 'mouseout', function () { highlight('pushpinMouseout'); });
  Microsoft.Maps.Events.addHandler(pushpin, 'mouseover', function () { highlight('pushpinMouseover'); });
  Microsoft.Maps.Events.addHandler(pushpin, 'mouseup', function () { highlight('pushpinMouseup'); });
複製程式碼

bing Map 給圖釘新增hover樣式

其核心還是給bing Map的圖釘新增事件,通過事件修改圖釘的樣式

// demo
var defaultColor = 'blue';
var hoverColor = 'red';
var mouseDownColor = 'purple';

var pin = new Microsoft.Maps.Pushpin(map.getCenter(), {
    color: defaultColor
});

map.entities.push(pin);

Microsoft.Maps.Events.addHandler(pin, 'mouseover', function (e) {
    e.target.setOptions({ color: hoverColor });
});

Microsoft.Maps.Events.addHandler(pin, 'mousedown', function (e) {
    e.target.setOptions({ color: mouseDownColor });
});

Microsoft.Maps.Events.addHandler(pin, 'mouseout', function (e) {
    e.target.setOptions({ color: defaultColor });
});
複製程式碼

給圖釘新增hover樣式

Pushpin_4.jpeg

bing Map 固定錨點

開發人員在使用自定義圖釘時遇到的最常見問題之一是,當他們縮放地圖時,看起來好像他們的圖釘正在漂移到或離開它所要錨定的位置。這是由於圖釘選項中的錨點值不正確。錨點指定影象的哪個畫素座標相對於影象的左上角應與圖釘位置座標重疊。

常見配置參考

bing Map 在vue中使用

vue引入bing Map可能會遇到的問題

由於vue一般引用第三方外掛是用import的方式進行的,所以的在html中使用script標籤引入bing Map SDK會出現兩種問題

1.在控制檯會報錯:Mirosorft is not defined

2.vue-cli會報錯:Mirosorft is not defined

這裡的原因是由於非同步載入,所以在呼叫"Mirosorft"的時候可能SDK並沒有引用成功

解決“Mirosorft is not defined”的錯誤

文件參考

解決“Mirosorft is not defined”的錯誤,只要在專案中保證呼叫地圖之前,能夠正確引入相關工具類就行了。

// bing map init devTools
export default {
  init: function (){
    console.log("初始化bing地圖指令碼...");
    // bing map key
    const bingUesrKey = '你的bingMap Key';
    const BingMap_URL = 'http://www.bing.com/api/maps/mapcontrol?callback=GetMap&key=' + bingUesrKey;
    return new Promise((resolve, reject) => {
      if(typeof Microsoft !== "undefined") {
        resolve(Microsoft);
        return true;
      }

      // 插入script指令碼
      let scriptNode = document.createElement("script");
      scriptNode.setAttribute("type", "text/javascript");
      scriptNode.setAttribute("src", BingMap_URL);
      document.body.appendChild(scriptNode);

      // 等待頁面載入完畢回撥
      let timeout = 0;
      let interval = setInterval(() => {
        // 超時10秒載入失敗
        if(timeout >= 20) {
          reject();
          clearInterval(interval);
          console.error("bing地圖指令碼初始化失敗...");
        }
        // 載入成功
        if(typeof Microsoft !== "undefined") {
          resolve(Microsoft);
          clearInterval(interval);
          console.log("bing地圖指令碼初始化成功...");
        }
        timeout += 1;
      }, 500);
    });
  }
}  

// bing map vue
import bingMap from './**/bing-map';
bingMap.init()
  .then((Microsoft) => {
      console.log(Microsoft)
      console.log("載入成功...")
      // 開始地圖操作
  })
複製程式碼

整合bing Map元件到vue中

需要達到的功能

  • 在vue專案中成功載入bing Map (完成)
  • 當點選bing Map的時候,返回點選點的經緯度 (完成)
    • 子元件觸發事件返回引數到父元件
  • 當已有經緯度的時候,載入bingMap自動顯示其經緯度所在的位置並設定圖釘 (待完成)

子元件觸發事件返回引數到父元件

// 子元件
<template>
<div @click="iclick"></div>
</template>
methods:{
  iclick(){
    let data = {
      a:'data'
    };
    this.$emit('ievent', data1, 'data2Str');
  }
}
// 父元件
<i-template @ievent = "ievent"></i-template>
methods:{
  ievent(...data){
    console.log('allData:',data); // data為包含傳過來所有資料的陣列,第一個元素是物件,第二個元素是字串
  }
}
複製程式碼

封裝bing Map通用元件

// 核心程式碼
<template>
  <div class="map-container">
    <div id="localMap"></div>
  </div>
</template>

<script>

import initBingMap from './initMap.js'

export default {
  data () {
    return {
      lngNum: null, // 經度
      latNum: null, // 緯度
    }
  },
  created: function () { 
    let _this = this;
    initBingMap.init()
    .then((Microsoft) => {
      console.log(Microsoft)
      console.log("載入成功...")
      _this.initMap();
    })
  },
  methods: {
    initMap () {
      let _this = this;
      let map = new Microsoft.Maps.Map('#localMap', {
        credentials: 'AgzeobkGvmpdZTFuGa7_6gkaHH7CXHKsFiTQlBvi55x-QLZLh1rSjhd1Da9bfPhD'
      });
      Microsoft.Maps.Events.addHandler(map, 'click', _this.getClickLocation);
    },
    getClickLocation (e) {
      //若點選到地圖的標記上,而非地圖上
      let [_this, loc] = [this, null];
      if (e.targetType == 'pushpin') {
        loc = e.target.getLocation();
      }
      //若點選到地圖上
      else {
        var point = new Microsoft.Maps.Point(e.pageX, e.pageY);
        loc = e.target.tryPixelToLocation(point, Microsoft.Maps.PixelReference.page);
      }
      console.log(loc.latitude+", "+loc.longitude);
      console.log(loc);
      _this.lngNum = loc.longitude;
      _this.latNum = loc.latitude;
      let data = {
        lngNum: _this.lngNum,
        latNum: _this.latNum
      }
      this.$emit('getLocationNums',data);
    },
  }
}
</script>

<style scoped>
  .map-container {
    width: 100%;
    height: 400px;
    border: 1px solid #000;
  }
</style>
複製程式碼

在元件中呼叫bing Map通用元件

// 引入bingMap
import bingMapsLayer from 'bingMap.vue'

// component中定義
components: {
  bingMapsLayer
},

// template中使用
<bing-maps-layer @getLocationNums="getLocationNums"></bing-maps-layer>

// 定義觸發點選標記返回經緯度的事件函式
getLocationNums (...data) {
  let _this = this;
  console.log('click');
  console.log(data);
  // 這裡的data中即子元件bingMap返回的點選獲取的經緯度值
},
複製程式碼

未完待續

後續

  • 在bingMap元件中使用自定義圖釘
  • 在bingMap元件中定義可拖動圖釘標記經緯度
  • 整合bingMap自定義搜尋
  • 整合bingMap圖釘詳情展示

BY - Luca_LJX github: luca_ljx

相關文章