cesium中编辑面

参考:Cesium笔记之实体编辑_Spider.Wang的博客-CSDN博客_cesium 编辑实体上文讲的是如何通过Cesium来完成一个实体的标绘,本文介绍如何对实体进行编辑。注:示例代码基于Vue框架。1.思路如果要对一个已经标绘完成的实体进行编辑,那么首先我需要获取到该实体的对象,同时应当生成编辑点进行拖拽编辑。Cesium提供了充分的监听器供我们使用,灵活的使用监听器和接口可以轻松的完成实体的编辑。下面是具体实现:2.初始化变量// 创建监听的handlerthis.h...https://blog.csdn.net/Spider_wang/article/details/89845309?spm=1001.2101.3001.6650.3&utm_medium=distribute.pc_relevant.none-task-blog-2~default~BlogCommendFromBaidu~Rate-3-89845309-blog-107801029.pc_relevant_3mothn_strategy_and_data_recovery&depth_1-utm_source=distribute.pc_relevant.none-task-blog-2~default~BlogCommendFromBaidu~Rate-3-89845309-blog-107801029.pc_relevant_3mothn_strategy_and_data_recovery&utm_relevant_index=6 

效果图:

实现代码:

<template>
  <div id="cesiumContainer"></div>
</template>
  
  <script setup>
import * as Cesium from "cesium";
import { onMounted } from "vue";
onMounted(() => {
  const viewer = new Cesium.Viewer("cesiumContainer", {
    infoBox: false, // 禁用沙箱,解决控制台报错
    selectionIndicator: false, //选择指示器
  });
  viewer._cesiumWidget._creditContainer.style.display = "none"; //隐藏logo版权

  viewer.entities.add({
    name: "polygon",
    polygon: {
      hierarchy: Cesium.Cartesian3.fromDegreesArray([
        -115.0, 37.0, -115.0, 32.0, -107.0, 33.0, -102.0, 31.0, -102.0, 35.0,
      ]),
      material: Cesium.Color.RED,
    },
  });

  // 创建监听的handler
  const handler = new Cesium.ScreenSpaceEventHandler(viewer.scene.canvas);

  // 用于保存实体的对象
  let gon = undefined;

  // 判断是否处于编辑状态
  let isEditting = false;

  // 设置当前的编辑点
  let currentPoint = undefined;

  // 清空编辑点ID数组
  let pointsId = [];

  // 对鼠标按下事件的监听
  handler.setInputAction((event) => {
    // 获取屏幕坐标
    let windowPosition = event.position;

    // 通过屏幕坐标获取当前位置的实体信息
    let pickedObject = viewer.scene.pick(windowPosition);

    // 如果实体信息存在则说明该位置存在实体
    if (Cesium.defined(pickedObject)) {
      // 获取当前点的实体
      let entity = pickedObject.id;

      // 如果实体为面同时没有处于编辑状态,那么保存面的实体
      if (entity.name === "polygon" && !isEditting) {
        gon = entity;

        // 生成编辑点
        for (let cartesian of gon.polygon.hierarchy._value.positions) {
          let point = viewer.entities.add({
            name: "gon_point",
            position: cartesian,
            point: {
              color: Cesium.Color.WHITE,
              pixelSize: 8,
              outlineColor: Cesium.Color.BLACK,
              outlineWidth: 1,
            },
          });

          // 保存点的ID以便删除
          pointsId.push(point.id);
        }

        // 设置编辑状态为true
        isEditting = true;

        // 禁止地球旋转和缩放,地球的旋转会对鼠标移动监听有影响,所以需要禁止
        viewer.scene.screenSpaceCameraController.enableRotate = false;
        viewer.scene.screenSpaceCameraController.enableZoom = false;
      } else if (entity.name === "gon_point") {
        // 如果实体为编辑点,那么设置当前编辑点为该点
        currentPoint = entity;
      }
    }
  }, Cesium.ScreenSpaceEventType.LEFT_DOWN);

  // 对鼠标移动事件的监听
  handler.setInputAction((event) => {
    // 如果处于编辑状态且编辑点已定义,那么开始拖拽编辑
    if (isEditting && currentPoint) {
      // 获取屏幕坐标,移动监听与点击有所不同,所以有起始位置和终点位置
      let windowPosition = event.startPosition;

      // 将屏幕坐标转为笛卡尔坐标
      let ellipsoid = viewer.scene.globe.ellipsoid;
      let cartesian = viewer.camera.pickEllipsoid(windowPosition, ellipsoid);

      // 如果点击到地球外,那么返回
      if (!cartesian) {
        return;
      }

      // 更新编辑点的位置
      currentPoint.position = cartesian;
      // 创建面标每个点位置信息的数组,并循环赋值
      let points = [];

      for (let id of pointsId) {
        points.push(viewer.entities.getById(id).position._value);
      }
      // 更新面标的位置数组
      gon.polygon.hierarchy = points;

      // 这种方式报错了,不知道为什么
      // gon.polygon.hierarchy = new Cesium.CallbackProperty(() => {
      //   return points;
      // }, false);
    }
  }, Cesium.ScreenSpaceEventType.MOUSE_MOVE);

  // 对鼠标抬起事件的监听
  handler.setInputAction((event) => {
    // 移除当前编辑点
    currentPoint = undefined;
  }, Cesium.ScreenSpaceEventType.LEFT_UP);
});
</script>
  
  <style scoped>
