/** * @name: index * @author: Administrator * @date: 2023-11-20 17:54 * @description:index * @update: 2023-11-20 17:54 */ import Dialog from '../../../Element/Dialog'; import { getHost } from "../../../../on"; import BaseSource from "../index"; import { setActiveViewer, closeRotateAround, closeViewFollow} from '../../../../Global/global' import { setSplitDirection, syncSplitData } from '../../../../Global/SplitScreen' class BaseTerrain extends BaseSource { #updateModelTimeout; constructor(sdk, options = {}, object = {}, _Dialog = {}) { super(sdk, options); this.object = JSON.parse(JSON.stringify(object)) this.object.west || (this.object.west = 40) this.object.south || (this.object.south = 30) this.object.east || (this.object.east = 160) this.object.north || (this.object.north = 50) this.show = this.options.show this._elms = {}; this.Dialog = _Dialog } get type() { return "terrain" } get name() { return this.options.name } set name(v) { this.options.name = v this._elms.name && this._elms.name.forEach((item) => { item.value = v }) } get show() { return !( this.sdk.viewer.scene.terrainProvider instanceof Cesium.EllipsoidTerrainProvider ) } set show(status) { status ? this.open() : this.close() } async open() { if (this.options.url) { return this.loadTerrain({ url: this.options.url }) } else { let res = await this.requestResource() let text = await res.text() text = JSON.parse(text) if ([0, 200].includes(text.code)) { if (text.data.url.length) return this.loadTerrain(text.data) else return new Promise((res, reject) => { reject('资源不存在') }) } else { return new Promise((res, reject) => { reject(text.msg || text.message) }) } } } //关闭地形 close() { this.sdk.viewer.scene.terrainProvider = new Cesium.EllipsoidTerrainProvider({}) syncSplitData(this.sdk, this.options.id) clearTimeout(this.#updateModelTimeout) this.#updateModelTimeout = setTimeout(() => { clearTimeout(this.#updateModelTimeout) for (let [key, entity] of this.sdk.entityMap) { if (entity.type === 'BillboardObject' && (entity.heightMode == 1 || entity.heightMode == 3)) { entity.updateHeight() } else { if (entity.label) { entity.label.show = entity.label.show } } } }, 500); } async loadTerrain(options) { let object = { ...options } let url = "" if (object.url.startsWith("http")) url = object.url else { //说明是本地的json,在磁盘中存在的 if (object.url.includes(":")) { url = object.url } else { if (this.options.host) { let o = new URL(object.url, this.options.host) url = o.href } else url = object.url } } if (Number(Cesium.VERSION.split('.')[1]) >= 107) { this.terrainProvider = await Cesium.CesiumTerrainProvider.fromUrl(url) } else { this.terrainProvider = new Cesium.CesiumTerrainProvider({ url: url }) } if (!this.sdk || !this.sdk.viewer) { return } this.sdk.viewer.terrainProvider = this.terrainProvider; clearTimeout(this.#updateModelTimeout) this.#updateModelTimeout = setTimeout(() => { clearTimeout(this.#updateModelTimeout) this.terrainProvider.readyPromise.then(() => { for (let [key, entity] of this.sdk.entityMap) { if (entity.type === 'BillboardObject' && (entity.heightMode == 1 || entity.heightMode == 3)) { entity.updateHeight() } else { if (entity.label) { entity.label.show = entity.label.show } } } }) }, 1000); syncSplitData(this.sdk, this.options.id) } remove() { this.close() } async flyTo(duration = 3) { if (this._error) { return } setActiveViewer(0) closeRotateAround(this.sdk) closeViewFollow(this.sdk) if (this.options.customView && this.options.customView.relativePosition && this.options.customView.orientation) { let orientation = { heading: Cesium.Math.toRadians(this.options.customView.orientation.heading || 0.0), pitch: Cesium.Math.toRadians(this.options.customView.orientation.pitch || -60.0), roll: Cesium.Math.toRadians(this.options.customView.orientation.roll || 0.0) } let lng = this.options.customView.relativePosition.lng let lat = this.options.customView.relativePosition.lat let alt = this.options.customView.relativePosition.alt let destination = Cesium.Cartesian3.fromDegrees(lng, lat, alt) let position = { lng: 0, lat: 0 } if (this.options.position) { position = { ...this.options.position } } else if (this.options.positions) { position = { ...this.options.positions[0] } } else if (this.options.center) { position = { ...this.options.center } } else if (this.options.start) { position = { ...this.options.start } } else { if (this.options.hasOwnProperty('lng')) { position.lng = this.options.lng } if (this.options.hasOwnProperty('lat')) { position.lat = this.options.lat } if (this.options.hasOwnProperty('alt')) { position.alt = this.options.alt } } // 如果没有高度值,则获取紧贴高度计算 if (!position.hasOwnProperty('alt')) { position.alt = await this.getClampToHeight(position) } lng = this.options.customView.relativePosition.lng + position.lng lat = this.options.customView.relativePosition.lat + position.lat alt = this.options.customView.relativePosition.alt + position.alt destination = Cesium.Cartesian3.fromDegrees(lng, lat, alt) this.sdk.viewer.camera.flyTo({ destination: destination, orientation: orientation, duration }) } else { let rectangle = new Cesium.Rectangle( Cesium.Math.toRadians(this.object.west), Cesium.Math.toRadians(this.object.south), Cesium.Math.toRadians(this.object.east), Cesium.Math.toRadians(this.object.north) ) this.sdk.viewer.camera.flyTo({ destination: rectangle, duration, }) } } setDefaultValue() { super.setDefaultValue() this.options.host = this.options.host || getHost() this.options.url = this.options.url || "" } /** * @description 编辑框 * @param state=false {boolean} 状态: true打开, false关闭 */ async edit(state = false) { this.originalOptions = this.deepCopyObj(this.options) if (this._DialogObject && this._DialogObject.close) { this._DialogObject.close() this._DialogObject = null } this._DialogObject = await new Dialog(this.sdk, this.options, { title: '地形属性', left: '180px', top: '100px', confirmCallBack: (options) => { this.name = this.name.trim() if (!this.name) { this.name = '未命名对象' } this.originalOptions = this.deepCopyObj(this.options) this._DialogObject.close() this.Dialog.confirmCallBack && this.Dialog.confirmCallBack(this.originalOptions) }, // resetCallBack: () => { // this.name = this.originalOptions.name // this.Dialog.resetCallBack && this.Dialog.resetCallBack() // }, removeCallBack: () => { this.Dialog.removeCallBack && this.Dialog.removeCallBack() }, }, true) let contentElm = document.createElement('div') contentElm.style.width = '300px' let html = `