From 5ea2094378f25a3f98d8f370dafaf9367c05c2e5 Mon Sep 17 00:00:00 2001
From: Xiajijian <1176061145@qq.com>
Date: Thu, 05 Feb 2026 09:06:39 +0800
Subject: [PATCH] 1. 增加任务航线websocket。 2. 增加执行人id信息,下发人id信息。

---
 ard-route/src/main/java/com/ard/route/service/impl/ArdRouteInfoServiceImpl.java |  364 +++++++++++++++++++++++++++------------------------
 1 files changed, 191 insertions(+), 173 deletions(-)

diff --git a/ard-route/src/main/java/com/ard/route/service/impl/ArdRouteInfoServiceImpl.java b/ard-route/src/main/java/com/ard/route/service/impl/ArdRouteInfoServiceImpl.java
index b48775c..f6859f7 100644
--- a/ard-route/src/main/java/com/ard/route/service/impl/ArdRouteInfoServiceImpl.java
+++ b/ard-route/src/main/java/com/ard/route/service/impl/ArdRouteInfoServiceImpl.java
@@ -1,41 +1,47 @@
 package com.ard.route.service.impl;
 
 import java.io.IOException;
-import java.util.ArrayList;
 import java.util.List;
 
 import com.ard.common.exception.ControlException;
 import com.ard.common.utils.DateUtils;
+import com.ard.common.utils.SecurityUtils;
 import com.ard.common.utils.file.FileUtils;
 import com.ard.common.utils.uuid.IdUtils;
 import com.ard.data.noflyzone.domain.ArdNoFlyZone;
 import com.ard.data.noflyzone.domain.Vertex;
 import com.ard.data.noflyzone.service.IArdNoFlyZoneService;
 import com.ard.data.noflyzone.utils.NoFlyZoneUtils;
+import com.ard.framework.web.service.TokenService;
 import com.ard.oss.model.MinioUploadResult;
 import com.ard.oss.service.impl.OssServiceContext;
-import com.ard.ossdock.service.impl.OssDockServiceContext;
 import com.ard.route.domain.djuav.ActionGroupReq;
 import com.ard.route.domain.djuav.PointActionReq;
 import com.ard.route.domain.djuav.RoutePointReq;
 import com.ard.route.domain.djuav.UavRouteReq;
 import com.ard.route.domain.dto.ArdNoflyDto;
 import com.ard.route.domain.route.ArdRouteInfo;
+import com.ard.route.domain.route.ArdRouteMission;
 import com.ard.route.domain.vo.KmzResultVo;
 import com.ard.route.mapper.ArdRouteInfoMapper;
+import com.ard.route.mapper.ArdRouteMissionMapper;
 import com.ard.route.service.IArdRouteInfoService;
 import com.ard.route.service.UavRouteService;
+import com.ard.work.domain.cache.UavTelemetryDataCache;
 import com.ard.work.domain.cache.UavWaylineCache;
-import com.ard.work.domain.dto.state.PointData;
+import com.ard.work.domain.dto.telemetry.TelemetryData;
 import com.ard.work.domain.dto.wayline.*;
 import com.ard.work.service.ITyService;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 import org.springframework.web.multipart.MultipartFile;
-
 import javax.annotation.Resource;
-
+import static com.ard.route.enums.kml.DroneEnumValueEnums.M350_RTK;
+import static com.ard.route.util.InitializationUtils.divided_23;
 import static com.ard.route.util.ToolUtils.*;
