| | |
| | | </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"; |
| | | import { ref, onMounted, defineExpose } from "vue"; |
| | | |
| | | const viewer = window.viewer; |
| | | |
| | |
| | | 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); |
| | |
| | | pickedPointsCross.value.push(point); |
| | | drawPointOnMap(point); |
| | | if (pickedPointsCross.value.length === 2) { |
| | | // ElMessage.success('当前两点坐标已选取完成,正在生成断面截面!'); |
| | | drawWall(pickedPointsCross.value[0], pickedPointsCross.value[1]); |
| | | isWallCreated.value = true; // 设置为已创建墙体 |
| | | } |
| | |
| | | } |
| | | }); |
| | | 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)); |
| | |
| | | isWallCreated.value = false; |
| | | isUploaded.value = false; |
| | | } |
| | | |
| | | // 拾取点坐标然后画点(简化版) |
| | | function initPickHandler() { |
| | | // 切换状态:如果之前在拾取,这次就是取消拾取 |
| | | if (isPicking.value) { |
| | | if (pickHandlerCross) { |
| | | pickHandlerCross.destroy(); |
| | |
| | | ElMessage.info('已关闭--断面截面--拾取点坐标功能!'); |
| | | return; |
| | | } |
| | | |
| | | // 进入拾取模式 |
| | | ElMessage.success(`开始--断面截面--拾取坐标功能,请点击地图选择点位!选取完请及时关闭,避免影响其他功能!`); |
| | | isPicking.value = true; |
| | | |
| | | if (!viewer?.scene?.canvas) return; |
| | | |
| | | // 销毁旧的 handler |
| | | if (pickHandlerCross) { |
| | | pickHandlerCross.destroy(); |
| | | pickHandlerCross = null; |
| | | } |
| | | |
| | | // 创建新 handler |
| | | pickHandlerCross = new Cesium.ScreenSpaceEventHandler(viewer.scene.canvas); |
| | | |
| | | const clickAction = (movement) => { |
| | |
| | | |
| | | pickHandlerCross.setInputAction(clickAction, Cesium.ScreenSpaceEventType.LEFT_CLICK); |
| | | } |
| | | // 确认按钮点击事件,发送请求调用接口 |
| | | function confirmPoints() { |
| | | if (pickedPointsCross.value.length < 2) { |
| | | ElMessage.warning('请先选择两个点后再进行确认!'); |
| | |
| | | cartesian: point2.cartesian |
| | | }); |
| | | |
| | | isUploaded.value = true; // 设置为已上传状态 |
| | | isUploaded.value = true; |
| | | ElMessage.success('正在进行--断面截面--数据分析上传,请稍等...'); |
| | | } |
| | | |
| | | defineExpose({ |
| | | clearPoints |
| | | }); |