#cesiumContainer {
  position: absolute;
  width: 100%;
  height: 100%;
  top: 0px;
  left: 0px;
  margin: 0;
  padding: 0;
  overflow: hidden;
}
</style>

结束编辑:

// 恢复地球的旋转和缩放
viewer.scene.screenSpaceCameraController.enableRotate = true;
viewer.scene.screenSpaceCameraController.enableZoom = true;

// 移除监听器
if (this.handler !== null && !this.handler.isDestroyed()) {
  this.handler.destroy();
}

// 移除编辑点,清空编辑点数组
for (let id of this.pointsId) {
  viewer.entities.removeById(id);
}

this.pointsId = [];

方式2:待验证

/**
 * 多边形自定义编辑类
 * author zk
 * date 2022-12-13
 */
import * as Cesium from "@cesium/Cesium";

export default class EditPolygon {
  constructor(viewer, options) {
    this.viewer = viewer;
    this.handler = new Cesium.ScreenSpaceEventHandler(this.viewer.scene.canvas);
    this.options = options || {
      polygonColor: "#00ff0088", //编辑面颜色rgba
      pointColor: "#ff0000ee", //正式点面颜色rgba
      pointSize: 10, //正式点大小
      tmpPointColor: "#ffff0088", //临时点面颜色rgba
      tmpPointSize: 7, //临时点大小
    };
    this.currentEntity = null;
    this.editCurrentEntity = null;
    this.isedit = false;
    this.editPolygons = null;
    this.editPoint = null;
    this.positions = null;
    this.editPointIndex = [];
  }

  /**
   *  启动编辑功能
   *  currentEntity 当前编辑的entity面对象
   * ************************/

