Vue:百度地圖API 定位 地點檢索
阿新 • • 發佈:2018-11-17
一個全棧向前端的退化過程。 (咳~抱怨一句)
高德--API清晰,就是定位可能差了那麼點!
百度--國內較好支援國外定位 搜尋的平臺。(不過需要申請配額)
google -- 需要翻牆,沒花錢配額之前給你一次呼叫機會,
使用需求因個人而異,目前我需要拿到我當前定位的位置半徑2000米的地址檢索資訊。
<template> <div> <div id="allmap" hidden="true"></div> //這個必須帶上,就算不需要地圖隱藏即可 <loding ref="changes"/> //因為是載入函式,所以給了個loding子元件等待一下 <span v-for="item in distSort"> <div class="box_background"> <img src="http://p2.music.126.net/CQDGeibcfkSHbbyjapNBmw==/109951163430714435.jpg"/> <span class="shopName">name:{{item.title}}</span> <span class="shopAddress">address:{{item.address}}</span> <span class="shopPhone" v-if="item.phoneNumber!=null">phone:{{item.phoneNumber}}</span> <span class="shopDistance">distance:{{item.distance}} M</span> </div> </span> </div> </template>
因為沒有做路線規劃,所以我需要拿到我檢索的地址經緯度請求後臺,用mongoDB 2D索引計算他們之間的距離。
注意:
1.檢索出來的results裡的地址資訊是按照搜尋條件分組的,如:一個檢索條件,results中的長度才為1,2個條件長度為2,以此內推,(當初沒注意細節,直取資料也報錯,迴圈也報錯)
2.下面有一個去重函式,解釋一下,因為是按照條件搜尋,有時候不可避免兩個條件或多個條件搜尋出來的資料有重複,所以去重。
<script> import BMap from 'BMap' import BMapSymbolSHAPEPOINT from 'BMap_Symbol_SHAPE_POINT' import loding from "@/components/element/loding" export default{ name:"pet_shoplist", data(){ return{ pet_server: [], distSort:[] } }, mounted() { this.Map_Api() }, components:{ loding }, methods:{ //獲取定位IP地址的經緯度編碼並按需檢索 Map_Api() { var that = this var map = new BMap.Map("allmap"); map.enableScrollWheelZoom(); //得到IP地址經緯度資訊 function myFun(result) { console.log(result) //開啟地址檢索 --------------Ip地址獲取的經緯度資訊 寫入搜尋,以當前經緯度2000為圓圈 var mPoint = new BMap.Point(result.center.lng, result.center.lat); map.centerAndZoom(mPoint, 12); var circle = new BMap.Circle(mPoint, 2000, { fillColor: "blue", strokeWeight: 1, fillOpacity: 0.3, strokeOpacity: 0.3 }); map.addOverlay(circle); var local = new BMap.LocalSearch(map, { renderOptions: { map: map, autoViewport: false } }); //設定一個條件檢索最多15條資料 local.setPageCapacity(20); //搜尋範圍1500--搜尋周邊2公里附近的... local.searchNearby(['酒店','酒吧'], mPoint, 2000); local.setSearchCompleteCallback(function(results) { //呼叫請求方法,將results回撥引數傳遞 that.Req_lng_lat(results) }) } var myCity = new BMap.LocalCity(); myCity.get(myFun); }, //請求後臺利用mangoDB計算經緯度間的距離 Req_lng_lat(res_t) { console.log(res_t) //this指向 var that=this; //接收引數 var arr = [] //請求攜帶json引數 var petShop_context = [] // 判斷百度地圖API檢索條件,條件為一,那麼長度為一,可直接賦值給變數, // 若檢索條件為多...那麼檢索回撥長度就為多,直接取資料無效,必須2層迴圈遍歷,並將它們一一條 // 賦值給arr陣列 // 第一層迴圈遍歷檢索條件的長度,第二次迴圈遍歷條件下的檢索資料並賦值 if(res_t.length != null) { for(var i = 0; i < res_t.length; i++) { //console.log(res_t[i].Ar.length) for(var j = 0; j < res_t[i].Ar.length; j++) { //console.log(res_t[i].Ar[j].title) //that.pet_server.push(res_t[i].Ar[j]) arr.push(res_t[i].Ar[j]) } } } else { //單條件檢索,不需要遍歷,直接賦值 arr.push(res_t) } //---------------------------------------------------------------------- //去重 呼叫 var doSer_Arr=this.$options.methods.jsonUniq(arr,'uid') //---------------------------------------------------------------------- //---------------------------------------------------------------------- // 將檢索遍歷的資料取出後,迴圈他們將它們裝起做請求攜帶引數 for(var k = 0; k < doSer_Arr.length; k++) { //將檢索UUID&經緯度資訊封裝成一個json陣列,方便後臺呼叫 petShop_context.push({ uuid: doSer_Arr[k].uid, point: doSer_Arr[k].point }) } // console.log(petShop_context) //---------------------------------------------------------------------- //post請求,將引數傳遞給後臺拿他們去mangoDB做2D索引計算,並返回 this.$Request_post('/api/calDistance', {petShop_context:petShop_context}).then(res=>{ //迴圈請求返回資料,將他們的UUID對比,如果一樣就將返回的距離賦值 // console.log(res) for(var i=0;i<res.data.length;i++){ //因為請求的引數是獨立裝出來的所以需要 遍歷Arr for(var j=0;j<doSer_Arr.length;j++){ if(doSer_Arr[j].uid==res.data[i].uuid){ // console.log(res.data[i].dist) // arr[j].push({distance:res.data[i].dist}) // 給arr陣列新增一個距離欄位。 doSer_Arr[j].distance=Math.floor(res.data[i].dist) // console.log(res.data[i].dist) } } } this.changeStuta() //賦值Data中的變數,讓html程式碼遍歷展示 that.distSort=doSer_Arr }) //--------------------------------------------------------------------- }, //外部連結跳轉 Redierct(e) { window.location.href = e }, jsonUniq(arrjson, key) {//json 陣列去重 let arr1 = [arrjson[0]]; //記錄下標為1 arrjson.forEach(function (item1, idx1) { let flag = false; arr1.forEach(function (item2, idx2) { if (item1[key] == item2[key]) { flag = true; return; } }) if (!flag ) { arr1.push(item1) } }) return arr1; }, changeStuta(){ this.$refs.changes.changeStuta() //回撥子元件函式關閉loding載入 } } } </script>
<style scoped="true"> .box_background{ /*顏色漸變*/ background: linear-gradient(to bottom right,pink,darkgray); box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.2), 0 6px 20px 0 rgba(0, 0, 0, 0.19); width: 100%; height: 150px; font-size: 16px; font-weight:lighter; font-family: "Times New Roman",Georgia,Serif; color: #585858; border-radius: 8px; } img{ width: 80px; height: 80px; display: flex; margin-left: 10px; margin-top: 10px; padding-top: 35px; border-radius: 4px; } .box_background .shopName{ display: flex; margin-left: 110px; margin-top: -85px; } .box_background .shopAddress{ display: flex; margin-left: 110px; /*margin-top: -60px;*/ } .box_background .shopPhone{ display: flex; margin-left: 110px; /*margin-top: -30px;*/ } .box_background .shopDistance{ display: flex; margin-left: 110px; } </style>
loding載入元件:
<template>
<div>
<div class="fuceng" v-show="stuta">
<div class="loading">
<div class="loader-inner line-spin-fade-loader">
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
</div>
</div>
</div>
</div>
</template>
<script>
export default{
name:'loadin',
data(){
return{
stuta:true
}
},
methods:{
changeStuta(){
this.stuta=false
}
}
}
</script>
<style scoped>
.fuceng {
/*position: absolute;*/
display: flex;
margin-left: 50%;
margin-top: 40%;
}
.ball-spin-fade-loader {
position: relative;
}
.ball-spin-fade-loader>div:nth-child(1) {
top: 25px;
left: 0;
-webkit-animation: ball-spin-fade-loader 1s 0s infinite linear;
animation: ball-spin-fade-loader 1s 0s infinite linear;
}
.ball-spin-fade-loader>div:nth-child(2) {
top: 17.04545px;
left: 17.04545px;
-webkit-animation: ball-spin-fade-loader 1s 0.12s infinite linear;
animation: ball-spin-fade-loader 1s 0.12s infinite linear;
}
.ball-spin-fade-loader>div:nth-child(3) {
top: 0;
left: 25px;
-webkit-animation: ball-spin-fade-loader 1s 0.24s infinite linear;
animation: ball-spin-fade-loader 1s 0.24s infinite linear;
}
.ball-spin-fade-loader>div:nth-child(4) {
top: -17.04545px;
left: 17.04545px;
-webkit-animation: ball-spin-fade-loader 1s 0.36s infinite linear;
animation: ball-spin-fade-loader 1s 0.36s infinite linear;
}
.ball-spin-fade-loader>div:nth-child(5) {
top: -25px;
left: 0;
-webkit-animation: ball-spin-fade-loader 1s 0.48s infinite linear;
animation: ball-spin-fade-loader 1s 0.48s infinite linear;
}
.ball-spin-fade-loader>div:nth-child(6) {
top: -17.04545px;
left: -17.04545px;
-webkit-animation: ball-spin-fade-loader 1s 0.6s infinite linear;
animation: ball-spin-fade-loader 1s 0.6s infinite linear;
}
.ball-spin-fade-loader>div:nth-child(7) {
top: 0;
left: -25px;
-webkit-animation: ball-spin-fade-loader 1s 0.72s infinite linear;
animation: ball-spin-fade-loader 1s 0.72s infinite linear;
}
.ball-spin-fade-loader>div:nth-child(8) {
top: 17.04545px;
left: -17.04545px;
-webkit-animation: ball-spin-fade-loader 1s 0.84s infinite linear;
animation: ball-spin-fade-loader 1s 0.84s infinite linear;
}
.ball-spin-fade-loader>div {
background-color: #279fcf;
width: 15px;
height: 15px;
border-radius: 100%;
margin: 2px;
-webkit-animation-fill-mode: both;
animation-fill-mode: both;
position: absolute;
}
@-webkit-keyframes line-spin-fade-loader {
50% {
opacity: 0.3;
}
100% {
opacity: 1;
}
}
@keyframes line-spin-fade-loader {
50% {
opacity: 0.3;
}
100% {
opacity: 1;
}
}
.line-spin-fade-loader {
position: relative;
}
.line-spin-fade-loader>div:nth-child(1) {
top: 20px;
left: 0;
-webkit-animation: line-spin-fade-loader 1.2s 0.12s infinite ease-in-out;
animation: line-spin-fade-loader 1.2s 0.12s infinite ease-in-out;
}
.line-spin-fade-loader>div:nth-child(2) {
top: 13.63636px;
left: 13.63636px;
-webkit-transform: rotate(-45deg);
-ms-transform: rotate(-45deg);
transform: rotate(-45deg);
-webkit-animation: line-spin-fade-loader 1.2s 0.24s infinite ease-in-out;
animation: line-spin-fade-loader 1.2s 0.24s infinite ease-in-out;
}
.line-spin-fade-loader>div:nth-child(3) {
top: 0;
left: 20px;
-webkit-transform: rotate(90deg);
-ms-transform: rotate(90deg);
transform: rotate(90deg);
-webkit-animation: line-spin-fade-loader 1.2s 0.36s infinite ease-in-out;
animation: line-spin-fade-loader 1.2s 0.36s infinite ease-in-out;
}
.line-spin-fade-loader>div:nth-child(4) {
top: -13.63636px;
left: 13.63636px;
-webkit-transform: rotate(45deg);
-ms-transform: rotate(45deg);
transform: rotate(45deg);
-webkit-animation: line-spin-fade-loader 1.2s 0.48s infinite ease-in-out;
animation: line-spin-fade-loader 1.2s 0.48s infinite ease-in-out;
}
.line-spin-fade-loader>div:nth-child(5) {
top: -20px;
left: 0;
-webkit-animation: line-spin-fade-loader 1.2s 0.6s infinite ease-in-out;
animation: line-spin-fade-loader 1.2s 0.6s infinite ease-in-out;
}
.line-spin-fade-loader>div:nth-child(6) {
top: -13.63636px;
left: -13.63636px;
-webkit-transform: rotate(-45deg);
-ms-transform: rotate(-45deg);
transform: rotate(-45deg);
-webkit-animation: line-spin-fade-loader 1.2s 0.72s infinite ease-in-out;
animation: line-spin-fade-loader 1.2s 0.72s infinite ease-in-out;
}
.line-spin-fade-loader>div:nth-child(7) {
top: 0;
left: -20px;
-webkit-transform: rotate(90deg);
-ms-transform: rotate(90deg);
transform: rotate(90deg);
-webkit-animation: line-spin-fade-loader 1.2s 0.84s infinite ease-in-out;
animation: line-spin-fade-loader 1.2s 0.84s infinite ease-in-out;
}
.line-spin-fade-loader>div:nth-child(8) {
top: 13.63636px;
left: -13.63636px;
-webkit-transform: rotate(45deg);
-ms-transform: rotate(45deg);
transform: rotate(45deg);
-webkit-animation: line-spin-fade-loader 1.2s 0.96s infinite ease-in-out;
animation: line-spin-fade-loader 1.2s 0.96s infinite ease-in-out;
}
.line-spin-fade-loader>div {
background-color: #279fcf;
width: 4px;
height: 35px;
border-radius: 2px;
margin: 2px;
-webkit-animation-fill-mode: both;
animation-fill-mode: both;
position: absolute;
width: 5px;
height: 15px;
}
</style>
效果圖: