当前位置:   article > 正文

Vue3 + 百度地图实现位置选择,获取地址经纬度_vue实现定位

vue实现定位

Vue3 + 百度地图实现位置选择,获取地址经纬度

  • 需求:添加传感器时,需要选择传感器所在的省、市、区、详细地址、以及传感器的经纬度信息。
  • 解决方案:集成百度地图API,通过在地图上搜索或者点击获取传感器的具体位置信息。

百度地图选择地址效果

  • 具体效果如下图所示

集成百度地图的具体实现

  • 技术方案: Vue + ElementUI + 百度地图 JavaScript API v3.0
  • 申请成为百度地图开发者并获取秘钥
    • 参考文档:https://lbsyun.baidu.com/index.php?title=jspopular3.0/guide/getkey

第一步:引入百度地图 JavaScript API v3.0 文件

  1. export function BMPGL(ak) {
  2. return new Promise(function (resolve, reject) {
  3. window.init = function () {
  4. // eslint-disable-next-line
  5. resolve(BMapGL);
  6. };
  7. const script = document.createElement("script");
  8. script.type = "text/javascript";
  9. script.src = `http://api.map.baidu.com/api?v=3.0&type=webgl&ak=${ak}&callback=init`;
  10. script.onerror = reject;
  11. document.head.appendChild(script);
  12. });
  13. }

