百度地圖行政區域高亮顯示升級版
前幾天寫的部落格,使用百度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, {width: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>
採集點資訊是從資料庫讀取的,要演示的話必須要將資料來源