1.对toolbar代码进行拆分;2.修复bug;

This commit is contained in:
zhangquan 2025-07-15 10:43:02 +08:00
parent 8e6a168c37
commit 816f788240
8 changed files with 667 additions and 591 deletions

View File

@ -0,0 +1,16 @@
import * as Cesium from "cesium";
export default class FeaturePrimitive extends Cesium.Primitive {
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)) {
properties.addProperty(key, properties[key]);
}
}
}
}
}

View File

@ -67,7 +67,7 @@ export const useEventBus = (viewer) => {
if (typeof event === 'string') {
// 触发自定义事件
// mitt.emit(type, event), event 是 payload
cache.customEmitter.emit(event, args) // 将 ...args 作为单个数组 payload 传递
cache.customEmitter.emit(event, ...args) // 将 ...args 作为单个数组 payload 传递
} else if (Object.values(ScreenSpaceEventType).includes(event)) {
// 触发屏幕空间事件 (触发所有监听器,无模式检查)
// 屏幕空间事件通常只有一个参数

View File

@ -1,589 +0,0 @@
<template>
<div class="toolbar-box">
<div class="toolbar-title" :class="{ 'open': isOpen }" :title="isOpen ? '收起工具栏' : '展开工具栏'" @click="isOpen = !isOpen">
<span>工具栏</span>
<el-icon v-if="isOpen" style="font-size: 18px;"><DArrowRight /></el-icon>
<el-icon v-if="!isOpen" style="font-size: 28px;"><DArrowLeft /></el-icon>
</div>
<div class="toolbar-content">
<div v-if="isOpen" class="toolbar-item" v-for="(item, index) in options" :key="index" :title="item.label" @click="bus.emit(`toolbar_${item.name}`)">
<img :src="item.icon" alt="" />
<span class="toolbar-label">{{ item.label }}</span>
</div>
</div>
</div>
</template>
<script setup>
import * as Cesium from 'cesium';
import DialogPropertyGrid from './DialogPropertyGrid';
import {
useDrawTool,
createCurvePolygonPositions,
createStraightArrowPositions,
createWideArrowPositions,
createAttackArrowPositions,
createDoubleArrowPositions
} from '@/components/CesiumMap/mixins/useDrawTool';
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';
import toolbarPolygonIcon from '@/assets/icons/toolbar_polygon.png';
import toolbarCurvePolygonIcon from '@/assets/icons/toolbar_curve_polygon.png';
import toolbarStraightArrowIcon from '@/assets/icons/toolbar_straight_arrow.png';
import toolbarWideArrowIcon from '@/assets/icons/toolbar_wide_arrow.png';
import toolbarAttackArrowIcon from '@/assets/icons/toolbar_attack_arrow.png';
import toolbarDoubleArrowIcon from '@/assets/icons/toolbar_double_arrow.png';
import toolbarMeasureDistanceIcon from '@/assets/icons/toolbar_measure_distance.png';
import toolbarMeasureAreaIcon from '@/assets/icons/toolbar_measure_area.png';
import toolbarWarehouseIcon from '@/assets/icons/toolbar_warehouse.png';
import toolbarWatersourceIcon from '@/assets/icons/toolbar_watersource.png';
import toolbarClearIcon from '@/assets/icons/toolbar_clear.png';
import drawLocationIcon from '@/assets/icons/draw_location.png';
import fireWarehouseIcon from '@/assets/icons/fire_warehouse.png';
const props = defineProps({
viewer: {
default: null
}
})
//
let viewer = null
let drawTool = null
let measureTool = null
let bus = null
let toolbarLayer = null
let primitiveList = []
const isOpen = ref(false)
const options = ref([{
name: 'location',
label: '位置',
icon: toolbarLocationIcon
}, {
name: 'polyline',
label: '线',
icon: toolbarPolylineIcon
}, {
name: 'polygon',
label: '面',
icon: toolbarPolygonIcon
}, {
name: 'curvePolygon',
label: '曲面',
icon: toolbarCurvePolygonIcon
}, {
name: 'straightArrow',
label: '直箭头',
icon: toolbarStraightArrowIcon
}, {
name: 'wideArrow',
label: '宽箭头',
icon: toolbarWideArrowIcon
}, {
name: 'attackArrow',
label: '攻击箭头',
icon: toolbarAttackArrowIcon
}, {
name: 'doubleArrow',
label: '双箭头',
icon: toolbarDoubleArrowIcon
}, {
name: 'measureDistance',
label: '测距',
icon: toolbarMeasureDistanceIcon
}, {
name: 'measureArea',
label: '测面',
icon: toolbarMeasureAreaIcon
}, {
name: 'warehouse',
label: '仓库',
icon: toolbarWarehouseIcon
}, {
name: 'watersource',
label: '水源',
icon: toolbarWatersourceIcon
}, {
name: 'clear',
label: '清除',
icon: toolbarClearIcon
}])
//
const drawLocation = (params) => {
if(!drawTool) {
console.error('绘制工具未初始化');
return;
}
drawTool.abort();
measureTool.abort();
drawTool.drawPoint().then(position => {
toolbarLayer?.entities.add({
position,
billboard: {
image: params?.icon || drawLocationIcon,
verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
heightReference: Cesium.HeightReference.CLAMP_TO_GROUND,
}
});
});
};
// 线
const drawPolyline = () => {
if(!drawTool) {
console.error('绘制工具未初始化');
return;
}
drawTool.abort();
measureTool.abort();
drawTool.drawPolyline().then((positions) => {
toolbarLayer?.entities.add({
polyline: {
positions,
width: 2,
material: Cesium.Color.YELLOW,
clampToGround: true,
},
})
});
};
//
const drawPolygon = () => {
if(!drawTool) {
console.error('绘制工具未初始化');
return;
}
drawTool.abort();
measureTool.abort();
drawTool.drawPolygon().then((positions) => {
toolbarLayer?.entities.add({
polyline: {
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,
},
});
});
};
//
const drawCurvePolygon = () => {
if(!drawTool) {
console.error('绘制工具未初始化');
return;
}
drawTool.abort();
measureTool.abort();
drawTool.drawCurvePolygon().then((positions) => {
if (positions.length < 2 || !positions[0]) return
const fullPositions = createCurvePolygonPositions(positions)
toolbarLayer?.entities.add({
polyline: {
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,
},
});
});
};
//
const drawStraightArrow = () => {
if(!drawTool) {
console.error('绘制工具未初始化');
return;
}
drawTool.abort();
measureTool.abort();
drawTool.drawStraightArrow().then((positions) => {
if (!positions[0] || !positions[1]) return
const fullPositions = createStraightArrowPositions(positions)
toolbarLayer?.entities.add({
polyline: {
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,
},
})
});
};
//
const drawWideArrow = () => {
if(!drawTool) {
console.error('绘制工具未初始化');
return;
}
drawTool.abort();
measureTool.abort();
drawTool.drawWideArrow().then((positions) => {
if (positions.length < 2) return
const fullPositions = createWideArrowPositions(positions)
toolbarLayer?.entities.add({
polyline: {
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,
},
})
});
};
//
const drawAttackArrow = () => {
if(!drawTool) {
console.error('绘制工具未初始化');
return;
}
drawTool.abort();
measureTool.abort();
drawTool.drawAttackArrow().then((positions) => {
if (positions.length < 3) return
const fullPositions = createAttackArrowPositions(positions)
toolbarLayer?.entities.add({
polyline: {
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,
},
})
});
};
//
const drawDoubleArrow = () => {
if(!drawTool) {
console.error('绘制工具未初始化');
return;
}
drawTool.abort();
measureTool.abort();
drawTool.drawDoubleArrow().then((positions) => {
if (positions.length < 3) return
const fullPositions = createDoubleArrowPositions(positions)
toolbarLayer?.entities.add({
polyline: {
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,
},
})
});
};
//
const drawMeasureDistance = () => {
if(!measureTool) {
console.error('绘制工具未初始化');
return;
}
drawTool.abort();
measureTool.abort();
measureTool.distance();
};
//
const drawMeasureArea = () => {
if(!measureTool) {
console.error('绘制工具未初始化');
return;
}
drawTool.abort();
measureTool.abort();
measureTool.area();
};
//
const drawWatersource = () => {
if(!drawTool) {
console.error('绘制工具未初始化');
return;
}
drawTool.abort();
measureTool.abort();
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: 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(waterPrimitive, (data) => {
// console.log(':', formData);
//
setPropertyData(data, waterPrimitive);
//
});
});
};
//
const drawWarehouse = (params) => {
if(!drawTool) {
console.error('绘制工具未初始化');
return;
}
drawTool.abort();
drawTool.drawPoint().then((position) => {
//
const center = Cesium.Cartographic.fromCartesian(position);
const entity = toolbarLayer?.entities.add({
position,
billboard: {
image: params?.icon || fireWarehouseIcon,
verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
pixelOffset: new Cesium.Cartesian2(0, params?.icon ? 0 : 18), //
},
properties: {
__type: 'warehouse',
name: '',
longitude: Cesium.Math.toDegrees(center.longitude).toFixed(6),
latitude: Cesium.Math.toDegrees(center.latitude).toFixed(6),
}
});
//
DialogPropertyGrid.show(entity, (data) => {
// console.log(':', formData);
//
setPropertyData(data, entity);
//
});
});
};
//
const toolbarClear = () => {
if (!viewer || !toolbarLayer) return;
//
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();
//
if (measureTool) {
measureTool.abort();
}
//
if (drawTool) {
drawTool.abort();
}
};
watch(() => props.viewer, (v) => {
if (v) {
viewer = v;
//
toolbarLayer = new Cesium.CustomDataSource('toolbarLayer');
viewer.dataSources.add(toolbarLayer);
drawTool = useDrawTool(viewer);
measureTool = useMeasureTool(viewer);
//
bus = useEventBus(viewer);
bus.on('toolbar_location', drawLocation);
bus.on('toolbar_polyline', drawPolyline);
bus.on('toolbar_polygon', drawPolygon);
bus.on('toolbar_curvePolygon', drawCurvePolygon);
bus.on('toolbar_straightArrow', drawStraightArrow);
bus.on('toolbar_wideArrow', drawWideArrow);
bus.on('toolbar_attackArrow', drawAttackArrow);
bus.on('toolbar_doubleArrow', drawDoubleArrow);
bus.on('toolbar_measureDistance', drawMeasureDistance);
bus.on('toolbar_measureArea', drawMeasureArea);
bus.on('toolbar_watersource', drawWatersource);
bus.on('toolbar_warehouse', drawWarehouse);
bus.on('toolbar_clear', toolbarClear);
}
}, { immediate: true });
</script>
<style lang="scss" scoped>
.toolbar-box {
.toolbar-title {
display: flex;
flex-direction: column;
align-items: center;
justify-content: space-between;
color: #8EF8FF;
background-color: rgba(7, 111, 111, 0.7);
padding: 4px;
border-radius: 4px;
cursor: pointer;
margin: 0 4px 4px 0;
&.open {
flex-direction: row;
align-items: end;
}
}
}
.toolbar-content {
max-height: 420px;
font-size: 12px;
display: flex;
flex-direction: column;
flex-wrap: wrap;
// justify-content: space-around;
.toolbar-item {
width: 48px;
height: 48px;
color: #8EF8FF;
background-color: rgba(7, 111, 111, 0.7);
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
margin: 0 4px 4px 0;
border-radius: 4px;
cursor: pointer;
&:hover {
background-color: rgba(255, 215, 0, 0.5);
}
.toolbar-label {
width: 100%;
text-align: center;
text-overflow: ellipsis;
overflow: hidden;
word-break: break-all;
white-space: nowrap;
}
}
}
</style>

