openlayers3 实现测距 面积

  1 <!DOCTYPE html>
  2 <html xmlns="http://www.w3.org/1999/xhtml">
  3 <head>
  4 <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
  5 <title></title>
  6 <link href="~/Scripts/OpenLayers-demo/css/ol.css" rel="stylesheet" />
  7 <script src="~/Scripts/OpenLayers-demo/build/ol.js"></script>
  8 <script src="~/Scripts/jquery-1.10.2.min.js"></script>
  9 <script src="~/Scripts/map/mapzoomtool.js" charset="gb2312"></script>
 10 <link href="~/Content/mapCtrlsstyles.css" rel="stylesheet" />
 11 <link href="~/Content/resources/KitchenSink-all.css" rel="stylesheet" />
 12 <script src="~/Scripts/ext-all.js"></script>
 13 <style type="text/css">
 14 #map {
 15 width: 100%;
 16 height: 100%;
 17 position: absolute;
 18 }
 19
 20 #menu {
 21 float: left;
 22 position: absolute;
 23 bottom: 10px;
 24 left: 10px;
 25 z-index: 2000;
 26 }
 27
 28 .checkbox {
 29 left: 20px;
 30 }
 31 /**
 32 * 提示框的样式信息
 33 */
 34 .tooltip {
 35 position: relative;
 36 background: rgba(0, 0, 0, 0.5);
 37 border-radius: 4px;
 38 color: white;
 39 padding: 4px 8px;
 40 opacity: 0.7;
 41 white-space: nowrap;
 42 }
 43
 44 .tooltip-measure {
 45 opacity: 1;
 46 font-weight: bold;
 47 }
 48
 49 .tooltip-static {
 50 background-color: #ffffff;
 51 color: black;
 52 border: 1px solid white;
 53 }
 54
 55 .tooltip-measure:before,
 56 .tooltip-static:before {
 57 border-top: 6px solid rgba(0, 0, 0, 0.5);
 58 border-right: 6px solid transparent;
 59 border-left: 6px solid transparent;
 60 content: "";
 61 position: absolute;
 62 bottom: -6px;
 63 margin-left: -7px;
 64 left: 50%;
 65 }
 66
 67 .tooltip-static:before {
 68 border-top-color: #ffffff;
 69 }
 70
 71 #scalebar {
 72 float: left;
 73 margin-bottom: 10px;
 74 }
 75 </style>
 76 <script type="text/javascript">
 77 $(function () {
 78 //初始化地图
 79 var map = new ol.Map({
 80 target: ‘map‘,
 81 layers: [
 82 new ol.layer.Tile({
 83 source:new ol.source.OSM()
 84 })
 85 ],
 86 view: new ol.View({
 87 center: new ol.proj.fromLonLat([114.4250, 23.0890]),
 88 zoom: 18,
 89 maxZoom: 20
 90 })
 91 });
 92
 93 //定义矢量数据源
 94 var source = new ol.source.Vector();
 95 //定义矢量图层
 96 var vector = new ol.layer.Vector({
 97 source: source,
 98 style: new ol.style.Style({
 99 fill: new ol.style.Fill({
100 color:‘rgba(255,255,255,0.2)‘
101 }),
102 stroke: new ol.style.Stroke({
103 color: ‘#e21e0a‘,
104 width:2
105 }),
106 image: new ol.style.Circle({
107 radius: 5,
108 fill: new ol.style.Fill({
109 color:‘#ffcc33‘
110 })
111 })
112 })
113 });
114 //将矢量图层添加到地图中
115 map.addLayer(vector);
116
117 //添加比例尺控件
118 var scaleLineControl = new ol.control.ScaleLine({
119 units: ‘metric‘,
120 target: ‘scalebar‘,
121 className: ‘ol-scale-line‘
122 });
123 map.addControl(scaleLineControl);
124
125
126 //创建一个WGS84球体对象
127 var wgs84Sphere = new ol.Sphere(6378137);
128 //创建一个当前要绘制的对象
129 var sketch = new ol.Feature();
130 //创建一个帮助提示框对象
131 var helpTooltipElement;
132 //创建一个帮助提示信息对象
133 var helpTooltip;
134 //创建一个测量提示框对象
135 var measureTooltipElement;
136 //创建一个测量提示信息对象
137 var measureTooltip;
138 //继续绘制多边形的提示信息
139 var continuePolygonMsg = ‘Click to continue drawing the polygon‘;
140 //继续绘制线段的提示信息
141 var continueLineMsg = ‘Click to continue drawing the line‘;
142
143 //鼠标移动触发的函数
144 var pointerMoveHandler = function (evt) {
145 //Indicates if the map is currently being dragged.
146 //Only set for POINTERDRAG and POINTERMOVE events. Default is false.
147 //如果是平移地图则直接结束
148 if (evt.dragging) {
149 return;
150 }
151 //帮助提示信息
152 var helpMsg = ‘Click to start drawing‘;
153
154 if (sketch) {
155 //Get the feature‘s default geometry.
156 //A feature may have any number of named geometries.
157 //获取绘图对象的几何要素
158 var geom = sketch.getGeometry();
159 //如果当前绘制的几何要素是多边形,则将绘制提示信息设置为多边形绘制提示信息
160 //如果当前绘制的几何要素是多线段,则将绘制提示信息设置为多线段绘制提示信息
161 if (geom instanceof ol.geom.Polygon) {
162 helpMsg = continuePolygonMsg;
163 } else if (geom instanceof ol.geom.LineString) {
164 helpMsg = continueLineMsg;
165 }
166 }
167 //设置帮助提示要素的内标签为帮助提示信息
168 helpTooltipElement.innerHTML = helpMsg;
169 //设置帮助提示信息的位置
170 //The coordinate in view projection corresponding to the original browser event.
171 helpTooltip.setPosition(evt.coordinate);
172 //移除帮助提示要素的隐藏样式
173 $(helpTooltipElement).removeClass(‘hidden‘);
174 };
175
176 //触发pointermove事件
177 map.on(‘pointermove‘, pointerMoveHandler);
178
179 //当鼠标移除地图视图的时为帮助提示要素添加隐藏样式
180 $(map.getViewport()).on(‘mouseout‘, function () {
181 $(helpTooltipElement).addClass(‘hidden‘);
182 });
183
184 //获取大地测量复选框
185 var geodesicCheckbox = document.getElementById(‘geodesic‘);
186 //获取类型
187 var typeSelect = document.getElementById(‘type‘);
188 //定义一个交互式绘图对象
189 var draw;
190
191 //添加交互式绘图对象的函数
192 function addInteraction() {
193 // 获取当前选择的绘制类型
194 var type = typeSelect.value == ‘area‘ ? ‘Polygon‘ : ‘LineString‘;
195 //创建一个交互式绘图对象
196 draw = new ol.interaction.Draw({
197 //绘制的数据源
198 source: source,
199 //绘制类型
200 type: type,
201 //样式
202 style: new ol.style.Style({
203 fill: new ol.style.Fill({
204 color:‘rgba(255,255,255,0.2)‘
205 }),
206 stroke: new ol.style.Stroke({
207 color: ‘rgba(0,0,0,0.5)‘,
208 lineDash: [10, 10],
209 width:2
210 }),
211 image: new ol.style.Circle({
212 radius: 5,
213 stroke: new ol.style.Stroke({
214 color:‘rgba(0,0,0,0.7)‘
215 }),
216 fill: new ol.style.Fill({
217 color: ‘rgba(255,255,255,0.2)‘
218 })
219 })
220 })
221 });
222 //将交互绘图对象添加到地图中
223 map.addInteraction(draw);
224
225 //创建测量提示框
226 createMeasureTooltip();
227 //创建帮助提示框
228 createHelpTooltip();
229
230 //定义一个事件监听
231 var listener;
232 //定义一个控制鼠标点击次数的变量
233 var count = 0;
234 //绘制开始事件
235 draw.on(‘drawstart‘, function (evt) {
236 //The feature being drawn.
237 sketch = evt.feature;
238 //提示框的坐标
239 var tooltipCoord = evt.coordinate;
240 //监听几何要素的change事件
241 //Increases the revision counter and dispatches a ‘change‘ event.
242
243 listener = sketch.getGeometry().on(‘change‘, function (evt) {
244 //The event target.
245 //获取绘制的几何对象
246 var geom = evt.target;
247 //定义一个输出对象,用于记录面积和长度
248 var output;
249 if (geom instanceof ol.geom.Polygon) {
250 map.removeEventListener(‘singleclick‘);
251 map.removeEventListener(‘dblclick‘);
252 //输出多边形的面积
253 output = formatArea(geom);
254 //Return an interior point of the polygon.
255 //获取多变形内部点的坐标
256 tooltipCoord = geom.getInteriorPoint().getCoordinates();
257 } else if (geom instanceof ol.geom.LineString) {
258 //输出多线段的长度
259 output = formatLength(geom);
260 //Return the last coordinate of the geometry.
261 //获取多线段的最后一个点的坐标
262 tooltipCoord = geom.getLastCoordinate();
263 }
264
265 //设置测量提示框的内标签为最终输出结果
266 measureTooltipElement.innerHTML = output;
267 //设置测量提示信息的位置坐标
268 measureTooltip.setPosition(tooltipCoord);
269 });
270
271 //地图单击事件
272 map.on(‘singleclick‘, function (evt) {
273 //设置测量提示信息的位置坐标,用来确定鼠标点击后测量提示框的位置
274 measureTooltip.setPosition(evt.coordinate);
275 //如果是第一次点击,则设置测量提示框的文本内容为起点
276 if (count == 0) {
277 measureTooltipElement.innerHTML = "起点";
278 }
279 //根据鼠标点击位置生成一个点
280 var point = new ol.geom.Point(evt.coordinate);
281 //将该点要素添加到矢量数据源中
282 source.addFeature(new ol.Feature(point));
283 //更改测量提示框的样式,使测量提示框可见
284 measureTooltipElement.className = ‘tooltip tooltip-static‘;
285 //创建测量提示框
286 createMeasureTooltip();
287 //点击次数增加
288 count++;
289 });
290
291 //地图双击事件
292 map.on(‘dblclick‘, function (evt) {
293 //根据
294 var point = new ol.geom.Point(evt.coordinate);
295 source.addFeature(new ol.Feature(point));
296 });
297 }, this);
298 //绘制结束事件
299 draw.on(‘drawend‘, function (evt) {
300 count = 0;
301 //设置测量提示框的样式
302 measureTooltipElement.className = ‘tooltip tooltip-static‘;
303 //Set the offset for this overlay.
304 //设置偏移量
305 measureTooltip.setOffset([0, -7]);
306 //清空绘制要素
307 sketch = null;
308 //清空测量提示要素
309 measureTooltipElement = null;
310 //创建测量提示框
311 createMeasureTooltip();
312 //Removes an event listener using the key returned by on() or once().
313 //移除事件监听
314 ol.Observable.unByKey(listener);
315 //移除地图单击事件
316 map.removeEventListener(‘singleclick‘);
317 }, this);
318 }
319 //创建帮助提示框
320 function createHelpTooltip() {
321 //如果已经存在帮助提示框则移除
322 if (helpTooltipElement) {
323 helpTooltipElement.parentNode.removeChild(helpTooltipElement);
324 }
325 //创建帮助提示要素的div
326 helpTooltipElement = document.createElement(‘div‘);
327 //设置帮助提示要素的样式
328 helpTooltipElement.className = ‘tooltip hidden‘;
329 //创建一个帮助提示的覆盖标注
330 helpTooltip = new ol.Overlay({
331 element: helpTooltipElement,
332 offset: [15, 0],
333 positioning:‘center-left‘
334 });
335 //将帮助提示的覆盖标注添加到地图中
336 map.addOverlay(helpTooltip);
337 }
338 //创建测量提示框
339 function createMeasureTooltip() {
340 //创建测量提示框的div
341 measureTooltipElement = document.createElement(‘div‘);
342 measureTooltipElement.setAttribute(‘id‘,‘lengthLabel‘);
343 //设置测量提示要素的样式
344 measureTooltipElement.className = ‘tooltip tooltip-measure‘;
345 //创建一个测量提示的覆盖标注
346 measureTooltip = new ol.Overlay({
347 element: measureTooltipElement,
348 offset: [0, -15],
349 positioning:‘bottom-center‘
350 });
351 //将测量提示的覆盖标注添加到地图中
352 map.addOverlay(measureTooltip);
353 }
354 //测量类型发生改变时触发事件
355 typeSelect.onchange = function () {
356 //移除之前的绘制对象
357 map.removeInteraction(draw);
358 //重新进行绘制
359 addInteraction();
360 };
361
362 //格式化测量长度
363 var formatLength = function (line) {
364 //定义长度变量
365 var length;
366 //如果大地测量复选框被勾选,则计算球面距离
367 if (geodesicCheckbox.checked) {
368 //Return the coordinates of the linestring.
369 //获取坐标串
370 var coordinates = line.getCoordinates();
371 //初始长度为0
372 length = 0;
373 //获取源数据的坐标系
374 var sourceProj = map.getView().getProjection();
375 //进行点的坐标转换
376 for (var i = 0; i < coordinates.length - 1; i++) {
377 //第一个点
378 var c1 = ol.proj.transform(coordinates[i], sourceProj, ‘EPSG:4326‘);
379 //第二个点
380 var c2 = ol.proj.transform(coordinates[i + 1], sourceProj, ‘EPSG:4326‘);
381 //获取转换后的球面距离
382 //Returns the distance from c1 to c2 using the haversine formula.
383 length += wgs84Sphere.haversineDistance(c1,c2);
384 }
385 } else {
386 //Return the length of the linestring on projected plane.
387 //计算平面距离
388 length = Math.round(line.getLength() * 100) / 100;
389 }
390 //定义输出变量
391 var output;
392 //如果长度大于1000,则使用km单位,否则使用m单位
393 if (length > 1000) {
394 output = (Math.round(length / 1000 * 100) / 100) + ‘ ‘ + ‘km‘; //换算成KM单位
395 } else {
396 output = (Math.round(length * 100) / 100) + ‘ ‘ + ‘m‘; //m为单位
397 }
398 return output;
399 };
400
401 //格式化测量面积
402 var formatArea = function (polygon) {
403 //定义面积变量
404 var area;
405 //如果大地测量复选框被勾选,则计算球面面积
406 if (geodesicCheckbox.checked) {
407 //获取初始坐标系
408 var sourceProj = map.getView().getProjection();
409 //Make a complete copy of the geometry.
410 //Transform each coordinate of the geometry from one coordinate reference system to another.
411 //The geometry is modified in place. For example, a line will be transformed to a line and a circle to a circle.
412 //If you do not want the geometry modified in place, first clone() it and then use this function on the clone.
413 //克隆该几何对象然后转换坐标系
414 var geom = polygon.clone().transform(sourceProj, ‘EPSG:4326‘);
415 //Return the Nth linear ring of the polygon geometry.
416 //Return null if the given index is out of range.
417 //The exterior linear ring is available at index 0 and the interior rings at index 1 and beyond.
418 //获取多边形的坐标系
419 var coordinates = geom.getLinearRing(0).getCoordinates();
420 //Returns the geodesic area for a list of coordinates.
421 //获取球面面积
422 area = Math.abs(wgs84Sphere.geodesicArea(coordinates));
423 } else {
424 //获取平面面积
425 area = polygon.getArea();
426 }
427 //定义输出变量
428 var output;
429 //当面积大于10000时,转换为平方千米,否则为平方米
430 if (area > 10000) {
431 output = (Math.round(area/1000000*100)/100) + ‘ ‘ + ‘km<sup>2</sup>‘;
432 } else {
433 output = (Math.round(area*100)/100) + ‘ ‘ + ‘m<sup>2</sup>‘;
434 }
435 return output;
436 };
437 //添加交互绘图对象
438 addInteraction();
439 });
440 </script>
441 </head>
442 <body>
443 <div id="map">
444 <div id="menu">
445 <label>测量类型选择</label>
446 <select id="type">
447 <option value="length">长度</option>
448 <option value="area">面积</option>
449 </select>
450 <label class="checkbox"><input type="checkbox" id="geodesic" />使用大地测量</label>
451 </div>
452 </div>
453 <div id="scalebar"></div>
454 </body>
455 </html>
时间: 2024-11-05 00:18:16

