項目中接到一個這樣的需求,需要展示公司所有員工在本市的住址分布情況,需要展示員工信息,需要展示本市疫情中風險地區並用紅色覆蓋,彈框展示信息,以及快速定位該區域。
em。。。很緊急,領導要看。
來吧,二話不說打開百度地圖api來研究,官方地址:http://lbsyun.baidu.com/
打開api文檔的時候,瞬間被潑冷水,公司網絡不能使用,攔截掉了嗎?不服氣的我立馬申請了密鑰,創建了項目,寫了個例子,果不其然,攔截了。這里沒有研究怎么解決,畢竟公司大部分用的內網。時間緊急,放棄。。。
搗騰半天,發現百度地圖api有專門供vue使用的,可以百度搜vue-baidu-map,中文文檔地址:https://dafrok.github.io/vue-baidu-map/#/zh/other/boundary。
寫了個小demo,發現還是有上面的問題。切到外網,就可以了,啊。。。咋整
突然想起以前寫的一個百度地圖覆蓋物的小筆記,哈,還可以這樣,不管了,先把功能整出來,上干貨(這里就不使用vue-baidu-map了,下次有需求再寫寫)
index.html文件中引用,密鑰ak就不貼出來了,可以自己申請:http://lbsyun.baidu.com/apiconsole/key#/home
<script src="http://api.map.baidu.com/api?v=3.0&ak=xxx"></script>
index.vue文件
<template> <div class="home"> <div class="title"> <p>中風險地區:</p> <Row v-for="(item,index) in contentArray" :key="index"> <Col class="ground"><span @click="goTake(index)">{{index+1}}、{{item}}</span></Col> </Row> </div> <div style="position:absolute;top:0;left:0;z-index:998;width:100%;height:100%;border:#ccc solid 1px;font-size:12px" id="map"></div> </div> </template>
initMap() { let map = new BMap.Map('map'); let _this = this; _this.map = map; let point = new BMap.Point(121.48053886017651, 31.235929042252014) // 創建點坐標 map.centerAndZoom(point, 12) // 初始化地圖,設置中心點坐標和地圖級別 map.enableScrollWheelZoom(true) //開啟鼠標滾輪縮放 map.addControl(new BMap.NavigationControl()) //添加默認縮放平移控件 map.addControl(new BMap.ScaleControl({anchor: BMAP_ANCHOR_BOTTOM_LEFT})) //向地圖中添加比例尺控件 map.addControl(new BMap.OverviewMapControl()) map.addControl(new BMap.MapTypeControl()) //map.setMapStyle({ style: 'midnight' }) //地圖風格 }
重點來了,如何在地圖上創建點覆蓋和區域划分覆蓋,達到顯示員工信息分布和中風險地區顯示的目的。
首先點覆蓋,公司整了份在線excel文檔,里面有所有員工信息,那么如何把所有信息都展示在地圖上呢,后台很忙,沒空把這些數據導入數據庫,再整個接口給我,所以自己想辦法唄,不就是轉成json數據嘛。。。百度搜索excel在線轉json,地址:http://www.jsonla.com/excel2json/,順便還格式化了一下,美滋滋
init() { this.custArr = require('../../../../static/json/person.json'); // this.$axios.get(URL).then((res) => { // this.custArr = res.data this.initMap(); this.getPoints(); // }) },
json放在了static文件中,這里沒有用axios,直接用的require,使用相對路徑是為了打包后路徑依然正確。相信用過這種獲取文件方式的人都遇到過打包后路徑不對的問題,這里不做考究。
var myGeo = new BMap.Geocoder(); this.custArr.forEach((item,index) => { if(!item.address) return myGeo.getPoint(item.address, function(point){ if (point) { let address = new BMap.Point(point.lng, point.lat);//創建坐標點 // console.log(item.name,item.address,address) let opts = { width:250, height: 100, title: '' }; let label = new BMap.Label(item.name,{offset:new BMap.Size(25,5)}) label.setStyle({ color: 'blue', borderRadius: '3px', borderColor: 'blue', padding: '0 3px', fontFamily: '微軟雅黑' }); let content = '<div>'; content += '<p style="height:20px;line-height:20px;">二級部門:' + item.department + '</p>'; content += '<p style="height:20px;line-height:20px;">姓名:' + item.name + '</p>'; content += '<p style="height:20px;line-height:20px;">手機號:' + item.phone + '</p>'; content += '<p style="height:20px;line-height:20px;overflow: hidden;text-overflow: ellipsis;white-space: nowrap;" title="'+item.address+'">住址:' + item.address + '</p>'; content += '<p style="height:20px;line-height:20px;">小區名:' + item.village + '</p>'; let infoWindows = new BMap.InfoWindow(content,opts); _this.addMarker(address,label,infoWindows); } },'中國'); }) if(this.boundariesArr.length != 0){ setTimeout(function () { _this.getBoundary(map); }, 2000); }
addMarker (points,label,infoWindows) { let greenIcon = new BMap.Icon(require("./images/greenIcon.png"), new BMap.Size(26, 26)); let markers = new BMap.Marker(points, {icon: greenIcon}); this.map.addOverlay(markers); markers.setLabel(label); markers.addEventListener("click",function (event) { this.map.openInfoWindow(infoWindows,points);//參數:窗口、點 根據點擊的點出現對應的窗口 }); }, getBoundary(map) { let polygons = []; let colors = ["#b95817", "#fff492", "#fff492"]; let pointArray = []; this.boundariesArr.forEach(item => { var ply = new BMap.Polygon(item, { strokeWeight: 2, strokeColor: "#ff0000" }); //建立多邊形覆蓋物 ply.setFillColor(colors[0]) //設置多邊形的填充顏色 ply.setFillOpacity(0.35); // ply.enableEditing(); //范圍可編輯 polygons.push(ply); //加入多邊形數組,以之后獲取多邊形邊界點集 map.addOverlay(ply); //添加覆蓋物 pointArray = pointArray.concat(ply.getPath()); }) // console.log(pointArray,123); // map.setViewport(pointArray); //調整視野 this.addlabel(map); },
這里創建點覆蓋,和區域覆蓋貼了部分代碼,大部分都是官網api就能看到。
最重要的問題來了,區域覆蓋,如何獲取行政區域區級以下邊界的點集,查了很多資料,大部分也沒有說出個所以然來,其實很簡單,百度地圖自己就帶有這樣的功能。
先上個地址:http://api.map.baidu.com/lbsapi/creatmap/, 一看是不是就明悟了一些
這里是可以自己標注范圍的,只要切換至你想要的省市,在地圖上找到你要的區域,標注好。獲取代碼,你可以找到標注線數組集合,改下格式就能用了
getPoints() { let _this = this; _this.boundariesArr = ["121.761489,31.147357;121.762207,31.145394;121.76713,31.146785;121.766375,31.148485;121.761525,31.147357;121.761489,31.147357","121.583571,31.110795;121.587757,31.111769;121.588799,31.10809;121.588781,31.107054;121.588386,31.105848;121.584883,31.105848;121.583589,31.11078;121.583571,31.110795","121.746989,31.179173;121.748642,31.1763;121.754391,31.17837;121.759494,31.179049;121.758883,31.181799;121.753134,31.18115;121.746989,31.179142","121.631745,31.195153;121.630792,31.190148;121.631152,31.189809;121.636919,31.192095;121.63505,31.195755;121.631691,31.195153"]; _this.initMap(); },
這是我找標注的四組數據,接下來添加覆蓋區就可以了
addlabel(map) { let pointArray = [ new BMap.Point(121.764498, 31.147079), //浦東新區祝橋鎮航城七路450弄小區 new BMap.Point(121.5857, 31.108059), //周浦鎮明天華城小區 new BMap.Point(121.748229, 31.178362), //浦東新區祝橋鎮新生小區 new BMap.Point(121.633712, 31.191616), //張江鎮順和路126弄小區 ]; let optsArray = [{}, {}, {}, {}, {}, {}, {}, {}, {}, {}]; let labelArray = []; for (let i = 0; i < pointArray.length; i++) { optsArray[i].position = pointArray[i]; labelArray[i] = new BMap.Label(this.contentArray[i], optsArray[i]); labelArray[i].setStyle({ color: "red", fontSize: "12px", height: "20px", borderRadius: '3px', lineHeight: "20px", fontFamily: "微軟雅黑" }); map.addOverlay(labelArray[i]); } },