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. //创建一个WGS84球体对象
  126. var wgs84Sphere = new ol.Sphere(6378137);
  127. //创建一个当前要绘制的对象
  128. var sketch = new ol.Feature();
  129. //创建一个帮助提示框对象
  130. var helpTooltipElement;
  131. //创建一个帮助提示信息对象
  132. var helpTooltip;
  133. //创建一个测量提示框对象
  134. var measureTooltipElement;
  135. //创建一个测量提示信息对象
  136. var measureTooltip;
  137. //继续绘制多边形的提示信息
  138. var continuePolygonMsg = 'Click to continue drawing the polygon';
  139. //继续绘制线段的提示信息
  140. var continueLineMsg = 'Click to continue drawing the line';
  141.  
  142. //鼠标移动触发的函数
  143. var pointerMoveHandler = function (evt) {
  144. //Indicates if the map is currently being dragged.
  145. //Only set for POINTERDRAG and POINTERMOVE events. Default is false.
  146. //如果是平移地图则直接结束
  147. if (evt.dragging) {
  148. return;
  149. }
  150. //帮助提示信息
  151. var helpMsg = 'Click to start drawing';
  152.  
  153. if (sketch) {
  154. //Get the feature's default geometry.
  155. //A feature may have any number of named geometries.
  156. //获取绘图对象的几何要素
  157. var geom = sketch.getGeometry();
  158. //如果当前绘制的几何要素是多边形,则将绘制提示信息设置为多边形绘制提示信息
  159. //如果当前绘制的几何要素是多线段,则将绘制提示信息设置为多线段绘制提示信息
  160. if (geom instanceof ol.geom.Polygon) {
  161. helpMsg = continuePolygonMsg;
  162. } else if (geom instanceof ol.geom.LineString) {
  163. helpMsg = continueLineMsg;
  164. }
  165. }
  166. //设置帮助提示要素的内标签为帮助提示信息
  167. helpTooltipElement.innerHTML = helpMsg;
  168. //设置帮助提示信息的位置
  169. //The coordinate in view projection corresponding to the original browser event.
  170. helpTooltip.setPosition(evt.coordinate);
  171. //移除帮助提示要素的隐藏样式
  172. $(helpTooltipElement).removeClass('hidden');
  173. };
  174.  
  175. //触发pointermove事件
  176. map.on('pointermove', pointerMoveHandler);
  177.  
  178. //当鼠标移除地图视图的时为帮助提示要素添加隐藏样式
  179. $(map.getViewport()).on('mouseout', function () {
  180. $(helpTooltipElement).addClass('hidden');
  181. });
  182.  
  183. //获取大地测量复选框
  184. var geodesicCheckbox = document.getElementById('geodesic');
  185. //获取类型
  186. var typeSelect = document.getElementById('type');
  187. //定义一个交互式绘图对象
  188. var draw;
  189.  
  190. //添加交互式绘图对象的函数
  191. function addInteraction() {
  192. // 获取当前选择的绘制类型
  193. var type = typeSelect.value == 'area' ? 'Polygon' : 'LineString';
  194. //创建一个交互式绘图对象
  195. draw = new ol.interaction.Draw({
  196. //绘制的数据源
  197. source: source,
  198. //绘制类型
  199. type: type,
  200. //样式
  201. style: new ol.style.Style({
  202. fill: new ol.style.Fill({
  203. color:'rgba(255,255,255,0.2)'
  204. }),
  205. stroke: new ol.style.Stroke({
  206. color: 'rgba(0,0,0,0.5)',
  207. lineDash: [10, 10],
  208. width:2
  209. }),
  210. image: new ol.style.Circle({
  211. radius: 5,
  212. stroke: new ol.style.Stroke({
  213. color:'rgba(0,0,0,0.7)'
  214. }),
  215. fill: new ol.style.Fill({
  216. color: 'rgba(255,255,255,0.2)'
  217. })
  218. })
  219. })
  220. });
  221. //将交互绘图对象添加到地图中
  222. map.addInteraction(draw);
  223.  
  224. //创建测量提示框
  225. createMeasureTooltip();
  226. //创建帮助提示框
  227. createHelpTooltip();
  228.  
  229. //定义一个事件监听
  230. var listener;
  231. //定义一个控制鼠标点击次数的变量
  232. var count = 0;
  233. //绘制开始事件
  234. draw.on('drawstart', function (evt) {
  235. //The feature being drawn.
  236. sketch = evt.feature;
  237. //提示框的坐标
  238. var tooltipCoord = evt.coordinate;
  239. //监听几何要素的change事件
  240. //Increases the revision counter and dispatches a 'change' event.
  241.  
  242. listener = sketch.getGeometry().on('change', function (evt) {
  243. //The event target.
  244. //获取绘制的几何对象
  245. var geom = evt.target;
  246. //定义一个输出对象,用于记录面积和长度
  247. var output;
  248. if (geom instanceof ol.geom.Polygon) {
  249. map.removeEventListener('singleclick');
  250. map.removeEventListener('dblclick');
  251. //输出多边形的面积
  252. output = formatArea(geom);
  253. //Return an interior point of the polygon.
  254. //获取多变形内部点的坐标
  255. tooltipCoord = geom.getInteriorPoint().getCoordinates();
  256. } else if (geom instanceof ol.geom.LineString) {
  257. //输出多线段的长度
  258. output = formatLength(geom);
  259. //Return the last coordinate of the geometry.
  260. //获取多线段的最后一个点的坐标
  261. tooltipCoord = geom.getLastCoordinate();
  262. }
  263.  
  264. //设置测量提示框的内标签为最终输出结果
  265. measureTooltipElement.innerHTML = output;
  266. //设置测量提示信息的位置坐标
  267. measureTooltip.setPosition(tooltipCoord);
  268. });
  269.  
  270. //地图单击事件
  271. map.on('singleclick', function (evt) {
  272. //设置测量提示信息的位置坐标,用来确定鼠标点击后测量提示框的位置
  273. measureTooltip.setPosition(evt.coordinate);
  274. //如果是第一次点击,则设置测量提示框的文本内容为起点
  275. if (count == 0) {
  276. measureTooltipElement.innerHTML = "起点";
  277. }
  278. //根据鼠标点击位置生成一个点
  279. var point = new ol.geom.Point(evt.coordinate);
  280. //将该点要素添加到矢量数据源中
  281. source.addFeature(new ol.Feature(point));
  282. //更改测量提示框的样式,使测量提示框可见
  283. measureTooltipElement.className = 'tooltip tooltip-static';
  284. //创建测量提示框
  285. createMeasureTooltip();
  286. //点击次数增加
  287. count++;
  288. });
  289.  
  290. //地图双击事件
  291. map.on('dblclick', function (evt) {
  292. //根据
  293. var point = new ol.geom.Point(evt.coordinate);
  294. source.addFeature(new ol.Feature(point));
  295. });
  296. }, this);
  297. //绘制结束事件
  298. draw.on('drawend', function (evt) {
  299. count = 0;
  300. //设置测量提示框的样式
  301. measureTooltipElement.className = 'tooltip tooltip-static';
  302. //Set the offset for this overlay.
  303. //设置偏移量
  304. measureTooltip.setOffset([0, -7]);
  305. //清空绘制要素
  306. sketch = null;
  307. //清空测量提示要素
  308. measureTooltipElement = null;
  309. //创建测量提示框
  310. createMeasureTooltip();
  311. //Removes an event listener using the key returned by on() or once().
  312. //移除事件监听
  313. ol.Observable.unByKey(listener);
  314. //移除地图单击事件
  315. map.removeEventListener('singleclick');
  316. }, this);
  317. }
  318. //创建帮助提示框
  319. function createHelpTooltip() {
  320. //如果已经存在帮助提示框则移除
  321. if (helpTooltipElement) {
  322. helpTooltipElement.parentNode.removeChild(helpTooltipElement);
  323. }
  324. //创建帮助提示要素的div
  325. helpTooltipElement = document.createElement('div');
  326. //设置帮助提示要素的样式
  327. helpTooltipElement.className = 'tooltip hidden';
  328. //创建一个帮助提示的覆盖标注
  329. helpTooltip = new ol.Overlay({
  330. element: helpTooltipElement,
  331. offset: [15, 0],
  332. positioning:'center-left'
  333. });
  334. //将帮助提示的覆盖标注添加到地图中
  335. map.addOverlay(helpTooltip);
  336. }
  337. //创建测量提示框
  338. function createMeasureTooltip() {
  339. //创建测量提示框的div
  340. measureTooltipElement = document.createElement('div');
  341. measureTooltipElement.setAttribute('id','lengthLabel');
  342. //设置测量提示要素的样式
  343. measureTooltipElement.className = 'tooltip tooltip-measure';
  344. //创建一个测量提示的覆盖标注
  345. measureTooltip = new ol.Overlay({
  346. element: measureTooltipElement,
  347. offset: [0, -15],
  348. positioning:'bottom-center'
  349. });
  350. //将测量提示的覆盖标注添加到地图中
  351. map.addOverlay(measureTooltip);
  352. }
  353. //测量类型发生改变时触发事件
  354. typeSelect.onchange = function () {
  355. //移除之前的绘制对象
  356. map.removeInteraction(draw);
  357. //重新进行绘制
  358. addInteraction();
  359. };
  360.  
  361. //格式化测量长度
  362. var formatLength = function (line) {
  363. //定义长度变量
  364. var length;
  365. //如果大地测量复选框被勾选,则计算球面距离
  366. if (geodesicCheckbox.checked) {
  367. //Return the coordinates of the linestring.
  368. //获取坐标串
  369. var coordinates = line.getCoordinates();
  370. //初始长度为0
  371. length = 0;
  372. //获取源数据的坐标系
  373. var sourceProj = map.getView().getProjection();
  374. //进行点的坐标转换
  375. for (var i = 0; i < coordinates.length - 1; i++) {
  376. //第一个点
  377. var c1 = ol.proj.transform(coordinates[i], sourceProj, 'EPSG:4326');
  378. //第二个点
  379. var c2 = ol.proj.transform(coordinates[i + 1], sourceProj, 'EPSG:4326');
  380. //获取转换后的球面距离
  381. //Returns the distance from c1 to c2 using the haversine formula.
  382. length += wgs84Sphere.haversineDistance(c1,c2);
  383. }
  384. } else {
  385. //Return the length of the linestring on projected plane.
  386. //计算平面距离
  387. length = Math.round(line.getLength() * 100) / 100;
  388. }
  389. //定义输出变量
  390. var output;
  391. //如果长度大于1000,则使用km单位,否则使用m单位
  392. if (length > 1000) {
  393. output = (Math.round(length / 1000 * 100) / 100) + ' ' + 'km'; //换算成KM单位
  394. } else {
  395. output = (Math.round(length * 100) / 100) + ' ' + 'm'; //m为单位
  396. }
  397. return output;
  398. };
  399.  
  400. //格式化测量面积
  401. var formatArea = function (polygon) {
  402. //定义面积变量
  403. var area;
  404. //如果大地测量复选框被勾选,则计算球面面积
  405. if (geodesicCheckbox.checked) {
  406. //获取初始坐标系
  407. var sourceProj = map.getView().getProjection();
  408. //Make a complete copy of the geometry.
  409. //Transform each coordinate of the geometry from one coordinate reference system to another.
  410. //The geometry is modified in place. For example, a line will be transformed to a line and a circle to a circle.
  411. //If you do not want the geometry modified in place, first clone() it and then use this function on the clone.
  412. //克隆该几何对象然后转换坐标系
  413. var geom = polygon.clone().transform(sourceProj, 'EPSG:4326');
  414. //Return the Nth linear ring of the polygon geometry.
  415. //Return null if the given index is out of range.
  416. //The exterior linear ring is available at index 0 and the interior rings at index 1 and beyond.
  417. //获取多边形的坐标系
  418. var coordinates = geom.getLinearRing(0).getCoordinates();
  419. //Returns the geodesic area for a list of coordinates.
  420. //获取球面面积
  421. area = Math.abs(wgs84Sphere.geodesicArea(coordinates));
  422. } else {
  423. //获取平面面积
  424. area = polygon.getArea();
  425. }
  426. //定义输出变量
  427. var output;
  428. //当面积大于10000时,转换为平方千米,否则为平方米
  429. if (area > 10000) {
  430. output = (Math.round(area/1000000*100)/100) + ' ' + 'km<sup>2</sup>';
  431. } else {
  432. output = (Math.round(area*100)/100) + ' ' + 'm<sup>2</sup>';
  433. }
  434. return output;
  435. };
  436. //添加交互绘图对象
  437. addInteraction();
  438. });
  439. </script>
  440. </head>
  441. <body>
  442. <div id="map">
  443. <div id="menu">
  444. <label>测量类型选择</label>
  445. <select id="type">
  446. <option value="length">长度</option>
  447. <option value="area">面积</option>
  448. </select>
  449. <label class="checkbox"><input type="checkbox" id="geodesic" />使用大地测量</label>
  450. </div>
  451. </div>
  452. <div id="scalebar"></div>
  453. </body>
  454. </html>

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

  1. 百度地图整合功能分享修正版[ZMap.js] 实例源码!

    ZMap 功能说明 ZMap 是学习百度地图 api 接口,开发基本功能后整的一个脚本类,本类方法功能大多使用 prototype 原型 实现: 包含的功能有:轨迹回放,圈画区域可编辑,判断几个坐标是 ...

  2. 百度地图API开发一——仿照现有测距效果实现测面功能

      最近做了一个百度地图API的开发项目,里面有测量距离和测量面积的功能需求.测量距离百度给出了封装好的javascript包——BMapLib.DistanceTool,效果如下: 这个效果体验很好 ...

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

    美丽的滴水湖   美丽的滴水湖坐落在上海的东南角,濒临东海,风景秀丽,安静舒适,是旅游.恋爱的绝佳去处.笔者有幸去过一回,对那儿的风土人情留下了深刻的印象,如果有机会,笔者还会多去几次!   滴水湖是 ...

  4. 玩转X-CTR100 l STM32F4 l HC-SR04超声波测距

    我造轮子,你造车,创客一起造起来!更多塔克创新资讯[塔克社区 www.xtark.cn ][塔克博客 www.cnblogs.com/xtark/ ] 超声波测距模块HC-SR04可以测量2cm~40 ...

  5. 利用百度API(JavaScript 版)实现在地图上绘制任一多边形,并判断给定经纬度是否在多边形范围内。以及两点间的测距功能

    权声明:本文为博主原创文章,未经博主允许不得转载. 利用百度API(JavaScript 版)实现在地图上绘制任一多边形,并判断给定经纬度是否在多边形范围内.以及两点间的测距功能. 绘制多边形(蓝色) ...

  6. ArcGIS Runtime SDK for WPF之测量距离和面积

    bu不多说,上代码 using System.Windows; using ESRI.ArcGIS.Client; using ESRI.ArcGIS.Client.Tasks; using ESRI ...

  7. openlayers之地图测距侧面

    项目背景vue-cli3.0 public下html需要引入文件 <link rel="stylesheet" href="<%= BASE_URL %> ...

  8. Openlayers3 WebGis二次开发包实例

    <%@ Page Language="C#" AutoEventWireup="true" CodeBehind="index.aspx.cs& ...

  9. C语言单片机项目实战超声波雷达测距

    本实验是基于MSP430利用HC-SR04超声波传感器进行测距,测距范围是3-65cm,讲得到的数据显示在LCD 1602液晶屏上. 模块工作原理如下 (1)采用 IO 触发测距,给至少 10us 的 ...

