From b2d307b308cf2b43ab79ad8afbeb9d7dcea21819 Mon Sep 17 00:00:00 2001
From: zh <972939975@qq.com>
Date: Thu, 21 Aug 2025 16:34:30 +0800
Subject: [PATCH] =?UTF-8?q?=E5=B9=BF=E5=91=8A=E7=89=8C=E6=B7=BB=E5=8A=A0?=
=?UTF-8?q?=E5=B1=9E=E6=80=A7=E6=A1=86?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
src/Obj/Base/BillboardObject/index.js | 370 +++++++++++++++++++++++++-
src/Obj/Element/cy_html_tabs.js | 15 +-
2 files changed, 380 insertions(+), 5 deletions(-)
diff --git a/src/Obj/Base/BillboardObject/index.js b/src/Obj/Base/BillboardObject/index.js
index 3bd6bfc..b637a4f 100644
--- a/src/Obj/Base/BillboardObject/index.js
+++ b/src/Obj/Base/BillboardObject/index.js
@@ -40,6 +40,10 @@ import {
import { getGoodsList } from '../../../Tools/getGoodsList'
class BillboardObject extends Base {
+ #_postRenderEvent = null
+ #_destroyMouseEvent = null
+
+
/**
* @constructor
* @description 创建点标注
@@ -145,11 +149,18 @@ class BillboardObject extends Base {
this.options.attribute.goods.content || []
this.options.attributeType = options.attributeType || 'richText'
this.options.coordinate = options.coordinate || ''
+ this.options.attributeBoxState = options.attributeBoxState || false
this.operate = {}
this._elms = {}
this.previous = {
positions: { ...this.options.positions }
}
+ this.options.attributePos = options.attributePos || {
+ x: 60,
+ y: 60,
+ width: 200,
+ height: 120
+ }
this.entity
this._proj = this.sdk.proj
@@ -182,7 +193,107 @@ class BillboardObject extends Base {
+ this.#_destroyMouseEvent = () => {
+ this.attributeElm && (this.attributeElm.style.pointerEvents = 'unset')
+ this.sdk.viewer._element.onmousemove = null
+ document.removeEventListener('mouseup', this.#_destroyMouseEvent)
+ document.removeEventListener('mouseleave', this.#_destroyMouseEvent)
+ }
+ this.#_postRenderEvent = () => {
+ let siteInfoPosition = Cesium.Cartesian3.fromDegrees(
+ this.options.positions.lng,
+ this.options.positions.lat
+ )
+ if (this.attributeElm && this.entity) {
+ let winpos = this.sdk.viewer.scene.cartesianToCanvasCoordinates(
+ siteInfoPosition
+ )
+ let pixelOffset = this.entity.label.pixelOffset.getValue()
+ if (winpos) {
+ let scale = getCurrentBillboardScale(this.entity, this.sdk.viewer.scene)
+ let height = ((this.entity.billboard.height.getValue() * (this.options.billboard.scale || 0)) + this.options.label.fontSize) * (1 - (scale * scale))
+ let flag = false
+ let lineElm = this.attributeElm.getElementsByClassName('billboard-attribute-box-line')[0]
+ let leftTopElm = this.attributeElm.getElementsByClassName('left-top')[0]
+ let rightTopElm = this.attributeElm.getElementsByClassName('right-top')[0]
+ this.attributeElm.style.left = (winpos.x + this.options.attributePos.x).toFixed(0) + 'px'
+ this.attributeElm.style.top = (winpos.y + pixelOffset.y - (this.options.label.show ? (this.options.label.fontSize / 2) : -(this.options.label.fontSize / 2)) - this.attributeElm.offsetHeight - this.options.attributePos.y + height).toFixed(0) + 'px'
+ this.attributeElm.style.width = this.options.attributePos.width + 'px'
+ this.attributeElm.style.height = this.options.attributePos.height + 'px'
+ if (this.options.attributePos.x < -this.options.attributePos.width / 2) {
+ flag = true
+ lineElm.style.left = 'unset'
+ lineElm.style.right = '0'
+ leftTopElm.style.display = 'block'
+ rightTopElm.style.display = 'none'
+ }
+ else {
+ lineElm.style.left = '0'
+ lineElm.style.right = 'unset'
+ leftTopElm.style.display = 'none'
+ rightTopElm.style.display = 'block'
+ }
+
+ let lineLength
+ let lineAngleRad
+ let lineAngle
+ let x
+ let y
+ if (flag) {
+ x = this.attributeElm.offsetWidth + this.options.attributePos.x
+ y = this.options.attributePos.y ? this.options.attributePos.y : 0
+ }
+ else {
+ x = this.options.attributePos.x
+ y = this.options.attributePos.y ? this.options.attributePos.y : 0
+ }
+ lineLength = Math.sqrt((x * x) + (y * y)).toFixed(2);
+ lineAngleRad = Math.atan(x / y);
+ lineAngle = parseFloat((lineAngleRad * 180 / Math.PI).toFixed(2));
+ if (this.options.attributePos.y < 0) {
+ lineAngle = lineAngle + 180
+ }
+ // if(this.options.attributePos.y<-this.options.attributePos.height/2) {
+ // lineElm.style.bottom = 'unset'
+ // lineElm.style.top = '0'
+ // }
+ // else {
+ // lineElm.style.bottom = -lineLength + 'px'
+ // lineElm.style.top = 'unset'
+ // }
+ lineElm.style.height = lineLength + 'px'
+ lineElm.style.transform = 'rotate(' + lineAngle + 'deg)'
+ }
+ }
+ }
+
+ function getCurrentBillboardScale(entity, scene) {
+ // 获取相机到Billboard的距离
+ const distance = Cesium.Cartesian3.distance(
+ scene.camera.positionWC,
+ entity.position.getValue()
+ );
+ // 获取缩放距离配置
+ const scaleByDistance = entity.billboard.scaleByDistance ? entity.billboard.scaleByDistance.getValue() : undefined;
+
+ if (!scaleByDistance) {
+ // 如果没有设置距离缩放,则使用基础缩放值
+ return 1.0;
+ }
+
+ // 解析缩放距离参数 [near, nearScale, far, farScale]
+ const { near, nearValue, far, farValue } = scaleByDistance;
+ if (distance <= near) {
+ return nearValue;
+ } else if (distance >= far) {
+ return farValue;
+ } else {
+ // 计算中间距离的缩放值(线性插值)
+ const t = (distance - near) / (far - near);
+ return Cesium.Math.lerp(nearValue, farValue, t);
+ }
+ }
this.sdk.addIncetance(this.options.id, this)
@@ -243,6 +354,7 @@ class BillboardObject extends Base {
that.entity.billboard.imgHeight = 0
that.entity.billboard.image = canvas
addCluster(that.sdk, that.entity)
+ that.attributeBoxState && (that.attributeBoxState = true)
}
return
}
@@ -267,6 +379,7 @@ class BillboardObject extends Base {
return img
}, false)
addCluster(that.sdk, that.entity)
+ that.attributeBoxState && (that.attributeBoxState = true)
}
})
}
@@ -298,6 +411,7 @@ class BillboardObject extends Base {
that.entity.billboard.imgHeight = height
that.entity.billboard.image = canvas
addCluster(that.sdk, that.entity)
+ that.attributeBoxState && (that.attributeBoxState = true)
}
}
image.onerror = function (err) {
@@ -309,6 +423,7 @@ class BillboardObject extends Base {
that.entity.billboard.imgHeight = 0
that.entity.billboard.image = canvas
addCluster(that.sdk, that.entity)
+ that.attributeBoxState && (that.attributeBoxState = true)
}
};
}
@@ -465,15 +580,36 @@ class BillboardObject extends Base {
return this.options.show
}
set show(v) {
- if(!this.isShowView) {
+ if (!this.isShowView) {
this.options.show = v
this.originalOptions.show = v
}
- if(!this.showView || this.showView == 3) {
+ if (!this.showView || this.showView == 3) {
this.entity && (this.entity.show = this.options.show)
+ if (this.attributeBoxState && this.options.show) {
+ this.attributeBoxState = this.options.show
+ }
+ else {
+ // 关闭属性框
+ document.addEventListener('mouseup', this.#_destroyMouseEvent);
+ document.addEventListener('mouseleave', this.#_destroyMouseEvent);
+ if (this.attributeElm) {
+ this.sdk.viewer._element.removeChild(this.attributeElm)
+ this.attributeElm = null
+ }
+ this.sdk.viewer.scene.postRender.removeEventListener(this.#_postRenderEvent)
+ }
}
else {
this.entity && (this.entity.show = false)
+ // 关闭属性框
+ document.addEventListener('mouseup', this.#_destroyMouseEvent);
+ document.addEventListener('mouseleave', this.#_destroyMouseEvent);
+ if (this.attributeElm) {
+ this.sdk.viewer._element.removeChild(this.attributeElm)
+ this.attributeElm = null
+ }
+ this.sdk.viewer.scene.postRender.removeEventListener(this.#_postRenderEvent)
}
syncData(this.sdk, this.options.id)
syncSplitData(this.sdk, this.options.id)
@@ -1716,6 +1852,22 @@ class BillboardObject extends Base {
this.cameraSelect && this.cameraSelect()
this.ISCSelect && this.ISCSelect()
this.goodsSelect && this.goodsSelect()
+
+ let col = document.createElement('div')
+ col.className = 'col'
+ col.style.flex = '0 0 80px'
+ col.innerHTML = `
+ 属性框
+
+ `
+
+ let row = this._DialogObject._element.content.getElementsByClassName('attribute')[0].getElementsByClassName('row')[0]
+ row.appendChild(col)
+ let boxSwitch = col.getElementsByClassName('btn-switch')[0]
+ boxSwitch.checked = this.attributeBoxState
+ boxSwitch.addEventListener('change', (e) => {
+ this.attributeBoxState = boxSwitch.checked
+ })
let tagData = this.attributeSelect
let attributeElm = this._DialogObject._element.content.getElementsByClassName(
'attribute-select-box'
@@ -2736,6 +2888,220 @@ class BillboardObject extends Base {
(this.originalOptions.customView = this.options.customView)
}
}
+
+ get attributeBoxState() {
+ return this.options.attributeBoxState
+ }
+
+ set attributeBoxState(state) {
+ state = state ? true : false
+ this.options.attributeBoxState = state
+ document.addEventListener('mouseup', this.#_destroyMouseEvent);
+ document.addEventListener('mouseleave', this.#_destroyMouseEvent);
+ if (this.attributeElm) {
+ this.sdk.viewer._element.removeChild(this.attributeElm)
+ this.attributeElm = null
+ }
+ this.sdk.viewer.scene.postRender.removeEventListener(this.#_postRenderEvent)
+ if (state && this.sdk && this.sdk.viewer && this.sdk.viewer._element && this.show) {
+ let attributeElm = document.createElement('div')
+ this.attributeElm = attributeElm
+ attributeElm.className = 'billboard-attribute-box'
+ attributeElm.style.top = '0px'
+ attributeElm.style.left = '0px'
+ attributeElm.style.width = 0
+ attributeElm.style.height = 0
+ // attributeElm.innerHTML = this.options.richTextContent
+ this.sdk.viewer._element.appendChild(attributeElm)
+ let linkHtml = ''
+ let goodsHtml = ''
+ let richTextHtml = ''
+ for (let i = 0; i < this.options.attribute.link.content.length; i++) {
+ linkHtml += `
暂无属性信息
' + } + else { + boxHtml = boxHtml + ` +