/** * @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