| | |
| | | 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.data.noflyzone.utils.NoFlyZoneUtils; |
| | | import com.ard.oss.model.MinioUploadResult; |
| | | import com.ard.oss.service.impl.OssServiceContext; |
| | | import com.ard.route.domain.UavRouteReq; |
| | | 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.sixhe.ArdRouteChange; |
| | | import com.ard.route.domain.vo.KmzInfoVo; |
| | | import com.ard.route.domain.vo.KmzResultVo; |
| | | import com.ard.route.mapper.ArdRouteInfoMapper; |
| | | import com.ard.route.service.IArdRouteInfoService; |
| | | import com.ard.route.service.UavRouteService; |
| | | import com.ard.work.domain.dto.state.PointData; |
| | | import com.ard.work.domain.dto.wayline.*; |
| | | import com.ard.work.service.ITyService; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.stereotype.Service; |
| | | import org.springframework.web.multipart.MultipartFile; |
| | |
| | | @Resource |
| | | private IArdNoFlyZoneService ardNoFlyZoneService; |
| | | |
| | | @Resource |
| | | private ITyService tyService; |
| | | |
| | | /** |
| | | * 查询航线(kmz) |
| | | * |
| | |
| | | public ArdRouteInfo selectArdRouteInfoById(String id) { |
| | | ArdRouteInfo ardRouteInfo = ardRouteInfoMapper.selectArdRouteInfoById(id); |
| | | try { |
| | | ardRouteInfo.setUavRouteReq((UavRouteReq) deserialize(ardRouteInfo.getRouteData())); |
| | | if (ardRouteInfo.getRouteData() != null){ |
| | | ardRouteInfo.setUavRouteReq((UavRouteReq) deserialize(ardRouteInfo.getRouteData())); |
| | | } |
| | | } catch (IOException | ClassNotFoundException e) { |
| | | throw new RuntimeException(e); |
| | | } |
| | |
| | | */ |
| | | @Override |
| | | public List<ArdRouteInfo> selectArdRouteInfoList(ArdRouteInfo ardRouteInfo) { |
| | | if ("1".equals(ardRouteInfo.getOrderByTime())) { |
| | | ardRouteInfo.setOrderByTime("DESC"); |
| | | }else if ("0".equals(ardRouteInfo.getOrderByTime())) { |
| | | ardRouteInfo.setOrderByTime("ASC"); |
| | | } |
| | | return ardRouteInfoMapper.selectArdRouteInfoList(ardRouteInfo); |
| | | } |
| | | |
| | |
| | | public String insertArdRouteInfo(ArdRouteInfo ardRouteInfo) { |
| | | ardRouteInfo.setId(IdUtils.simpleUUID()); |
| | | ardRouteInfo.setCreateTime(DateUtils.getNowDate()); |
| | | ardRouteInfo.setUpdateTime(DateUtils.getNowDate()); // 修改时间,用于排序 |
| | | if (ardRouteInfo.getGroupId() == null){ |
| | | ardRouteInfo.setGroupId("0"); |
| | | } |
| | |
| | | } catch (IOException e) { |
| | | throw new RuntimeException(e); |
| | | } |
| | | ardRouteInfo.getUavRouteReq().setDroneType(subStringDroneType(ardRouteInfo.getAircraft())); |
| | | ardRouteInfo.setRouteData(routeData); |
| | | KmzResultVo kmzResult = routeService.buildKmz(ardRouteInfo.getUavRouteReq(), ardRouteInfo.getName()); |
| | | ardRouteInfo.setPath(kmzResult.getPath()); |
| | | ardRouteInfo.setReadOnly("0"); |
| | | ardRouteInfo.setPointCount(getPointCount(ardRouteInfo)); |
| | | ardRouteInfoMapper.insertArdRouteInfo(ardRouteInfo); |
| | | return kmzResult.getPath(); |
| | | } |
| | |
| | | @Override |
| | | public int updateArdRouteInfo(ArdRouteInfo ardRouteInfo) { |
| | | ardRouteInfo.setUpdateTime(DateUtils.getNowDate()); |
| | | KmzResultVo kmzResult = new KmzResultVo(); |
| | | // 获取源文件名字 |
| | | ArdRouteInfo route = ardRouteInfoMapper.selectArdRouteInfoById(ardRouteInfo.getId()); |
| | | if (route.getName().equals(ardRouteInfo.getName())) { |
| | | kmzResult = routeService.updateKmz(ardRouteInfo.getUavRouteReq(), ardRouteInfo.getName()); |
| | | }else { |
| | | kmzResult = routeService.updateKmzNew(ardRouteInfo.getUavRouteReq(), route.getName(), ardRouteInfo.getName()); |
| | | // 判断生成kmz文件实体类是否为空,为空就修改航信信息,不修改行点信息。 |
| | | if (ardRouteInfo.getUavRouteReq() != null) { |
| | | KmzResultVo kmzResult; |
| | | // 获取源文件名字 |
| | | ArdRouteInfo route = ardRouteInfoMapper.selectArdRouteInfoById(ardRouteInfo.getId()); |
| | | if (route.getName().equals(ardRouteInfo.getName())) { |
| | | kmzResult = routeService.updateKmz(ardRouteInfo.getUavRouteReq(), ardRouteInfo.getName()); |
| | | }else { |
| | | kmzResult = routeService.updateKmzNew(ardRouteInfo.getUavRouteReq(), route.getName(), ardRouteInfo.getName()); |
| | | } |
| | | if ("更新航线kmz文件失败".equals(kmzResult.getData())) { |
| | | return 0; |
| | | } |
| | | ardRouteInfo.setPath(kmzResult.getPath()); |
| | | } |
| | | if ("更新航线kmz文件失败".equals(kmzResult.getData())) { |
| | | return 0; |
| | | } |
| | | ardRouteInfo.setPath(kmzResult.getPath()); |
| | | ardRouteInfo.setPointCount(getPointCount(ardRouteInfo)); |
| | | return ardRouteInfoMapper.updateArdRouteInfo(ardRouteInfo); |
| | | } |
| | | |
| | | private Integer getPointCount(ArdRouteInfo ardRouteInfo) { |
| | | if (ardRouteInfo.getUavRouteReq().getRoutePointList() != null) { |
| | | return ardRouteInfo.getUavRouteReq().getRoutePointList().size(); |
| | | } |
| | | return 0; |
| | | } |
| | | |
| | | /** |
| | |
| | | information.setName(file.getOriginalFilename()); |
| | | information.setPath(url); |
| | | information.setGroupId("0"); // 默认分组 |
| | | information.setReadOnly("1"); // 默认只读 |
| | | // 增加航线实体类信息 |
| | | insertRouteInfomation(information); |
| | | return MinioUploadResult.builder() |
| | | .url(url) |
| | |
| | | } |
| | | |
| | | /** |
| | | * 根据文件名称查询航线信息 |
| | | * 根据名称查询航线信息 |
| | | * |
| | | * @param name 文件名称 |
| | | * @return 结果 |
| | |
| | | * 修改航线分组ID |
| | | * |
| | | * @param id ID |
| | | * @param GroupId 分组ID |
| | | * @param groupId 分组ID |
| | | * @return 结果 |
| | | */ |
| | | @Override |
| | | public int updateRouteInfomationGroupId(String id, String GroupId) { |
| | | return ardRouteInfoMapper.updateRouteInforGroupId(id, GroupId); |
| | | public int updateRouteInfomationGroupId(String id, String groupId) { |
| | | return ardRouteInfoMapper.updateRouteInforGroupId(id, groupId); |
| | | } |
| | | |
| | | /** |
| | | * 判断行点是否在禁飞区 |
| | | * |
| | | * @param longitude 经度 |
| | | * @param latitude 纬度 |
| | | * @return 结果 |
| | | */ |
| | | @Override |
| | | public Boolean selectRouteInfomationNoFly(Double longitude, Double latitude) { |
| | | if (longitude == null || latitude == null) { |
| | | throw new ControlException("方法参数中未找到有效经纬度字段,无法判断禁飞区!"); |
| | | public Boolean selectRouteInfomationNoFly(ArdNoflyDto ardNoflyDto) { |
| | | return verifyNoFlyZone(ardNoflyDto); |
| | | } |
| | | |
| | | /** |
| | | * 上传航线到边缘服务器 |
| | | * |
| | | * ardNoflyDto |
| | | * @return 结果 |
| | | */ |
| | | @Override |
| | | public Boolean uploadRouteToSixHe(String id,String boxSn) { |
| | | // 1.获取航线信息 |
| | | // 1.1通过航线数据,转换。 |
| | | ArdRouteInfo route = ardRouteInfoMapper.selectArdRouteInfoById(id); |
| | | try { |
| | | route.setUavRouteReq((UavRouteReq) deserialize(route.getRouteData())); |
| | | } catch (IOException | ClassNotFoundException e) { |
| | | throw new RuntimeException(e); |
| | | } |
| | | List<ArdNoFlyZone> ardNoFlyZones = ardNoFlyZoneService.selectArdNoFlyZoneList(new ArdNoFlyZone()); |
| | | if (!ardNoFlyZones.isEmpty()) { |
| | | Vertex vertex = new Vertex(longitude, latitude); |
| | | // boolean inNoFlyZones = NoFlyZoneUtils.isPointInPolygon(vertex, ardNoFlyZones); |
| | | // if (inNoFlyZones) { |
| | | // throw new ControlException("目标点在禁飞区内,无法执行操作!"); |
| | | // } |
| | | } |
| | | // 1.2通过minio获取航线信息 |
| | | // 2.将航线信息转换成对应实体类 |
| | | WayLineUploadDTO wayLineUploadDTO = buildWayLineUploadDTO(route); |
| | | wayLineUploadDTO.setBoxSn(boxSn); |
| | | // 3.调用接口 |
| | | tyService.wayLineUpload(wayLineUploadDTO); |
| | | return true; |
| | | } |
| | | |
| | | /** |
| | | * 开始航线 |
| | | * |
| | | * @param boxSn 云盒SN编号 |
| | | * @return 结果 |
| | | */ |
| | | @Override |
| | | public Boolean routeBegins(String boxSn) { |
| | | WayLineBeginDTO wayLineBeginDTO = new WayLineBeginDTO(boxSn); |
| | | tyService.wayLineBegin(wayLineBeginDTO); |
| | | return true; |
| | | } |
| | | |
| | | /** |
| | | * 暂停航线 |
| | | * |
| | | * @param boxSn 云盒SN编号 |
| | | * @return 结果 |
| | | */ |
| | | @Override |
| | | public Boolean routeSuspension(String boxSn) { |
| | | WayLinePauseDTO wayLinePauseDTO = new WayLinePauseDTO(boxSn); |
| | | tyService.wayLinePause(wayLinePauseDTO); |
| | | return true; |
| | | } |
| | | |
| | | /** |
| | | * 恢复航线 |
| | | * |
| | | * @param boxSn 云盒SN编号 |
| | | * @return 结果 |
| | | */ |
| | | @Override |
| | | public Boolean routeResumption(String boxSn) { |
| | | WayLineResumeDTO wayLineResumeDTO = new WayLineResumeDTO(boxSn); |
| | | tyService.wayLineResume(wayLineResumeDTO); |
| | | return true; |
| | | } |
| | | |
| | | /** |
| | | * 结束航线 |
| | | * |
| | | * @param boxSn 云盒SN编号 |
| | | * @return 结果 |
| | | */ |
| | | @Override |
| | | public Boolean routeEnd(String boxSn) { |
| | | 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; |
| | | |
| | | } |
| | | |
| | | /** |
| | |
| | | ardRouteInfoMapper.insertArdRouteInfo(ardRouteInfo); |
| | | } |
| | | |
| | | /** |
| | | * 判断行点是否在禁飞区 |
| | | * 原点 current 第一个节点 |
| | | * 目标点 target 第二个节点 |
| | | */ |
| | | private Boolean verifyNoFlyZone(ArdNoflyDto ardNoflyDto){ |
| | | // ③ 查询禁飞区 |
| | | List<ArdNoFlyZone> zones = ardNoFlyZoneService.selectArdNoFlyZoneList(new ArdNoFlyZone()); |
| | | if (zones.isEmpty()) { |
| | | return true; |
| | | } |
| | | for (ArdNoFlyZone zone : zones) { |
| | | List<Vertex> polygon = zone.getVertices(); |
| | | if (polygon == null || polygon.size() < 3) continue; |
| | | |
| | | // 检查目标点是否在禁飞区 |
| | | if (NoFlyZoneUtils.isPointInPolygon(ardNoflyDto.getTarget(), polygon)) { |
| | | throw new ControlException("目标点在禁飞区【" + zone.getName() + "】内,无法执行操作!"); |
| | | } |
| | | |
| | | // 检查路径是否穿越禁飞区 |
| | | if (ardNoflyDto.getCurrent() != null && NoFlyZoneUtils.isLineIntersectPolygon(ardNoflyDto.getCurrent(), ardNoflyDto.getTarget(), polygon)) { |
| | | throw new ControlException("路径穿越禁飞区【" + zone.getName() + "】,无法执行操作!"); |
| | | } |
| | | } |
| | | return true; |
| | | } |
| | | |
| | | } |