本文实例为大家分享了OpenLayers3实现测量功能的具体代码,供大家参考,具体内容如下
1. 前言
测量功能实现面积的测量以及长度的测量。通过鼠标绘制区域以及长度来进行测量。OpenLayers 3 框架没有提供测量控件,但提供了相应的接口,需要需要基于几何对象的相应接口,结合图形绘制功能实现。
2. 实现思路
(1)新建一个网页,引用 openlayers 3 开发库、jQuery 库与 bootstrap 库,并参照前面显示地图的文章,加载 OSM 瓦片图层。
(2)在地图容器中,创建一个测量类型选择控件,进行选择距离测量与面积测量。
(3)编写代码实现测量功能。
3. 实现代码
html主要代码
<div id="map"> <div id="menu"> <label>测量类型:</label> <select id="type"> <option value="length">长度</option> <option value="area">面积</option> </select> <label class="checkbox"><input type="checkbox" id="geodesic">使用大地测量</label> </div> </div>
测量类型控件的样式设置:
#menu { float: left; position: absolute; bottom: 10px; left: 10px; z-index: 2000; } .checkbox { left: 20px; } /* 提示框的样式信息 */ .tooltip { position: relative; background: rgba(0, 0, 0, 0.5); border-radius: 4px; color: white; padding: 4px 8px; opacity: 0.7; white-space: nowrap; } .tooltip-measure { opacity: 1; font-weight: bold; } .tooltip-static { background-color: #ffcc33; color: black; border: 1px solid white; } .tooltip-measure::before, .tooltip-static::before { border-top: 6px solid rgb(0, 0, 0, 0.5); border-right: 6px solid transparent; border-left: 6px solid transparent; content: ""; position: absolute; bottom: -6px; margin-left: -7px; left: 50%; } .tooltip-static::before { border-top-color: #ffcc33; }
代码解析
上面的代码是结合 bootstrap库,使用冒泡提示框形式显示当前的测量结果,上面的样式分别设置了两种提示框的样式。
4. 实现测量功能的核心代码
(1)首先在地图上加载测量功能的绘制层,即矢量图层,就相当于,我们画画,需要纸来进行绘画,这里的矢量图层,相当于我们的纸。代码如下:
//加载测量的绘制矢量层 var source = new ol.source.Vector(); //图层数据源 var vector = new ol.layer.Vector({ source: source, style: new ol.style.Style({ //图层样式 fill: new ol.style.Fill({ color: 'rgba(255, 255, 255, 0.2)' //填充颜色 }), stroke: new ol.style.Stroke({ color: '#ffcc33', //边框颜色 width: 2 // 边框宽度 }), image: new ol.style.Circle({ radius: 7, fill: new ol.style.Fill({ color: '#ffcc33' }) }) }) }); map.addLayer(vector);
(2)通过 addInteraction 方法实现测量功能,首先加载交互绘图控件(ol.interaction.Draw),也就是我们前面所说的画画需要的笔,在测量时根据测量类型选择绘制线段或多边形,然后分别为交互绘图控件绑定 drawstart 与 drawend 事件。在绘图开始时实时计算当前当前绘制线的长度或多边形的面积,以提示框形式显示,绘图结束时重新创建一个测量提示框显示测量结果。通过 addInteraction 函数实现绘图测量的代码:
4.1 addInteraction 函数实现绘图测量的代码:
/** * 切换选择测量类型(长度或面积) * @param {Event} e Change event. */ typeSelect.onchange = function(e) { map.removeInteraction(draw); //移除绘制图形 addInteraction(); //添加绘图进行测量 }; addInteraction(); //调用加载绘制交互控件的方法,添加绘图进行测量
addInteraction()函数代码:
var geodesicCheckbox = document.getElementById('geodesic'); //测地学方式对象 var typeSelect = document.getElementById('type'); //测量类型对象 var draw; // global so we can remove it later /** * 加载交互绘制控件函数 */ function addInteraction() { var type = (typeSelect.value == 'area' "color: #800000">4.2 创建提示框的代码:/** *创建一个新的帮助提示框(tooltip) */ function createHelpTooltip() { if (helpTooltipElement) { helpTooltipElement.parentNode.removeChild(helpTooltipElement); } helpTooltipElement = document.createElement('div'); helpTooltipElement.className = 'tooltip hidden'; helpTooltip = new ol.Overlay({ element: helpTooltipElement, offset: [15, 0], positioning: 'center-left' }); map.addOverlay(helpTooltip); } /** *创建一个新的测量工具提示框(tooltip) */ function createMeasureTooltip() { if (measureTooltipElement) { measureTooltipElement.parentNode.removeChild(measureTooltipElement); } measureTooltipElement = document.createElement('div'); measureTooltipElement.className = 'tooltip tooltip-measure'; measureTooltip = new ol.Overlay({ element: measureTooltipElement, offset: [0, -15], positioning: 'bottom-center' }); map.addOverlay(measureTooltip); }代码解析
基于Openlayers 3 的 ol.Overlay 实现创建帮助信息提示框和测量工具提示框,分别通过 createHelpTooltip() 与 createMeasureTooltip() 创建帮助信息提示框和测量工具提示框, ol.Overlay j就是动态创建叠加层对象与其目标容器(div层),并将叠加层对象添加到地图容器中。
4.3 计算长度与面积的代码:
/** * 测量长度输出 * @param {ol.geom.LineString} line * @return {string} */ var formatLength = function(line) { var length; if (geodesicCheckbox.checked) { //若使用测地学方法测量 var coordinates = line.getCoordinates(); //解析线的坐标 length = 0; var sourceProj = map.getView().getProjection(); //地图数据源投影坐标系 //通过遍历坐标计算两点之前距离,进而得到整条线的长度 for (var i = 0, ii = coordinates.length - 1; i < ii; ++i) { var c1 = ol.proj.transform(coordinates[i], sourceProj, 'EPSG:4326'); var c2 = ol.proj.transform(coordinates[i + 1], sourceProj, 'EPSG:4326'); length += wgs84Sphere.haversineDistance(c1, c2); } } else { length = Math.round(line.getLength() * 100) / 100; //直接得到线的长度 } var output; if (length > 100) { output = (Math.round(length / 1000 * 100) / 100) + ' ' + 'km'; //换算成KM单位 } else { output = (Math.round(length * 100) / 100) + ' ' + 'm'; //m为单位 } return output; //返回线的长度 }; /** * 测量面积输出 * @param {ol.geom.Polygon} polygon * @return {string} */ var formatArea = function(polygon) { var area; if (geodesicCheckbox.checked) { //若使用测地学方法测量 var sourceProj = map.getView().getProjection(); //地图数据源投影坐标系 var geom = /** @type {ol.geom.Polygon} */ (polygon.clone().transform(sourceProj, 'EPSG:4326')); //将多边形要素坐标系投影为EPSG:4326 var coordinates = geom.getLinearRing(0).getCoordinates(); //解析多边形的坐标值 area = Math.abs(wgs84Sphere.geodesicArea(coordinates)); //获取面积 } else { area = polygon.getArea(); //直接获取多边形的面积 } var output; if (area > 10000) { output = (Math.round(area / 1000000 * 100) / 100) + ' ' + 'km<sup>2</sup>'; //换算成KM单位 } else { output = (Math.round(area * 100) / 100) + ' ' + 'm<sup>2</sup>'; //m为单位 } return output; //返回多边形的面积 }; addInteraction(); //调用加载绘制交互控件方法,添加绘图进行测量代码解析
上面代码通过 formatLength() 与 formatArea() 分别计算输出的长度值以及面积值。计算长度值或者面积值时可以通过两种方法进行计算,一种是使用测地学的方法基于数据的投影坐标系进行计算,另一种是调用几何对象或者多边形对象的方法直接获取值。
(3)开始画画了,分别使用map对象绑定鼠标移动事件(pointermove)和鼠标移除事件(mouseout)。
4.4 添加地图鼠标移动事件的代码:
/** * 当用户正在绘制多边形时的提示信息文本 * @type {string} */ var continuePolygonMsg = '单击继续绘制多边形'; /** * 当用户正在绘制线时的提示信息文本 * @type {string} */ var continueLineMsg = '单击继续绘制线'; /** * 鼠标移动事件处理函数 * @param {ol.MapBrowserEvent} evt */ var pointerMoveHandler = function(evt) { if (evt.dragging) { return; } /** @type {string} */ var helpMsg = '开始绘制'; //当前默认提示信息 //判断绘制几何类型设置相应的帮助提示信息 if (sketch) { var geom = (sketch.getGeometry()); if (geom instanceof ol.geom.Polygon) { helpMsg = continuePolygonMsg; //绘制多边形时提示相应内容 } else if (geom instanceof ol.geom.LineString) { helpMsg = continueLineMsg; //绘制线时提示相应内容 } } helpTooltipElement.innerHTML = helpMsg; //将提示信息设置到对话框中显示 helpTooltip.setPosition(evt.coordinate); //设置帮助提示框的位置 $(helpTooltipElement).removeClass('hidden'); //移除帮助提示框的隐藏样式进行显示 }; map.on('pointermove', pointerMoveHandler); //地图容器绑定鼠标移动事件,动态显示帮助提示框内容 //地图绑定鼠标移出事件,鼠标移出时为帮助提示框设置隐藏样式 $(map.getViewport()).on('mouseout', function() { $(helpTooltipElement).addClass('hidden'); });代码解析
鼠标移动事件(pointermove),在回调函数中,根据用户选择测量的类型,在弹窗中显示帮助提示信息,同时为地图容器绑定鼠标移除事件(mouseout),该事件发生后影藏提示框。
5. 实现效果
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。
免责声明:本站资源来自互联网收集,仅供用于学习和交流,请遵循相关法律法规,本站一切资源不代表本站立场,如有侵权、后门、不妥请联系本站删除!
更新日志
- 凤飞飞《我们的主题曲》飞跃制作[正版原抓WAV+CUE]
- 刘嘉亮《亮情歌2》[WAV+CUE][1G]
- 红馆40·谭咏麟《歌者恋歌浓情30年演唱会》3CD[低速原抓WAV+CUE][1.8G]
- 刘纬武《睡眠宝宝竖琴童谣 吉卜力工作室 白噪音安抚》[320K/MP3][193.25MB]
- 【轻音乐】曼托凡尼乐团《精选辑》2CD.1998[FLAC+CUE整轨]
- 邝美云《心中有爱》1989年香港DMIJP版1MTO东芝首版[WAV+CUE]
- 群星《情叹-发烧女声DSD》天籁女声发烧碟[WAV+CUE]
- 刘纬武《睡眠宝宝竖琴童谣 吉卜力工作室 白噪音安抚》[FLAC/分轨][748.03MB]
- 理想混蛋《Origin Sessions》[320K/MP3][37.47MB]
- 公馆青少年《我其实一点都不酷》[320K/MP3][78.78MB]
- 群星《情叹-发烧男声DSD》最值得珍藏的完美男声[WAV+CUE]
- 群星《国韵飘香·贵妃醉酒HQCD黑胶王》2CD[WAV]
- 卫兰《DAUGHTER》【低速原抓WAV+CUE】
- 公馆青少年《我其实一点都不酷》[FLAC/分轨][398.22MB]
- ZWEI《迟暮的花 (Explicit)》[320K/MP3][57.16MB]