前言
随着互联网的发展,地图应用已经成为了人们生活中不可或缺的一部分。而在开发中,如何快速、方便地实现地图选点功能,成为了一个备受关注的问题。本文将介绍如何使用百度地图和 vue,快速地实现地图选点功能,并将其封装成一个可复用的组件。无论是开发地图应用,还是需要在项目中使用地图选点功能,本文都将为大家提供一些有用的参考。
准备工作
1. 首先你需要注册一个百度账号,登录百度地图开放平台。可参考官方开发文档
2. 右上角点击进入控制台,申请注册成为开发者。
提交后在 『应用管理』–『我的应用』 中拿到申请密钥(ak)
3. 在 public
目录下 index.html
文件,添加如下引用
<script type="text/javascript" src="https://api.map.baidu.com/api?v=3.0&ak=你的密钥"></script>
4. npm
包
npm i vue-baidu-map --save
main.js
注册
import BaiduMap from 'vue-baidu-map'
Vue.use(BaiduMap,{ak:'你的密钥'})
实现思路
- 引入百度地图
API
; - 在
vue
组件中创建地图容器; - 初始化地图,并添加地图控件;
- 监听地图点击事件,获取点击位置的经纬度;
- 在地图上添加标记,并将标记位置设置为点击位置;
- 逆向解析经纬度从而拿到详细的地址;
- 将标记位置的经纬度及详细地址保存到变量中传递。
话不多说,下面直接进入实战环节
封装文件
<template>
<div>
<el-dialog :close-on-click-modal="false" :visible.sync="dialogVisible" width="80%">
<baidu-map @moving="syncCenterAndZoom" @moveend="syncCenterAndZoom" @zoomend="syncCenterAndZoom" class="bm-view" :center="center"
:zoom="zoom" :scroll-wheel-zoom="true" @click="getClickInfo">
<bm-marker :position="{lng: center.lng, lat: center.lat}" :dragging="true" animation="BMAP_ANIMATION_BOUNCE">
</bm-marker>
<bm-control :offset="{width: '10px', height: '10px'}">
<bm-auto-complete v-model="keyword" :sugStyle="{zIndex: 9999}">
<input type="text" placeholder="请输入搜索关键字" class="serachinput">
</bm-auto-complete>
</bm-control>
<bm-local-search :keyword="keyword" :auto-viewport="true" style="width:0px;height:0px;overflow: hidden;"></bm-local-search>
</baidu-map>
<div class="btnBox">
<el-button size="medium" type="primary" @click="confirm">确定</el-button>
</div>
</el-dialog>
</div>
</template>
<script>
export default {
data: function () {
return {
dialogVisible: this.value, //弹框显隐
keyword: "", //搜索关键字
center: { lng: 116.404555, lat: 39.915599 }, //经纬度
zoom: 13, //缩放级别
address: "", //详细地址
point: { lng: 116.404555, lat: 39.915599 }, //经纬度
};
},
props: {
value: Boolean,
},
methods: {
// 打开弹框
revealShow() {
this.dialogVisible = true;
},
// 点击地图
getClickInfo(e) {
this.center.lng = Number(e.point.lng).toFixed(6);
this.center.lat = Number(e.point.lat).toFixed(6);
this.geocAddress(e.point);
},
// 地图缩放、地图缩放、移动过程中持续触发
syncCenterAndZoom(e) {
const { lng, lat } = e.target.getCenter();
this.center.lng = Number(lng).toFixed(6);
this.center.lat = Number(lat).toFixed(6);
this.zoom = e.target.getZoom();
this.geocAddress(e.target.getCenter());
},
// 逆向解析地址
geocAddress(point) {
let that = this;
var geoc = new BMap.Geocoder();
geoc.getLocation(point, function (geocInfo) {
if (geocInfo) {
let detailsInfo = geocInfo.addressComponents;
let address =
detailsInfo.province +
detailsInfo.city +
detailsInfo.district +
detailsInfo.street +
detailsInfo.streetNumber;
if (geocInfo.surroundingPois.length > 0) {
address = address + geocInfo.surroundingPois[0].title;
}
that.address = address;
that.point = point;
}
});
},
// 确认
confirm() {
this.dialogVisible = false;
this.$emit("confirmOn", this.point, this.address);
},
},
};
</script>
<style scoped>
.bm-view {
width: 100%;
height: 60vh;
}
.serachinput {
margin: 10px;
width: 300px;
border: none;
border-radius: 4px;
padding: 0px 10px;
height: 40px;
line-height: 40px;
border: 1px solid #dcdfe6;
color: #606266;
}
.btnBox {
margin-top: 20px;
display: flex;
justify-content: right;
}
/* 去除百度地图的图标 根据实际情况看是否要加样式穿透 */
/* ::v-deep .anchorBL {
display: none !important;
} */
</style>
使用文件
<template>
<div>
<el-card class="box-card">
<div style="margin-bottom:10px">
<p>经度:{{center.lng ? center.lng : "--"}}</p>
<p>维度:{{center.lat ? center.lat : "--"}}</p>
<p>地址:{{address ? address : "--"}}</p>
</div>
<el-button size="mini" type="primary" @click="openMapDialog">打开地图</el-button>
</el-card>
<!-- 地图组件 -->
<div>
<geographicalMap @confirmOn="ensureOn" ref="bmapAddressSelect"></geographicalMap>
</div>
</div>
</template>
<script>
import geographicalMap from "./mapView";
export default {
components: {
geographicalMap,
},
data() {
return {
center: { lng: "", lat: "" },
address: "",
};
},
methods: {
// 打开地图
openMapDialog() {
this.$refs.bmapAddressSelect.revealShow();
},
// 确定
ensureOn(center, address) {
this.center = center;
this.address = address;
},
},
};
</script>