Files
sdk4.0/src/Obj/Base/BaseSource/BaseTileset/Tileset/index.js

374 lines
12 KiB
JavaScript
Raw Normal View History

2025-07-03 13:54:01 +08:00
/**
* @name: index
* @author: Administrator
* @date: 2023-11-20 16:05
* @descriptionindex
* @update: 2023-11-20 16:05
*/
import BaseTileset from "../index";
import cy_slider from "../../../../Element/cy_html_slider";
import { html, css } from "./_element";
import EventBinding from '../../../../Element/Dialog/eventBinding';
import { syncSplitData } from '../../../../../Global/SplitScreen'
import Dialog from '../../../../Element/Dialog';
class Tileset extends BaseTileset {
#updateModelTimeout;
/**
* @constructor
* @description 加载Tileset模型
* @param sdk {object} sdk
* @param options {object} 模型参数
* @param options.id {string} 对象id
* @param options.show=true {boolean} 模型显隐
* @param options.name {string} 名称
* @param options.url {string} 资源地址
* @param options.accuracy=1 {number} 精度()
* @param options.position {object} 模型位置
* @param options.position.lng {number} 经度
* @param options.position.lat {number} 纬度
* @param options.position.alt {number} 高度
* */
constructor(earth, options = {}, _Dialog = {}) {
super(earth, options)
this.picking = false
this.Dialog = _Dialog
this._elms = {};
this._EventBinding = new EventBinding()
}
get type() {
return "tileset"
}
on() {
return this.add()
}
get name() {
return this.newData.name
}
set name(v) {
this.newData.name = v
this._elms.name && this._elms.name.forEach((item) => {
item.value = v
})
}
get height() {
return this.newData.height
}
set height(v) {
this.newData.height = v
this.options.position.alt = v
this._elms.height && this._elms.height.forEach((item) => {
item.value = v
})
this.updateModel(this.newData.lng, this.newData.lat, this.newData.height, this.newData.roll, this.newData.heading, this.newData.pitch)
}
get accuracy() {
return this.newData.accuracy
}
set accuracy(v) {
this.newData.accuracy = Number(v.toFixed(1))
if(this.newData.accuracy<0.1) {
this.newData.accuracy = 0.1
}
if(this.entity) {
this.entity.maximumScreenSpaceError = 32/this.newData.accuracy
}
this._elms.accuracy && this._elms.accuracy.forEach((item) => {
item.value = this.newData.accuracy
})
}
get lng() {
return this.newData.lng
}
set lng(v) {
this.newData.lng = v
this.options.position.lng = v
this.updateModel(this.newData.lng, this.newData.lat, this.newData.height, this.newData.roll, this.newData.heading, this.newData.pitch)
}
get lat() {
return this.newData.lat
}
set lat(v) {
this.newData.lat = v
this.options.position.lat = v
this.updateModel(this.newData.lng, this.newData.lat, this.newData.height, this.newData.roll, this.newData.heading, this.newData.pitch)
}
get roll() {
return this.newData.roll
}
set roll(v) {
this.newData.roll = v
this.updateModel(this.newData.lng, this.newData.lat, this.newData.height, this.newData.roll, this.newData.heading, this.newData.pitch, this.newData.scale)
}
get heading() {
return this.newData.heading
}
set heading(v) {
this.newData.heading = v
this.updateModel(this.newData.lng, this.newData.lat, this.newData.height, this.newData.roll, this.newData.heading, this.newData.pitch, this.newData.scale)
}
get pitch() {
return this.newData.pitch
}
set pitch(v) {
this.newData.pitch = v
this.updateModel(this.newData.lng, this.newData.lat, this.newData.height, this.newData.roll, this.newData.heading, this.newData.pitch, this.newData.scale)
}
get transparency() {
return this.newData.transparency
}
set transparency(v) {
if (!this.newData) {
return
}
this.newData.transparency = Number(v)
this._elms.transparency && this._elms.transparency.forEach((item) => {
item.value = v
})
let transparency = this.newData.transparency
// if (transparency == 1) {
// transparency = 0.99
// }
this.entity.style = new Cesium.Cesium3DTileStyle({
color: {
"conditions": [
//有size属性表示为点云需要与点颜色融合
["Boolean(${SIZE})", "${COLOR} * color('rgba(255,255,255)', " + transparency + ")"],
["true", "color('rgba(255,255,255," + transparency + ")')"]
]
},
show: true,
});
}
/**
* @description 编辑框
* @param state=false {boolean} 状态: true打开, false关闭
*/
async edit(state = false) {
let _this = this
this._element_style = null
// let elms = this.sdk.viewer._container.getElementsByClassName('YJ-custom-base-dialog')
// for (let i = elms.length - 1; i >= 0; i--) {
// this.sdk.viewer._container.removeChild(elms[i])
// }
if (this._DialogObject && this._DialogObject.close) {
this._DialogObject.close()
this._DialogObject = null
}
if (state) {
this._element_style = document.createElement('style');
this._element_style.type = 'text/css';
this._element_style.setAttribute('data-name', 'YJ_style_dialog');
this._element_style.innerHTML = css();
this._DialogObject = await new Dialog(this.sdk, this.newData, {
title: '倾斜模型属性', left: '180px', top: '100px',
confirmCallBack: (options) => {
this.oldData.name = this.newData.name
this.oldData.height = this.newData.height
this.oldData.lng = this.newData.lng
this.oldData.lat = this.newData.lat
this.oldData.transparency = this.newData.transparency
this.oldData.scale = this.newData.scale
this.oldData.roll = this.newData.roll
this.oldData.heading = this.newData.heading
this.oldData.pitch = this.newData.pitch
this.oldData.type = this.type
this.oldData.accuracy = this.newData.accuracy
this._DialogObject.close()
this.Dialog.confirmCallBack && this.Dialog.confirmCallBack({ ...this.oldData, type: this.type })
syncSplitData(this.sdk, this.oldData.id)
},
resetCallBack: () => {
this.reset()
this.Dialog.resetCallBack && this.Dialog.resetCallBack()
},
removeCallBack: () => {
this.Dialog.removeCallBack && this.Dialog.removeCallBack()
},
closeCallBack: () => {
this.reset()
if (this.positionEditing) {
this.positionEditing = false
}
if (this.rotationEditing) {
this.rotationEditing = false
}
this.Dialog.closeCallBack && this.Dialog.closeCallBack()
},
showCallBack: (show) => {
this.newData.show = show
this.entity && (this.entity.show = show)
this.Dialog.showCallBack && this.Dialog.showCallBack()
},
rotateCallBack: () => {
if (this.rotationEditing) {
this.rotationEditing = false
}
else {
this.rotationEditing = true
}
},
translationalCallBack: () => {
if (this.positionEditing) {
this.positionEditing = false
}
else {
this.positionEditing = true
}
}
}, true)
document.getElementsByTagName('head')[0].appendChild(this._element_style);
let contentElm = document.createElement('div');
contentElm.innerHTML = html()
this._DialogObject.contentAppChild(contentElm)
let all_elm = contentElm.getElementsByTagName("*")
this._EventBinding.on(this, all_elm)
this._elms = this._EventBinding.element
} else {
// if (this._element_style) {
// document.getElementsByTagName('head')[0].removeChild(this._element_style)
// this._element_style = null
// }
// if (this._DialogObject && this._DialogObject.remove) {
// this._DialogObject.remove()
// this._DialogObject = null
// }
}
}
//更新模型位置
updateModel(_tx, _ty, _tz, _rx = 0, _ry = 0, _rz = 0, s = 1) {
if (!this.tileset.root.transform) {
if (window.ELEMENT) {
window.ELEMENT.Message.closeAll();
window.ELEMENT.Message({
message: '该模型不支持移动和旋转!',
type: 'warning',
duration: 1500
});
}
console.warn('该模型不支持移动和旋转!')
return
}
if ((!_tx && _tx!==0) || (!_ty && _ty!==0) || (!_tz && _tz!==0)) {
return
}
let mx = Cesium.Matrix3.fromRotationX(
Cesium.Math.toRadians(_rx)
)
let my = Cesium.Matrix3.fromRotationY(
Cesium.Math.toRadians(_ry)
)
let mz = Cesium.Matrix3.fromRotationZ(
Cesium.Math.toRadians(_rz)
)
// 平移
let m = Cesium.Transforms.eastNorthUpToFixedFrame(new Cesium.Cartesian3.fromDegrees(_tx, _ty, _tz))
// 旋转
let rotationX = Cesium.Matrix4.fromRotationTranslation(mx)
let rotationY = Cesium.Matrix4.fromRotationTranslation(my)
let rotationZ = Cesium.Matrix4.fromRotationTranslation(mz)
let originalMatrix = new Cesium.Matrix4()
Cesium.Matrix4.multiply(m, rotationX, originalMatrix)
Cesium.Matrix4.multiply(originalMatrix, rotationY, originalMatrix)
Cesium.Matrix4.multiply(originalMatrix, rotationZ, originalMatrix)
const scale = Cesium.Matrix4.fromUniformScale(s);
Cesium.Matrix4.multiply(originalMatrix, scale, this.entity._root.transform)
// console.log(_tx, _ty, _tz)
if (!this.editObj.activeAxis) {
this.editObj.position = { lng: _tx, lat: _ty, alt: _tz }
}
if (!this.editObj.activeCircle) {
this.editObj.rotate = { x: _rx, y: _ry, z: _rz }
}
this.editObj && this.editObj.update()
clearTimeout(this.#updateModelTimeout)
this.#updateModelTimeout = setTimeout(() => {
clearTimeout(this.#updateModelTimeout)
let center = this.cartesian3Towgs84(this.entity.boundingSphere.center, this.sdk.viewer)
let circle = turf.circle([center.lng, center.lat], this.entity.boundingSphere.radius / 1000, { steps: 360, units: 'kilometers' });
for (let [key, entity] of this.sdk.entityMap) {
if (entity.type === 'BillboardObject' && entity.heightMode == 3) {
let pt = turf.point([entity.lng, entity.lat]);
if (turf.booleanPointInPolygon(pt, circle)) {
entity.updateHeight()
}
}
else {
if (entity.label) {
entity.label.show = entity.label.show
}
}
}
}, 300);
}
// flyTo() {
// this.entity.readyPromise.then(() => {
// console.log(this.entity)
// let boundingSphere
// if(!this.lng || !this.lat) {
// boundingSphere = new Cesium.BoundingSphere(this.entity.boundingSphere)
// }
// else {
// boundingSphere = new Cesium.BoundingSphere(Cesium.Cartesian3.fromDegrees(this.lng, this.lat, this.height), this.entity.boundingSphere.radius)
// }
// this.sdk.viewer.camera.flyToBoundingSphere(boundingSphere)
// })
// }
reset() {
this.editObj.destroy()
if (!this.entity) {
return
}
this.transparency = this.oldData.transparency
this.name = this.oldData.name
this.height = this.oldData.height
this.lng = this.oldData.lng
this.lat = this.oldData.lat
this.roll = this.oldData.roll
this.heading = this.oldData.heading
this.pitch = this.oldData.pitch
this.scale = this.oldData.scale
this.accuracy = this.oldData.accuracy
this.entity.style = new Cesium.Cesium3DTileStyle({
color: {
"conditions": [
["Boolean(${SIZE})", "${COLOR} * color('rgba(255,255,255)', " + this.transparency + ")"],
["true", "color('rgba(255,255,255," + this.transparency + ")')"]
]
},
show: true,
});
}
}
export default Tileset