主要目的
在百度地图上添加一个矩形选择框(后面我们就用选择刷这个称号来代替),最终是要实现选择刷与百度地图的交互操作,能在地图上拖动选择刷时,实时读取到刷内的地图图元数据
方法介绍
在实现选择刷的过程中,主要尝试了两种方法
方法一
用jquery ui中的选择框实现,引用draggable
npm install jquery-ui
- 直接引入
主要步骤
- 计算矩形框西北角相对于地图的位置
- 根据像素距离获取剩下三个角的坐标
- 根据矩形框的范围判断图元是否在矩形框内
实现流程
- 获取可视区域内的坐标:用getBounds()函数获取可视区域四个角的经纬度坐标,取西北角的坐标转换为可视区域坐标
- 使用drag(event,ui)事件获取选择刷相对地图的位置,当鼠标在拖放过程时触发
- 获取选择刷四个角的像素坐标,利用PixelToPoint()函数转换为经纬度坐标
- 根据Polygon()函数获取选择刷范围
- 引入GeoUtils,根据isPointInPolygon()函数判断点是不是在选择刷内
6.将刷内的点存放在数组中,此数组就是刷内的地图图元数据
方法二
直接引用百度地图API上的函数
实现步骤
- 将可拖拽点修改为可拖拽矩形框,拖拽结束后再响应事件
- 计算出x轴和y轴上的分辨率
- 根据分辨率和像素距离计算地图图元的经纬度
- 最后根据矩形框的范围判断图元是否在矩形框内
实现流程
- 将百度地图中可拖拽的点修改为可拖拽的矩形框
- 修改选择刷的样式布局
- 分别计算出选择刷左下角和右上角的地理经纬度坐标和像素坐标
- 计算分辨率:实际距离(经纬度坐标差)/像素值(像素坐标差)
- 根据经度方向和纬度方向的分辨率分别换算出拖拽结束后选择刷四个角的经纬度
- 最后再将地图上图元数据的经纬度跟选择刷经纬度对比,过滤出符合条件的图元数据即可
相关知识点
源代码var bounds = map.getBounds() 得到的是一堆aa、bb、cc之类的值,类似运行结果图:
矩形bounds放入坐标系中查看经纬度,一目了然:
Bounds四个角点经纬度值分别为:
- 左上角点LTPoint: ( bounds.Cf.lng, bounds.uf.lat) (bounds.cc, bounds.Zb)
- 右上角点RTPoint: (bounds.uf.lng, bounds.uf.lat) (bounds.$b, bounds.Zb)
- 左下角点LBPoint: (bounds.Cf.lng, bounds.Cf.lat) (bounds.cc, bounds.bc)
- 右下角点RBPoint: (bounds.uf,lng,bounds.Cf.lat) (bounds.$b,bounds.bc)
Bounds中含有获取两个角点坐标的实例方法:
-
左上角点LTPoint:(bounds.getSouthWest().lng,bounds.getNorthEast().lat)
-
右上角点RTPoint:bounds.getNorthEast()
-
左下角点LBPoint:bounds.getSouthWest()
-
右下角点RBPoint:(bounds.getNorthEast().lng,bounds.getSouthWest().lat)
获取矩形框四个角的坐标(交互)
根据drag(event,ui)事件,当鼠标在拖动过程中移动时触发:
源代码
$(“#draggable”).draggable({
Drag:function(event,ui){
Console.log(ui.position) //position是相对于父元素的位置
Console.log(ui.offset) //offset是相对于浏览器窗口}
})
根据构造函数BMap.Pixel(ui.position.top,ui.position.left)创建像素点对象实例,像素坐标的坐标原点为地图区域的左上角。
百度地图使用经纬度地理坐标(lng,lat)和像素坐标(x,y)两种,同时有两种坐标转换的方法:
经纬度装换为地理坐标的方法为:
PointToPixel(point:point) 返回值:Pixel 描述:经纬度坐标转换为像素坐标
地理坐标转换为经纬度的方法为:
pixelToPoint(pixel:Pixel) 返回值:point 描述:像素坐标转换为经纬度坐标
判断点是否在多边形内
引入BMapLib.GeoUtils静态类库
<script type="text/javascript" src="http://api.map.baidu.com/library/GeoUtils/1.2/src/GeoUtils_min.js"></script>
首先根据矩形框每个角的坐标确定多边形范围:Var ply = new BMap.Polygon(polyPoints)
;再用forEach函数循环地图上存放的所有点数,将点逐个与矩形框范围作比较,判断结果为true时将该点存放在数组中
直接判断是否在矩形框的边线内
分别用覆盖点的纬度与东北点纬度、西南点纬度比较,覆盖点的经度与西南角经度、东北角经度比较