前言
大家好,我又带着我破破烂烂的代码大摇大摆地走来了。今天要做的是一个百度地图的使用,由于后期工作可能需要用到大量坐标,所以现在做一个模板,旨在方便用户录入确切的物理地址和经纬度坐标,总之需求就是这么个需求,那咱们一起来看看小弟写的代码吧
代码描述
本篇随笔实现了这样一个功能:用户可以根据输入的地址文字,然后跳转到地图的相应位置,并进行更准确的地址选择,然后将选定的点数据保存下来。在这里碰到了几个难点,接下来会讲到的,请~
代码
html:
<link rel="stylesheet" href="../css/included/bootstrap/bootstrap.min.css">
<link rel="stylesheet" href="../css/included/jquery/jquery-confirm.min.css">
<!-- 地图展示区域 -->
<div class="modal fade" tabindex="-1" role="dialog" id="modal_2">
<div class="modal-dialog modal-lg" role="document">
<div class="modal-content" style="margin-top: 100px" id="map_container">
<!-- <div id="container" style="width: 100%;height: 300px; padding: 20px;"></div> -->
</div>
</div>
</div>
<!-- 输入框及按钮区域 -->
<input class="form-control" style="display: inline-block;width: 200px;" id="address" type="text" placeholder="" />
<a href="#!" id="open_map" style="width: 30px;margin-left: 5px;">
点我查看地图
</a>
<!-- 引入的文件比较多, -->
<script type="text/javascript" src="../js/included/jquery/jquery.min.js"></script>
<script type="text/javascript" src="../js/included/jquery/jquery-confirm.min.js"></script>
<script type="text/javascript" src="../js/included/bootstrap/bootstrap-notify.min.js"></script>
<script type="text/javascript" src="../js/included/bootstrap/bootstrap.min.js"></script>
<!-- 这是调用百度API的必备,需要注册为百度开发者且申请密钥 -->
<script type="text/javascript"
src="http://api.map.baidu.com/getscript?v=2.0&ak=CQAzYqYyk1rMbcc9st8DG9szFZAfioib"></script>
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 = $(‘<div id="‘ + c_node + ‘" style="width: 100 %; height: 300px; padding: 20px; "></div>‘);
$(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: ‘<p><a style="color:red">是否选中此点?</a></p>‘ +
‘<p> 地理位置:<a>‘ + result.address + ‘</a></p>‘ +
‘<p> 地理坐标:<a>[‘ + result.point.lng + ‘, ‘ + result.point.lat + ‘]</a></p>‘,
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
坐标: 广东省深圳市
原文:https://www.cnblogs.com/caoLeiYing/p/13542026.html