CrossLinesFinder.java 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169
  1. package com.shkpr.service.alambizplugin.components.checker;
  2. import com.global.base.log.LogLevelFlag;
  3. import com.global.base.log.LogPrintMgr;
  4. import com.shkpr.service.alambizplugin.commtools.BeanUtil;
  5. import com.shkpr.service.alambizplugin.components.AsyncResultManager;
  6. import com.shkpr.service.alambizplugin.constants.GisSurveySystemCheckKeys;
  7. import com.shkpr.service.alambizplugin.constants.GisSurveySystemCheckResultHead;
  8. import com.shkpr.service.alambizplugin.constants.LogFlagBusiType;
  9. import com.shkpr.service.alambizplugin.dto.GisSurveyLayerApplyLine;
  10. import com.shkpr.service.alambizplugin.dto.GisSurveySystemCheckElement;
  11. import com.shkpr.service.alambizplugin.dto.GisSurveySystemCheckId;
  12. import com.shkpr.service.alambizplugin.dto.GisSurveySystemCheckResultDetail;
  13. import org.locationtech.jts.geom.LineString;
  14. import org.locationtech.jts.index.strtree.STRtree;
  15. import org.springframework.scheduling.annotation.Async;
  16. import org.springframework.scheduling.annotation.AsyncResult;
  17. import org.springframework.stereotype.Component;
  18. import org.springframework.util.concurrent.ListenableFuture;
  19. import java.nio.file.Path;
  20. import java.util.ArrayList;
  21. import java.util.Arrays;
  22. import java.util.HashMap;
  23. import java.util.HashSet;
  24. import java.util.List;
  25. import java.util.Map;
  26. import java.util.Objects;
  27. import java.util.Set;
  28. import java.util.stream.Collectors;
  29. import java.util.stream.IntStream;
  30. /**
  31. * 交叉线差寻找器
  32. *
  33. * @author 欧阳劲驰
  34. * @since 1.0.0
  35. */
  36. @Component
  37. public class CrossLinesFinder {
  38. /**
  39. * log
  40. */
  41. private final String mStrClassName;
  42. private final String mBizType;
  43. private final AsyncResultManager asyncResultManager;
  44. public CrossLinesFinder(AsyncResultManager asyncResultManager) {
  45. mStrClassName = "OverlapLinesFinder";
  46. mBizType = LogFlagBusiType.BUSI_GIS_SURVEY.toStrValue();
  47. this.asyncResultManager = asyncResultManager;
  48. }
  49. /**
  50. * 寻找交叉线
  51. * <p>返回的为交叉线组,未交叉的线不会出现在返回结果</p>
  52. * <p>一组线,仅为两条交叉的线,长度固定为2</p>
  53. *
  54. * @param lines 线集合
  55. * @return 交叉线分组
  56. */
  57. @Async
  58. public ListenableFuture<GisSurveySystemCheckResultDetail> findCrossLines(List<GisSurveyLayerApplyLine> lines
  59. , GisSurveySystemCheckId systemCheckId) throws InterruptedException {
  60. LogPrintMgr.getInstance().printLogMsg(LogLevelFlag.LOG_INFO, mBizType, mStrClassName, "开始执行寻找重叠线========>");
  61. long begin = System.currentTimeMillis();
  62. //创建空间索引
  63. STRtree tree = new STRtree();
  64. //元素存入索引
  65. for (GisSurveyLayerApplyLine layerApplyLine : lines) {
  66. if (layerApplyLine.getGis() == null) continue;
  67. LineString line = layerApplyLine.getGis();
  68. tree.insert(line.getEnvelopeInternal(), layerApplyLine);
  69. }
  70. tree.build();
  71. //结果
  72. List<List<GisSurveySystemCheckElement>> groupElements = new ArrayList<>();
  73. //处理过的code
  74. Set<String> processedCodes = new HashSet<>();
  75. //遍历所有线
  76. for (GisSurveyLayerApplyLine line1 : lines) {
  77. if (line1.getGis() == null) continue;
  78. //响应中断
  79. if (Thread.interrupted()) throw new InterruptedException();
  80. //查询索引内元素
  81. List<?> candidates = tree.query(line1.getGis().getEnvelopeInternal());
  82. for (Object obj : candidates) {
  83. GisSurveyLayerApplyLine line2 = (GisSurveyLayerApplyLine) obj;
  84. //排除code相同或已经处理的元素,
  85. if (Objects.equals(line1.getCode(), line2.getCode())
  86. || processedCodes.contains(line2.getCode())
  87. || line2.getGis() == null
  88. ) continue;
  89. //响应中断
  90. if (Thread.interrupted()) throw new InterruptedException();
  91. // 判断是否交叉
  92. if (line1.getGis().crosses(line2.getGis())) {
  93. //创建两两一组交叉线对
  94. groupElements.add(Arrays.asList(
  95. BeanUtil.copy(line1, GisSurveySystemCheckElement.class),
  96. BeanUtil.copy(line2, GisSurveySystemCheckElement.class)
  97. ));
  98. }
  99. }
  100. //存入code,避免重复处理
  101. processedCodes.add(line1.getCode());
  102. }
  103. return new AsyncResult<>(createResult(groupElements, systemCheckId, begin));
  104. }
  105. /**
  106. * 创建结果
  107. *
  108. * @param data 数据
  109. * @param systemCheckId 系统检查id
  110. * @param begin 开始时间
  111. * @return 结果
  112. */
  113. private GisSurveySystemCheckResultDetail createResult(List<List<GisSurveySystemCheckElement>> data
  114. , GisSurveySystemCheckId systemCheckId, long begin) {
  115. //数据大小
  116. final int size = data.size();
  117. //结果flag
  118. final String FLAG = systemCheckId.getFlag();
  119. //写入json和excel结果
  120. Path jsonPath = asyncResultManager.writeJson(data, FLAG, GisSurveySystemCheckKeys.CROSS_LINES + ".json");
  121. Path excelPath = asyncResultManager.writeExcel(GisSurveySystemCheckResultHead.CROSS_LINES,
  122. buildExcel(data), FLAG, GisSurveySystemCheckKeys.CROSS_LINES + ".xlsx");
  123. long end = System.currentTimeMillis();
  124. LogPrintMgr.getInstance().printLogMsg(LogLevelFlag.LOG_INFO, mBizType, mStrClassName
  125. , String.format(
  126. "结束执行寻找交叉线,用时(毫秒):%d"
  127. , (end - begin)
  128. )
  129. );
  130. //构建结果
  131. return new GisSurveySystemCheckResultDetail(true
  132. , FLAG + "/" + jsonPath.getFileName()
  133. , FLAG + "/" + excelPath.getFileName()
  134. , size);
  135. }
  136. /**
  137. * 构建excel数据
  138. *
  139. * @param data 数据
  140. * @return excel数据
  141. */
  142. private List<Map<String, Object>> buildExcel(List<List<GisSurveySystemCheckElement>> data) {
  143. return IntStream.range(0, data.size())
  144. .boxed()
  145. .flatMap(i -> data.get(i).stream().map(element -> {
  146. Map<String, Object> map = new HashMap<>();
  147. map.put(GisSurveySystemCheckResultHead.KEYS.GROUP_NAME, i + 1);
  148. map.put(GisSurveySystemCheckResultHead.KEYS.UP_NO, element.getUpNo());
  149. map.put(GisSurveySystemCheckResultHead.KEYS.DOWN_NO, element.getDownNo());
  150. map.put(GisSurveySystemCheckResultHead.KEYS.CODE, element.getCode());
  151. map.put(GisSurveySystemCheckResultHead.KEYS.UP_NODE, element.getUpNode());
  152. map.put(GisSurveySystemCheckResultHead.KEYS.DOWN_NODE, element.getDownNode());
  153. map.put(GisSurveySystemCheckResultHead.KEYS.NAME, element.getName());
  154. return map;
  155. })).collect(Collectors.toList());
  156. }
  157. }