View File

@ -0,0 +1,242 @@
<template>
<div class="toolbar-box">
<div class="toolbar-title" :class="{ 'open': isOpen }" :title="isOpen ? '收起工具栏' : '展开工具栏'" @click="isOpen = !isOpen">
<span>工具栏</span>
<el-icon v-if="isOpen" style="font-size: 18px;"><DArrowRight /></el-icon>
<el-icon v-if="!isOpen" style="font-size: 28px;"><DArrowLeft /></el-icon>
</div>
<div class="toolbar-content">
<div v-if="isOpen" class="toolbar-item" v-for="(item, index) in options" :key="index" :title="item.label" @click="bus.emit(`toolbar_${item.name}`, params)">
<img :src="item.icon" alt="" />
<span class="toolbar-label">{{ item.label }}</span>
</div>
</div>
</div>
</template>
<script setup>
import * as Cesium from 'cesium';
import { useDrawTool } from '@/components/CesiumMap/mixins/useDrawTool';
import { useEventBus } from '@/components/CesiumMap/mixins/useEventBus';
import { useMeasureTool } from '@/components/CesiumMap/mixins/useMeasureTool';
import {
drawLocation,
drawPolyline,
drawPolygon,
drawCurvePolygon,
drawStraightArrow,
drawWideArrow,
drawAttackArrow,
drawDoubleArrow,
drawMeasureDistance,
drawMeasureArea
} from './baseDraw'
import {
drawWatersource,
drawWarehouse
} from './forestFireDraw'
import toolbarLocationIcon from '@/assets/icons/toolbar_location.png';
import toolbarPolylineIcon from '@/assets/icons/toolbar_polyline.png';
import toolbarPolygonIcon from '@/assets/icons/toolbar_polygon.png';
import toolbarCurvePolygonIcon from '@/assets/icons/toolbar_curve_polygon.png';
import toolbarStraightArrowIcon from '@/assets/icons/toolbar_straight_arrow.png';
import toolbarWideArrowIcon from '@/assets/icons/toolbar_wide_arrow.png';
import toolbarAttackArrowIcon from '@/assets/icons/toolbar_attack_arrow.png';
import toolbarDoubleArrowIcon from '@/assets/icons/toolbar_double_arrow.png';
import toolbarMeasureDistanceIcon from '@/assets/icons/toolbar_measure_distance.png';
import toolbarMeasureAreaIcon from '@/assets/icons/toolbar_measure_area.png';
import toolbarWarehouseIcon from '@/assets/icons/toolbar_warehouse.png';
import toolbarWatersourceIcon from '@/assets/icons/toolbar_watersource.png';
import toolbarClearIcon from '@/assets/icons/toolbar_clear.png';
const props = defineProps({
viewer: {
default: null
}
})
//
let viewer = null
let drawTool = null
let measureTool = null
let bus = null
let toolbarLayer = null
let primitiveList = []
let params = {}
const isOpen = ref(false)
const options = ref([{
name: 'location',
label: '位置',
icon: toolbarLocationIcon
}, {
name: 'polyline',
label: '线',
icon: toolbarPolylineIcon
}, {
name: 'polygon',
label: '面',
icon: toolbarPolygonIcon
}, {
name: 'curvePolygon',
label: '曲面',
icon: toolbarCurvePolygonIcon
}, {
name: 'straightArrow',
label: '直箭头',
icon: toolbarStraightArrowIcon
}, {
name: 'wideArrow',
label: '宽箭头',
icon: toolbarWideArrowIcon
}, {
name: 'attackArrow',
label: '攻击箭头',
icon: toolbarAttackArrowIcon
}, {
name: 'doubleArrow',
label: '双箭头',
icon: toolbarDoubleArrowIcon
}, {
name: 'measureDistance',
label: '测距',
icon: toolbarMeasureDistanceIcon
}, {
name: 'measureArea',
label: '测面',
icon: toolbarMeasureAreaIcon
}, {
name: 'warehouse',
label: '仓库',
icon: toolbarWarehouseIcon
}, {
name: 'watersource',
label: '水源',
icon: toolbarWatersourceIcon
}, {
name: 'clear',
label: '清除',
icon: toolbarClearIcon
}])
//
const toolbarClear = () => {
if (!viewer || !toolbarLayer) return;
//
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();
//
if (measureTool) {
measureTool.abort();
}
//
if (drawTool) {
drawTool.abort();
}
};
watch(() => props.viewer, (v) => {
if (v) {
viewer = v;
//
toolbarLayer = new Cesium.CustomDataSource('toolbarLayer');
viewer.dataSources.add(toolbarLayer);
drawTool = useDrawTool(viewer);
measureTool = useMeasureTool(viewer);
//
params = {
drawTool,
measureTool,
viewer,
toolbarLayer,
primitiveList,
}
bus = useEventBus(viewer);
bus.on('toolbar_location', drawLocation);
bus.on('toolbar_polyline', drawPolyline);
bus.on('toolbar_polygon', drawPolygon);
bus.on('toolbar_curvePolygon', drawCurvePolygon);
bus.on('toolbar_straightArrow', drawStraightArrow);
bus.on('toolbar_wideArrow', drawWideArrow);
bus.on('toolbar_attackArrow', drawAttackArrow);
bus.on('toolbar_doubleArrow', drawDoubleArrow);
bus.on('toolbar_measureDistance', drawMeasureDistance);
bus.on('toolbar_measureArea', drawMeasureArea);
bus.on('toolbar_watersource', drawWatersource);
bus.on('toolbar_warehouse', drawWarehouse);
bus.on('toolbar_clear', toolbarClear);
}
}, { immediate: true });
</script>
<style lang="scss" scoped>
.toolbar-box {
.toolbar-title {
display: flex;
flex-direction: column;
align-items: center;
justify-content: space-between;
color: #8EF8FF;
background-color: rgba(7, 111, 111, 0.7);
padding: 4px;
border-radius: 4px;
cursor: pointer;
margin: 0 4px 4px 0;
&.open {
flex-direction: row;
align-items: end;
}
}
}
.toolbar-content {
max-height: 420px;
font-size: 12px;
display: flex;
flex-direction: column;
flex-wrap: wrap;
// justify-content: space-around;
.toolbar-item {
width: 48px;
height: 48px;
color: #8EF8FF;
background-color: rgba(7, 111, 111, 0.7);
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
margin: 0 4px 4px 0;
border-radius: 4px;
cursor: pointer;
&:hover {
background-color: rgba(255, 215, 0, 0.5);
}
.toolbar-label {
width: 100%;
text-align: center;
text-overflow: ellipsis;
overflow: hidden;
word-break: break-all;
white-space: nowrap;
}
}
}
</style>

