一个全栈向前端的退化过程。 (咳~抱怨一句)
高德--API清晰,就是定位可能差了那么点!
百度--国内较好支持国外定位 搜索的平台。(不过需要申请配额)
google -- 没花钱配额之前给你几次调用机会。
进入webpack.base.conf.js文件:在entry{}下添加
externals: {
'BMap': 'BMap',
'BMap_Symbol_SHAPE_POINT': 'BMap_Symbol_SHAPE_POINT'
},
index.html页添加:<script type="text/javascript" src="http://api.map.baidu.com/api?v=2.0&ak=KEY"></script>
使用需求因个人而异,目前我需要拿到我当前定位的位置半径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>
效果图: