|
|
|
|
@ -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 {
|
|
|
|
|
|