Cesium开发学习笔记(六)续---动态测距显示距离

测距实现总结

开发过程中,有一个需求是测距实时让文本居中显示。参考cesium的API总结如下代码实现测距显示距离。
文本API
动态绘制API
在编写的时候,需要理解的是CallbackProperty这个回调函数,建议去看看api文档或技术网站文章对它有个大概认识。在集成两个API代码遇到最大的问题就是销毁模型问题。大概率就是我这边个人原因,经常报错,经过多次调试,发现是自己通过常用的移除并不能移除模型所导致的。当一个模型被销毁时,该回调函数也跟着销毁。如果销毁模型失败,建议使用removeById去销毁。

/*
@activeShape 动态线
@floatingPoint 点模型
@startPog 开始点坐标 用于计算距离
@labels  动态文本模型
*/
var activeShapePoints = [];
      var activeShape;
      var floatingPoint;
      let startPog;
      var scratch = new Cesium.Cartographic();
      var geodesic = new Cesium.EllipsoidGeodesic();
      let isConstant = false;
      var labels;

      //创建点
      function createP(worldPosition) {
        var point = viewer.entities.add({
          position: worldPosition,
          point: {
            color: Cesium.Color.WHITE,
            pixelSize: 5,
            heightReference: Cesium.HeightReference.CLAMP_TO_GROUND,
          },
        });
        return point;
      }

      //划线
      function drawShape(positionData) {
        var shape;

        shape = viewer.entities.add({
          polyline: {
            positions: positionData,
            clampToGround: true,
            width: 3,
          },
        });
        return shape;
      }


      // 动态获取距离
      function getLength(time, result) {
        // Get the end position from the polyLine's callback.
        let endPog = Cesium.Cartographic.fromCartesian(activeShapePoints[1]);
        geodesic.setEndPoints(startPog, endPog);
        var lengthInMeters = Math.round(geodesic.surfaceDistance);

        console.log('持续触发中')
        return (lengthInMeters / 1000).toFixed(1) + " km";
      }

      // 动态取中间值
      function getMidpoint(time, result) {
        // Get the end position from the polyLine's callback.

        let endPog = Cesium.Cartographic.fromCartesian(activeShapePoints[1]);

        geodesic.setEndPoints(startPog, endPog);
        var midpointCartographic = geodesic.interpolateUsingFraction(
          0.5,
          scratch
        );

        return Cesium.Cartesian3.fromRadians(
          midpointCartographic.longitude,
          midpointCartographic.latitude
        );
      }

      // 添加文本显示文字
      function addlabel() {
        var text;
        text = viewer.entities.add({
          // id: '距离文本',
          position: new Cesium.CallbackProperty(getMidpoint, isConstant),
          label: {
            // This callback updates the length to print each frame.
            text: new Cesium.CallbackProperty(getLength, isConstant),
            font: "20px sans-serif",
            pixelOffset: new Cesium.Cartesian2(0.0, 20),
          },
        });
        return text;
      }
      // 固定文本
      function bindlabel() {
        var text;
          text = viewer.entities.add({
          // id: '距离文本2',
          position: getMidpoint(),
          label: {
            // This callback updates the length to print each frame.
            text: getLength(),
            font: "20px sans-serif",
            pixelOffset: new Cesium.Cartesian2(0.0, 20),
          },
        });
        return text;
      }

      // 鼠标左键
      var handler = new Cesium.ScreenSpaceEventHandler(viewer.scene.canvas);
      handler.setInputAction(function (movement) {
      	//pickPosition 不能没有很好的随鼠标的移动
        // var earthPosition = viewer.scene.pickPosition(movement.position);
        var earthPosition = viewer.camera.pickEllipsoid(movement.position, viewer.scene.globe.ellipsoid);

        if (Cesium.defined(earthPosition)) {
          if (activeShapePoints.length === 0) {  // 数组为0时,创建起点
            floatingPoint = createP(earthPosition);
            activeShapePoints.push(earthPosition);
            // 设置起始点
            startPog = Cesium.Cartographic.fromCartesian(activeShapePoints[0]);
            // 构建回调函数点
            var dynamicPositions = new Cesium.CallbackProperty(function () {

              return activeShapePoints;
            }, false);
            // 创建动态文本
            labels = addlabel();
            // 创建动态线条
            activeShape = drawShape(dynamicPositions);
          }

          // 点击固定文本
          if (activeShapePoints.length >= 2) {
            activeShapePoints.push(earthPosition);
            terminateShape();
          }
          activeShapePoints.push(earthPosition);

        }
      }, Cesium.ScreenSpaceEventType.LEFT_CLICK);

      // 鼠标移动监听
      handler.setInputAction(function (event) {
        if (Cesium.defined(floatingPoint)) {
          // var newPosition = viewer.scene.pickPosition(event.endPosition);
        var newPosition = viewer.camera.pickEllipsoid(event.endPosition, viewer.scene.globe.ellipsoid);

          
          if (Cesium.defined(newPosition)) {

            floatingPoint.position.setValue(newPosition);
            activeShapePoints.pop();
            activeShapePoints.push(newPosition);
          }
        }
      }, Cesium.ScreenSpaceEventType.MOUSE_MOVE);

      // Redraw the shape so it's not dynamic and remove the dynamic shape.
      function terminateShape() {
        viewer.entities.remove(floatingPoint);
        viewer.entities.remove(activeShape);
        viewer.entities.remove(labels);
        // viewer.entities.removeById('距离文本');

        labels = undefined;
        floatingPoint = undefined;
        activeShape = undefined;
        
        activeShape = drawShape(activeShapePoints);
        labels = bindlabel();
        // _this.linesdata.push(activeShape)
        // _this.linesdata.push(labels)
        activeShapePoints = [];
        handler.removeInputAction(Cesium.ScreenSpaceEventType.MOUSE_MOVE);
        handler.removeInputAction(Cesium.ScreenSpaceEventType.LEFT_CLICK);
      }

      handler.setInputAction(function (event) {
        viewer.entities.remove(activeShape);
        // viewer.entities.removeById('距离文本2');
        viewer.entities.remove(labels);
        handler.removeInputAction(Cesium.ScreenSpaceEventType.RIGHT_CLICK);
        handler.destroy();

      }, Cesium.ScreenSpaceEventType.RIGHT_CLICK);

