145 lines
4.8 KiB
JavaScript
145 lines
4.8 KiB
JavaScript
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; |