<template>
  <transition
    appear
    name="animate__animated animate__move"
    enter-active-class="animate__zoomIn"
    leave-active-class="animate__zoomOut"
  >
    <div class="widget-ExcavationAnalysis" v-Gpdrag>
      <div class="header">
        <div class="wrap">
          <div class="title">管道综合开挖分析</div>
          <span class="close">
            <i class="el-icon-close" @click="close()" />
          </span>
        </div>
      </div>
      <el-container>
        <el-header>
          <el-form :inline="true" :model="pipeInfo" size="mini">
            <el-form-item label="选择管段：">
              <el-input v-model="pipeInfo.pipe"></el-input>
            </el-form-item>
            <el-form-item>
              <el-button type="primary" @click="addRectClickEvent2()">选取</el-button>
            </el-form-item>
            <el-form-item label="开挖半径：">
              <el-input-number v-model="pipeInfo.radius" controls-position="right" :min="0" :max="10"></el-input-number>
            </el-form-item>
            <el-form-item>
              <span>米</span>
            </el-form-item>
            <el-form-item>
              <el-button type="primary" @click="analysisImpact()">分析</el-button>
              <el-button type="primary" @click="clear()">清除</el-button>
            </el-form-item>
          </el-form>
        </el-header>
        <el-container>
          <el-aside>
            <crossSectionChart :drawSectionInfo="drawSectionInfo" />
          </el-aside>
          <el-main>
            <detailsTable :detailsData="detailsData" @location="location($event)" v-if="detailsData.length > 0" />
          </el-main>
        </el-container>
      </el-container>
    </div>
  </transition>
</template>

<script lang="ts">
import _ from 'lodash'
import { Vue, Component, Prop, Watch } from 'vue-property-decorator'
import * as turf from '@turf/turf'
import { createTooltip, CesiumToSuperMap } from '@/utils/mapCommon/tools'
import PipeQueryHelper from '@/utils/mapCommon/PipeQueryHelper'
import PipeAnalysisTool from '@/utils/mapCommon/PipeAnalysisTool'
import crossSectionChart from './crossSectionChart.vue'
import Config from './config.json'
import detailsTable from './detailsTable.vue'
const Cesium = (window as any).Cesium
const SuperMap = (window as any).SuperMap
const queryUrl = 'http://221.182.8.141:8090/iserver/services/map-sxgk_yc/rest/maps/hnyy_geoquery'
const queryDataService = 'http://221.182.8.141:8090/iserver/services/data-sxgk_yc/rest/data'
//管道开挖综合分析
@Component({ name: 'ExcavationAnalysis', components: { crossSectionChart, detailsTable } })
export default class ExcavationAnalysis extends Vue {
  //地图参数
  viewer
  _primitiveCollection
  _selectPick //已选中的对象
  //
  maskLoading = null //加载遮罩
  config = Config
  //开挖参数
  pipeInfo = {
    pipe: '',
    radius: '3'
  }
  //服务地址
  apiUrls = {
    bjsmidfw: '',
    sjdt: '',
    sjfw: ''
  }
  handleFlag = null
  toolTip = null
  excavation = null
  _selectFeatures = []
  currentSelectPipe = null
  pcuniqueField = 'PIPE_ID'
  sjuniqueField = 'CODE'
  dicIds = {}
  dicNotIds = {}
  dicTotals = {}
  g_crossLinePoints = []
  layerOids = null //记录各图层要素的objectid
  g_queryIndex = 0
  g_crossResult = []
  g_crossInfos = []
  drawSectionInfo = {} //断面图表信息
  detailsData = []
  get AppX() {
    return this.$store.state.bigScreen.mapConfig
  }
  mounted() {
    if (!(window as any).viewer) return
    this.viewer = (window as any).viewer
    this.init()
  }
  init() {
    this.apiUrls.sjfw = this.AppX.gisResource.tiplayers.config['sjfw'].url
    this.apiUrls.bjsmidfw = this.AppX.gisResource.tiplayers.config['bjsmidfw'].url
    this.apiUrls.sjdt = this.AppX.gisResource.maps.config['sjdt'].url
  }
  //选取事件
  addRectClickEvent2() {
    this.viewer.enableCursorStyle = false
    this.viewer._element.style.cursor = ''
    this.clearObjs()
    this.toolTip = createTooltip(document.querySelector('#' + this.$store.state.bigScreen.mapContainerId))
    const handler = new Cesium.ScreenSpaceEventHandler(this.viewer.canvas)
    this.handleFlag = handler
    handler.setInputAction((e) => {
      const radius = 2
      const position = this.viewer.scene.pickPosition(e.position)
      const ellpise = new Cesium.Entity({
        position: position,
        ellipse: {
          semiMajorAxis: radius,
          semiMinorAxis: radius,
          material: Cesium.Color.ORANGERED,
          classificationType: Cesium.ClassificationType.TERRAIN
        }
      })
      const positions = PipeQueryHelper.converCesiumToSuperMapEllipse(ellpise)
      this.queryForPipeUnitInfoByPolygon(positions.positions)
    }, Cesium.ScreenSpaceEventType.LEFT_CLICK)
    handler.setInputAction((movement) => {
      this.toolTip.showAt(movement.endPosition, '<p>鼠标左键确定缓冲中心,右键单击取消</p>')
    }, Cesium.ScreenSpaceEventType.MOUSE_MOVE)
    handler.setInputAction(
      function (movement) {
        this.clearObjs()
      }.bind(this),
      Cesium.ScreenSpaceEventType.RIGHT_CLICK
    )
  }
  /**
   * 该方法用于空间查询数据服务
   * @param {Cesium.Cartesian3[]} positions 多边形顶点
   */
  queryForPipeUnitInfoByPolygon(positions) {
    const geometry = CesiumToSuperMap.convertPolygon(Cesium, SuperMap, { positions: positions })
    const layers = this.viewer.scene.layers
    const layerList = layers.layerQueue
    const pipeInfo = []
    const allPipe = PipeQueryHelper.pipe
    const filters = []
    layerList.forEach((item) => {
      if (!item.visible) return false
      const pipe = _.find(allPipe, (sjpipe) => {
        const isnode = sjpipe.geometryType === 'point' && sjpipe.WELL.indexOf(item.name) > -1
        const ispipe = sjpipe.geometryType === 'line' && item.name === sjpipe.name
        return (isnode || ispipe) && sjpipe.pipeType === 'SJ' && sjpipe.geometryType === 'line'
      })
      if (!pipe) return false
      let unipipeInfo = { dataset: null }
      if (pipe.geometryType === 'line') {
        unipipeInfo.dataset = pipe.origindataset
      } else if (pipe.geometryType === 'point' && pipe.WELL.indexOf(item.name) > -1) {
        unipipeInfo.dataset = pipe.origindataset
      }
      const isExsit = _.find(pipeInfo, (pipeItem) => {
        return pipeItem.dataset === unipipeInfo.dataset
      })
      if (!isExsit) {
        pipeInfo.push(unipipeInfo)
        const filter = unipipeInfo.dataset + '@' + pipe.datasource
        filters.push(filter)
      }
    })
    if (filters.length === 0) return
    const onComplete = function (geoResult) {
      if (geoResult.originResult.currentCount === 0) {
        this.$message('当前范围内无管网数据')
        return
      }
      if (this.handleFlag && !this.handleFlag.isDestroyed()) {
        this.handleFlag.destroy()
        this.handleFlag = null
      }
      this.flashMapService(geoResult.originResult.recordsets)
    }.bind(this)
    PipeQueryHelper.queryMapByGeometry({
      url: this.apiUrls.sjdt,
      datasetNames: filters,
      geometry: geometry,
      completed: onComplete.bind(this),
      failed: function (err) {
        console.log(err)
      }
    })
    if (!this._primitiveCollection) {
      this._primitiveCollection = new Cesium.PrimitiveCollection()
      this.viewer.scene.primitives.add(this._primitiveCollection)
    }
  }
  /**
   * 该方法用于添加二维管线高亮
   * @param records
   */
  flashMapService(records) {
    if (!records || records.length === 0) return
    if (!this._primitiveCollection) return
    const primtCol = this._primitiveCollection
    //保存feature属性信息
    const newFeatures = []
    records.forEach((record) => {
      record.features.forEach((feature) => {
        const obj = new Object()
        feature.fieldNames.forEach((fieldName, index) => {
          obj[fieldName] = feature.fieldValues[index]
        })
        obj['s3mlayername'] = record.datasetName.split('@')[0]
        newFeatures.push(obj)
      })
    })
    this._selectFeatures = newFeatures
    records.forEach((record) => {
      if (record.features.length == 0) return false
      record.features.forEach((feature) => {
        const geometry = feature.geometry.points
        const geotype = feature.geometry.type.toLowerCase().indexOf('line') > -1 ? 'LINE' : 'POINT'
        if (geotype === 'LINE') {
          const pointA = Cesium.Cartesian3.fromDegrees(geometry[0].x, geometry[0].y)
          const pointB = Cesium.Cartesian3.fromDegrees(geometry[1].x, geometry[1].y)
          primtCol.add(this.generaGroundPolyline([pointA, pointB], feature))
        }
      })
    })
    if (newFeatures.length === 1) {
      this.clearDrawEvent()
      this.markPipeLabel(newFeatures[0])
    } else {
      this.addPrimitiveHandler()
    }
  }
  addPrimitiveHandler() {
    if (this.toolTip) {
      this.toolTip.remove()
      this.toolTip = null
    }
    this.toolTip = createTooltip(document.querySelector('#' + this.$store.state.bigScreen.mapContainerId))
    const handler = new Cesium.ScreenSpaceEventHandler(this.viewer.canvas)
    this.handleFlag = handler
    const that = this
    const fields = this.config.fields
    handler.setInputAction(function (movement) {
      that.removeHightLight(that._selectPick)
      var pick = that.viewer.scene.pick(movement.position)
      if (pick) {
        that.pickHightLight(pick)
        const selecFeature = _.find(that._selectFeatures, (feature) => {
          return feature[fields.pbs] === pick.id
        })
        that.markPipeLabel(selecFeature)
      } else {
      }
    }, Cesium.ScreenSpaceEventType.LEFT_CLICK)
    handler.setInputAction(
      function (movement) {
        that.toolTip.showAt(movement.endPosition, '<p>当前范围内有多条管线，鼠标左键选中目标管线,右键单击取消</p>')
      }.bind(this),
      Cesium.ScreenSpaceEventType.MOUSE_MOVE
    )
    handler.setInputAction(
      function (movement) {
        that.clearObjs()
      }.bind(this),
      Cesium.ScreenSpaceEventType.RIGHT_CLICK
    )
  }
  //对象高亮
  pickHightLight(pick) {
    if (pick) {
      var attributes = pick.primitive.getGeometryInstanceAttributes(pick.id) //获取某个实例的属性集
      attributes.color = Cesium.ColorGeometryInstanceAttribute.toValue(Cesium.Color.fromBytes(255, 125, 0)) //设置其高亮
      this._selectPick = pick
    }
  }
  //清除对象高亮
  removeHightLight(pick) {
    if (pick) {
      var attributes = pick.primitive.getGeometryInstanceAttributes(pick.id) //获取某个实例的属性集
      attributes.color = Cesium.ColorGeometryInstanceAttribute.toValue(Cesium.Color.fromBytes(0, 255, 255, 100)) //设置其初始颜色
    }
  }
  //该方法用于生成贴地线图元
  generaGroundPolyline(positions, feature) {
    const fields = this.config.fields
    const id = feature.fieldValues[feature.fieldNames.indexOf(fields.id)]
    const code = feature.fieldValues[feature.fieldNames.indexOf(fields.pbs)]
    const pipeId = feature.fieldValues[feature.fieldNames.indexOf(fields.pipeID)]
    const instance = new Cesium.GeometryInstance({
      geometry: new Cesium.GroundPolylineGeometry({
        positions: positions,
        width: 15.0
      }),
      attributes: {
        color: new Cesium.ColorGeometryInstanceAttribute(0.0, 1.0, 1.0, 0.5)
      },
      id: code
    })
    const polyline = new Cesium.GroundPolylinePrimitive({
      geometryInstances: instance,
      appearance: new Cesium.PolylineColorAppearance(),
      classificationType: Cesium.ClassificationType.TERRAIN
    })
    polyline.custom = { id: id, pipeId: pipeId }
    return polyline
  }
  //标注图层
  markPipeLabel(feature) {
    if (feature) {
      this.currentSelectPipe = feature
      this.pipeInfo.pipe = feature[this.config.pipeStartName] + '-' + feature[this.config.pipeEndName]
    }
  }
  //分析
  analysisImpact() {
    const that = this
    const feature = this.currentSelectPipe
    const txtRi = this.pipeInfo.radius
    this.dicIds = {}
    this.dicNotIds = {}
    this.dicTotals = {}
    if (feature && Number(txtRi) > 0) {
      this.clearDrawEvent()
      var txtR = parseFloat(txtRi)
      var endHeight = parseFloat(feature[this.config.pipeEndHeight])
      var startHeight = parseFloat(feature[this.config.pipeStartHeight])

      var endLgtd = parseFloat(feature[this.config.latitude2])
      var endLttd = parseFloat(feature[this.config.longitude2])

      var startLgtd = parseFloat(feature[this.config.latitude])
      var startLttd = parseFloat(feature[this.config.longitude])
      var pointsList = []
      pointsList = [
        [startLttd, startLgtd],
        [endLttd, endLgtd]
      ]
      var pipe = turf.lineString(pointsList)
      var buffered = turf.buffer(pipe, txtR, { units: 'meters', steps: 16 })
      var pts = buffered.geometry.coordinates[0]
      var height = Math.min(startHeight, endHeight)
      let pipes = []
      var positions = []
      pts.forEach((item) => {
        let point = turf.toMercator(item)
        //转为世界坐标
        var ellipsoid = this.viewer.scene.globe.ellipsoid
        var cartographic = Cesium.Cartographic.fromDegrees(item[0], item[1], height)
        var cartesian3 = ellipsoid.cartographicToCartesian(cartographic)
        pipes.push(point)
        positions.push(cartesian3)
      })
      pts = pipes
      //管线坐标
      const crossLineFrom = Cesium.Cartesian3.fromDegrees(startLttd, startLgtd, startHeight)
      const crossLineTo = Cesium.Cartesian3.fromDegrees(endLttd, endLgtd, endHeight)
      this.g_crossLinePoints = [crossLineFrom, crossLineTo]
      if (positions.length >= 3) {
        let options = {
          name: '多边形',
          polygon: {
            hierarchy: positions,
            perPositionHeight: true,
            outline: true,
            outlineColor: Cesium.Color.RED,
            outlineWidth: 2,
            material: Cesium.Color.DARKSEAGREEN.withAlpha(0.3)
          }
        }
      }
      const geo = CesiumToSuperMap.convertPolygon(Cesium, SuperMap, { positions: positions })
      const linegeo = CesiumToSuperMap.convertPolyline(Cesium, SuperMap, { positions: this.g_crossLinePoints })
      this.queryPipesAnalysis(geo)
      //横断面分析
      this.query(linegeo)
      that.addTerrainRegion(positions, 1)
    } else {
      this.$message('请选取管线或设置参数！')
    }
  }
  //查询管线并分析
  queryPipesAnalysis(geo) {
    this.maskLoading = this.$loading({
      lock: true,
      text: '正在执行中，请耐心等待...',
      spinner: 'el-icon-loading',
      background: 'rgba(0, 0, 0, 0.7)'
    })
    const url = queryUrl
    const layers = this.viewer.scene.layers
    const pipes = PipeQueryHelper.pipe.filter((item) => {
      const layer = layers.find(item.name)
      return layer && layer.visible === true && item.geometryType === 'line'
    })
    const datasetName = pipes.map((item) => {
      return item.mapname
    })
    const completed = function (result) {
      var recordSets = result.result.recordsets
      this.onIdentifyFinished(recordSets)
    }
    const failed = function (error) {
      this.maskLoading.close()
      this.$message.error('查询数据失败!')
    }
    PipeQueryHelper.queryMapByGeometry({
      url: url,
      datasetNames: datasetName,
      geometry: geo,
      completed: completed.bind(this),
      failed: failed.bind(this)
    })
  }
  //根据区域将获取到的管线按照类型分类
  onIdentifyFinished(results) {
    var rlength = results.length
    var polylineTypes = []
    for (var i = 0; i < rlength; i++) {
      var pipeItem = results[i] //成果数据
      var layername = pipeItem.datasetName //图层名称
      const pipeType = _.find(PipeQueryHelper.pipe, (item) => {
        return item.mapname === layername
      })
      const uniqueField = pipeType.pipeType === 'SJ' ? this.config.sjuniqueField : this.config.pcuniqueField
      var features = pipeItem.features //管线信息集合
      if (layername !== undefined && features.length > 0) {
        polylineTypes.push({ layername: layername, features: features })
        for (var j = 0; j < features.length; j++) {
          var feature = features[j]
          this.dicIds[feature.attributes[uniqueField]] = { layername: layername, feature: feature, pipeType: pipeType }
        }
      }
    }
    this.impactAnalysis(polylineTypes) //执行碰撞分析
  }
  /**
   * 碰撞分析
   * @param polylineTypes 类型管线集合
   */
  impactAnalysis(polylineTypes) {
    var notStandards = []
    var totalAll = [],
      dicTotalAll = {}
    for (var i = 0, length = polylineTypes.length; i < length; i++) {
      var pipeTypeItem = polylineTypes[i]
      var EndAnalysis = {}
      var notStandardFeatures = []
      //判断是sj还是PC
      var slayername = pipeTypeItem.layername
      const sourcepipeType = _.find(PipeQueryHelper.pipe, (item) => {
        return item.mapname === slayername
      })
      const sourceuniqueField = sourcepipeType.pipeType === 'SJ' ? this.config.sjuniqueField : this.config.pcuniqueField

      EndAnalysis['layername'] = slayername

      var SourceFeatures = pipeTypeItem.features
      for (var fi = 0, flength = SourceFeatures.length; fi < flength; fi++) {
        var sfeature = SourceFeatures[fi]
        var sattributes = sfeature.attributes

        var compareAnalysiss = []
        var sdiameter = sattributes[this.config.analysisFields.DIAMETER]
        var soid = sattributes[sourceuniqueField]
        if (soid !== this.currentSelectPipe[sourceuniqueField]) {
          continue
        }

        var pipeId = sattributes[this.config.analysisFields.SID]
        var sourcegeometry = sfeature.geometry //图形
        var sstartid = sattributes[this.config.analysisFields.START_SID]
        var sendid = sattributes[this.config.analysisFields.END_SID]

        var sStart_Elevation = sattributes[this.config.pipeStartHeight]
        var sEnd_Elevation = sattributes[this.config.pipeEndHeight]

        for (var ci = 0, clength = polylineTypes.length; ci < clength; ci++) {
          var cpipeTypeItem = polylineTypes[ci]
          var compareAnalysis = {
            sourcelayername: slayername,
            sourceobjectid: '',
            sourcediameter: '',
            comparelayername: '',
            sourceobjectid_name: ''
          }
          var clayername = cpipeTypeItem.layername
          compareAnalysis['sourceobjectid'] = soid
          compareAnalysis['sourceobjectid_name'] = pipeId
          compareAnalysis['sourcediameter'] = sdiameter
          compareAnalysis['comparelayername'] = clayername

          const cpipeType = _.find(PipeQueryHelper.pipe, (item) => {
            return item.mapname === clayername
          })
          const cuniqueField = cpipeType.pipeType === 'SJ' ? this.config.sjuniqueField : this.config.pcuniqueField
          var OnlyCompareAnalysiss = []
          var CompareFeatures = cpipeTypeItem.features
          for (var cfi = 0, cflength = CompareFeatures.length; cfi < cflength; cfi++) {
            var cfeature = CompareFeatures[cfi]
            var cattributes = cfeature.attributes
            var comparegeometry = cfeature.geometry
            var OnlyCompareAnalysis = {}

            var cdiameter = cattributes[this.config.analysisFields.DIAMETER]
            var coid = cattributes[cuniqueField]
            var cpipeId = cattributes[this.config.analysisFields.SID]

            if (soid == coid && clayername == slayername) {
              continue
            }
            //过滤同类要素连接关系
            var cstartid = cattributes[this.config.analysisFields.START_SID]
            var cendid = cattributes[this.config.analysisFields.END_SID]
            if (
              (sstartid == cendid || sstartid == cstartid || sendid == cstartid || sendid == cendid) &&
              clayername == slayername
            ) {
              continue
            }
            OnlyCompareAnalysis['compareobjectid'] = coid
            OnlyCompareAnalysis['compareobjectid_name'] = cpipeId
            OnlyCompareAnalysis['comparediameter'] = cdiameter

            var cStart_Elevation = cattributes[this.config.pipeStartHeight]
            var cEnd_Elevation = cattributes[this.config.pipeEndHeight]

            var disjoint = PipeAnalysisTool.IsOrNotIntersect(sourcegeometry, comparegeometry)

            var hdistance = undefined,
              vdistance = undefined
            const lsDisjoint = this.IsOrNotIntersect(sourcegeometry, comparegeometry)
            if (!disjoint.iscross) {
              //交点不在线段上执行水平净距分析
              hdistance = PipeAnalysisTool.GetShortestDistance(sourcegeometry, comparegeometry, sdiameter, cdiameter) //水平净距
              OnlyCompareAnalysis['hdistance'] = hdistance.toFixed(3)
              OnlyCompareAnalysis['isCross'] = '否'
            } else {
              //相交
              OnlyCompareAnalysis['isCross'] = '是'
              OnlyCompareAnalysis['hdistance'] = 0
              hdistance = 0
            }

            if (disjoint.iscross) {
              //相交且交点在线段上执行垂直净距分析
              if (disjoint.crossPoint.x != 0 && disjoint.crossPoint.y != 0) {
                //获取对象在交点处的埋深
                const lonlat = this.getCrossPointAndHeight(
                  comparegeometry,
                  lsDisjoint.lerp,
                  cStart_Elevation,
                  cEnd_Elevation
                )
                const sourceLonlat = this.getCrossPointAndHeight(
                  sourcegeometry,
                  lsDisjoint.slerp,
                  sStart_Elevation,
                  sEnd_Elevation
                )
                vdistance = PipeAnalysisTool.GetShortestVDistance(
                  sourceLonlat.height,
                  lonlat.height,
                  sdiameter,
                  cdiameter
                )
                OnlyCompareAnalysis['vdistance'] = vdistance.toFixed(3)
                OnlyCompareAnalysis['x'] = Cesium.Math.toDegrees(lonlat.longitude).toFixed(2)
                OnlyCompareAnalysis['y'] = Cesium.Math.toDegrees(lonlat.latitude).toFixed(2)
                if (isNaN(cdiameter)) {
                  OnlyCompareAnalysis['elevation'] = lonlat.height.toFixed(2)
                  OnlyCompareAnalysis['bottomelevation'] = lonlat.height.toFixed(2)
                } else {
                  OnlyCompareAnalysis['elevation'] = (lonlat.height + parseFloat(cdiameter) / 2000).toFixed(2)
                  OnlyCompareAnalysis['bottomelevation'] = (lonlat.height - parseFloat(cdiameter) / 2000).toFixed(2)
                }
                const crossDepth = this.getCrossDepth(
                  lsDisjoint.lerp,
                  cattributes[this.config.pipeStartDepth],
                  cattributes[this.config.pipeEndDepth]
                )
                OnlyCompareAnalysis['depth'] = crossDepth.toFixed(2)
              }
            }
            if (!this.dicNotIds[soid + '$$' + coid] && !this.dicNotIds[coid + '$$' + soid]) {
              if (vdistance <= 0 && hdistance <= 0) {
                OnlyCompareAnalysis['isKnock'] = '是'

                OnlyCompareAnalysiss.push(OnlyCompareAnalysis)
                this.dicNotIds[soid + '$$' + coid] = 1
              } else if (hdistance <= 0 && (vdistance > 0 || vdistance === undefined)) {
                OnlyCompareAnalysis['isKnock'] = '否'
                OnlyCompareAnalysiss.push(OnlyCompareAnalysis)
                this.dicNotIds[soid + '$$' + coid] = 1
              } else if (vdistance <= 0 && hdistance > 0) {
                OnlyCompareAnalysis['isKnock'] = '否'
                OnlyCompareAnalysiss.push(OnlyCompareAnalysis)
                this.dicNotIds[soid + '$$' + coid] = 1
              } else if ((vdistance > 0 || vdistance === undefined) && hdistance > 0) {
                OnlyCompareAnalysis['isKnock'] = '否'
                OnlyCompareAnalysiss.push(OnlyCompareAnalysis)
                this.dicNotIds[soid + '$$' + coid] = 1
              }
            }
          }
          if (OnlyCompareAnalysiss.length > 0) {
            for (var ri = 0; ri < OnlyCompareAnalysiss.length; ri++) {
              var AnalysisReturn = {}

              //AnalysisReturn["sourcelayername"] = compareAnalysis.sourcelayername;
              //AnalysisReturn["sourceobjectid"] = compareAnalysis.sourceobjectid;
              //AnalysisReturn["sourceobjectid_name"] = compareAnalysis.sourceobjectid_name;
              //AnalysisReturn["sourcediameter"] = compareAnalysis.sourcediameter;
              //AnalysisReturn["order"]=ri+1;
              AnalysisReturn['comparelayername'] = compareAnalysis.comparelayername
              AnalysisReturn['compareobjectid'] = OnlyCompareAnalysiss[ri].compareobjectid
              AnalysisReturn['isCross'] = OnlyCompareAnalysiss[ri]['isCross']
              AnalysisReturn['isKnock'] = OnlyCompareAnalysiss[ri]['isKnock']
              AnalysisReturn['compareobjectid_name'] = OnlyCompareAnalysiss[ri].compareobjectid_name
              AnalysisReturn['comparediameter'] = OnlyCompareAnalysiss[ri].comparediameter
              AnalysisReturn['hdistance'] = OnlyCompareAnalysiss[ri].hdistance
              AnalysisReturn['vdistance'] = OnlyCompareAnalysiss[ri].vdistance
              AnalysisReturn['x'] = OnlyCompareAnalysiss[ri].x
              AnalysisReturn['y'] = OnlyCompareAnalysiss[ri].y
              AnalysisReturn['elevation'] = OnlyCompareAnalysiss[ri].elevation
              AnalysisReturn['bottomelevation'] = OnlyCompareAnalysiss[ri].bottomelevation
              AnalysisReturn['depth'] = OnlyCompareAnalysiss[ri]['depth']
              //AnalysisReturn["remarks"] = OnlyCompareAnalysiss[ri].remarks;
              compareAnalysiss.push(AnalysisReturn)
              var slyn = AnalysisReturn['sourcelayername'],
                clyn = AnalysisReturn['comparelayername']
              var stdicstr = slyn + '$$' + AnalysisReturn['sourceobjectid'],
                etdicstr = clyn + '$$' + AnalysisReturn['compareobjectid']
              if (!dicTotalAll.hasOwnProperty(slyn)) {
                dicTotalAll[slyn] = 0
              }
              if (!dicTotalAll.hasOwnProperty(clyn)) {
                dicTotalAll[clyn] = 0
              }
              if (totalAll.indexOf(stdicstr) == -1) {
                totalAll.push(stdicstr)
                dicTotalAll[slyn]++
              }

              if (totalAll.indexOf(etdicstr) == -1) {
                totalAll.push(etdicstr)
                dicTotalAll[clyn]++
              }
            }
          }
        }
        if (compareAnalysiss.length > 0) {
          notStandardFeatures.push(compareAnalysiss)
        }
      }
      if (notStandardFeatures.length > 0) {
        EndAnalysis['notStandards'] = notStandardFeatures
        notStandards.push(EndAnalysis)
      }
    }
    this.layerOids = notStandards
    this.dicTotals = dicTotalAll
    this.maskLoading.close()
    if (notStandards.length > 0) {
      this.showDetailInfos() //表格显示
    } else {
      this.showDetailInfos()
      this.$message('区域内管线均不碰撞')
    }
  }
  //相交判断
  IsOrNotIntersect(sourcegeometry, comparegeometry) {
    const sFrompoint = Cesium.Cartesian3.fromDegrees(sourcegeometry.components[0].x, sourcegeometry.components[0].y, 0)
    const sTopoint = Cesium.Cartesian3.fromDegrees(sourcegeometry.components[1].x, sourcegeometry.components[1].y, 0)
    const cFromPoint = Cesium.Cartesian3.fromDegrees(
      comparegeometry.components[0].x,
      comparegeometry.components[0].y,
      0
    )

    const cToPoint = Cesium.Cartesian3.fromDegrees(comparegeometry.components[1].x, comparegeometry.components[1].y, 0)

    const sFrompoint2 = Cesium.Cartesian2.fromCartesian3(sFrompoint)
    const sTopoint2 = Cesium.Cartesian2.fromCartesian3(sTopoint)
    const cFromPoint2 = Cesium.Cartesian2.fromCartesian3(cFromPoint)
    const cToPoint2 = Cesium.Cartesian2.fromCartesian3(cToPoint)

    const crossPoint = Cesium.Intersections2D.computeLineSegmentLineSegmentIntersection(
      sFrompoint2.x,
      sFrompoint2.y,
      sTopoint2.x,
      sTopoint2.y,
      cFromPoint2.x,
      cFromPoint2.y,
      cToPoint2.x,
      cToPoint2.y
    )
    if (!crossPoint) {
      return {
        iscross: false
      }
    }
    const t = Cesium.Cartesian2.distance(cFromPoint2, crossPoint) / Cesium.Cartesian2.distance(cFromPoint2, cToPoint2)
    const st = Cesium.Cartesian2.distance(sFrompoint2, crossPoint) / Cesium.Cartesian2.distance(sFrompoint2, sTopoint2)
    const interop = Cesium.Cartesian3.lerp(cFromPoint, cToPoint, t, new Cesium.Cartesian3())
    return {
      iscross: true,
      crossPoint: interop,
      lerp: t,
      slerp: st
    }
  }
  //该方法用于计算交点处的埋深
  getCrossDepth(lerp, inDeep, outDeep) {
    const t = lerp
    const depth = parseFloat(inDeep) + t * (parseFloat(outDeep) - parseFloat(inDeep))
    return depth
  }
  /**
   * 计算交点坐标和管顶高程
   * @param geometry
   * @param lerp
   * @param inDeep
   * @param outDeep
   */
  getCrossPointAndHeight(geometry, lerp, inHeight, outHeight) {
    inHeight = parseFloat(inHeight)
    outHeight = parseFloat(outHeight)
    const sourcePoint1 = geometry.components[0]
    const sourcePoint2 = geometry.components[1]
    const fromPoint = Cesium.Cartesian3.fromDegrees(sourcePoint1.x, sourcePoint1.y, inHeight)
    const toPoint = Cesium.Cartesian3.fromDegrees(sourcePoint2.x, sourcePoint2.y, outHeight)
    const t = lerp
    const cross3D = Cesium.Cartesian3.lerp(fromPoint, toPoint, t, new Cesium.Cartesian3())
    const lonlat = Cesium.Cartographic.fromCartesian(cross3D)
    return lonlat
  }
  //显示详细信息
  showDetailInfos() {
    var result = this.layerOids
    var datas = []
    for (var ri = 0, rlength = result.length; ri < rlength; ri++) {
      var data = result[ri].notStandards
      for (var ni = 0; ni < data.length; ni++) {
        var notStandards = data[ni]
        for (var i = 0; i < notStandards.length; i++) {
          var info = notStandards[i]
          const clayerName = _.find(PipeQueryHelper.pipe, (item) => {
            return info['comparelayername'] === item.mapname
          })
          // info["compareobjectid"] = notStandards[i].compareobjectid;
          info['order'] = datas.length + 1
          info['comparelayername'] = info['comparelayername'] ? clayerName.title : ''
          info['isCross'] = info['isCross'] === '是' ? info['isCross'] : info['isCross']
          info['isKnock'] = info['isKnock'] === '是' ? info['isKnock'] : info['isKnock']
          info['vdistance'] = info['vdistance'] != undefined ? info['vdistance'] : ''
          info['hdistance'] = info['hdistance'] != undefined ? info['hdistance'] : ''
          info['x'] = info['x'] != undefined ? info['x'] : ''
          info['y'] = info['y'] != undefined ? info['y'] : ''
          info['depth'] = info['depth'] != undefined ? info['depth'] : ''
          info['elevation'] = info['elevation'] != undefined ? info['elevation'] : ''
          info['bottomelevation'] = info['bottomelevation'] != undefined ? info['bottomelevation'] : ''
          info['comparediameter'] = info['comparediameter']
            ? PipeAnalysisTool.FixedDiameter(info['comparediameter'])
            : ''
          info['matreial'] = info['matreial'] != undefined ? info['matreial'] : ''
          datas.push(info)
        }
      }
    }
    this.detailsData = datas
  }
  location(sid) {
    if (!sid || sid.trim() === '') {
      this.$message('部件唯一标识不存在，请检查数据')
      return
    }
    var featureinfo = this.dicIds[sid]
    if (featureinfo) {
      const datasetName = _.find(PipeQueryHelper.pipe, (item) => {
        return item.mapname === featureinfo.layername
      })
      PipeQueryHelper.location(this.viewer, featureinfo.feature, 'line', datasetName)
    }
  }
  /**
   * 横断面分析查询
   * @param queryType
   */
  query(geometry) {
    const url = queryUrl
    const layers = this.viewer.scene.layers
    const pipes = PipeQueryHelper.pipe.filter((item) => {
      const layer = layers.find(item.name)
      return layer && layer.visible === true && item.geometryType === 'line'
    })
    const datasetName = pipes.map((item) => {
      return item.mapname
    })
    const gl = this
    const completed = function (result) {
      const crossInfo = gl.drawPolyline(result.originResult.recordsets)
      gl.queryForHeight(crossInfo)
    }
    const failed = function (error) {
      console.error(error)
    }
    PipeQueryHelper.queryMapByGeometry({
      url: url,
      datasetNames: datasetName,
      queryOption: SuperMap.REST.QueryOption.ATTRIBUTEANDGEOMETRY,
      spatialMode: SuperMap.REST.SpatialQueryMode.CROSS,
      geometry: geometry,
      completed: completed.bind(this),
      failed: failed.bind(this)
    })
  }
  /**
   * 计算横截线与二维管线的交点
   * @param recordsets
   */
  drawPolyline(recordsets) {
    const crossPoints = this.g_crossLinePoints
    const cartesian2Points = crossPoints.map((point) => {
      const carto = Cesium.Cartographic.fromCartesian(point)
      const ii = Cesium.Cartographic.fromRadians(carto.longitude, carto.latitude, 0)
      return Cesium.Cartesian2.fromCartesian3(Cesium.Cartographic.toCartesian(ii))
    })
    if (!recordsets) return
    let crossInfo = []
    recordsets.forEach((recordset) => {
      const features = recordset.features
      features.forEach((feature) => {
        const points = feature.geometry.points
        const positions = points.map((point) => {
          const geo84 = Cesium.Cartesian3.fromDegrees(point.x, point.y, 0)
          return geo84
        })
        const linePoints = positions.map((position) => {
          return Cesium.Cartesian2.fromCartesian3(position)
        })
        const crossPoint = Cesium.Intersections2D.computeLineSegmentLineSegmentIntersection(
          cartesian2Points[0].x,
          cartesian2Points[0].y,
          cartesian2Points[1].x,
          cartesian2Points[1].y,
          linePoints[0].x,
          linePoints[0].y,
          linePoints[1].x,
          linePoints[1].y
        )
        const t =
          Cesium.Cartesian2.distance(linePoints[0], crossPoint) /
          Cesium.Cartesian2.distance(linePoints[0], linePoints[1])
        const interop = Cesium.Cartesian3.lerp(positions[0], positions[1], t, new Cesium.Cartesian3())
        crossInfo.push({ mapname: recordset.datasetName, feature: feature, crossPoint: interop, t: t })
      })
    })
    return crossInfo
  }
  queryForHeight(crossInfos) {
    this.g_queryIndex = 0
    this.g_crossResult = []
    this.g_crossInfos = crossInfos
    this.queryFeatureForHeight(crossInfos[this.g_queryIndex])
  }
  queryFeatureForHeight(crossInfo) {
    //无相交管线
    if (!crossInfo) {
      this.drawSectionPicture()
      return
    }
    const pipe = PipeQueryHelper.pipe.find((pipe) => {
      return pipe.mapname === crossInfo.mapname
    })
    const queryField = pipe.pipeType === 'SJ' ? this.sjuniqueField : this.pcuniqueField
    const resultFields = pipe.pipeType === 'SJ' ? this.config.sjFields : this.config.pcFields
    if (!pipe) {
      return
    }
    const completed = (result) => {
      if (result.originResult.features.length === 0) {
        return
      }
      const feature = result.originResult.features[0]
      const fromPoint = Cesium.Cartesian3.fromDegrees(
        feature.geometry.points[0].x,
        feature.geometry.points[0].y,
        parseFloat(feature.fieldValues[feature.fieldNames.indexOf(this.config.pipeStartHeight)])
      )
      const toPoint = Cesium.Cartesian3.fromDegrees(
        feature.geometry.points[1].x,
        feature.geometry.points[1].y,
        parseFloat(feature.fieldValues[feature.fieldNames.indexOf(this.config.pipeEndHeight)])
      )
      const points = [fromPoint, toPoint]
      const ThreeDPoint = Cesium.Cartesian3.lerp(points[0], points[1], crossInfo.t, new Cesium.Cartesian3())
      //点积求投影长度
      const fcross = Cesium.Cartographic.fromCartesian(this.g_crossLinePoints[0])
      const lcross = Cesium.Cartographic.fromCartesian(this.g_crossLinePoints[1])
      const newLcross = Cesium.Cartographic.fromRadians(lcross.longitude, lcross.latitude, fcross.height)
      const vectora = Cesium.Cartesian3.subtract(
        Cesium.Cartographic.toCartesian(newLcross),
        Cesium.Cartographic.toCartesian(fcross),
        new Cesium.Cartesian3()
      )
      const vectorb = Cesium.Cartesian3.subtract(ThreeDPoint, this.g_crossLinePoints[0], new Cesium.Cartesian3())
      const projectDistance = Cesium.Cartesian3.dot(vectora, vectorb) / Cesium.Cartesian3.magnitude(vectora)

      const depth =
        parseFloat(feature.fieldValues[feature.fieldNames.indexOf(resultFields.inDeep)]) +
        crossInfo.t *
          (parseFloat(feature.fieldValues[feature.fieldNames.indexOf(resultFields.outDeep)]) -
            parseFloat(feature.fieldValues[feature.fieldNames.indexOf(resultFields.inDeep)]))
      const height = Cesium.Cartographic.fromCartesian(ThreeDPoint).height
      const roadHeight = depth + height
      const diameter = feature.fieldValues[feature.fieldNames.indexOf(resultFields.diameter)]

      let pipeDiameter = 10
      let diameterType = 'circle'
      if (diameter.indexOf('*') !== -1) {
        pipeDiameter = parseFloat(diameter.split('*')[0])
        diameterType = 'rect'
      } else if (diameter.indexOf('#') !== -1) {
        pipeDiameter = parseFloat(diameter.split('#')[0])
        diameterType = 'rect'
      } else if (diameter.indexOf('X') !== -1) {
        pipeDiameter = parseFloat(diameter.split('#')[0])
        diameterType = 'rect'
      } else if (!isNaN(parseFloat(diameter))) {
        pipeDiameter = parseFloat(diameter)
      }
      this.g_crossResult.push({
        mapname: crossInfo.mapname, //地图图层名称
        title: pipe.title, //管线名称
        feature: feature, //管线要素
        position: ThreeDPoint, //交点位置
        distance: Math.abs(projectDistance), //与起点的距离
        diameter: pipeDiameter, //管径
        diameterStr: diameter, //管线管径
        pipeType: pipe.pipeType, //管线大类
        lineColor: pipe.lineColor, //管线颜色
        diameterType: diameterType, //管径类型
        height: roadHeight, //地面高程
        depth: depth //埋深
      })
      ++this.g_queryIndex
      if (this.g_queryIndex === this.g_crossInfos.length) {
        this.drawSectionPicture()
        return
      }
      this.queryFeatureForHeight(this.g_crossInfos[this.g_queryIndex])
    }
    const failed = (error) => {
      console.log(error)
    }
    const SID = crossInfo.feature.fieldValues[crossInfo.feature.fieldNames.indexOf(queryField)]
    PipeQueryHelper.queryByAttribute({
      url: queryDataService,
      datasetNames: [pipe.datasource + ':' + pipe.origindataset],
      whereclause: queryField + "='" + SID + "'",
      fields: [],
      completed: completed.bind(this),
      failed: failed.bind(this)
    })
  }
  //触发断面图表数据更新
  drawSectionPicture() {
    let crossResult = this.g_crossResult
    let SelectPipe = this.currentSelectPipe
    let crossLinePoints = this.g_crossLinePoints
    this.drawSectionInfo = {
      crossResult: crossResult,
      SelectPipe: SelectPipe,
      crossLinePoints: crossLinePoints
    }
  }
  //地形开挖
  addTerrainRegion(posittions, height) {
    const that = this
    const points = []
    posittions.forEach((position) => {
      const lonlat = Cesium.Cartographic.fromCartesian(position)
      const longitude = Cesium.Math.toDegrees(lonlat.longitude)
      const latitude = Cesium.Math.toDegrees(lonlat.latitude)
      points.push(longitude)
      points.push(latitude)
      points.push(lonlat.height)
    })
    this.excavation = this.viewer.scene.globe.addExcavationRegion({
      name: '挖方点',
      position: points,
      height: height,
      transparent: false
    })
    this.clearPrimitives()
  }
  //清除绘制对象
  clearDrawEvent() {
    if (this.toolTip) {
      this.toolTip.remove()
      this.toolTip = null
    }
    if (this.handleFlag && !this.handleFlag.isDestroyed()) {
      this.handleFlag.destroy()
      this.handleFlag = null
    }
  }
  //清除开挖地形
  removeTerrainRegion() {
    if (this.excavation) {
      this.viewer.scene.globe.removeAllExcavationRegion()
      this.excavation = null
    }
  }
  //清除管段高亮
  clearPrimitives() {
    if (this._primitiveCollection) {
      this._primitiveCollection.removeAll()
      const isDel = this.viewer.scene.primitives.remove(this._primitiveCollection)
      if (isDel) this._primitiveCollection = null
    }
    this._selectPick = null
  }
  //清除临时对象
  clearObjs() {
    if (this.toolTip) {
      this.toolTip.remove()
      this.toolTip = null
    }
    this.viewer.enableCursorStyle = true
    if (this.handleFlag && !this.handleFlag.isDestroyed()) {
      this.handleFlag.destroy()
      this.handleFlag = null
    }
    this.removeTerrainRegion()
    this.clearPrimitives()
  }
  //清除分析操作
  clear() {
    this.clearObjs()
    this.viewer.entities.removeAll()
    //初始化data
    this.pipeInfo = {
      pipe: '',
      radius: '3'
    }
    this.drawSectionInfo = {} //断面图表信息
    this.detailsData = []
    this.init()
  }
  destroyed() {
    this.clear()
  }
  close() {
    this.$store.state.bigScreen.isShowExcavationAnalysis = false
  }
}
</script>

