Measure.js 8.64 KB
/**
 * Created by cp on 2018/8/20.
 */

/**
 * Created by cp on 2018/7/2.
 */


import Map from 'ol/Map.js';
import {unByKey} from 'ol/Observable.js';
import Overlay from 'ol/Overlay.js';
import {getArea, getLength} from 'ol/sphere.js';
import {LineString, Polygon} from 'ol/geom.js';
import Draw from 'ol/interaction/Draw.js';
import { Vector as VectorLayer} from 'ol/layer.js';
import { Vector as VectorSource} from 'ol/source.js';
import {Circle as CircleStyle, Fill, Stroke, Style} from 'ol/style.js';

// 定义类
class Measure {
  constructor(vueThis, mainMap) {
    this.vm = vueThis;//类中变量

    this.name='measure';
    if (mainMap) {
      this.map = mainMap.getMap();//地图
      this.mainMap = mainMap;
    }
    this.init();
  }

  /****初始化方法****/
  init(){
    let source = new VectorSource();
    let vector = new VectorLayer({
      source: source,
      style: new Style({
        fill: new Fill({
          color: 'rgba(255, 255, 255, 0.2)'
        }),
        stroke: new Stroke({
          color: '#ffcc33',
          width: 2
        }),
        image: new CircleStyle({
          radius: 7,
          fill: new Fill({
            color: '#ffcc33'
          })
        })
      })
    });

    vector.set("name",this.name);
    this.source=source;
    this.vector=vector;


    this.startMeasureStatus=false;//是否在绘制 初始化时候并不在绘制
    this.map.addLayer(vector);
    /**
     * Currently drawn feature.
     * @type {module:ol/Feature~Feature}
     */
    this.sketch=null;
    /**
     * The help tooltip element.
     * @type {Element}
     */
    this.helpTooltipElement=null;


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


    /**
     * The measure tooltip element.
     * @type {Element}
     */
    this.measureTooltipElement=null;


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


    /**
     * Message to show when the user is drawing a polygon.
     * @type {string}
     */
    this.continuePolygonMsg = '双击结束绘制';


    /**
     * Message to show when the user is drawing a line.
     * @type {string}
     */
    this.continueLineMsg = '双击结束绘制';

    //初始化样式
    this.initStyle();
  }



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

    if (this.sketch) {
      var geom = (this.sketch.getGeometry());
      if (geom instanceof Polygon) {
        helpMsg = this.continuePolygonMsg;
      } else if (geom instanceof LineString) {
        helpMsg = this.continueLineMsg;
      }
    }
    this.helpTooltipElement.innerHTML = helpMsg;
    this.helpTooltip.setPosition(evt.coordinate);
    this.helpTooltipElement.classList.remove('hidden');
  };




  /****添加地图监听事件****/
  addMapEvent(){
    let classThis=this;
    let mapPointermove=classThis.map.on('pointermove', function(evt){
      classThis.pointerMoveHandler(evt);
    });
    let mapMouseout =classThis.map.getViewport().addEventListener('mouseout', function() {
      classThis.helpTooltipElement.classList.add('hidden');
    });
    this.mapPointermove=mapPointermove;
    this.mapMouseout=mapMouseout;

  }

  removeMapLisenter(){
    if(this.mapPointermove||this.mapMouseout){
      unByKey(this.mapPointermove);
      unByKey(this.mapMouseout);
      this.mapPointermove=null;
      this.mapMouseout=null;
      this.helpTooltipElement.innerHTML = "请选择绘制的点";
      this.helpTooltipElement.className = 'tooltip hidden';

    }
    this.startMeasureStatus=false;
  }


  /**
   * Format length output.
   * @param {module:ol/geom/LineString~LineString} line The line.
   * @return {string} The formatted length.
   */
  formatLength(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;
  };


  /**
   * Format area output.
   * @param {module:ol/geom/Polygon~Polygon} polygon The polygon.
   * @return {string} Formatted area.
   */
  formatArea(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;
  };


  initStyle(){
    let style = new Style({
      fill: new Fill({
        color: 'rgba(255, 255, 255, 0.5)'
      }),
      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)'
        })
      })
    });
    this.style=style;
  }


  /***  绘制的方法  类型有两种
   * 'Polygon'
   * 'LineString'
   * ****/
  addInteraction(type){

    let classThis=this;
    let draw = new Draw({
      source: classThis.source,
      type: type,
      style:classThis.style
    });
    classThis.map.addInteraction(draw);

    classThis.createMeasureTooltip();
    classThis.createHelpTooltip();

    let  listener;
    draw.on('drawstart',
      function(evt) {
        // set sketch
        classThis.sketch = evt.feature;
        /** @type {module:ol/coordinate~Coordinate|undefined} */
        var tooltipCoord = evt.coordinate;
        listener = classThis.sketch.getGeometry().on('change', function(evt) {
          var geom = evt.target;
          var output;
          if (geom instanceof Polygon) {
            output = classThis.formatArea(geom);
            tooltipCoord = geom.getInteriorPoint().getCoordinates();
          } else if (geom instanceof LineString) {
            output = classThis.formatLength(geom);
            tooltipCoord = geom.getLastCoordinate();
          }
          classThis.measureTooltipElement.innerHTML = output;
          classThis.measureTooltip.setPosition(tooltipCoord);
        });
      });

    draw.on('drawend',
      function() {
        classThis.measureTooltipElement.className = 'tooltip tooltip-static';
        classThis.measureTooltip.setOffset([0, -7]);
        // unset sketch
        classThis.sketch = null;
        // unset tooltip so that a new one can be created
        classThis.measureTooltipElement = null;
        unByKey(listener);
        classThis.endDraw();
        classThis.removeMapLisenter();

      });

    this.draw=draw;
  }



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


  /**
   * Creates a new measure tooltip
   */
  createMeasureTooltip() {
    let classThis=this;

    if (classThis.measureTooltipElement) {
      classThis.measureTooltipElement.parentNode.removeChild(classThis.measureTooltipElement);
    }
    classThis.measureTooltipElement = document.createElement('div');
    classThis.measureTooltipElement.className = 'tooltip tooltip-measure';
    classThis.measureTooltip = new Overlay({
      element: classThis.measureTooltipElement,
      offset: [0, -15],
      positioning: 'bottom-center'
    });
    classThis.map.addOverlay(classThis.measureTooltip);
  }


  cleanMeasure(){
    this.endDraw();
    this.removeMapLisenter();
    this.map.removeOverlay(this.helpTooltip);
    this.map.removeOverlay(this.measureTooltip);
    if(this.measureTooltipElement){
      this.measureTooltipElement.innerHTML = "";
    }
    if(this.helpTooltipElement){
      this.helpTooltipElement.innerHTML = "";
    }
    this.clanLayer();
  }
  clanLayer(){
    this.vector.getSource().clear();
  }
  /****结束的接口***/
  endDraw(){
    let classThis=this;
    if(classThis.draw){
      this.map.removeInteraction(classThis.draw);
      classThis.draw=null;
    }
  }

  /****测量开始的接口***/
  startMeasure(type){
    if(!this.startMeasureStatus){
      this.addMapEvent();
      this.startMeasureStatus=true;
    }
    this.endDraw();
    this.addInteraction(type);

  }


}

// Measure.para = 'Allen'; 静态变量

export {Measure};