前几天写的博客,使用百度API实现了行政区域高亮显示,见下面的连接。
现在要进一步完善这个功能:
1、使用地理反解析经纬度,获得行政区域的值
2、二级行政区域(省下面的市)显示颜色加重
3、二级行政区域下添加分布点的标注
4、点击分布点弹出该标注的详细信息
关于第一点,我本来以为百度地图API的反解析接口是可以无限制使用的,后来才知道其使用配额是有限的
也就是说,每天调用接口的数量,以及每分钟调用的次数,都是有限的
未认证用户每天的调用次数最多6000次。因此要先申请认证,成为百度的认证用户才可以得到更多的配额。升级为认证用户是免费的,但需要3-5个工作日的审核。如果还是不够用可以通过收费渠道购买配额。
关于第二点,本来我的思路是,判断覆盖层是省还是市,如果是省设置为浅颜色的填充,如果是市则设置深颜色的填充。做之前感觉思路是没问题的,然而运行后的效果有时候正确,有时候只显示深色,有时候浅色。当我百思不得其解的时候,试着仅设置城市的填充色,结果省的填充色竟然自动变浅了。
关于第三点,在地图上添加标注是很简单的了,但有个问题是,如果在全国范围内添加全部采集点的分布,就显得太拥挤,能不能在放大到一定级别的时候,再显示这些采集点的标注呢?答案是肯定的。API提供了一个getZoom()方法,可以获取到当前map的缩放比例,再添加一个鼠标滑轮变化的事件,就可以根据缩放比例去显示和移除这些标记了。然而js本身并没有提供鼠标滑轮变化的事件,我们需要引用一个第三方的jquery库,jquery.mousewheel.js,这个可以在CDN找到的。其使用方法可以自己百度。
关于第四点,也是很简单的,只要注册一个点击事件,在弹出的div框中显示数据库中读取的数据就OK了。
在做这个效果时还遇到了其他各种各样的问题,最后终于完成了。下面看代码。
1 <!DOCTYPE html> 2 3 <html> 4 <head> 5 <meta name="viewport" content="width=device-width" /> 6 <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> 7 <title></title> 8 <script src="https://cdn.bootcss.com/jquery/1.11.2/jquery.js"></script> 9 <script src="/js/getrequest.js"></script> 10 <script src="/js/FormatDate.js"></script> 11 <script type="text/javascript" src="http://api.map.baidu.com/api?v=2.0&ak=TgvCNe2d0HTMpHGKPdcKrWHQvyrM01BY"></script> 12 <script type="text/javascript" src="http://api.map.baidu.com/library/AreaRestriction/1.2/src/AreaRestriction_min.js"></script> 13 <script src="https://cdn.bootcss.com/jquery-mousewheel/3.1.13/jquery.mousewheel.js"></script> 14 <style type="text/css"> 15 html, body { 16 margin: 0px; 17 padding: 0px; 18 height: 100%; 19 } 20 #container { 21 height: 100%; 22 } 23 .spinfo{ 24 line-height: 1em; 25 height: 1em; 26 } 27 </style> 28 </head> 29 30 <body> 31 <div id="container"></div> 32 33 <script type='text/javascript'> 34 var params = GetRequest(); 35 var map = new BMap.Map("container",{ minZoom : 5,maxZoom:20 }); // 创建地图实例 36 //设置个性化样式,不显示道路 37 map.setMapStyle({ 38 styleJson: [{ 39 "featureType": "road", 40 "elementType": "all", 41 "stylers": { 42 "color": "#ffffff", 43 "visibility": "off" 44 } 45 }] 46 }); 47 48 map.enableScrollWheelZoom(); //允许鼠标滑轮缩放 49 map.enableDragging(); //允许拖拽 50 map.disableDoubleClickZoom(); //禁用双击鼠标缩放 51 52 /* 53 =====从数据库获取照片数据===== 54 */ 55 $.get("../AjaxServer/SpeciesServ.ashx", { action: "getphotoinfobyspid", spid: params.spid }, function (data) { 56 var response = $.parseJSON(data); 57 // console.log(response); 58 //遍历照片数据,通过地理信息获取省市名称 59 for(var i=0;i<response.Table.length;i++){ 60 getAddressByLatLng(response.Table[i].Longitude,response.Table[i].Latitude,response.Table[i]); 61 } 62 }) 63 64 var arrCities = []; //用于存放城市名称 65 var arrProvices = []; //用于存放省名称 66 /* 67 =====通过经纬度得到省市名称,并获取行政区域边界===== 68 */ 69 function getAddressByLatLng(longitude,latitude,info){ 70 $.ajax({ 71 url:"http://api.map.baidu.com/geocoder/v2/?ak=TgvCNe2d0HTMpHGKPdcKrWHQvyrM01BY&callback=renderReverse&location="+latitude+","+longitude+"&output=json&pois=1", //由经纬度反地理编码得到地理位置信息 72 dataType:"jsonp", //JSONP跨域请求 73 success:function(data){ 74 var address = data.result.addressComponent; 75 //console.log(data) 76 //将省名称去重存入数组 77 if($.inArray(address.province,arrProvices)==-1 && address.province){ 78 arrProvices.push(address.province); 79 getBoundary(address.province); //描绘省边界 80 } 81 82 //将城市名称去重存入数组(注意有的城市名和省名一样,如上海市) 83 if($.inArray(address.city,arrCities)==-1 && $.inArray(address.city,arrProvices)==-1 && address.city){ 84 arrCities.push(address.city); 85 getBoundary(address.city); //描绘城市边界 86 var collectPoint = { point: new BMap.Point(longitude,latitude), info: info }; //采集点 87 arrCollectPoints.push(collectPoint); //添加至采集点标注数组 88 } 89 90 }, 91 error:function(XMLHttpRequest,status,e){ 92 console.log(status+","+XMLHttpRequest.status); 93 } 94 }); 95 } 96 /* 97 ======打开信息窗口,显示物种信息====== 98 */ 99 function openInfo(e,info) { 100 var p = e.target; 101 var point = new BMap.Point(p.getPosition().lng, p.getPosition().lat); 102 var CName = info.CName == undefined ? "" : info.CName; 103 var LName = info.LName == undefined ? "" : info.LName; 104 var AuthorColSN = info.AuthorColSN == undefined ? "" : info.AuthorColSN; 105 var Province = info.Province == undefined ? "" : info.Province; 106 var City = info.City == undefined ? "" : info.City; 107 var Place = info.Place == undefined ? "" : info.Place; 108 var Author = info.Author == undefined ? "" : info.Author; 109 var TakeTime = info.TakeTime == undefined ? "" : info.TakeTime; 110 var content = "<div class='spinfo'><span>" + CName + " ( " + LName + " )<span></div>"; 111 content += "<div><span>采集号:" + AuthorColSN + "<span></div>"; 112 content += "<div><span>采集地:" + Province + City + Place + "<span></div>"; 113 content += "<div><span>采集人:" + Author + "<span></div>"; 114 content += "<div><span>采集时间:" + FormatDate(TakeTime,"cdate") + "<span></div>"; 115 var infoWindow = new BMap.InfoWindow(content, {300,height:120,title:""}); // 创建信息窗口对象 116 map.openInfoWindow(infoWindow, point); //开启信息窗口 117 } 118 119 /* 120 =====鼠标滑轮滚动事件===== 121 */ 122 var arrCollectPoints = []; //保存采集点标注 123 var arrPointMarker = []; //保存采集点覆盖物 124 $("body").bind("mousewheel",function(){ 125 if(map.getZoom()>=7){ 126 for(var i=0;i<arrCollectPoints.length;i++){ 127 var point = arrCollectPoints[i].point; 128 var info = arrCollectPoints[i].info; 129 var marker = new BMap.Marker(point); 130 //在标注点上单击鼠标,弹出采集点的详细信息 131 marker.addEventListener("click", function (e) { openInfo(e,info); }, false); 132 arrPointMarker.push(marker); 133 map.addOverlay(marker); 134 } 135 } 136 else{ 137 for(var i=0;i<arrPointMarker.length;i++){ 138 map.removeOverlay(arrPointMarker[i]); 139 } 140 arrPointMarker.length = 0; 141 } 142 143 }) 144 145 146 /* 147 =====获取行政区域边界===== 148 */ 149 function getBoundary(location) { 150 addDistrict(location); 151 } 152 153 var blist = []; 154 var districtLoading = 0; 155 /* 156 =====添加行政区域===== 157 */ 158 function addDistrict(districtName) { 159 //使用计数器来控制加载过程 160 districtLoading++; 161 var bdary = new BMap.Boundary(); 162 bdary.get(districtName, function (rs) { //获取行政区域 163 var count = rs.boundaries.length; //行政区域的点有多少个 164 for (var i = 0; i < count; i++) { 165 blist.push({ points: rs.boundaries[i], name: districtName }); 166 }; 167 //加载完成区域点后计数器-1 168 districtLoading--; 169 if (districtLoading == 0) { 170 //全加载完成后画端点 171 drawBoundary("#3385FF"); 172 } 173 }); 174 } 175 176 /* 177 =====点击行政区域事件===== 178 */ 179 function click(evt) { 180 console.log(evt.target.name); 181 } 182 /* 183 =====绘制边界===== 184 */ 185 function drawBoundary(fillColor) { 186 //包含所有区域的点数组 187 var pointArray = []; 188 //循环添加各闭合区域 189 for (var i = 0; i < blist.length; i++) { 190 //添加多边形层并显示 191 var ply = new BMap.Polygon(blist[i].points, { 192 strokeWeight: 1, //边框宽度 193 trokeColor: "#014F99", //边框颜色 194 fillColor: fillColor //填充颜色 195 }); //建立多边形覆盖物 196 ply.name = blist[i].name; 197 ply.addEventListener("click", click); 198 map.addOverlay(ply); 199 200 //将点增加到视野范围内 201 var path = ply.getPath(); 202 pointArray = pointArray.concat(path); 203 } 204 map.setViewport(pointArray); //调整视野 205 } 206 207 </script> 208 </body> 209 </html>
采集点信息是从数据库读取的,要演示的话必须要将数据源做成JSON格式,我就不去做了。下面直接看运行效果: