修改障碍物保存逻辑

main
suixy 1 month ago
parent f28e2bcc7a
commit 42f3b1d86d

@ -13,6 +13,11 @@
-moz-osx-font-smoothing: grayscale;
}
* {
margin: 0;
padding: 0;
}
a {
font-weight: 500;
color: #646cff;

@ -0,0 +1,90 @@
const DEG_TO_RAD = Math.PI / 180;
// 偏差值
let deviationValue = {}
function lonLatToXY(lon, lat, lat0) {
const R = 111320; // 每度约等于 111.32 km
const cosLat = Math.cos(lat0 * DEG_TO_RAD);
return {x: lon * R * cosLat, y: lat * R};
}
function calcRectangleFromPoints(points) {
if (!points || points.length !== 4) {
console.log("必须传入4个点");
return
}
const p1raw = points.find(p => p.name === "点位1") || points[0];
const p2raw = points.find(p => p.name === "点位2") || points[1];
const p3raw = points.find(p => p.name === "点位3") || points[2];
const p4raw = points.find(p => p.name === "点位4") || points[3];
const lat0 = (points.reduce((s, p) => s + p.lat, 0) / points.length);
const p1 = lonLatToXY(p1raw.lon, p1raw.lat, lat0);
const p2 = lonLatToXY(p2raw.lon, p2raw.lat, lat0);
const p3 = lonLatToXY(p3raw.lon, p3raw.lat, lat0);
const p4 = lonLatToXY(p4raw.lon, p4raw.lat, lat0);
const dist = (a, b) => Math.hypot(a.x - b.x, a.y - b.y);
const top = dist(p2, p3);
const bottom = dist(p4, p1);
const left = dist(p4, p3);
const right = dist(p1, p2);
const trapezoid = Math.abs(top - bottom) / Math.max(top, bottom) > 0.05;
const width = trapezoid ? (top + bottom) / 2 : bottom;
const height = trapezoid ? (left + right) / 2 : right;
const bottomAngleRad = Math.atan2(p1.y - p4.y, p1.x - p4.x);
const angleDeg = bottomAngleRad * 180 / Math.PI;
return {
width: Number(width.toFixed(2)), height: Number(height.toFixed(2)), angle: Number(angleDeg.toFixed(6))
};
}
function getLocalPositionRelativeToP4(point, rectPoints, rectInfo) {
if (!rectInfo || typeof rectInfo.angle !== 'number') {
console.log("rectInfo.angle 必须是由 calcRectangleFromPoints 得到的角度");
return
}
const lat0 = rectPoints.reduce((a, b) => a + b.lat, 0) / rectPoints.length;
const p4raw = rectPoints.find(p => p.name === "点位4") || rectPoints[3];
const p4 = lonLatToXY(p4raw.lon, p4raw.lat, lat0);
const p = lonLatToXY(point.lon, point.lat, lat0);
const dx = p.x - p4.x;
const dy = p.y - p4.y;
const rad = -rectInfo.angle * DEG_TO_RAD;
const x_local = dx * Math.cos(rad) - dy * Math.sin(rad);
const y_local = dx * Math.sin(rad) + dy * Math.cos(rad);
const rotate_local = ((point.rotate ?? 0) + rectInfo.angle + 360) % 360;
return {
x: Number(x_local.toFixed(2)), y: Number(y_local.toFixed(2)), rotate: Number(rotate_local.toFixed(2))
};
}
// 设置偏差值
const getDeviationValue = (e, areaPoints) => {
if (!e) return
const rectInfo = calcRectangleFromPoints(areaPoints);
const local = getLocalPositionRelativeToP4(e, areaPoints, rectInfo);
deviationValue = local;
}
// 修正偏差
const correctDeviation = (e) => {
let numH = deviationValue.y || 0
let numW = deviationValue.x || 0
let Ratio = e?.y / numH
return {
...e, x: e?.x - numW * Ratio
}
}
export {
calcRectangleFromPoints, getLocalPositionRelativeToP4, getDeviationValue, correctDeviation
}

@ -12,6 +12,14 @@
<span>主界面</span>
</div>
<div
class="item"
:class="{ click: itemsId === 5 }"
@click="setItemsId(5)"
>
<span>固定物</span>
</div>
<div
class="item"
:class="{ click: itemsId === 2 }"
@ -195,7 +203,7 @@
<el-table
ref="table1Ref"
highlight-current-row
:data="tableData1Computed"
:data="table1Data"
style="width: 100%"
@row-click="table1Current"
>
@ -588,6 +596,27 @@
</el-table>
</el-card>
</div>
<div v-if="itemsId === 5" class="tabsItem">
<!-- 数据表格 -->
<el-card shadow="always" style="margin-top: 12px">
<el-table :data="tableData2" style="width: 100%">
<el-table-column label="序号" type="index" width="60"/>
<el-table-column prop="coordinate" label="目标坐标" width="120"/>
<el-table-column label="告警等级" width="160">
<template #default="scope">
<el-rate :model-value="scope.row.rate" disabled/>
</template>
</el-table-column>
<el-table-column label="处理状态" show-overflow-tooltip>
<template #default="scope">
<span v-if="scope.row.type === 1"></span>
<span v-else-if="scope.row.type === 2">不处理</span>
<span v-else-if="scope.row.type === 3">未发现</span>
</template>
</el-table-column>
</el-table>
</el-card>
</div>
</div>
<el-button style="position: fixed;top: 10px;right: 10px" type="primary" @click="toAdmin"></el-button>
@ -696,7 +725,7 @@
/>
</div>
</template>
<script setup lang="jsx">
<script setup>
import Ruler from "@/components/ruler.vue";
import {onMounted, ref, watch,computed } from "vue";
import {
@ -724,98 +753,101 @@ import {
} from "@/api/api";
import {useRouter} from "vue-router";
import {ElMessage} from "element-plus";
import {
calcRectangleFromPoints,
getLocalPositionRelativeToP4,
getDeviationValue,
correctDeviation
} from '@/utils/tool'
const router = useRouter();
const rulerRef = ref()
const getSocket = () => {
// const socket = new WebSocket("ws://192.168.1.123:7789/ws");
const socket = new WebSocket("ws://192.168.1.123:7789/ws");
// 2.
socket.addEventListener("open", () => {
console.log("✅ WebSocket 连接成功");
});
// 3.
socket.addEventListener("message", (event) => {
processData(JSON.parse(event.data))
});
// 4.
socket.addEventListener("close", () => {
console.log("❌ WebSocket 已关闭");
});
// 5.
socket.addEventListener("error", (error) => {
console.error("⚠️ WebSocket 出错:", error);
});
const date1 = ref([])
const form1 = ref({})
const form2 = ref({})
const form3 = ref({})
const form4 = ref({})
const form5 = ref({})
const form6 = ref({})
const options1 = ref([])
const options2 = ref([])
const selectUpdate = (val) => {
form1.value.region = val
getArea({airId: val}).then(e => {
options2.value = e.data
})
}
const select2Update = (val) => {
form6.value.region = val
getArea({airId: val}).then(e => {
options2.value = e.data
})
}
const select3Update = (val) => {
form6.value.region1 = val
}
const processData = (data) => {
if (data.FodName === '雷达信息') {
radarWorkState.value = data.radar_work_state
}
if (data.FodName === '图像数据') {
}
if (data.FodName === 'fod信息') {
console.log('障碍物信息', data)
setDot(data)
}
if (data.ty === 3) {
}
if (data.FodName === '车辆信息') {
currentPosition.value = {
lon: data.Longitude,
lat: data.Latitude,
}
const rectInfo = calcRectangleFromPoints(areaPoints.value);
const point = {
lon: data.Longitude,
lat: data.Latitude,
rotate: data.HeadingAngle
};
const local = correctDeviation(getLocalPositionRelativeToP4(point, areaPoints.value, rectInfo))
boxPos.value = local
}
};
//
const uploadRef = ref(null)
const uploadFiles = async (e) => {
const res = await UpdateImage({files: [e.file]})
}
//
const handlePictureCardPreview = (file) => {
dialogImageUrl.value = file.url
imgDialog.value = true
}
//
const handleDownload = (file) => {
console.log(file)
}
//
const handleRemove = (file) => {
console.log(file)
dialog1Form.value.fileList = dialog1Form.value.fileList.filter(e => e.url !== file.url)
}
//
const cameraInput = ref(null)
const openCamera = () => {
cameraInput.value?.click()
}
const handleCameraChange = (e) => {
const file = e.target.files[0]
if (!file) return
const url = URL.createObjectURL(file)
UpdateImage({files: [file]})
dialog1Form.fileList.value.push({
name: file.name,
url,
raw: file
})
// input
e.target.value = ''
}
//
const onSubmit = (e) => {
console.log(e)
}
// id
const itemsId = ref(1)
// id
const setItemsId = (e) => {
itemsId.value = e
}
//
const radarWorkState = ref(0)
//
const boxPos = ref({x: 100, y: 150, rotate: 0})
//
const areaData = ref({
width: 500,
height: 1000,
angle: 0
})
//
const dots = ref([])
//
const dotIndex = ref(-1)
//
const toAdmin = () => {
router.push('/serve')
}
//
const StartWorkBtn = () => {
StartWork()
tableData1.value = []
}
//
const StopWorkBtn = () => {
StopWork()
}
//
const RestartWorkBtn = () => {
RestartWork()
}
//
const ShutDownWorkBtn = () => {
ShutDownWork()
}
// &
const parasSignalproForm = ref({
imaging: {},
@ -864,7 +896,6 @@ const getOption = () => {
}
})
}
// &
const saveParasSignalproForm = () => {
setParasSignalpro(parasSignalproForm.value).then(e => {
@ -900,35 +931,105 @@ const updateRunwayNum = (e) => {
})
parasPosForm.value.runwayedges = JSON.parse(JSON.stringify(arr))
}
//
const router = useRouter();
const rulerRef = ref()
// id
const itemsId = ref(1)
// id
const setItemsId = (e) => {
itemsId.value = e
}
//
const areaData = ref({
width: 500,
height: 1000,
angle: 0
})
//
const radarWorkState = ref(0)
//
const boxPos = ref({x: 100, y: 150, rotate: 0})
//
const currentPosition = ref({})
//
const table1Current = (e,) => {
if (dotIndex.value === e.index) {
dotIndex.value = -1
} else {
dotIndex.value = e.index
}
}
// ws
const getSocket = () => {
//
const StartWorkBtn = () => {
StartWork()
// rulerRef.value.setDot([], true)
setDot([], true)
tableData1.value = []
const socket = new WebSocket("ws://192.168.1.123:7789/ws");
socket.addEventListener("open", () => {
console.log("✅ WebSocket 连接成功");
});
socket.addEventListener("message", (event) => {
processData(JSON.parse(event.data))
});
socket.addEventListener("close", () => {
console.log("❌ WebSocket 已关闭");
});
socket.addEventListener("error", (error) => {
console.error("⚠️ WebSocket 出错:", error);
});
}
//
const StopWorkBtn = () => {
StopWork()
}
//
const RestartWorkBtn = () => {
RestartWork()
}
//
const ShutDownWorkBtn = () => {
ShutDownWork()
// ws
const processData = (data) => {
if (data.FodName === '雷达信息') {
radarWorkState.value = data.radar_work_state
}
if (data.FodName === '图像数据') {
}
if (data.FodName === 'fod信息') {
console.log('障碍物信息', data)
setTable1Data(data)
}
if (data.ty === 3) {
}
if (data.FodName === '车辆信息') {
currentPosition.value = {
lon: data.Longitude,
lat: data.Latitude,
}
const rectInfo = calcRectangleFromPoints(areaPoints.value);
const point = {
lon: data.Longitude,
lat: data.Latitude,
rotate: data.HeadingAngle
};
const local = correctDeviation(getLocalPositionRelativeToP4(point, areaPoints.value, rectInfo))
boxPos.value = local
}
};
// 1
const setTable1Data = (e) => {
let fodInfo = e.DarDatas.filter(v => v.Lon !== 0 && v.Lat !== 0)
tableData1.value = [...tableData1.value, ...fodInfo.map((v, k) => {
return {...v, index: tableData1.value.length + k}
})]
}
const form1 = ref({})
const form2 = ref({})
const form3 = ref({})
const form4 = ref({})
const form5 = ref({})
const form6 = ref({})
//
const tableData1 = ref([])
const table1Data = computed(() => {
return tableData1.value.slice((currentPage1.value - 1) * pageSize1.value, currentPage1.value * pageSize1.value)
});
//
const currentPage1 = ref(1)
//
const pageSize1 = ref(10)
//
//
const tableData2 = ref([])
//
@ -936,6 +1037,11 @@ const currentPage2 = ref(1)
//
const pageSize2 = ref(10)
const total2 = ref(0)
//
const dots = ref([])
//
const dotIndex = ref(-1)
//
const shildDialog = ref(false)
const shildForm = ref({})
//
@ -990,48 +1096,6 @@ const getShildTableList = () => {
})
}
//
const tableData1 = ref([])
const tableData1Computed = computed(() => {
return tableData1.value.slice((currentPage1.value - 1) * pageSize1.value, currentPage1.value * pageSize1.value)
});
//
const uploadRef = ref(null)
const uploadFiles = async (e) => {
const res = await UpdateImage({files: [e.file]})
}
//
const handlePictureCardPreview = (file) => {
dialogImageUrl.value = file.url
imgDialog.value = true
}
//
const handleDownload = (file) => {
console.log(file)
}
//
const handleRemove = (file) => {
console.log(file)
dialog1Form.value.fileList = dialog1Form.value.fileList.filter(e => e.url !== file.url)
}
//
const cameraInput = ref(null)
const openCamera = () => {
cameraInput.value?.click()
}
const handleCameraChange = (e) => {
const file = e.target.files[0]
if (!file) return
const url = URL.createObjectURL(file)
UpdateImage({files: [file]})
dialog1Form.fileList.value.push({
name: file.name,
url,
raw: file
})
// input
e.target.value = ''
}
//
const dialog1 = ref(false)
const dialog1Form = ref({})
@ -1045,11 +1109,6 @@ const delPoint = (e) => {
dotIndexF((currentPage1.value - 1) * pageSize1.value + e.$index)
table1DataIndexF()
}
//
const currentPage1 = ref(1)
//
const pageSize1 = ref(10)
//
const openHandleObstacleDialog = (e) => {
dialog1.value = true
@ -1125,153 +1184,6 @@ const batchShild = () => {
table1DataIndexF()
}
const date1 = ref([])
const currentPosition = ref({})
const DEG_TO_RAD = Math.PI / 180;
function lonLatToXY(lon, lat, lat0) {
const R = 111320; // 111.32 km
const cosLat = Math.cos(lat0 * DEG_TO_RAD);
return {x: lon * R * cosLat, y: lat * R};
}
function calcRectangleFromPoints(points) {
if (!points || points.length !== 4) {
console.log("必须传入4个点");
return
}
const p1raw = points.find(p => p.name === "点位1") || points[0];
const p2raw = points.find(p => p.name === "点位2") || points[1];
const p3raw = points.find(p => p.name === "点位3") || points[2];
const p4raw = points.find(p => p.name === "点位4") || points[3];
const lat0 = (points.reduce((s, p) => s + p.lat, 0) / points.length);
const p1 = lonLatToXY(p1raw.lon, p1raw.lat, lat0);
const p2 = lonLatToXY(p2raw.lon, p2raw.lat, lat0);
const p3 = lonLatToXY(p3raw.lon, p3raw.lat, lat0);
const p4 = lonLatToXY(p4raw.lon, p4raw.lat, lat0);
const dist = (a, b) => Math.hypot(a.x - b.x, a.y - b.y);
const top = dist(p2, p3);
const bottom = dist(p4, p1);
const left = dist(p4, p3);
const right = dist(p1, p2);
const trapezoid = Math.abs(top - bottom) / Math.max(top, bottom) > 0.05;
const width = trapezoid ? (top + bottom) / 2 : bottom;
const height = trapezoid ? (left + right) / 2 : right;
const bottomAngleRad = Math.atan2(p1.y - p4.y, p1.x - p4.x);
const angleDeg = bottomAngleRad * 180 / Math.PI;
return {
width: Number(width.toFixed(2)),
height: Number(height.toFixed(2)),
angle: Number(angleDeg.toFixed(6))
};
}
function getLocalPositionRelativeToP4(point, rectPoints, rectInfo) {
if (!rectInfo || typeof rectInfo.angle !== 'number') {
console.log("rectInfo.angle 必须是由 calcRectangleFromPoints 得到的角度");
return
}
const lat0 = rectPoints.reduce((a, b) => a + b.lat, 0) / rectPoints.length;
const p4raw = rectPoints.find(p => p.name === "点位4") || rectPoints[3];
const p4 = lonLatToXY(p4raw.lon, p4raw.lat, lat0);
const p = lonLatToXY(point.lon, point.lat, lat0);
const dx = p.x - p4.x;
const dy = p.y - p4.y;
const rad = -rectInfo.angle * DEG_TO_RAD;
const x_local = dx * Math.cos(rad) - dy * Math.sin(rad);
const y_local = dx * Math.sin(rad) + dy * Math.cos(rad);
const rotate_local = ((point.rotate ?? 0) + rectInfo.angle + 360) % 360;
return {
x: Number(x_local.toFixed(2)),
y: Number(y_local.toFixed(2)),
rotate: Number(rotate_local.toFixed(2))
};
}
//
const deviationValue = ref({})
//
const getDeviationValue = (e) => {
if (!e) return
const rectInfo = calcRectangleFromPoints(areaPoints.value);
const local = getLocalPositionRelativeToP4(e, areaPoints.value, rectInfo);
deviationValue.value = local;
}
//
const correctDeviation = (e) => {
let numH = deviationValue.value.y || 0
let numW = deviationValue.value.x || 0
let Ratio = e?.y / numH
return {
...e,
x: e?.x - numW * Ratio
}
}
const getPoint = (k) => {
regionLabeling.value[k].lon = currentPosition.value.lon || 0
regionLabeling.value[k].lat = currentPosition.value.lat || 0
}
const setDot = (e, re) => {
let fodInfo = e.DarDatas.filter(v => v.Lon !== 0 && v.Lat !== 0)
tableData1.value = [...tableData1.value, ...fodInfo.map((v, k) => {
return {...v, index: tableData1.value.length + k}
})]
}
const dotIndexF = (index) => {
if (dotIndex.value === index) {
dotIndex.value = -1
} else if (dotIndex.value > index) {
dotIndex.value -= 1
} else if (dotIndex.value > index) {
} else {
}
}
const table1Current = (e, ) => {
if (dotIndex.value ===e.index) {
dotIndex.value = -1
} else {
dotIndex.value = e.index
}
}
const options1 = ref([])
const options2 = ref([])
const getTableData = async () => {
await getAllAirPort().then(e => {
options1.value = e.data
})
}
const selectUpdate = (val) => {
form1.value.region = val
getArea({airId: val}).then(e => {
options2.value = e.data
})
}
const select2Update = (val) => {
form6.value.region = val
getArea({airId: val}).then(e => {
options2.value = e.data
})
}
const select3Update = (val) => {
form6.value.region1 = val
}
//
const getArea2 = () => {
GetAllCData({areaId: form6.value.region1}).then((res) => {
@ -1282,6 +1194,11 @@ const getArea2 = () => {
const regionLabeling = ref([])
//
const areaPoints = ref([])
//
const getPoint = (k) => {
regionLabeling.value[k].lon = currentPosition.value.lon || 0
regionLabeling.value[k].lat = currentPosition.value.lat || 0
}
//
const saveAreaPoint = () => {
let arr = []
@ -1293,20 +1210,54 @@ const saveAreaPoint = () => {
ElMessage.success('保存成功')
let data = calcRectangleFromPoints(areaPoints.value)
areaData.value = data
getDeviationValue(areaPoints.value.find(e => e.name === '点位3'))
getDeviationValue(areaPoints.value.find(e => e.name === '点位3'), areaPoints.value)
}).catch((err) => {
ElMessage.error(err)
})
}
const dotIndexF = (index) => {
if (dotIndex.value === index) {
dotIndex.value = -1
} else if (dotIndex.value > index) {
dotIndex.value -= 1
} else if (dotIndex.value > index) {
} else {
}
}
const readTableData = () => {
const storedStr = localStorage.getItem('tableData1');
if (!storedStr) {
return;
}
const storedData = JSON.parse(storedStr);
if (!Array.isArray(storedData)) {
return;
}
tableData1.value.splice(0, tableData1.value.length, ...(storedData.map((e, index) => {
return {
...e,
index: index,
}
})));
if (table1Ref.value) {
table1Ref.value.doLayout(); //
}
}
const getTableData = async () => {
await getAllAirPort().then(e => {
options1.value = e.data
})
}
//
const getAreaData = () => {
GetAllCData({areaId: form1.value.region1}).then((res) => {
areaPoints.value = res.data
let data = calcRectangleFromPoints(res.data)
areaData.value = data
getDeviationValue(res.data.find(e => e.name === '点位3'))
getDeviationValue(res.data.find(e => e.name === '点位3'), areaPoints.value)
const sorted = res.data.sort((a, b) => {
const numA = parseInt(a.name.replace(/[^\d]/g, ''), 10);
@ -1323,51 +1274,58 @@ const getAreaData = () => {
UpdateFodScopeData(result)
})
}
onMounted(() => {
readTableData()
getTableData()
getSocket()
getOption()
getShildTableList()
// testFun()
getDotsData()
})
const testFun = () => {
let areaData111 = [
{
"id": 8,
"name": "点位4",
"lon": 119.684151,
"lat": 25.93293,
"isDel": 0,
"fodAreaId": 1,
"fodAirId": 1
},
{
"id": 7,
"name": "点位3",
"lon": 119.680298,
"lat": 25.9260902,
"isDel": 0,
"fodAreaId": 1,
"fodAirId": 1
},
{
"id": 6,
"name": "点位2",
"lon": 119.679855,
"lat": 25.9263058,
"isDel": 0,
"fodAreaId": 1,
"fodAirId": 1
},
{
"id": 5,
"name": "点位1",
"lon": 119.683708,
"lat": 25.9331474,
"isDel": 0,
"fodAreaId": 1,
"fodAirId": 1
}
]
areaPoints.value =areaData111
let areaData111 = [
{
"id": 8,
"name": "点位4",
"lon": 119.684151,
"lat": 25.93293,
"isDel": 0,
"fodAreaId": 1,
"fodAirId": 1
},
{
"id": 7,
"name": "点位3",
"lon": 119.680298,
"lat": 25.9260902,
"isDel": 0,
"fodAreaId": 1,
"fodAirId": 1
},
{
"id": 6,
"name": "点位2",
"lon": 119.679855,
"lat": 25.9263058,
"isDel": 0,
"fodAreaId": 1,
"fodAirId": 1
},
{
"id": 5,
"name": "点位1",
"lon": 119.683708,
"lat": 25.9331474,
"isDel": 0,
"fodAreaId": 1,
"fodAirId": 1
}
]
areaPoints.value = areaData111
let data = calcRectangleFromPoints(areaData111)
areaData.value = data
getDeviationValue(areaData111.find(e => e.name === '点位3'))
getDeviationValue(areaData111.find(e => e.name === '点位3'), areaPoints.value)
let data1 = {
lon: 119.684151,
lat: 25.93293,
@ -1381,6 +1339,7 @@ const testFun = () => {
}
getLocal()
}
const getDotsData = () => {
dots.value = [...tableData1.value.map((v, k) => {
const rectInfo = calcRectangleFromPoints(areaPoints.value);
@ -1402,7 +1361,8 @@ watch(() => JSON.stringify([tableData1.value, areaPoints.value]), (oldVal, newVa
console.log(dots.value)
}, {deep: true})
const table1DataIndexF = () =>{
const table1DataIndexF = () => {
tableData1.value = tableData1.value.map((v, k) => {
return {
@ -1411,40 +1371,6 @@ const table1DataIndexF = () =>{
}
})
}
const readTableData = () =>{
const storedStr = localStorage.getItem('tableData1');
if (!storedStr) {
console.log('localStorage中无数据');
return;
}
const storedData = JSON.parse(storedStr);
if (!Array.isArray(storedData)) {
console.error('存储的数据不是数组');
return;
}
tableData1.value.splice(0, tableData1.value.length, ...(storedData.map((e,index)=>{
return {
...e,
index: index,
}
})));
if (table1Ref.value) {
table1Ref.value.doLayout(); //
}
console.log('加载成功,数据长度:', tableData1.value.length);
}
onMounted(() => {
readTableData()
getTableData()
getSocket()
getOption()
getShildTableList()
// testFun()
getDotsData()
})
</script>
<style>
.app-container {

Loading…
Cancel
Save