openlayers3实现测量功能 -九游会下载

本文实例为大家分享了openlayers3实现测量功能的具体代码,供大家参考,具体内容如下

1. 前言

测量功能实现面积的测量以及长度的测量。通过鼠标绘制区域以及长度来进行测量。openlayers 3 框架没有提供测量控件,但提供了相应的接口,需要需要基于几何对象的相应接口,结合图形绘制功能实现。

2. 实现思路

(1)新建一个网页,引用 openlayers 3 开发库、jquery 库与 bootstrap 库,并参照前面显示地图的文章,加载 osm 瓦片图层。
(2)在地图容器中,创建一个测量类型选择控件,进行选择距离测量与面积测量。
(3)编写代码实现测量功能。

3. 实现代码

html主要代码

测量类型控件的样式设置:

#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' ? 'polygon' : 'linestring');
 draw = new ol.interaction.draw({
  source: source, //测量绘制层数据源
  type: /** @type {ol.geom.geometrytype} */ (type), //几何图形类型
  style: new ol.style.style({ //绘制几何图形的样式
   fill: new ol.style.fill({
    color: 'rgba(255, 255, 255, 0.2)'
   }),
   stroke: new ol.style.stroke({
    color: 'rgba(0, 0, 0, 0.5)',
    linedash: [10, 10],
    width: 2
   }),
   image: new ol.style.circle({
    radius: 5,
    stroke: new ol.style.stroke({
     color: 'rgba(0, 0, 0, 0.7)'
    }),
    fill: new ol.style.fill({
     color: 'rgba(255, 255, 255, 0.2)'
    })
   })
  })
 });
 map.addinteraction(draw);
 createmeasuretooltip(); //创建测量工具提示框
 createhelptooltip(); //创建帮助提示框
 var listener;
 //绑定交互绘制工具开始绘制的事件
 draw.on('drawstart',
  function(evt) {
   // set sketch
   sketch = evt.feature; //绘制的要素
   /** @type {ol.coordinate|undefined} */
   var tooltipcoord = evt.coordinate; // 绘制的坐标
   //绑定change事件,根据绘制几何类型得到测量长度值或面积值,并将其设置到测量工具提示框中显示
   listener = sketch.getgeometry().on('change', function(evt) {
    var geom = evt.target; //绘制几何要素
    var output;
    if (geom instanceof ol.geom.polygon) {
     output = formatarea( /** @type {ol.geom.polygon} */ (geom)); //面积值
     tooltipcoord = geom.getinteriorpoint().getcoordinates(); //坐标
    } else if (geom instanceof ol.geom.linestring) {
     output = formatlength( /** @type {ol.geom.linestring} */ (geom)); //长度值
     tooltipcoord = geom.getlastcoordinate(); //坐标
    }
    measuretooltipelement.innerhtml = output; //将测量值设置到测量工具提示框中显示
    measuretooltip.setposition(tooltipcoord); //设置测量工具提示框的显示位置
   });
  }, this);
 //绑定交互绘制工具结束绘制的事件
 draw.on('drawend',
  function(evt) {
   measuretooltipelement.classname = 'tooltip tooltip-static'; //设置测量提示框的样式
   measuretooltip.setoffset([0, -7]);
   // unset sketch
   sketch = null; //置空当前绘制的要素对象
   // unset tooltip so that a new one can be created
   measuretooltipelement = null; //置空测量工具提示框对象
   createmeasuretooltip(); //重新创建一个测试工具提示框显示结果
   ol.observable.unbykey(listener);
  }, this);
}

代码解析

首先加载绘图控件(ol.interaction.draw),也就是我们的笔,在实例化控件时设置当前绘图要素的样式,然后分别调用 createhelptooltop() 与 createmeasuretooltip() 创建帮助信息提示框和测量工具提示框对象;最后绑定绘图控件对象的 drawstart 与 drawend 事件,实现绘图测量功能。其中,在drawstart 事件处理函数中, 由事件对象得到当前绘制的要素(sketch),通过绘制要素的几何对象绑定 change 事件,根据事件监听的几何对象类型是线或是多边形(ol.geom.polygon 或 ol.geom.linestring),调用 formatarea() 与 formatlength() 计算输出测量得到的面积值或长度值。

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)   ' '   'km2'; //换算成km单位
  } else {
   output = (math.round(area * 100) / 100)   ' '   'm2'; //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. 实现效果

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持呐喊教程。

声明:本文内容来源于网络,九游会下载的版权归原作者所有,内容由互联网用户自发贡献自行上传,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任。如果您发现有涉嫌九游会下载的版权的内容,欢迎发送邮件至:notice#www.elefans.com(发邮件时,请将#更换为@)进行举报,并提供相关证据,一经查实,本站将立刻删除涉嫌侵权内容。

网站地图