// * 创建视锥
|
import * as Cesium from 'cesium'
|
|
/* eslint-disable new-cap */
|
/* eslint-disable no-undef */
|
export default class CreateFrustum {
|
constructor(viewer, options) {
|
this.position = options.position
|
this.viewer = viewer
|
this.fov = options.fov || 0
|
this.near = options.near || 0
|
this.far = options.far || 0
|
this.heading = options.heading || 0
|
this.pitch = options.pitch || 0
|
this.roll = options.roll || 0
|
this.width = options.width
|
this.height = options.height
|
this.add()
|
}
|
|
UpdateWidth(value) {
|
this.width = value
|
this.add()
|
}
|
UpdateHeight(value) {
|
this.height = value
|
this.add()
|
}
|
UpdateFov(value) {
|
this.fov = value
|
this.add()
|
}
|
UpdateNear(value) {
|
this.near = value
|
this.add()
|
}
|
UpdateFar(value) {
|
this.far = value
|
this.add()
|
}
|
UpdateHeading(value) {
|
this.heading = value
|
this.add()
|
}
|
UpdatePitch(value) {
|
this.pitch = value
|
this.add()
|
}
|
UpdateRoll(value) {
|
this.roll = value
|
this.add()
|
}
|
UpdataPosition(position) {
|
if (!position) return
|
this.position = position
|
this.add()
|
}
|
|
// 更新视锥体的姿态
|
Update(position, headingPitchRoll) {
|
this.position = Cesium.Cartesian3.fromDegrees(
|
position.longitude,
|
position.latitude,
|
position.altitude
|
)
|
this.orientation = Cesium.Transforms.headingPitchRollQuaternion(
|
this.position,
|
new Cesium.HeadingPitchRoll.fromDegrees(
|
headingPitchRoll.heading,
|
headingPitchRoll.pitch,
|
headingPitchRoll.roll
|
)
|
)
|
this.add()
|
}
|
|
// 创建视锥体和轮廓线
|
add() {
|
this.clear()
|
this.addFrustum()
|
this.addOutline()
|
this.addCenterline()
|
}
|
|
// 清除视锥体和轮廓线
|
clear() {
|
this.clearFrustum()
|
this.clearOutline()
|
this.clearCenterline()
|
}
|
|
// 清除视锥体
|
clearFrustum() {
|
if (this.frustumPrimitive) {
|
this.viewer.scene.primitives.remove(this.frustumPrimitive)
|
this.frustumPrimitive = null
|
}
|
}
|
|
// 清除轮廓线
|
clearOutline() {
|
if (this.outlinePrimitive) {
|
this.viewer.scene.primitives.remove(this.outlinePrimitive)
|
this.outlinePrimitive = null
|
}
|
}
|
|
clearCenterline() {
|
if (this.centerDataSource) {
|
this.centerDataSource.entities.removeAll()
|
this.viewer.dataSources.remove(this.centerDataSource)
|
this.centerDataSource = null
|
}
|
}
|
|
// 创建视锥体
|
addFrustum() {
|
const frustum = new Cesium.PerspectiveFrustum({
|
// 查看的视场角,绕Z轴旋转,以弧度方式输入
|
fov: Cesium.Math.toRadians(this.fov),
|
// 视锥体的宽度/高度
|
aspectRatio: this.width / this.height,
|
// 近面距视点的距离
|
near: this.near,
|
// 远面距视点的距离
|
far: this.far,
|
})
|
const position = Cesium.Cartesian3.fromDegrees(
|
this.position.longitude,
|
this.position.latitude,
|
this.position.altitude
|
)
|
const geometry = new Cesium.FrustumGeometry({
|
frustum: frustum,
|
origin: position,
|
orientation: Cesium.Transforms.headingPitchRollQuaternion(
|
position,
|
new Cesium.HeadingPitchRoll.fromDegrees(this.heading, this.pitch, this.roll)
|
),
|
vertexFormat: Cesium.VertexFormat.POSITION_ONLY,
|
})
|
const instance = new Cesium.GeometryInstance({
|
geometry: geometry,
|
attributes: {
|
color: Cesium.ColorGeometryInstanceAttribute.fromColor(
|
Cesium.Color.fromBytes(0, 213, 144, 20)
|
),
|
},
|
})
|
const primitive = new Cesium.Primitive({
|
geometryInstances: instance,
|
appearance: new Cesium.PerInstanceColorAppearance({
|
closed: true,
|
flat: true,
|
}),
|
asynchronous: false,
|
})
|
this.frustumPrimitive = this.viewer.scene.primitives.add(primitive)
|
}
|
|
// 创建轮廓线
|
addOutline() {
|
const frustum = new Cesium.PerspectiveFrustum({
|
// 查看的视场角度,绕Z轴旋转,以弧度方式输入
|
// The angle of the field of view (FOV), in radians.
|
// This angle will be used as the horizontal FOV if the width is greater than the height, otherwise it will be the vertical FOV.
|
fov: Cesium.Math.toRadians(this.fov),
|
// 视锥体的宽度/高度
|
aspectRatio: this.width / this.height,
|
// 近面距视点的距离
|
near: this.near,
|
// 远面距视点的距离
|
far: this.far,
|
})
|
const position = Cesium.Cartesian3.fromDegrees(
|
this.position.longitude,
|
this.position.latitude,
|
this.position.altitude
|
)
|
const geometry = new Cesium.FrustumOutlineGeometry({
|
frustum: frustum,
|
origin: position,
|
orientation: Cesium.Transforms.headingPitchRollQuaternion(
|
position,
|
new Cesium.HeadingPitchRoll.fromDegrees(this.heading, this.pitch, this.roll)
|
),
|
vertexFormat: Cesium.VertexFormat.POSITION_ONLY,
|
})
|
const instance = new Cesium.GeometryInstance({
|
geometry: geometry,
|
attributes: {
|
color: Cesium.ColorGeometryInstanceAttribute.fromColor(
|
Cesium.Color.fromBytes(0, 213, 144, 255)
|
),
|
},
|
})
|
const primitive = new Cesium.Primitive({
|
geometryInstances: instance,
|
appearance: new Cesium.PerInstanceColorAppearance({
|
closed: true,
|
flat: true,
|
}),
|
asynchronous: false,
|
})
|
this.outlinePrimitive = this.viewer.scene.primitives.add(primitive)
|
}
|
|
addCenterline() {
|
this.centerDataSource = new Cesium.CustomDataSource()
|
this.viewer.dataSources.add(this.centerDataSource)
|
|
const position = Cesium.Cartesian3.fromDegrees(
|
this.position.longitude,
|
this.position.latitude,
|
this.position.altitude
|
)
|
|
let matrix = Cesium.Matrix3.fromQuaternion(
|
Cesium.Transforms.headingPitchRollQuaternion(
|
position,
|
new Cesium.HeadingPitchRoll.fromDegrees(this.heading, this.pitch, this.roll)
|
),
|
new Cesium.Matrix3()
|
)
|
|
let right1 = Cesium.Matrix3.getColumn(matrix, 0, new Cesium.Cartesian3())
|
let up1 = Cesium.Matrix3.getColumn(matrix, 1, new Cesium.Cartesian3())
|
let direction = Cesium.Matrix3.getColumn(matrix, 2, new Cesium.Cartesian3())
|
|
// const direction = new Cartesian3(-0.10668226241650887, 0.8103322335050215, -0.5761775474872814)
|
|
let frontDirect = Cesium.Cartesian3.multiplyByScalar(
|
direction,
|
this.far,
|
new Cesium.Cartesian3()
|
)
|
let bottomCenter = Cesium.Cartesian3.add(position, frontDirect, new Cesium.Cartesian3())
|
|
// 创建Entity来显示中心线
|
this.centerDataSource.entities.add({
|
name: 'Center Line of Frustum',
|
polyline: {
|
positions: [position, bottomCenter],
|
width: 1,
|
// material: Cesium.Color.RED.withAlpha(0.5)
|
material: new Cesium.PolylineDashMaterialProperty({
|
color: Cesium.Color.fromBytes(0, 213, 144, 255),
|
dashLength: 30.0,
|
gapColor: Cesium.Color.TRANSPARENT,
|
gapWidth: 1.0,
|
}),
|
},
|
})
|
}
|
}
|