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
|