小案例-前端使用百度地图插件

前言

大家好,我又带着我破破烂烂的代码大摇大摆地走来了。今天要做的是一个百度地图的使用,由于后期工作可能需要用到大量坐标,所以现在做一个模板,旨在方便用户录入确切的物理地址和经纬度坐标,总之需求就是这么个需求,那咱们一起来看看小弟写的代码吧



代码描述

本篇随笔实现了这样一个功能:用户可以根据输入的地址文字,然后跳转到地图的相应位置,并进行更准确的地址选择,然后将选定的点数据保存下来。在这里碰到了几个难点,接下来会讲到的,请~



代码

html:











    点我查看地图










js:

/**
 * @description     实现对``查看地图``按钮的监听
 */
$("#open_map").on('click', () => {

    // 首先生成地图载体,这么做是为了将来好销毁地图
    show_map($("#address").val());
    $("#modal_2").modal('show');
});


/**
 * @description         实现地图的销毁和挂载
 * @param p_node{string}   挂载地图标签的父容器
 * @param c_node{string}   地图标签的ID值
 */
function getMapContainer(p_node, c_node) {
    // 构造地图前判断是否存在地图容器,存在则销毁(因为无法销毁地图)
    if ($('#' + c_node).length > 0) {
        $("div").remove('#' + c_node);
    }

    // 构造地图容器并挂载到某元素下
    var $newMap = $('
'); $(p_node).append($newMap); } /** * @description 主函数,创建地图 * @param location{string} 传入的地理地址 */ var show_map = function (location) { // 构造地图容器 getMapContainer("#map_container", "area_map"); // 由于无法返回坐标点,因此只能从在地址转换函数中的回调函数中创建地图 location2point(location || 1, "", point => { var map = new BMap.Map("area_map"); // 设置中心点和开启滚轮权限 map.centerAndZoom(point, 14); map.enableScrollWheelZoom(true); // 地图上挂载标注 var myIcon = new BMap.Icon("", new BMap.Size(0, 0)); var marker = new BMap.Marker(point, myIcon); map.addOverlay(marker); // 监听右击事件 map.addEventListener("rightclick", function (event) { point2location(event.Ag, getCurrPoint); }); // 修正中心点和标记点偏移 let loadCount = 0; map.addEventListener("tilesloaded", function () { if (loadCount == 1) { map.setCenter(point); // 重设中心点 } loadCount += 1; }); }); }; /** * @description 右键触发时执行函数,旨在将点击信息带回 * @param result{JSON} 包含坐标点等数据的json对象 */ var getCurrPoint = function (result) { $.confirm({ title: '警告', content: '

是否选中此点?

' + '

地理位置:' + result.address + '

' + '

地理坐标:[' + result.point.lng + ', ' + result.point.lat + ']

', buttons: { confirm: { text: '确认', btnClass: "HL-btn-red", action: function () { $("#address").prop("value", result.address); $("#modal_2").modal("hide"); } }, cancel: { text: '取消', }, } }); }; /** * @description 地址转换成坐标函数 * @param address {string} 详细地址 * @param city {string} 所在城市 * @return {string} 坐标数组 */ function location2point(address, city, callback) { var myGeo = new BMap.Geocoder(); myGeo.getPoint(address, callback, city); } /** * @description 坐标转换成地址函数 * @param point {JSON} 坐标对象 * @return {string} 地址字符串 */ function point2location(point, callback) { var myGeo = new BMap.Geocoder(); // 传入的回调函数替代了默认的函数 myGeo.getLocation(new BMap.Point(point.lng, point.lat), callback); }


出现的问题

地图实例无法销毁:

首先第一个就是创建的地图实例无法销毁,最终逐渐累加成多层级,一般情况下不影响操作,但会造成页面臃肿和响应卡顿;而当你在地图层操作界面或新增层级时,还会出现多个重复(显示),其原因是点击在多层级页面时,会同时触发多个相同效果,如右键地图弹出弹框等,这种情况就属于BUG了。

在这里我想到的解决办法是,将地图挂载在即时生成的元素上,在每次展示地图时销毁地图父容器并重新创建


地图中心点和初始化标记偏移:

这个很好理解,就是初始化地图时,想看到的点跑偏了,这种问题通常是容器处于隐藏状态导致的,api会认为地图宽高为0(这种情况非常常见)。建议等待容器处于可见状态后再初始化地图。

在施展百度后,我找到了解决方法:如果中心点不对,那么在加载完成后重设中心点即可(哈哈哈,好直接的方法),使用的是tilesloaded()函数



结语

最后吐槽一下百度API,说实话不是很友好,实例用完不会自动销毁,同时地址解析/逆地址解析的结果居然不能直接返回,只能在回调函数中使用(或许是我搞错了,哈哈哈哈哈),一点都不符合解耦原则,这使得代码非常臃肿,即难看也难复用。好了,再见啦老铁们~ ~ ~


时间: 2020/08/21 17:08

坐标: 广东省深圳市


你可能感兴趣的:(小案例-前端使用百度地图插件)