<template>
|
<div style="display: flex; justify-content: space-between;">
|
<div @click="initPickHandler">
|
<img v-if="!isPicking" src="@/assets/img/timeline/断面.png" style="width: 26px;height: 26px;" />
|
<img v-else src="@/assets/img/timeline/已断面.png" style="width: 26px;height: 26px;" />
|
</div>
|
<div @click="confirmPoints">
|
<img v-if="!isUploaded" src="@/assets/img/timeline/上传.png" style="width: 26px;height: 26px;" />
|
<img v-else src="@/assets/img/timeline/已上传.png" style="width: 26px;height: 26px;" />
|
</div>
|
<div @click="clearPoints">
|
<img src="@/assets/img/timeline/清除.png" style="width: 26px;height: 26px;" />
|
</div>
|
</div>
|
</template>
|
|
<script setup>
|
import { ElMessage } from 'element-plus';
|
import { ref, onMounted, defineExpose } from "vue";
|
|
const viewer = window.viewer;
|
|
let pickedPointsCross = ref([]);
|
let pickHandlerCross = null;
|
let isWallCreated = ref(false); // 新增状态变量,标记墙体是否已创建
|
let isPicking = ref(false); // 是否正在拾取点
|
const isUploaded = ref(false); // 控制是否已上传
|
|
// 获取断面坐标
|
function getPickPosition(windowPosition) {
|
if (!viewer) return null;
|
viewer.scene.globe.depthTestAgainstTerrain = true;
|
const cartesian = viewer.scene.pickPosition(windowPosition);
|
if (!cartesian) return null;
|
const cartographic = Cesium.Cartographic.fromCartesian(cartesian);
|
const longitude = Cesium.Math.toDegrees(cartographic.longitude);
|
const latitude = Cesium.Math.toDegrees(cartographic.latitude);
|
const terrainHeight = viewer.scene.globe.getHeight(cartographic);
|
if (!terrainHeight) return null;
|
const positionWithTerrainHeight = Cesium.Cartesian3.fromRadians(
|
cartographic.longitude,
|
cartographic.latitude,
|
terrainHeight
|
);
|
return {
|
cartesian: positionWithTerrainHeight,
|
longitude,
|
latitude
|
};
|
}
|
|
// 选取两个断面点坐标并绘制断面截面
|
function addPointToViewer(point) {
|
if (pickedPointsCross.value.length >= 2) {
|
clearPoints();
|
}
|
pickedPointsCross.value.push(point);
|
drawPointOnMap(point);
|
if (pickedPointsCross.value.length === 2) {
|
drawWall(pickedPointsCross.value[0], pickedPointsCross.value[1]);
|
isWallCreated.value = true; // 设置为已创建墙体
|
}
|
}
|
|
let pickedEntitiesIds = ref([]); // 用于存储创建的点和墙的ID
|
|
// 绘制两个断面点坐标,并记录其ID
|
function drawPointOnMap(point) {
|
const entity = viewer.entities.add({
|
position: point.cartesian,
|
point: {
|
color: Cesium.Color.RED,
|
outlineColor: Cesium.Color.YELLOW,
|
outlineWidth: 2,
|
pixelSize: 8 // 圆点半径大小
|
}
|
});
|
pickedEntitiesIds.value.push(entity.id); // 记录实体ID
|
}
|
|
// 创建断面截面,并记录其ID
|
function drawWall(startPoint, endPoint) {
|
const entity = viewer.entities.add({
|
wall: {
|
positions: [startPoint.cartesian, endPoint.cartesian],
|
material: Cesium.Color.YELLOW,
|
heightReference: Cesium.HeightReference.RELATIVE_TO_GROUND,
|
}
|
});
|
pickedEntitiesIds.value.push(entity.id); // 记录实体ID
|
// 同时绘制模拟点
|
drawSimulationPoint(startPoint, endPoint);
|
}
|
|
// 新增:绘制模拟点(圆柱 + label)
|
function drawSimulationPoint(start, end) {
|
// 计算中点(经纬度平均值)
|
const midLon = (start.longitude + end.longitude) / 2;
|
const midLat = (start.latitude + end.latitude) / 2;
|
const terrainHeight = viewer.scene.globe.getHeight(
|
Cesium.Cartographic.fromDegrees(midLon, midLat)
|
);
|
const cylinderBottomHeight = 0;
|
const cylinderTopHeight = terrainHeight + 190;
|
const cartesianBottom = viewer.scene.globe.ellipsoid.cartographicToCartesian(
|
Cesium.Cartographic.fromDegrees(midLon, midLat, cylinderBottomHeight)
|
);
|
const CrosscylinderEntity = viewer.entities.add({
|
position: cartesianBottom,
|
cylinder: {
|
length: 190.0,
|
topRadius: 1.0,
|
bottomRadius: 1.0,
|
material: Cesium.Color.YELLOW,
|
outline: true,
|
outlineColor: Cesium.Color.YELLOW,
|
slices: 64,
|
heightReference: Cesium.HeightReference.RELATIVE_TO_GROUND,
|
distanceDisplayCondition: new Cesium.DistanceDisplayCondition(0, 5000)
|
}
|
});
|
const labelHeight = cylinderTopHeight + 10;
|
const cartesianLabel = viewer.scene.globe.ellipsoid.cartographicToCartesian(
|
Cesium.Cartographic.fromDegrees(midLon, midLat, labelHeight)
|
);
|
|
const CrosslabelEntity = viewer.entities.add({
|
position: cartesianLabel,
|
label: {
|
text: '断面截面模拟点',
|
font: 'bold 14pt monospace',
|
style: Cesium.LabelStyle.FILL_AND_OUTLINE,
|
fillColor: Cesium.Color.YELLOW,
|
outlineColor: Cesium.Color.BLACK,
|
outlineWidth: 2,
|
verticalOrigin: Cesium.VerticalOrigin.CENTER,
|
horizontalOrigin: Cesium.HorizontalOrigin.CENTER,
|
backgroundColor: Cesium.Color.fromCssColorString('rgba(0,0,0,0.7)'),
|
backgroundPadding: new Cesium.Cartesian2(10, 10),
|
showBackground: true,
|
scale: 1,
|
distanceDisplayCondition: new Cesium.DistanceDisplayCondition(0, 5000),
|
pixelOffsetScaleByDistance: new Cesium.NearFarScalar(100, 1.0, 5000, 0.3),
|
heightReference: Cesium.HeightReference.NONE // 使用绝对高度
|
}
|
});
|
pickedEntitiesIds.value.push(CrosscylinderEntity.id);
|
pickedEntitiesIds.value.push(CrosslabelEntity.id);
|
}
|
function clearPoints() {
|
for (const id of pickedEntitiesIds.value) {
|
viewer.entities.remove(viewer.entities.getById(id));
|
}
|
pickedPointsCross.value = [];
|
pickedEntitiesIds.value = [];
|
isWallCreated.value = false;
|
isUploaded.value = false;
|
}
|
function initPickHandler() {
|
if (isPicking.value) {
|
if (pickHandlerCross) {
|
pickHandlerCross.destroy();
|
pickHandlerCross = null;
|
}
|
isPicking.value = false;
|
isUploaded.value = false;
|
ElMessage.info('已关闭--断面截面--拾取点坐标功能!');
|
return;
|
}
|
ElMessage.success(`开始--断面截面--拾取坐标功能,请点击地图选择点位!选取完请及时关闭,避免影响其他功能!`);
|
isPicking.value = true;
|
if (!viewer?.scene?.canvas) return;
|
if (pickHandlerCross) {
|
pickHandlerCross.destroy();
|
pickHandlerCross = null;
|
}
|
pickHandlerCross = new Cesium.ScreenSpaceEventHandler(viewer.scene.canvas);
|
|
const clickAction = (movement) => {
|
const position = getPickPosition(movement.position);
|
if (position) {
|
addPointToViewer(position);
|
}
|
};
|
|
pickHandlerCross.setInputAction(clickAction, Cesium.ScreenSpaceEventType.LEFT_CLICK);
|
}
|
function confirmPoints() {
|
if (pickedPointsCross.value.length < 2) {
|
ElMessage.warning('请先选择两个点后再进行确认!');
|
return;
|
}
|
|
const point1 = pickedPointsCross.value[0];
|
const point2 = pickedPointsCross.value[1];
|
|
console.log('第一个点信息:', {
|
longitude: point1.longitude,
|
latitude: point1.latitude,
|
cartesian: point1.cartesian
|
});
|
|
console.log('第二个点信息:', {
|
longitude: point2.longitude,
|
latitude: point2.latitude,
|
cartesian: point2.cartesian
|
});
|
|
isUploaded.value = true;
|
ElMessage.success('正在进行--断面截面--数据分析上传,请稍等...');
|
}
|
|
defineExpose({
|
clearPoints
|
});
|
</script>
|