mr-hu2009
升级到最新版openlayers5.2,重新写量测方法,官网examples里面有实现好的代码,但是项目是基于vue的模块化开发,官网的例子直接引入不是很合适,并且官网的例子是可以一直连续的测量,而项目中需要测量一次的方法,所以需要对官网例子做一些改进,在此mark一下,有同样需要的朋友们直接拿走不谢o( ̄︶ ̄)o
效果图如下所示:

实现Measure.js

import Draw from \'ol/interaction/Draw\'
import VectorSource from \'ol/source/Vector\';
import VectorLayer from \'ol/layer/Vector\';
import TileLayer from \'ol/layer/Tile\';
import OSM from \'ol/source/OSM\';

import {
  unByKey
} from \'ol/Observable.js\';
import Overlay from \'ol/Overlay\';
import {
  getArea,
  getLength
} from \'ol/sphere.js\';
import View from \'ol/View\';
import {
  LineString,
  Polygon
} from \'ol/geom.js\';
import {
  Circle as CircleStyle,
  Fill,
  Stroke,
  Style
} from \'ol/style.js\';
export default{

  measure(map, measureType) {
    /**
     * Currently drawn feature.
     * @type {module:ol/Feature~Feature}
     */
    var sketch;


    /**
     * The help tooltip element.
     * @type {Element}
     */
    var helpTooltipElement;


    /**
     * Overlay to show the help messages.
     * @type {module:ol/Overlay}
     */
    var helpTooltip;


    /**
     * The measure tooltip element.
     * @type {Element}
     */
    var measureTooltipElement;


    /**
     * Overlay to show the measurement.
     * @type {module:ol/Overlay}
     */
    var measureTooltip;


    /**
     * Message to show when the user is drawing a polygon.
     * @type {string}
     */
    var continuePolygonMsg = \'继续点击绘制多边形\';


    /**
     * Message to show when the user is drawing a line.
     * @type {string}
     */
    var continueLineMsg = \'继续点击绘制线\';

    createMeasureTooltip();
    createHelpTooltip();

    /**
     * Handle pointer move.
     * @param {module:ol/MapBrowserEvent~MapBrowserEvent} evt The event.
     */
    var pointerMoveHandler = function (evt) {
      if (evt.dragging) {
        return;
      }
      /** @type {string} */
      var helpMsg = \'请点击开始绘制\';

      if (sketch) {
        var geom = (sketch.getGeometry());
        if (geom instanceof Polygon) {
          helpMsg = continuePolygonMsg;
        } else if (geom instanceof LineString) {
          helpMsg = continueLineMsg;
        }
      }

      helpTooltipElement.innerHTML = helpMsg;
      helpTooltip.setPosition(evt.coordinate);

      helpTooltipElement.classList.remove(\'hidden\');
    };

    map.on(\'pointermove\', pointerMoveHandler);

    map.getViewport().addEventListener(\'mouseout\', function () {
      helpTooltipElement.classList.add(\'hidden\');
    });

    var draw;
    var formatLength = function (line) {
      var length = getLength(line);
      var output;
      if (length > 100) {
        output = (Math.round(length / 1000 * 100) / 100) +
          \' \' + \'km\';
      } else {
        output = (Math.round(length * 100) / 100) +
          \' \' + \'m\';
      }
      return output;
    };
    var formatArea = function (polygon) {
      var area = getArea(polygon);
      var output;
      if (area > 10000) {
        output = (Math.round(area / 1000000 * 100) / 100) +
          \' \' + \'km<sup>2</sup>\';
      } else {
        output = (Math.round(area * 100) / 100) +
          \' \' + \'m<sup>2</sup>\';
      }
      return output;
    };
    var source;
    // var layer ;
    // 获取存放feature的vectorlayer层。map初始化的时候可以添加好了
    for(let layerTmp of map.getLayers().getArray()){
      if(layerTmp.get("name")=="feature"){
        // layer = layerTmp;
        // layerTmp.setSource(null)
        source= layerTmp.getSource();
      }
    }

    function addInteraction() {
      var type = (measureType == \'area\' ? \'Polygon\' : \'LineString\');
      draw = new Draw({
        source: source,
        type: type,
        style: new Style({
          fill: new Fill({
            color: \'rgba(255, 255, 255, 0.2)\'
          }),
          stroke: new Stroke({
            color: \'rgba(0, 0, 0, 0.5)\',
            lineDash: [10, 10],
            width: 2
          }),
          image: new CircleStyle({
            radius: 5,
            stroke: new Stroke({
              color: \'rgba(0, 0, 0, 0.7)\'
            }),
            fill: new Fill({
              color: \'rgba(255, 255, 255, 0.2)\'
            })
          })
        })
      });
      map.addInteraction(draw);

      var listener;
      draw.on(\'drawstart\',
        function (evt) {
          // set sketch
          sketch = evt.feature;

          /** @type {module:ol/coordinate~Coordinate|undefined} */
          var tooltipCoord = evt.coordinate;

          listener = sketch.getGeometry().on(\'change\', function (evt) {
            var geom = evt.target;
            var output;
            if (geom instanceof Polygon) {
              output = formatArea(geom);
              tooltipCoord = geom.getInteriorPoint().getCoordinates();
            } else if (geom instanceof LineString) {
              output = formatLength(geom);
              tooltipCoord = geom.getLastCoordinate();
            }
            measureTooltipElement.innerHTML = output;
            measureTooltip.setPosition(tooltipCoord);
          });
        }, this);

      draw.on(\'drawend\',
        function () {
          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();
          unByKey(listener);
          map.un(\'pointermove\', pointerMoveHandler);
          map.removeInteraction(draw);
          helpTooltipElement.classList.add(\'hidden\');
        }, this);
    }

    function createHelpTooltip() {
      if (helpTooltipElement) {
        helpTooltipElement.parentNode.removeChild(helpTooltipElement);
      }
      helpTooltipElement = document.createElement(\'div\');
      helpTooltipElement.className = \'tooltip hidden\';
      helpTooltip = new Overlay({
        element: helpTooltipElement,
        offset: [15, 0],
        positioning: \'center-left\'
      });
      map.addOverlay(helpTooltip);
    }

    function createMeasureTooltip() {
      if (measureTooltipElement) {
        measureTooltipElement.parentNode.removeChild(measureTooltipElement);
      }
      measureTooltipElement = document.createElement(\'div\');
      measureTooltipElement.className = \'tooltip tooltip-measure\';
      measureTooltip = new Overlay({
        element: measureTooltipElement,
        offset: [0, -15],
        positioning: \'bottom-center\'
      });
      map.addOverlay(measureTooltip);
    }
    // 量测调用
    addInteraction();
  }
}

以上代码为官网例子的重构,可以一直多次进行测量。
若只想要进行一次量测则在drawend事件中添加

map.un(\'pointermove\', pointerMoveHandler);
map.removeInteraction(draw);
helpTooltipElement.classList.add(\'hidden\');

改为

draw.on(\'drawend\',
        function () {
          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();
          unByKey(listener);
          map.un(\'pointermove\', pointerMoveHandler);
          map.removeInteraction(draw);
          helpTooltipElement.classList.add(\'hidden\');
        }, this);
    }

即可。

调用

然后直接

import Measure from "./Measure";

...
 Measure.measure(this.map, type);
...

就可以调用啦,type值为LineString时为距离测量,area时为面积测量



链接:https://www.jianshu.com/p/f00da34bb4da

分类:

技术点:

相关文章: