1. 程式人生 > 實用技巧 >百度地圖電子圍欄功能的實現

百度地圖電子圍欄功能的實現

最近公司專案需求,要做一個百度地圖電子圍欄的功能,在網上查了一下資料,看了很多部落格,大多數都寫的不是很詳細,我看的雲裡霧裡的,最後終於集合所有的幾篇資料,自己做出了一個簡單的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