Files
sdk4.0/src/Obj/Analysis/Section/index.js

145 lines
4.8 KiB
JavaScript
Raw Normal View History

2025-07-03 13:54:01 +08:00
import Tools from "../../../Tools";
class Section extends Tools {
/**
* @constructor 剖切
* @param sdk
* @param tiles3d {object} 3dtiles对象
* @param {Array.<object>} options.positions 经纬度[{lon,lat,alt},...]
* @param options.regionsType=false 裁剪类型 false:裁剪内部true:裁剪外部
* **/
constructor(sdk, tiles3d, options = {}) {
super(sdk, options)
this.viewer = sdk.viewer
this.tiles3d = tiles3d
this.options = { ...options }
this.options.regionsType = this.options.regionsType || false
2025-07-03 18:18:08 +08:00
YJ.Analysis.SectionResults.push(this)
2025-07-03 13:54:01 +08:00
this.Planes = []
Section.start(this)
}
get regionsType() {
return this.options.regionsType
}
set regionsType(v) {
this.options.regionsType = v
if (this.Planes.length > 0) {
this.Planes = []
Section.planeCollection(this)
}
}
static start(that) {
let positions = that.options.positions || []
if(!that.isConvex(positions)) {
window.ELEMENT && window.ELEMENT.Message({
message: '不支持凹多边形',
type: 'warning',
duration: 1500
});
console.log('不支持凹多边形')
return
}
that.inverseTransform = getInverseTransform(that.tiles3d)
that.Planes = []
let array = []
if (positions.length > 0) {
for (let i = 0; i < positions.length; i++) {
array.push([positions[i].lng, positions[i].lat])
}
array.push([positions[0].lng, positions[0].lat])
that.isClockwise = turf.booleanClockwise(turf.lineString(array));
}
Section.planeCollection(that)
function getInverseTransform(tileSet) {
let transform
const tmp = tileSet.root.transform
if ((tmp && tmp.equals(Cesium.Matrix4.IDENTITY)) || !tmp) {
transform = Cesium.Transforms.eastNorthUpToFixedFrame(tileSet.boundingSphere.center)
} else {
transform = Cesium.Matrix4.fromArray(tileSet.root.transform)
}
return Cesium.Matrix4.inverseTransformation(transform, new Cesium.Matrix4())
}
}
static planeCollection(that) {
let positions = that.options.positions || []
if (that.regionsType == that.isClockwise) {
for (let i = 0; i < positions.length; i++) {
if (i === (positions.length - 1)) {
that.Planes.push(createPlane(positions[i], positions[0], that.inverseTransform))
} else {
that.Planes.push(createPlane(positions[i], positions[i + 1], that.inverseTransform))
}
}
}
else {
for (let i = positions.length - 1; i >= 0; i--) {
if (i === 0) {
that.Planes.push(createPlane(positions[i], positions[positions.length - 1], that.inverseTransform))
} else {
that.Planes.push(createPlane(positions[i], positions[i - 1], that.inverseTransform))
}
}
}
if(that.tiles3d.clippingPlanes) {
that.tiles3d.clippingPlanes.removeAll()
for(let i=0;i<that.Planes.length;i++) {
that.tiles3d.clippingPlanes.add(that.Planes[i])
}
that.tiles3d.clippingPlanes.enabled = true
}
else {
const PlaneCollection = new Cesium.ClippingPlaneCollection({
planes: that.Planes,
enabled: true,
unionClippingRegions: that.regionsType,
edgeColor: Cesium.Color.WHITE,
edgeWidth: 1,
})
that.tiles3d.clippingPlanes = PlaneCollection
}
function createPlane(p1, p2, inverseTransform) {
// 将仅包含经纬度信息的p1,p2转换为相应坐标系的cartesian3对象
const p1C3 = getOriginCoordinateSystemPoint(p1, inverseTransform)
const p2C3 = getOriginCoordinateSystemPoint(p2, inverseTransform)
// 定义一个垂直向上的向量up
const up = new Cesium.Cartesian3(0, 0, 10)
// right 实际上就是由p1指向p2的向量
const right = Cesium.Cartesian3.subtract(p2C3, p1C3, new Cesium.Cartesian3())
// 计算normal right叉乘up得到平面法向量这个法向量指向right的右侧
let normal = Cesium.Cartesian3.cross(right, up, new Cesium.Cartesian3())
normal = Cesium.Cartesian3.normalize(normal, normal)
// 由于已经获得了法向量和过平面的一点因此可以直接构造Plane,并进一步构造ClippingPlane
const planeTmp = Cesium.Plane.fromPointNormal(p1C3, normal)
return Cesium.ClippingPlane.fromPlane(planeTmp)
}
function getOriginCoordinateSystemPoint(point, inverseTransform) {
const val = Cesium.Cartesian3.fromDegrees(point.lng, point.lat)
return Cesium.Matrix4.multiplyByPoint(
inverseTransform, val, new Cesium.Cartesian3(0, 0, 0))
}
}
destroy() {
this.Planes = []
// this.tiles3d.clippingPlanes = new Cesium.ClippingPlaneCollection()
if(this.tiles3d.clippingPlanes) {
this.tiles3d.clippingPlanes.enabled = false
this.tiles3d.clippingPlanes.removeAll()
}
}
}
export default Section;