随机推荐

  1. springboot动态修改日志级别+权限认证

    1. springboot动态修改日志级别+权限认证 1.1. 需求 网上找到的动态修改日志级别的方式,基本都是没有权限验证的,或者特地关闭权限验证,但也没给出加上验证的解决方式 修改日志等级也是一个 ...

  2. base64编解码学习及python代码实现

    Base64是一种用64个字符来表示任意二进制数据的方法. Base64编码可以成为密码学的基石.可以将任意的二进制数据进行Base64编码.所有的数据都能被编码为并只用65个字符就能表示的文本文件. ...

  3. Group By Grouping Sets

    Group by分组函数的自定义,与group by配合使用可更加灵活的对结果集进行分组,Grouping sets会对各个层级进行汇总,然后将各个层级的汇总值union all在一起,但却比单纯的g ...

  4. PHP的会话控制

    页面数据的作用域: 当前页共享数据:变量.常量 两个页面间传递数据:get,post 跟踪用户的多页面数据共享(会话):session.cookie 全局数据共享:文件.数据库.memcached C ...

  5. Python 游戏之旅(Pygame)

    Pygame是跨平台Python模块,专为电子游戏设计,包含图像.声音.建立在SDL基础上,允许实时电子游戏研发而无需被低级语言(如机器语言和汇编语言)束缚.基于这样一个设想,所有需要的游戏功能和理念 ...

  6. pycharm安装plugins

    1 . 启动 PyCharm 软件 2 . 打开 设置(Setting) 窗口.(操作:File -> Setting 或者 按快捷键 Ctrl + Alt + S) 3 . 在搜索框里面搜索: ...

  7. Chapter 4 Invitations——10

    "Mr. Cullen?" the teacher called, seeking the answer to a question that I hadn't heard. “C ...

  8. TOMCAT启动流程分析

    ------------------tomcat服务开启----------2014-9-26 9:17:07 org.apache.catalina.core.AprLifecycleListene ...

  9. 02 Tensorflow Hello World程序

    打开python idle,输入: import tensorflow as tf # 创建常量 hello = tf.constant('Hello,world!') # 创建会话 sess = t ...

  10. 【原创】驱动开发中Memory read error导致的蓝屏问题

    最近在看着<windows驱动开发技术详解>这本书,模仿着敲了第七章中的模拟文件读写部分.在Debug过程中,蓝屏了好多次并出现了各种奇葩的问题.在调了快两天之后,问题终于解决了!现在在这 ...