From b4d75c3917bab54f677dab0570ff028c0609a99a Mon Sep 17 00:00:00 2001
From: 罗广辉 <guanghui.luo@foxmail.com>
Date: Wed, 21 Jan 2026 15:40:04 +0800
Subject: [PATCH] feat: flyVisual
---
applications/drone-command/src/components/map-container/mapContainer.vue | 2
applications/task-work-order/src/components/map-container/mapContainer.vue | 2
applications/task-work-order/src/hooks/useRouteLine/useRouteLine.js | 2
applications/task-work-order/src/utils/cesium/DrawPolygon.js | 3
packages/utils/map/index.js | 75 ++++++++-
applications/drone-command/src/utils/cesium/mapUtil.js | 61 --------
applications/drone-command/src/views/job/components/DeviceJobDetailsMap.vue | 2
applications/task-work-order/src/views/orderView/orderManage/orderManage/FormDiaLog.vue | 7
applications/task-work-order/src/components/PlaybackVideo/components/MapContainer.vue | 2
applications/task-work-order/src/utils/cesium/mapUtil.js | 59 --------
applications/drone-command/src/utils/cesium/DrawPolygon.js | 3
applications/drone-command/src/views/resource/components/spotDetails.vue | 92 ++++++------
applications/task-work-order/src/views/resource/components/spotDetails.vue | 92 ++++++------
applications/drone-command/src/hooks/useRouteLine/useRouteLine.js | 2
applications/drone-command/src/components/PlaybackVideo/components/MapContainer.vue | 2
applications/drone-command/src/views/monitor/log/flightLog.vue | 4
applications/drone-command/src/views/layerManagement/index.vue | 2
applications/drone-command/src/views/recordManage/historyTracks/TrajectoryDiaLog.vue | 6
18 files changed, 176 insertions(+), 242 deletions(-)
diff --git a/applications/drone-command/src/components/PlaybackVideo/components/MapContainer.vue b/applications/drone-command/src/components/PlaybackVideo/components/MapContainer.vue
index 0ab4b0e..033a347 100644
--- a/applications/drone-command/src/components/PlaybackVideo/components/MapContainer.vue
+++ b/applications/drone-command/src/components/PlaybackVideo/components/MapContainer.vue
@@ -15,7 +15,7 @@
import PlanarRouteLineList from '@/components/PlanarRouteLineList/PlanarRouteLineList.vue'
-import { flyVisual } from '@/utils/cesium/mapUtil'
+import { flyVisual } from '@ztzf/utils'
import * as Cesium from 'cesium'
import { PublicCesium } from '@/utils/cesium/publicCesium'
diff --git a/applications/drone-command/src/components/map-container/mapContainer.vue b/applications/drone-command/src/components/map-container/mapContainer.vue
index bd5dc22..c9c6ae3 100644
--- a/applications/drone-command/src/components/map-container/mapContainer.vue
+++ b/applications/drone-command/src/components/map-container/mapContainer.vue
@@ -30,7 +30,7 @@
import { Cartesian3, Terrain, Viewer } from 'cesium';
import { PublicCesium } from '@/utils/cesium/publicCesium';
import ImageTrailMaterial from '@/utils/cesium/ImageTrailMaterial';
-import { flyVisual } from '@/utils/cesium/mapUtil';
+import { flyVisual } from '@ztzf/utils';
import * as turf from '@turf/turf';
import { nextTick, onBeforeUnmount, onMounted, onUnmounted } from 'vue';
diff --git a/applications/drone-command/src/hooks/useRouteLine/useRouteLine.js b/applications/drone-command/src/hooks/useRouteLine/useRouteLine.js
index 8dfae23..45dacd5 100644
--- a/applications/drone-command/src/hooks/useRouteLine/useRouteLine.js
+++ b/applications/drone-command/src/hooks/useRouteLine/useRouteLine.js
@@ -11,7 +11,7 @@
import endPointImg from '@/assets/images/EndPointicon.png'
import { ArrowLineMaterialProperty } from '@/utils/cesium/Material'
-import { flyVisual } from '@/utils/cesium/mapUtil'
+import { flyVisual } from '@ztzf/utils'
import { useStore } from 'vuex'
diff --git a/applications/drone-command/src/utils/cesium/DrawPolygon.js b/applications/drone-command/src/utils/cesium/DrawPolygon.js
index 4a4f10c..b7bc2c0 100644
--- a/applications/drone-command/src/utils/cesium/DrawPolygon.js
+++ b/applications/drone-command/src/utils/cesium/DrawPolygon.js
@@ -2,7 +2,8 @@
import * as turf from '@turf/turf'
import { boxTransformScale } from '@/utils/turfFunc'
import { ElMessage } from 'element-plus'
-import { flyVisual, getPointPositionsHeight } from '@/utils/cesium/mapUtil'
+import { getPointPositionsHeight } from '@/utils/cesium/mapUtil'
+import { flyVisual } from '@ztzf/utils'
/**
* 多边形绘制与编辑工具类
diff --git a/applications/drone-command/src/utils/cesium/mapUtil.js b/applications/drone-command/src/utils/cesium/mapUtil.js
index 89bf787..767f5b0 100644
--- a/applications/drone-command/src/utils/cesium/mapUtil.js
+++ b/applications/drone-command/src/utils/cesium/mapUtil.js
@@ -449,67 +449,6 @@
}
}
-/**
- * 飞到中心点并且所有点在可视范围
- * @param positionsData 二维数组,每项为 [lon, lat] 或 三维数组 [lon, lat, height]
- * @param viewer Cesium.Viewer 实例
- * @param multiple 缩放倍数-默认为4
- * @param pitch 俯仰角-默认为-90
- */
-export function flyVisual({ positionsData, viewer, multiple = 4, pitch = -90 }) {
- if (!Array.isArray(positionsData) || positionsData.length === 0) return
-
- // 如果是一个点,加两个点方便后续生成外包围盒
- if (positionsData.length === 1) {
- const [lon, lat, height = 0] = positionsData[0]
- positionsData = [
- [lon + 0.001, lat + 0.001, height],
- [lon - 0.001, lat - 0.001, height],
- [lon, lat, height],
- ]
- }
- const positions = positionsData.map(([lon, lat, height = 0]) =>
- Cesium.Cartesian3.fromDegrees(Number(lon), Number(lat), Number(height || 0))
- )
-
- // 计算最高高度和中心点经纬度
- let maxHeight = -Infinity
- let sumLon = 0,
- sumLat = 0
- for (const [lon, lat, height] of positionsData) {
- sumLon += Number(lon)
- sumLat += Number(lat)
- maxHeight = Math.max(maxHeight, Number(height || 0))
- }
- const centerLon = sumLon / positionsData.length
- const centerLat = sumLat / positionsData.length
- const boundingSphere = Cesium.BoundingSphere.fromPoints(positions)
- // 暂时飞向 BoundingSphere
- viewer.camera.flyToBoundingSphere(Cesium.BoundingSphere.fromPoints(positions), {
- duration: 0,
- offset: {
- heading: Cesium.Math.toRadians(0),
- pitch: Cesium.Math.toRadians(pitch),
- range: boundingSphere.radius * multiple,
- },
- complete: () => {
- // 飞行完成后检查相机高度是否小于最高点
- const cameraHeight = Cesium.Cartographic.fromCartesian(viewer.camera.position).height
- if (cameraHeight < maxHeight) {
- viewer.camera.flyTo({
- destination: Cesium.Cartesian3.fromDegrees(centerLon, centerLat, maxHeight + 100), // 加100米缓冲
- duration: 1.5,
- orientation: {
- heading: viewer.camera.heading,
- pitch: viewer.camera.pitch,
- roll: viewer.camera.roll,
- },
- })
- }
- },
- })
-}
-
// 获取视口地图中心点
export function getMapCenterPoint(viewer) {
const centerResult = viewer.camera.pickEllipsoid(
diff --git a/applications/drone-command/src/views/job/components/DeviceJobDetailsMap.vue b/applications/drone-command/src/views/job/components/DeviceJobDetailsMap.vue
index a6ee92d..c22b3c9 100644
--- a/applications/drone-command/src/views/job/components/DeviceJobDetailsMap.vue
+++ b/applications/drone-command/src/views/job/components/DeviceJobDetailsMap.vue
@@ -2,7 +2,7 @@
<div id="deviceJobDetailsMap" class="command-cesium"></div>
</template>
<script setup>
-import { flyVisual } from '@/utils/cesium/mapUtil'
+import { flyVisual } from '@ztzf/utils'
import _ from 'lodash'
import * as Cesium from 'cesium'
diff --git a/applications/drone-command/src/views/layerManagement/index.vue b/applications/drone-command/src/views/layerManagement/index.vue
index f1bcf7a..8ec2742 100644
--- a/applications/drone-command/src/views/layerManagement/index.vue
+++ b/applications/drone-command/src/views/layerManagement/index.vue
@@ -57,7 +57,7 @@
import { dataFolderApi } from '@/api/layer/index';
import folderFile from '@/views/layerManagement/components/folderFile.vue';
import { parseGeoDataToPositions } from '@/utils/geoParseUtil';
-import { flyVisual } from '@/utils/cesium/mapUtil';
+import { flyVisual } from '@ztzf/utils';
import rightEdit from '@/views/layerManagement/components/rightEdit.vue';
import leftList from '@/views/layerManagement/components/leftList.vue';
import { DrawPolygon } from '@/views/layerManagement/components/utils';
diff --git a/applications/drone-command/src/views/monitor/log/flightLog.vue b/applications/drone-command/src/views/monitor/log/flightLog.vue
index c9bc594..8bf95ad 100644
--- a/applications/drone-command/src/views/monitor/log/flightLog.vue
+++ b/applications/drone-command/src/views/monitor/log/flightLog.vue
@@ -123,7 +123,7 @@
import { ElMessage, ElMessageBox, ElLoading } from 'element-plus';
import {Delete, Refresh, Search} from '@element-plus/icons-vue';
import { ArrowLineMaterialProperty } from '@/utils/cesium/Material'
-import { flyVisual } from '@/utils/cesium/mapUtil'
+import { flyVisual } from '@ztzf/utils'
import rwqfdImg from '@/assets/images/signMachineNest/rwqfd.png'
import endPointImg from '@/assets/images/EndPointicon.png'
import { nextTick } from 'vue';
@@ -526,4 +526,4 @@
height: 500px;
width: 100%;
}
-</style>
\ No newline at end of file
+</style>
diff --git a/applications/drone-command/src/views/recordManage/historyTracks/TrajectoryDiaLog.vue b/applications/drone-command/src/views/recordManage/historyTracks/TrajectoryDiaLog.vue
index 1840cd8..4c18aaa 100644
--- a/applications/drone-command/src/views/recordManage/historyTracks/TrajectoryDiaLog.vue
+++ b/applications/drone-command/src/views/recordManage/historyTracks/TrajectoryDiaLog.vue
@@ -14,10 +14,10 @@
<div class="right-container">
<div class="header">
<span>{{ dialogTitle }}</span>
-
+
<el-icon class="close-btn" @click.stop="visible = false"><Close /></el-icon>
</div>
-
+
<div class="content">
<div class="detail-title">轨迹信息</div>
<el-row>
@@ -71,7 +71,7 @@
import { fwDroneFlightRecordDetailPageApi } from '@/views/recordManage/historyTracks/flyTrajectory'
import { PublicCesium } from '@/utils/cesium/publicCesium'
import * as Cesium from 'cesium'
-import { flyVisual } from '@/utils/cesium/mapUtil'
+import { flyVisual } from '@ztzf/utils'
import { ArrowLineMaterialProperty } from '@/utils/cesium/Material'
import droneIcon from '@/assets/images/dataCockpit/map/drone.png'
diff --git a/applications/drone-command/src/views/resource/components/spotDetails.vue b/applications/drone-command/src/views/resource/components/spotDetails.vue
index 2161bc4..c5bcbc4 100644
--- a/applications/drone-command/src/views/resource/components/spotDetails.vue
+++ b/applications/drone-command/src/views/resource/components/spotDetails.vue
@@ -61,24 +61,24 @@
<div class="table-overlay">
<div class="table-content">
<div class="tabname">图斑列表</div>
- <div class="tabBoxLoading"
+ <div class="tabBoxLoading"
v-loading="tableLoading"
- element-loading-text="加载中..."
+ element-loading-text="加载中..."
element-loading-background="rgba(0, 0, 0, 0.1)"
>
<el-table
v-if="tableData.length > 0"
-
+
ref="polygonTableEle"
highlight-current-row
:row-class-name="tableRowClassName"
:data="tableData"
@row-click="handleLocationPolygon"
-
+
>
<el-table-column type="index" align="center" :width="pxToRemNum(30)" label="序号">
<template #default="{ $index }">
- {{ ($index + 1).toString().padStart(2, '0') }}
+ {{ ($index + 1).toString().padStart(2, '0') }}
</template>
</el-table-column>
<el-table-column prop="dkbh" align="center" label="图斑名称" show-overflow-tooltip />
@@ -99,25 +99,25 @@
{{ isEditing && selectionIds === scope.row.id ? '取消编辑' : '编辑' }}
</span> -->
<template v-if="scope.row.is_exception == 2">
- <el-button
+ <el-button
v-if="!isEditing || selectionIds !== scope.row.id"
- icon="el-icon-edit"
- link
+ icon="el-icon-edit"
+ link
@click.stop="handleSelectionChange(scope.row)"
/>
- <el-button
+ <el-button
v-else
- icon="el-icon-circle-close"
- link
+ icon="el-icon-circle-close"
+ link
@click.stop="handleSelectionChange(scope.row)"
-
+
/>
</template>
</template>
</el-table-column>
</el-table>
</div>
-
+
</div>
</div>
<!--绘制按钮-->
@@ -126,7 +126,7 @@
ref="drawPolygonRef"
v-if="isEditing"
@upDateDrawState="handleUpDateDrawState"
-
+
/>
<!-- 完成/取消 -->
<div class="btnGroups" v-if="props.title === '图斑编辑'">
@@ -141,7 +141,7 @@
</template>
<script setup>
-import { flyVisual } from '@/utils/cesium/mapUtil'
+import { flyVisual } from '@ztzf/utils'
import { pxToRem, pxToRemNum } from '@/utils/rem'
import DrawPolygon from '@/views/resource/components/DrawPolygon.vue';
import { ElMessage, ElMessageBox } from 'element-plus';
@@ -270,7 +270,7 @@
const isInit = ref(true);
// 图斑管理表格
const getTableList = () => {
- tableLoading.value = true;
+ tableLoading.value = true;
const requestParams = {
patchesInfoId: props.detailid,
};
@@ -297,7 +297,7 @@
// 地图
const initMap = () => {
if (!document.getElementById('spotMap') || isMapReady.value) return;
-
+
publicCesiumInstance = new PublicCesium({
dom: 'spotMap',
flatMode: false,
@@ -305,17 +305,17 @@
layerMode: 4,
contour: false,
});
-
+
homeViewer.value = publicCesiumInstance.getViewer();
viewer = publicCesiumInstance.getViewer();
- viewInstance.value = publicCesiumInstance;
+ viewInstance.value = publicCesiumInstance;
viewer.scene.globe.depthTestAgainstTerrain = true;
viewInstance.value.switchContour(true);
// 确保 readyPromise 存在
if (viewer.readyPromise) {
viewer.readyPromise.then(() => {
- isMapReady.value = true;
+ isMapReady.value = true;
getTableList();
}).catch((error) => {
console.error('地图加载失败:', error);
@@ -335,18 +335,18 @@
// 仅弹框初始化时执行的定位逻辑
const initMapLocation = () => {
if (tbJwdList.length === 0 || !homeViewer.value) return;
-
+
// 计算所有图斑的包围球(用于初始化定位)
- const allPositions = tbJwdList.flatMap(item =>
+ const allPositions = tbJwdList.flatMap(item =>
Cesium.Cartesian3.fromDegreesArray(item.grouped)
);
const boundingSphere = Cesium.BoundingSphere.fromPoints(allPositions);
-
+
// 初始化定位(仅执行一次)
homeViewer.value.camera.flyToBoundingSphere(boundingSphere, {
duration: 0,
offset: new Cesium.HeadingPitchRange(
- Cesium.Math.toRadians(0),
+ Cesium.Math.toRadians(0),
Cesium.Math.toRadians(-90)
),
});
@@ -356,7 +356,7 @@
if (!isMapReady.value || !viewer) return;
viewer?.entities.removeAll();
tbJwdList = []; // 重置经纬度列表
-
+
tableData.value.forEach(item => {
const numbersWithCommas = item.dkfw.match(/\d+(\.\d+)?/g);
if (!numbersWithCommas) return;
@@ -365,11 +365,11 @@
tbJwdList.push({ ...item, grouped }); // 存储经纬度用于后续操作
// 绘制图斑(保留原有逻辑,仅移除定位相关代码)
- const fillColor = item.is_exception === 2
- ? Cesium.Color.RED.withAlpha(0.5)
+ const fillColor = item.is_exception === 2
+ ? Cesium.Color.RED.withAlpha(0.5)
: Cesium.Color.YELLOW.withAlpha(0.5);
- const outlineColor = item.is_exception === 2
- ? Cesium.Color.RED
+ const outlineColor = item.is_exception === 2
+ ? Cesium.Color.RED
: Cesium.Color.YELLOW;
homeViewer.value?.entities?.add({
@@ -492,13 +492,13 @@
for (let i = 0; i < numbersWithCommas.length; i += 2) {
const lon = Number(numbersWithCommas[i]);
const lat = Number(numbersWithCommas[i + 1]);
- positionsData.push([lon, lat, 10]);
+ positionsData.push([lon, lat, 10]);
}
flyVisual({
- positionsData: positionsData,
- viewer: homeViewer.value,
- multiple: 15,
-
+ positionsData: positionsData,
+ viewer: homeViewer.value,
+ multiple: 15,
+
});
}
}
@@ -522,7 +522,7 @@
// 定位到选中的图斑
handleLocationPolygon(row);
-
+
// 仅异常图斑可编辑
if (row.is_exception !== 2) {
ElMessage.warning('仅异常图斑支持编辑绘制');
@@ -645,21 +645,21 @@
watch(uploadPatchDialog, newVal => {
if (newVal) {
- isInit.value = true;
- isMapReady.value = false;
+ isInit.value = true;
+ isMapReady.value = false;
setTimeout(() => {
- initMap();
- getspotManagementTableApi();
+ initMap();
+ getspotManagementTableApi();
}, 0);
} else {
tableLoading.value = false;
- tableData.value = [];
+ tableData.value = [];
isEditing.value = false;
handleUpDateDrawState(false);
destroyMap();
- isInit.value = false;
+ isInit.value = false;
clearSelect();
- isMapReady.value = false;
+ isMapReady.value = false;
}
refreshonload();
});
@@ -682,7 +682,7 @@
}
:global(.spotDialog .el-dialog__body) {
padding: 2rem 2rem 0 !important;
-
+
}
.container {
display: flex;
@@ -854,7 +854,7 @@
// 选中行
.current-row td {
-
+
background-color: rgba(64, 158, 255,0.3) !important;
}
}
@@ -948,8 +948,8 @@
width: 100%;
}
.el-button {
- padding: 0;
- color: #fff;
+ padding: 0;
+ color: #fff;
width: 17px;
}
</style>
diff --git a/applications/task-work-order/src/components/PlaybackVideo/components/MapContainer.vue b/applications/task-work-order/src/components/PlaybackVideo/components/MapContainer.vue
index 98599ee..621394c 100644
--- a/applications/task-work-order/src/components/PlaybackVideo/components/MapContainer.vue
+++ b/applications/task-work-order/src/components/PlaybackVideo/components/MapContainer.vue
@@ -15,7 +15,7 @@
import PlanarRouteLineList from '@/components/PlanarRouteLineList/PlanarRouteLineList.vue'
-import { flyVisual } from '@/utils/cesium/mapUtil'
+import { flyVisual } from '@ztzf/utils'
import * as Cesium from 'cesium'
import { PublicCesium } from '@/utils/cesium/publicCesium'
diff --git a/applications/task-work-order/src/components/map-container/mapContainer.vue b/applications/task-work-order/src/components/map-container/mapContainer.vue
index bd5dc22..c9c6ae3 100644
--- a/applications/task-work-order/src/components/map-container/mapContainer.vue
+++ b/applications/task-work-order/src/components/map-container/mapContainer.vue
@@ -30,7 +30,7 @@
import { Cartesian3, Terrain, Viewer } from 'cesium';
import { PublicCesium } from '@/utils/cesium/publicCesium';
import ImageTrailMaterial from '@/utils/cesium/ImageTrailMaterial';
-import { flyVisual } from '@/utils/cesium/mapUtil';
+import { flyVisual } from '@ztzf/utils';
import * as turf from '@turf/turf';
import { nextTick, onBeforeUnmount, onMounted, onUnmounted } from 'vue';
diff --git a/applications/task-work-order/src/hooks/useRouteLine/useRouteLine.js b/applications/task-work-order/src/hooks/useRouteLine/useRouteLine.js
index 8dfae23..45dacd5 100644
--- a/applications/task-work-order/src/hooks/useRouteLine/useRouteLine.js
+++ b/applications/task-work-order/src/hooks/useRouteLine/useRouteLine.js
@@ -11,7 +11,7 @@
import endPointImg from '@/assets/images/EndPointicon.png'
import { ArrowLineMaterialProperty } from '@/utils/cesium/Material'
-import { flyVisual } from '@/utils/cesium/mapUtil'
+import { flyVisual } from '@ztzf/utils'
import { useStore } from 'vuex'
diff --git a/applications/task-work-order/src/utils/cesium/DrawPolygon.js b/applications/task-work-order/src/utils/cesium/DrawPolygon.js
index 6c37a35..598024f 100644
--- a/applications/task-work-order/src/utils/cesium/DrawPolygon.js
+++ b/applications/task-work-order/src/utils/cesium/DrawPolygon.js
@@ -2,7 +2,8 @@
import * as turf from '@turf/turf'
import { boxTransformScale } from '@/utils/turfFunc'
import { ElMessage } from 'element-plus'
-import { flyVisual, getPointPositionsHeight } from '@/utils/cesium/mapUtil'
+import { getPointPositionsHeight } from '@/utils/cesium/mapUtil'
+import { flyVisual } from '@ztzf/utils'
/**
* 多边形绘制与编辑工具类
diff --git a/applications/task-work-order/src/utils/cesium/mapUtil.js b/applications/task-work-order/src/utils/cesium/mapUtil.js
index 89bf787..c8e1d7c 100644
--- a/applications/task-work-order/src/utils/cesium/mapUtil.js
+++ b/applications/task-work-order/src/utils/cesium/mapUtil.js
@@ -449,66 +449,7 @@
}
}
-/**
- * 飞到中心点并且所有点在可视范围
- * @param positionsData 二维数组,每项为 [lon, lat] 或 三维数组 [lon, lat, height]
- * @param viewer Cesium.Viewer 实例
- * @param multiple 缩放倍数-默认为4
- * @param pitch 俯仰角-默认为-90
- */
-export function flyVisual({ positionsData, viewer, multiple = 4, pitch = -90 }) {
- if (!Array.isArray(positionsData) || positionsData.length === 0) return
- // 如果是一个点,加两个点方便后续生成外包围盒
- if (positionsData.length === 1) {
- const [lon, lat, height = 0] = positionsData[0]
- positionsData = [
- [lon + 0.001, lat + 0.001, height],
- [lon - 0.001, lat - 0.001, height],
- [lon, lat, height],
- ]
- }
- const positions = positionsData.map(([lon, lat, height = 0]) =>
- Cesium.Cartesian3.fromDegrees(Number(lon), Number(lat), Number(height || 0))
- )
-
- // 计算最高高度和中心点经纬度
- let maxHeight = -Infinity
- let sumLon = 0,
- sumLat = 0
- for (const [lon, lat, height] of positionsData) {
- sumLon += Number(lon)
- sumLat += Number(lat)
- maxHeight = Math.max(maxHeight, Number(height || 0))
- }
- const centerLon = sumLon / positionsData.length
- const centerLat = sumLat / positionsData.length
- const boundingSphere = Cesium.BoundingSphere.fromPoints(positions)
- // 暂时飞向 BoundingSphere
- viewer.camera.flyToBoundingSphere(Cesium.BoundingSphere.fromPoints(positions), {
- duration: 0,
- offset: {
- heading: Cesium.Math.toRadians(0),
- pitch: Cesium.Math.toRadians(pitch),
- range: boundingSphere.radius * multiple,
- },
- complete: () => {
- // 飞行完成后检查相机高度是否小于最高点
- const cameraHeight = Cesium.Cartographic.fromCartesian(viewer.camera.position).height
- if (cameraHeight < maxHeight) {
- viewer.camera.flyTo({
- destination: Cesium.Cartesian3.fromDegrees(centerLon, centerLat, maxHeight + 100), // 加100米缓冲
- duration: 1.5,
- orientation: {
- heading: viewer.camera.heading,
- pitch: viewer.camera.pitch,
- roll: viewer.camera.roll,
- },
- })
- }
- },
- })
-}
// 获取视口地图中心点
export function getMapCenterPoint(viewer) {
diff --git a/applications/task-work-order/src/views/orderView/orderManage/orderManage/FormDiaLog.vue b/applications/task-work-order/src/views/orderView/orderManage/orderManage/FormDiaLog.vue
index 3f65277..f554aab 100644
--- a/applications/task-work-order/src/views/orderView/orderManage/orderManage/FormDiaLog.vue
+++ b/applications/task-work-order/src/views/orderView/orderManage/orderManage/FormDiaLog.vue
@@ -201,7 +201,7 @@
<script setup>
import { computed, ref, onMounted, nextTick } from 'vue'
import { ElMessage } from 'element-plus'
-import { dateRangeFormat, fieldRules, geomAnalysis, getDictLabel } from '@ztzf/utils'
+import { dateRangeFormat, fieldRules, flyVisual, geomAnalysis, getDictLabel } from '@ztzf/utils'
import {
gdWorkOrderDetailApi,
gdWorkOrderFlowListApi,
@@ -403,7 +403,10 @@
material: Cesium.Color.RED,
},
})
- viewer.flyTo(mian, { duration: 0 })
+ flyVisual({
+ positionsData: pointList.map(i => [i.longitude, i.latitude, i.height || 0]),
+ viewer,
+ })
}
// 同步关联场景
diff --git a/applications/task-work-order/src/views/resource/components/spotDetails.vue b/applications/task-work-order/src/views/resource/components/spotDetails.vue
index 97bf8a4..63b2c0d 100644
--- a/applications/task-work-order/src/views/resource/components/spotDetails.vue
+++ b/applications/task-work-order/src/views/resource/components/spotDetails.vue
@@ -61,24 +61,24 @@
<div class="table-overlay">
<div class="table-content">
<div class="tabname">图斑列表</div>
- <div class="tabBoxLoading"
+ <div class="tabBoxLoading"
v-loading="tableLoading"
- element-loading-text="加载中..."
+ element-loading-text="加载中..."
element-loading-background="rgba(0, 0, 0, 0.1)"
>
<el-table
v-if="tableData.length > 0"
-
+
ref="polygonTableEle"
highlight-current-row
:row-class-name="tableRowClassName"
:data="tableData"
@row-click="handleLocationPolygon"
-
+
>
<el-table-column type="index" align="center" :width="pxToRemNum(30)" label="序号">
<template #default="{ $index }">
- {{ ($index + 1).toString().padStart(2, '0') }}
+ {{ ($index + 1).toString().padStart(2, '0') }}
</template>
</el-table-column>
<el-table-column prop="dkbh" align="center" label="图斑名称" show-overflow-tooltip />
@@ -99,25 +99,25 @@
{{ isEditing && selectionIds === scope.row.id ? '取消编辑' : '编辑' }}
</span> -->
<template v-if="scope.row.is_exception == 2">
- <el-button
+ <el-button
v-if="!isEditing || selectionIds !== scope.row.id"
- icon="el-icon-edit"
- link
+ icon="el-icon-edit"
+ link
@click.stop="handleSelectionChange(scope.row)"
/>
- <el-button
+ <el-button
v-else
- icon="el-icon-circle-close"
- link
+ icon="el-icon-circle-close"
+ link
@click.stop="handleSelectionChange(scope.row)"
-
+
/>
</template>
</template>
</el-table-column>
</el-table>
</div>
-
+
</div>
</div>
<!--绘制按钮-->
@@ -126,7 +126,7 @@
ref="drawPolygonRef"
v-if="isEditing"
@upDateDrawState="handleUpDateDrawState"
-
+
/>
<!-- 完成/取消 -->
<div class="btnGroups" v-if="props.title === '图斑编辑'">
@@ -141,7 +141,7 @@
</template>
<script setup>
-import { flyVisual } from '@/utils/cesium/mapUtil'
+import { flyVisual } from '@ztzf/utils'
import { pxToRem, pxToRemNum } from '@/utils/rem'
import DrawPolygon from '@/views/resource/components/DrawPolygon.vue';
import { ElMessage, ElMessageBox } from 'element-plus';
@@ -270,7 +270,7 @@
const isInit = ref(true);
// 图斑管理表格
const getTableList = () => {
- tableLoading.value = true;
+ tableLoading.value = true;
const requestParams = {
patchesInfoId: props.detailid,
};
@@ -297,7 +297,7 @@
// 地图
const initMap = () => {
if (!document.getElementById('spotMap') || isMapReady.value) return;
-
+
publicCesiumInstance = new PublicCesium({
dom: 'spotMap',
flatMode: false,
@@ -305,17 +305,17 @@
layerMode: 4,
contour: false,
});
-
+
homeViewer.value = publicCesiumInstance.getViewer();
viewer = publicCesiumInstance.getViewer();
- viewInstance.value = publicCesiumInstance;
+ viewInstance.value = publicCesiumInstance;
viewer.scene.globe.depthTestAgainstTerrain = true;
viewInstance.value.switchContour(true);
// 确保 readyPromise 存在
if (viewer.readyPromise) {
viewer.readyPromise.then(() => {
- isMapReady.value = true;
+ isMapReady.value = true;
getTableList();
}).catch((error) => {
console.error('地图加载失败:', error);
@@ -335,18 +335,18 @@
// 仅弹框初始化时执行的定位逻辑
const initMapLocation = () => {
if (tbJwdList.length === 0 || !homeViewer.value) return;
-
+
// 计算所有图斑的包围球(用于初始化定位)
- const allPositions = tbJwdList.flatMap(item =>
+ const allPositions = tbJwdList.flatMap(item =>
Cesium.Cartesian3.fromDegreesArray(item.grouped)
);
const boundingSphere = Cesium.BoundingSphere.fromPoints(allPositions);
-
+
// 初始化定位(仅执行一次)
homeViewer.value.camera.flyToBoundingSphere(boundingSphere, {
duration: 0,
offset: new Cesium.HeadingPitchRange(
- Cesium.Math.toRadians(0),
+ Cesium.Math.toRadians(0),
Cesium.Math.toRadians(-90)
),
});
@@ -356,7 +356,7 @@
if (!isMapReady.value || !viewer) return;
viewer?.entities.removeAll();
tbJwdList = []; // 重置经纬度列表
-
+
tableData.value.forEach(item => {
const numbersWithCommas = item.dkfw.match(/\d+(\.\d+)?/g);
if (!numbersWithCommas) return;
@@ -365,11 +365,11 @@
tbJwdList.push({ ...item, grouped }); // 存储经纬度用于后续操作
// 绘制图斑(保留原有逻辑,仅移除定位相关代码)
- const fillColor = item.is_exception === 2
- ? Cesium.Color.RED.withAlpha(0.5)
+ const fillColor = item.is_exception === 2
+ ? Cesium.Color.RED.withAlpha(0.5)
: Cesium.Color.YELLOW.withAlpha(0.5);
- const outlineColor = item.is_exception === 2
- ? Cesium.Color.RED
+ const outlineColor = item.is_exception === 2
+ ? Cesium.Color.RED
: Cesium.Color.YELLOW;
homeViewer.value?.entities?.add({
@@ -492,13 +492,13 @@
for (let i = 0; i < numbersWithCommas.length; i += 2) {
const lon = Number(numbersWithCommas[i]);
const lat = Number(numbersWithCommas[i + 1]);
- positionsData.push([lon, lat, 10]);
+ positionsData.push([lon, lat, 10]);
}
flyVisual({
- positionsData: positionsData,
- viewer: homeViewer.value,
- multiple: 15,
-
+ positionsData: positionsData,
+ viewer: homeViewer.value,
+ multiple: 15,
+
});
}
}
@@ -522,7 +522,7 @@
// 定位到选中的图斑
handleLocationPolygon(row);
-
+
// 仅异常图斑可编辑
if (row.is_exception !== 2) {
ElMessage.warning('仅异常图斑支持编辑绘制');
@@ -645,21 +645,21 @@
watch(uploadPatchDialog, newVal => {
if (newVal) {
- isInit.value = true;
- isMapReady.value = false;
+ isInit.value = true;
+ isMapReady.value = false;
setTimeout(() => {
- initMap();
- getspotManagementTableApi();
+ initMap();
+ getspotManagementTableApi();
}, 0);
} else {
tableLoading.value = false;
- tableData.value = [];
+ tableData.value = [];
isEditing.value = false;
handleUpDateDrawState(false);
destroyMap();
- isInit.value = false;
+ isInit.value = false;
clearSelect();
- isMapReady.value = false;
+ isMapReady.value = false;
}
refreshonload();
});
@@ -682,7 +682,7 @@
}
:global(.spotDialog .el-dialog__body) {
padding: 2rem 2rem 0 !important;
-
+
}
.container {
display: flex;
@@ -854,7 +854,7 @@
// 选中行
.current-row td {
-
+
background-color: rgba(64, 158, 255,0.3) !important;
}
}
@@ -948,8 +948,8 @@
width: 100%;
}
.el-button {
- padding: 0;
- color: #fff;
+ padding: 0;
+ color: #fff;
width: 17px;
}
</style>
diff --git a/packages/utils/map/index.js b/packages/utils/map/index.js
index fa9ec9a..b2bee02 100644
--- a/packages/utils/map/index.js
+++ b/packages/utils/map/index.js
@@ -1,16 +1,4 @@
-/*
- * @Author : yuan
- * @Date : 2025-12-26 11:01:31
- * @LastEditors : yuan
- * @LastEditTime : 2025-12-31 16:00:54
- * @FilePath : \packages\utils\map\index.js
- * @Description :
- * Copyright 2025 OBKoro1, All Rights Reserved.
- * 2025-12-26 11:01:31
- */
-
import * as Cesium from 'cesium'
-
// 获取正射影像4至点
export function getOrthoImageBoundaryPoints (data) {
@@ -29,4 +17,65 @@
east,
north
)
-}
\ No newline at end of file
+}
+
+/**
+ * 飞到中心点并且所有点在可视范围
+ * @param positionsData 二维数组,每项为 [lon, lat] 或 三维数组 [lon, lat, height]
+ * @param viewer Cesium.Viewer 实例
+ * @param multiple 缩放倍数-默认为4
+ * @param pitch 俯仰角-默认为-90
+ */
+export function flyVisual({ positionsData, viewer, multiple = 4, pitch = -90 }) {
+ if (!Array.isArray(positionsData) || positionsData.length === 0) return
+
+ // 如果是一个点,加两个点方便后续生成外包围盒
+ if (positionsData.length === 1) {
+ const [lon, lat, height = 0] = positionsData[0]
+ positionsData = [
+ [lon + 0.001, lat + 0.001, height],
+ [lon - 0.001, lat - 0.001, height],
+ [lon, lat, height],
+ ]
+ }
+ const positions = positionsData.map(([lon, lat, height = 0]) =>
+ Cesium.Cartesian3.fromDegrees(Number(lon), Number(lat), Number(height || 0))
+ )
+
+ // 计算最高高度和中心点经纬度
+ let maxHeight = -Infinity
+ let sumLon = 0,
+ sumLat = 0
+ for (const [lon, lat, height] of positionsData) {
+ sumLon += Number(lon)
+ sumLat += Number(lat)
+ maxHeight = Math.max(maxHeight, Number(height || 0))
+ }
+ const centerLon = sumLon / positionsData.length
+ const centerLat = sumLat / positionsData.length
+ const boundingSphere = Cesium.BoundingSphere.fromPoints(positions)
+ // 暂时飞向 BoundingSphere
+ viewer.camera.flyToBoundingSphere(Cesium.BoundingSphere.fromPoints(positions), {
+ duration: 0,
+ offset: {
+ heading: Cesium.Math.toRadians(0),
+ pitch: Cesium.Math.toRadians(pitch),
+ range: boundingSphere.radius * multiple,
+ },
+ complete: () => {
+ // 飞行完成后检查相机高度是否小于最高点
+ const cameraHeight = Cesium.Cartographic.fromCartesian(viewer.camera.position).height
+ if (cameraHeight < maxHeight) {
+ viewer.camera.flyTo({
+ destination: Cesium.Cartesian3.fromDegrees(centerLon, centerLat, maxHeight + 100), // 加100米缓冲
+ duration: 1.5,
+ orientation: {
+ heading: viewer.camera.heading,
+ pitch: viewer.camera.pitch,
+ roll: viewer.camera.roll,
+ },
+ })
+ }
+ },
+ })
+}
--
Gitblit v1.9.3