百度map开发初步及常见问题
一 功能实现
添加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.根据输入的地址查找到坐标,并标记在地图上
//创建地址解析器实例 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; }); }
setPlace(myValue)方法是根据传入的myValue(实际地址,如福州市动物园)来获取map坐标,并由map.addOverlay(marker);方法来标记在地图上。 实际开发中可能会报出can't find coord错,这个后面再讲。
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) { if (point) { ..... } else { .... } }, "福州市");
时出现的。主要原因可能是因为方法调用时机问题出现错误,比如在input输入发生变换时就调用,会导致无法查找到坐标从而报出该错误。解决办法是不要在输入未完成时就调用查询方法,最好在用户成功点击input输入框下拉提示后调用。
二 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解决问题!