package com.dji.sample.patches.utils;
|
|
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
import com.dji.sample.common.model.CustomClaim;
|
import com.dji.sample.common.model.ResponseResult;
|
import com.dji.sample.media.dao.IFileMapper;
|
import com.dji.sample.media.model.MediaFileEntity;
|
import com.dji.sample.patches.config.pojo.PatchesConfigPojo;
|
import com.dji.sample.patches.dao.ShpToDataSourceMapper;
|
import com.dji.sample.patches.model.entity.LotInfo;
|
import com.dji.sample.patches.service.GetPatchesService;
|
import com.dji.sample.patches.xml.mode.XMLTemplateModel;
|
import com.dji.sample.patches.xml.utils.CreateWaylineFileUtils;
|
import com.dji.sample.territory.pojo.TerritoryConfigPojo;
|
import com.dji.sample.territory.service.ITbFJService;
|
import com.dji.sample.wayline.model.entity.WaylineFileEntity;
|
import com.dji.sample.wayline.model.param.CreateJobParam;
|
import com.dji.sample.wayline.service.IWaylineFileService;
|
import com.dji.sample.wayline.service.IWaylineJobService;
|
|
import com.fasterxml.jackson.core.JsonProcessingException;
|
import com.fasterxml.jackson.databind.JsonNode;
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
import com.fasterxml.jackson.databind.node.ObjectNode;
|
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.core.io.ByteArrayResource;
|
import org.springframework.http.*;
|
import org.springframework.scheduling.annotation.Scheduled;
|
import org.springframework.stereotype.Component;
|
import org.springframework.transaction.annotation.Transactional;
|
import org.springframework.util.LinkedMultiValueMap;
|
import org.springframework.util.MultiValueMap;
|
import org.springframework.web.client.RestTemplate;
|
import org.springframework.web.multipart.MultipartFile;
|
import org.springframework.web.util.UriComponentsBuilder;
|
|
import javax.xml.transform.Result;
|
import java.nio.file.StandardCopyOption;
|
import java.time.LocalDateTime;
|
|
import java.io.*;
|
import java.net.HttpURLConnection;
|
import java.net.URL;
|
import java.nio.charset.StandardCharsets;
|
import java.nio.file.Files;
|
import java.nio.file.Path;
|
import java.nio.file.Paths;
|
import java.sql.SQLException;
|
import java.time.format.DateTimeFormatter;
|
import java.util.ArrayList;
|
import java.util.HashMap;
|
import java.util.List;
|
import java.util.Map;
|
import java.util.concurrent.ExecutorService;
|
import java.util.concurrent.Executors;
|
import java.util.concurrent.Future;
|
import java.util.stream.Collectors;
|
|
import static com.dji.sample.patches.utils.MultipartFileTOFileUtil.convert;
|
import static com.dji.sample.patches.utils.ZipUtil.zipFolder;
|
import static com.dji.sample.wayline.model.enums.WaylineTaskTypeEnum.TIMED;
|
import static com.dji.sample.wayline.model.enums.WaylineTemplateTypeEnum.WAYPOINT;
|
|
@Component
|
public class TimerUtil {
|
@Autowired
|
private ShpToDataSourceMapper shpToDataSourceMapper;
|
@Autowired
|
private PatchesConfigPojo patchesConfigPojo;
|
@Autowired
|
public IWaylineFileService waylineFileService;
|
@Autowired
|
private IFileMapper fileMapper;
|
@Autowired
|
private ITbFJService tbFJService;
|
@Autowired
|
private GetPatchesService getPatchesService;
|
@Autowired
|
private IWaylineJobService waylineJobService;
|
@Autowired
|
private TerritoryConfigPojo territoryConfigPojo;
|
|
|
/**
|
* 定时器,将没有规划的图斑生成航线,并将航线飞完后的成果数据进行保存推送
|
*
|
* @throws IOException
|
* @throws SQLException
|
*/
|
@Scheduled(cron = "0 0 0 * * ?")
|
public void myTask() throws Exception {
|
String taskId = "";
|
String workspaceId = "4a574db8-4ad3-48f7-9f16-3edbcd8056e1";
|
// 获取未规划的图斑集合
|
List<List<LotInfo>> lists = getNoPlan();
|
List<List<LotInfo>> convertedLists = convertToLists(lists);
|
for (List<LotInfo> list : convertedLists) {
|
long timestamp = System.currentTimeMillis();
|
String waylineName = "云飞行调查" + timestamp;
|
//根据获取的图斑集合获得kmz航线文件
|
MultipartFile multipartFile = null;
|
try {
|
multipartFile = getFile(waylineName, list);
|
} catch (IOException e) {
|
throw new RuntimeException(e);
|
}
|
//上传航线文件
|
backWayline(multipartFile, waylineName, workspaceId, backclaim().getUsername());
|
//将为规划的图斑状态更新为已规划
|
updatePatchesStatu(list);
|
// waylineJobService.publishFlightTask(JobParam("656c62f4-cb86-4911-930d-b38089829348"),backclaim());
|
}
|
|
}
|
|
@Scheduled(cron = "0 0 0 * * ?")
|
public void myTask2() {
|
ExecutorService executor = Executors.newSingleThreadExecutor();
|
executor.execute(() -> {
|
try {
|
dbOperation();
|
} catch (Exception e) {
|
throw new RuntimeException(e);
|
}
|
});
|
executor.shutdown();
|
}
|
|
@Transactional
|
public void dbOperation() throws Exception {
|
String workspaceId = "4a574db8-4ad3-48f7-9f16-3edbcd8056e1";
|
String taskId = "";
|
List<List<MediaFileEntity>> list = getNoadd();
|
List<List<MediaFileEntity>> medias = convertToLists(list);
|
for (List<MediaFileEntity> media : medias) {
|
//清空FJ表
|
tbFJService.deleteData();
|
for (MediaFileEntity mediaFile : media) {
|
//获取媒体文件名里的dkbh和taskId
|
String dkbh = getDkbh(mediaFile.getFileName());
|
taskId = getTaskId(mediaFile.getFileName());
|
//获取该媒体文件的图斑信息
|
LotInfo lotInfo = getPatchesService.getLotinfo(dkbh, workspaceId);
|
tbFJService.insertOneData(mediaFile, lotInfo);
|
//更新媒体文件的是否添加状态
|
updateMediaStatu(mediaFile);
|
}
|
//发送请求给第三方接口
|
sendPostWithFileAndParameter(territoryConfigPojo.getResult(), taskId);
|
//存储db到服务器
|
dbSave(territoryConfigPojo.getResult(), territoryConfigPojo.getResultsave(), taskId);
|
}
|
}
|
|
/**
|
* 创建航线
|
*
|
* @param waylineName
|
* @param list
|
* @return
|
* @throws IOException
|
*/
|
public MultipartFile getFile(String waylineName, List<LotInfo> list) throws IOException {
|
List<PointPO> coordinates = GeoToolsUtil.getRoutePointOrder(list, 28.62452712442823, 115.85666327144976);
|
XMLTemplateModel xmlModel = XMLTemplateModel.init(coordinates, list);
|
CreateWaylineFileUtils.createWaylineFile(xmlModel, patchesConfigPojo.getTemplate(), patchesConfigPojo.getTargetTemplate(), patchesConfigPojo.getWaylines(), patchesConfigPojo.getTargetWaylines());
|
// 压缩文件夹中的内容
|
String destKMZFile = patchesConfigPojo.getDestKMZFile() + waylineName + ".kmz"; // 输出的KMZ文件路径
|
zipFolder(patchesConfigPojo.getSourceDir(), destKMZFile);
|
return convert(new File(destKMZFile));
|
}
|
|
/**
|
* 将航线上传Oss
|
*
|
* @param multipartFile
|
* @param waylineName
|
* @param workspaceId
|
* @param username
|
* @return
|
*/
|
public String backWayline(MultipartFile multipartFile, String waylineName, String workspaceId, String username) {
|
waylineFileService.importKmzFile(multipartFile, workspaceId, username);
|
WaylineFileEntity entity = waylineFileService.selectByName(waylineName);
|
try {
|
waylineFileService.getObjectUrl(workspaceId, entity.getWaylineId());
|
} catch (SQLException e) {
|
throw new RuntimeException(e);
|
}
|
return entity.getWaylineId();
|
}
|
|
/**
|
* 获取未规划的图斑集合
|
*
|
* @return
|
*/
|
public List<List<LotInfo>> getNoPlan() {
|
List<LotInfo> list = shpToDataSourceMapper.selectList(new LambdaQueryWrapper<LotInfo>().eq(LotInfo::getIsPlan, 0));
|
List<List<LotInfo>> combinedTasks = list.stream()
|
.collect(Collectors.groupingBy(LotInfo::getTaskId))
|
.values().stream()
|
.map(ArrayList::new)
|
.collect(Collectors.toList());
|
return combinedTasks;
|
}
|
|
/**
|
* 更新图斑执行状态
|
*
|
* @param list
|
*/
|
public void updatePatchesStatu(List<LotInfo> list) {
|
for (LotInfo lotInfo : list) {
|
lotInfo.setIsPlan(1);
|
shpToDataSourceMapper.updateById(lotInfo);
|
}
|
}
|
|
public void updateMediaStatu(MediaFileEntity mediaFile) {
|
mediaFile.setIsadd(1);
|
fileMapper.updateById(mediaFile);
|
}
|
|
public List<List<MediaFileEntity>> getNoadd() {
|
List<MediaFileEntity> list = fileMapper.selectList(new LambdaQueryWrapper<MediaFileEntity>()
|
.eq(MediaFileEntity::getIsadd, 0).like(MediaFileEntity::getFileName, "~"));
|
List<List<MediaFileEntity>> groupedFilenames = groupTasks(list);
|
return groupedFilenames;
|
}
|
|
public CustomClaim backclaim() {
|
CustomClaim claim = new CustomClaim();
|
claim.setId("1");
|
claim.setUsername("adminPC");
|
claim.setWorkspaceId("4a574db8-4ad3-48f7-9f16-3edbcd8056e1");
|
claim.setUserType(1);
|
return claim;
|
}
|
|
public static CreateJobParam JobParam(String waylineId) {
|
long timestamp = System.currentTimeMillis();
|
List<List<Long>> listOfLists = new ArrayList<>();
|
List<Long> sublist = new ArrayList<>();
|
sublist.add(1715941980L); // 添加整数值
|
listOfLists.add(sublist);
|
List<Long> list = new ArrayList<>();
|
list.add(1715941980L);
|
CreateJobParam param = new CreateJobParam();
|
param.setName("云飞行调查" + timestamp);
|
param.setExecuteStartTimeArr(listOfLists);
|
param.setTaskType(TIMED);
|
param.setOutOfControlAction(0);
|
param.setRepFreType(3);
|
param.setRepFreVal(1);
|
param.setRepRuleType(1);
|
param.setRthAltitude(80);
|
param.setWaylineType(WAYPOINT);
|
param.setTaskPeriods(listOfLists);
|
param.setTaskDays(list);
|
param.setFileId(waylineId);
|
param.setDockSn("4TADKCMB0010016");
|
return param;
|
}
|
|
public static <T> List<List<T>> convertToLists(List<List<T>> listOfLists) {
|
List<List<T>> convertedLists = new ArrayList<>();
|
for (List<T> list : listOfLists) {
|
convertedLists.add(new ArrayList<>(list));
|
}
|
return convertedLists;
|
}
|
|
|
// 对任务ID进行分组
|
public static List<List<MediaFileEntity>> groupTasks(List<MediaFileEntity> mediaFiles) {
|
Map<String, List<MediaFileEntity>> groupedTasks = new HashMap<>();
|
for (MediaFileEntity mediaFile : mediaFiles) {
|
String taskId = getTaskId(mediaFile.getFileName());
|
if (!groupedTasks.containsKey(taskId)) {
|
groupedTasks.put(taskId, new ArrayList<>());
|
}
|
groupedTasks.get(taskId).add(mediaFile);
|
}
|
return new ArrayList<>(groupedTasks.values());
|
}
|
|
// 从filename字段中提取任务ID(任务ID在文件名中以"~"开头、"."结尾)
|
public static String getTaskId(String filename) {
|
// 这里只是一个示例,你需要根据实际情况编写提取task_id的逻辑
|
int startIndex = filename.indexOf("~") + 1;
|
int endIndex = filename.indexOf(".");
|
return filename.substring(startIndex, endIndex);
|
}
|
|
public static String getDkbh(String filename) {
|
// 这里只是一个示例,你需要根据实际情况编写提取task_id的逻辑
|
int startIndex = filename.indexOf("点") + 1;
|
int endIndex = filename.indexOf("~");
|
return filename.substring(startIndex, endIndex);
|
}
|
|
/**
|
* 将成果发送post请求到第三方接口
|
*
|
* @param filePath
|
* @param taskId
|
* @throws IOException
|
*/
|
public static void sendPostWithFileAndParameter(String filePath, String taskId) throws IOException {
|
// 创建 RestTemplate 实例
|
try {
|
RestTemplate restTemplate = new RestTemplate();
|
|
// 读取文件内容为字节数组
|
byte[] fileContent = readFileToBytes(filePath);
|
|
// 构建请求体
|
MultiValueMap<String, Object> body = buildRequestBody(taskId, fileContent, filePath);
|
|
// 设置请求头
|
HttpHeaders headers = new HttpHeaders();
|
headers.setContentType(MediaType.MULTIPART_FORM_DATA);
|
headers.set("X-SHARE-TOKEN", "981D9B822A9A09DE28B66243AA330DC666E1A82826B58EC3FE63FEB1EC8AA190");
|
headers.set("X-SHARE-AK", "gwc952d483-bfe5-476b-8431-ae15fe94c006");
|
|
// 构建请求实体
|
HttpEntity<MultiValueMap<String, Object>> requestEntity = new HttpEntity<>(body, headers);
|
|
// 发送请求
|
ResponseEntity<String> response =restTemplate.exchange(
|
"https://jxlandcloud.org.cn/landCloudWork/artifact/media/upload.action",
|
// "http://localhost:6789/territory/tbdkjbxx/upload",
|
HttpMethod.POST,
|
requestEntity,
|
String.class);
|
} catch (Exception e) {
|
throw new IllegalArgumentException("db推送失败" + e.getMessage());
|
}
|
}
|
|
private static MultiValueMap<String, Object> buildRequestBody(String taskId, byte[] fileContent, String filePath) {
|
MultiValueMap<String, Object> body = new LinkedMultiValueMap<>();
|
body.add("taskId", taskId);
|
body.add("file", new ByteArrayResource(fileContent) {
|
@Override
|
public String getFilename() {
|
return Paths.get(filePath).getFileName().toString();
|
}
|
});
|
return body;
|
}
|
|
private static byte[] readFileToBytes(String filePath) throws IOException {
|
Path path = Paths.get(filePath);
|
return Files.readAllBytes(path);
|
}
|
|
/**
|
* 将上传的db保存一份到本地
|
*
|
* @param path
|
* @param folder
|
* @param taskId
|
*/
|
public void dbSave(String path, String folder, String taskId) {
|
String sourceFilePath = path; // 源文件路径
|
String targetFolderPath = fileFold(folder).getPath(); // 目标文件夹路径
|
|
try {
|
// 创建目标文件夹
|
File targetFolder = new File(targetFolderPath);
|
if (!targetFolder.exists()) {
|
targetFolder.mkdirs();
|
}
|
|
// 获取当前时间
|
LocalDateTime currentTime = LocalDateTime.now();
|
|
// 格式化时间,生成文件名
|
String timeName = currentTime.format(DateTimeFormatter.ofPattern("HHmmss"));
|
String fileName = timeName + "_" + taskId + ".db";
|
// 构建目标文件路径
|
String targetFilePath = targetFolderPath + File.separator + fileName;
|
|
// 复制文件到目标文件夹
|
Path sourcePath = Paths.get(sourceFilePath);
|
Path targetPath = Paths.get(targetFilePath);
|
Files.copy(sourcePath, targetPath, StandardCopyOption.REPLACE_EXISTING);
|
} catch (IOException e) {
|
throw new RuntimeException("Db文件复制失败", e); // 捕获并抛出原始异常
|
}
|
}
|
|
private static File fileFold(String fold) {
|
// 获取当前时间
|
LocalDateTime currentTime = LocalDateTime.now();
|
|
// 格式化时间,生成文件夹名字
|
String folderName = currentTime.format(DateTimeFormatter.ofPattern("yyyyMMdd"));
|
|
// 拼接文件夹路径
|
String folderPath = fold + File.separator + folderName;
|
|
// 创建文件夹
|
File folder = new File(folderPath);
|
if (!folder.exists()) {
|
if (!folder.mkdirs()) {
|
throw new RuntimeException("文件创建失败" + folderPath);
|
}
|
}
|
return folder;
|
}
|
|
}
|