代码迁移

This commit is contained in:
zh
2025-07-03 13:54:01 +08:00
parent b04de8a084
commit 2a4da33e62
985 changed files with 358292 additions and 13 deletions

View File

@ -0,0 +1,73 @@
/**
* @name: index
* @author: Administrator
* @date: 2023-11-20 19:00
* @descriptionindex
* @update: 2023-11-20 19:00
*/
import BaseLayer from "../index";
import { setSplitDirection, setActiveId } from '../../../../../Global/SplitScreen'
class ArcgisLayer extends BaseLayer {
constructor(sdk, options = {}) {
super(sdk, options);
}
get type() {
return "layer"
}
async createArcGis(url) {
let imageryProvider
if (Number(Cesium.VERSION.split('.')[1]) >= 107) {
imageryProvider = await Cesium.ArcGisMapServerImageryProvider.fromUrl(url);
}
else {
imageryProvider = new Cesium.ArcGisMapServerImageryProvider({
url
});
}
if (this.options.hasOwnProperty("layer_index")) {
this.entity = this.sdk.viewer.imageryLayers.addImageryProvider(imageryProvider, this.options.layer_index)
} else {
this.entity = this.sdk.viewer.imageryLayers.addImageryProvider(imageryProvider,)
}
for (let i = 0; i < this.sdk.viewer.imageryLayers._layers.length; i++) {
if (this.sdk.viewer.imageryLayers._layers[i]._imageryProvider && this.sdk.viewer.imageryLayers._layers[i]._imageryProvider._type && (this.sdk.viewer.imageryLayers._layers[i]._imageryProvider._type === 'flw' || this.sdk.viewer.imageryLayers._layers[i]._imageryProvider._type === 'jww')) {
let layer = this.sdk.viewer.imageryLayers._layers[i]
this.sdk.viewer.imageryLayers.raiseToTop(layer)
}
}
this.show = this.options.show
this.alpha = this.options.alpha
this.brightness = this.options.brightness
if(this.options.show) {
setSplitDirection(0, this.options.id)
}
}
}
class ArcgisWXImagery extends ArcgisLayer {
constructor(sdk, options) {
super(sdk, options);
this.createArcGis("https://services.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer")
}
}
class ArcgisBLUEImagery extends ArcgisLayer {
constructor(sdk, options) {
super(sdk, options);
this.createArcGis("https://map.geoq.cn/arcgis/rest/services/ChinaOnlineStreetPurplishBlue/MapServer")
}
}
class ArcgisLWImagery extends ArcgisLayer {
constructor(sdk, options) {
super(sdk, options);
this.createArcGis("https://services.arcgisonline.com/ArcGIS/rest/services/World_Street_Map/MapServer")
}
}
export {ArcgisWXImagery, ArcgisBLUEImagery, ArcgisLWImagery}

View File

@ -0,0 +1,71 @@
import BaseLayer from "../index";
import { setSplitDirection, setActiveId } from '../../../../../Global/SplitScreen'
/**
* @name: index
* @author: Administrator
* @date: 2023-11-20 19:18
* @descriptionindex
* @update: 2023-11-20 19:18
*/
class GdImagery extends BaseLayer {
constructor(sdk, options = {}) {
super(sdk, options);
}
get type() {
return "layer"
}
createGD(url) {
let gdLayer = new Cesium.UrlTemplateImageryProvider({
url,
minimumLevel: 3,
maximumLevel: 18,
tilingScheme: this.amapMercatorTilingScheme()
})
if (this.options.hasOwnProperty("layer_index")) {
this.entity = this.sdk.viewer.imageryLayers.addImageryProvider(gdLayer, this.options.layer_index)
} else {
this.entity = this.sdk.viewer.imageryLayers.addImageryProvider(gdLayer,)
}
for (let i = 0; i < this.sdk.viewer.imageryLayers._layers.length; i++) {
if (this.sdk.viewer.imageryLayers._layers[i]._imageryProvider && this.sdk.viewer.imageryLayers._layers[i]._imageryProvider._type && (this.sdk.viewer.imageryLayers._layers[i]._imageryProvider._type === 'flw' || this.sdk.viewer.imageryLayers._layers[i]._imageryProvider._type === 'jww')) {
let layer = this.sdk.viewer.imageryLayers._layers[i]
this.sdk.viewer.imageryLayers.raiseToTop(layer)
}
}
this.show = this.options.show
this.alpha = this.options.alpha
this.brightness = this.options.brightness
if(this.options.show) {
setSplitDirection(0, this.options.id)
}
}
}
class GDLWImagery extends GdImagery {
constructor(earth, options = {}) {
super(earth, options);
this.createGD("https://webst02.is.autonavi.com/appmaptile?x={x}&y={y}&z={z}&lang=zh_cn&size=1&scale=1&style=8")
}
}
class GDWXImagery extends GdImagery {
constructor(earth, options = {}) {
super(earth, options);
this.createGD("https://webst02.is.autonavi.com/appmaptile?style=6&x={x}&y={y}&z={z}")
}
}
class GDSLImagery extends GdImagery {
constructor(earth, options = {}) {
super(earth, options);
this.createGD("https://webrd02.is.autonavi.com/appmaptile?lang=zh_cn&size=1&scale=1&style=8&x={x}&y={y}&z={z}")
}
}
export {GDLWImagery, GDWXImagery, GDSLImagery}

View File

@ -0,0 +1,146 @@
/**
* @name: index
* @author: Administrator
* @date: 2023-11-20 15:51
* @descriptionindex
* @update: 2023-11-20 15:51
*/
import { getHost } from "../../../../../on";
import { syncData } from '../../../../../Global/MultiViewportMode'
import BaseLayer from "../index";
import { setSplitDirection, setActiveId } from '../../../../../Global/SplitScreen'
class Layer extends BaseLayer {
constructor(sdk, options = {}) {
super(sdk, options)
this.object = {}
this.options.host = this.options.host || getHost()
}
get type() {
return "layer"
}
on() {
return this.add()
}
async add() {
let res = await this.requestResource()
let text = await res.text()
text = JSON.parse(text)
if ([0, 200].includes(text.code)) {
return this.loadLayer(text.data)
} else {
return new Promise((res, reject) => {
reject(text.msg || text.message)
})
}
}
async loadLayer(data) {
this.object = { ...data }
let url = ""
if (this.object.url.startsWith("http"))
url = this.object.url
else {
if (this.options.host) {
let o = new URL(this.object.url, this.options.host)
url = o.href
} else
url = this.object.url
}
let params = {
url: url,
mimmumLevel: this.object.minimumLevel,
maximumLevel: this.object.maximumLevel,
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)
),
}
// if (this.object.scheme_name === "GeographicTilingScheme") {
// console.log("添加GeographicTilingScheme")
// params.tilingScheme = new Cesium.GeographicTilingScheme()
// }
// if (this.object.scheme_name === "amapMercatorTilingScheme") {
// console.log("添加amapMercatorTilingScheme")
// params.tilingScheme = this.amapMercatorTilingScheme()
// }
let layer
// if (this.object.tiletrans === 'tms') {
// params.url = params.url.substr(0, params.url.indexOf('{'))
// tms = new Cesium.TileMapServiceImageryProvider(params)
// } else {
// tms = new Cesium.UrlTemplateImageryProvider(params)
// }
switch (this.object.scheme_name) {
case "amapMercatorTilingScheme":
params.tilingScheme = this.amapMercatorTilingScheme()
break;
case "":
break;
default:
params.tilingScheme = new Cesium[this.object.scheme_name]()
break;
}
switch (this.object.load_method) {
case "tms":
if(this.object.url.endsWith("tilemapresource.xml")){
let arr = this.object.url.split("/")
arr.pop()
let url = arr.join("/")
params.url = url
}
if (Number(Cesium.VERSION.split('.')[1]) >= 107) {
layer = await Cesium.TileMapServiceImageryProvider.fromUrl(params.url, params);
}
else {
layer = new Cesium.TileMapServiceImageryProvider(params)
}
break;
case "xyz":
layer = new Cesium.UrlTemplateImageryProvider(params)
break;
case "wmts":
layer = new Cesium.WebMapTileServiceImageryProvider(params)
break;
default:
layer = new Cesium.UrlTemplateImageryProvider(params)
break;
}
if(!this.sdk || !this.sdk.viewer) {
return
}
if (this.options.hasOwnProperty("layer_index")) {
this.entity =
this.sdk.viewer.scene.imageryLayers.addImageryProvider(layer, this.options.layer_index)
} else {
this.entity =
this.sdk.viewer.scene.imageryLayers.addImageryProvider(layer,)
}
for (let i = 0; i < this.sdk.viewer.imageryLayers._layers.length; i++) {
if (this.sdk.viewer.imageryLayers._layers[i]._imageryProvider && this.sdk.viewer.imageryLayers._layers[i]._imageryProvider._type && (this.sdk.viewer.imageryLayers._layers[i]._imageryProvider._type === 'flw' || this.sdk.viewer.imageryLayers._layers[i]._imageryProvider._type === 'jww')) {
let layer = this.sdk.viewer.imageryLayers._layers[i]
this.sdk.viewer.imageryLayers.raiseToTop(layer)
}
}
this.show = this.options.show
this.alpha = this.options.alpha
this.brightness = this.options.brightness
if(this.options.show) {
setSplitDirection(0, this.options.id)
}
}
}
export default Layer

View File

