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


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

 

  


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM