879 lines
31 KiB
JavaScript
879 lines
31 KiB
JavaScript
/**
|
||
* @name: index
|
||
* @author: Administrator
|
||
* @date: 2023-11-20 16:05
|
||
* @description:index
|
||
* @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()
|
||
this.on()
|
||
}
|
||
|
||
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} `
|
||
}
|
||
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
|