core/analysis/Path.js

import { Cesium } from '../../../namespace'
import { seconds2HMS } from '../../utils/Generate'

/**
 * 路径规划类
 * @class
 */
class Path {
  /**
   * 构造函数
   * @param {Viewer} viewer 地图场景对象
   * @param {PathGD} path {@link drivingByGd}drivingByGd路径导航的产物
   * @param {Boolean} [label=false] 是否进行文字标注
   */
  constructor(viewer, path, label = false) {
    this._viewer = viewer
    this._path = path
    this.init(label)
  }
  init(label) {
    if (!this._path) return
    this._tmcs = []
    const steps = this._path.steps
    for (let index = 0; index < steps.length; index++) {
      const step = steps[index]
      step.tmcs && step.tmcs.length > 0 && this._tmcs.push(...step.tmcs)
    }
    this.createPathLine(this._tmcs, label)
  }
  /**
   * 是否显示
   * @type {Boolean}
   */
  set show(bool) {
    if (this._pathPrimitive) {
      this._pathPrimitive.show = bool
    }
    if (this._labelEntity) {
      this._labelEntity.show = bool
    }
  }
  createPathLine(tmcs, label) {
    const types = {
      未知: Cesium.Color.LIGHTGREEN,
      畅通: Cesium.Color.LAWNGREEN,
      缓行: Cesium.Color.YELLOW,
      拥堵: Cesium.Color.ORANGE,
      严重拥堵: Cesium.Color.RED,
    }

    let instances = []
    let positions = []
    let status
    for (let index = 0; index < tmcs.length; index++) {
      const tmc = tmcs[index]
      const { tmc_polyline, tmc_status } = tmc
      const pos0 = tmc_polyline[0]
      if (status != tmc_status) {
        positions.length > 0 && createInstance(positions)
        positions = []
        status = tmc_status
        positions.push(pos0.lng, pos0.lat)
      }
      for (let i = 1; i < tmc_polyline.length; i++) {
        const pos = tmc_polyline[i]
        positions.push(pos.lng, pos.lat)
      }
      index === tmcs.length - 1 && createInstance(positions)
      label &&
        index === Math.floor(tmcs.length / 2) &&
        this.createLabel(positions)
    }
    this._pathPrimitive = this._viewer.scene.groundPrimitives.add(
      new Cesium.GroundPolylinePrimitive({
        geometryInstances: instances,
        appearance: new Cesium.PolylineColorAppearance(),
      })
    )
    function createInstance(points) {
      const instance2 = new Cesium.GeometryInstance({
        geometry: new Cesium.GroundPolylineGeometry({
          positions: Cesium.Cartesian3.fromDegreesArray(points),
          width: 4.0,
        }),
        attributes: {
          color: Cesium.ColorGeometryInstanceAttribute.fromColor(
            types[status] || Cesium.Color.WHITE
          ),
        },
      })
      instances.push(instance2)
    }
  }
  createLabel(positions) {
    const index = positions.length / 2
    const lng = index % 2 > 0 ? positions[index - 1] : positions[index]
    const lat = index % 2 > 0 ? positions[index] : positions[index + 1]

    let { distance, duration } = this._path
    const dis =
      distance < 1000 ? distance + 'm' : (distance / 1000).toFixed(2) + 'km'
    const time = seconds2HMS(duration)
    const pos = Cesium.Cartesian3.fromDegrees(lng, lat)
    const text = `总距离:${dis}\n总用时:${time}`
    this._labelEntity = this._viewer.entities.add({
      position: pos,
      label: {
        show: true,
        text: text,
        color: Cesium.Color.fromCssColorString('#fff'),
        font: 'normal 32px MicroSoft YaHei',
        backgroundColor: Cesium.Color.fromCssColorString('#000'),
        showBackground: true,
        backgroundPadding: new Cesium.Cartesian2(7, 20),
        scale: 0.5,
        distanceDisplayCondition: new Cesium.DistanceDisplayCondition(
          300,
          50000
        ),
        verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
        scaleByDistance: new Cesium.NearFarScalar(300, 1.5, 50000, 0.2),
        heightReference: Cesium.HeightReference.CLAMP_TO_GROUND,
      },
    })
  }
  /**
   * 注销对象
   */
  destroy() {
    this._pathPrimitive &&
      this._viewer.scene.groundPrimitives.remove(this._pathPrimitive)
    this._pathPrimitive = undefined
    this._labelEntity && this._viewer.entities.remove(this._labelEntity)
    this._labelEntity = undefined
    this._path = this._tmcs = this._viewer = undefined
  }
}

export default Path