@ -0,0 +1,57 @@
/**
* @name: index
* @author: Administrator
* @date: 2023-11-20 15:51
* @descriptionindex
* @update: 2023-11-20 15:51
*/
import BaseLayer from "../index";
import { setSplitDirection, setActiveId } from '../../../../../Global/SplitScreen'
class Layer3rdparty extends BaseLayer {
constructor(sdk, options = {}) {
super(sdk, options)
this.loadLayer()
}
get type() {
return "layer"
}
loadLayer(data) {
let params = {
url: this.options.url,
mimmumLevel: this.options.minimumLevel || 0,
maximumLevel: this.options.maximumLevel || 20,
subdomains: ['0','1','2','3','4','5','6','7'],
}
let layer
layer = new Cesium.UrlTemplateImageryProvider(params)
if (this.options.hasOwnProperty("layer_index")) {
this.entity =
this.sdk.viewer.scene.imageryLayers.addImageryProvider(layer, this.options.layer_index)
} else {
this.entity =
this.sdk.viewer.scene.imageryLayers.addImageryProvider(layer,)
}
for (let i = 0; i < this.sdk.viewer.imageryLayers._layers.length; i++) {
if (this.sdk.viewer.imageryLayers._layers[i]._imageryProvider && this.sdk.viewer.imageryLayers._layers[i]._imageryProvider._type && (this.sdk.viewer.imageryLayers._layers[i]._imageryProvider._type === 'flw' || this.sdk.viewer.imageryLayers._layers[i]._imageryProvider._type === 'jww')) {
let layer = this.sdk.viewer.imageryLayers._layers[i]
this.sdk.viewer.imageryLayers.raiseToTop(layer)
}
}
this.show = this.options.show
this.alpha = this.options.alpha
this.brightness = this.options.brightness
if(this.options.show) {
setSplitDirection(0, this.options.id)
}
}
}
export default Layer3rdparty

View File

