ol测距、测面工具,并清除图层

<template>
  <div class="measure-tools" style="display: flex; flex-direction: column">
    <div class="menu-box" @click="measure('distance')">
      <i class="tool tool-distance"></i>
      <span> 测距 </span>
    </div>
    <div class="menu-box" @click="measure('area')">
      <i class="tool tool-area"></i>
      <span> 测面 </span>
    </div>
  </div>
</template>

<script>
// import { length, area } from "@turf";
import { Vector as VectorSource } from "ol/source";
import { Vector as VectorLayer } from "ol/layer";
// import GeoJSON from "ol/format/GeoJSON";
import { Draw } from "ol/interaction";

// import Point from "ol/geom/Point";
import { unByKey } from "ol/Observable.js";
import Overlay from "ol/Overlay";
// import { Feature } from "ol";
// import {
//   getArea,
//   getLength
// } from 'ol/sphere.js';
import { getLength } from "ol/sphere";
import { getArea } from "ol/sphere";

import LineString from "ol/geom/LineString";
import Polygon from "ol/geom/Polygon";
import DoubleClickZoom from "ol/interaction/DoubleClickZoom";
import tMessager from '@/entries/bus.ts'
import { Circle as CircleStyle, Fill, Stroke, Style } from "ol/style.js";
let piemap;
let helpTooltipElement;
export default {
  name: "measure-tools",
  data() {
    return {
      drawInteraction: null,
      renderLayer: null,
    };
  },
  props: ["parentRef", "clear"],
  components: {},
  mounted() {
    // 此处传过来的val指的是map
    tMessager.$on('getMap',(val)=>{
      piemap = val
    })
  },
  computed: {},
  watch: {
    clear: {
      handler(newIndex) {
        console.log(newIndex,'newIndex');
        if (newIndex) {
          this.clearMeasure();
        }
      },
    },
  },
  methods: {
    measure(measureType) {
      let that = this;
      let drawLayer = this.getLayer("lineAndArea");
      if (this.drawInteraction != null) {
        piemap.removeInteraction(this.drawInteraction);
      }
      let vector = null;
      let source = null;
      if (drawLayer != null) {
        vector = drawLayer;
        source = drawLayer.getSource();
      } else {
        source = new VectorSource();
        vector = new VectorLayer({
          source: source,
          style: new Style({
            fill: new Fill({
              color: "rgba(255, 255, 255, 0.2)",
            }),
            stroke: new Stroke({
              color: "rgba(255, 0, 0, 0.5)",
              lineDash: [10, 10],
              width: 2,
            }),
            image: new CircleStyle({
              radius: 7,
              fill: new Fill({
                color: "#ffcc33",
              }),
            }),
          }),
          zIndex: 16,
        });
        vector.set("id", "lineAndArea");
        piemap.addLayer(vector);
      }
      /**
       * Currently drawn feature.
       * @type {module:ol/Feature~Feature}
       */
      let sketch;
      /**
       * The help tooltip element.
       * @type {Element}
       */
      // let helpTooltipElement;
      /**
       * Overlay to show the help messages.
       * @type {module:ol/Overlay}
       */
      let helpTooltip;
      /**
       * The measure tooltip element.
       * @type {Element}
       */
      let measureTooltipElement;
      /**
       * Overlay to show the measurement.
       * @type {module:ol/Overlay}
       */
      let measureTooltip;
      /**
       * Message to show when the user-manger is drawing a polygon.
       * @type {string}
       */
      let continuePolygonMsg = "";
      /**
       * Message to show when the user-manger is drawing a line.
       * @type {string}
       */
      let continueLineMsg = "";
      createMeasureTooltip();
      createHelpTooltip();
      /**
       * Handle pointer move.
       * @param {module:ol/MapBrowserEvent~MapBrowserEvent} evt The event.
       */
      let pointerMoveHandler = function (evt) {
        if (evt.dragging) {
          return;
        }
        /** @type {string} */
        let helpMsg = "请点击开始绘制";

        if (sketch) {
          let 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");
      };

      piemap.on("pointermove", pointerMoveHandler);
      piemap.getViewport().addEventListener("mouseout", function () {
        if (helpTooltipElement) {
          helpTooltipElement.classList.add("hidden");
        }
      });

      let formatLength = function (line) {
        //获取投影坐标系
        let sourceProj = piemap.getView().getProjection();
        //ol/sphere里有getLength()和getArea()用来测量距离和区域面积,默认的投影坐标系是EPSG:3857, 其中有个options的参数,可以设置投影坐标系
        let length = getLength(line, { projection: sourceProj });
        //let length = getLength(line);
        let output;
        if (length > 100) {
          output = Math.round((length / 1000) * 100) / 100 + " " + "km";
        } else {
          output = Math.round(length * 100) / 100 + " " + "m";
        }
        return output;
      };

      let formatArea = function (polygon) {
        //获取投影坐标系
        let sourceProj = piemap.getView().getProjection();
        let area = getArea(polygon, { projection: sourceProj });
        //let area = getArea(polygon);
        //console.info(area)
        let 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;
      };

      function addInteraction() {
        let type = measureType == "area" ? "Polygon" : "LineString";
        that.drawInteraction = 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)",
              }),
            }),
          }),
        });
        piemap.addInteraction(that.drawInteraction);

        let listener;
        that.drawInteraction.on(
          "drawstart",
          function (evt) {
            // set sketch
            sketch = evt.feature;
            //禁用双击放大功能
            disableMapDoubleClickZoom();
            /** @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
        );

        that.drawInteraction.on(
          "drawend",
          function (event) {
            //打开双击放大功能
            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);
            piemap.un("pointermove", pointerMoveHandler);
            piemap.removeInteraction(that.drawInteraction);
            helpTooltipElement.classList.add("hidden");
            //地图双击事件
            piemap.once("dblclick", addLastPoint);
            if (measureTooltipElement) {
              helpTooltipElement.parentNode.removeChild(helpTooltipElement);
              helpTooltipElement = null;
            }
          },
          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",
        });
        piemap.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",
        });
        piemap.addOverlay(measureTooltip);
      }

      function disableMapDoubleClickZoom() {
        const dblClickInteraction = piemap
          .getInteractions()
          .getArray()
          .find((interaction) => {
            return interaction instanceof DoubleClickZoom;
          });
        if (dblClickInteraction) {
          piemap.removeInteraction(dblClickInteraction);
        }
      }

      function enableMapDoubleClickZoom() {
        let dblClickInteraction = new DoubleClickZoom();
        piemap.addInteraction(dblClickInteraction);
      }

      function addLastPoint(event) {
        event.stopPropagation();
        enableMapDoubleClickZoom();
      }

      // 量测调用
      addInteraction();
      //绘制结束
    },
    // 清除测距、测面标绘内容
    clearMeasure() {
      console.log(piemap,'piemap');
      const layers = piemap.getLayers().getArray()
      const layer = layers.filter((item, index) => item.values_.id && item.values_.id === 'shuixi' || item.values_.id === 'xingzheng'|| item.values_.id === 'shuiku1'|| item.values_.id === 'shuiku2'|| item.values_.id === 'shuizha'|| item.values_.id === 'difang'|| item.values_.id === 'shuiwen'|| item.values_.id === 'yuliang'|| item.values_.id === 'xingbian'|| item.values_.id === 'shenya'|| item.values_.id === 'shipin' || item.values_.id === 'lineAndArea')
      console.log(layers,'layers');
      console.log(layer,'layer');
      if(layer.length > 0){
        layer.forEach((item) => {
          item.getSource().clear();
          piemap.removeLayer(item)
          piemap.getOverlays().clear();
          if (this.drawInteraction != null) {
            piemap.removeInteraction(this.drawInteraction);
          }
          this.$emit('clearChange')
        })
      }else {
        this.$emit('clearChange')
      }
      
      
      // let drawLayer = this.getLayer("lineAndArea");
      // if (drawLayer) {
      //   drawLayer.getSource().clear();
      //   piemap.removeLayer(drawLayer);
      //   piemap.getOverlays().clear(); //清除覆盖对象
      //   if (this.drawInteraction != null) {
      //     piemap.removeInteraction(this.drawInteraction);
      //   }
      // }
    },

    getLayer(layerId) {
      console.log("woyaokaishihuale");
      for (let layerTmp of piemap.getLayers().getArray()) {
        if (layerTmp.get("id") == layerId) {
          return layerTmp;
        }
      }
    },
  },
};
</script>

<!-- Add "scoped" attribute to limit CSS to this component only -->
<style lang="scss" scoped>
.measure-tools {
  .menu-box {
	&:first-child{
		margin-top: 0;
	}
    margin-top: 24px;
    width: 76px;
    height: 16px;
    line-height: 20px;
    text-align: center;
    box-sizing: border-box;
    cursor: pointer;
    span {
      display: inline-block;
      height: 20px;
      line-height: 20px;
      font-size: 14px;
      color: #666666;
      margin-left: 3px;
    }
    .tool {
      display: inline-block;
      width: 16px;
      height: 16px;
      vertical-align: middle;
      &.tool-distance {
        background: url("/src/assets/img/image/tc1.png")
          no-repeat;
        background-size: 100%;
      }
      &.tool-area {
        background: url("/src/assets/img/image/gj1.png")
          no-repeat;
        background-size: 100%;
      }
    }
  }

}

:deep .hidden {
  display: none;
}
</style>
<style>
.hidden {
  display: none;
}
</style>

在页面内使用

<template>
    <!-- 清除测距按钮 -->
     <div>
        <div class="menu-box" style="border-right:none" @click="clearMeasure"  :class="{active:curIndex==3}"  id="p3">
          <i class="tool tool-qingchu"></i>
          <span> 清除 </span>
        </div>
      </div>

    <!-- 测距、测面工具 -->
    <measure-tools  :clear="clear" @clearChange="clearChange"></measure-tools>
</template>

import MeasureTools from "./MeasureTools.vue";
export default {

    components: { MeasureTools },

    data(){
        return {
            clear: false,
        }
    },
    methods:{
        clearChange(){
          this.clear = false
        },
        // 清除测距、测面标绘内容
        clearMeasure() {
           this.curIndex=3;
           this.clear = true;
           this.$nextTick(()=>{
               this.$refs.tree.setCheckedKeys([]);
           })
        },
    }
}

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值