294 lines
8.6 KiB
JavaScript
294 lines
8.6 KiB
JavaScript
/**
|
||
* @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({})
|
||
for (let i = 0; i < YJ.Analysis.AnalysesResults.length; i++) {
|
||
if (YJ.Analysis.AnalysesResults[i].type === 'ContourAnalysis') {
|
||
YJ.Analysis.AnalysesResults[i].destroy()
|
||
}
|
||
}
|
||
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()
|
||
let cdoptions = this.deepCopyObj(this.options)
|
||
cdoptions.host = ''
|
||
this.Dialog.confirmCallBack && this.Dialog.confirmCallBack(cdoptions)
|
||
},
|
||
// 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 = `
|
||
<span class="custom-divider"></span>
|
||
<div class="div-item">
|
||
<div class="row">
|
||
<div class="col">
|
||
<span class="label">名称:</span>
|
||
<input class="input name" type="text">
|
||
</div>
|
||
</div>
|
||
</div>
|
||
`
|
||
contentElm.innerHTML = html
|
||
let nameElm = contentElm.getElementsByClassName('name')[0]
|
||
nameElm.value = this.name
|
||
nameElm.addEventListener('input', () => {
|
||
this.name = nameElm.value
|
||
})
|
||
this._DialogObject.contentAppChild(contentElm)
|
||
this._elms.name = [nameElm]
|
||
}
|
||
|
||
flicker() { }
|
||
}
|
||
|
||
export default BaseTerrain
|