2025-07-03 13:54:01 +08:00
|
|
|
|
/**
|
|
|
|
|
* @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";
|
2025-07-23 16:42:47 +08:00
|
|
|
|
import { setActiveViewer, closeRotateAround, closeViewFollow } from '../../../../Global/global'
|
2025-07-03 13:54:01 +08:00
|
|
|
|
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({})
|
2025-07-23 16:42:47 +08:00
|
|
|
|
for (let i = 0; i < YJ.Analysis.AnalysesResults.length; i++) {
|
|
|
|
|
if (YJ.Analysis.AnalysesResults[i].type === 'ContourAnalysis') {
|
|
|
|
|
YJ.Analysis.AnalysesResults[i].destroy()
|
|
|
|
|
}
|
|
|
|
|
}
|
2025-07-03 13:54:01 +08:00
|
|
|
|
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)
|
2025-07-23 16:42:47 +08:00
|
|
|
|
closeViewFollow(this.sdk)
|
2025-07-03 13:54:01 +08:00
|
|
|
|
|
|
|
|
|
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()
|
2025-07-11 09:19:20 +08:00
|
|
|
|
let cdoptions = this.deepCopyObj(this.options)
|
|
|
|
|
cdoptions.host = ''
|
|
|
|
|
this.Dialog.confirmCallBack && this.Dialog.confirmCallBack(cdoptions)
|
2025-07-03 13:54:01 +08:00
|
|
|
|
},
|
|
|
|
|
// 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
|