Vue + openLayers 测距,侧面,清楚轨迹(封装measure)引入即用

1.效果图(测距)

 2.测面

 3.封装measure.Vue(把样式放到要引入的页面)

<template>
  <div>
    <div class="btns-box">
      <el-button type="primary" @click="measure('LineString')">测距</el-button>
      <el-button type="primary" @click="measure('Polygon')">测面</el-button>
      <el-button type="primary" @click="clearMeasure">清除测量轨迹</el-button>
    </div>
  </div>
</template>
<script>
import 'ol/ol.css'
import Draw from 'ol/interaction/Draw'
import Map from 'ol/Map'
import Overlay from 'ol/Overlay'
import View from 'ol/View'
import TileArcGISRest from 'ol/source/TileArcGISRest'
import { Circle as CircleStyle, Fill, Stroke, Style } from 'ol/style'
import { LineString, Polygon } from 'ol/geom'
import { OSM, Vector as VectorSource } from 'ol/source'
import { Tile as TileLayer, Vector as VectorLayer } from 'ol/layer'
import { getArea, getLength } from 'ol/sphere'
import { unByKey } from 'ol/Observable'

import CONSTANT from '@/utils/constant.js'

let layerIndex = 0
export default {
  name: 'Measure',
  props: {
    drawLineMap: {
      type: Object,
      default: () => {
      }
    }
  },
  data() {
    return {
      map: null,
      raster: null,
      vector: new VectorLayer({
        source: new VectorSource(),
        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'
            })
          })
        })
      }),
      sketch: null, // Currently drawn feature
      helpTooltipElement: null, // The help tooltip element.
      helpTooltip: null, // Overlay to show the help messages.
      measureTooltipElement: null, // The measure tooltip element.
      measureTooltip: null, // Overlay to show the measurement.
      // Message to show when the user is drawing a polygon.
      continuePolygonMsg: '单击继续绘制多边形',
      // Message to show when the user is drawing a line
      continueLineMsg: '单击继续绘制直线',
      draw: null, //global so we can remove it later
      listener: null,
      shapeType: null,
      drawCache: {},
    }
  },
  created() {
    setTimeout(() => {
      this.map = this.drawLineMap
      this.map.addLayer(this.vector)
    }, 1000)
  },
  methods: {
    // 测距、测面
    measure(type) {
      this.shapeType = type
      layerIndex++
      this.drawCache[layerIndex] = {
        feature: null,
        measureTooltip: null
      }
      if (this.draw) {
        this.map.removeInteraction(this.draw)
      }
      // 添加map事件
      this.addMapEvent()
    },
    // 清除测量
    clearMeasure() {
      for (const i in this.drawCache) {
        this.map.removeOverlay(this.drawCache[i].measureTooltip)
        this.vector.getSource().removeFeature(this.drawCache[i].feature)
      }
      this.drawCache = {}
      layerIndex = 0
    },
    addMapEvent() {
      console.log(111)
      console.log(this.map)
      this.map.on('pointermove', (evt) => {
        this.draw ? this.pointerMoveHandler(evt) : this.map.removeOverlay(this.helpTooltip)
      })
      this.map.getViewport().addEventListener('mouseout', () => {
        this.helpTooltipElement && this.helpTooltipElement.classList.add('hidden')
      })
      this.addInteraction()
    },
    addInteraction() {
      this.draw = new Draw({
        source: this.vector.getSource(),
        type: this.shapeType,
        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)'
            })
          })
        })
      })

      this.map.addInteraction(this.draw)
      this.createMeasureTooltip()
      this.createHelpTooltip()
      this.drawHandler()
    },
    /**
     * Handle pointer move.
     * @param {import('../src/ol/MapBrowserEvent').default} evt The event.
     */
    pointerMoveHandler(evt) {
      if (evt.dragging) {
        return
      }
      /** @type {string} */
      var helpMsg = '单击开始绘图'

      if (this.sketch) {
        var geom = this.sketch.getGeometry()
        if (geom instanceof LineString) {
          helpMsg = this.continueLineMsg
        }
      }

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

      this.helpTooltipElement.classList.remove('hidden')
    },
    /**
     * Format length output.
     * @param {LineString} line The line.
     * @return {string} The formatted length.
     */
    formatLength(line) {
      const sourceProj = this.map.getView().getProjection() // 获取投影坐标系
      var length = getLength(line, { projection: sourceProj })
      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 {Polygon} polygon The polygon.
     * @return {string} Formatted area.
     */
    formatArea(polygon) {
      const sourceProj = this.map.getView().getProjection() //获取投影坐标系
      const geom = polygon.clone().transform(sourceProj, 'EPSG:3857')
      const area = getArea(geom)

      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
    },
    /**
     * Creates a new measure tooltip
     */
    createMeasureTooltip() {
      if (this.measureTooltipElement) {
        this.measureTooltipElement.parentNode.removeChild(this.measureTooltipElement)
      }
      this.measureTooltipElement = document.createElement('div')
      this.measureTooltipElement.className = 'ol-tooltip ol-tooltip-measure'
      this.measureTooltip = new Overlay({
        element: this.measureTooltipElement,
        offset: [0, -15],
        positioning: 'bottom-center'
      })
      this.map.addOverlay(this.measureTooltip)
    },
    /**
     * Creates a new help tooltip
     */
    createHelpTooltip() {
      if (this.helpTooltipElement) {
        this.helpTooltipElement.parentNode.removeChild(this.helpTooltipElement)
      }
      this.helpTooltipElement = document.createElement('div')
      this.helpTooltipElement.className = 'ol-tooltip hidden'
      this.helpTooltip = new Overlay({
        element: this.helpTooltipElement,
        offset: [15, 0],
        positioning: 'center-left'
      })
      this.map.addOverlay(this.helpTooltip)
    },
    drawHandler() {
      this.draw.on('drawstart', (evt) => {
        this.sketch = evt.feature
        let tooltipCoord = evt.coordinate

        this.listener = this.sketch.getGeometry().on('change', (evt) => {
          let output
          const geom = evt.target
          if (geom instanceof LineString) {
            output = this.formatLength(geom)
            tooltipCoord = geom.getLastCoordinate()
          } else if (geom instanceof Polygon) {
            output = this.formatArea(geom)
            tooltipCoord = geom.getInteriorPoint().getCoordinates()
          }
          const closeBtn =
              '<i class=\'tooltip-close-btn tooltip-close-btn_' + layerIndex + '\' data-index=\'' + layerIndex + '\'></i>'
          this.measureTooltipElement.innerHTML = output + closeBtn
          this.measureTooltip.setPosition(tooltipCoord)
          this.drawCache[layerIndex].measureTooltip = this.measureTooltip
        })
      })

      this.draw.on('drawend', (evt) => {
        this.drawCache[layerIndex].feature = evt.feature

        this.measureTooltipElement.className = 'ol-tooltip ol-tooltip-static'
        this.measureTooltip.setOffset([0, -7])
        // unset sketch
        this.sketch = null
        // unset tooltip so that a new one can be created
        this.measureTooltipElement = null
        this.createMeasureTooltip()
        unByKey(this.listener)
        this.map.removeInteraction(this.draw)
        this.draw = null

        // 删除图层
        const self = this
        document.querySelector('.tooltip-close-btn_' + layerIndex).addEventListener('click', function() {
          self.vector.getSource().removeFeature(self.drawCache[this.dataset.index].feature)
          self.map1.removeOverlay(self.drawCache[this.dataset.index].measureTooltip)
          delete self.drawCache[this.dataset.index]
        })
      })
    }
  },
  mounted() {
  }

}
</script>
<style lang="scss" scoped>
.btns-box {
  float: left;
  margin-left: 5px;
}
//测距,测面
::v-deep .ol-tooltip {
  position: relative;
  background: rgba(0, 0, 0, 0.5);
  border-radius: 4px;
  color: white;
  padding: 4px 14px 4px 8px;
  opacity: 0.7;
  white-space: nowrap;
  font-size: 12px;
}
::v-deep .ol-tooltip-measure {
  opacity: 1;
  font-weight: bold;
}
::v-deep .ol-tooltip-static {
  background-color: #ffcc33;
  color: black;
  border: 1px solid white;
}
::v-deep .ol-tooltip-measure:before,
::v-deep .ol-tooltip-static:before {
  border-top: 6px solid rgba(0, 0, 0, 0.5);
  border-right: 6px solid transparent;
  border-left: 6px solid transparent;
  content: '';
  position: absolute;
  bottom: -6px;
  margin-left: -5px;
  left: 50%;
}
::v-deep .ol-tooltip-static:before {
  border-top-color: #ffcc33;
}
//测面、测距的样式
::v-deep .tooltip-close-btn {
  font-style: normal;
  position: absolute;
  color: #2d8cf0;
  right: 0px;
  top: -7px;
  font-weight: bold;
  font-size: 15px;
  cursor: pointer;
  &:hover {
    color: #fff;
  }
}
</style>

4.使用

1.向引入的页面引入measure.vue
import Measure from './components/Measure.vue'
2.使用
<Measure
  :draw-line-map = "drawLineMap"
  :draw-area-map = "drawAreaMap"
  :clear-measure-map ="clearMeasureMap"
  style="float: left;margin-left: 8px"
></Measure>
3.data(){
return{
    drawLineMap: {},
    drawAreaMap: {},
    clearMeasureMap: {},
    }
}
4.new Map()之后   this.drawLineMap=new Map()

5.成功

  • 3
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值