  startEditEntity(currentEntity) {
    var that = this;
    that.editCurrentEntity = currentEntity;
    that.editCurrentEntity.show = false;
    that.positions = that.editCurrentEntity.polygon.hierarchy._value;
    that.cleanEntityCollection("editTbEntityCollection");
    let entityCollection = new Cesium.CustomDataSource(
      "editTbEntityCollection"
    );
    entityCollection.key = that.editCurrentEntity.id;
    entityCollection.label = "图斑编辑";
    entityCollection.show = true;
    that.viewer.dataSources.add(entityCollection);
    //添加编辑点
    that.addPointByData(that.positions.positions);
    //添加临时中点
    that.addTmpPoint(that.positions.positions);
    var options = {
      id: "edit-tb-polygon",
      name: "edit-tb-polygon",
      polygon: {
        hierarchy: [],
        material: Cesium.Color.fromCssColorString(that.options.polygonColor),
      },
    };
    options.polygon.hierarchy = new Cesium.CallbackProperty(function () {
      return that.positions;
    }, false);

    entityCollection.entities.add(new Cesium.Entity(options));

    //操作事件监听
    that.handler.setInputAction((movement) => {
      var picks = that.viewer.scene.drillPick(movement.position);
      if (picks.length > 0) {
        var pick = picks[0];
        var entity = pick.id;
        //点击原有点
        if (entity.id.indexOf("edit-tb-point-") !== -1) {
          that.editPointIndex = [];
          var strs = entity.id.split("-");
          if (strs.length == 5) {
            that.editPointIndex.push(Number(strs[4]));
          } else if (strs.length == 7) {
            that.editPointIndex.push(Number(strs[4]));
            that.editPointIndex.push(Number(strs[6]));
          }
          that.editPolygons = that.getEditTbItemById("edit-tb-polygon");
          that.editPoint = entity;
          that.isedit = true;
        }
        // 点击临时点
        if (entity.name.indexOf("edit-tb-tmp-point-") !== -1) {
          that.editPointIndex = [];
          var pindex = Number(entity.description._value);
          pindex = pindex + 1;
          that.editPointIndex.push(pindex);
          that.positions.positions.splice(pindex, 0, entity.position._value);
          that.addPointByData(that.positions.positions);
          that.addTmpPoint(that.positions.positions);
          that.editPolygons = that.getEditTbItemById("edit-tb-polygon");
          var tmp = that.viewer.dataSources.getByName(
            "editTbPointEntityCollection"
          )[0];
          that.editPoint = tmp.entities.values[pindex];
          that.isedit = true;
        }
      }
    }, Cesium.ScreenSpaceEventType.LEFT_CLICK);
    //移动
    that.handler.setInputAction(function (movement) {
      if (that.isedit) {
        const ray = that.viewer.camera.getPickRay(movement.endPosition);
        var cartesian = that.viewer.scene.globe.pick(ray, viewer.scene);
        that.editPoint.position = cartesian;

        if (that.editPointIndex.length > 1) {
          var dt = that.positions.holes[that.editPointIndex[0]].positions;
          if (
            that.editPointIndex[1] == 0 ||
            that.editPointIndex[1] == dt.length - 1
          ) {
            dt[dt.length - 1] = cartesian;
            dt[0] = cartesian;
            var poStart = that.getEditTbItemById(
              "edit-tb-point-holes-" + that.editPointIndex[0] + "-positions-0"
            );
            if (poStart != null) {
              poStart.position = cartesian;
            }
            var poEnd = that.getEditTbItemById(
              "edit-tb-point-holes-" +
                that.editPointIndex[0] +
                "-positions-" +
                dt.length -
                1
            );
            if (poEnd != null) {
              poEnd.position = cartesian;
            }
          } else {
            dt[that.editPointIndex[1]] = cartesian;
          }
        } else if ((that.editPointIndex.length = 1)) {
          if (
            that.editPointIndex[0] == 0 ||
            that.editPointIndex[0] == that.positions.positions.length - 1
          ) {
            that.positions.positions[that.positions.positions.length - 1] =
              cartesian;
            that.positions.positions[0] = cartesian;
            var poStart = that.getEditTbItemById("edit-tb-point-position-0");
            if (poStart != null) {
              poStart.position = cartesian;
            }
            var poEnd = that.getEditTbItemById(
              "edit-tb-point-position-" + that.positions.positions.length - 1
            );
            if (poEnd != null) {
              poEnd.position = cartesian;
            }
          } else {
            that.positions.positions[that.editPointIndex[0]] = cartesian;
          }
          that.addTmpPoint(that.positions.positions);
        }
      }
    }, Cesium.ScreenSpaceEventType.MOUSE_MOVE);

    //双击删除点
    that.handler.setInputAction(function (movement) {
      that.isedit = false;
      var picks = that.viewer.scene.drillPick(movement.position);
      if (picks.length > 0) {
        var pick = picks[0];
        var entity = pick.id;
        if (entity.name.indexOf("edit-tb-point-") !== -1) {
          if (that.positions.positions.length < 5) {
            that.$message.warning("图斑最少有三个点");
          } else {
            var pindex = Number(entity.description._value);
            if (pindex == 0) {
              that.positions.positions[that.positions.positions.length - 1] =
                that.positions.positions[1];
            }
            that.positions.positions.splice(pindex, 1);
            that.addPointByData(that.positions.positions);
            that.addTmpPoint(that.positions.positions);
          }
        }
      }
    }, Cesium.ScreenSpaceEventType.LEFT_DOUBLE_CLICK);

    //右击取消 固定位置
    that.handler.setInputAction(function () {
      that.isedit = false;
    }, Cesium.ScreenSpaceEventType.RIGHT_CLICK);
  }