openlayers3 实现测距 面积的相关文章

【开源】电子围栏-测距离-测面积-拉框放大-实时路况-逆地理编码的实现

最近项目上涉及到地图,考虑到精度等问题,最终选择了51ditu.要实现电子围栏等等功能,经过几天努力,大致有了个雏形,由于是第一次接触HTML和JavaScript编程,三天下来脑袋大了不少,碰到了一些问题,暂时还在挣扎当中,现在我将雏形工程发布出来,目的在于向大家学习,希望得到各位的指点和教导,以期我的工程能够日益完美. 一.相关文件说明:         (1) 工程文件我已经放到了http://download.csdn.net/detail/zhangyuehua123/3704087上

百度地图API开发一——仿照现有测距实现测量面积功能

  最近做了一个百度地图API的开发项目,里面有测量距离和测量面积的功能需求.测量距离百度给出了封装好的javascript包--BMapLib.DistanceTool,效果如下: 这个效果体验很好:测量面积也给出了开源javascript包--BMapLib.DrawingManger,如下: 但这个效果和体验就很差了.客户希望测量面积能实现和测距一样的效果体验(鼠标在移动绘制过程中实时显示绘制面积,且样式效果要一样),经过一番折腾,修改了百度测距的javascript包,终于搞定.先上效果

