You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1075 lines
35 KiB
Vue

4 months ago
<template>
2 months ago
4 months ago
<div class="app-container">
3 months ago
<TOP/>
<LEFT/>
<RIGHT/>
3 months ago
<el-button style="position: fixed;top: 10px;right: 10px" type="primary" @click="toAdmin"></el-button>
4 months ago
</div>
3 months ago
<!-- </div>-->
4 months ago
</template>
3 months ago
<script setup lang="jsx">
4 months ago
import Ruler from "@/components/ruler.vue";
3 months ago
import {defineComponent, nextTick, onMounted, ref} from "vue";
4 months ago
import {
getParasPos,
getParasSignalpro,
setParasPos,
setParasSignalpro,
getShildList,
addShildData,
2 months ago
delShildData,
StartWork,
StopWork,
RestartWork,
ShutDownWork,
getAllAirPort,
getArea,
GetAllCData,
InsertCListData,
2 months ago
UpdateCData, DeleteCData
4 months ago
} from "@/api/api";
3 months ago
import {useRouter} from "vue-router";
2 months ago
const router = useRouter();
2 months ago
import {ElMessage} from "element-plus";
4 months ago
2 months ago
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);
});
3 months ago
}
2 months ago
const processData = (data) => {
if (data.FodName === '雷达信息') {
radarWorkState.value = data.radar_work_state
}
if (data.FodName === '图像数据') {
}
if (data.FodName === 'fod信息') {
2 months ago
console.log('障碍物信息', data)
2 months ago
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 = getLocalPositionRelativeToP4(point, areaPoints.value, rectInfo);
boxPos.value = local
}
};
3 months ago
const TOP = defineComponent({
name: 'TOP',
setup() {
return () => (
<div class="top">
<div class="title">探测系统</div>
<div class="items">
<div
class={{item: true, click: itemsId.value === 1}}
onClick={() => setItemsId(1)}
>
<span>主界面</span>
</div>
<div
class={{item: true, click: itemsId.value === 2}}
onClick={() => setItemsId(2)}
>
<span>区域标定</span>
</div>
<div
class={{item: true, click: itemsId.value === 3}}
onClick={() => setItemsId(3)}
>
<span>软件设置</span>
</div>
<div
class={{item: true, click: itemsId.value === 4}}
onClick={() => setItemsId(4)}
>
<span>历史记录</span>
</div>
</div>
</div>
)
}
})
const LEFT = defineComponent({
name: 'LEFT',
setup() {
return () => (
<div class="left">
<Ruler
ref={rulerRef}
2 months ago
width={areaData.value.width}
height={areaData.value.height}
3 months ago
boxPos={boxPos.value}
3 months ago
dots={dots.value}
2 months ago
dotIndex={dotIndex.value}
3 months ago
/>
</div>
)
}
})
const RIGHT = defineComponent({
name: 'RIGHT',
setup() {
return () => (
<div class="right">
{itemsId.value === 1 && (
<div class="tabsItem">
<ElCard shadow="always">
<ElForm inline model={form1.value} class="demo-form-inline">
<ElFormItem>
<ElSelect
modelValue={form1.value.region}
placeholder="请选择机场名称"
style={{width: "200px"}}
clearable
3 months ago
onUpdate:modelValue={val => selectUpdate(val)}
3 months ago
>
3 months ago
{
options1.value.map(i => {
return <ElOption label={i.name} value={i.id}/>
})
}
3 months ago
</ElSelect>
</ElFormItem>
<ElFormItem>
<ElSelect
modelValue={form1.value.region1}
placeholder="请选择区域名称"
style={{width: "200px"}}
clearable
onUpdate:modelValue={val => (form1.value.region1 = val)}
>
3 months ago
{
options2.value.map(i => {
return <ElOption label={i.name} value={i.id}/>
})
}
3 months ago
</ElSelect>
</ElFormItem>
<ElFormItem>
2 months ago
<ElButton type="primary" onClick={getAreaData}>获取区域</ElButton>
3 months ago
</ElFormItem>
</ElForm>
</ElCard>
<ElCard shadow="always" style={{marginTop: "12px"}}>
<ElButton
type="primary"
disabled={radarWorkState.value === 1}
onClick={StartWorkBtn}
>
启动雷达
</ElButton>
<ElButton
type="danger"
disabled={radarWorkState.value === 0}
onClick={StopWorkBtn}
>
关闭雷达
</ElButton>
<ElButton type="warning" onClick={RestartWorkBtn}>重启雷达</ElButton>
2 months ago
<ElButton type="info" onClick={ShutDownWorkBtn}>关闭雷达</ElButton>
3 months ago
</ElCard>
<ElCard shadow="always" style={{marginTop: "12px"}}>
{radarWorkState.value === 1 && (
<div style={{
width: 'calc(50% - 50px)',
position: 'relative',
borderRadius: '5px',
backgroundColor: '#01CE69',
height: '44px',
display: 'inline-block',
padding: '0 20px',
marginRight: '20px'
}}>
<span style={{
position: 'absolute',
top: '50%',
transform: 'translateY(-50%)',
left: '20%',
color: '#fff',
letterSpacing: '2px'
}}>雷达通讯状态</span>
<ElIcon size="20px" style={{
position: 'absolute',
top: '50%',
transform: 'translateY(-50%)',
right: '40px'
}}>
<SuccessFilled color="#fff"/>
</ElIcon>
</div>
)}
{radarWorkState.value === 0 && (
<div style={{
width: 'calc(50% - 50px)',
position: 'relative',
borderRadius: '5px',
backgroundColor: '#E8370D',
height: '44px',
display: 'inline-block',
padding: '0 20px'
}}>
<span style={{
position: 'absolute',
top: '50%',
transform: 'translateY(-50%)',
left: '20%',
color: '#fff',
letterSpacing: '2px'
}}>雷达通讯状态</span>
<ElIcon size="20px" style={{
position: 'absolute',
top: '50%',
transform: 'translateY(-50%)',
right: '40px'
}}>
<WarningFilled color="#fff"/>
</ElIcon>
</div>
)}
</ElCard>
<ElCard shadow="always" style={{marginTop: "12px"}}>
<ElForm inline model={form2.value} class="demo-form-inline">
<ElFormItem>
<ElDatePicker
modelValue={form2.value.date}
type="date"
placeholder="选择时间"
clearable
onUpdate:modelValue={val => (form2.value.date = val)}
/>
</ElFormItem>
<ElFormItem>
<ElButton onClick={onSubmit}>停止检测</ElButton>
<ElButton type="primary" onClick={onSubmit}>批量操作</ElButton>
</ElFormItem>
</ElForm>
<ElTable
highlightCurrentRow
2 months ago
onRowClick={table1Current}
3 months ago
data={tableData1.value}
style={{width: "100%"}}
>
<ElTableColumn type="selection" width={55}/>
<ElTableColumn label="序号" type="index" width={60}/>
<ElTableColumn prop="Lon" label="目标经度" width={120}/>
<ElTableColumn prop="Lat" label="目标纬度" width={120}/>
<ElTableColumn label="告警等级" width={160}>
{{
default: scope => <ElRate modelValue={scope.row.rate || 3} disabled/>
}}
</ElTableColumn>
<ElTableColumn label="处理状态" showOverflowTooltip>
{{
default: scope => (
<>
<ElButton type="primary" link>已处理</ElButton>
<ElButton type="primary" link onClick={() => addShildItem()}>不处理</ElButton>
<ElButton type="primary" link>未发现</ElButton>
</>
)
}}
</ElTableColumn>
</ElTable>
</ElCard>
<ElCard shadow="always" style={{marginTop: "12px"}}>
<ElTable data={tableData2.value} style={{width: "100%"}}>
<ElTableColumn label="序号" type="index" width={60}/>
<ElTableColumn prop="name" label="目标名称" width={120}/>
<ElTableColumn prop="lon" label="目标经度" width={120}/>
<ElTableColumn prop="lat" label="目标纬度" width={120}/>
<ElTableColumn prop="deviation" label="deviation" width={120}/>
<ElTableColumn prop="shielding" label="shielding" width={120}/>
<ElTableColumn label="操作" showOverflowTooltip>
{{
default: scope => (
<ElButton type="primary" link onClick={() => delShildItem(scope.row)}>删除</ElButton>
)
}}
</ElTableColumn>
</ElTable>
</ElCard>
</div>
)}
{itemsId.value === 2 && (
<div class="tabsItem">
<ElCard shadow="always">
<ElForm inline model={form5.value} class="demo-form-inline">
<ElFormItem>
<ElInput
modelValue={form5.value.region}
placeholder="请输入机场名称"
style={{width: "200px"}}
onUpdate:modelValue={val => (form5.value.region = val)}
/>
</ElFormItem>
<ElFormItem>
<ElInput
modelValue={form5.value.region1}
placeholder="请输入区域名称"
style={{width: "200px"}}
onUpdate:modelValue={val => (form5.value.region1 = val)}
/>
</ElFormItem>
<ElFormItem>
<ElButton type="primary" onClick={onSubmit}>添加</ElButton>
</ElFormItem>
</ElForm>
<ElForm inline model={form6.value} class="demo-form-inline" style={{marginTop: "12px"}}>
<ElFormItem>
<ElSelect
modelValue={form6.value.region}
placeholder="请选择机场名称"
style={{width: "200px"}}
clearable
3 months ago
onUpdate:modelValue={val => select2Update(val)}
3 months ago
>
3 months ago
{
options1.value.map(i => {
return <ElOption label={i.name} value={i.id}/>
})
}
3 months ago
</ElSelect>
</ElFormItem>
<ElFormItem>
<ElSelect
modelValue={form6.value.region1}
placeholder="请选择区域名称"
style={{width: "200px"}}
clearable
3 months ago
onUpdate:modelValue={val => select3Update(val)}
3 months ago
>
3 months ago
{
options2.value.map(i => {
return <ElOption label={i.name} value={i.id}/>
})
}
3 months ago
</ElSelect>
</ElFormItem>
<ElFormItem>
3 months ago
<ElButton type="primary" onClick={getArea2}>确定</ElButton>
3 months ago
</ElFormItem>
</ElForm>
</ElCard>
<ElCard shadow="always" style={{marginTop: "12px"}}>
2 months ago
{regionLabeling.value.map((i, k) => (
3 months ago
<div style={{marginBottom: "12px"}} key={k}>
2 months ago
<ElInput disabled onUpdate:modelValue={val => (regionLabeling.value[k].name = val)}
2 months ago
modelValue={i.name}
2 months ago
placeholder="点位名称" style={{width: "100px"}}/>
3 months ago
<ElInput
2 months ago
modelValue={i.lon} placeholder="经度"
3 months ago
style={{width: "150px", marginLeft: "20px"}}
2 months ago
onUpdate:modelValue={val => (regionLabeling.value[k].lon = val)}
3 months ago
/>
<ElInput
2 months ago
modelValue={i.lat} placeholder="纬度"
3 months ago
style={{width: "150px", marginLeft: "20px"}}
2 months ago
onUpdate:modelValue={val => (regionLabeling.value[k].lat = val)}
3 months ago
/>
<ElButton type="primary" onClick={() => getPoint(k)}
style={{marginLeft: "20px"}}>获取</ElButton>
2 months ago
<ElButton type="danger"
onClick={() => DeleteCData({id: parseFloat(i.id)}).then(() => getArea2())}
2 months ago
style={{marginLeft: "20px"}}>删除</ElButton>
3 months ago
</div>
))}
2 months ago
2 months ago
<ElButton type="primary" onClick={() => {
2 months ago
InsertCListData([{
2 months ago
name: `点位${regionLabeling.value.length + 1}`,
2 months ago
lon: '1',
lat: '1',
2 months ago
fodAreaId: form6.value.region1,
fodAirId: form6.value.region
}]).then(() => {
2 months ago
getArea2()
})
}}
2 months ago
style={{textAlign: "center"}}>添加</ElButton>
3 months ago
</ElCard>
<div style={{textAlign: "center", marginTop: "12px"}}>
2 months ago
<ElButton type="primary" onClick={saveAreaPoint} style={{marginLeft: "20px"}}>提交</ElButton>
3 months ago
</div>
</div>
)}
{itemsId.value === 3 && (
<div class="tabsItem">
<div>成像设置</div>
<ElForm model={parasSignalproForm.value} inline labelWidth="auto" labelPosition="top">
{["imaging_rangemin", "imaging_rangemax", "imaging_rangeres", "imaging_azimuthlength", "imaging_azimuthres"].map((key, idx) => (
<ElFormItem style={{width: "calc(33% - 32px)"}} label={key} key={idx}>
<ElInput
modelValue={(parasSignalproForm.value.imaging || {})[key]}
onUpdate:modelValue={val => ((parasSignalproForm.value.imaging ||= {})[key] = val)}
/>
</ElFormItem>
))}
</ElForm>
<div>检测设置</div>
<ElForm model={parasSignalproForm.value} inline labelWidth="auto" labelPosition="top">
{["alpha", "decstartr", "decwidth", "sk_r", "sk_a", "lk_r", "lk_a"].map((key, idx) => (
<ElFormItem style={{width: "calc(33% - 32px)"}} label={key} key={idx}>
<ElInput
modelValue={(parasSignalproForm.value.dectection || {})[key]}
onUpdate:modelValue={val => ((parasSignalproForm.value.dectection ||= {})[key] = val)}
/>
</ElFormItem>
))}
<ElFormItem style={{width: "100%"}}>
<div style={{textAlign: "center", width: "100%"}}>
<ElButton type="primary" onClick={saveParasSignalproForm}>保存</ElButton>
</div>
</ElFormItem>
</ElForm>
<div>路线设置</div>
<ElForm model={parasPosForm.value} inline labelWidth="auto" labelPosition="top">
<ElFormItem style={{width: "calc(33% - 32px)"}} label="路线数量">
<ElInputNumber
modelValue={(parasPosForm.value.runwaynum || {}).startpos_num}
precision={0}
step={1}
min={0}
onUpdate:modelValue={val => {
parasPosForm.value.runwaynum.startpos_num = val;
updateRunwayNum(val);
}}
/>
</ElFormItem>
{Array.from({length: (parasPosForm.value.runwaynum || {}).startpos_num || 0}).map((_, k) => (
<div key={k} style="width: 100%">
<div>路线{k + 1}设置</div>
{["startpos_lon_a", "startpos_lat_a", "startpos_alt_a", "startpos_lon_b", "startpos_lat_b", "startpos_alt_b", "startpos_ori"].map((field, idx) => (
<ElFormItem style={{width: "calc(33% - 32px)", display: "inline-block"}} label={field}
key={idx}>
<ElInput
modelValue={(parasPosForm.value.runwayedges[k] || {})[field]}
onUpdate:modelValue={val => (((parasPosForm.value.runwayedges[k] ||= {})[field] = val))}
/>
</ElFormItem>
))}
</div>
))}
<ElFormItem style={{width: "100%"}}>
<div style={{textAlign: "center", width: "100%"}}>
<ElButton type="primary" onClick={saveParasPosForm}>保存</ElButton>
</div>
</ElFormItem>
</ElForm>
</div>
)}
{itemsId.value === 4 && (
<div class="tabsItem">
<ElCard shadow="always">
<ElDatePicker
style={{width: "calc(100% - 20px)"}}
modelValue={date1.value}
type="datetimerange"
rangeSeparator="到"
startPlaceholder="选择开始时间"
endPlaceholder="选择结束时间"
onUpdate:modelValue={val => (date1.value = val)}
/>
</ElCard>
<ElCard shadow="always" style={{marginTop: "12px"}}>
<ElForm inline model={form3.value} class="demo-form-inline">
{["region", "region1", "region2"].map((key, idx) => (
<ElFormItem key={idx}>
{key === "region2" ? (
<ElSelect
modelValue={form3.value[key]}
placeholder="请选择固定目标"
style={{width: "170px"}}
clearable
onUpdate:modelValue={val => (form3.value[key] = val)}
>
<ElOption label="目标1" value="shanghai"/>
<ElOption label="目标2" value="beijing"/>
</ElSelect>
) : (
<ElSelect
modelValue={form3.value[key]}
placeholder={`请选择${key === "region" ? "机场" : "区域"}`}
style={{width: "170px"}}
clearable
onUpdate:modelValue={val => (form3.value[key] = val)}
>
<ElOption label="机场1" value="shanghai"/>
<ElOption label="机场2" value="beijing"/>
<ElOption label="区域1" value="shanghai"/>
<ElOption label="区域2" value="beijing"/>
</ElSelect>
)}
</ElFormItem>
))}
</ElForm>
</ElCard>
<ElCard shadow="always" style={{marginTop: "12px"}}>
<ElForm inline model={form4.value} class="demo-form-inline">
<ElFormItem>
<ElInput
modelValue={form4.value.input1}
placeholder="请输入检测序号"
style={{width: "170px"}}
onUpdate:modelValue={val => (form4.value.input1 = val)}
/>
</ElFormItem>
<ElFormItem>
<ElDatePicker
modelValue={form4.value.date1}
type="date"
placeholder="选择检测时间"
clearable
style={{width: "170px"}}
onUpdate:modelValue={val => (form4.value.date1 = val)}
/>
</ElFormItem>
<ElFormItem>
<ElInput
modelValue={form4.value.input2}
placeholder="请输入检测人员"
style={{width: "170px"}}
onUpdate:modelValue={val => (form4.value.input2 = val)}
/>
</ElFormItem>
</ElForm>
</ElCard>
<ElCard shadow="always" style={{marginTop: "12px"}}>
<ElTable data={tableData2.value} style={{width: "100%"}}>
<ElTableColumn label="序号" type="index" width={60}/>
<ElTableColumn prop="coordinate" label="目标坐标" width={120}/>
<ElTableColumn label="告警等级" width={160}>
{{default: scope => <ElRate modelValue={scope.row.rate} disabled/>}}
</ElTableColumn>
<ElTableColumn label="处理状态" showOverflowTooltip>
{{
default: scope => (
<>
<span>{scope.row.type === 1 ? "已处理" : ""}</span>
<span>{scope.row.type === 2 ? "不处理" : ""}</span>
<span>{scope.row.type === 3 ? "未发现" : ""}</span>
</>
)
}}
</ElTableColumn>
</ElTable>
</ElCard>
</div>
)}
</div>
)
}
})
2 months ago
// 默认方法
const onSubmit = (e) => {
console.log(e)
3 months ago
}
3 months ago
2 months ago
// 当前菜单id
const itemsId = ref(1)
// 菜单id跳转
const setItemsId = (e) => {
itemsId.value = e
4 months ago
}
2 months ago
// 雷达状态
const radarWorkState = ref(0)
// 车辆位置
2 months ago
const boxPos = ref({x: 100, y: 150, rotate: 0})
2 months ago
// 左侧区域宽高
const areaData = ref({
width: 500,
height: 1000,
angle: 0
})
// 缩放等级
const areaType = ref(1)
// 障碍物点位
3 months ago
const dots = ref([
2 months ago
// {
// x: 150,
// y: 98
// },
// {
// x: 50,
// y: 102
// },
// {
// x: 75,
// y: 75
// },
// {
// x: 125,
// y: 125
// }
3 months ago
])
2 months ago
// 当前的目标障碍物
3 months ago
const dotIndex = ref(-1)
2 months ago
// 跳转到管理界面
const toAdmin = () => {
router.push('/serve')
2 months ago
}
2 months ago
// 检测&成像设置
4 months ago
const parasSignalproForm = ref({
imaging: {},
dectection: {}
})
2 months ago
// 路线设置
4 months ago
const parasPosForm = ref({
runwaynum: {
startpos_num: 1
4 months ago
},
runwayedges: [
{
startpos_lon_a: '',
startpos_lat_a: '',
startpos_alt_a: '',
startpos_lon_b: '',
startpos_lat_b: '',
startpos_alt_b: '',
startpos_ori: ''
}
]
4 months ago
})
2 months ago
// 获取配置文件
4 months ago
const getOption = () => {
getParasPos().then((e) => {
parasPosForm.value = {
runwaynum: e.runwaynum,
runwayedges: e.runwayedges,
}
})
getParasSignalpro().then((e) => {
parasSignalproForm.value = {
imaging: e.imaging,
dectection: e.dectection,
}
})
}
2 months ago
// 保存成像&检测设置
4 months ago
const saveParasSignalproForm = () => {
setParasSignalpro(parasSignalproForm.value).then(e => {
})
}
2 months ago
// 保存路线设置
4 months ago
const saveParasPosForm = () => {
setParasPos(parasPosForm.value).then(e => {
console.log(e)
})
}
2 months ago
// 更新路线数量
4 months ago
const updateRunwayNum = (e) => {
let arr = new Array(e).fill(0)
.map((item, index) => {
if (index <= parasPosForm.value.runwayedges.length - 1) {
return JSON.parse(JSON.stringify(parasPosForm.value.runwayedges[index]))
} else {
return {
startpos_lon_a: '',
startpos_lat_a: '',
startpos_alt_a: '',
startpos_lon_b: '',
startpos_lat_b: '',
startpos_alt_b: '',
startpos_ori: ''
}
}
})
parasPosForm.value.runwayedges = JSON.parse(JSON.stringify(arr))
}
2 months ago
// 启动雷达
const StartWorkBtn = () => {
StartWork()
rulerRef.value.setDot([], true)
tableData1.value = []
}
// 停止雷达
const StopWorkBtn = () => {
StopWork()
}
// 重启雷达
const RestartWorkBtn = () => {
RestartWork()
}
// 关闭雷达
const ShutDownWorkBtn = () => {
ShutDownWork()
}
// 设置障碍物-不处理
4 months ago
const addShildItem = () => {
addShildData({
name: 'string',
lon: 123,
lat: 12,
deviation: 12,
shielding: 23
}).then(e => {
getShildTableList()
})
}
2 months ago
// 删除已处理的障碍物
4 months ago
const delShildItem = (e) => {
delShildData(e).then(e => {
getShildTableList()
})
}
2 months ago
// 获取已处理的障碍物列表
4 months ago
const getShildTableList = () => {
getShildList({
pageIndex: 1,
pageSize: 10,
name: 'string'
}).then((e) => {
tableData2.value = e.data
})
}
2 months ago
const form1 = ref({})
const form2 = ref({})
const form3 = ref({})
const form4 = ref({})
const form5 = ref({})
const form6 = ref({})
4 months ago
2 months ago
const tableData1 = ref([])
2 months ago
const tableData2 = ref([
{
"id": 2,
"name": "测试",
"lon": 12.2299995,
"lat": 323.329987,
"deviation": 12,
"shielding": 20
},
{
"id": 1,
"name": "测试",
"lon": 12.2299995,
"lat": 323.329987,
"deviation": 12,
"shielding": 20
}
])
const date1 = ref([])
const currentPosition = ref({})
4 months ago
2 months ago
const DEG_TO_RAD = Math.PI / 180;
4 months ago
2 months ago
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};
}
4 months ago
2 months ago
function calcRectangleFromPoints(points) {
if (!points || points.length !== 4) throw new Error("必须传入4个点");
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];
4 months ago
2 months ago
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);
4 months ago
2 months ago
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;
2 months ago
console.log({
width: Number(width.toFixed(2)),
height: Number(height.toFixed(2)),
angle: Number(angleDeg.toFixed(6))
})
2 months ago
return {
width: Number(width.toFixed(2)),
height: Number(height.toFixed(2)),
angle: Number(angleDeg.toFixed(6))
};
4 months ago
}
2 months ago
function getLocalPositionRelativeToP4(point, rectPoints, rectInfo) {
if (!rectInfo || typeof rectInfo.angle !== 'number') {
throw new Error("rectInfo.angle 必须是由 calcRectangleFromPoints 得到的角度");
}
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))
};
4 months ago
}
2 months ago
const getPoint = (k) => {
2 months ago
regionLabeling.value[k].lon = currentPosition.value.lon || 0
regionLabeling.value[k].lat = currentPosition.value.lat || 0
}
3 months ago
const setDot = (e) => {
2 months ago
let fodInfo = e.DarDatas.filter(v => v.Lon !== 0 && v.Lat !== 0)
dots.value = [...dots.value, ...fodInfo.map((v, k) => {
2 months ago
2 months ago
const rectInfo = calcRectangleFromPoints(areaPoints.value);
const point = {
lon: v.Lon,
lat: v.Lat,
rotate: 0
};
const local = getLocalPositionRelativeToP4(point, areaPoints.value, rectInfo);
return local
2 months ago
}).filter(v => v)]
2 months ago
console.log(dots.value)
2 months ago
tableData1.value = [...tableData1.value, ...fodInfo.map((v, k) => {
return {...v, index: tableData1.value.length + k}
3 months ago
})]
2 months ago
// rulerRef.value.setDot(dots, false)
3 months ago
}
3 months ago
const table1Current = (e, v) => {
3 months ago
if (dotIndex.value === e.index) {
dotIndex.value = -1
} else {
dotIndex.value = e.index || 0
}
3 months ago
console.log(e)
}
3 months ago
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
}
2 months ago
// 区域标定页面获取区域信息
3 months ago
const getArea2 = () => {
2 months ago
GetAllCData({areaId: form6.value.region1}).then((res) => {
2 months ago
regionLabeling.value = res.data
2 months ago
})
}
2 months ago
// 区域标定信息
const regionLabeling = ref([])
// 区域点位信息
const areaPoints = ref([])
// 保存区域信息
2 months ago
const saveAreaPoint = () => {
2 months ago
let arr = []
2 months ago
regionLabeling.value.forEach((v, k) => {
2 months ago
arr.push(UpdateCData(v))
})
Promise.all(arr).then(() => {
2 months ago
areaPoints.value = JSON.parse(JSON.stringify(regionLabeling.value))
2 months ago
ElMessage.success('保存成功')
2 months ago
let data = calcRectangleFromPoints(areaPoints.value)
2 months ago
areaData.value = data
2 months ago
}).catch((err) => {
ElMessage.error(err)
2 months ago
})
3 months ago
}
2 months ago
2 months ago
// 主界面获取区域信息
2 months ago
const getAreaData = () => {
GetAllCData({areaId: form1.value.region1}).then((res) => {
2 months ago
areaPoints.value = res.data
2 months ago
let data = calcRectangleFromPoints(res.data)
areaData.value = data
})
}
2 months ago
onMounted(() => {
getTableData()
getSocket()
getOption()
getShildTableList()
})
4 months ago
</script>
<style>
.app-container {
3 months ago
width: 1080px;
min-width: 1080px;
3 months ago
height: 100vh;
4 months ago
margin: 0 auto;
}
.top {
width: 100%;
height: 80px;
font-size: 24px;
background-color: #202227;
position: relative;
}
.items {
position: absolute;
top: 15%;
left: 50%;
transform: translateX(-50%);
white-space: nowrap;
}
.item {
display: inline-block;
width: 120px;
height: 100%;
color: #8C9A9C;
line-height: 56px;
cursor: pointer;
font-size: 18px;
font-weight: 600;
letter-spacing: 2px;
}
.item span {
display: inline-block;
height: 100%;
}
3 months ago
.item.click span,
.item:hover span {
4 months ago
color: #0D52BF;
border-bottom: 2px solid #0D52BF;
}
.title {
line-height: 80px;
color: #fff;
margin-left: 20px;
display: inline-block;
text-align: left;
}
.left {
display: inline-block;
3 months ago
height: calc(100vh - 80px);
width: 34%;
4 months ago
vertical-align: top;
}
.right {
3 months ago
padding: 20px 20px 0 20px;
4 months ago
display: inline-block;
3 months ago
height: calc(100vh - 80px - 20px);
width: calc(66% - 40px);
4 months ago
background-color: #F6F7FB;
3 months ago
overflow: auto;
4 months ago
}
</style>