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