多边形自定义编辑工具CesiumEditPolygon

 

图1                                                                        图2

                                     图 3                                                    图4

图5

 

简介:

  EditPolygon工具实现功能如上图。图1为初始状态。图2,图3为编辑状态。图4为数据保存状态。图5为操作流程演示。高度问题与地形和坐标拾取方式有关。可自行测试解决。输出结果可根据js方法editExit()自行修改输出数据格式,其中编辑后结果数据为that.positions数组。项目中使用的是MULTIPOLYGON格式。示例采用gejson格式演示。

开发环境:

  vue2+cesium1.97

操作方法:

  1、正式点在鼠标左键点击后进入活动状态,此正式点会跟随鼠标移动而移动同时实时更新图形信息。鼠标右击时为此正式点的落点。

  2、双击正式点为删除此正式点。

  3、临时点在点击后变为活动状态的正式点并生成新的临时点。

使用说明:

引用CesiumEditPolygon.js文件,调用startEditEntity方法传入需编辑的多边形entity对象即可。

<template>
  <!-- 多边形编辑 -->
  <div class="editPolyBox">
    <div id="cesiumContainerBox" />
    <div id="layerMsgBox" class="body">
      <el-button type="success" @click="editTB">编辑</el-button>
      <el-button type="danger" @click="editTBExit">退出编辑</el-button>
      <br />
      修改后数据:{{ result }}
    </div>
  </div>
</template>

