最近公司項目需求,要做一個百度地圖電子圍欄的功能,在網上查了一下資料,看了很多博客,大多數都寫的不是很詳細,我看的雲里霧裡的,最後終於集合所有的幾篇資料,自己做出了一個簡單的demo,下麵將過程記錄和分享一下,希望給予有需要同學一些幫助,我這個人說話比較啰嗦,所以寫的一定會很詳細的,哈哈!閑言少敘, ...
最近公司項目需求,要做一個百度地圖電子圍欄的功能,在網上查了一下資料,看了很多博客,大多數都寫的不是很詳細,我看的雲里霧裡的,最後終於集合所有的幾篇資料,自己做出了一個簡單的demo,下麵將過程記錄和分享一下,希望給予有需要同學一些幫助,我這個人說話比較啰嗦,所以寫的一定會很詳細的,哈哈!閑言少敘,開始了。
本篇內容實現的過程中將會解決如下幾個問題:
(1)實現百度地圖滑鼠繪製多邊形功能;
(2)實現根據給定的坐標繪製多邊形的功能;
(3)判斷某個坐標點是否在繪製的區域內;
(4)繪製的坐標點如何在資料庫中保存;
下麵按照實際需求一步一步來講解和實現:
-
1 實現多邊形繪製功能
1.1 從百度地圖官方庫下載滑鼠繪製多邊形功能demo
如何繪製一個多邊形,我在看網上博客的時候,大部分人都是直接貼一堆代碼上來,我最開始一直迷迷糊糊,以為是別人自己寫的代碼,所以得逐句去讀,很煩。後來乾脆直接去官方文檔上去找,就來果然找到了,原來這個功能,百度地圖官方有現成的實現,直接copy那部分代碼就可以用。
1>百度搜百度地圖開放平臺>開發文檔>web開發>JavaScript API >示例DEMO >滑鼠示例 > 滑鼠繪製點線面
進入這個地方就可以看到示例代碼了,如下:
可以把中間的代碼複製到自己的html頁面中,更改一下百度密鑰,打開代碼就能看到效果了。
需要註意的是:改代碼中用到的幾個js文件,不要忘了添加。
代碼如下:
<!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <meta name="viewport" content="initial-scale=1.0, user-scalable=no" /> <style type="text/css"> body, html{width: 100%;height: 100%;margin:0;font-family:"微軟雅黑";} #allmap {width: 100%; height:500px; overflow: hidden;} #result {width:100%;font-size:12px;} dl,dt,dd,ul,li{ margin:0; padding:0; list-style:none; } p{font-size:12px;} dt{ font-size:14px; font-family:"微軟雅黑"; font-weight:bold; border-bottom:1px dotted #000; padding:5px 0 5px 5px; margin:5px 0; } dd{ padding:5px 0 0 5px; } li{ line-height:28px; } </style> <script type="text/javascript" src="http://api.map.baidu.com/api?v=2.0&ak=您的密鑰"></script> <!--載入滑鼠繪製工具--> <script type="text/javascript" src="http://api.map.baidu.com/library/DrawingManager/1.4/src/DrawingManager_min.js"></script> <link rel="stylesheet" href="http://api.map.baidu.com/library/DrawingManager/1.4/src/DrawingManager_min.css" /> <!--載入檢索信息視窗--> <script type="text/javascript" src="http://api.map.baidu.com/library/SearchInfoWindow/1.4/src/SearchInfoWindow_min.js"></script> <link rel="stylesheet" href="http://api.map.baidu.com/library/SearchInfoWindow/1.4/src/SearchInfoWindow_min.css" /> <title>滑鼠繪製工具</title> </head> <body> <div id="allmap" style="overflow:hidden;zoom:1;position:relative;"> <div id="map" style="height:100%;-webkit-transition: all 0.5s ease-in-out;transition: all 0.5s ease-in-out;"></div> </div> <div id="result"> <input type="button" value="獲取繪製的覆蓋物個數" onclick="alert(overlays.length)"/> <input type="button" value="清除所有覆蓋物" onclick="clearAll()"/> </div> <script type="text/javascript"> // 百度地圖API功能 var map = new BMap.Map('map'); var poi = new BMap.Point(116.307852,40.057031); map.centerAndZoom(poi, 16); map.enableScrollWheelZoom(); var overlays = []; var overlaycomplete = function(e){ overlays.push(e.overlay); }; var styleOptions = { strokeColor:"red", //邊線顏色。 fillColor:"red", //填充顏色。當參數為空時,圓形將沒有填充效果。 strokeWeight: 3, //邊線的寬度,以像素為單位。 strokeOpacity: 0.8, //邊線透明度,取值範圍0 - 1。 fillOpacity: 0.6, //填充的透明度,取值範圍0 - 1。 strokeStyle: 'solid' //邊線的樣式,solid或dashed。 } //實例化滑鼠繪製工具 var drawingManager = new BMapLib.DrawingManager(map, { isOpen: false, //是否開啟繪製模式 enableDrawingTool: true, //是否顯示工具欄 drawingToolOptions: { anchor: BMAP_ANCHOR_TOP_RIGHT, //位置 offset: new BMap.Size(5, 5), //偏離值 }, circleOptions: styleOptions, //圓的樣式 polylineOptions: styleOptions, //線的樣式 polygonOptions: styleOptions, //多邊形的樣式 rectangleOptions: styleOptions //矩形的樣式 }); //添加滑鼠繪製工具監聽事件,用於獲取繪製結果 drawingManager.addEventListener('overlaycomplete', overlaycomplete); function clearAll() { for(var i = 0; i < overlays.length; i++){ map.removeOverlay(overlays[i]); } overlays.length = 0 } </script> </body> </html>
現象如下:
1.2 獲取繪製多邊形個個頂點的坐標
我們畫出多邊形的最終目的其實都是一樣的,想把這個區域的坐標信息保存到資料庫,然後下次能夠根據這個區域的坐標信息,把這個區域顯示在地圖上。那麼我們首先得知道這個區域的坐標是什麼,所以接下來說下如何獲取繪製的區域的坐標。
首先我們先看下代碼:
這裡的添加滑鼠繪製工具監聽時間,用於獲取繪製結果,實際上就是在這裡把多邊形的頂點放入overlays這個對象中,那麼我們如何獲取這些點的坐標呢,還是從官方文檔里找答案,看下麵:
1>在剛纔的JavaScript API界面側欄找到類參考項>覆蓋物類>PolyLine>getPath()
就是使用這個getPath()方法來獲取。
具體用法如下:
在上面代碼中新增按鈕 "獲取覆蓋物信息" ,然後添加一個getLayerInformation()的方法,點擊進行測試,代碼如下:
//html代碼 <input type="button" value="獲取繪製覆蓋物信息" onclick="getLayerInformation()"> //js代碼 function getLayerInformation(){ console.log(overlays[0].getPath()); }
overlays[0]表示第一個多邊形,然後我們繪製一個多邊形,點擊一下,看下控制台列印的結果:
這樣就可以獲取了多邊形頂點坐標了。
2.已知經緯度坐標,繪製多邊形
接下來看一下已知一些坐標點如何繪製一個多邊形,在代碼中增加一個按鈕 “繪製多邊形” ,然後定義一個有坐標信息的數組:
代碼如下:
<input type="button" value="繪製多邊形" onclick="drawPolygon()">
js代碼:
function drawPolygon(){ let point = [ { lng:"116.291611", lat:"40.061946" }, { lng:"116.291539", lat:"40.059295" }, { lng:"116.296102", lat:"40.057252" }, { lng:"116.303109", lat:"40.060179" } ]; let polArry = []; point.forEach(item => { let p = new BMap.Point(item.lng,item.lat); polArry.push(p); }); let polygon = new BMap.Polygon(polArry,styleOptions); map.addOverlay(polygon); }
結果如下:
點擊 “繪製多邊形” 按鈕:
3.判斷坐標點是否在某個區域內
在不瞭解之前,我一直以為需要一個演算法來判斷是否在多邊形內,後來發現,百度已經為我們寫好了這個演算法,我們直接使用即可。
判斷坐標點是否在某個區域,需要引入一個js文件,GeoUtils.js ,這個文件同樣在百度提供的資料中可以找到,具體見下圖:
在引入這個文件後,我們在頁面中添加兩個輸入框,輸入經緯度,在添加一個按鈕,來判斷該坐標是不是在區域內:
代碼如下:
html:
<div id="result"> <input type="button" value="獲取繪製覆蓋物個數" onclick="alert(overlays.length)"/> <input type="button" value="獲取繪製覆蓋物信息" onclick="getLayerInformation()"> <input type="button" value="繪製多邊形" onclick="drawPolygon()"> <input type="button" value="清除所有覆蓋物" onclick="clearAll()"/> <label for="">經度:</label> <input type="text" id="ILng"> <label for="">緯度:</label> <input type="text" id="ILat"> <input type="button" value="判斷點是否在多邊形內" onclick="IsInPolygon()"> </div>
js:
function IsInPolygon(){ let lng = $("#ILng").val(); let lat = $("#ILat").val(); let point = new BMap.Point(lng,lat); let marker = new BMap.Marker(point); map.addOverlay(marker); if(BMapLib.GeoUtils.isPointInPolygon(point,polygon)){console.log("在區域內");
}else{console.log("不在區域內");
}
}
核心的部分就是這個方法:
BMapLib.GeoUtils.isPointInPolygon(point,polygon)
第一個參數是輸入的坐標點,第二個參數是判斷的多邊形,這裡我用的多邊形是上一步繪製的多邊形,所以測試時,先點擊 “繪製多邊形” ,然後再輸入坐標,再點擊 “判斷是否在多邊形內”。
具體結果如下:
4.在資料庫中如何存儲這些坐標的點
這個問題,我只提供一個思路,因為不同的多邊形坐標個數不同,所以我們不能把每一個坐標點的經度和緯度當成一個單獨的欄位,我給出的做法是,採用字元串拼接的方式去處理,把每個坐標的經度用 一種特殊符號拼接起來當成一個欄位,緯度同理,存到資料庫中,然後顯示的時候,提前對這些坐標進行解析,得出實際坐標點,就可以了。
如下所示:
用 # 拼接
緯度:
lat1#lat2#lat3#lat4#lat5.....#latn
經度:
lng1#lng2#lng3#lng4#lng5......#lngn
字元串拼接的方法是:split,具體用法可自行百度。
好了,本篇內容就寫到這裡了,下麵給出代碼文件,和一個參考資料壓縮包(這個包很好,很有用);
網盤鏈接:
鏈接:https://pan.baidu.com/s/1OYSIMJ36U4f3LH3_i35dgQ 提取碼:xd98