利用线结构光进行三维重构(测距)

利用线结构光进行三维重构(测距) 通过线激光器扫描物体,同时用摄像机对其拍照得到带有结构光的图片,提取结构光上的点的三维坐标,激光器扫描整个物体就可求出所有点的三维坐标实现物体表面的三维重构,即可测量物体表面任意两点距离. 准备知识: 四个坐标系的转换 世界坐标系--摄像机坐标系 将摄像机光心定位摄像机坐标原点Oc,摄像机的光轴定位摄像机坐标系的Zc轴,Xc轴,Yc轴分别与图像坐标系的x轴y轴平行. R为3阶正交单位矩阵,t为平移向量,均为相机外参数 物理坐标系--像素坐标系 图像的x,y轴分别

利用Python测量滴水湖的水面面积

美丽的滴水湖 ??美丽的滴水湖坐落在上海的东南角,濒临东海,风景秀丽,安静舒适,是旅游.恋爱的绝佳去处.笔者有幸去过一回,对那儿的风土人情留下了深刻的印象,如果有机会,笔者还会多去几次! ??滴水湖是个神奇的地方,神奇之处在于它的外形是一个正圆形,这源于城市规划者对临港新城的美好设想.每次路过这个美丽的湖时,笔者总会想:这个湖到底多大呢? ??本文将会谈到如何如何得到滴水湖的水面面积.是手动测量?是地质勘测?No,No,No,我们还是借用我们熟悉的工具,那就是Python!什么,Python还能