@ -0,0 +1,311 @@
/**
* @name: index
* @author: Administrator
* @date: 2023-11-20 18:06
* @descriptionindex
* @update: 2023-11-20 18:06
*/
import Dialog from '../../../Element/Dialog';
import CoordTransform from "../../../../transform/CoordTransform";
import BaseSource from "../index";
import { syncData } from '../../../../Global/MultiViewportMode'
import { setSplitDirection, syncSplitData } from '../../../../Global/SplitScreen'
import { setActiveViewer, closeRotateAround, closeViewFollow } from '../../../../Global/global'
class BaseLayer extends BaseSource {
constructor(sdk, options, _Dialog = {}) {
super(sdk, options);
this.options.name = options.name || '未命名对象'
this.Dialog = _Dialog
this._elms = {};
}
setDefaultValue() {
super.setDefaultValue();
this.options.alpha = this.options.alpha ?? 1
this.options.brightness = this.options.brightness ?? 1
}
get layerIndex() {
return this.entity._layerIndex
}
get layer_index() {
return this.entity._layerIndex
}
get brightness() {
return this.options.brightness
}
set brightness(v) {
this.options.brightness = v
this.entity.brightness = v
}
get alpha() {
return this.options.alpha
}
set alpha(v) {
if (Number(v) > 1) v = 1
if (Number(v) < 0) v = 0
this.entity.alpha = v
this.options.alpha = v
this._elms.alpha && this._elms.alpha.forEach((item) => {
item.value = v
})
}
/**@description 提高图层的一层层级
* @method layerRaise
* @param id {string} 图层id
*@memberOf Layer
* */
layerRaise(id) {
this.sdk.viewer.imageryLayers.raise(this.entity)
for (let i = 0; i < this.sdk.viewer.imageryLayers._layers.length; i++) {
if (this.sdk.viewer.imageryLayers._layers[i]._imageryProvider && this.sdk.viewer.imageryLayers._layers[i]._imageryProvider._type && (this.sdk.viewer.imageryLayers._layers[i]._imageryProvider._type === 'flw' || this.sdk.viewer.imageryLayers._layers[i]._imageryProvider._type === 'jww')) {
let layer = this.sdk.viewer.imageryLayers._layers[i]
this.sdk.viewer.imageryLayers.raiseToTop(layer)
}
}
this.options.layer_index = this.entity._layerIndex
return this.entity._layerIndex
}
/**@description 降低图层的一层层级
* @method layerLower
* @memberOf Layer
* */
layerLower() {
this.sdk.viewer.imageryLayers.lower(this.entity)
this.options.layer_index = this.entity._layerIndex
return this.entity._layerIndex
}
/**@description 置顶
* @method layerToTop
* @memberOf Layer
* */
layerToTop() {
this.sdk.viewer.imageryLayers.raiseToTop(this.entity)
for (let i = 0; i < this.sdk.viewer.imageryLayers._layers.length; i++) {
if (this.sdk.viewer.imageryLayers._layers[i]._imageryProvider && this.sdk.viewer.imageryLayers._layers[i]._imageryProvider._type && (this.sdk.viewer.imageryLayers._layers[i]._imageryProvider._type === 'flw' || this.sdk.viewer.imageryLayers._layers[i]._imageryProvider._type === 'jww')) {
let layer = this.sdk.viewer.imageryLayers._layers[i]
this.sdk.viewer.imageryLayers.raiseToTop(layer)
}
}
this.options.layer_index = this.entity._layerIndex
return this.entity._layerIndex
}
/**@description 置底
* @method lowerToBottom
* @memberOf Layer
* */
layerToBottom() {
this.sdk.viewer.imageryLayers.lowerToBottom(this.entity)
this.options.layer_index = this.entity._layerIndex
return this.entity._layerIndex
}
remove() {
super.remove()
this.sdk.viewer.scene.imageryLayers.remove(this.entity)
this.entity = null
}
/**@description 定位
* @method flyTo
* @memberOf Layer
* */
async flyTo(options = {}) {
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
})
}
else {
this.sdk.viewer.flyTo(this.entity)
}
}
/*高德的纠偏*/
amapMercatorTilingScheme(options) {
class AmapMercatorTilingScheme extends Cesium.WebMercatorTilingScheme {
constructor(options) {
super(options)
let projection = new Cesium.WebMercatorProjection()
this._projection.project = function (cartographic, result) {
result = CoordTransform.WGS84ToGCJ02(
Cesium.Math.toDegrees(cartographic.longitude),
Cesium.Math.toDegrees(cartographic.latitude)
)
result = projection.project(
new Cesium.Cartographic(
Cesium.Math.toRadians(result[0]),
Cesium.Math.toRadians(result[1])
)
)
return new Cesium.Cartesian2(result.x, result.y)
}
this._projection.unproject = function (cartesian, result) {
let cartographic = projection.unproject(cartesian)
result = CoordTransform.GCJ02ToWGS84(
Cesium.Math.toDegrees(cartographic.longitude),
Cesium.Math.toDegrees(cartographic.latitude)
)
return new Cesium.Cartographic(
Cesium.Math.toRadians(result[0]),
Cesium.Math.toRadians(result[1])
)
}
}
}
return new AmapMercatorTilingScheme(options)
}
/**
* @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)
syncData(this.sdk, this.options.id)
syncSplitData(this.sdk, this.options.id)
},
closeCallBack: () => {
this.reset()
this.Dialog.closeCallBack && this.Dialog.closeCallBack()
},
// resetCallBack: () => {
// this.name = this.originalOptions.name
// this.alpha = this.originalOptions.alpha
// 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" style="flex: 0 0 60px;">名称:</span>
<input class="input name" type="text">
</div>
</div>
<div class="row">
<div class="col">
<span class="label" style="flex: 0 0 60px;">透明度:</span>
<input type="range" class="alpha" min="0" max="1" step="0.01">
</div>
</div>
</div>
`
contentElm.innerHTML = html
let nameElm = contentElm.getElementsByClassName('name')[0]
let alphaElm = contentElm.getElementsByClassName('alpha')[0]
nameElm.value = this.name
alphaElm.value = this.alpha
nameElm.addEventListener('input', () => {
this.name = nameElm.value
})
alphaElm.addEventListener('input', () => {
this.alpha = alphaElm.value
})
this._DialogObject.contentAppChild(contentElm)
this._elms.name = [nameElm]
this._elms.alpha = [alphaElm]
}
reset() {
if (!this.entity && !this._DialogObject) {
return
}
this.options = this.deepCopyObj(this.originalOptions)
this.name = this.options.name
this.alpha = this.options.alpha
this.brightness = this.options.brightness
}
flicker() { }
}
export default BaseLayer

View File

@ -0,0 +1,196 @@
import { attributeElm, labelStyleElm1, labelStyleElm2 } from '../../../../Element/elm_html'
function html(that) {
return `
<span class="custom-divider"></span>
<div class="div-item">
<div class="row" style="align-items: flex-start;">
<div class="col">
<span class="label">名称</span>
<input class="input" maxlength="40" type="text" @model="name">
</div>
<div class="col">
<span class="label" style="flex: 0 0 60px;">颜色</span>
<div class="color"></div>
</div>
</div>
</div>
<span class="custom-divider"></span>
<div class="div-item">
<div class="row">
<div class="col">
<span class="label">经度</span>
<input class="input" type="number" title="" min="-180" max="180" @model="lng">
</div>
<div class="col">
<span class="label" style="flex: 0 0 60px;">最大比例</span>
<div class="input-number input-number-unit-1">
<input class="input" type="number" title="" min="0.1" max="99999" step="0.1" @model="maximumScale">
<span class="unit">倍</span>
<span class="arrow"></span>
</div>
</div>
</div>
<div class="row">
<div class="col">
<span class="label">纬度</span>
<input class="input" type="number" title="" min="-90" max="90" @model="lat">
</div>
<div class="col">
<span class="label" style="flex: 0 0 60px;">最小像素</span>
<div class="input-number input-number-unit-1">
<input class="input" type="number" title="" min="1" max="99999" @model="minimumPixelSize">
<span class="unit">px</span>
<span class="arrow"></span>
</div>
</div>
</div>
<div class="row">
<div class="col">
<span class="label">高度</span>
<div class="input-number input-number-unit-1">
<input class="input" type="number" title="" min="-99999" max="9999999" @model="alt">
<span class="unit">m</span>
<span class="arrow"></span>
</div>
</div>
<div class="col">
<span class="label">视野缩放</span>
<input class="btn-switch" type="checkbox" @model="scaleByDistance">
</div>
</div>
</div>
<div class="div-item">
<div class="row">
<DIV-cy-tabs id="model-edit-tabs">
<DIV-cy-tab-pane label="属性信息">
${attributeElm(that)}
</DIV-cy-tab-pane>
<DIV-cy-tab-pane label="方向信息">
<div>
<div class="row">
<p class="lable-left-line">旋转</p>
</div>
<div class="row">
<div class="col">
<span class="label">x 轴</span>
<input style="flex: 1;margin-right: 15px;" type="range" max="360" min="0" step="0.01" @model="rotateX">
<div class="input-number input-number-unit-1" style="width: auto;">
<input style="width: 100px;" type="number" title="" min="0" max="360" @model="rotateX">
<span class="unit">°</span>
<span class="arrow"></span>
</div>
</div>
</div>
<div class="row">
<div class="col">
<span class="label">y 轴</span>
<input style="flex: 1;margin-right: 15px;" type="range" max="360" min="0" step="0.01" @model="rotateY">
<div class="input-number input-number-unit-1" style="width: auto;">
<input style="width: 100px;" type="number" title="" min="0" max="360" @model="rotateY">
<span class="unit">°</span>
<span class="arrow"></span>
</div>
</div>
</div>
<div class="row">
<div class="col">
<span class="label">z 轴</span>
<input style="flex: 1;margin-right: 15px;" type="range" max="360" min="0" step="0.01" @model="rotateZ">
<div class="input-number input-number-unit-1" style="width: auto;">
<input style="width: 100px;" type="number" title="" min="0" max="360" @model="rotateZ">
<span class="unit">°</span>
<span class="arrow"></span>
</div>
</div>
</div>
<div class="row">
<div class="lable-left-line">
<span>缩放</span>
<div class="checkbox-box">
<input type="checkbox">
<span>是否等比例缩放</span>
</div>
</div>
</div>
<div class="row no-equal" style="display: none;">
<div class="row">
<div class="col">
<span class="label">x 轴</span>
<input style="flex: 1;margin-right: 15px;" type="range" max="99999" min="0" step="1" @model="scaleX">
<div class="input-number input-number-unit-1" style="width: auto;">
<input style="width: 100px;" type="number" title="" min="0" max="99999" @model="scaleX">
<span class="unit">倍</span>
<span class="arrow"></span>
</div>
</div>
</div>
<div class="row">
<div class="col">
<span class="label">y 轴</span>
<input style="flex: 1;margin-right: 15px;" type="range" max="99999" min="0" step="1" @model="scaleY">
<div class="input-number input-number-unit-1" style="width: auto;">
<input style="width: 100px;" type="number" title="" min="0" max="99999" @model="scaleY">
<span class="unit">倍</span>
<span class="arrow"></span>
</div>
</div>
</div>
<div class="row">
<div class="col">
<span class="label">z 轴</span>
<input style="flex: 1;margin-right: 15px;" type="range" max="99999" min="0" step="1" @model="scaleZ">
<div class="input-number input-number-unit-1" style="width: auto;">
<input style="width: 100px;" type="number" title="" min="0" max="99999" @model="scaleZ">
<span class="unit">倍</span>
<span class="arrow"></span>
</div>
</div>
</div>
</div>
<div class="row equal" style="display: none;">
<div class="row">
<div class="col">
<span class="label">等比例缩放</span>
<input style="flex: 1;margin-right: 15px;" type="range" max="99999" min="0" step="1">
<div class="input-number input-number-unit-1" style="width: auto;">
<input style="width: 100px;" type="number" title="" min="0" max="99999" step="1">
<span class="unit">倍</span>
<span class="arrow"></span>
</div>
</div>
</div>
</div>
<div class="row">
<p class="lable-left-line">高度</p>
</div>
<div class="row">
<div class="col">
<span class="label">高度</span>
<input style="flex: 1;margin-right: 15px;" type="range" max="999999" min="-99999" step="0.01" @model="alt">
<div class="input-number input-number-unit-1" style="width: auto;">
<input style="width: 100px;" type="number" title="" min="-99999" max="999999" @model="alt">
<span class="unit">m</span>
<span class="arrow"></span>
</div>
</div>
</div>
</div>
</DIV-cy-tab-pane>
<DIV-cy-tab-pane label="标注风格">
${labelStyleElm1()}
</DIV-cy-tab-pane>
<DIV-cy-tab-pane label="标签风格">
${labelStyleElm2()}
</DIV-cy-tab-pane>
</DIV-cy-tabs>
</div>
</div>
<span class="custom-divider"></span>
`
}
export { html }

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,123 @@
import { attributeElm, labelStyleElm1, labelStyleElm2 } from '../../../../Element/elm_html'
function html(that) {
return `
<div class="row" style="align-items: flex-start;">
<div class="col">
<span class="label">名称</span>
<input class="input" maxlength="40" type="text" @model="name">
</div>
<div class="col">
<span class="label">颜色</span>
<div class="color"></div>
</div>
</div>
<div class="row">
<div class="col">
<span class="label">经度</span>
<input class="input" type="number" title="" min="-180" max="180" @model="lng">
</div>
<div class="col">
<span class="label">最大比例</span>
<input class="input" type="number" title="" min="0.1" max="99999" step="0.1" @model="maximumScale">
</div>
</div>
<div class="row">
<div class="col">
<span class="label">纬度</span>
<input class="input" type="number" title="" min="-90" max="90" @model="lat">
</div>
<div class="col">
<span class="label">最小像素</span>
<input class="input" type="number" title="" min="1" max="99999" @model="minimumPixelSize">
</div>
</div>
<div class="row">
<div class="col">
<span class="label">高度</span>
<input class="input" type="number" title="" min="-9999999" max="999999999" @model="alt">
</div>
<div class="col">
<span class="label">视野缩放</span>
<input class="btn-switch" type="checkbox" @model="scaleByDistance">
</div>
</div>
<div class="row">
<DIV-cy-tabs id="model-edit-tabs">
<DIV-cy-tab-pane label="属性信息">
${attributeElm(that)}
</DIV-cy-tab-pane>
<DIV-cy-tab-pane label="方向信息">
<div>
<div class="row">
<div class="col">
<span class="label">x轴</span>
<input style="width: 332px;" type="range" max="360" min="0" step="0.01" @model="rotateX">
<input style="font-size: 13px;width: 100px;" type="number" title="" min="0" max="360" @model="rotateX">
</div>
</div>
<div class="row">
<div class="col">
<span class="label">y轴</span>
<input style="width: 332px;" type="range" max="360" min="0" step="0.01" @model="rotateY">
<input style="font-size: 13px;width: 100px;" type="number" title="" min="0" max="360" @model="rotateY">
</div>
</div>
<div class="row">
<div class="col">
<span class="label">z轴</span>
<input style="width: 332px;" type="range" max="360" min="0" step="0.01" @model="rotateZ">
<input style="font-size: 13px;width: 100px;" type="number" title="" min="0" max="360" @model="rotateZ">
</div>
</div>
<div class="row">
<div class="col">
<span class="label">高度</span>
<input style="width: 332px;" type="range" max="999999" min="-99999" step="0.01" @model="alt">
<input style="font-size: 13px;width: 100px;" type="number" title="" min="-99999" max="999999" @model="alt">
</div>
</div>
<div class="row">
<div class="col">
<span class="label">缩放</span>
<input style="width: 332px;" type="range" max="999" min="0" step="1" @model="scale">
<input style="font-size: 13px;width: 100px;" type="number" title="" min="0" max="999" step="1" @model="scale">
</div>
</div>
</div>
</DIV-cy-tab-pane>
<DIV-cy-tab-pane label="标注风格">
${labelStyleElm1()}
</DIV-cy-tab-pane>
<DIV-cy-tab-pane label="标签风格">
${labelStyleElm2()}
</DIV-cy-tab-pane>
</DIV-cy-tabs>
</div>
`
}
function css() {
return `
.YJ-custom-base-dialog>.content {
width: 600px;
}
.YJ-custom-base-dialog>.content>div>.row .col {
margin: 0 10px;
}
.YJ-custom-base-dialog>.content>div>.row .col:first-child {
margin-left: 0;
}
.YJ-custom-base-dialog>.content>div>.row .col:last-child {
margin-right: 0;
}
.YJ-custom-base-dialog>.content>div>.row .label {
flex: 0 0 74px;
}
.YJ-custom-base-dialog>.content .DIV-cy-tab-content-pane .input-select {
width: 100px;
}
`
}
export { html, css }

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,74 @@
import richText from "../../../Element/richText";
import BaseSource from "../index";
class BaseModel extends BaseSource {
constructor(sdk, options, _Dialog = {}) {
super(sdk, options);
}
async add() {
if (this.options.url) {
return this.loadModel(this.options.url)
}
}
_addLink() {
// document.getElementsByClassName
if (this._DialogObject._element.content.getElementsByClassName('link_add')[0].value) {
this.options.attribute.link.content.push({
name: this.getDateTimeString(),
url: this._DialogObject._element.content.getElementsByClassName('link_add')[0].value
})
this._DialogObject._element.content.getElementsByClassName('link_add')[0].value = ''
this.attributeLink = this.options.attribute.link.content
}
else {
this.Dialog.clickAddLink && this.Dialog.clickAddLink()
}
}
addAttributeLink(link) {
this.options.attribute.link.content.push({
name: this.getDateTimeString(),
url: link
})
this.attributeLink = this.options.attribute.link.content
}
_addRr() {
if (this._DialogObject._element.content.getElementsByClassName('vr_add')[0].value) {
this.options.attribute.vr.content.push({
name: '全景图' + (this.options.attribute.vr.content.length + 1),
url: this._DialogObject._element.content.getElementsByClassName('vr_add')[0].value
})
this._DialogObject._element.content.getElementsByClassName('vr_add')[0].value = ''
this.attributeVr = this.options.attribute.vr.content
}
else {
this.Dialog.clickAddVr && this.Dialog.clickAddVr()
}
}
addAttributeRr(vr) {
this.options.attribute.vr.content.push({
name: '全景图' + (this.options.attribute.vr.content.length + 1),
url: vr
})
this.attributeVr = this.options.attribute.vr.content
}
/**
* 打开富文本框
*/
openRichTextEditor(e) {
// var ue = UE.getEditor('app');
richText.open(this.options.id, this.options.name, this.options.richTextContent)
richText.primaryCallBack = (content) => {
this.options.richTextContent = content
}
}
}
export default BaseModel

View File

