vue2+cesium实现面积计算

 需要安装

 

 在页面中引入

AreaUse() {

      const viewer = QJViewer;

      const _this = this;

      var positions = [];

      var height = undefined;

      var polygonEntity = undefined;

      var mesureResultEntity = undefined;

      var tempPositions = [];

      // 测量功能激活

      var isMeasure = true;

      _this.$message({

        message: "开始计算面积,右键结束计算",

        type: "success",

        customClass: "message",

      });

      unRegisterEvents();

      //创建面对象

      function createPolygonEntity() {

        polygonEntity = viewer.entities.add({

          polygon: {

            hierarchy: new Cesium.CallbackProperty((event) => {

              return new Cesium.PolygonHierarchy(tempPositions);

              //使用最新1.72的时候 必须返回PolygonHierarchy类型 Cannot read property 'length' of undefined

              //低版本好像都可以

            }, false),

            material: Cesium.Color.RED.withAlpha(0.4),

            perPositionHeight: true, //

          },

          polyline: {

            positions: new Cesium.CallbackProperty((event) => {

              return tempPositions.concat(tempPositions[0]);

            }, false),

            width: 1,

            material: new Cesium.PolylineDashMaterialProperty({

              color: Cesium.Color.YELLOW,

            }),

            depthFailMaterial: new Cesium.PolylineDashMaterialProperty({

              color: Cesium.Color.YELLOW,

            }),

          },

        });

        _this.AreaEntities.push(polygonEntity);

      }

      // 创建起点

      function createStartEntity() {

        let vertexEntity = viewer.entities.add({

          position: positions[0],

          type: "MeasureDistanceVertex",

          point: {

            color: Cesium.Color.FUCHSIA,

            pixelSize: 6,

          },

        });

        _this.AreaEntities.push(vertexEntity);

      }

      // 创建节点

      function createVertex() {

        let vertexEntity = viewer.entities.add({

          position: positions[positions.length - 1],

          type: "MeasureAreaVertex",

          point: {

            color: Cesium.Color.FUCHSIA,

            pixelSize: 8,

            disableDepthTestDistance: 500,

          },

        });

        _this.AreaEntities.push(vertexEntity);

      }

      //统一节点的高度

      function unifiedHeight(positions, height) {

        if (!height) height = getPositionHeight(positions[0]); //如果没有指定高度 就用第一个的高度

        let point3d;

        for (let i = 0; i < positions.length; i++) {

          const element = positions[i];

          point3d = cartesian3ToPoint3D(element);

          positions[i] = Cesium.Cartesian3.fromDegrees(

            point3d.x,

            point3d.y,

            height

          );

        }

        return height;

      }

      //获取某个点的高度

      function getPositionHeight(position) {

        const cartographic = Cesium.Cartographic.fromCartesian(position);

        return cartographic.height;

      }

      // 将 Cesium 的 Cartesian3 类型的位置坐标转换为一个更易于理解和处理的经纬度坐标对象

      function cartesian3ToPoint3D(position) {

        const cartographic = Cesium.Cartographic.fromCartesian(position);

        const lon = Cesium.Math.toDegrees(cartographic.longitude);

        const lat = Cesium.Math.toDegrees(cartographic.latitude);

        return { x: lon, y: lat, z: cartographic.height };

      }

      // 计算面积

      function computeArea(positions) {

        let s = 0;

        let p1 = 0;

        let p2 = 0;

        for (let i = 0; i < positions.length; ++i) {

          p1 = positions[i];

          let j = (i + 1) % positions.length;

          p2 = positions[j];

          s += p1.x * p2.y;

          s -= p2.x * p1.y;

        }

        return Math.abs(s / 2 / 1000000.0).toFixed(6);

      }

      //测量结果标签

      function createResultLabel() {

        mesureResultEntity = viewer.entities.add({

          position: new Cesium.CallbackProperty((event) => {

            return getCenterPosition();

          }, false),

          type: "MeasureAreaResult",

          label: {

            text: new Cesium.CallbackProperty((event) => {

              return "面积" + computeArea(tempPositions) + "km²";

            }, false),

            scale: 0.5,

            font: "normal 28px MicroSoft YaHei",

            // distanceDisplayCondition: new Cesium.DistanceDisplayCondition(0, 5000),

            scaleByDistance: new Cesium.NearFarScalar(1000, 1, 3000, 1),

            verticalOrigin: Cesium.VerticalOrigin.BOTTOM,

            style: Cesium.LabelStyle.FILL_AND_OUTLINE,

            // pixelOffset: new Cesium.Cartesian2(0, -30),

            outlineWidth: 9,

            outlineColor: Cesium.Color.YELLOW,

          },

        });

        _this.AreaEntities.push(mesureResultEntity);

      }

      //获取节点的中心点

      function getCenterPosition() {

        let points = [];

        if (tempPositions.length < 3) return tempPositions[0];

        tempPositions.forEach((position) => {

          const point3d = cartesian3ToPoint3D(position);

          points.push([point3d.x, point3d.y]);

        });

        // 构建turf.js  lineString

        let geo = turf.lineString(points);

        let bbox = turf.bbox(geo);

        let bboxPolygon = turf.bboxPolygon(bbox);

        let pointOnFeature = turf.center(bboxPolygon);

        let lonLat = pointOnFeature.geometry.coordinates;

        console.log(444);

        return Cesium.Cartesian3.fromDegrees(

          lonLat[0],

          lonLat[1],

          height + 0.3

        );

      }

      //禁用

      function deactivate() {

        if (!isMeasure) return;

        unRegisterEvents();

        viewer._element.style.cursor = "pointer";

        viewer.enableCursorStyle = true;

        isMeasure = false;

        tempPositions = [];

        positions = [];

        height = undefined;

      }

      // 清除

      function clear() {

        //清除线对象

        viewer.entities.remove(polygonEntity);

        polygonEntity = undefined;

        //清除节点

        _this.AreaEntities.forEach((item) => {

          viewer.entities.remove(item);

        });

        _this.AreaEntities = [];

        viewer.entities.remove(mesureResultEntity);

        mesureResultEntity = undefined;

        height = undefined;

      }

      // 解除鼠标事件

      function unRegisterEvents() {

        viewer.screenSpaceEventHandler.removeInputAction(

          Cesium.ScreenSpaceEventType.LEFT_CLICK

        );

        viewer.screenSpaceEventHandler.removeInputAction(

          Cesium.ScreenSpaceEventType.RIGHT_CLICK

        );

        viewer.screenSpaceEventHandler.removeInputAction(

          Cesium.ScreenSpaceEventType.MOUSE_MOVE

        );

      }

      //左键点击事件

      viewer.screenSpaceEventHandler.setInputAction(function (event) {

        viewer._element.style.cursor = "crosshair";

        // 获取鼠标点击位置的屏幕坐标

        var ray = viewer.camera.getPickRay(event.position);

        if (!ray) return null;

        var earthPosition = viewer.scene.globe.pick(ray, viewer.scene);

        if (Cesium.defined(earthPosition)) {

          const ellipsoid = viewer.scene.globe.ellipsoid;

          earthPosition = viewer.scene.camera.pickEllipsoid(

            event.position,

            ellipsoid

          );

        }

        if (!earthPosition) return;

        positions.push(earthPosition);

        height = unifiedHeight(positions, height);

        if (positions.length == 1) {

          //首次点击

          createPolygonEntity();

          createStartEntity();

        }

        createVertex();

      }, Cesium.ScreenSpaceEventType.LEFT_CLICK);

      // 鼠标移动事件

      viewer.screenSpaceEventHandler.setInputAction(function (event) {

        if (!isMeasure) return;

        viewer._element.style.cursor = "crosshair";

        // 获取鼠标点击位置的屏幕坐标

        var ray = viewer.camera.getPickRay(event.endPosition);

        if (!ray) return null;

        var earthPosition = viewer.scene.globe.pick(ray, viewer.scene);

        if (earthPosition) {

          earthPosition = viewer.scene.camera.pickEllipsoid(

            event.startPosition,

            viewer.scene.globe.ellipsoid

          );

        }

        if (!earthPosition) return;

        if (positions.length < 1) return;

        height = unifiedHeight(positions, height);

        tempPositions = positions.concat(earthPosition);

        if (tempPositions.length >= 3 && !mesureResultEntity) {

          createResultLabel();

        }

      }, Cesium.ScreenSpaceEventType.MOUSE_MOVE);

      // 鼠标右键事件

      viewer.screenSpaceEventHandler.setInputAction(function (event) {

        // console.log(event);

        if (!isMeasure || positions.length < 3) {

          deactivate();

          clear();

        } else {

          tempPositions = [...positions];

          polygonEntity.polyline = {

            positions: positions.concat(positions[0]),

            width: 2,

            material: Cesium.Color.YELLOW,

            depthFailMaterial: new Cesium.PolylineDashMaterialProperty({

              color: Cesium.Color.YELLOW,

            }),

          };

          polygonEntity.polygon.hierarchy = new Cesium.PolygonHierarchy(

            tempPositions

          );

          mesureResultEntity.position = getCenterPosition();

          mesureResultEntity.label.text =

            "总面积" + computeArea(positions) + "km²";

          deactivate();

        }

      }, Cesium.ScreenSpaceEventType.RIGHT_CLICK);

    },

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值