第二步:编写百度地图选择位置组件

  1. <template>
  2. <div class="bmapgl">
  3. <p>搜索地址获取地址的经纬度</p>
  4. <el-button @click="show" style="margin-bottom: 20px">打开地图</el-button>
  5. <el-form label-width="80px">
  6. <el-row>
  7. <el-col :span="10">
  8. <el-form-item label="当前地点">
  9. <el-input
  10. size="small"
  11. type="text"
  12. readonly
  13. v-model="addressInfo.address"
  14. />
  15. </el-form-item>
  16. </el-col>
  17. <el-col :span="7">
  18. <el-form-item label="位置经度">
  19. <el-input
  20. size="small"
  21. type="text"
  22. v-model="addressInfo.longitude"
  23. readonly
  24. />
  25. </el-form-item>
  26. </el-col>
  27. <el-col :span="7">
  28. <el-form-item label="位置纬度">
  29. <el-input
  30. size="small"
  31. type="text"
  32. v-model="addressInfo.latitude"
  33. readonly
  34. />
  35. </el-form-item>
  36. </el-col>
  37. </el-row>
  38. </el-form>
  39. <el-dialog
  40. v-model="openMap"
  41. title="位置选择"
  42. width="1000px"
  43. :close-on-click-modal="false"
  44. destroy-on-close
  45. >
  46. <el-form label-width="80px">
  47. <el-row>
  48. <el-col :span="10">
  49. <el-form-item label="当前地点">
  50. <el-input
  51. size="small"
  52. type="text"
  53. id="suggestId"
  54. v-model="addressInfo.address"
  55. placeholder="请输入地点"
  56. />
  57. </el-form-item>
  58. </el-col>
  59. <el-col :span="7">
  60. <el-form-item label="位置经度">
  61. <el-input
  62. size="small"
  63. type="text"
  64. v-model="addressInfo.longitude"
  65. readonly
  66. />
  67. </el-form-item>
  68. </el-col>
  69. <el-col :span="7">
  70. <el-form-item label="位置纬度">
  71. <el-input
  72. size="small"
  73. type="text"
  74. v-model="addressInfo.latitude"
  75. readonly
  76. />
  77. </el-form-item>
  78. </el-col>
  79. </el-row>
  80. </el-form>
  81. <div
  82. class="baidu"
  83. ref="mapRef"
  84. id="baidumap"
  85. style="width: 100%; height: 450px"
  86. ></div>
  87. <template #footer>
  88. <span class="dialog-footer">
  89. <el-button @click="cancel">取 消</el-button>
  90. <el-button type="primary" @click="confirmSelect"> 确 定 </el-button>
  91. </span>
  92. </template>
  93. </el-dialog>
  94. </div>
  95. </template>
  96. <script setup lang="ts">
  97. import { BMPGL } from "@/utils/loadBmap.ts";
  98. import { onMounted, watch, ref, reactive } from "vue";
  99. import { ElMessage } from "element-plus";
  100. const emit = defineEmits(["confirmMapAddress"]);
  101. let map = ref(null);
  102. const mapZoom = ref(15);
  103. const ak = ref("填百度地图密钥");
  104. let openMap = ref(false);
  105. let addressInfo = reactive({
  106. // 地址信息
  107. longitude: "", // 经度
  108. latitude: "", // 纬度
  109. province: "", // 省
  110. city: "", // 市
  111. district: "", // 区
  112. address: "", // 详细地址
  113. });
  114. watch(
  115. () => [openMap],
  116. () => {
  117. if (!openMap.value) {
  118. map.value && map.value.destroy();
  119. }
  120. },
  121. { deep: true }
  122. );
  123. onMounted(() => {
  124. initMap();
  125. });
  126. const initMap = () => {
  127. map.value = null;
  128. BMPGL(ak.value).then((BMapGL: any) => {
  129. map.value = new BMapGL.Map("baidumap");
  130. var ac = new BMapGL.Autocomplete({
  131. //建立一个自动完成的对象
  132. input: "suggestId",
  133. location: map.value,
  134. });
  135. var zoomCtrl = new BMapGL.ZoomControl(); // 添加缩放控件
  136. map.value.addControl(zoomCtrl);
  137. var cityCtrl = new BMapGL.CityListControl(); // 添加城市列表控件
  138. map.value.addControl(cityCtrl);
  139. var LocationControl = new BMapGL.LocationControl(); // 添加定位控件,用于获取定位
  140. map.value.addControl(LocationControl);
  141. var scaleCtrl = new BMapGL.ScaleControl(); // 添加比例尺控件
  142. map.value.addControl(scaleCtrl);
  143. map.value.setMapType(); // 设置地图类型为标准地图模式;
  144. var localcity = new BMapGL.LocalCity();
  145. localcity.get((e: { name: any }) => {
  146. map.value.centerAndZoom(e.name, mapZoom.value);
  147. });
  148. let point: any;
  149. //初始化的时候如果有经纬度,需要先在地图上添加点标记
  150. if (addressInfo.longitude && addressInfo.latitude) {
  151. point = new BMapGL.Point(addressInfo.longitude, addressInfo.latitude);
  152. map.value.centerAndZoom(point, mapZoom.value);
  153. var marker2 = new BMapGL.Marker(point);
  154. //在地图上添加点标记
  155. map.value.addOverlay(marker2);
  156. }
  157. map.value.enableScrollWheelZoom(true);
  158. map.value.setHeading(64.5);
  159. map.value.setTilt(73);
  160. //点击下拉框的值
  161. map.value.addEventListener(
  162. "click",
  163. function (e: { latlng: { lng: string; lat: string } }) {
  164. map.value.clearOverlays();
  165. var point1 = new BMapGL.Point(e.latlng.lng, e.latlng.lat);
  166. // 创建点标记
  167. var marker1 = new BMapGL.Marker(point1);
  168. // 在地图上添加点标记
  169. map.value.addOverlay(marker1);
  170. addressInfo.longitude = e.latlng.lng;
  171. addressInfo.latitude = e.latlng.lat;
  172. var geoc = new BMapGL.Geocoder(); // 创建地址解析器的实例
  173. geoc.getLocation(point1, (rs: { addressComponents: any }) => {
  174. let adr = rs.addressComponents;
  175. addressInfo.address =
  176. adr.province +
  177. adr.city +
  178. adr.district +
  179. adr.street +
  180. adr.streetNumber; // 省市区街道门牌号
  181. });
  182. }
  183. );
  184. ac.addEventListener("onconfirm", function (e: { item: { value: any } }) {
  185. //鼠标点击下拉列表后的事件
  186. var _value = e.item.value;
  187. addressInfo.address =
  188. _value.province +
  189. _value.city +
  190. _value.district +
  191. _value.street +
  192. _value.business;
  193. // 搜索
  194. map.value.clearOverlays(); //清除地图上所有覆盖物
  195. //智能搜索
  196. var local = new BMapGL.LocalSearch(map.value, {
  197. onSearchComplete: () => {
  198. //获取第一个智能搜索的结果
  199. const pp = local.getResults().getPoi(0).point;
  200. map.value.centerAndZoom(pp, mapZoom.value);
  201. map.value.addOverlay(new BMapGL.Marker(pp)); //添加标注
  202. addressInfo.longitude = pp.lng;
  203. addressInfo.latitude = pp.lat;
  204. },
  205. });
  206. local.search(addressInfo.address);
  207. });
  208. });
  209. };
  210. /** 打开地图选择 */
  211. const show = () => {
  212. openMap.value = true;
  213. initMap();
  214. };
  215. /**
  216. * 确认选择
  217. */
  218. const confirmSelect = () => {
  219. if (addressInfo.address == "") {
  220. ElMessage({
  221. message: "请选择位置",
  222. type: "error",
  223. center: true,
  224. });
  225. return;
  226. }
  227. emit("confirmMapAddress", addressInfo);
  228. openMap.value = false;
  229. };
  230. /**
  231. * 取消选择
  232. */
  233. const cancel = () => {
  234. openMap.value = false;
  235. };
  236. </script>
  237. <style>
  238. .tangram-suggestion {
  239. z-index: 99999;
  240. }
  241. </style>
  242. <style scoped lang="scss">
  243. :deep(.BMap_cpyCtrl) {
  244. display: none !important;
  245. }
  246. :deep(.BMap_cpyCtrl) {
  247. display: none !important;
  248. }
  249. :deep(.el-dialog__header),
  250. :deep(.el-dialog__footer) {
  251. padding: 15px 20px;
  252. }
  253. :deep(.el-dialog__body) {
  254. border-top: 1px solid #e8eaec;
  255. border-bottom: 1px solid #e8eaec;
  256. padding: 20px;
  257. }
  258. :deep(.el-dialog__headerbtn) {
  259. top: 0;
  260. font-size: 18px;
  261. }
  262. :deep(.el-dialog) {
  263. border-radius: 8px;
  264. }
  265. </style>