  //添加编辑点
  addPointByData(activeShapePoints1) {
    var that = this;
    var activeShapePoints = activeShapePoints1.slice(
      0,
      activeShapePoints1.length - 1
    );
    this.cleanEntityCollection("editTbPointEntityCollection");
    let entityCollection = new Cesium.CustomDataSource(
      "editTbPointEntityCollection"
    );
    that.viewer.dataSources.add(entityCollection);
    for (let i = 0; i < activeShapePoints.length; i++) {
      var entry = new Cesium.Entity({
        id: "edit-tb-point-position-" + i,
        name: "edit-tb-point-position-" + i,
        position: activeShapePoints[i],
        point: {
          show: true,

          color: Cesium.Color.fromCssColorString(that.options.pointColor),
          pixelSize: that.options.pointSize,
        },

        description: i,
      });

      entityCollection.entities.add(entry);
    }
  }
  //添加临时编辑点
  addTmpPoint(activeShapePoints1) {
    var that = this;
    var activeShapePoints = activeShapePoints1.slice(
      0,
      activeShapePoints1.length - 1
    );
    this.cleanEntityCollection("editTbMidEntityCollection");
    let entityCollection = new Cesium.CustomDataSource(
      "editTbMidEntityCollection"
    );
    that.viewer.dataSources.add(entityCollection);
    var midposition;
    for (let i = 0; i < activeShapePoints.length; i++) {
      if (i + 1 === activeShapePoints.length) {
        midposition = Cesium.Cartesian3.midpoint(
          activeShapePoints[i],
          activeShapePoints[0],
          new Cesium.Cartesian3()
        );
      } else {
        midposition = Cesium.Cartesian3.midpoint(
          activeShapePoints[i],
          activeShapePoints[i + 1],
          new Cesium.Cartesian3()
        );
      }
      var entry1 = new Cesium.Entity({
        name: "edit-tb-tmp-point-position-",
        position: midposition,
        point: {
          pixelSize: that.options.tmpPointSize,
          color: Cesium.Color.fromCssColorString(that.options.tmpPointColor),
        },
        show: true,
        description: i,
      });
      entityCollection.entities.add(entry1);
    }
  }
  //获取编辑点
  getEditTbItemById(id) {
    var that = this;
    var ent = null;
    var tmp = that.viewer.dataSources.getByName("editTbEntityCollection");
    if (tmp.length > 0) {
      tmp.map((res) => {
        var entities = res.entities.values;
        entities.map((re) => {
          if (re.id == id) {
            ent = re;
          }
        });
      });
    }
    return ent;
  }
  /********************  退出编辑功能  ************************/
  editExit() {
    var that = this;
    that.cleanEntityCollection("editTbEntityCollection");
    that.cleanEntityCollection("editTbMidEntityCollection");
    that.cleanEntityCollection("editTbPointEntityCollection");

    that.editCurrentEntity.show = true;
    var positions = that.positions;
    that.editCurrentEntity.polygon.hierarchy = JSON.parse(
      JSON.stringify(positions)
    );
    that.editPolygons = null; //关闭操作事件
    if (that.handler != null) {
      that.handler.destroy();
    }
    //数据整理
    var tempPoints = [];
    var geom = "MULTIPOLYGON(((";
    positions.positions.map((rr) => {
      var cartographic = Cesium.Cartographic.fromCartesian(rr);
      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,
      });
      geom += longitudeString + " " + latitudeString + ",";
    });
    geom = geom.slice(0, geom.length - 1);
    geom += ")";
    if (positions.holes.length > 0) {
      geom += ",(";
      positions.holes.map((res) => {
        res.positions.map((rr) => {
          var cartographic = Cesium.Cartographic.fromCartesian(rr);
          var longitudeString = Cesium.Math.toDegrees(cartographic.longitude);
          var latitudeString = Cesium.Math.toDegrees(cartographic.latitude);
          var heightString = cartographic.height;
          geom += longitudeString + " " + latitudeString + ",";
        });
        geom = geom.slice(0, geom.length - 1);
        geom += "),(";
      });
      geom = geom.slice(0, geom.length - 2);
    }
    geom += "))";
    //保存数据
    return geom;
  }
  /** 清理资源 */
  cleanEntityCollection(key) {
    var that = this;
    var tmp = that.viewer.dataSources.getByName(key);
    if (tmp.length > 0) {
      tmp.map((res) => {
        that.viewer.dataSources.remove(res);
      });
    }
  }
}

  • 2
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值