在这里插入图片描述

遇到的bug图:
在这里插入图片描述

此笔记仅仅为了记录自己在项目中所学到的知识,如果有问题,可以提出,我们可以共同探讨。

好的,您想了解有关自定义几何体的内容,我很乐意为您解答。首先,让我们了解一下什么是几何体。 在Cesium中,几何体是由一些点、线和三角形组成的图形。几何体可以在地球上显示各种形状的物体,如建筑、飞机、汽车等。Cesium提供了一些内置的几何体,如BoxGeometry、CylinderGeometry、SphereGeometry等,但是有时候我们需要展示一些特殊形状的物体,这时候就需要自定义几何体了。 下面是一个简单的自定义几何体的例子: ```javascript var geometry = new Cesium.Geometry({ attributes: { position: new Cesium.GeometryAttribute({ componentDatatype: Cesium.ComponentDatatype.DOUBLE, componentsPerAttribute: 3, values: new Float64Array([ 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 1.0, 0.0 ]) }) }, indices: new Uint16Array([ 0, 1, 2, 0, 2, 3 ]), primitiveType: Cesium.PrimitiveType.TRIANGLES }); ``` 这个例子中,我们创建了一个由四个点组成的矩形,并用这些点的索引定义了两个三角形。这个几何体可以用来在地球上显示一个矩形。 接下来,让我们逐步了解这个例子中的代码。首先是Cesium.GeometryAttribute。 Cesium.GeometryAttribute是几何体属性的容器。在这个例子中,我们定义了一个名为position的属性,它有三个分量:x、y和z。这个属性使用的数据类型是Cesium.ComponentDatatype.DOUBLE,表示每个分量有一个双精度浮点数。componentsPerAttribute表示每个属性有几个分量。在这个例子中,每个属性都有三个分量。最后,我们用一个Float64Array数组来定义这个属性的值。 接下来是indices,它定义了几何体使用哪些点来组成三角形。在这个例子中,我们定义了两个三角形,每个三角形使用三个顶点。在indices数组中,我们用顶点在attributes数组中的索引来定义每个三角形。 最后,我们定义了几何体的primitiveType,它表示几何体的类型。在这个例子中,我们使用的是三角形类型,所以primitiveType为Cesium.PrimitiveType.TRIANGLES。 希望这个例子可以帮助您更好地理解自定义几何体的实现。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值