百度地图电子围栏功能的实现

       最近公司项目需求,要做一个百度地图电子围栏的功能,在网上查了一下资料,看了很多博客,大多数都写的不是很详细,我看的云里雾里的,最后终于集合所有的几篇资料,自己做出了一个简单的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 

 

  

posted @ 2019-04-16 17:00  CherishTheYouth  阅读(29116)  评论(11编辑  收藏  举报