<style lang='scss' scoped>
.animate__zoomIn,
.animate__zoomOut {
  animation-duration: 1s; //动画持续时间
  animation-delay: 0s; //动画延迟时间
}
.widget-ExcavationAnalysis {
  bottom: 0.052083rem /* 10/192 */;
  left: calc(50% - 2.734375rem /* 525/192 */);
  width: 5.46875rem /* 1050/192 */;
  height: 1.5625rem /* 300/192 */;
  position: absolute;
  font-family: Source Han Sans CN;
  z-index: 999;
  //
  background: rgba(0, 60, 98, 0.7);
  border-radius: 4px;
  .header {
    padding: 0.026042rem /* 5/192 */;
    background: #0ea7ff;
    .wrap {
      width: 100%;
      display: flex;
      justify-content: space-between;
      padding: 0.026042rem /* 5/192 */;
      background: rgba(6, 13, 25, 1);
      box-shadow: 0 0 8px 5px #060d19;
      border-radius: 2px;
      .title {
        font-size: 0.072917rem /* 14/192 */;
        font-family: Source Han Sans CN-HEAVY;
        font-weight: bold;
        color: #0ea7ff;
        background: linear-gradient(0deg, #a3d3ff 0%, #e4f3ff 100%);
        background-clip: text;
        -webkit-text-fill-color: transparent;
      }
      .close {
        position: absolute;
        // top: 0.052083rem /* 10/192 */;
        right: 0.052083rem /* 10/192 */;
        color: #a3d3ff;
        font-size: 0.083333rem /* 16/192 */;
        z-index: 10;
        cursor: pointer;
      }
    }
  }
  .el-header {
    height: fit-content !important;
    padding: 5px 10px;
    margin-bottom: 5px;
    font-size: 0.072917rem /* 14/192 */;
    color: #2ba7ff;
    .el-form-item {
      margin-bottom: 0;
      /deep/ .el-form-item__label {
        font-size: 0.072917rem /* 14/192 */;
        color: #2ba7ff;
      }
      /deep/ .el-form-item__content {
        .el-input__inner {
          color: #eee;
          background-color: #08446c;
          border: none;
        }
      }
    }
  }
  .el-container {
    height: calc(100% - 0.197917rem /* 38/192 */);
  }
  .el-aside {
    flex: 0.4;
  }
  .el-main {
    flex: 0.6;
    padding: 0 !important;
    height: 100%;
  }
}
</style>