<script>
import commonMixin from '@/base/mixins/common.js'
import $ from 'jquery'
export default {
  name: 'bs-measure',
  mixins: [commonMixin('interaction')],
  render () { },
  data () {
    return {
      sketch: null,
      helpTooltipElement: null,
      helpTooltip: null,
      measureTooltipElement: null,
      measureTooltip: null,
      continuePolygonMsg: '单击继续绘制多边形,双击结束绘制',
      continueLineMsg: '单击继续绘制线,双击结束绘制',
      wgs84Sphere: null
    }
  },
  props: {
    type: {
      type: String
    },
    id: { type: String },
    name: { type: String },
    actived: {
      type: Boolean,
      default: false
    }
  },
  watch: {
    actived (flag) {
      this.originInstance.setActive(flag)
    }
  },
  methods: {
    load () {
      debugger
      const { ol, $rootComponent, id, name, continuePolygonMsg, continueLineMsg } = this
      var vector = $rootComponent.addLayer({ id, name })
      this.wgs84Sphere = new ol.Sphere(6378137)
      vector.setStyle(new ol.style.Style({ // 图层样式
        fill: new ol.style.Fill({
          color: 'rgba(255, 255, 255, 0.2)' // 填充颜色
        }),
        stroke: new ol.style.Stroke({
          color: '#ffcc33', // 边框颜色
          width: 2 // 边框宽度
        }),
        image: new ol.style.Circle({
          radius: 7,
          fill: new ol.style.Fill({
            color: '#ffcc33'
          })
        })
      })
      )
      $rootComponent.$on('mousemove', (evt) => {
        if (evt.dragging) {
          return
        }
        /** @type {string} */
        var helpMsg = '单击开始绘制'
        // 判断绘制几何类型设置相应的帮助提示信息
        if (this.sketch) {
          var geom = (this.sketch.getGeometry())
          if (geom instanceof ol.geom.Polygon) {
            helpMsg = continuePolygonMsg // 绘制多边形时提示相应内容
          } else if (geom instanceof ol.geom.LineString) {
            helpMsg = continueLineMsg // 绘制线时提示相应内容
          }
        }
        if (this.actived) {
          this.helpTooltipElement.innerHTML = helpMsg // 将提示信息设置到对话框中显示
          this.helpTooltip.setPosition([evt.lon, evt.lat]) // 设置帮助提示框的位置
        }
        // $(helpTooltipElement).removeClass('hidden') // 移除帮助提示框的隐藏样式进行显示
        $($rootComponent.getViewport()).on('mouseout', function () {
          // $(helpTooltipElement).addClass('hidden')
        })
      })
      this.addInteraction()
    },
    addInteraction () {
      const { type, ol, $rootComponent, id } = this
      const source = $rootComponent.getLayer(id).getSource()
      this.originInstance = new ol.interaction.Draw({
        source: source, // 测量绘制层数据源
        type: /** @type {ol.geom.GeometryType} */ (type), // 几何图形类型
        style: new ol.style.Style({ // 绘制几何图形的样式
          fill: new ol.style.Fill({
            color: 'rgba(255, 255, 255, 0.2)'
          }),
          stroke: new ol.style.Stroke({
            color: 'rgba(0, 0, 0, 0.5)',
            lineDash: [10, 10],
            width: 2
          }),
          image: new ol.style.Circle({
            radius: 5,
            stroke: new ol.style.Stroke({
              color: 'rgba(0, 0, 0, 0.7)'
            }),
            fill: new ol.style.Fill({
              color: 'rgba(255, 255, 255, 0.2)'
            })
          })
        })
      })
      $rootComponent.addInteraction(this.originInstance, this.actived)
      this.createMeasureTooltip() // 创建测量工具提示框
      this.createHelpTooltip() // 创建帮助提示框
      var listener = null
      // 绑定交互绘制工具开始绘制的事件
      this.originInstance.on('drawstart', (evt) => {
        // set sketch
        this.sketch = evt.feature // 绘制的要素
        /** @type {ol.Coordinate|undefined} */
        var tooltipCoord = evt.coordinate // 绘制的坐标
        // 绑定change事件，根据绘制几何类型得到测量长度值或面积值，并将其设置到测量工具提示框中显示
        listener = this.sketch.getGeometry().on('change', (evt) => {
          var geom = evt.target // 绘制几何要素
          var output
          if (geom instanceof ol.geom.Polygon) {
            output = this.formatArea(/** @type {ol.geom.Polygon} */(geom)) // 面积值
            tooltipCoord = geom.getInteriorPoint().getCoordinates() // 坐标
          } else if (geom instanceof ol.geom.LineString) {
            output = this.formatLength(/** @type {ol.geom.LineString} */(geom)) // 长度值
            tooltipCoord = geom.getLastCoordinate() // 坐标
          }
          this.measureTooltipElement.innerHTML = output // 将测量值设置到测量工具提示框中显示
          this.measureTooltip.setPosition(tooltipCoord) // 设置测量工具提示框的显示位置
        })
      })
      // 绑定交互绘制工具结束绘制的事件
      this.originInstance.on('drawend', (evt) => {
        this.measureTooltipElement.className = 'tooltip tooltip-static' // 设置测量提示框的样式
        this.measureTooltip.setOffset([0, -7])
        this.sketch = null // 置空当前绘制的要素对象
        this.measureTooltipElement = null // 置空测量工具提示框对象
        this.createMeasureTooltip() // 重新创建一个测试工具提示框显示结果
        ol.Observable.unByKey(listener)
      })
    },
    createHelpTooltip () {
      const { ol, $rootComponent } = this
      if (this.helpTooltipElement) {
        this.helpTooltipElement.parentNode.removeChild(this.helpTooltipElement)
      }
      this.helpTooltipElement = document.createElement('div')
      this.helpTooltipElement.className = 'tooltip hidden'
      this.helpTooltip = new ol.Overlay({
        element: this.helpTooltipElement,
        offset: [15, 0],
        positioning: 'center-left'
      })
      $rootComponent.addOverlay(this.helpTooltip)
    },
    createMeasureTooltip () {
      const { ol, $rootComponent } = this
      if (this.measureTooltipElement) {
        this.measureTooltipElement.parentNode.removeChild(this.measureTooltipElement)
      }
      this.measureTooltipElement = document.createElement('div')
      this.measureTooltipElement.className = 'tooltip tooltip-measure'
      this.measureTooltip = new ol.Overlay({
        element: this.measureTooltipElement,
        offset: [0, -15],
        positioning: 'bottom-center'
      })
      $rootComponent.addOverlay(this.measureTooltip)
    },
    formatLength (line) {
      var coordinates = line.getCoordinates() // 解析线的坐标
      var length = 0
      const { ol, $rootComponent } = this
      var sourceProj = $rootComponent.getView().getProjection()
      // 通过遍历坐标计算两点之前距离，进而得到整条线的长度
      for (var i = 0, ii = coordinates.length - 1; i < ii; ++i) {
        var c1 = ol.proj.transform(coordinates[i], sourceProj, 'EPSG:4326')
        var c2 = ol.proj.transform(coordinates[i + 1], sourceProj, 'EPSG:4326')
        length += this.wgs84Sphere.haversineDistance(c1, c2)
      }
      var output = ''
      if (length > 100) {
        output = (Math.round(length / 1000 * 100) / 100) + ' ' + 'km' // 换算成KM单位
      } else {
        output = (Math.round(length * 100) / 100) + ' ' + 'm' // m为单位
      }
      return output // 返回线的长度
    },
    formatArea (polygon) {
      const { $rootComponent } = this
      var sourceProj = $rootComponent.getView().getProjection()
      var geom = /** @type {ol.geom.Polygon} */ (polygon.clone().transform(sourceProj, 'EPSG:4326'))
      var coordinates = geom.getLinearRing(0).getCoordinates() // 解析多边形的坐标值
      var area = Math.abs(this.wgs84Sphere.geodesicArea(coordinates))
      var output = ''
      if (area > 10000) {
        output = (Math.round(area / 1000000 * 100) / 100) + ' ' + 'km<sup>2</sup>'// 换算成KM单位
      } else {
        output = (Math.round(area * 100) / 100) + ' ' + 'm<sup>2</sup>'// m为单位
      }
      return output
    }
  }
}
</script>
 <style scoped>
.tooltip {
  position: relative;
  background: rgba(0, 0, 0, 0.5);
  border-radius: 4px;
  color: white;
  padding: 4px 8px;
  opacity: 0.7;
  white-space: nowrap;
}

.tooltip-measure {
  opacity: 1;
  font-weight: bold;
}

.tooltip-static {
  background-color: #ffcc33;
  color: black;
  border: 1px solid white;
}

.tooltip-measure:before,
.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: -7px;
  left: 50%;
}

.tooltip-static:before {
  border-top-color: #ffcc33;
}

.hidden {
  display: none!important
}
</style>