+import static com.ard.route.util.UavRouteReqUtils.buildWayLineUploadDTO;
 import static com.ard.route.util.UavRouteReqUtils.fileConversionEntity;
 
 /**
@@ -47,6 +53,8 @@
 @Service
 public class ArdRouteInfoServiceImpl implements IArdRouteInfoService {
 
+    private static final Logger log = LoggerFactory.getLogger(TokenService.class);
+
     @Autowired
     private ArdRouteInfoMapper ardRouteInfoMapper;
 
@@ -54,10 +62,10 @@
     private OssServiceContext ossService;
 
     @Autowired
-    private OssDockServiceContext ossDockService;
+    private UavRouteService routeService;
 
     @Autowired
-    private UavRouteService routeService;
+    private ArdRouteMissionMapper ardRouteMissionMapper;
 
     @Resource
     private IArdNoFlyZoneService ardNoFlyZoneService;
@@ -75,13 +83,35 @@
     public ArdRouteInfo selectArdRouteInfoById(String id) {
         ArdRouteInfo ardRouteInfo = ardRouteInfoMapper.selectArdRouteInfoById(id);
         try {
-            if (ardRouteInfo.getRouteData() != null){
-                ardRouteInfo.setUavRouteReq((UavRouteReq) deserialize(ardRouteInfo.getRouteData()));
+            if (ardRouteInfo != null) {
+                if (ardRouteInfo.getRouteData() != null){
+                    ardRouteInfo.setUavRouteReq((UavRouteReq) deserialize(ardRouteInfo.getRouteData()));
+                }
             }
         } catch (IOException | ClassNotFoundException e) {
             throw new RuntimeException(e);
         }
+
+        // 如果参考起飞点不为空,将每个航点高度进行加工。
+        if (ardRouteInfo.getUavRouteReq().getTakeOffRefPoint() != null){
+            double altitudeOffset = getDoublePoint(ardRouteInfo.getUavRouteReq().getTakeOffRefPoint(), "alt");
+            for (RoutePointReq routePointReq : ardRouteInfo.getUavRouteReq().getRoutePointList()) {
+                adjustRoutePointHeight(routePointReq, altitudeOffset);
+            }
+        }else {
+            // 如果没有设置参考起飞点,将第一个航点设置为参考起飞点。
+            ardRouteInfo.getUavRouteReq().setTakeOffRefPoint(
+                    ardRouteInfo.getUavRouteReq().getRoutePointList().get(0).getLatitude().toString() +"," +
+                    ardRouteInfo.getUavRouteReq().getRoutePointList().get(0).getLongitude().toString()+","+
+                    ardRouteInfo.getUavRouteReq().getRoutePointList().get(0).getHeight().toString());
+        }
+
         return ardRouteInfo;
+    }
+
+    // 调整每个航点高度
+    private void adjustRoutePointHeight(RoutePointReq routePointReq, double altitudeOffset) {
+        routePointReq.setHeight(routePointReq.getHeight() + altitudeOffset);
     }
 
     /**
@@ -108,6 +138,8 @@
      */
     @Override
     public String insertArdRouteInfo(ArdRouteInfo ardRouteInfo) {
+        checkRouteMissionStatus(ardRouteInfo,"1");
+        checkRouteMissionStatus(ardRouteInfo,"2");
         ardRouteInfo.setId(IdUtils.simpleUUID());
         ardRouteInfo.setCreateTime(DateUtils.getNowDate());
         ardRouteInfo.setUpdateTime(DateUtils.getNowDate()); // 修改时间,用于排序
@@ -115,11 +147,62 @@
             ardRouteInfo.setGroupId("0");
         }
         ardRouteInfo.getUavRouteReq().setDroneType(subStringDroneType(ardRouteInfo.getAircraft()));
-        KmzResultVo kmzResult = routeService.buildKmz(ardRouteInfo.getUavRouteReq(), ardRouteInfo.getName());
+        KmzResultVo kmzResult = routeService.buildKmz(ardRouteInfo.getUavRouteReq(),ardRouteInfo.getName());
+        zoomProcessing(ardRouteInfo);
         ardRouteInfo.setPath(kmzResult.getPath());
         ardRouteInfo.setReadOnly("0");
         ardRouteInfoMapper.insertArdRouteInfo(dataProcessing(ardRouteInfo));
         return kmzResult.getPath();
