图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 绘制可编辑的多边形
结束