<script>
import * as Cesium from '@assets/Cesium'
import CesiumEditPolygon from '@/map/CesiumEditPolygon.js'
var tmpCesiumEditPolygon = null
export default {
  name: 'EditPoly',
  components: {},
  props: [],
  data() {
    return {
      result: [],
      gejson: {
        type: 'FeatureCollection',
        features: [
          {
            type: 'Feature',
            properties: {},
            geometry: {
              coordinates: [
                [
                  [113.65588449380067, 34.78582296420147],
                  [113.64354773327517, 34.78582296420147],
                  [113.64354773327517, 34.76421781263694],
                  [113.65588449380067, 34.76421781263694],
                  [113.65588449380067, 34.78582296420147]
                ]
              ],
              type: 'Polygon'
            }
          },
          {
            type: 'Feature',
            properties: {},
            geometry: {
              coordinates: [
                [
                  [113.68540113854772, 34.784640576011384],
                  [113.68540113854772, 34.76418244965326],
                  [113.7147300409273, 34.76418244965326],
                  [113.7147300409273, 34.784640576011384],
                  [113.68540113854772, 34.784640576011384]
                ]
              ],
              type: 'Polygon'
            }
          }
        ]
      },
      currentEntity: null
    }
  },
  created() {
    this.$nextTick(function() {
      this.startInit()
    })
  },
  methods: {
    startInit() {
      const key =
        '你的CesiumToken'
      Cesium.Ion.defaultAccessToken = key
      // homeButton
      Cesium.Camera.DEFAULT_VIEW_RECTANGLE = Cesium.Rectangle.fromDegrees(
        106.6437,
        36.7976,
        119.9501,
        31.2365
      )
      var viewer = new Cesium.Viewer('cesiumContainerBox', {
        imageryProvider: new Cesium.ArcGisMapServerImageryProvider({
          url:
            'https://services.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer' // 影像底图  World_Imagery  无注记
          // 暗色地图 Canvas/World_Dark_Gray_Base  矢量有注记
          // 亮色地图 Canvas/World_Light_Gray_Base
          // url:
          //   'http://services.arcgisonline.com/ArcGIS/rest/services/World_Street_Map/MapServer'
        }),
        // terrainProvider: Cesium.createWorldTerrain(),
        geocoder: true,
        homeButton: true,
        sceneModePicker: true,
        baseLayerPicker: true,
        navigationHelpButton: true,
        shouldAnimate: true,
        animation: true,
        timeline: true,
        fullscreenButton: true,
        vrButton: false,
        // 关闭点选出现的提示框
        selectionIndicator: false,
        infoBox: false
      })
      // viewer.imageryLayers.addImageryProvider(
      //   new Cesium.ArcGisMapServerImageryProvider({
      //     url:
      //       'https://services.arcgisonline.com/ArcGIS/rest/services/Reference/World_Transportation/MapServer'
      //   })
      // )
      viewer._cesiumWidget._creditContainer.style.display = 'none' // 隐藏版权
      viewer.camera.flyTo({
        destination: Cesium.Cartesian3.fromDegrees(
          113.6440552299206,
          34.78411814959118,
          10000000
        ),
        orientation: {
          heading: Cesium.Math.toRadians(0.0), // 左右方向
          pitch: Cesium.Math.toRadians(-90.0), // 上下方向
          roll: Cesium.Math.toRadians(0) // 镜头(屏幕)到定位目标点(实体)的距离
        },
        duration: 3 // 执行定位动画的时间
      })
      viewer.scene.debugShowFramesPerSecond = true
      viewer.scene.globe.enableLighting = true
      viewer.shadows = true
      window.viewer = viewer
      // 初始化完成
      //   加载entity
      var promise = Cesium.GeoJsonDataSource.load(this.gejson)
      promise.then(ds => {
        ds.name = 'tmpGejson'
        viewer.dataSources.add(ds)
        viewer.flyTo(ds)
      })
      // 监听双击触发编辑方法
      var that = this
      var handler = new Cesium.ScreenSpaceEventHandler(viewer.scene.canvas)
      console.log(handler)
      handler.setInputAction(function(movement) {
        const picked = viewer.scene.pick(movement.position)
        if (picked) {
          var entity = picked.id
          if (entity) {
            that.currentEntity = entity
            that.positionPopUp()
          }
        }
      }, Cesium.ScreenSpaceEventType.LEFT_CLICK)
    },
    positionPopUp() {
      var lmb = document.getElementById('layerMsgBox')
      lmb.style.display = 'block'
    },
    // 多边形编辑
    editTB() {
      this.result = []
      if (this.currentEntity == null) {
        return
      }
      tmpCesiumEditPolygon = new CesiumEditPolygon(window.viewer, {
        polygonColor: '#00ff0088', // 编辑面颜色rgba
        pointColor: '#ff0000ee', // 正式点面颜色rgba
        pointSize: 10, // 正式点大小
        tmpPointColor: '#ffff0088', // 临时点面颜色rgba
        tmpPointSize: 7 // 临时点大小
      })
      tmpCesiumEditPolygon.startEditEntity(this.currentEntity)
    },
    // 退出多边形编辑
    editTBExit() {
      var positions = tmpCesiumEditPolygon.editExit() // 修改后数据
      console.log(positions) // 格式个根据自己需要进修改
      this.result = positions
      //   var geom = tmpCesiumEditPolygon.editExit('geom') // 修改后数据
      // console.log(geom)

      // 数据存入后台,更新数据即可,也可直接更新多边形数据
      // ...
    }
  }
}
</script>

<style lang="scss" scoped>
.show {
  display: block;
}
.editPolyBox {
  width: 100vw;
  height: 100vh;
}
/* cesium */
#cesiumContainerBox {
  width: 100%;
  height: 100%;
  .cesium-viewer-toolbar {
    z-index: 1000;
  }
}

.body {
  position: fixed;
  right: calc(100% - 300px);
  top: 166px;
  z-index: 999;
  width: 300px;
  text-align: center;
  background: rgba(0, 0, 0, 0.6);
  padding: 15px;
  color: #fff;
  display: none;
}

.hide {
  display: none;
}
</style>

部分源码:

/**
   *  启动编辑功能
   *  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);
  }

下载地址:

Cesium多边形自定义编辑工具CesiumEditPolygon.js-Javascript文档类资源-CSDN文库

设计参考:

Cesium自定义编辑多边形_风暴撼大树的博客-CSDN博客_cesium 绘制可编辑的多边形


结束

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Zk9509

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值