+    }
+
+    /**
+     * 航线任务数据加工校验
+     * 1.新建航线时,判断航线任务是否已完成
+     * 2.新建航线时,对航线任务数据进行加工
+     * 3.执行航线的时,修改航线任务表执行状态
+     */
+    private void checkRouteMissionStatus(ArdRouteInfo ardRouteInfo,String type){
+        ArdRouteMission mission = ardRouteMissionMapper.selectArdRouteMissionById(ardRouteInfo.getMissionId());
+        if (mission != null){
+            switch(type){
+                case "1":
+                    validateForCreate(mission);
+                    break;
+                case "2":
+                    bindRoute(mission,ardRouteInfo);
+                    break;
+                case "3":
+                    executeMission(mission,ardRouteInfo);
+                    break;
+                default:
+                    throw new RuntimeException("不支持的操作类型!!!");
+            }
+        }
+    }
+
+    private void validateForCreate(ArdRouteMission mission) {
+        if ("1".equals(mission.getExecuteStatus())){
+            throw new RuntimeException("航线任务已完成,无法创建航线!!!");
+        }
+    }
+
+    private void bindRoute(ArdRouteMission mission, ArdRouteInfo routeInfo) {
+        if (mission.getRouteId() != null) {
+            throw new RuntimeException("航线任务下已绑定航线,不可创建新航线信息!!!");
+        }
+        mission.setRouteId(routeInfo.getId());
+        ardRouteMissionMapper.updateArdRouteMission(mission);
+    }
+
+    private void executeMission(ArdRouteMission mission,ArdRouteInfo ardRouteInfo) {
+        if ("0".equals(mission.getExecuteStatus())) {
+            mission.setRouteId(ardRouteInfo.getId());
+            mission.setExecuteStatus("1");
+            mission.setExecuteName(SecurityUtils.getUsername());
+            mission.setExecuteTime(DateUtils.getNowDate());
+            mission.setUpdateTime(DateUtils.getNowDate());
+            ardRouteMissionMapper.updateArdRouteMission(mission);
+        }
     }
 
     /**
@@ -139,14 +222,31 @@
             // 先删除航线
             delOssService(route);
             // 再生成航线
+            ardRouteInfo.getUavRouteReq().setDroneType(subStringDroneType(ardRouteInfo.getAircraft()));
+            zoomProcessing(ardRouteInfo);
             kmzResult = routeService.buildKmz(ardRouteInfo.getUavRouteReq(), ardRouteInfo.getName());
             if ("更新航线kmz文件失败".equals(kmzResult.getData())) {
                 return 0;
             }
             ardRouteInfo.setPath(kmzResult.getPath());
         }
-        ardRouteInfo.setReadOnly("0");
         return ardRouteInfoMapper.updateArdRouteInfo(dataProcessing(ardRouteInfo));
+    }
+
+    // 变倍加工方法
+    private void zoomProcessing(ArdRouteInfo ardRouteInfo) {
+        if (M350_RTK.getValue().equals(ardRouteInfo.getUavRouteReq().getDroneType())) {
+            // 变焦数值加工
+            for (RoutePointReq routePointReq : ardRouteInfo.getUavRouteReq().getRoutePointList()) {
+                for (ActionGroupReq actionGroupReq : routePointReq.getActionGroupList()) {
+                    for (PointActionReq action : actionGroupReq.getActions()) {
+                        if (action.getZoom() != null){
+                            action.setZoom(divided_23(action.getZoom()));
+                        }
+                    }
+                }
+            }
+        }
     }
 
     // 新增信息加工
@@ -196,9 +296,6 @@
         if (information.getPath() != null){
             ossService.deleteObject("kmz", subStringMinioUrlName(information.getPath()));
         }
-        if (information.getPath1() != null){
-            ossDockService.deleteObject("kmz", subStringMinioUrlName(information.getPath1()));
-        }
     }
 
     /**
@@ -209,6 +306,9 @@
      */
     @Override
     public int deleteArdRouteInfoById(String id) {
+        // 删除航线(kmz)文件
+        ArdRouteInfo information = ardRouteInfoMapper.selectArdRouteInfoById(id);
+        delOssService(information);
         return ardRouteInfoMapper.deleteArdRouteInfoById(id);
     }
 
