完成实时飞行轨迹

This commit is contained in:
2025-12-19 16:15:15 +08:00
parent baf2af1fc3
commit a147563b70
4 changed files with 83 additions and 12 deletions

View File

@@ -11,7 +11,7 @@
"dependencies": { "dependencies": {
"@amap/amap-jsapi-loader": "^1.0.1", "@amap/amap-jsapi-loader": "^1.0.1",
"@element-plus/icons-vue": "^2.3.2", "@element-plus/icons-vue": "^2.3.2",
"DroneCtrl": "1.0.1", "DroneCtrl": "1.0.3",
"axios": "^1.13.2", "axios": "^1.13.2",
"element-plus": "^2.12.0", "element-plus": "^2.12.0",
"gcoord": "^1.0.7", "gcoord": "^1.0.7",

12
pnpm-lock.yaml generated
View File

@@ -18,8 +18,8 @@ importers:
specifier: ^2.3.2 specifier: ^2.3.2
version: 2.3.2(vue@3.5.25) version: 2.3.2(vue@3.5.25)
DroneCtrl: DroneCtrl:
specifier: 1.0.1 specifier: 1.0.3
version: 1.0.1 version: 1.0.3
axios: axios:
specifier: ^1.13.2 specifier: ^1.13.2
version: 1.13.2 version: 1.13.2
@@ -207,7 +207,7 @@ packages:
resolution: {integrity: sha512-iHmwV3QcVGGvSC1BG5bZ4z6iwa1SOpAPWmnjOErd4Ske+lZua5K9TtAVdx0gMBClJ28DViCbSmZitjWZsWO3LA==} resolution: {integrity: sha512-iHmwV3QcVGGvSC1BG5bZ4z6iwa1SOpAPWmnjOErd4Ske+lZua5K9TtAVdx0gMBClJ28DViCbSmZitjWZsWO3LA==}
engines: {node: ^20.19.0 || >=22.12.0} engines: {node: ^20.19.0 || >=22.12.0}
peerDependencies: peerDependencies:
vite: npm:rolldown-vite@7.2.5 vite: ^5.0.0 || ^6.0.0 || ^7.0.0
vue: ^3.2.25 vue: ^3.2.25
'@vue/compiler-core@3.5.25': '@vue/compiler-core@3.5.25':
@@ -248,8 +248,8 @@ packages:
'@vueuse/shared@9.13.0': '@vueuse/shared@9.13.0':
resolution: {integrity: sha512-UrnhU+Cnufu4S6JLCPZnkWh0WwZGUp72ktOF2DFptMlOs3TOdVv8xJN53zhHGARmVOsz5KqOls09+J1NR6sBKw==} resolution: {integrity: sha512-UrnhU+Cnufu4S6JLCPZnkWh0WwZGUp72ktOF2DFptMlOs3TOdVv8xJN53zhHGARmVOsz5KqOls09+J1NR6sBKw==}
DroneCtrl@1.0.1: DroneCtrl@1.0.3:
resolution: {integrity: sha512-3ibzb0sXZGXAkbSTg4Zb8heTx6ASBkWaI2yAO8V+4/Y2ygULruPCzb8o3c89wWlnfQQ/AALWlNmkpVV/ezBujQ==} resolution: {integrity: sha512-8SC/nx1byB/dhqSb0nNjamzQTQXi15JKkFRkMUnRErBcKBeNypz0Rjn6k7kGMuC/d0RNYODAgj8xc4NQEKokfw==}
async-validator@4.2.5: async-validator@4.2.5:
resolution: {integrity: sha512-7HhHjtERjqlNbZtqNqy2rckN/SpOOlmDliet+lP7k+eKZEjPk3DgyeU9lIXLdeLz0uBbbVp+9Qdow9wJWgwwfg==} resolution: {integrity: sha512-7HhHjtERjqlNbZtqNqy2rckN/SpOOlmDliet+lP7k+eKZEjPk3DgyeU9lIXLdeLz0uBbbVp+9Qdow9wJWgwwfg==}
@@ -773,7 +773,7 @@ snapshots:
- '@vue/composition-api' - '@vue/composition-api'
- vue - vue
DroneCtrl@1.0.1: {} DroneCtrl@1.0.3: {}
async-validator@4.2.5: {} async-validator@4.2.5: {}

View File

@@ -319,6 +319,8 @@ let mouseTool = null
const mapType = ref('satellite') // 'normal' | 'satellite' const mapType = ref('satellite') // 'normal' | 'satellite'
const dronePath = ref([]) // 无人机轨迹点集合 const dronePath = ref([]) // 无人机轨迹点集合
let droneTrackLine = null let droneTrackLine = null
const drone2Path = ref([]) // 无人机2轨迹点集合
let drone2TrackLine = null
const MAX_TRACK_POINTS = 2000 const MAX_TRACK_POINTS = 2000
// 围栏相关状态 // 围栏相关状态
@@ -543,7 +545,7 @@ const toggleWebSocket = () => {
gcoord.GCJ02, // 目标坐标系 gcoord.GCJ02, // 目标坐标系
); );
console.log(point, point2); console.log(point, point2);
// updateDroneMarker(point[0], point[1], drone1.heading); updateDroneMarker(point[0], point[1], point2[0], point2[1], drone1.heading);
// updateDrone2Marker(point2[0], point2[1], drone2.heading); // updateDrone2Marker(point2[0], point2[1], drone2.heading);
}; };
} }
@@ -572,7 +574,7 @@ const handleDroneData = (data) => {
} }
// 更新无人机marker // 更新无人机marker
const updateDroneMarker = (lng, lat, heading = 0) => { const updateDroneMarker = (lng, lat, lng2, lat2, heading = 0) => {
if (!map || !AMap) return if (!map || !AMap) return
if (!droneMarker.value) { if (!droneMarker.value) {
@@ -589,25 +591,40 @@ const updateDroneMarker = (lng, lat, heading = 0) => {
position: [lng, lat], position: [lng, lat],
icon: icon, icon: icon,
zIndex: 100, zIndex: 100,
title: '无人机', title: '侦查机',
offset: new AMap.Pixel(-20, -20), offset: new AMap.Pixel(-20, -20),
// 优化:禁用动画,减少性能消耗 // 优化:禁用动画,减少性能消耗
animation: 'AMAP_ANIMATION_NONE' animation: 'AMAP_ANIMATION_NONE'
}) })
map.add(droneMarker.value) map.add(droneMarker.value)
drone2Marker.value = new AMap.Marker({
position: [lng, lat],
icon: icon,
zIndex: 100,
title: '投弹机',
offset: new AMap.Pixel(-20, -20),
// 优化:禁用动画,减少性能消耗
animation: 'AMAP_ANIMATION_NONE'
})
map.add(drone2Marker.value)
} else { } else {
// 更新位置 // 更新位置
droneMarker.value.setPosition([lng, lat]) droneMarker.value.setPosition([lng, lat])
drone2Marker.value.setPosition([lng2, lat2])
// 更新旋转角度如果有heading数据 // 更新旋转角度如果有heading数据
if (heading !== undefined) { if (heading !== undefined) {
droneMarker.value.setAngle(heading) droneMarker.value.setAngle(heading)
drone2Marker.value.setAngle(heading)
} }
} }
// 更新飞行轨迹 // 更新飞行轨迹
updateDroneTrack(lng, lat) updateDroneTrack(lng, lat)
updateDrone2Track(lng2, lat2)
// 将地图中心移动到无人机位置(可选,可以注释掉) // 将地图中心移动到无人机位置(可选,可以注释掉)
map.setCenter([lng, lat]) map.setCenter([lng, lat])
@@ -638,6 +655,30 @@ const initDroneTrack = () => {
}) })
} }
const initDrone2Track = () => {
if (!map || !AMap) return
// 如果已有轨迹线,先移除
if (drone2TrackLine) {
map.remove(drone2TrackLine)
}
drone2TrackLine = new AMap.Polyline({
map,
path: [],
showDir: true,
isOutline: true,
outlineColor: 'rgba(0,0,0,0.3)',
borderWeight: 2,
strokeColor: '#00e0ff',
strokeOpacity: 0.8,
strokeWeight: 4,
lineJoin: 'round',
lineCap: 'round',
zIndex: 90
})
}
// 更新无人机轨迹 // 更新无人机轨迹
const updateDroneTrack = (lng, lat) => { const updateDroneTrack = (lng, lat) => {
if (!map || !AMap) return if (!map || !AMap) return
@@ -656,6 +697,24 @@ const updateDroneTrack = (lng, lat) => {
} }
} }
const updateDrone2Track = (lng, lat) => {
if (!map || !AMap) return
if (!drone2TrackLine) {
initDrone2Track()
}
drone2Path.value.push([lng, lat])
if (drone2Path.value.length > MAX_TRACK_POINTS) {
drone2Path.value.shift()
}
if (drone2TrackLine) {
drone2TrackLine.setPath(drone2Path.value)
}
}
// 清空无人机轨迹 // 清空无人机轨迹
const clearDroneTrack = () => { const clearDroneTrack = () => {
dronePath.value = [] dronePath.value = []
@@ -664,6 +723,13 @@ const clearDroneTrack = () => {
} }
} }
const clearDrone2Track = () => {
drone2Path.value = []
if (drone2TrackLine) {
drone2TrackLine.setPath([])
}
}
// 检测点是否在多边形内(射线法) // 检测点是否在多边形内(射线法)
const isPointInPolygon = (point, polygon) => { const isPointInPolygon = (point, polygon) => {
const [x, y] = point const [x, y] = point
@@ -1383,6 +1449,11 @@ onUnmounted(() => {
wsClient = null wsClient = null
} }
if (conn) {
conn.close()
conn = null
}
// 清理地图 // 清理地图
if (droneMarker.value) { if (droneMarker.value) {
map?.remove(droneMarker.value) map?.remove(droneMarker.value)

View File

@@ -97,9 +97,9 @@ function upload(url, params) {
}); });
} }
// export let host = `${window.location.protocol}//${window.location.host}`; export let host = `${window.location.protocol}//${window.location.host}`;
// export let host = "http://192.168.43.98:5678"; // export let host = "http://192.168.43.98:5678";
export let host = "http://192.168.3.81:5678"; // export let host = "http://192.168.3.81:5678";
// export let host = "http://127.0.0.1:5678"; // export let host = "http://127.0.0.1:5678";
export const getConfig = () => { export const getConfig = () => {