• openlayers5-距离测量和面积量测


    升级到最新版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],
                 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

  • 相关阅读:
    习题解答chapter09
    习题解答chapter08
    习题解答chapter07
    银行账户实验-1.2
    银行账户实验-1.1
    银行账户实验-1.0
    习题解答chapter06
    习题解答chapter05
    习题解答chapter04
    习题解答chapter03
  • 原文地址:https://www.cnblogs.com/mr-hu2009/p/10936619.html
Copyright © 2020-2023  润新知