@@ -221,29 +321,55 @@
     @Override
     public MinioUploadResult uploadArdRouteInfo(MultipartFile file) {
         try {
-            String url = ossService.upload("kmz",file);
-            String urlDock = ossDockService.upload("kmz",file);
-            ArdRouteInfo information = new ArdRouteInfo();
-            information.setName(file.getOriginalFilename());
-            information.setPath(url);
-            information.setPath1(urlDock);
-            information.setGroupId("0");     // 默认分组
-            information.setReadOnly("1");   // 默认只读
             // 增加航线实体类信息
             UavRouteReq uavRouteReq = fileConversionEntity(file);
+            ArdRouteInfo ardRouteInfo = new ArdRouteInfo();
             if (uavRouteReq != null){
-                information.setUavRouteReq(uavRouteReq);
-                information.setType(templateTypeData(uavRouteReq));
-                information.setAircraft(droneTypeData(uavRouteReq));
+                ardRouteInfo.setUavRouteReq(uavRouteReq);
+                ardRouteInfo.setType(templateTypeData(uavRouteReq));
+                ardRouteInfo.setAircraft(droneTypeData(uavRouteReq));
             }
-            insertRouteInfomation(information);
+            String url = ossService.upload("kmz",file);
+            ardRouteInfo.setName(file.getOriginalFilename());
+            ardRouteInfo.setPath(url);
+            ardRouteInfo.setGroupId("0");     // 默认分组
+            ardRouteInfo.setReadOnly("1");   // 默认只读
+            insertRouteInfomation(ardRouteInfo);
             return MinioUploadResult.builder()
                     .url(url)
                     .newFileName(FileUtils.getName(url))
                     .originalFilename(file.getOriginalFilename())
                     .build();
         }catch (Exception e){
+            log.error("上传航线文件失败", e);
             return null;
+        }
+    }
+
+    /**
+     * 判断一组数组,是否包含禁飞区
+     */
+    private void arrayWithinNoFlyZone(List<RoutePointReq> routePointList) {
+        if (routePointList == null || routePointList.isEmpty()) {
+            return;
+        }
+        // 检查第一个航点
+        ArdNoflyDto firstDto = new ArdNoflyDto();
+        firstDto.setTarget(new Vertex(
+                routePointList.get(0).getLongitude(),
+                routePointList.get(0).getLatitude()));
+        verifyNoFlyZone(firstDto);
+
+        // 检查后续航点及与前一个航点的线段
+        for (int i = 1; i < routePointList.size(); i++) {
+            ArdNoflyDto dto = new ArdNoflyDto();
+            dto.setCurrent(new Vertex(
+                    routePointList.get(i - 1).getLongitude(),
+                    routePointList.get(i - 1).getLatitude()));
+            dto.setTarget(new Vertex(
+                    routePointList.get(i).getLongitude(),
+                    routePointList.get(i).getLatitude()));
+            verifyNoFlyZone(dto);
         }
     }
 
@@ -281,7 +407,6 @@
 
     /**
      * 上传航线到边缘服务器
-     *
      * ardNoflyDto
      * @return 结果
      */
@@ -295,6 +420,36 @@
         } catch (IOException | ClassNotFoundException e) {
             throw new RuntimeException(e);
         }
