需求:
1.以某一點(diǎn)為圓心,半徑5000米以?xún)?nèi)的地方進(jìn)行標(biāo)注遣铝;
2.點(diǎn)擊選擇定位佑刷,添加覆蓋物,并解析地址酿炸;
3.通過(guò)搜索進(jìn)行定位:↑↓鍵進(jìn)行選擇Enter鍵確定瘫絮,也可以點(diǎn)擊選擇,并添加覆蓋物填硕。
官網(wǎng)地址:
https://lbsyun.baidu.com/index.php?title=webapi/guide/webservice-placeapi
這次的需求是麦萤,圓心五公里之內(nèi)的地方鹿鳖,需要可以搜索定點(diǎn)。根據(jù)文檔壮莹,需要用到的api是
https://api.map.baidu.com/place/v2/search?query=銀行&location=39.915,116.404&radius=2000&output=xml&ak=您的密鑰
具體參數(shù)看上面的網(wǎng)址就成~~
在解析地址時(shí)翅帜,可能會(huì)出現(xiàn)跨域問(wèn)題,所以我們還需要安裝一個(gè)vue-jsonp垛孔。
安裝 ↓
npm install vue-jsonp --s
main.js ↓
import {VueJsonp} from "vue-jsonp";
Vue.use(VueJsonp);
在utils中創(chuàng)建文件loadMap.js ↓
export default function loadBMap(ak) {
return new Promise(function(resolve, reject) {
if (typeof BMap !== 'undefined') {
resolve(BMap)
return true
}
window.onBMapCallback = function() {
resolve(BMap)
}
let script = document.createElement('script')
script.type = 'text/javascript'
script.src =
'http://api.map.baidu.com/api?v=2.0&ak=' + ak + '&callback=onBMapCallback'
script.onerror = reject
document.head.appendChild(script)
})
}
準(zhǔn)備工作就完成啦~~~~
正式代碼片段
html ↓
<div class="baidu-map-container">
<div id="tips-container">
當(dāng)前定位地址:
<el-input
clearable
v-model="locationTips"
size="mini"
@input="onInputLocation"
@blur="dispearAddressDrop"
@keyup.native="keydownChangeLocation"
@focus="onFocusLocation"
></el-input>
<!-- ↓ 為搜索時(shí)出現(xiàn)的下拉框 -->
<div class="drop-container" v-if="addressSearchDropShow">
<div
class="loop-address-search"
v-for="(address, idx) in addressSearchList"
:key="address.uid"
:class="addressNum === idx ? 'active-address' : ''"
@click="handleChooseAddress(idx)"
>
<i class="el-icon-search icon"></i>
<p class="name">{{ address.name }}</p>
<p class="address">{{ address.city + address.area }}</p>
</div>
</div>
</div>
<!-- ↓ 地圖容器 -->
<div id="baidu-map-container"></div>
</div>
css ↓ (首先要確保容器有足夠的寬高)
.baidu-map-container {
height: 480px;
position: relative;
#baidu-map-container {
width: 100%;
height: 100%;
position: absolute;
left: 0;
top: 0;
}
#tips-container {
z-index: 1;
position: absolute;
top: 10px;
left: 10px;
padding: 0px 7px;
min-width: 400px;
height: 70px;
line-height: 35px;
background: #fff;
box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
border-bottom: 1px solid lightgrey;
font-size: 12px;
.drop-container {
min-width: 400px;
max-height: 400px;
overflow: scroll;
overflow-y: auto;
overflow-x: hidden;
position: absolute;
left: 0;
background: white;
.loop-address-search {
padding: 0 7px;
display: flex;
align-items: center;
cursor: pointer;
.icon,
.name {
margin-right: 10px;
}
.icon {
line-height: 20px;
}
.address {
color: #999999;
}
}
.loop-address-search:hover {
background: rgba(0, 0, 0, 0.1);
}
.active-address {
background: rgba(0, 0, 0, 0.1);
}
}
.drop-container::-webkit-scrollbar {
display: none;
}
}
}
script ↓
// 引入寫(xiě)好的使用百度地圖的方法
import loadMap from "@/components/BaiduMap/loadMap";
data() {
return {
addressSearchDropShow: false,
addressNum: -1, // 控制地址搜索下拉框是否選中的變量
addressSearchList: [], // 搜索下拉框的數(shù)組
locationTips: "",
ifHasSearchAddress: false,
// 不知道該怎么備注了藕甩。。周荐。狭莱。都是語(yǔ)義化自己理解吧
currentSearchAddressInfo: {
lng: "",
lat: "",
},
// 中心點(diǎn)坐標(biāo)
center: {
lng: "119.587727",
lat: "39.961482",
},
};
},
methods: {
// 下拉框消失
dispearAddressDrop() {
// 設(shè)置定時(shí)器原因:
// 當(dāng)點(diǎn)擊下拉框中的任意一條時(shí),會(huì)先執(zhí)行el-input的blur方法
// 即概作,下拉框先消失腋妙,后面的語(yǔ)句都執(zhí)行不了啦
setTimeout(() => {
this.addressNum = -1;
this.addressSearchDropShow = false;
}, 100);
},
// 選中某條數(shù)據(jù)時(shí),將選中的地址放輸入框里讯榕,并保存經(jīng)緯度
handleChooseAddress(idx) {
let addressInfo = this.addressSearchList[idx];
// 當(dāng)選擇了一個(gè)地址后保存一個(gè)變量骤素,地圖添加覆蓋物時(shí)會(huì)有用
this.ifHasSearchAddress = true;
// 文字入框 獲取經(jīng)緯度
this.locationTips = addressInfo.name;
this.currentSearchAddressInfo = { ...addressInfo.location };
// 獲取到選中的經(jīng)緯度后需要重新加載地圖
this.initBaiduMap();
this.dispearAddressDrop();
},
onFocusLocation(e) {
if (e.target.value) {
this.addressNum = -1;
this.addressSearchDropShow = true;
}
},
keydownChangeLocation(e) {
if (e.keyCode === 40) {
// ↓
if (this.addressNum < this.addressSearchList.length - 1) {
this.addressNum++;
} else {
this.addressNum = 0;
}
}
if (e.keyCode === 38) {
// ↑
if (this.addressNum <= 0) {
this.addressNum = this.addressSearchList.length - 1;
} else {
this.addressNum--;
}
}
if (e.keyCode === 13) {
// Enter
this.handleChooseAddress(this.addressNum);
}
},
// 通過(guò)輸入的文字搜索一定范圍內(nèi)的地址
onInputLocation(val) {
this.addressNum = -1;
this.addressSearchDropShow = true;
// 獲取出現(xiàn)地址的API
this.$jsonp(
`https://api.map.baidu.com/place/v2/search?query=${val}&location=${this.center.lat},${this.center.lng}&radius=5000&output=json&ak=你的密鑰`
).then((res) => {
this.addressSearchList = res.results;
});
},
initBaiduMap() {
loadMap("你的密鑰")
.then(() => {
// 之后在circle中添加點(diǎn)擊事件時(shí)this指向會(huì)發(fā)生改變所以先存一個(gè)
let _this = this;
// 初始化地圖
this.myMap = new BMap.Map("baidu-map-container");
// 中心點(diǎn)和縮放
this.myMap.centerAndZoom(
new BMap.Point(this.center.lng, this.center.lat),
13
);
// 地圖可以使用鼠標(biāo)滾輪進(jìn)行縮小放大
this.myMap.enableScrollWheelZoom();
let geoc = new BMap.Geocoder();
// 設(shè)置規(guī)定范圍的圓圈
let circle = new BMap.Circle(
new BMap.Point(this.center.lng, this.center.lat),
5000,
{
strokeColor: "green",
strokeWeight: 6,
strokeOpacity: 0.5,
}
);
// 添加覆蓋物 規(guī)定范圍的圈兒
this.myMap.addOverlay(circle);
// 圓圈兒在之后可能會(huì)進(jìn)行的clearOverlays()時(shí)不會(huì)被刪除
circle.disableMassClear();
let marker;
// 選擇搜索地址后保存的變量
if (this.ifHasSearchAddress) {
marker = new BMap.Marker(
new BMap.Point(
this.currentSearchAddressInfo.lng,
this.currentSearchAddressInfo.lat
)
);
// 如果有選中的地址則添加marker
this.myMap.addOverlay(marker);
}
// 給圈兒內(nèi)的地圖范圍添加點(diǎn)擊事件
circle.addEventListener("click", function (e) {
// 清空下拉框中的數(shù)據(jù)
_this.addressSearchList = [];
// 清空之前的覆蓋物
_this.myMap.clearOverlays();
let point = e.point;
// 獲取點(diǎn)擊地點(diǎn)的經(jīng)緯度
_this.longitude = point.lng;
_this.latitude = point.lat;
// 添加覆蓋物
let markerPoint = new BMap.Marker(
new BMap.Point(point.lng, point.lat)
);
_this.myMap.addOverlay(markerPoint);
// 將點(diǎn)選的地址信息存入data中
geoc.getLocation(point, function (rs) {
let position = rs.addressComponents;
_this.locationTips = `${position.province}${position.city}${position.district}${position.street}${position.streetNumber}`;
});
});
})
.catch((err) => {
console.log("地圖加載失敗");
});
}
},
mounted() {
this.initBaiduMap();
},