@ -0,0 +1,286 @@
/**
* @name: index
* @author: Administrator
* @date: 2023-11-20 17:54
* @descriptionindex
* @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 = `
<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

View File

@ -0,0 +1,93 @@
function html() {
return `
<span class="custom-divider"></span>
<div class="div-item">
<div class="row">
<div class="col">
<span class="label">名称</span>
<input class="input" @model="name">
</div>
<div class="col">
</div>
</div>
</div>
<span class="custom-divider"></span>
<div class="div-item">
<div class="row">
<div class="col">
<span class="label">经度</span>
<input class="input" type="number" title="" min="-180" max="180" @model="lng">
</div>
<div class="col">
<span class="label">x轴</span>
<input type="number" title="" min="-180" max="180" @model="roll">
</div>
</div>
<div class="row">
<div class="col">
<span class="label">纬度</span>
<input class="input" type="number" title="" min="-90" max="90" @model="lat">
</div>
<div class="col">
<span class="label">y轴</span>
<input type="number" title="" min="-180" max="180" @model="heading">
</div>
</div>
<div class="row">
<div class="col">
<span class="label">高度</span>
<div class="input-number input-number-unit-1">
<input class="input" type="number" title="" min="-9999999" max="999999999" @model="height">
<span class="unit">m</span>
<span class="arrow"></span>
</div>
</div>
<div class="col">
<span class="label">z轴</span>
<input type="number" title="" min="-180" max="180" @model="pitch">
</div>
</div>
<div class="row">
<div class="col">
<span class="label">大小</span>
<input type="range" max="10" min="0.1" step="0.1" @model="scale">
<div class="input-number" style="width: 100px;margin-left: 10px;">
<input type="number" title="" min="0" max="10" step="0.1" @model="scale">
<span class="arrow"></span>
</div>
</div>
</div>
</div>
<div class="divide">
<div class="line"></div>
<p>BIM属性导出选项</p>
<div class="line"></div>
</div>
<div class="row">
<div style="display: flex;">
<div class="checkbox-box" @click="exportState">
<input type="checkbox" value="3">
<span>修建中</span>
</div>
<div class="checkbox-box" @click="exportState">
<input type="checkbox" value="2">
<span>未完成</span>
</div>
<div class="checkbox-box" @click="exportState">
<input type="checkbox" value="1">
<span>已完成</span>
</div>
</div>
<div class="col">
<button @click="exportProperty">导 出</button>
</div>
</div>
<span class="custom-divider"></span>
`
}
export { html }

View File

@ -0,0 +1,82 @@
function html2() {
return `
<div class="row">
<div class="col">
<span class="label">构件名称</span>
<input class="input" name="name" disabled="disabled">
</div>
</div>
<div class="row">
<div class="col">
<span class="label">选择状态</span>
<select class="input input-select" name="state-select">
<option value="0" style="color: #000;">重置</option>
<option value="1" style="color: #f00;">已完成</option>
<option value="2" style="color: #0f0;">未完成</option>
<option value="3" style="color: #00f;">修建中</option>
</select>
</div>
</div>
<div class="divide">
<div class="line"></div>
<p>自定义属性</p>
<div class="line"></div>
</div>
<div class="property">
</div>
`
}
function css2() {
return `
.YJ-custom-base-dialog>.content {
width: 440px;
}
.YJ-custom-base-dialog>.content .row .label {
flex: 0 0 110px;
}
.col:first-child {
margin-right: 10px;
}
.col:last-child {
margin-left: 10px;
}
.YJ-custom-base-dialog>.content .divide {
position: relative;
display: flex;
align-items: center;
margin: 20px 0;
}
.YJ-custom-base-dialog>.content .divide .line{
height: 1px;
background: #ddd;
flex: 1;
}
.YJ-custom-base-dialog>.content .divide p{
margin: 0 10px;
}
.YJ-custom-base-dialog>.content .property .property-item .btn{
font-size: 24px;
line-height: 20px;
padding: 2px 0;
}
.YJ-custom-base-dialog>.content .property .property-item .input_lable {
flex: 0 0 115px;
border: none;
margin-right: 15px;
text-align: right;
}
.YJ-custom-base-dialog>.content .property .property-item:first-child .delete{
display: none
}
.YJ-custom-base-dialog>.content .property .property-item .add{
display: none;
}
.YJ-custom-base-dialog>.content .property .property-item:last-child .add{
display: inline-block;
}
`
}
export { html2, css2 }

View File

@ -0,0 +1,877 @@
/**
* @name: index
* @author: Administrator
* @date: 2023-11-20 16:05
* @descriptionindex
* @update: 2023-11-20 16:05
*/
import BaseTileset from "../index";
import { html } from "./_element";
import { html2, css2 } from "./_element2";
import Dialog from '../../../../Element/Dialog';
import EventBinding from '../../../../Element/Dialog/eventBinding';
import BaseDialog from '../../../../../BaseDialog'
import { syncData } from '../../../../../Global/MultiViewportMode'
import { syncSplitData } from '../../../../../Global/SplitScreen'
import { setActiveViewer, closeRotateAround, closeViewFollow} from '../../../../../Global/global'
class BIM extends BaseTileset {
#updateModelTimeout
/**
* @constructor
* @description 加载BIM模型
* @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.position {object} 模型位置
* @param options.position.lng {number} 经度
* @param options.position.lat {number} 纬度
* @param options.position.alt {number} 高度
* */
constructor(sdk, options = {}, _Dialog = {}) {
super(sdk, options)
this.picking = false
this.features = options.features || []
this.exportStateArray = []
this.Dialog = _Dialog
this._elms = {};
this._EventBinding = new EventBinding()
this.Dialog.exportState = (e) => {
this.exportState(e)
}
this.Dialog.exportProperty = (e) => {
this.exportProperty(this.exportStateArray)
}
this.features = new Map()
}
get type() {
return "bim"
}
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 lng() {
return this.newData.lng
}
set lng(v) {
this.newData.lng = v
this.updateModel(this.newData.lng, this.newData.lat, this.newData.height, this.newData.roll, this.newData.heading, this.newData.pitch, this.newData.scale)
this._elms.lng && this._elms.lng.forEach((item) => {
item.value = v
})
}
get lat() {
return this.newData.lat
}
set lat(v) {
this.newData.lat = v
this.updateModel(this.newData.lng, this.newData.lat, this.newData.height, this.newData.roll, this.newData.heading, this.newData.pitch, this.newData.scale)
this._elms.lat && this._elms.lat.forEach((item) => {
item.value = v
})
}
get height() {
return this.newData.height
}
set height(v) {
this.newData.height = v
this.updateModel(this.newData.lng, this.newData.lat, this.newData.height, this.newData.roll, this.newData.heading, this.newData.pitch, this.newData.scale)
this._elms.height && this._elms.height.forEach((item) => {
item.value = v
})
}
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)
this._elms.roll && this._elms.roll.forEach((item) => {
item.value = v
})
}
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)
this._elms.heading && this._elms.heading.forEach((item) => {
item.value = v
})
}
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)
this._elms.pitch && this._elms.pitch.forEach((item) => {
item.value = v
})
}
get scale() {
return this.newData.scale
}
set scale(v) {
this.newData.scale = v
this.updateModel(this.newData.lng, this.newData.lat, this.newData.height, this.newData.roll, this.newData.heading, this.newData.pitch, this.newData.scale)
this._elms.scale && this._elms.scale.forEach((item) => {
item.value = v
})
}
// get transparency() {
// return this.newData.transparency
// }
// set transparency(v) {
// this.newData.transparency = v
// this.entity.style = new Cesium.Cesium3DTileStyle({
// color: "color('rgba(255,255,255," + this.newData.transparency + ")')",
// show: true,
// });
// this.entity.transparency = Number(this.newData.transparency)
// this._elms.transparency && this._elms.transparency.forEach((item) => {
// item.value = v
// })
// }
async loadSceneTree(url) {
// Cesium.ExperimentalFeatures.enableModelExperimental = true;
let array = url.split('/')
array[array.length - 1] = 'scenetree.json'
await Cesium.Resource.fetchJson({
url: array.join('/')
}).then(res => {
this.scenetree = res
const initData = (array) => {
array.forEach(item => {
if (this.features.has(item.id)) {
this.features.get(item.id).sphere = item.sphere
}
else {
this.features.set(item.id, { sphere: item.sphere })
}
if (item.children) {
initData(item.children)
}
})
}
initData(res.scenes[0].children)
// res.scenes[0].children.forEach(item => {
// if (this.features.has(item.id)) {
// this.features.get(item.id).sphere = item.sphere
// }
// else {
// this.features.set(item.id, {sphere: item.sphere})
// }
// })
})
}
// 编辑框
async edit(state) {
let _this = this
this.originalOptions = this.deepCopyObj(this.options)
if (this._DialogObject && this._DialogObject.close) {
this._DialogObject.close()
this._DialogObject = null
}
if (state) {
this._DialogObject = await new Dialog(this.sdk, this.newData, {
title: 'BIM模型属性', left: '180px', top: '100px',
resetCallBack: () => {
this.reset()
this.Dialog.resetCallBack && this.Dialog.resetCallBack()
},
confirmCallBack: (info) => {
this.name = this.name.trim()
if (!this.name) {
this.name = '未命名对象'
}
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._DialogObject.close()
let features = new Map()
this.features.forEach((item, key) => {
let data = { ...item }
delete data.features
features.set(key, data)
})
this.Dialog.confirmCallBack && this.Dialog.confirmCallBack({ ...this.oldData, features: features, type: this.type })
syncSplitData(this.sdk, this.oldData.id)
},
removeCallBack: () => {
this.Dialog.removeCallBack && this.Dialog.removeCallBack()
},
closeCallBack: () => {
this.reset()
// this.newData.transparency = this.oldData.transparency
// this.newData.name = this.oldData.name
// this.newData.height = this.oldData.height
// this.newData.lng = this.oldData.lng
// this.newData.lat = this.oldData.lat
// this.newData.scale = this.oldData.scale
// this.entity.style = new Cesium.Cesium3DTileStyle({
// color: "color('rgba(255,255,255," + this.newData.transparency + ")')",
// show: true,
// });
this.editObj.destroy()
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
}
}
})
this._DialogObject._element.body.className = this._DialogObject._element.body.className + ' tileset-bim'
// 内容部分
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._DialogObject && this._DialogObject.close) {
this._DialogObject.close()
this._DialogObject = null
}
}
}
async featureEdit(state, feature) {
let _this = this
this._element_style = null
if (this._DialogObject && this._DialogObject.close) {
this._DialogObject.close()
this._DialogObject = null
}
if (state) {
// console.log(this.entity)
// console.log(this.entity.root.children[0].content)
// console.log(feature.getProperty('id'), feature.getProperty('name'), feature.getProperty('state'))
let name = feature.getProperty('name')
// console.log(feature.getProperty('descriptions'))
let data = {
id: feature.getProperty('id'),
name: name,
state: feature.getProperty('state') || 0,
descriptions: feature.getProperty('descriptions') || [
{
id: this.randomString(),
key: "点击此处可编辑",
value: ""
}
]
}
switch (feature.getProperty('state')) {
case '0': data.stateCH = ''
break
case '1': data.stateCH = '已完成'
break
case '2': data.stateCH = '未完成'
break
case '3': data.stateCH = '修建中'
break
}
// let feature = this.entity.root.children[0].content.getFeature(0)
// console.log(id,feature, this.entity)
// return
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 = css2();
this._DialogObject = await new BaseDialog(this.sdk.viewer._container, {
title: this.oldData.name + '-----设置状态', left: 'calc(50% - 200px)', top: 'calc(50% - 200px)',
closeCallBack: () => {
this.Dialog.closeCallBack && this.Dialog.closeCallBack()
}
})
await this._DialogObject.init()
document.getElementsByTagName('head')[0].appendChild(this._element_style);
// 内容部分
let content = document.createElement('div');
content.innerHTML = html2()
// 名称
let e_name = content.querySelector("input[name='name']")
e_name.value = name
//状态
let e_state = content.querySelector("select[name='state-select']")
e_state.value = data.state
e_state.addEventListener('change', (e) => {
data.state = e.target.value
switch (data.state) {
case '0': data.stateCH = ''
break
case '1': data.stateCH = '已完成'
break
case '2': data.stateCH = '未完成'
break
case '3': data.stateCH = '修建中'
break
}
});
//自定义属性
let e_property = content.getElementsByClassName('property')[0]
for (let i = 0; i < data.descriptions.length; i++) {
createPropertyItem(data.descriptions[i], i)
}
function createPropertyItem(item) {
let html = `<div class="row property-item">
<div class="col">
<input class="input_lable" name="key" value="${item.key}">
<input class="input" name="value" value="${item.value}">
<button class="btn add"></button>
<button class="btn delete"></button>
</div>
</div>`
// document.createRange().createContextualFragment(html)
let newElement = document.createElement("div");
newElement.innerHTML = html
let itemElm = newElement.getElementsByClassName('property-item')[0]
let e_key = itemElm.querySelector("input[name='key']")
let e_value = itemElm.querySelector("input[name='value']")
let e_add = itemElm.getElementsByClassName('add')[0]
let e_delete = itemElm.getElementsByClassName('delete')[0]
e_key.addEventListener('input', (e) => {
item.key = e.target.value
})
e_value.addEventListener('input', (e) => {
item.value = e.target.value
})
e_add.addEventListener('click', () => {
let newItem = {
id: _this.randomString(),
key: "点击此处可编辑",
value: ""
}
data.descriptions.push(newItem)
createPropertyItem(newItem)
})
e_delete.addEventListener('click', (e) => {
for (let i = 0; i < data.descriptions.length; i++) {
if (data.descriptions[i].id === item.id) {
data.descriptions.splice(i, 1)
break
}
}
e_property.removeChild(itemElm)
// let item = {
// key: "点击此处可编辑",
// value: ""
// }
// createPropertyItem(item)
})
e_property.appendChild(itemElm)
}
let target = this._DialogObject._element.foot.getElementsByClassName('translational')[0]
this._DialogObject.contentAppChild(content)
// foot部分
let confirmBtn = document.createElement('button');
confirmBtn.className = 'confirm';
confirmBtn.innerHTML = '确认'
this._DialogObject.footAppChild(confirmBtn, target)
confirmBtn.addEventListener('click', () => {
let flag = false
for (let i = 0; i < this.features.length; i++) {
if (this.features[i].id == data.id) {
this.features[i] = data
flag = true
break
}
}
if (!flag) {
this.features.push(data)
}
feature.setProperty('state', data.state)
feature.setProperty('descriptions', data.descriptions)
let color = '#fff'
switch (data.state) {
case '0':
color = '#fff'
break;
case '1':
color = '#f00'
break;
case '2':
color = '#0f0'
break;
case '3':
color = '#00f'
break;
default:
}
feature.color = Cesium.Color.fromCssColorString(color)
this._DialogObject.close()
this.Dialog.confirmCallBack && this.Dialog.confirmCallBack({ ...this.newData, features: this.features })
});
} else {
if (this._element_style) {
document.getElementsByTagName('head')[0].removeChild(this._element_style)
this._element_style = null
}
if (this._DialogObject && this._DialogObject.close) {
this._DialogObject.close()
this._DialogObject = null
}
}
}
reset() {
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
}
//更新模型位置
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)
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);
}
// exportProperty(states) {
// console.log(this.features)
// let fieldKeys = ['name', '', '', '', '', '', '', '', '', '', '', '', 'stateCH', 'descriptions']
// let fieldLabels = ['构件名称', '体积', '墩全高H', '墩身高h', '底部高程', '承台宽', '承台长', '承台高', '族', '桩径', '桩长', '结构材质', '完成情况', '自定义属性']
// let dataStr = fieldLabels.toString() + '\r\n';
// for (let i = 0; i < this.features.length; i++) {
// for (let j = 0; j < states.length; j++) {
// if (this.features[i].state == states[j]) {
// fieldKeys.forEach(key => {
// if (Array.isArray(this.features[i][key])) {
// let str = ''
// for (let k in this.features[i][key]) {
// str += `${this.features[i][key][k].key + '' + this.features[i][key][k].value}\n`
// }
// dataStr += `"${str}"\t`
// }
// else {
// // 加引号是为了使换行符在单元格内正常显示
// dataStr += `"${this.features[i][key] ? this.features[i][key] : ''}"\t,`;
// }
// });
// dataStr += '\r\n';
// break
// }
// }
// }
// // encodeURIComponent 解决中文乱码
// const url = "data:text/xls;charset=utf-8,\ufeff" + encodeURIComponent(dataStr);
// console.log(url)
// // const link = document.createElement("a");
// // link.href = url;
// // link.download = this.oldData.name + "--构件属性.xls";
// // link.style.display = 'none';
// // document.body.appendChild(link);
// // link.click();
// // document.body.removeChild(link); //释放标签
// }
getScenetree() {
return this.scenetree
}
// 设置feature颜色
featureColor(id, color) {
if (this.features.has(id)) {
let features = this.features.get(id).features
for (let key in features) {
if (features[key].content._model) {
features[key].color = Cesium.Color.fromCssColorString(color)
}
features[key].customColor = Cesium.Color.fromCssColorString(color)
}
this.features.get(id).customColor = Cesium.Color.fromCssColorString(color)
}
}
getFeatureColor(id) {
if (this.features.has(id)) {
if (this.features.get(id).customColor) {
return this.features.get(id).customColor
}
let features = this.features.get(id).features
for (let key in features) {
if (features[key].content._model) {
return features[key].customColor || features[key].color
}
}
}
}
// 设置feature显隐
featureShow(id, show) {
if (this.features.has(id)) {
let features = this.features.get(id).features
for (let key in features) {
if (features[key].content._model) {
features[key].show = show
}
features[key].customShow = show
}
this.features.get(id).customShow = show
}
}
//飞到feature位置
async featureFlyto(id) {
if (this.features.has(id)) {
let sphere = this.features.get(id).sphere
let center = new Cesium.Cartesian3(
sphere[0],
sphere[1],
sphere[2]
)
let srcMatInv = this.entity._root.originalTransform
srcMatInv = Cesium.Matrix4.inverse(srcMatInv, new Cesium.Matrix4())
let curMat = this.entity._root.transform
let mat = Cesium.Matrix4.multiply(curMat, srcMatInv, new Cesium.Matrix4())
let center2 = Cesium.Matrix4.multiplyByPoint(
mat,
center,
new Cesium.Cartesian3()
)
let wgs84 = this.cartesian3Towgs84(center2, this.sdk.viewer)
let cartesian3 = Cesium.Cartesian3.fromDegrees(
wgs84.lng,
wgs84.lat,
wgs84.alt + sphere[3]
)
setActiveViewer(0)
closeRotateAround(this.sdk)
closeViewFollow(this.sdk)
this.sdk.viewer.camera.flyTo({
destination: cartesian3
})
// this.entity.style = await new Cesium.Cesium3DTileStyle({
// color: "color('rgba(255,255,255,0.2)')"
// });
this.features.forEach((item, key) => {
if (key === id) {
let color = this.getFeatureColor(id)
if (this.features.has(id) && color) {
let features = this.features.get(id).features
for (let k in features) {
if (features[k].content._model) {
features[k].color = color
}
features[k].customAlpha = 1
}
this.features.get(id).customAlpha = 1
}
// this.featureColor(id, `rgba(${Cesium.Color.floatToByte(color.red)},${Cesium.Color.floatToByte(color.green)},${Cesium.Color.floatToByte(color.blue)},${color.alpha})`)
}
else {
let color = this.getFeatureColor(key)
if (this.features.has(key) && color) {
let features = this.features.get(key).features
for (let k in features) {
if (features[k].content._model) {
features[k].color = Cesium.Color.fromCssColorString(`rgba(${Cesium.Color.floatToByte(color.red)},${Cesium.Color.floatToByte(color.green)},${Cesium.Color.floatToByte(color.blue)},${color.alpha * 0.2})`)
}
features[k].customAlpha = color.alpha * 0.2
}
this.features.get(key).customAlpha = color.alpha * 0.2
}
// this.featureColor(key, `rgba(${Cesium.Color.floatToByte(color.red)},${Cesium.Color.floatToByte(color.green)},${Cesium.Color.floatToByte(color.blue)},${color.alpha * 0.2})`)
}
})
// this.entity.readyPromise.then(()=>{
// this.featureColor(id, '#ffffff')
// })
}
else {
this.features.forEach((item, key) => {
let features = this.features.get(key).features
let color = this.getFeatureColor(key)
if (color) {
for (let k in features) {
if (features[k].content._model) {
features[k].color = color
}
features[k].customAlpha = 1
}
this.features.get(key).customAlpha = color.alpha * 0.2
}
})
}
}
// 导出属性
exportProperty(states) {
if (this.exportStateArray.length === 0) {
window.ELEMENT && window.ELEMENT.Message({
message: '未选择属性导出选项!',
type: 'warning',
duration: 1500
});
return
}
let fieldKeys = ['name', '', '', '', '', '', '', '', '', '', '', '', 'stateCH', 'descriptions']
let fieldLabels = ['构件名称', '体积', '墩全高H', '墩身高h', '底部高程', '承台宽', '承台长', '承台高', '族', '桩径', '桩长', '结构材质', '完成情况', '自定义属性']
var url = 'data:application/vnd.ms-excel;base64,',
tmplWorkbookXML = '<?xml version="1.0"?><?mso-application progid="Excel.Sheet"?><Workbook xmlns="urn:schemas-microsoft-com:office:spreadsheet" xmlns:ss="urn:schemas-microsoft-com:office:spreadsheet">'
+ '<DocumentProperties xmlns="urn:schemas-microsoft-com:office:office"><Author>Axel Richter</Author><Created>{created}</Created></DocumentProperties>'
+ '<Styles>'
+ '<Style ss:ID="Currency"><NumberFormat ss:Format="Currency"></NumberFormat></Style>'
+ '<Style ss:ID="Date"><NumberFormat ss:Format="Medium Date"></NumberFormat></Style>'
+ '</Styles>'
+ '{worksheets}</Workbook>'
, tmplWorksheetXML = '<Worksheet ss:Name="{nameWS}"><Table><ss:Column ss:Width="120"/><ss:Column ss:Width="120"/><ss:Column ss:Width="120"/><ss:Column ss:Width="120"/><ss:Column ss:Width="120"/><ss:Column ss:Width="120"/><ss:Column ss:Width="120"/><ss:Column ss:Width="120"/><ss:Column ss:Width="120"/><ss:Column ss:Width="120"/><ss:Column ss:Width="120"/><ss:Column ss:Width="120"/><ss:Column ss:Width="120"/><ss:Column ss:Width="240"/>{rows}</Table></Worksheet>'
, tmplCellXML = '<Cell><Data ss:Type="{nameType}">{data}</Data></Cell>'
, base64 = function (s) {
return window.btoa(unescape(encodeURIComponent(s)))
}
, format = function (s, c) {
return s.replace(/{(\w+)}/g, function (m, p) {
return c[p];
})
}
var ctx = "";
var workbookXML = "";
var worksheetsXML = "";
var rowsXML = "";
var pil = 0;
for (var i = 0; i < this.features.length; i++) {
for (let j = 0; j < states.length; j++) {
if (this.features[i].state == states[j]) {
if (i == 0) {
rowsXML += '<Row>' +
'<Cell><Data ss:Type="String">构件名称</Data></Cell>' +
'<Cell><Data ss:Type="String">体积</Data></Cell>' +
'<Cell><Data ss:Type="String">墩全高H</Data></Cell>' +
'<Cell><Data ss:Type="String">墩身高h</Data></Cell>' +
'<Cell><Data ss:Type="String">底部高程</Data></Cell>' +
'<Cell><Data ss:Type="String">承台宽</Data></Cell>' +
'<Cell><Data ss:Type="String">承台长</Data></Cell>' +
'<Cell><Data ss:Type="String">承台高</Data></Cell>' +
'<Cell><Data ss:Type="String">族</Data></Cell>' +
'<Cell><Data ss:Type="String">桩径</Data></Cell>' +
'<Cell><Data ss:Type="String">桩长</Data></Cell>' +
'<Cell><Data ss:Type="String">结构材质</Data></Cell>' +
'<Cell><Data ss:Type="String">完成情况</Data></Cell>' +
'<Cell><Data ss:Type="String">自定义属性</Data></Cell>' +
'</Row>';
}
rowsXML += '<Row>';
for (var key in fieldKeys) {
if (Array.isArray(this.features[i][fieldKeys[key]])) {
let str = ''
for (let k in this.features[i][fieldKeys[key]]) {
str += `${this.features[i][fieldKeys[key]][k].key + '' + this.features[i][fieldKeys[key]][k].value}&#10;`
}
ctx = {
nameType: 'String',
data: str
};
}
else {
ctx = {
nameType: 'String',
data: this.features[i][fieldKeys[key]] || "0"
};
}
rowsXML += format(tmplCellXML, ctx);
}
rowsXML += '</Row>';
if (i > 0 && (i / 60000) % 1 === 0) {
pil++;
ctx = { rows: rowsXML, nameWS: 'Sheet' + i };
worksheetsXML += format(tmplWorksheetXML, ctx);
rowsXML = "";
rowsXML += '<Row>' +
'<Cell><Data ss:Type="String">构件名称</Data></Cell>' +
'<Cell><Data ss:Type="String">体积</Data></Cell>' +
'<Cell><Data ss:Type="String">墩全高H</Data></Cell>' +
'<Cell><Data ss:Type="String">墩身高h</Data></Cell>' +
'<Cell><Data ss:Type="String">底部高程</Data></Cell>' +
'<Cell><Data ss:Type="String">承台宽</Data></Cell>' +
'<Cell><Data ss:Type="String">承台长</Data></Cell>' +
'<Cell><Data ss:Type="String">承台高</Data></Cell>' +
'<Cell><Data ss:Type="String">族</Data></Cell>' +
'<Cell><Data ss:Type="String">桩径</Data></Cell>' +
'<Cell><Data ss:Type="String">桩长</Data></Cell>' +
'<Cell><Data ss:Type="String">结构材质</Data></Cell>' +
'<Cell><Data ss:Type="String">完成情况</Data></Cell>' +
'<Cell><Data ss:Type="String">自定义属性</Data></Cell>' +
'</Row>';
}
}
}
}
ctx = { rows: rowsXML, nameWS: 'Sheet' };
worksheetsXML += format(tmplWorksheetXML, ctx);
rowsXML = "";
ctx = { created: (new Date()).getTime(), worksheets: worksheetsXML };
workbookXML = format(tmplWorkbookXML, ctx);
var link = document.createElement("A");
link.href = url + base64(workbookXML);
link.download = this.oldData.name + "--构件属性.xls"
link.target = '_blank';
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
}
exportState(e) {
let checkbox = e.target.getElementsByTagName('input')[0]
checkbox.checked = !checkbox.checked
if (checkbox.checked) {
this.exportStateArray.push(checkbox.value)
this.exportStateArray = Array.from(new Set(this.exportStateArray))
}
else {
for (let i = 0; i < this.exportStateArray.length; i++) {
if (this.exportStateArray[i] == checkbox.value) {
this.exportStateArray.splice(i, 1)
break
}
}
}
}
}
export default BIM