+
+        // 获取第一个点
+        double firstPointLng = route.getUavRouteReq().getRoutePointList().get(0).getLongitude();
+        double firstPointLat = route.getUavRouteReq().getRoutePointList().get(0).getLatitude();
+
+        // 获取最后一个点
+        double lastPointLng = route.getUavRouteReq().getRoutePointList().get(route.getUavRouteReq().getRoutePointList().size()-1).getLongitude();
+        double lastPointLat = route.getUavRouteReq().getRoutePointList().get(route.getUavRouteReq().getRoutePointList().size()-1).getLatitude();
+
+        // 无人机遥测数据,用于校验真实起飞点和第一个点是否在禁飞区
+        TelemetryData telemetryData = UavTelemetryDataCache.get(boxSn);
+        double telemetryDataLng = 0;
+        double telemetryDataLat = 0;
+        if (telemetryData != null){
+            telemetryDataLng = telemetryData.getLng();
+            telemetryDataLat = telemetryData.getLat();
+        }
+
+        ArdNoflyDto dto1 = new ArdNoflyDto();
+        dto1.setCurrent(new Vertex(telemetryDataLng,telemetryDataLat));
+        dto1.setTarget(new Vertex(firstPointLng,firstPointLat));
+        verifyNoFlyZone(dto1);
+
+        ArdNoflyDto dto2 = new ArdNoflyDto();
+        dto2.setCurrent(new Vertex(lastPointLng,lastPointLat));
+        dto2.setTarget(new Vertex(telemetryDataLng,telemetryDataLat));
+        verifyNoFlyZone(dto2);
+
+        // 判断禁飞区
+        arrayWithinNoFlyZone(route.getUavRouteReq().getRoutePointList());
         // 1.2通过minio获取航线信息
         // 2.将航线信息转换成对应实体类
         WayLineUploadDTO wayLineUploadDTO = buildWayLineUploadDTO(route);
@@ -316,7 +471,15 @@
      * @return 结果
      */
     @Override
