diff --git a/src/components/CesiumMap/FeatureGroundPrimitive.js b/src/components/CesiumMap/FeatureGroundPrimitive.js new file mode 100644 index 0000000..8248d52 --- /dev/null +++ b/src/components/CesiumMap/FeatureGroundPrimitive.js @@ -0,0 +1,16 @@ +import * as Cesium from "cesium"; + +export default class FeatureGroundPrimitive extends Cesium.GroundPrimitive { + + properties = new Cesium.PropertyBag() + constructor(options, properties) { + super(options); + if(properties && properties instanceof Object) { + for (const key in properties) { + if (Object.prototype.hasOwnProperty.call(properties, key)) { + this.properties.addProperty(key, properties[key]); + } + } + } + } +} \ No newline at end of file diff --git a/src/components/CesiumMap/mixins/useDrawTool/drawAttackArrow.js b/src/components/CesiumMap/mixins/useDrawTool/drawAttackArrow.js index 1a8cc8a..f9eb102 100644 --- a/src/components/CesiumMap/mixins/useDrawTool/drawAttackArrow.js +++ b/src/components/CesiumMap/mixins/useDrawTool/drawAttackArrow.js @@ -67,7 +67,7 @@ export const drawAttackArrow = (deps) => { const pts = createAttackArrowPositions(positions) return [...pts, pts[0]] }, false), - // clampToGround: true, // 多边形边界线通常不需要 clampToGround,因为多边形本身已经处理了高度 + clampToGround: true, width: 2, material: CesiumColor.fromCssColorString('#ff0000'), }, diff --git a/src/components/CesiumMap/mixins/useDrawTool/drawCurvePolygon.js b/src/components/CesiumMap/mixins/useDrawTool/drawCurvePolygon.js index 4304024..a5b1026 100644 --- a/src/components/CesiumMap/mixins/useDrawTool/drawCurvePolygon.js +++ b/src/components/CesiumMap/mixins/useDrawTool/drawCurvePolygon.js @@ -62,7 +62,7 @@ export const drawCurvePolygon = (deps) => { } return createCurvePolygonPositions(positions) }, false), - // clampToGround: true, // 多边形边界线通常不需要 clampToGround,因为多边形本身已经处理了高度 + clampToGround: true, width: 2, material: CesiumColor.fromCssColorString('#ff0000'), }, diff --git a/src/components/CesiumMap/mixins/useDrawTool/drawDoubleArrow.js b/src/components/CesiumMap/mixins/useDrawTool/drawDoubleArrow.js index 8a5a607..1038bc3 100644 --- a/src/components/CesiumMap/mixins/useDrawTool/drawDoubleArrow.js +++ b/src/components/CesiumMap/mixins/useDrawTool/drawDoubleArrow.js @@ -67,7 +67,7 @@ export const drawDoubleArrow = (deps) => { const pts = createDoubleArrowPositions(positions) return [...pts, pts[0]] }, false), - // clampToGround: true, // 多边形边界线通常不需要 clampToGround,因为多边形本身已经处理了高度 + clampToGround: true, width: 2, material: CesiumColor.fromCssColorString('#ff0000'), }, diff --git a/src/components/CesiumMap/mixins/useDrawTool/drawPolygon.js b/src/components/CesiumMap/mixins/useDrawTool/drawPolygon.js index 25eebe9..f94ac3c 100644 --- a/src/components/CesiumMap/mixins/useDrawTool/drawPolygon.js +++ b/src/components/CesiumMap/mixins/useDrawTool/drawPolygon.js @@ -64,6 +64,7 @@ export const drawPolygon = (deps) => { // clampToGround: true, // 多边形边界线通常不需要 clampToGround,因为多边形本身已经处理了高度 width: 2, material: CesiumColor.fromCssColorString('#ff0000'), + clampToGround: true, }, }) diff --git a/src/components/CesiumMap/mixins/useDrawTool/drawStraightArrow.js b/src/components/CesiumMap/mixins/useDrawTool/drawStraightArrow.js index cbfcc78..bae007c 100644 --- a/src/components/CesiumMap/mixins/useDrawTool/drawStraightArrow.js +++ b/src/components/CesiumMap/mixins/useDrawTool/drawStraightArrow.js @@ -63,7 +63,7 @@ export const drawStraightArrow = (deps) => { const pts = createStraightArrowPositions(positions) return [...pts, pts[0]] }, false), - // clampToGround: true, // 多边形边界线通常不需要 clampToGround,因为多边形本身已经处理了高度 + clampToGround: true, width: 2, material: CesiumColor.fromCssColorString('#ff0000'), }, diff --git a/src/components/CesiumMap/mixins/useDrawTool/drawWideArrow.js b/src/components/CesiumMap/mixins/useDrawTool/drawWideArrow.js index 8afef2d..425989b 100644 --- a/src/components/CesiumMap/mixins/useDrawTool/drawWideArrow.js +++ b/src/components/CesiumMap/mixins/useDrawTool/drawWideArrow.js @@ -64,7 +64,7 @@ export const drawWideArrow = (deps) => { return [...pts, pts[0]] // return [...pts] }, false), - // clampToGround: true, // 多边形边界线通常不需要 clampToGround,因为多边形本身已经处理了高度 + clampToGround: true, width: 2, material: CesiumColor.fromCssColorString('#ff0000'), }, diff --git a/src/components/CesiumMap/mixins/useDrawTool/index.js b/src/components/CesiumMap/mixins/useDrawTool/index.js index c5fc9e7..064b1a9 100644 --- a/src/components/CesiumMap/mixins/useDrawTool/index.js +++ b/src/components/CesiumMap/mixins/useDrawTool/index.js @@ -6,6 +6,7 @@ import { Entity, CallbackPositionProperty, Color as CesiumColor, + HeightReference, } from 'cesium' import { useEventBus } from '../useEventBus' import { useHoverPosition } from '../useHoverPosition' @@ -69,9 +70,8 @@ export const useDrawTool = (viewer) => { color: CesiumColor.BLUE, outlineColor: CesiumColor.WHITE, outlineWidth: 1, + heightReference: HeightReference.CLAMP_TO_GROUND, }, - // 可以考虑是否需要 HeightReference.CLAMP_TO_GROUND - // heightReference: HeightReference.CLAMP_TO_GROUND, }) viewer.entities.add(assistPoint) diff --git a/src/views/systemTemplate/forestFire/Toolbar.vue b/src/views/systemTemplate/forestFire/Toolbar.vue index b03ed56..77a6af1 100644 --- a/src/views/systemTemplate/forestFire/Toolbar.vue +++ b/src/views/systemTemplate/forestFire/Toolbar.vue @@ -29,6 +29,7 @@ import { import { useEventBus } from '@/components/CesiumMap/mixins/useEventBus'; import { useMeasureTool, getArea, getBoundingCenterCoordinate } from '@/components/CesiumMap/mixins/useMeasureTool'; import { setPropertyData } from './DialogPropertyGrid/property'; +import FeatureGroundPrimitive from '@/components/CesiumMap/FeatureGroundPrimitive'; import toolbarLocationIcon from '@/assets/icons/toolbar_location.png'; import toolbarPolylineIcon from '@/assets/icons/toolbar_polyline.png'; @@ -59,6 +60,7 @@ let drawTool = null let measureTool = null let bus = null let toolbarLayer = null +let primitiveList = [] const isOpen = ref(false) const options = ref([{ name: 'location', @@ -128,7 +130,8 @@ const drawLocation = (params) => { position, billboard: { image: params?.icon || drawLocationIcon, - verticalOrigin: Cesium.VerticalOrigin.BOTTOM + verticalOrigin: Cesium.VerticalOrigin.BOTTOM, + heightReference: Cesium.HeightReference.CLAMP_TO_GROUND, } }); }); @@ -148,6 +151,7 @@ const drawPolyline = () => { positions, width: 2, material: Cesium.Color.YELLOW, + clampToGround: true, }, }) }); @@ -167,10 +171,12 @@ const drawPolygon = () => { positions:[...positions, positions[0]], // 闭合多边形 width: 2, material: Cesium.Color.YELLOW, + clampToGround: true, }, polygon: { hierarchy: positions, material: Cesium.Color.YELLOW.withAlpha(0.5), + heightReference: Cesium.HeightReference.CLAMP_TO_GROUND, }, }); }); @@ -193,10 +199,12 @@ const drawCurvePolygon = () => { positions: fullPositions, width: 2, material: Cesium.Color.YELLOW, + clampToGround: true, }, polygon: { hierarchy: fullPositions, material: Cesium.Color.YELLOW.withAlpha(0.5), + heightReference: Cesium.HeightReference.CLAMP_TO_GROUND, }, }); }); @@ -219,10 +227,12 @@ const drawStraightArrow = () => { positions: [...fullPositions, fullPositions[0]], width: 2, material: Cesium.Color.YELLOW, + clampToGround: true, }, polygon: { hierarchy: fullPositions, material: Cesium.Color.YELLOW.withAlpha(0.5), + heightReference: Cesium.HeightReference.CLAMP_TO_GROUND, }, }) }); @@ -245,10 +255,12 @@ const drawWideArrow = () => { positions: [...fullPositions, fullPositions[0]], width: 2, material: Cesium.Color.YELLOW, + clampToGround: true, }, polygon: { hierarchy: fullPositions, material: Cesium.Color.YELLOW.withAlpha(0.5), + heightReference: Cesium.HeightReference.CLAMP_TO_GROUND, }, }) }); @@ -271,10 +283,12 @@ const drawAttackArrow = () => { positions: [...fullPositions, fullPositions[0]], width: 2, material: Cesium.Color.YELLOW, + clampToGround: true, }, polygon: { hierarchy: fullPositions, material: Cesium.Color.YELLOW.withAlpha(0.5), + heightReference: Cesium.HeightReference.CLAMP_TO_GROUND, }, }) }); @@ -297,10 +311,12 @@ const drawDoubleArrow = () => { positions: [...fullPositions, fullPositions[0]], width: 2, material: Cesium.Color.YELLOW, + clampToGround: true, }, polygon: { hierarchy: fullPositions, material: Cesium.Color.YELLOW.withAlpha(0.5), + heightReference: Cesium.HeightReference.CLAMP_TO_GROUND, }, }) }); @@ -342,31 +358,82 @@ const drawWatersource = () => { drawTool.drawPolygon().then((positions) => { // 计算中心点坐标 const center = getBoundingCenterCoordinate(positions); - // 添加水源地实体 - const entity = toolbarLayer?.entities.add({ - polyline: { - positions:[...positions, positions[0]], // 闭合多边形 - width: 2, - material: Cesium.Color.BLUE, - }, - polygon: { - hierarchy: positions, - material: Cesium.Color.BLUE.withAlpha(0.5), - }, - properties: { - __type: 'watersource', - name: '', - area: getArea(positions).toFixed(2), // 面积 - longitude: center[0].toFixed(6), - latitude: center[1].toFixed(6), - volume: 0 // 储水量,默认0 + + // // 添加水源地实体 + // const entity = toolbarLayer?.entities.add({ + // // polyline: { + // // positions:[...positions, positions[0]], // 闭合多边形 + // // width: 2, + // // material: Cesium.Color.BLUE, + // // }, + // polygon: { + // hierarchy: positions, + // material: riverMaterial, + // // material: Cesium.Color.BLUE.withAlpha(0.5), + // }, + // properties: { + // __type: 'watersource', + // name: '', + // area: getArea(positions).toFixed(2), // 面积 + // longitude: center[0].toFixed(6), + // latitude: center[1].toFixed(6), + // volume: 0 // 储水量,默认0 + // } + // }); + + const waterMaterial = new Cesium.Material({ + fabric: { + type: 'Water', + uniforms: { + normalMap: Cesium.buildModuleUrl('Assets/Textures/waterNormals.jpg'), + baseWaterColor: new Cesium.Color( + 64 / 255.0, + 157 / 255.0, + 253 / 255.0, + 0.6 + ), + // blendColor: new Cesium.Color(0.0, 0.5, 1.0, 1.0), + // frequency: 10.0, + // animationSpeed: 0.05, + // amplitude: 10, + // specularIntensity: 0.5, + // alpha: 0.1 + frequency: 1000.0, + animationSpeed: 0.1, + amplitude: 10, + specularIntensity: 1.5, + } } }); + + const waterPrimitive = new FeatureGroundPrimitive({ + geometryInstances: new Cesium.GeometryInstance({ + geometry: new Cesium.PolygonGeometry({ + polygonHierarchy: new Cesium.PolygonHierarchy(positions), + vertexFormat: Cesium.EllipsoidSurfaceAppearance.VERTEX_FORMAT, + }) + }), + appearance: new Cesium.EllipsoidSurfaceAppearance({ + material: waterMaterial, + }) + }, { + __type: 'watersource', + name: '', + area: getArea(positions).toFixed(2), // 面积 + longitude: center[0].toFixed(6), + latitude: center[1].toFixed(6), + volume: 0 // 储水量,默认0 + }); + + // 将 Primitive 添加到场景中 + viewer.scene.primitives.add(waterPrimitive); + primitiveList.push(waterPrimitive); + // 编辑属性 - DialogPropertyGrid.show(entity, (data) => { + DialogPropertyGrid.show(waterPrimitive, (data) => { // console.log('确定按钮被点击,最新表单数据:', formData); // 更新实体属性 - setPropertyData(data, entity); + setPropertyData(data, waterPrimitive); // 调用接口 }); }); @@ -414,6 +481,14 @@ const toolbarClear = () => { // 清除所有绘制的实体 toolbarLayer.entities.removeAll(); + // 清除所有绘制的图元 + for (let index = primitiveList.length - 1; index >= 0; index--) { + const p = primitiveList[index]; + if(viewer.scene.primitives.contains(p)) { + viewer.scene.primitives.remove(p); + primitiveList.splice(index, 1); + } + } measureTool?.clear(); // 清除当前测量 diff --git a/src/views/systemTemplate/forestFire/index.vue b/src/views/systemTemplate/forestFire/index.vue index 756597c..e1c4ffe 100644 --- a/src/views/systemTemplate/forestFire/index.vue +++ b/src/views/systemTemplate/forestFire/index.vue @@ -14,6 +14,7 @@ import { useEventBus } from '@/components/CesiumMap/mixins/useEventBus'; import Toolbar from './Toolbar.vue'; import DialogPropertyGrid from './DialogPropertyGrid'; import { setPropertyData } from './DialogPropertyGrid/property'; +import FeatureGroundPrimitive from '@/components/CesiumMap/FeatureGroundPrimitive'; const viewerRef = shallowRef(null) const options = ref({ @@ -27,6 +28,7 @@ const options = ref({ roll: 0 // 翻滚角 }, ditu: 'tianditu', // 底图选择 + isTerrainProvider: true, // 启用地形 }) const showProperty = ref(false); // 控制属性面板的显示与隐藏 const propertyData = ref([]) @@ -48,7 +50,7 @@ const initMap = (v) => { // 遍历拾取实体,获取第一个非辅助实体 for (let index = 0; index < pickedObjectList.length; index++) { const obj = pickedObjectList[index]; - if (Cesium.defined(obj) && obj.id && obj.id instanceof Cesium.Entity) { + if (obj && obj.id && obj.id instanceof Cesium.Entity) { // 辅助实体的name都以'__'开头,不识别 if(obj.id.name?.indexOf('__') === 0) { continue @@ -60,51 +62,18 @@ const initMap = (v) => { // 调用接口 }) return + } else if(obj.primitive && obj.primitive instanceof FeatureGroundPrimitive) { + DialogPropertyGrid.show(obj.primitive, (data) => { + // 更新实体属性 + setPropertyData(data, obj.primitive); + // 调用接口 + }) } } } }) }; -// 示例属性数据 -// propertyData.value = [ -// { key: 'id', name: 'ID', value: '12345', type: 'text', disabled: true }, -// { key: 'title', name: '标题', value: '这是一个标题', type: 'text', checkMethod: (val) => val.length > 0 || (ElMessage.error('标题不能为空'), false) }, -// { key: 'fontSize', name: '字体大小', value: 16, type: 'number', checkMethod: (val) => val >= 12 && val <= 72 || (ElMessage.error('字体大小必须在12-72之间'), false) }, -// { -// key: 'align', -// name: '对齐方式', -// value: 'left', -// type: 'select', -// options: [ -// { label: '左对齐', value: 'left' }, -// { label: '居中', value: 'center' }, -// { label: '右对齐', value: 'right' }, -// ], -// checkMethod: (val) => ['left', 'center', 'right'].includes(val) || (ElMessage.error('请选择有效的对齐方式'), false) -// }, -// { key: 'color', name: '文字颜色', value: '#409EFF', type: 'color' }, -// { key: 'visible', name: '是否可见', value: true, type: 'select', options: [{ label: '是', value: true }, { label: '否', value: false }] }, -// { key: 'description', name: '描述', value: '这是一段描述文本。', type: 'text' }, -// { key: 'padding', name: '内边距', value: 10, type: 'number', checkMethod: (val) => val >= 0 || (ElMessage.error('内边距不能为负数'), false) }, -// ]; - -// 处理属性值变化的事件 -const handlePropertyChange = (key, newValue, property) => { - console.log(`属性 "${property.name}" (key: ${key}) 的值变更为:`, newValue); - // 在这里你可以根据需要处理值的变化,例如同步到后端或更新其他状态 - // 因为组件内部已经更新了 internalData,如果父组件也需要响应式地使用这个数据, - // 并且不希望直接修改原始的 properties 数组,可以在这里根据 key 更新父组件的状态。 - // 例如: - // const index = properties.value.findIndex(item => item.key === key); - // if (index !== -1) { - // properties.value[index].value = newValue; - // } - // 注意:上面的直接修改 properties.value[index].value 是可以的,因为 properties 是 ref 包裹的数组。 - // 但如果 properties 是 props 传递下来的,则不应该直接修改。 - // 在这个示例中,properties 是父组件的 ref,所以直接修改是允许的。 -}; -