前言
近期遇到了一个需求,对3DTileset进行裁剪。一开始理解是绘制一个平面然后对平面进行移动切割模型。
①第一版功能 :移动进行裁剪
b3dm = map.scene.primitives.add(
new Cesium.Cesium3DTileset({
url: `Tileset/tileset.json`
})
)
b3dm.readyPromise.then((tileset) => {
map.zoomTo(tileset)
var clippingPlanes = (tileset.clippingPlanes = loadClip())
var boundingSphere = tileset.boundingSphere
console.log(boundingSphere)
for (var i = 0; i < clippingPlanes.length; ++i) {
plane = clippingPlanes.get(i)
var planeEntity = map.entities.add({
//添加平面实体 直观裁切面
id: '裁切面' + i,
position: boundingSphere.center, // offset, 根据3dtiles同步调整裁切面高度
plane: {
dimensions: new Cesium.Cartesian2(
boundingSphere.radius,
boundingSphere.radius
), //(radius * 2.5, radius * 2.5),
material: Cesium.Color.WHITE.withAlpha(0.0),
plane: new Cesium.CallbackProperty(
createPlaneUpdateFunction(plane),
false
),
outline: true,
outlineColor: Cesium.Color.WHITE
}
})
}
})
const loadClip = () => {
var clippingPlanes = new Cesium.ClippingPlaneCollection({
planes: [new Cesium.ClippingPlane(new Cesium.Cartesian3(1.0, 0.0, 0), 0)],
edgeColor: Cesium.Color.RED,
edgeWidth: 1.0,
unionClippingRegions: true //true 才能多个切割
})
return clippingPlanes
}
const createPlaneUpdateFunction = (plane) => {
return function () {
plane.distance = value1.value
return plane
}
}
完成后,想要的效果变成了超图网页的这种效果:
②第二版功能:单个面的裁剪
实现步骤:实现先绘制面,获取到面的经纬度数据进行存储,这里使用一个静态数据测试(注意事项:经纬度坐标点(一定要逆时针顺序选点),最后一个坐标点和起点一致形成闭合多边形;(或者找一个顺序转换方法,把顺时针选取的坐标点转成逆时针顺序),可以使用turf.js里面的truf.booleanClockwise()方法进行转换)
// 经纬度坐标点(一定要逆时针顺序选点),最后一个坐标点和起点一致形成闭合多边形;(或者找一个顺序转换方法,把顺时针选取的坐标点转成逆时针顺序)
const polygon = [
[122.50659820182338, 40.92167507082603],
[122.50647158464602, 40.92209157639903],
[122.5056436778383, 40.921389892895164],
[122.50590698641585, 40.92120253418978],
[122.50659820182338, 40.92167507082603]
]
// 裁剪方法调用
let clipping = new Clipping(tileset, polygon)
class Clipping {