-    public Boolean routeBegins(String boxSn) {
+    public Boolean routeBegins(String id,String boxSn) {
+        ArdRouteInfo route = ardRouteInfoMapper.selectArdRouteInfoById(id);
+        if (null != route){
+            // 判断是否循环航线
+            if ("0".equals(route.getIsLoop())){
+                deleteArdRouteInfoById(id);
+            }
+            checkRouteMissionStatus(route,"3");
+        }
         WayLineBeginDTO wayLineBeginDTO = new WayLineBeginDTO(boxSn);
         tyService.wayLineBegin(wayLineBeginDTO);
         return true;
@@ -359,151 +522,6 @@
         WayLineEndDTO wayLineEndDTO = new WayLineEndDTO(boxSn);
         tyService.wayLineEnd(wayLineEndDTO);
         return true;
-    }
-
-    /**
-     * ArdRouteInfo实体转换,WayLineUploadDTO
-     */
-    private WayLineUploadDTO buildWayLineUploadDTO(ArdRouteInfo ardRouteInfo){
-        WayLineUploadDTO wayLineUploadDTO = new WayLineUploadDTO();
-        String finishAction = ardRouteInfo.getUavRouteReq().getFinishAction(); //1
-        Double autoFlightSpeed = ardRouteInfo.getUavRouteReq().getAutoFlightSpeed(); //15
-        Double globalTransitionalSpeed = ardRouteInfo.getUavRouteReq().getGlobalTransitionalSpeed(); //8
-        String exitOnRcLostAction = ardRouteInfo.getUavRouteReq().getExitOnRcLostAction();  //0
-
-        PlanLineData planLineData = new PlanLineData();
-        if (finishAction != null){
-            planLineData.setLoseAction(0);
-        }
-        if (autoFlightSpeed != null){
-            planLineData.setAutoSpeed(8);
-        }
-        planLineData.setMaxSpeed(15);
-//        if (globalTransitionalSpeed != null){
-//            planLineData.setMaxSpeed(15);
-//        }
-        if (exitOnRcLostAction != null){
-            planLineData.setFinishedAction(1);
-        }
-        planLineData.setHomeHeight(50);
-        planLineData.setInterests(new ArrayList<>());
-        planLineData.setIsSaveEnergyMode(0);
-        planLineData.setPoints(buildPointDataList(ardRouteInfo.getUavRouteReq()));
-
-        wayLineUploadDTO.setWayLineData(planLineData);
-        return wayLineUploadDTO;
-    }
-
-    private List<PointData> buildPointDataList(UavRouteReq uavRouteReq){
-        List<PointData> pointDataList = new ArrayList<>();
-        for (RoutePointReq routePointReq : uavRouteReq.getRoutePointList()) {
-            PointData pointData = new PointData();
-
-            Integer routePointIndex = routePointReq.getRoutePointIndex();
-            if (routePointIndex != null){
-                pointData.setGroupIndex(routePointIndex);
-            }
-            Double height = routePointReq.getHeight();
-            if (height != null){
-                pointData.setHeight(height.floatValue());
-            }
-            Double longitude = routePointReq.getLongitude();
-            if (longitude != null){
-                pointData.setLng(longitude.floatValue());
-            }
-            Double latitude = routePointReq.getLatitude();
-            if (latitude != null){
-                pointData.setLat(latitude.floatValue());
-            }
-            Double speed = routePointReq.getSpeed();
-            if (speed != null){
-                pointData.setSpeed(speed.floatValue());
-            }
-            pointData.setDampingDistance(0);
-            pointData.setFlightPathMode(1);
-            pointData.setHeading(0);
-            pointData.setHeadingMode(0);
-            pointData.setInterestIndex(-1);
-            pointData.setSafeGohomeFlag(0);
-            pointData.setActions(buildPointActionList(routePointReq.getActionGroupList()));
-            pointDataList.add(pointData);
-
-        }
-        return pointDataList;
-    }
-
-    private List<PointAction> buildPointActionList(List<ActionGroupReq> actionGroupList){
-        List<PointAction> pointActionList = new ArrayList<>();
-        for (ActionGroupReq actionGroupReq : actionGroupList) {
-            for (PointActionReq action : actionGroupReq.getActions()) {
-                PointAction pointAction = typeProcessing(action);
-                pointActionList.add(pointAction);
-            }
-        }
-        return pointActionList;
-    }
-
-    private PointAction typeProcessing(PointActionReq pointActionReq){
-        PointAction pointAction = new PointAction();
-
-        if (pointActionReq.getZoom() != null){
-            pointAction.setType(1);
-            pointAction.setParam(pointActionReq.getZoom().floatValue());
-            pointAction.setSpeakInfo("");
-            pointAction.setWaitTime(2);
-        }
-
-        if (pointActionReq.getTakePhotoType() != null){
-            pointAction.setType(2);
-            pointAction.setParam(1);
-            pointAction.setSpeakInfo("");
-            pointAction.setWaitTime(2);
-        }
-
-        if (pointActionReq.getStartRecord() != null){
-            pointAction.setType(3);
-            pointAction.setParam(1);
-            pointAction.setSpeakInfo("");
-            pointAction.setWaitTime(2);
-        }
-
-        if (pointActionReq.getStopRecord() != null){
-            pointAction.setType(4);
-            pointAction.setParam(1);
-            pointAction.setSpeakInfo("");
-            pointAction.setWaitTime(2);
-        }
-
-        if (pointActionReq.getAircraftHeading() != null){
-            pointAction.setType(5);
-            pointAction.setParam(pointActionReq.getAircraftHeading().floatValue());
-            pointAction.setSpeakInfo("");
-            pointAction.setWaitTime(2);
-        }
-
-        if (pointActionReq.getGimbalPitchRotateAngle() != null){
-            pointAction.setType(6);
-            pointAction.setParam(pointActionReq.getGimbalPitchRotateAngle().floatValue());
-            pointAction.setSpeakInfo("");
-            pointAction.setWaitTime(2);
-        }
-
-        if (pointActionReq.getGimbalYawRotateAngle() != null){
-            pointAction.setType(7);
-            pointAction.setParam(pointActionReq.getGimbalYawRotateAngle().floatValue());
-            pointAction.setSpeakInfo("");
-            pointAction.setWaitTime(2);
-        }
-
-        if (pointActionReq.getHoverTime() != null){
-            pointAction.setType(9);
-            pointAction.setParam(pointActionReq.getHoverTime().floatValue());
-            pointAction.setSpeakInfo("");
-            pointAction.setWaitTime(2);
-        }
-
-        return pointAction;
-
     }
 
     /**

--
Gitblit v1.9.3