View File

@ -0,0 +1,262 @@
import * as Cesium from 'cesium'
import {
createCurvePolygonPositions,
createStraightArrowPositions,
createWideArrowPositions,
createAttackArrowPositions,
createDoubleArrowPositions
} from '@/components/CesiumMap/mixins/useDrawTool';
import drawLocationIcon from '@/assets/icons/draw_location.png';
// 绘制位置
const drawLocation = (options) => {
const { toolbarLayer, drawTool, measureTool } = options;
if(!drawTool) {
console.error('绘制工具未初始化');
return;
}
drawTool.abort();
measureTool.abort();
drawTool.drawPoint().then(position => {
toolbarLayer?.entities.add({
position,
billboard: {
image: drawLocationIcon,
verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
heightReference: Cesium.HeightReference.CLAMP_TO_GROUND,
}
});
});
};
// 绘制线
const drawPolyline = (options) => {
const { toolbarLayer, drawTool, measureTool } = options;
if(!drawTool) {
console.error('绘制工具未初始化');
return;
}
drawTool.abort();
measureTool.abort();
drawTool.drawPolyline().then((positions) => {
toolbarLayer?.entities.add({
polyline: {
positions,
width: 2,
material: Cesium.Color.YELLOW,
clampToGround: true,
},
})
});
};
// 绘制面
const drawPolygon = (options) => {
const { toolbarLayer, drawTool, measureTool } = options;
if(!drawTool) {
console.error('绘制工具未初始化');
return;
}
drawTool.abort();
measureTool.abort();
drawTool.drawPolygon().then((positions) => {
toolbarLayer?.entities.add({
polyline: {
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,
},
});
});
};
// 绘制曲面
const drawCurvePolygon = (options) => {
const { toolbarLayer, drawTool, measureTool } = options;
if(!drawTool) {
console.error('绘制工具未初始化');
return;
}
drawTool.abort();
measureTool.abort();
drawTool.drawCurvePolygon().then((positions) => {
if (positions.length < 2 || !positions[0]) return
const fullPositions = createCurvePolygonPositions(positions)
toolbarLayer?.entities.add({
polyline: {
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,
},
});
});
};
// 绘制直箭头
const drawStraightArrow = (options) => {
const { toolbarLayer, drawTool, measureTool } = options;
if(!drawTool) {
console.error('绘制工具未初始化');
return;
}
drawTool.abort();
measureTool.abort();
drawTool.drawStraightArrow().then((positions) => {
if (!positions[0] || !positions[1]) return
const fullPositions = createStraightArrowPositions(positions)
toolbarLayer?.entities.add({
polyline: {
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,
},
})
});
};
// 绘制宽箭头
const drawWideArrow = (options) => {
const { toolbarLayer, drawTool, measureTool } = options;
if(!drawTool) {
console.error('绘制工具未初始化');
return;
}
drawTool.abort();
measureTool.abort();
drawTool.drawWideArrow().then((positions) => {
if (positions.length < 2) return
const fullPositions = createWideArrowPositions(positions)
toolbarLayer?.entities.add({
polyline: {
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,
},
})
});
};
// 绘制攻击箭头
const drawAttackArrow = (options) => {
const { toolbarLayer, drawTool, measureTool } = options;
if(!drawTool) {
console.error('绘制工具未初始化');
return;
}
drawTool.abort();
measureTool.abort();
drawTool.drawAttackArrow().then((positions) => {
if (positions.length < 3) return
const fullPositions = createAttackArrowPositions(positions)
toolbarLayer?.entities.add({
polyline: {
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,
},
})
});
};
// 绘制双箭头
const drawDoubleArrow = (options) => {
const { toolbarLayer, drawTool, measureTool } = options;
if(!drawTool) {
console.error('绘制工具未初始化');
return;
}
drawTool.abort();
measureTool.abort();
drawTool.drawDoubleArrow().then((positions) => {
if (positions.length < 3) return
const fullPositions = createDoubleArrowPositions(positions)
toolbarLayer?.entities.add({
polyline: {
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,
},
})
});
};
// 平面距离测量的绘制
const drawMeasureDistance = (options) => {
const { drawTool, measureTool } = options;
if(!measureTool) {
console.error('绘制工具未初始化');
return;
}
drawTool.abort();
measureTool.abort();
measureTool.distance();
};
// 平面面积测量的绘制
const drawMeasureArea = (options) => {
const { drawTool, measureTool } = options;
if(!measureTool) {
console.error('绘制工具未初始化');
return;
}
drawTool.abort();
measureTool.abort();
measureTool.area();
};
export {
drawLocation,
drawPolyline,
drawPolygon,
drawCurvePolygon,
drawStraightArrow,
drawWideArrow,
drawAttackArrow,
drawDoubleArrow,
drawMeasureDistance,
drawMeasureArea
}

