在OpenLayers中实现测距功能有两种测距方式,一种是测平面距离,另一种是测球面距离,这里采用大地测量的方式进行测距功能的实现。
首先设置相关的样式,因为在执行测距功能代码的时候,有时要根据不同的状态切换成不同的样式,所以这里给出用到的详细样式。其中对于样式具体的含义,有兴趣的读者可以自行查阅资料。
在body标签中添加一个用来选择测量类型的选择框,并在下方定义地图容器div,使用div为“scalrber”的div存放提示信息。
以下为script代码(代码中省略了map的创建和矢量数据源的创建,请读者自行补充),首先创建和声明需要用到的对象,具体含义已经在注释中给出:
声明鼠标移动触发的函数,传入当前的事件,根据不同的事件类型,进行不同的操作:
添加交互式绘图对象的函数,首先根据选择框获取当前选择的绘制类型(有多边形和线类型两种),创建交互式绘制对象进行图形的绘制,调用相关函数创建绘图所需的对象,然后添加绘图开始监听事件、地图单击监听事件、地图双击监听事件、绘图结束监听事件。
(www.xing528.com)
分别定义创建帮助提示框和创建测量提示框的函数,如果已存在提示框,则先将提示框移除,然后创建新的提示框,并进行绑定。
分别定义测量类型发生变化时的监听函数和格式化测量长度(或面积)的函数。测量类型发生改变时触发事件,在测量类型发生变化时,先移除绘制对象,然后调用绘制函数进行重新绘制; 格式化测量长度(或面积)的函数将绘制出的线(或面)要素作为参数传入函数,然后转换为球面距离(或面积),最后将数据格式化为对应的单位后返回对应的值。
【说明】上面的代码中,首先通过下拉选择框,选择要测量的类型(这里是线和多边形),以便确认是测量距离还是面积。在选择完类型后,在地图上进行图形的绘制,测线时每次进行单击,都会测量出相应的距离,双击结束。测面积同理。
代码中定义了两个draw.on()函数。其中,第一个函数的第一个参数与前面用到的不同,通过参数名“drawstart”也可以知道,是每当开始绘制时会触发。第二个参数定义了触发事件函数,主要用于监听几何要素的改变事件,记录实时测量的面积和长度的值,并在测量提示框显示结果。第二个函数则在第一个参数传入了“drawend”,也就是绘制结束的事件,将绘制要素清空,重置一些变量,以便用户下次测量时能够顺利使用而不发生错误。
其中ol.Overlay可以在地图中添加各种html要素,上面的例子就是创建一个帮助提示的覆盖标注,我们可以看到它的element参数是定义的div元素。我们可以通过overlay.setPosition([经度,纬度])设置弹出的经纬度位置,如果想要不再显示弹框,只需设置overlay.setPosition(undefined)即可。用户同样可以在Overlay中放置一些和地图位置相关的其他元素,如点标记、图片等。由于它可以和传统的html技术相结合,所以可以方便地设置样式,改变其他属性等。
代码中的ol.Sphere是一个地形对象,可提供计算精准长度和面积。其实在平面上的地图是把地球这个球体通过各种投影方式投影到平面上的,通过实际地理形状计算,需要把坐标转换为对应坐标系的经纬度,调用geom的transform(coordinate,projection1,projection2),把projection1下的坐标转化为projection2的坐标,例如,把墨卡托投影系EPSG:3857(大地坐标)下的坐标转换为EPSG:4236投影系下的坐标(经纬度)。
使用Sphere对象的haversineDistance函数计算两个坐标之间的距离。在formatLength函数返回格式化后的测量长度,其使用了ol.proj.transform函数将坐标系转换成EPSG:4236,再使用wgs84Sphere.haversineDistance(wgs84Sphere就是一个ol.Sphere实例)计算两点间的球面距离,然后定义输出变量,格式化输出的单位。formatArea函数返回格式化后的测量面积,同样是先使用polygon.clone().transform()函数转换坐标系,然后使用wgs84Sphere.geodesicArea()函数计算球面面积,传入多边形的坐标系数组,它会计算出对应数值。现在还不是最终的面积值,因为有时会算出来负值,所以要用Math.abs()函数计算出绝对值,最后定义输出变量。
测量后的结果如图6-17所示。
图6-17 测量结果
免责声明:以上内容源自网络,版权归原作者所有,如有侵犯您的原创版权请告知,我们将尽快删除相关内容。