GisSurveyThirdExporter.java 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333
  1. package com.shkpr.service.alambizplugin.components;
  2. import com.global.base.log.LogLevelFlag;
  3. import com.global.base.log.LogPrintMgr;
  4. import com.shkpr.service.alambizplugin.commproperties.TempFileProperties;
  5. import com.shkpr.service.alambizplugin.commtools.CompressorUtils;
  6. import com.shkpr.service.alambizplugin.commtools.ExcelUtils;
  7. import com.shkpr.service.alambizplugin.commtools.ShapeUtils;
  8. import com.shkpr.service.alambizplugin.constants.CommAsyncStatusEnum;
  9. import com.shkpr.service.alambizplugin.constants.ExcelEnum;
  10. import com.shkpr.service.alambizplugin.constants.FileTypeEnum;
  11. import com.shkpr.service.alambizplugin.constants.GisMetadataDefine;
  12. import com.shkpr.service.alambizplugin.constants.GisSurveyExcelDefine;
  13. import com.shkpr.service.alambizplugin.constants.LogFlagBusiType;
  14. import com.shkpr.service.alambizplugin.dbdao.services.intef.GisMetadataLayerTemplateService;
  15. import com.shkpr.service.alambizplugin.dbdao.services.intef.GisSurveyLayerApplyService;
  16. import com.shkpr.service.alambizplugin.dto.CommAsyncResult;
  17. import com.shkpr.service.alambizplugin.dto.GisMetadataLayerTemplate;
  18. import com.shkpr.service.alambizplugin.dto.GisMetadataPropertyTemplate;
  19. import com.shkpr.service.alambizplugin.dto.GisSurveyLayerApply;
  20. import com.shkpr.service.alambizplugin.dto.GisSurveyPropertyValue;
  21. import org.apache.commons.compress.archivers.ArchiveException;
  22. import org.apache.commons.lang3.StringUtils;
  23. import org.locationtech.jts.geom.Geometry;
  24. import org.springframework.scheduling.annotation.Async;
  25. import org.springframework.scheduling.annotation.AsyncResult;
  26. import org.springframework.stereotype.Component;
  27. import org.springframework.util.concurrent.ListenableFuture;
  28. import java.io.IOException;
  29. import java.nio.file.Files;
  30. import java.nio.file.Path;
  31. import java.time.Duration;
  32. import java.time.LocalDateTime;
  33. import java.util.Comparator;
  34. import java.util.HashMap;
  35. import java.util.LinkedHashMap;
  36. import java.util.List;
  37. import java.util.Map;
  38. import java.util.Objects;
  39. import java.util.stream.Collectors;
  40. /**
  41. * 第三方导出执行器
  42. *
  43. * @author 欧阳劲驰
  44. * @since 1.0.0
  45. */
  46. @Component
  47. public class GisSurveyThirdExporter {
  48. /**
  49. * log
  50. */
  51. private final String mStrClassName;
  52. private final String mBizType;
  53. private final TempFileProperties tempFileProperties;
  54. private final GisMetadataLayerTemplateService layerTemplateService;
  55. private final GisSurveyLayerApplyService gisSurveyLayerApplyService;
  56. public GisSurveyThirdExporter(TempFileProperties tempFileProperties
  57. , GisMetadataLayerTemplateService layerTemplateService, GisSurveyLayerApplyService gisSurveyLayerApplyService) {
  58. mStrClassName = "GisSurveyThirdExporter";
  59. mBizType = LogFlagBusiType.BUSI_GIS_SURVEY.toStrValue();
  60. this.tempFileProperties = tempFileProperties;
  61. this.layerTemplateService = layerTemplateService;
  62. this.gisSurveyLayerApplyService = gisSurveyLayerApplyService;
  63. }
  64. /**
  65. * 第三方导出任务
  66. *
  67. * @param jobId 任务id
  68. * @param fileType 导出文件类型
  69. * @return 导出结果
  70. */
  71. @Async
  72. public ListenableFuture<CommAsyncResult<String>> thirdExportTask(String jobId, FileTypeEnum fileType) {
  73. //构建返回
  74. CommAsyncResult<String> result = CommAsyncResult.fail(jobId);
  75. try {
  76. LogPrintMgr.getInstance().printLogMsg(LogLevelFlag.LOG_INFO, mBizType, mStrClassName
  77. , String.format(
  78. "开始执行第三方导出;任务id: %s"
  79. , jobId
  80. )
  81. );
  82. //查询点线数据
  83. List<GisSurveyLayerApply> points = gisSurveyLayerApplyService.findAllByJobIdAndKind(jobId, GisMetadataDefine.TYPE_KINE.POINT);
  84. List<GisSurveyLayerApply> lines = gisSurveyLayerApplyService.findAllByJobIdAndKind(jobId, GisMetadataDefine.TYPE_KINE.LINE);
  85. //根据文件类型导出
  86. Path resultPath = null;
  87. if (fileType == FileTypeEnum.EXCEL)
  88. resultPath = exportExcel(points, lines);
  89. if (fileType == FileTypeEnum.SHAPE_FILE)
  90. resultPath = exportShape(points, lines);
  91. //导出文件判断
  92. if (resultPath == null || !Files.exists(resultPath)) {
  93. //打印报错信息
  94. LogPrintMgr.getInstance().printLogMsg(LogLevelFlag.LOG_ERROR, mBizType, mStrClassName
  95. , String.format("第三方导出文件写入失败, 任务id:%s", jobId)
  96. );
  97. return new AsyncResult<>(result);
  98. }
  99. //导出完成
  100. result.setStatus(CommAsyncStatusEnum.SUCCESS.getCode());
  101. result.setCompleteTime(LocalDateTime.now());
  102. result.setData(resultPath.getFileName().toString());
  103. LogPrintMgr.getInstance().printLogMsg(LogLevelFlag.LOG_INFO, mBizType, mStrClassName
  104. , String.format(
  105. "结束第三方导出;任务id: %s, 用时(毫秒):%d"
  106. , jobId
  107. , Duration.between(result.getRequestTime(), result.getCompleteTime()).toMillis()
  108. )
  109. );
  110. return new AsyncResult<>(result);
  111. } catch (InterruptedException | IOException | ArchiveException e) {
  112. //打印报错信息
  113. LogPrintMgr.getInstance().printLogMsg(LogLevelFlag.LOG_ERROR, mBizType, mStrClassName
  114. , String.format("第三方导出异常 任务id:%s error:%s", jobId, e)
  115. );
  116. return new AsyncResult<>(result);
  117. }
  118. }
  119. /**
  120. * 导出excel
  121. *
  122. * @param points 点
  123. * @param lines 线
  124. * @return excel路径
  125. * @throws IOException io异常
  126. */
  127. private Path exportExcel(List<GisSurveyLayerApply> points, List<GisSurveyLayerApply> lines) throws IOException {
  128. //获取图层key
  129. List<String> pointLayer = getLayerKeys(points);
  130. List<String> lineLayer = getLayerKeys(lines);
  131. //查询点图层模版
  132. List<GisMetadataLayerTemplate> pointLayerTemplates = layerTemplateService.findByKeyIn(pointLayer);
  133. //查询线图层模版
  134. List<GisMetadataLayerTemplate> lineLayerTemplates = layerTemplateService.findByKeyIn(lineLayer);
  135. //构建excel头
  136. Map<String, Map<String, String>> excelHeader = buildExcelHeader(pointLayerTemplates, lineLayerTemplates);
  137. //构建excel数据
  138. Map<String, List<Map<String, Object>>> excelData = buildExcelData(points, lines, pointLayerTemplates, lineLayerTemplates);
  139. //导出excel
  140. Path excelPath = Files.createTempFile(tempFileProperties.getResourcePath(), "third-export-", ".xlsx");
  141. ExcelUtils.writeFile(excelHeader, excelData, Files.newOutputStream(excelPath), ExcelEnum.XLSX);
  142. return excelPath;
  143. }
  144. /**
  145. * 导出shape
  146. *
  147. * @param points 点
  148. * @param lines 线
  149. * @return shape路径
  150. * @throws IOException io异常
  151. * @throws ArchiveException 压缩异常
  152. */
  153. private Path exportShape(List<GisSurveyLayerApply> points, List<GisSurveyLayerApply> lines) throws IOException, ArchiveException {
  154. //构建shape数据
  155. Map<String, List<Geometry>> shapeData = buildShapeData(points, lines);
  156. //创建临时文件夹
  157. Path directory = Files.createTempDirectory(tempFileProperties.getResourcePath(), "third-export-");
  158. //导出shape
  159. ShapeUtils.writeShape(shapeData, directory);
  160. //压缩文件夹
  161. return CompressorUtils.archivalZip(directory);
  162. }
  163. /**
  164. * 获取图层key
  165. *
  166. * @param datas 数据
  167. * @return 图层key集合
  168. */
  169. private List<String> getLayerKeys(List<GisSurveyLayerApply> datas) {
  170. //去重图层
  171. return datas.parallelStream()
  172. .map(GisSurveyLayerApply::getLayer)
  173. .filter(StringUtils::isNotBlank)
  174. .distinct()
  175. .collect(Collectors.toList());
  176. }
  177. /**
  178. * 构建excel表头
  179. *
  180. * @param pointLayerTemplates 点图层模版
  181. * @param lineLayerTemplates 线图层模版
  182. * @return excel数据
  183. */
  184. private Map<String, Map<String, String>> buildExcelHeader(List<GisMetadataLayerTemplate> pointLayerTemplates
  185. , List<GisMetadataLayerTemplate> lineLayerTemplates) {
  186. //点excel表头
  187. Map<String, String> pointExcelHeader = new LinkedHashMap<>();
  188. //线excel表头
  189. Map<String, String> lineExcelHeader = new LinkedHashMap<>();
  190. //点模版表头
  191. Map<String, String> pointTemplateHeader = pointLayerTemplates.stream()
  192. .flatMap(it -> it.getPropertyTemplates().stream())
  193. .sorted(Comparator.comparing(GisMetadataPropertyTemplate::getOrdering))
  194. .collect(Collectors.toMap(GisMetadataPropertyTemplate::getKey, GisMetadataPropertyTemplate::getName
  195. , (it1, it2) -> it1, LinkedHashMap::new));
  196. //线模版表头
  197. Map<String, String> lineTemplateHeader = lineLayerTemplates.stream()
  198. .flatMap(it -> it.getPropertyTemplates().stream())
  199. .collect(Collectors.toMap(GisMetadataPropertyTemplate::getKey, GisMetadataPropertyTemplate::getName
  200. , (it1, it2) -> it1, LinkedHashMap::new));
  201. //加入图层表头
  202. pointExcelHeader.put(GisSurveyExcelDefine.TEMPLATE.LAYER, GisSurveyExcelDefine.FILE.POINT_LAYER);
  203. lineExcelHeader.put(GisSurveyExcelDefine.TEMPLATE.LAYER, GisSurveyExcelDefine.FILE.LINE_LAYER);
  204. //加入模版表头
  205. pointExcelHeader.putAll(pointTemplateHeader);
  206. lineExcelHeader.putAll(lineTemplateHeader);
  207. //excel表头
  208. Map<String, Map<String, String>> excelHeader = new HashMap<>();
  209. excelHeader.put(GisMetadataDefine.TYPE_KINE.POINT, pointExcelHeader);
  210. excelHeader.put(GisMetadataDefine.TYPE_KINE.LINE, lineExcelHeader);
  211. return excelHeader;
  212. }
  213. /**
  214. * 构建excel数据
  215. *
  216. * @param points 点元素
  217. * @param lines 线元素
  218. * @param pointLayerTemplates 点图层模版
  219. * @param lineLayerTemplates 线图层模版
  220. * @return excel数据
  221. */
  222. private Map<String, List<Map<String, Object>>> buildExcelData(List<GisSurveyLayerApply> points, List<GisSurveyLayerApply> lines
  223. , List<GisMetadataLayerTemplate> pointLayerTemplates, List<GisMetadataLayerTemplate> lineLayerTemplates) {
  224. LogPrintMgr.getInstance().printLogMsg(LogLevelFlag.LOG_INFO, mBizType, mStrClassName, "开始构建excel数据 ======>");
  225. long begin = System.currentTimeMillis();
  226. //excel数据
  227. Map<String, List<Map<String, Object>>> excelData = new HashMap<>();
  228. excelData.put(GisMetadataDefine.TYPE_KINE.POINT, buildExcelSheetData(points, pointLayerTemplates));
  229. excelData.put(GisMetadataDefine.TYPE_KINE.LINE, buildExcelSheetData(lines, lineLayerTemplates));
  230. long end = System.currentTimeMillis();
  231. LogPrintMgr.getInstance().printLogMsg(LogLevelFlag.LOG_INFO, mBizType, mStrClassName
  232. , String.format(
  233. "结束构建excel数据,用时(毫秒):%d"
  234. , (end - begin)
  235. )
  236. );
  237. return excelData;
  238. }
  239. /**
  240. * 构建excel页数据
  241. *
  242. * @param layerApplies 采集元素集合
  243. * @param layerTemplates 图层模版
  244. * @return excel数据
  245. */
  246. private List<Map<String, Object>> buildExcelSheetData(List<GisSurveyLayerApply> layerApplies, List<GisMetadataLayerTemplate> layerTemplates) {
  247. return layerApplies.parallelStream()
  248. .map(it -> {
  249. //处理模版数据
  250. Map<String, Object> rowData = it.getPropertyValues().stream()
  251. .filter(it1 -> !StringUtils.isAnyBlank(it1.getProperty(), it1.getValue()))
  252. .collect(Collectors.toMap(GisSurveyPropertyValue::getProperty, GisSurveyPropertyValue::getValue));
  253. //处理图层数据
  254. if (StringUtils.isNotBlank(it.getLayer())) {
  255. //获取模版
  256. GisMetadataLayerTemplate gisMetadataLayerTemplate = layerTemplates.stream()
  257. .filter(it1 -> Objects.equals(it1.getKey(), it.getLayer()))
  258. .findFirst().orElse(null);
  259. //存入图层
  260. if (gisMetadataLayerTemplate != null)
  261. rowData.put(GisSurveyExcelDefine.TEMPLATE.LAYER, gisMetadataLayerTemplate.getName());
  262. }
  263. return rowData;
  264. }).collect(Collectors.toList());
  265. }
  266. /**
  267. * 构建shape数据
  268. *
  269. * @param points 点元素
  270. * @param lines 线元素
  271. * @return excel数据
  272. */
  273. private Map<String, List<Geometry>> buildShapeData(List<GisSurveyLayerApply> points, List<GisSurveyLayerApply> lines) {
  274. LogPrintMgr.getInstance().printLogMsg(LogLevelFlag.LOG_INFO, mBizType, mStrClassName, "开始构建shape数据 ======>");
  275. long begin = System.currentTimeMillis();
  276. //点excel数据
  277. List<Geometry> pointExcelData = points.parallelStream()
  278. .map(GisSurveyLayerApply::getGis)
  279. .filter(Objects::nonNull)
  280. .collect(Collectors.toList());
  281. //线excel数据
  282. List<Geometry> lineExcelData = lines.parallelStream()
  283. .map(GisSurveyLayerApply::getGis)
  284. .filter(Objects::nonNull)
  285. .collect(Collectors.toList());
  286. //excel数据
  287. Map<String, List<Geometry>> shapeData = new HashMap<>();
  288. shapeData.put(GisMetadataDefine.TYPE_KINE.POINT, pointExcelData);
  289. shapeData.put(GisMetadataDefine.TYPE_KINE.LINE, lineExcelData);
  290. long end = System.currentTimeMillis();
  291. LogPrintMgr.getInstance().printLogMsg(LogLevelFlag.LOG_INFO, mBizType, mStrClassName
  292. , String.format(
  293. "结束构建shape数据,用时(毫秒):%d"
  294. , (end - begin)
  295. )
  296. );
  297. return shapeData;
  298. }
  299. }