feat: 加载地图
This commit is contained in:
parent
780665fa9a
commit
6af1118a3c
@ -10,3 +10,5 @@ VITE_APP_BASE_API = '/dev-api'
|
||||
VITE_API_URL = http://192.168.28.10:13080
|
||||
VITE_WS_URL = ws://192.168.0.201:13080/ws
|
||||
|
||||
# explanation
|
||||
VITE_INSPECTION_TYPE = "inspection"
|
||||
@ -15,3 +15,6 @@ VITE_NODE_RED_URL = 'http://10.148.108.59:13080'
|
||||
|
||||
VITE_API_URL = http://192.168.28.10:13080
|
||||
VITE_WS_URL = ws://192.168.0.201:13080/ws
|
||||
|
||||
# explanation
|
||||
VITE_INSPECTION_TYPE = "inspection"
|
||||
@ -29,4 +29,29 @@ export function deleteRobot(id) {
|
||||
url: `/inspection/robot/${id}`,
|
||||
method: 'delete'
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取机器人地图
|
||||
* @param {*} robotId
|
||||
* @returns
|
||||
*/
|
||||
export function getMapByRobot(robotId) {
|
||||
return request({
|
||||
url: `/inspection/robot/${robotId}/maps`,
|
||||
method: 'get'
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取地图JSON数据
|
||||
* @param {*} params
|
||||
* @returns
|
||||
*/
|
||||
export function getMapJson(params) {
|
||||
return request({
|
||||
url: `/inspection/robot/${params.robotId}/download-map`,
|
||||
method: 'get',
|
||||
params
|
||||
})
|
||||
}
|
||||
@ -153,7 +153,7 @@ async function loadMapIntoApplication(parsedMap) {
|
||||
const worldHeightMeters = parsedMap.maxY - parsedMap.originY; // 地图世界高度
|
||||
const fitScaleX = inspectionStore.canvasWidthPx / worldWidthMeters; // 水平方向恰好填满的缩放
|
||||
const fitScaleY = inspectionStore.canvasHeightPx / worldHeightMeters; // 垂直方向恰好填满的缩放
|
||||
inspectionStore.camera.pixelsPerMeter = Math.max(1, Math.min(fitScaleX, fitScaleY) * 1); // 取较小值
|
||||
inspectionStore.camera.pixelsPerMeter = Math.max(1, Math.max(fitScaleX, fitScaleY) * 1); // 取较小值
|
||||
|
||||
// 标记加载完成并更新UI
|
||||
applicationState.isMapLoaded = true;
|
||||
|
||||
@ -65,10 +65,10 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="right-container">
|
||||
<div class="sensor-container">
|
||||
<!-- <div class="sensor-container">
|
||||
<div class="sensor-title">传感器数据</div>
|
||||
</div>
|
||||
<div class="split-line"></div>
|
||||
</div> -->
|
||||
<!-- <div class="split-line"></div> -->
|
||||
<div class="alarm-container">
|
||||
<div class="container-title">告警记录</div>
|
||||
<div class="alarm-box" v-for="item, index in 2">
|
||||
@ -85,6 +85,8 @@ import SvgIcon from "@/components/SvgIcon";
|
||||
import MapCanvas from "./MapCanvas.vue";
|
||||
import { onMounted, onUnmounted } from "vue";
|
||||
|
||||
console.log('sss', import.meta.env.VITE_INSPECTION_TYPE)
|
||||
|
||||
const robotState = ref('online')
|
||||
|
||||
const mapCanvasRef = ref(null)
|
||||
|
||||
@ -88,7 +88,7 @@
|
||||
|
||||
import { useContainerHeight } from "@/hooks/tableHeight";
|
||||
import { addMap, updateMap, deleteMap, getMapList } from "../../../api/inspection/map";
|
||||
import { getRobotList } from "../../../api/inspection/robot";
|
||||
import { getRobotList, getMapByRobot, getMapJson } from "../../../api/inspection/robot";
|
||||
import { onMounted } from "vue";
|
||||
|
||||
import {
|
||||
@ -171,6 +171,7 @@ function cancel() {
|
||||
}
|
||||
|
||||
window.removeEventListener('resize', resizeCanvasToContainer)
|
||||
canvasCtx.clearRect(0, 0, applicationState.canvasWidthPx, applicationState.canvasHeightPx);
|
||||
canvasCtx = null
|
||||
}
|
||||
|
||||
@ -215,6 +216,7 @@ function handleUpdate(row) {
|
||||
isNew.value = false;
|
||||
open.value = true;
|
||||
title.value = "修改地图";
|
||||
getMapArr(row.mapSourceRobotId)
|
||||
setTimeout(() => {
|
||||
init();
|
||||
if (form.value.mapSourceName) {
|
||||
@ -265,12 +267,6 @@ function handleDelete(row) {
|
||||
|
||||
}
|
||||
|
||||
const loadSourceMap = async (url) => {
|
||||
const response = await fetch(url);
|
||||
if (!response.ok) throw new Error(`加载失败:${response.status}`);
|
||||
return response.text();
|
||||
};
|
||||
|
||||
function parseSmapJson(rawJson) {
|
||||
// ── 解析 header ──
|
||||
const header = rawJson.header || rawJson; // 兼容 header 嵌套或平铺
|
||||
@ -360,7 +356,6 @@ const init = () => {
|
||||
*/
|
||||
function resizeCanvasToContainer() {
|
||||
const containerRect = mapCanvas.parentElement.getBoundingClientRect(); // 获取容器实际尺寸
|
||||
console.log('containerRect', containerRect)
|
||||
devicePixelRatio = window.devicePixelRatio || 1; // 获取设备像素比
|
||||
applicationState.canvasWidthPx = containerRect.width; // 更新逻辑宽度
|
||||
applicationState.canvasHeightPx = containerRect.height; // 逻辑高度 = 容器高度 - 状态栏高度
|
||||
@ -386,7 +381,7 @@ async function loadMapIntoApplication(parsedMap) {
|
||||
const worldHeightMeters = parsedMap.maxY - parsedMap.originY; // 地图世界高度
|
||||
const fitScaleX = applicationState.canvasWidthPx / worldWidthMeters; // 水平方向恰好填满的缩放
|
||||
const fitScaleY = applicationState.canvasHeightPx / worldHeightMeters; // 垂直方向恰好填满的缩放
|
||||
applicationState.camera.pixelsPerMeter = Math.max(1, Math.min(fitScaleX, fitScaleY)); // 取较小值并留12%边距
|
||||
applicationState.camera.pixelsPerMeter = Math.max(1, Math.max(fitScaleX, fitScaleY)); // 取较小值并留12%边距
|
||||
|
||||
// 标记加载完成并更新UI
|
||||
applicationState.isMapLoaded = true;
|
||||
@ -443,10 +438,16 @@ const bindEvent = () => {
|
||||
*/
|
||||
const loadUserFile = async () => {
|
||||
try {
|
||||
const filemapDesc = await loadSourceMap('/3.smap');
|
||||
const rawJsonObject = JSON.parse(filemapDesc); // 解析 JSON
|
||||
const parsedMap = parseSmapJson(rawJsonObject); // 转换为内部结构
|
||||
await loadMapIntoApplication(parsedMap); // 加载到应用
|
||||
const res = await getMapJson({
|
||||
robotId: form.value.mapSourceRobotId,
|
||||
mapName: form.value.mapSourceName
|
||||
});
|
||||
if (res.code === 200) {
|
||||
const rawJsonObject = JSON.parse(res.data); // 解析 JSON
|
||||
const parsedMap = parseSmapJson(rawJsonObject); // 转换为内部结构
|
||||
await loadMapIntoApplication(parsedMap); // 加载到应用
|
||||
}
|
||||
|
||||
} catch (parseError) {
|
||||
alert('Parse error: ' + parseError.message); // 显示错误信息
|
||||
}
|
||||
@ -530,13 +531,13 @@ const getRobotArr = () => {
|
||||
});
|
||||
}
|
||||
|
||||
const getMapArr = (robotId) => {
|
||||
// TODO: 这里可以根据 robotId 来过滤地图列表,目前接口没有提供这个功能,所以暂时获取全部地图
|
||||
mapList.value = [
|
||||
{ label: "地图1", value: "map1" },
|
||||
{ label: "地图2", value: "map2" },
|
||||
{ label: "地图3", value: "map3" },
|
||||
]
|
||||
const getMapArr = async (robotId) => {
|
||||
const res = await getMapByRobot(robotId)
|
||||
if (res.code === 200) {
|
||||
mapList.value = res.data.map(item => {
|
||||
return { label: item, value: item }
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
const robotChange = (value) => {
|
||||
|
||||
@ -26,7 +26,12 @@
|
||||
<div :style="containerHeight">
|
||||
<el-table v-loading="loading" height="100%" style="width: 100%" :data="tableDataList">
|
||||
<el-table-column label="机器人名称" align="center" prop="robotName" />
|
||||
<el-table-column label="机器人类型" align="center" prop="robotType" />
|
||||
<el-table-column label="机器人编码" align="center" prop="robotCode" />
|
||||
<el-table-column label="机器人类型" align="center" prop="robotType">
|
||||
<template #default="scope">
|
||||
{{ scope.row.robotType == 1 ? '讲解机器人' : '巡检机器人' }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="IP地址" align="center" prop="ipAddress" min-width="160" show-overflow-tooltip />
|
||||
<el-table-column label="电量" align="center" prop="batteryLevel" />
|
||||
<el-table-column label="状态" align="center" prop="status" />
|
||||
@ -49,6 +54,9 @@
|
||||
<el-form-item label="机器人名称" prop="robotName">
|
||||
<el-input v-model="form.robotName" placeholder="请输入机器人名称" />
|
||||
</el-form-item>
|
||||
<el-form-item label="机器人编码" prop="robotCode">
|
||||
<el-input v-model="form.robotCode" placeholder="请输入机器人编码" />
|
||||
</el-form-item>
|
||||
<el-form-item label="机器人类型" prop="robotType">
|
||||
<el-select v-model="form.robotType" placeholder="请输入机器人类型" clearable style="width: 100%">
|
||||
<el-option v-for="type in robot_type" :key="type.value" :label="type.label"
|
||||
@ -126,6 +134,9 @@ const data = reactive({
|
||||
robotName: [
|
||||
{ required: true, message: "请输入机器人名称", trigger: "change" },
|
||||
],
|
||||
robotCode: [
|
||||
{ required: true, message: "请输入机器人编码", trigger: "change" },
|
||||
],
|
||||
robotType: [
|
||||
{ required: true, message: "请输入机器人类型", trigger: "change" },
|
||||
],
|
||||
|
||||
@ -616,11 +616,6 @@ onUnmounted(() => {
|
||||
font-size: 14px;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.run-log-container {
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user