View File

@ -0,0 +1,142 @@
import * as Cesium from 'cesium'
import DialogPropertyGrid from '../DialogPropertyGrid';
import { setPropertyData } from '../DialogPropertyGrid/property';
import FeatureGroundPrimitive from '@/components/CesiumMap/FeatureGroundPrimitive';
import { getArea, getBoundingCenterCoordinate } from '@/components/CesiumMap/mixins/useMeasureTool';
import fireWarehouseIcon from '@/assets/icons/fire_warehouse.png';
// 绘制水源地(面)
const drawWatersource = (options) => {
const { drawTool, measureTool, viewer, primitiveList } = options;
if(!drawTool) {
console.error('绘制工具未初始化');
return;
}
drawTool.abort();
measureTool.abort();
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: 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(waterPrimitive, (data) => {
// 更新实体属性
setPropertyData(data, waterPrimitive);
// 调用接口
});
});
};
// 绘制仓库(点)
const drawWarehouse = (options) => {
const { drawTool, measureTool, toolbarLayer } = options;
if(!drawTool) {
console.error('绘制工具未初始化');
return;
}
drawTool.abort();
measureTool.abort();
drawTool.drawPoint().then((position) => {
// 计算中心点坐标
const center = Cesium.Cartographic.fromCartesian(position);
const entity = toolbarLayer?.entities.add({
position,
billboard: {
image: fireWarehouseIcon,
verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
pixelOffset: new Cesium.Cartesian2(0, 18), // 可选偏移
},
properties: {
__type: 'warehouse',
name: '',
longitude: Cesium.Math.toDegrees(center.longitude).toFixed(6),
latitude: Cesium.Math.toDegrees(center.latitude).toFixed(6),
}
});
// 编辑属性
DialogPropertyGrid.show(entity, (data) => {
// 更新实体属性
setPropertyData(data, entity);
// 调用接口
});
});
};
export {
drawWatersource,
drawWarehouse
}

View File

@ -0,0 +1,3 @@
import Toolbar from './Toolbar'
export default Toolbar

View File

@ -11,7 +11,7 @@ import { shallowRef } from 'vue';
import * as Cesium from 'cesium';
import CesiumMap from '@/components/CesiumMap/index.vue';
import { useEventBus } from '@/components/CesiumMap/mixins/useEventBus';
import Toolbar from './Toolbar.vue';
import Toolbar from './Toolbar';
import DialogPropertyGrid from './DialogPropertyGrid';
import { setPropertyData } from './DialogPropertyGrid/property';
import FeatureGroundPrimitive from '@/components/CesiumMap/FeatureGroundPrimitive';