一 功能实现
1.添加map对应的div,如下:
<strong> <div id="address_modal" style="background-color: #acacac">
<div style="position: absolute; z-index: 999;">
<input id="address_text" type="text"
placeholder="请输入路段名称,如软件园"
style="margin-left: 50px; width: 300px;" /> <input
type="button" value="确认" ng-click="addressSearch()" /> <input
type="button" value="取消" ng-click="addressCancel()" />
</div>
<div id="address-modal"
style="position: absolute; width: 600px; height: 600px; border: 1px solid gray;">
</div>
</div></strong>
以上是一个包含输入框,确认/取消按钮以及百度map的对话框。代码很简单,记得设置好对应控件的ID和样式即可。
2.创建初始化方法
//百度map初始化
map = new BMap.Map("address-modal");
//百度地图相关操作
function onMapShow () {
map.clearOverlays();//清空原来的标注
map.centerAndZoom("福州", 12);
map.addEventListener("tilesloaded", function() {
map.enableScrollWheelZoom(); //启用滚轮放大缩小,默认禁用
map.enableContinuousZoom(); //启用地图惯性拖拽,默认禁用
map.addControl(new BMap.NavigationControl()); //添加默认缩放平移控件
map.addControl(new BMap.OverviewMapControl()); //添加默认缩略地图控件
map.addControl(new BMap.OverviewMapControl({
isOpen : true,
anchor : BMAP_ANCHOR_BOTTOM_RIGHT
})); //右下角,打开
});
}
第一句话将baiduMap与div绑定,切记不要写在方法内导致多次初始化,否则容易出现地图显示不全的Bug...
OnMapShow()方法很简单,就是一些常见参数的设置,clearOverlays()会清空地图上所有的标注,如不需要可以删除。
3.根据输入的地址查找到坐标,并标记在地图上
//创建地址解析器实例setPlace(myValue)方法是根据传入的myValue(实际地址,如福州市动物园)来获取map坐标,并由map.addOverlay(marker);方法来标记在地图上。 实际开发中可能会报出can't find coord错,这个后面再讲。
function setPlace(myValue) {
var myGeo = new BMap.Geocoder();// 将地址解析结果显示在地图上,并调整地图视野
myGeo.getPoint(myValue, function(point) {
if (point) {
marker = new BMap.Marker(point);
map.centerAndZoom(point, 14);
map.addOverlay(marker);
marker.enableDragging(); //标注可拖拽
markListener(marker);
} else {
alert("您选择地址没有解析到结果!");
}
}, "福州市");
}
//地图监听方法
function markListener(marker) {
marker.addEventListener(
"click",
function() {
this.openInfoWindow(new BMap.InfoWindow(
"<p style='font-size:14px;'>"
+ document
.getElementById("address_text").value
+ "<br/><br/>经度:" + lng
+ "<br/>纬度:" + lat + "</p>"));
});
//拖拽结束事件
marker.addEventListener("dragend", function(e) {
//获取覆盖物位置
marker.closeInfoWindow();
var o_Point_now = marker.getPosition();
lng = o_Point_now.lng;
lat = o_Point_now.lat;
});
}
markListener(marker)方法是对地图上的marker进行监听绑定。里面写了两个监听方法,分别是对点击和拖拽的监听。当点击按钮时会弹出该marker点的地址名称以及经纬度坐标(标准),而拖拽事件监听开始时会先取消点击时显示的具体信息(如果有的话),结束时则会获取新位置的经纬度,以便弹出的具体信息坐标的刷新。
这些都是非常简单的功能,下面做一个小优化加强用户体验!
4. 加强搜索,自动索引。
搜索时应给出自动提示,如你在搜"动物园"时,输入框input应该自动弹出联想下拉如"福州市动物园","厦门市动物园"等等。用户一点击便可以选中描述更加精准且定位会变得更加精确,下面给出代码:
function onMapShow () {
.........
var ac = new BMap.Autocomplete( //建立一个自动完成的对象
{
"input" : "address_text",
"location" : map
});
ac.setInputValue("福建省");
var myValue;
ac.addEventListener(
"onconfirm",
function(e) { //鼠标点击下拉列表后的事件
map.clearOverlays();//清空原来的标注
var _value = e.item.value;
myValue = _value.province + _value.city
+ _value.district + _value.street
+ _value.business;
document.getElementById("address_text").innerHTML = "onconfirm<br />index = "
+ e.item.index
+ "<br />myValue = "
+ myValue;
$scope.inAddress = myValue;
setPlace(myValue);
});
}
在初始化的代码中添加如下代码。new BMap.Autocomplete建立一个自动完成的对象,他的参数"input"绑定的是你input输入框的Id。该对象建立后你的input在发生输入事件时就会自动显示下拉列表。
ac.setInputValue("福建省")函数表示input默认显示值,传入一个str值即可,没什么好说的...
接下来绑定一个鼠标点击下拉列表事件。点击后主要完成2件事:1 将地址赋值给input输入框并取消下拉显示 ; 2 调用setPlace(myValue)方法查询具体位置并标记。
综上,一个简单易用的根据具体位置查询map坐标的功能就实现啦!
二 开发中可能出现的问题
一 出现can't find coord....错误。
这个错误是在
在调用上述
setPlace(myValue)方法的函数
myGeo.getPoint(myValue, function(point) {时出现的。主要原因可能是因为方法调用时机问题出现错误,比如在input输入发生变换时就调用,会导致无法查找到坐标从而报出该错误。解决办法是不要在输入未完成时就调用查询方法,最好在用户成功点击input输入框下拉提示后调用。
if (point) {
.....
} else {
....
}
}, "福州市");
二 input输入框下拉联想提示弹不出来
在刚做这个功能时,发现new BMap.Autocomplete了,下拉提示死活就是不出现。查了很多办法,发现是因为项目中baiduMap是建立在遮照层上的,导致下拉提示被挡住而非不显示。
解决办法:按F12仔细观察找到下拉提示div的id(baiduMap用Js的办法将这些div都写好了),
Css添加
.tangram-suggestion-main {
position: absolute;
z-index: 12345;
left: 542px;
top: 128px;
width: 300px;
}
tangram-suggestion-main是总的class,还有许多子Id,可以根据具体情况去针对性的修改!记住,所有发现下拉提示不能正常显示的情况,都先去找是否被遮挡了,99%能找到div和id并通过设置CSS解决问题!