cesium实现测距测面

以下内容参考  Cesium开发工具篇 | 04量测工具与调试面板 - 简书

https://github.com/ls870061011/cesium_training/blob/main/examples/3_4_1measure.html

并做了一些简单的修改

定义

let measureFeature_line = []
let measureFeature_polygon = []

测距测面清除代码如下 

measureLineSpace() {
      var handler = new Cesium.ScreenSpaceEventHandler(viewer.scene.canvas)
      // 取消双击事件-追踪该位置
      viewer.cesiumWidget.screenSpaceEventHandler.removeInputAction(
        Cesium.ScreenSpaceEventType.LEFT_DOUBLE_CLICK
      )

      handler = new Cesium.ScreenSpaceEventHandler(
        viewer.scene._imageryLayerCollection
      )
      var positions = []
      var poly = null
      var distance = 0
      var cartesian = null
      var floatingPoint

      handler.setInputAction(function (movement) {
        // cartesian = viewer.scene.pickPosition(movement.endPosition);
        const ray = viewer.camera.getPickRay(movement.endPosition)
        cartesian = viewer.scene.globe.pick(ray, viewer.scene)
        // cartesian = viewer.scene.camera.pickEllipsoid(movement.endPosition, viewer.scene.globe.ellipsoid);
        if (positions.length >= 2) {
          if (!Cesium.defined(poly)) {
            poly = new PolyLinePrimitive(positions)
          } else {
            positions.pop()
            // cartesian.y += (1 + Math.random());
            positions.push(cartesian)
          }
          distance = getSpaceDistance(positions)
        }
      }, Cesium.ScreenSpaceEventType.MOUSE_MOVE)

      handler.setInputAction(function (movement) {
        // cartesian = viewer.scene.camera.pickEllipsoid(movement.position, viewer.scene.globe.ellipsoid);
        // cartesian = viewer.scene.pickPosition(movement.position);
        const ray = viewer.camera.getPickRay(movement.position)
        cartesian = viewer.scene.globe.pick(ray, viewer.scene)
        if (positions.length == 0) {
          positions.push(cartesian.clone())
        }
        positions.push(cartesian)
        // 在三维场景中添加Label
        //   var cartographic = Cesium.Cartographic.fromCartesian(cartesian);
        var textDisance
        if (distance > 1000) {
          textDisance = (distance / 1000).toFixed(2) + 'km'
        } else {
          textDisance = distance + 'm'
        }
        
        floatingPoint = viewer.entities.add({
          name: '空间直线距离',
          // position: Cesium.Cartesian3.fromDegrees(cartographic.longitude / Math.PI * 180, cartographic.latitude / Math.PI * 180,cartographic.height),
          position: positions[positions.length - 1],
          point: {
            pixelSize: 5,
            color: Cesium.Color.WHITE,
            // outlineColor: new Cesium.Color(1, 0, 0, 1),
            outlineColor: Cesium.Color.DEEPSKYBLUE,
            outlineWidth: 3
          },
          label: {
            text: textDisance,
            font: '16px sans-serif',
            fillColor: Cesium.Color.DARKORANGE,
            // style: Cesium.LabelStyle.FILL_AND_OUTLINE,
            // outlineWidth: 2,
            verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
            pixelOffset: new Cesium.Cartesian2(20, -20)
          }
        })
        measureFeature_line.push(floatingPoint)
      }, Cesium.ScreenSpaceEventType.LEFT_CLICK)

      handler.setInputAction(function (movement) {
        handler.destroy() // 关闭事件句柄
        positions.pop() // 最后一个点无效
        // viewer.entities.remove(floatingPoint);
      }, Cesium.ScreenSpaceEventType.RIGHT_CLICK)

      var PolyLinePrimitive = (function () {
        function _(positions) {
          this.options = {
            name: '直线',
            polyline: {
              show: true,
              positions: [],
              material: new Cesium.Color(0, 124 / 255, 247 / 255, 1),
              // material: Cesium.Color.CHARTREUSE,
              width: 3,
              clampToGround: true
            }
          }
          this.positions = positions
          this._init()
        }

        _.prototype._init = function () {
          var _self = this
          var _update = function () {
            return _self.positions
          }
          // 实时更新polyline.positions
          this.options.polyline.positions = new Cesium.CallbackProperty(
            _update,
            false
          )
          const line = viewer.entities.add(this.options)
          measureFeature_line.push(line)
        }

        return _
      })()
      console.log(measureFeature_line, 'measureFeature_line')

      // 空间两点距离计算函数
      function getSpaceDistance(positions) {
        var distance = 0
        for (var i = 0; i < positions.length - 1; i++) {
          var point1cartographic = Cesium.Cartographic.fromCartesian(
            positions[i]
          )
          var point2cartographic = Cesium.Cartographic.fromCartesian(
            positions[i + 1]
          )
          /** 根据经纬度计算出距离**/
          var geodesic = new Cesium.EllipsoidGeodesic()
          geodesic.setEndPoints(point1cartographic, point2cartographic)
          var s = geodesic.surfaceDistance
          // console.log(Math.sqrt(Math.pow(distance, 2) + Math.pow(endheight, 2)));
          // 返回两点之间的距离
          s = Math.sqrt(
            Math.pow(s, 2) +
              Math.pow(point2cartographic.height - point1cartographic.height, 2)
          )
          distance = distance + s
        }
        return distance.toFixed(2)
      }
    },
    measureAreaSpace() {
      var handler = new Cesium.ScreenSpaceEventHandler(viewer.scene.canvas)
      // 取消双击事件-追踪该位置
      viewer.cesiumWidget.screenSpaceEventHandler.removeInputAction(
        Cesium.ScreenSpaceEventType.LEFT_DOUBLE_CLICK
      )
      // 鼠标事件
      handler = new Cesium.ScreenSpaceEventHandler(
        viewer.scene._imageryLayerCollection
      )
      var positions = []
      var tempPoints = []
      var polygon = null
      var cartesian = null
      var floatingPoint

      handler.setInputAction(function (movement) {
        const ray = viewer.camera.getPickRay(movement.endPosition)
        cartesian = viewer.scene.globe.pick(ray, viewer.scene)
        // cartesian = viewer.scene.camera.pickEllipsoid(movement.endPosition, viewer.scene.globe.ellipsoid);
        if (positions.length >= 2) {
          if (!Cesium.defined(polygon)) {
            polygon = new PolygonPrimitive(positions)
          } else {
            positions.pop()
            positions.push(cartesian)
          }
        }
      }, Cesium.ScreenSpaceEventType.MOUSE_MOVE)

      handler.setInputAction(function (movement) {
        const ray = viewer.camera.getPickRay(movement.position)
        cartesian = viewer.scene.globe.pick(ray, viewer.scene)
        // cartesian = viewer.scene.camera.pickEllipsoid(movement.position, viewer.scene.globe.ellipsoid);
        if (positions.length == 0) {
          positions.push(cartesian.clone())
        }
        // positions.pop();
        positions.push(cartesian)
        // 在三维场景中添加点
        var cartographic = Cesium.Cartographic.fromCartesian(
          positions[positions.length - 1]
        )
        var longitudeString = Cesium.Math.toDegrees(cartographic.longitude)
        var latitudeString = Cesium.Math.toDegrees(cartographic.latitude)
        var heightString = cartographic.height
        tempPoints.push({
          lon: longitudeString,
          lat: latitudeString,
          hei: heightString
        })
        floatingPoint = viewer.entities.add({
          name: '多边形面积',
          position: positions[positions.length - 1],
          point: {
            pixelSize: 5,
            color: Cesium.Color.WHITE,
            outlineColor: Cesium.Color.DEEPSKYBLUE,
            // outlineColor: new Cesium.Color(1, 0, 0, 1),
            // color: Cesium.Color.RED,
            // outlineColor: Cesium.Color.WHITE,
            outlineWidth: 3
            // pixelSize: 5,
            // color: Cesium.Color.RED,
            // outlineColor: Cesium.Color.WHITE,
            // outlineWidth: 2,
            // heightReference: Cesium.HeightReference.CLAMP_TO_GROUND
          }
        })
        measureFeature_polygon.push(floatingPoint)
      }, Cesium.ScreenSpaceEventType.LEFT_CLICK)

      handler.setInputAction(function (movement) {
        handler.destroy()
        positions.pop()
        debugger
        var polyCenter = Cesium.BoundingSphere.fromPoints(positions).center
        var textArea = getArea(tempPoints) + 'km²'
        const _label = viewer.entities.add({
          name: '多边形面积',
          position: polyCenter,
          // position: positions[positions.length - 1],
          label: {
            text: textArea,
            font: '16px sans-serif',
            // fillColor: new Cesium.Color(255 / 255, 99 / 255, 25 / 255, 1),
            fillColor: Cesium.Color.DARKORANGE,
            // style: Cesium.LabelStyle.FILL_AND_OUTLINE,
            // outlineWidth: 2,
            // verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
            // pixelOffset: new Cesium.Cartesian2(20, -40),
            heightReference: Cesium.HeightReference.CLAMP_TO_GROUND
          }
        })
        measureFeature_polygon.push(_label)
      }, Cesium.ScreenSpaceEventType.RIGHT_CLICK)

      var radiansPerDegree = Math.PI / 180.0 // 角度转化为弧度(rad)
      var degreesPerRadian = 180.0 / Math.PI // 弧度转化为角度

      // 计算多边形面积
      function getArea(points) {
        var res = 0
        // 拆分三角曲面
        for (var i = 0; i < points.length - 2; i++) {
          var j = (i + 1) % points.length
          var k = (i + 2) % points.length
          var totalAngle = Angle(points[i], points[j], points[k])

          var dis_temp1 = distance(positions[i], positions[j])
          var dis_temp2 = distance(positions[j], positions[k])
          res += dis_temp1 * dis_temp2 * Math.abs(Math.sin(totalAngle))
          console.log(res)
        }

        return (res / 1000000.0).toFixed(4)
      }

      /* 角度 */
      function Angle(p1, p2, p3) {
        var bearing21 = Bearing(p2, p1)
        var bearing23 = Bearing(p2, p3)
        var angle = bearing21 - bearing23
        if (angle < 0) {
          angle += 360
        }
        return angle
      }
      /* 方向 */
      function Bearing(from, to) {
        var lat1 = from.lat * radiansPerDegree
        var lon1 = from.lon * radiansPerDegree
        var lat2 = to.lat * radiansPerDegree
        var lon2 = to.lon * radiansPerDegree
        var angle = -Math.atan2(
          Math.sin(lon1 - lon2) * Math.cos(lat2),
          Math.cos(lat1) * Math.sin(lat2) -
            Math.sin(lat1) * Math.cos(lat2) * Math.cos(lon1 - lon2)
        )
        if (angle < 0) {
          angle += Math.PI * 2.0
        }
        angle = angle * degreesPerRadian // 角度
        return angle
      }

      var PolygonPrimitive = (function () {
        function _(positions) {
          this.options = {
            name: '多边形',
            polygon: {
              hierarchy: [],
              // perPositionHeight : true,
              material: new Cesium.Color(0, 124 / 255, 247 / 255, 0.5)
              // material: Cesium.Color.GREEN.withAlpha(0.5)
              // heightReference:20000
            }
          }

          this.hierarchy = { positions }
          this._init()
        }

        _.prototype._init = function () {
          var _self = this
          var _update = function () {
            return _self.hierarchy
          }
          // 实时更新polygon.hierarchy
          this.options.polygon.hierarchy = new Cesium.CallbackProperty(
            _update,
            false
          )
          const _polygon = viewer.entities.add(this.options)
          measureFeature_polygon.push(_polygon)
        }

        return _
      })()

      function distance(point1, point2) {
        var point1cartographic = Cesium.Cartographic.fromCartesian(point1)
        var point2cartographic = Cesium.Cartographic.fromCartesian(point2)
        /** 根据经纬度计算出距离**/
        var geodesic = new Cesium.EllipsoidGeodesic()
        geodesic.setEndPoints(point1cartographic, point2cartographic)
        var s = geodesic.surfaceDistance
        // console.log(Math.sqrt(Math.pow(distance, 2) + Math.pow(endheight, 2)));
        // 返回两点之间的距离
        s = Math.sqrt(
          Math.pow(s, 2) +
            Math.pow(point2cartographic.height - point1cartographic.height, 2)
        )
        return s
      }
    },
    clearMeasureFeature() {
      viewer.cesiumWidget.screenSpaceEventHandler.removeInputAction(Cesium.ScreenSpaceEventType.RIGHT_CLICK)
      viewer.cesiumWidget.screenSpaceEventHandler.removeInputAction(Cesium.ScreenSpaceEventType.LEFT_CLICK)
      viewer.cesiumWidget.screenSpaceEventHandler.removeInputAction(Cesium.ScreenSpaceEventType.MOUSE_MOVE)
      if (measureFeature_line.length) {
        measureFeature_line.forEach(item => {
          viewer.entities.remove(item)
        })
        measureFeature_line = []
      }
      if (measureFeature_polygon.length) {
        measureFeature_polygon.forEach(item => {
          viewer.entities.remove(item)
        })
        measureFeature_polygon = []
      }
    },

结果如下

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值