View File

@ -0,0 +1,54 @@
function html() {
return `
<span class="custom-divider"></span>
<div class="div-item">
<div class="row">
<div class="col">
<span class="label">名称</span>
<input class="input" @model="name">
</div>
</div>
</div>
<span class="custom-divider"></span>
<div class="div-item">
<div class="row">
<div class="col">
<span class="label">高度</span>
<div class="input-number input-number-unit-3">
<input class="input" type="number" title="" @model="height">
<span class="unit">m</span>
<span class="arrow"></span>
</div>
</div>
<div class="col">
<span class="label">精度</span>
<div class="input-number input-number-unit-3">
<input class="input" type="number" title="" min="0.1" max="10" step="0.1" @model="accuracy">
<span class="unit">倍</span>
<span class="arrow"></span>
</div>
</div>
</div>
<div class="row">
<div class="col">
<span class="label">透视</span>
<input type="range" min="0" max="1" step="0.01" @model="transparency">
</div>
</div>
</div>
`
}
function css() {
return `
.YJ-custom-base-dialog>.content {
width: 420px;
}
.YJ-custom-base-dialog>.content .row .label {
flex: 0 0 45px;
}
`
}
export { html, css }

View File

@ -0,0 +1,87 @@
class eventBinding {
constructor() {
this.element = {}
}
static event = {}
getEvent(name) {
return eventBinding.event[name]
}
getEventAll() {
return eventBinding.event
}
setEvent(name, event) {
eventBinding.event[name] = event
}
on(that, elements) {
for (let i = 0; i < elements.length; i++) {
let Event = []
let isEvent = false
let removeName = []
if (!elements[i] || !elements[i].attributes) {
continue;
}
for (let m of elements[i].attributes) {
switch (m.name) {
case '@model': {
isEvent = true
if (elements[i].type == 'checkbox') {
Event.push((e) => { that[m.value] = e.target.checked })
elements[i].checked = that[m.value]
}
else {
Event.push((e) => {
let value = e.target.value
if(e.target.type == 'number') {
value = Number(value)
}
that[m.value] = value
})
if(elements[i].nodeName=='IMG') {
elements[i].src = that[m.value]
}
else {
elements[i].value = that[m.value]
}
}
this.element[m.value] = elements[i]
removeName.push(m.name)
break;
}
case '@click': {
elements[i].addEventListener('click', (e) => {
if (typeof (that.Dialog[m.value]) === 'function') {
that.Dialog[m.value](e)
}
});
removeName.push(m.name)
// elements[i].attributes.removeNamedItem(m.name)
break;
}
}
// elements[i].attributes[m] = undefined
}
for(let n=0;n<removeName.length;n++) {
elements[i].attributes.removeNamedItem(removeName[n])
}
if (isEvent) {
let ventType = 'input'
if (elements[i].tagName != 'INPUT' || elements[i].type == 'checkbox') {
ventType = 'change'
}
elements[i].addEventListener(ventType, (e) => {
for (let t = 0; t < Event.length; t++) {
Event[t](e)
}
});
}
}
}
}
const EventBinding = new eventBinding();
export default EventBinding;

