Files
sdk4.0/src/Obj/Analysis/Section/index.js
2025-07-03 18:18:08 +08:00

145 lines
4.8 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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
YJ.Analysis.SectionResults.push(this)
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;