jiuling 8 hónapja
szülő
commit
5713c19ed9

+ 73 - 0
src/components/OlMap/index.vue

@@ -322,6 +322,79 @@ export default {
     console.log("mapName地图组件:", this.mapName);
   },
   methods: {
+   // 初始化轨迹图层
+  initTrackLayer() {
+    if (this.trackLayer) {
+      this.map.removeLayer(this.trackLayer);
+    }
+    this.trackSource = new VectorSource();
+    this.trackLayer = new VectorLayer({
+      source: this.trackSource,
+      zIndex: 20
+    });
+    this.map.addLayer(this.trackLayer);
+  },
+
+  // 绘制轨迹线
+  drawTrackLine(start, end) {
+    this.initTrackLayer();
+
+    // 1. 绘制线
+    const line = new LineString([start, end]);
+    const lineFeature = new Feature(line);
+
+    // 计算长度
+    const length = getLength(line);
+    const lengthText = `${length.toFixed(2)}m`;
+
+    // 2. 线样式
+    lineFeature.setStyle(new Style({
+      stroke: new Stroke({
+        color: '#ff9800', // 轨迹颜色
+        width: 6
+      }),
+      text: new Text({
+        text: lengthText,
+        font: 'bold 14px sans-serif',
+        fill: new Fill({ color: '#00c387' }),
+        backgroundFill: new Fill({ color: 'rgba(255,255,255,0.8)' }),
+        offsetY: -15
+      })
+    }));
+
+    // 3. 起点
+    const startFeature = new Feature(new Point(start));
+    startFeature.setStyle(new Style({
+      image: new Icon({
+        src: require('@/assets/icons/olmap/dir_backward_red.png'), // 换成你的起点图标
+        scale: 0.18
+      }),
+      text: new Text({
+        text: 'S\n' + lengthText,
+        font: 'bold 14px sans-serif',
+        fill: new Fill({ color: '#00c387' }),
+        offsetY: -30
+      })
+    }));
+
+    // 4. 终点
+    const endFeature = new Feature(new Point(end));
+    endFeature.setStyle(new Style({
+      image: new Icon({
+        src: require('@/assets/icons/olmap/dir_backward_red.png'), // 换成你的终点图标
+        scale: 0.18
+      }),
+      text: new Text({
+        text: 'E\n' + lengthText,
+        font: 'bold 14px sans-serif',
+        fill: new Fill({ color: '#ff3b3b' }),
+        offsetY: -30
+      })
+    }));
+
+    // 5. 添加到轨迹图层
+    this.trackSource.addFeatures([lineFeature, startFeature, endFeature]);
+  },
     // 点击添加点位的操作
     addNowPoint() {
       // 追加当前选择的点位数据到数据列表

+ 5 - 5
src/utils/route-helpers.js

@@ -12,7 +12,7 @@ export function pickName(row) {
 
 // Nav route: name: 'MapNavigation', path: '/map/maplist/navigation/index/:mapId(\\d+)', params: { mapId }
 export function buildNavTo(row) {
-  const id = pickId(row);
+  // const id = pickId(row);
   const mapName = pickName(row);
   console.log("路由跳转mapName:", mapName);
   return { 
@@ -23,7 +23,7 @@ export function buildNavTo(row) {
 
 // Edit route: name: 'MapEdit', path: '/map/maplist/edit/index/:mapId(\\d+)', params: { mapId }
 export function buildEditTo(row) {
-  const id = pickId(row);
+  // const id = pickId(row);
   return { 
     name: 'MapEdit', 
     params: { mapId: id } 
@@ -32,7 +32,7 @@ export function buildEditTo(row) {
 
 // Calibration route: name: 'MapCalibration', path: '/map/maplist/calibration/index/:mapId(\\d+)', params: { mapId }
 export function buildCalibrateTo(row) {
-  const id = pickId(row);
+  // const id = pickId(row);
   const mapName = pickName(row);
   return { 
     name: 'MapCalibration', 
@@ -42,7 +42,7 @@ export function buildCalibrateTo(row) {
 
 // Build route (fallback implementation as no specific route was found)
 export function buildConstructTo(row) {
-  const id = pickId(row);
+  // const id = pickId(row);
   // 使用通用路径,因为未找到特定的构建地图路由
-  return { path: '/map/build', query: { id } };
+  return { path: '/map/build', query: {  } };
 }

+ 165 - 7
src/views/map/maplist/navigation.vue

@@ -1,7 +1,144 @@
 <template>
-	<div class="navigation-container">
-		<!-- 地图舞台容器 -->
-		<div class="map-stage" ref="mapStage">
+	<div class="main">
+		<el-row>
+			<el-col :xs="1" :sm="1" :md="1" :lg="1" :xl="1" style="position: relative;">
+				<div class="main-menu">
+					<div class="img-container" :class="{ 'active': activeIndex === 0 }" @click="openDraSetting"><img
+							src="@/assets/icons/img/setting.png" class="notification__image" width="22px" height="22px" />
+						<span class="notification__title">功能</span>
+					</div>
+					<div class="img-container" :class="{ 'active': activeIndex === 1 }" @click="openPoint"><img
+							src="@/assets/icons/img/post.png" class="notification__image" width="22px" height="22px" />
+						<span class="notification__title">目标点</span>
+					</div>
+					<div class="img-container" :class="{ 'active': activeIndex === 2 }" @click="openTask"><img
+							src="@/assets/icons/img/task.png" class="notification__image" width="22px" height="22px" />
+						<span class="notification__title">任务</span>
+					</div>
+					<div class="img-container" :class="{ 'active': activeIndex === 3 }" @click="initNavigation"><img
+							src="@/assets/icons/img/init.png" class="notification__image" width="22px" height="22px" />
+						<span class="notification__title">初始化</span>
+					</div>
+					<div class="img-container" @click="restNavigation"><img src="@/assets/icons/img/restart.png"
+							class="notification__image" width="22px" height="22px" />
+						<span class="notification__title">重启</span>
+					</div>
+					<div class="img-container" @click="offNavigation"><img src="@/assets/icons/img/off.png"
+							class="notification__image" width="22px" height="22px" />
+						<span class="notification__title">结束</span>
+					</div>
+				</div>
+				<!-- 功能设置 -->
+				<div class="drawer" v-show="settingDrawer" style="width: 200px;">
+					<div style="position: relative;">
+						<p>点云</p>
+						<el-radio-group v-model="settingParams.pointCloud" size="mini">
+							<el-radio-button :label="true">开</el-radio-button>
+							<el-radio-button :label="false">关</el-radio-button>
+						</el-radio-group>
+						<p>底图</p>
+						<el-radio-group v-model="settingParams.baseMap" size="mini">
+							<el-radio-button :label="true">开</el-radio-button>
+							<el-radio-button :label="false">关</el-radio-button>
+						</el-radio-group>
+						<p>点ID</p>
+						<el-radio-group v-model="settingParams.pointId" size="mini">
+							<el-radio-button :label="true">开</el-radio-button>
+							<el-radio-button :label="false">关</el-radio-button>
+						</el-radio-group>
+						<p>位置跟随</p>
+						<el-radio-group v-model="settingParams.follow" size="mini">
+							<el-radio-button :label="true">开</el-radio-button>
+							<el-radio-button :label="false">关</el-radio-button>
+						</el-radio-group>
+						<p>网络邻居</p>
+						<el-radio-group v-model="settingParams.network" size="mini">
+							<el-radio-button :label="true">开</el-radio-button>
+							<el-radio-button :label="false">关</el-radio-button>
+						</el-radio-group>
+					</div>
+					<div class="drawer-close" @click="closeDra('hand')"><i class="el-icon-close"></i></div>
+				</div>
+				<!-- 目标点 -->
+				<div class="drawer" v-show="pointDrawer" style="width: 450px;">
+					<div style="position: relative;">
+						<div style="width: 100%;margin-bottom: 10px;">
+							<!-- <el-tooltip class="item" effect="dark" content="将点位显示在地图上" placement="top">
+								<el-button type="primary" icon="el-icon-search" size="mini" :disabled="multiple"></el-button>
+							</el-tooltip> -->
+							<el-tooltip class="item" effect="dark" content="上移" placement="top">
+								<el-button type="primary" icon="el-icon-top" size="mini" :disabled="single" @click="moveUp"></el-button>
+							</el-tooltip>
+							<el-tooltip class="item" effect="dark" content="下移" placement="top">
+								<el-button type="primary" icon="el-icon-bottom" size="mini" :disabled="single"
+									@click="moveDown"></el-button>
+							</el-tooltip>
+							<el-popconfirm title="批量删除选中点位数据?" @confirm="removePoint">
+								<el-button type="danger" icon="el-icon-delete" size="mini" :disabled="multiple" slot="reference"
+									style="margin-left: 10px;"></el-button>
+							</el-popconfirm>
+						</div>
+						<el-table ref="multipleTable" :data="pointList" tooltip-effect="dark" style="width: 100%" max-height="200px"
+							@selection-change="handleSelectionChange" border>
+							<el-table-column type="selection" width="45" align="center">
+							</el-table-column>
+							<el-table-column label="编号" width="60" show-overflow-tooltip align="center">
+								<template slot-scope="scope">{{ scope.row.id }}</template>
+							</el-table-column>
+							<el-table-column label="x坐标" width="90" show-overflow-tooltip align="center">
+								<template slot-scope="scope">{{ scope.row.x }}</template>
+							</el-table-column>
+							<el-table-column label="y坐标" width="90" show-overflow-tooltip align="center">
+								<template slot-scope="scope">{{ scope.row.y }}</template>
+							</el-table-column>
+							<el-table-column label="操作" show-overflow-tooltip align="center">
+								<template slot-scope="scope">
+									<el-button size="mini" type="text" icon="el-icon-edit" @click="editPoint(scope.row)"
+										style="margin-right: 10px;">编辑</el-button>
+									<el-popconfirm title="删除当前点位数据?" @confirm="removePoint(scope.row)">
+										<el-button size="mini" type="text" icon="el-icon-edit" slot="reference">删除</el-button>
+									</el-popconfirm>
+								</template>
+							</el-table-column>
+						</el-table>
+						<div style="width: 100%;margin-top: 10px;">
+							<el-button type="warning" icon="el-icon-caret-right" size="mini" :disabled="single" @click="goto">立即前往</el-button>
+							<el-button type="success" icon="el-icon-folder-add" size="mini" :disabled="multiple"
+								@click="taskGenerateDiaShow = true">生成任务</el-button>
+							<el-button type="success" icon="el-icon-thumb" size="mini" @click="mapSelectEle('open')"
+								v-if="!pointSelectionEnabled">地图选点模式</el-button>
+							<el-button type="danger" icon="el-icon-thumb" size="mini" @click="mapSelectEle('close')"
+								v-else>关闭选点模式</el-button>
+						</div>
+					</div>
+					<div class="drawer-close" @click="closeDra('hand')"><i class="el-icon-close"></i></div>
+				</div>
+				<!-- 任务 -->
+				<div class="drawer" v-if="taskDrawer" style="width: 300px;">
+					<div style="position: relative;">
+						<el-empty description="暂无创建的任务!" v-if="taskDataList.length < 1"></el-empty>
+						<el-collapse v-else>
+							<el-collapse-item v-for="(item, index) in taskDataList" :name="index" :key="item.taskId">
+								<template slot="title"><span>任务名:{{ item.taskName }}</span>
+									<el-tag type="info" v-if="item.status == 1" size="mini" class="task-status-tag">空闲中</el-tag><el-tag
+										type="success" v-else size="mini" class="task-status-tag">执行中</el-tag>
+								</template>
+								<div class="collapse-content-div">
+									<el-button type="danger" size="mini" icon="el-icon-delete"
+										@click="removeTaskItem(item)">删除</el-button>
+									<el-button type="warning" size="mini" icon="el-icon-view">查看</el-button>
+									<el-button type="success" size="mini" icon="el-icon-caret-right" :disabled="item.status == 0"
+										@click="executeTask(item)">执行</el-button>
+								</div>
+							</el-collapse-item>
+						</el-collapse>
+					</div>
+					<div class="drawer-close" @click="closeDra('hand')" style="right: 1px;top: 1px;"><i class="el-icon-close"></i>
+					</div>
+				</div>
+			</el-col>
+			<el-col :xs="23" :sm="23" :md="23" :lg="23" :xl="23">
+				<div class="main-content">
 					<!-- 当前操作类型标记 -->
 					<div class="hand-ment-mark">
 						<el-tag type="danger" effect="dark" size="mini" v-if="nowHandMenu">{{ nowHandMenu }}</el-tag>
@@ -533,6 +670,27 @@ export default {
 		}
 	},
 	methods: {
+		goto() {
+			// if (this.pointIds.length !== 1) {
+			// 	this.$message.warning('请选择一个点位进行前往操作');
+			// 	return;
+			// }
+			// const point = this.pointList.find(p => p.id === this.pointIds[0]);
+			// if (point) {
+			// 	console.log('前往点位:', point);
+			// 	this.$refs.mqtt.publish(this.$mqttPrefix + "/task/target/action/goto", {
+			// 			"timestamp" : 123456,
+			// 			"args"      : [
+			// 					{
+			// 							"roadmap" : this.mapName,
+			// 							"coord"   : [[Number(point.x), Number(point.y)]]
+			// 					}
+			// 			]
+			// 	},2,false);
+			// 	this.$refs.olmap.drawPoint()
+			// }
+			this.$refs.olmap.drawTrackLine(-15.491 , -57.526,10.209 , -123.223)
+		},
 		onMessage({ topic, message }) {
         // console.log("收到消息:", topic, message);
 				if (topic === this.$mqttPrefix + '/localization/action/init/reply') {
@@ -656,7 +814,8 @@ export default {
 							// 重置地图的id计数器
 							this.$refs.olmap.restIdNum();
 						}
-						this.$refs.olmap.removeIconHtmlById("pose-" + id);
+						// this.$refs.olmap.removeIconHtmlById("pose-" + id);
+						this.$refs.olmap.removeCalibrationById(id)
 					}
 				});
 			}
@@ -882,9 +1041,8 @@ export default {
 		 * @param angle 角度
 		 */
 		initNavigationResult(position, angle, nid) {
-			const prefix = process.env.VUE_APP_PNS_MQTT_PROXY;
 			let num = nid.split("_")[1];// 获取点位id编号
-			this.$refs.mqtt.publish(prefix + "/localization/action/init", {
+			this.$refs.mqtt.publish(this.$mqttPrefix + "/localization/action/init", {
 					"timestamp" : 123456,
 					"args"      : [
 							{"nid"  : Number(num)}
@@ -1491,7 +1649,7 @@ export default {
 };
 </script>
 
-<style scoped>
+<style scoped lang="scss">
 .point-edit-span {
 	display: block;
 	margin: 10px 0;