View File

@ -0,0 +1,373 @@
/**
* @name: index
* @author: Administrator
* @date: 2023-11-20 16:05
* @descriptionindex
* @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

View File

@ -0,0 +1,650 @@
/**
* @name: index
* @author: Administrator
* @date: 2023-11-20 17:54
* @descriptionindex
* @update: 2023-11-20 17:54
*/
import { getHost } from "../../../../on";
import BaseSource from "../index";
import { regLeftClickCallback, regRightClickCallback, regMoveCallback } from "../../../../Global/ClickCallback";
import Controller from "../../../../Controller/index";
import { syncData } from '../../../../Global/MultiViewportMode'
import { setSplitDirection, syncSplitData, setActiveId } from '../../../../Global/SplitScreen'
class BaseTileset extends BaseSource {
#updateModelTimeout;
/**
* @constructor
* @param sdk
* @description 模型
* @param options {object}
* @param options.id{string} id
* @param options.name{string} 名称
* @param options.url{string} 模型地址
* @param options.lng{number} 经度
* @param options.lat{number} 纬度
* @param options.height=0{number} 高度
* @param options.scale=1{number} 模型比例
* @param options.roll=0{number} 模型x旋转
* @param options.heading=0{number} 模型z轴旋转角度
* @param options.pitch=0{number} 模型y轴旋转角度
* */
constructor(sdk, options) {
super(sdk, options);
this.setDefaultValue()
this.watchs = []
this.positionCallBack = null
this.rotationCallback = null
this.onClickCallback = null
this._DialogObject = null
this._element_style = null
this.options.accuracy = options.accuracy ? Number(options.accuracy.toFixed(1)) : 1
this.options.position = this.options.position || {}
this.oldData = {
id: this.options.id,
transparency: (this.options.transparency || this.options.transparency === 0) ? this.options.transparency : 1,
name: this.options.name,
accuracy: this.options.accuracy,
url: this.options.url,
height: this.options.position.alt || 0,
lng: this.options.position.lng,
lat: this.options.position.lat,
scale: (this.options.scale || this.options.scale === 0) ? this.options.scale : 1,
roll: this.options.roll || 0,
heading: this.options.heading || 0,
pitch: this.options.pitch || 0
}
this.newData = {
id: this.options.id,
transparency: (this.options.transparency || this.options.transparency === 0) ? this.options.transparency : 1,
name: this.options.name,
accuracy: this.options.accuracy,
url: this.options.url,
height: this.options.position.alt || 0,
lng: this.options.position.lng,
lat: this.options.position.lat,
scale: (this.options.scale || this.options.scale === 0) ? this.options.scale : 1,
roll: this.options.roll || 0,
heading: this.options.heading || 0,
pitch: this.options.pitch || 0
}
this.tileset = undefined
this.editObj = new Controller(this.sdk)
this.editObj.controllerCallBack = this.rotationEditingCallBack
}
async add() {
if (this.options.url) {
return this.loadTileset({
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.loadTileset(text.data)
else
return new Promise((res, reject) => {
reject('资源不存在')
})
} else {
return new Promise((res, reject) => {
reject(text.msg || text.message)
})
}
}
}
loadSceneTree() {
}
async loadTileset(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
}
}
let response = await fetch(url, {
method: 'get',
headers: {
'Content-Type': 'application/json',
}
})
if (response.status === 200) {
this.tileset = await response.json()
}
let params = {
show: this.options.show,
skipLevelOfDetail: true,
baseScreenSpaceError: 1024,
maximumScreenSpaceError: 32, // 数值加大,能让最终成像变模糊
skipScreenSpaceErrorFactor: 16,
skipLevels: 1,
immediatelyLoadDesiredLevelOfDetail: false,
loadSiblings: true, // 如果为true则不会在已加载完概况房屋后自动从中心开始超清化房屋
cullWithChildrenBounds: true,
cullRequestsWhileMoving: true,
cullRequestsWhileMovingMultiplier: 10, // 值越小能够更快的剔除
preloadWhenHidden: false,
preferLeaves: true,
maximumCacheOverflowBytes: 128, // 内存分配变小有利于倾斜摄影数据回收,提升性能体验
progressiveResolutionHeightFraction: 0.5, // 数值偏于0能够让初始加载变得模糊
dynamicScreenSpaceErrorDensity: 0.1, // 数值加大,能让周边加载变快
dynamicScreenSpaceErrorFactor: 1,
dynamicScreenSpaceError: true // 有了这个后,会在真正的全屏加载完之后才清晰化房屋
}
let tileset
if (Number(Cesium.VERSION.split('.')[1]) >= 107) {
tileset = await Cesium.Cesium3DTileset.fromUrl(url, params);
this.entity = tileset
this.entity.imageBasedLighting.luminanceAtZenith = 0.1
}
else {
params.url = url
tileset = new Cesium.Cesium3DTileset(params);
this.entity = await tileset.readyPromise
this.entity.imageBasedLighting.luminanceAtZenith = 0.1
}
// syncData(this.sdk, this.options.id)
await this.loadSceneTree(url)
const initData = (tile) => {
if (tile._contents) {
for (let i = 0; i < tile._contents.length; i++) {
initData(tile._contents[i])
}
}
else {
for (let i = 0; i < tile.featuresLength; i++) {
let feature = tile.getFeature(i)
let file = feature.content.url
let id = feature.getProperty('id')
if (this.features.has(id)) {
if (this.features.get(id).features) {
if (this.features.get(id).features[file]) {
// feature = this.features.get(id).features[feature.featureId]
if (this.features.get(id).features[file].customColor) {
feature.color = this.features.get(id).features[file].customColor
feature.customColor = this.features.get(id).features[file].customColor
}
if (this.features.get(id).features[file].customAlpha) {
let color = feature.color
feature.color = Cesium.Color.fromCssColorString(`rgba(${Cesium.Color.floatToByte(color.red)},${Cesium.Color.floatToByte(color.green)},${Cesium.Color.floatToByte(color.blue)},${this.features.get(id).features[file].customAlpha})`)
feature.customAlpha = this.features.get(id).features[file].customAlpha
}
if (this.features.get(id).features[file].customShow) {
feature.show = this.features.get(id).features[file].customShow
feature.customShow = this.features.get(id).features[file].customShow
}
}
this.features.get(id).features[file] = feature
}
else {
let object = {}
if (this.features.get(id).customColor) {
feature.color = this.features.get(id).customColor
feature.customColor = this.features.get(id).customColor
}
if (this.features.get(id).customAlpha) {
let color = feature.color
feature.color = Cesium.Color.fromCssColorString(`rgba(${Cesium.Color.floatToByte(color.red)},${Cesium.Color.floatToByte(color.green)},${Cesium.Color.floatToByte(color.blue)},${this.features.get(id).customAlpha})`)
feature.customAlpha = this.features.get(id).customAlpha
}
if (this.features.get(id).customShow) {
feature.show = this.features.get(id).customShow
feature.customShow = this.features.get(id).customShow
}
object[file] = feature
this.features.get(id).features = object
}
}
else {
let object = {}
object[file] = feature
this.features.set(id, { features: object })
}
if (!feature.customColor) {
feature.customColor = Cesium.Color.fromCssColorString('#ffffff')
}
}
}
// for (let i = 0; i < tile._content.featuresLength; i++) {
// let feature = tile._content.getFeature(i)
// feature.show = false
// }
// if (tile._content._contents) {
// for (let i = 0; i < tile._content._contents.length; i++) {
// for (let m = 0; m < tile._content._contents[i].featuresLength; m++) {
// let feature = tile._content._contents[i].getFeature(m)
// feature.show = false
// }
// }
// }
}
if (!this.sdk || !this.sdk.viewer || !this.sdk.viewer.scene) {
return
}
tileset.tileLoad.addEventListener(tile => {
// this.test()
initData(tile._content)
clearTimeout(this.#updateModelTimeout)
this.#updateModelTimeout = setTimeout(() => {
clearTimeout(this.#updateModelTimeout)
let center = this.cartesian3Towgs84(tileset.boundingSphere.center, this.sdk.viewer)
let circle = turf.circle([center.lng, center.lat], tileset.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
}
}
}
}, 500);
// if (tile._content._contents) {
// for (let i = 0; i < tile._content._contents.length; i++) {
// for (let m = 0; m < tile._content._contents[i].featuresLength; m++) {
// let feature = tile._content._contents[i].getFeature(m)
// console.log(feature)
// feature.show = false
// }
// }
// }
// for (let i = 0; i < tile._content.featuresLength; i++) {
// let feature = tile._content.getFeature(i)
// let file = feature.content.url
// let id = feature.getProperty('id')
// if (this.features.has(id)) {
// if (this.features.get(id).features) {
// if (this.features.get(id).features[file]) {
// // feature = this.features.get(id).features[feature.featureId]
// if (this.features.get(id).features[file].customColor) {
// feature.color = this.features.get(id).features[file].customColor
// feature.customColor = this.features.get(id).features[file].customColor
// }
// if (this.features.get(id).features[file].customAlpha) {
// let color = feature.color
// feature.color = Cesium.Color.fromCssColorString(`rgba(${Cesium.Color.floatToByte(color.red)},${Cesium.Color.floatToByte(color.green)},${Cesium.Color.floatToByte(color.blue)},${this.features.get(id).features[file].customAlpha})`)
// feature.customAlpha = this.features.get(id).features[file].customAlpha
// }
// if (this.features.get(id).features[file].customShow) {
// feature.show = this.features.get(id).features[file].customShow
// feature.customShow = this.features.get(id).features[file].customShow
// }
// }
// this.features.get(id).features[file] = feature
// }
// else {
// let object = {}
// object[file] = feature
// this.features.get(id).features = object
// }
// }
// else {
// let object = {}
// object[file] = feature
// this.features.set(id, { features: object })
// }
// if (!feature.customColor) {
// feature.customColor = Cesium.Color.fromCssColorString('#ffffff')
// }
// }
})
// // console.log(tileset)
// if (this.type === 'bim') {
// const setTilesetStyle = (f) => {
// if (tileset.style) {
// // tileset.style = new Cesium.Cesium3DTileStyle({
// // color: {
// // conditions: [
// // ['${name} ==="对象074" ', 'color("red")'], //符合条件项
// // ['true', 'rgba(255,255,255,1)'] //其他项
// // ]
// // }
// // })
// // tileset.tileLoad.removeEventListener(setTilesetStyle)
// }
// console.log(f)
// }
// tileset.tileLoad.addEventListener(setTilesetStyle)
// }
this.entity._root.originalTransform = { ...this.entity._root.transform }
this.entity.id = this.options.id || this.randomString()
this.entity.type = this.type
// this.editObj = new EditB3DM(this.sdk, this.entity)
this.sdk.viewer.scene.primitives.add(tileset);
if (this.options.position && JSON.stringify(this.options.position) != "{}"
&& (this.options.position.lng || this.options.position.lng === 0) && (this.options.position.lat || this.options.position.lat === 0)) {
this.options.position.alt == this.options.position.alt || 0
let cartographic = Cesium.Cartographic.fromCartesian(this.entity.boundingSphere.center);
if (this.tileset.root.transform) {
cartographic = Cesium.Cartographic.fromCartesian({ x: this.tileset.root.transform[12], y: this.tileset.root.transform[13], z: this.tileset.root.transform[14] })
}
this.entity.original = {
lng: Cesium.Math.toDegrees(cartographic.longitude), // 经度
lat: Cesium.Math.toDegrees(cartographic.latitude), // 纬度
height: cartographic.height
}
let m = Cesium.Transforms.eastNorthUpToFixedFrame(new Cesium.Cartesian3.fromDegrees(this.options.position.lng, this.options.position.lat, this.options.position.alt))
const scale = Cesium.Matrix4.fromUniformScale(this.oldData.scale);
if (this.tileset.root.transform) {
Cesium.Matrix4.multiply(m, scale, this.entity._root.transform)
}
this.lng = this.oldData.lng
this.lat = this.oldData.lat
this.height = this.oldData.height
}
else {
this.options.position = {}
let cartographic = Cesium.Cartographic.fromCartesian(this.entity.boundingSphere.center);
if (this.tileset.root.transform) {
cartographic = Cesium.Cartographic.fromCartesian({ x: this.tileset.root.transform[12], y: this.tileset.root.transform[13], z: this.tileset.root.transform[14] })
}
this.entity.original = {
lng: Cesium.Math.toDegrees(cartographic.longitude),
lat: this.oldData.lat = Cesium.Math.toDegrees(cartographic.latitude),
height: cartographic.height,
}
this.lng = this.oldData.lng = Cesium.Math.toDegrees(cartographic.longitude); // 经度
this.lat = this.oldData.lat = Cesium.Math.toDegrees(cartographic.latitude); // 纬度
this.height = this.oldData.height = cartographic.height; // 高度
}
this.scale = this.oldData.scale
this.roll = this.oldData.roll
this.heading = this.oldData.heading
this.pitch = this.oldData.pitch
this.transparency = this.oldData.transparency
syncSplitData(this.sdk, this.options.id)
regMoveCallback(this.entity.id, this.mouseMoveCB, this)
// this.entity = this.sdk.viewer.scene.primitives.add(tileset);
// if (this.options.position && JSON.stringify(this.options.position) != "{}") {
// let m = Cesium.Transforms.eastNorthUpToFixedFrame(new Cesium.Cartesian3.fromDegrees(this.options.position.lng, this.options.position.lat, this.options.position.alt))
// const scale = Cesium.Matrix4.fromUniformScale(this.oldData.scale);
// Cesium.Matrix4.multiply(m, scale, this.entity._root.transform)
// }
// else {
// this.options.position = {}
// }
// this.lng = this.oldData.lng
// this.lat = this.oldData.lat
// this.height = this.oldData.height
// this.scale = this.oldData.scale
// this.roll = this.oldData.roll
// this.heading = this.oldData.heading
// this.pitch = this.oldData.pitch
// this.transparency = this.oldData.transparency
// regMoveCallback(this.entity.id, this.mouseMoveCB, this)
// this.editObj = new EditB3DM(this.sdk, this.entity)
// this.editObj.transformCallBack = this.rotationEditingCallBack
// tileset.readyPromise.then(() => {
// this.entity = this.sdk.viewer.scene.primitives.add(tileset);
// })
// let x = this.sdk.viewer.scene.primitives.add(new Cesium.Cesium3DTileset({
// url: url
// }));
// setTimeout(() => {
// console.log(x)
// this.sdk.viewer.flyTo(this.entity)
// }, 3000);
}
// test() {
// let heightstyle = new Cesium.Cesium3DTileStyle({
// color: {
// conditions: [
// ["Number(${height})>=300", "rgba(45,0,75,0.5)"],
// ["Number(${height})>=200", "rgb(102,71,151)"],
// ["Number(${height})>=100", "rgb(170,162,204)"],
// ["Number(${height})>=50", "rgb(224,226,238)"],
// ["Number(${height})>=25", "rgb(252,230, 200)"],
// ["Number(${height})>=10", "rgb(248,176,87)"],
// ["Number(${height})>=5", "rgb(198, 106,11)"],
// ["isNaN(Number(${height}))", "rgb(255, 255, 255)"],
// ["true", "rgb(127,59,8)"]
// ]
// }
// });
// this.entity.style = heightstyle;
// }
remove() {
super.remove()
this.editObj.destroy()
this.sdk.viewer.scene.primitives.remove(this.entity);
this.entity = null
if (this._DialogObject) {
this._DialogObject.close()
this._DialogObject = null
}
}
flyTo() {
super.flyTo()
}
on() {
return this.add()
}
setDefaultValue() {
super.setDefaultValue()
this.options.host = this.options.host || getHost()
this.options.url = this.options.url || ""
}
get position() {
let cartographic = Cesium.Cartographic.fromCartesian(this.entity.boundingSphere.center);
if (this.tileset.root.transform) {
cartographic = Cesium.Cartographic.fromCartesian({ x: this.tileset.root.transform[12], y: this.tileset.root.transform[13], z: this.tileset.root.transform[14] })
}
let lng = Cesium.Math.toDegrees(cartographic.longitude + 0.00000000663814);
let lat = Cesium.Math.toDegrees(cartographic.latitude + 0.00000025137835);
if (this.newData.lng && this.newData.lat && this.newData.height) {
return { lng: this.newData.lng, lat: this.newData.lat, height: this.newData.height }
}
else {
return { lng: lng, lat: lat, height: cartographic.height - 2.19104611043234 }
}
}
set position(p) {
}
/**
* @desc 打开模型旋转功能
* @param status {boolean}
* @methodOf Source
* */
set rotationEditing(status) {
if (!this.tileset.root.transform) {
if (window.ELEMENT) {
window.ELEMENT.Message.closeAll();
window.ELEMENT.Message({
message: '该模型不支持移动和旋转!',
type: 'warning',
duration: 1500
});
}
console.warn('该模型不支持移动和旋转!')
return
}
if (status) {
this.editObj.position = { lng: this.newData.lng, lat: this.newData.lat, alt: this.newData.height }
this.editObj.update()
this.editObj.editRtation()
}
else {
this.editObj.destroy()
}
}
/**
* @desc 获取模型旋转状态
* @method rotationEditing
* @return boolean
* @methodOf Source
* */
get rotationEditing() {
if (this.editObj.getActiveState() === 'rtation') {
return true
}
return false
}
/**@desc 打开平移模型功能
*
* @memberOf Source
*@param status {boolean}
*
* */
set positionEditing(status) {
if (!this.sdk || !this.sdk.viewer || !this.entity) {
return
}
if (!this.tileset.root.transform) {
if (window.ELEMENT) {
window.ELEMENT.Message.closeAll();
window.ELEMENT.Message({
message: '该模型不支持移动和旋转!',
type: 'warning',
duration: 1500
});
}
console.warn('该模型不支持移动和旋转!')
return
}
if (status) {
this.editObj.position = { lng: this.newData.lng, lat: this.newData.lat, alt: this.newData.height }
this.editObj.update()
this.editObj.editTranslational()
}
else {
this.editObj.destroy()
}
}
get positionEditing() {
if (this.editObj.getActiveState() === 'translational') {
return true
}
return false
}
//平移时,坐标信息变化的回调
set positionEditingCallBack(callback) {
return
}
get positionEditingCallBack() {
}
//旋转时,坐标信息变化的回调
set rotationEditingCallBack(callback) {
this._rotationEditingCallBack = callback
}
get rotationEditingCallBack() {
return (params, state) => {
this.lng = params.position.lng
this.lat = params.position.lat
this.height = params.position.alt
this.roll = params.rotate.x
this.heading = params.rotate.y
this.pitch = params.rotate.z
// this._rotationEditingCallBack && this._rotationEditingCallBack(this.editObj._params)
}
}
flicker() { }
// 编辑框
async edit(state) { }
get show() {
return this.options.show
}
set show(v) {
if (typeof v === "boolean") {
this.options.show = v
this.entity && (this.entity.show = v)
if (this._DialogObject && this._DialogObject.showBtn) {
this._DialogObject.showBtn.checked = v
}
if (this.options.label && this.options.label.show && this.label) {
this.label.show = v
}
setTimeout(() => {
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
}
}
}
syncData(this.sdk, this.options.id)
syncSplitData(this.sdk, this.options.id)
}, 300);
} else {
console.error("参数必须为boolean")
}
}
}
export default BaseTileset

View File

@ -0,0 +1,45 @@
/**
* @name: index
* @author: Administrator
* @date: 2023-11-20 18:31
* @descriptionindex
* @update: 2023-11-20 18:31
*/
import Base from "../index";
import {getHost, getToken} from "../../../on";
import { setSplitDirection } from "../../../Global/SplitScreen";
class BaseSource extends Base {
constructor(sdk, options) {
super(sdk, options);
this.sdk.addIncetance(this.options.id, this)
if (this.options.show) {
setSplitDirection(0, this.options.id)
}
}
setDefaultValue() {
super.setDefaultValue();
this.options.host = this.options.host || getHost()
}
requestResource() {
let url = ""
if (this.options.host.endsWith("yjearth4.0"))
url = this.options.host + '/data/service/load-compact-service'
else
url = this.options.host + '/yjearth4.0/data/service/load-compact-service'
return fetch(url, {
method: 'post',
body: JSON.stringify({source_id: this.options.id}),
headers: {
'Content-Type': 'application/json',
"token": getToken(),
"Authorization": "Bearer " + getToken(),
}
})
}
}
export default BaseSource