项目中需要使用到Bmap模糊地址查询的功能,但是发现搜索出的结果展示被遮挡。已经搜索到结果但是被dialog给遮挡住了。

解决方式:

需要修改autocomplete的样式,调整css z-index设置元素的堆叠顺序:

  1. <style>
  2. .tangram-suggestion {
  3. z-index: 99999;
  4. }
  5. </style>

注意不要踩坑的是:

要去掉style标签的 scoped,这样的话重写的css样式才能生效。

百度地图Web开发
JavaScript API v3.0 (2D地图 标准版)
API文档地址:https://lbsyun.baidu.com/index.php?title=jspopular3.0
示例地址:https://lbsyun.baidu.com/index.php?title=open/jsdemo3.0
JavaScript API v2.0 (没有维护了)
JavaScript API v1.0(没有维护了)
JavaScript API Lite v1.0 (2D地图 移动端H5版)
API文档地址:https://lbsyun.baidu.com/index.php?title=jspopularLiteV1
示例地址:https://lbsyun.baidu.com/index.php?title=open/jsdemoLite
JavaScript API GL v1.0 (3D地图 )
API文档地址:https://lbsyun.baidu.com/index.php?title=jspopularGL
示例地址:https://lbsyun.baidu.com/jsdemo.htm

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/AllinToyou/article/detail/109905?site
推荐阅读
相关标签
  

闽ICP备14008679号