单目相机测距

单目测距的小项目,大概需要就是用单目相机,对一个特定的目标进行识别并测算相机与该目标的距离.所以便去网上找了一堆教程,这里给大家总结一下,希望给小白们一个参考. 首先是基本需求了 opencv自然要会的,这咱就不多说了,会一点就行 需要一个摄像头,我用的是一个畸变很大的鱼眼免驱动摄像头,大家用电脑上的那个自带摄像头也可以的,就是不方便. 需要MATLAB进行相机标定 其实上面都是废话,下面进入正题吧. 网上的方法大概有两种,这里主要介绍一个我身边的大哥们都称做PnP问题的一个方法,但会另外简单介

要求用户输入宽和高,显示出长方形的面积。

import java.util.Scanner; /** * @author 蓝色以太 * 要求用户输入宽和高,显示出长方形的面积. */ public class Area { public static void main(String[] args) { Scanner sc=new Scanner(System.in); System.out.println("请输入长度:"); double length=sc.nextDouble(); System.out.printl

输入一个半径求圆的面积和周长

Scanner sc = new Scanner(System.in); System.out.print("请输入半径"); int r =sc.nextInt(); final double π = 3.14; System.out.print("面积为:"+(π*r*r)); System.out.print("周长为:"+(π*r*2));

【POJ 1408】 Fishnet (叉积求面积)

[POJ 1408] Fishnet (叉积求面积) 一个1*1㎡的池塘 有2*n条线代表渔网 问这些网中围出来的最大面积 一个有效面积是相邻两行和相邻两列中间夹的四边形 Input为n 后面跟着四行 每行n个浮点数 每一行分别代表a,b,c,d 如图 并且保证a(i) > a(i-1) b(i) > b(i-1) c(i) > c(i-1) d(i) > d(i-1) n(n <= 30)*2+4(四个岸)条边 枚举点数就行 相邻的四个四个点枚举 找出围出的最大面积 找点用

codeforces1c给出三点求面积

题意:有一个正n边形的斗兽场,现存有3根柱子,柱子位于正n边形的任意3个节点上.求出正n边形的最小面积. 1 #include <iostream> 2 #include <stdio.h> 3 #include <stdlib.h> 4 #include <math.h>//采用三角函数大部分使用弧度 5 #include <utility> 6 #include <algorithm> 7 using namespace std;