374 lines
12 KiB
JavaScript
374 lines
12 KiB
JavaScript
/**
|
||
* @name: index
|
||
* @author: Administrator
|
||
* @date: 2023-11-20 16:05
|
||
* @description:index
|
||
* @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
|