InvalidPropertiesFinder.java 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303
  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.commtools.ThirdImportTemplateUtils;
  6. import com.shkpr.service.alambizplugin.constants.GisMetadataDefine;
  7. import com.shkpr.service.alambizplugin.constants.GisSurveyExcelDefine;
  8. import com.shkpr.service.alambizplugin.constants.LogFlagBusiType;
  9. import com.shkpr.service.alambizplugin.dto.GisMetadataLayerTemplate;
  10. import com.shkpr.service.alambizplugin.dto.GisMetadataPropertyTemplate;
  11. import com.shkpr.service.alambizplugin.dto.GisSurveyCondition;
  12. import com.shkpr.service.alambizplugin.dto.GisSurveyThirdImportElement;
  13. import com.shkpr.service.alambizplugin.dto.GisSurveyThirdImportResultDetail;
  14. import org.apache.commons.collections4.CollectionUtils;
  15. import org.apache.commons.lang3.StringUtils;
  16. import org.apache.commons.lang3.math.NumberUtils;
  17. import org.springframework.scheduling.annotation.Async;
  18. import org.springframework.scheduling.annotation.AsyncResult;
  19. import org.springframework.stereotype.Component;
  20. import org.springframework.util.concurrent.ListenableFuture;
  21. import java.util.ArrayList;
  22. import java.util.HashMap;
  23. import java.util.List;
  24. import java.util.Map;
  25. import java.util.Objects;
  26. import java.util.stream.Collectors;
  27. /**
  28. * 无效属性查找器
  29. *
  30. * @author 欧阳劲驰
  31. * @since 1.0.0
  32. */
  33. @Component
  34. public class InvalidPropertiesFinder {
  35. /**
  36. * 中国经纬度范围
  37. */
  38. private static final Double MIN_LNG = 73.62;
  39. private static final Double MAX_LNG = 134.77;
  40. private static final Double MIN_LAT = 16.7;
  41. private static final Double MAX_LAT = 53.56;
  42. /**
  43. * log
  44. */
  45. private final String mStrClassName;
  46. private final String mBizType;
  47. public InvalidPropertiesFinder() {
  48. mStrClassName = "InvalidPropertiesFinder";
  49. mBizType = LogFlagBusiType.BUSI_GIS_SURVEY.toStrValue();
  50. }
  51. /**
  52. * 寻找无效属性
  53. *
  54. * @param points 点集合
  55. * @param lines 线集合
  56. * @param pointLayerTemplates 点图层模版集合
  57. * @param lineLayerTemplates 线图层模版集合
  58. * @param checkConstraint 检查约束
  59. * @param projectConstraints 项目约束条件
  60. * @return 重复点
  61. */
  62. @Async
  63. public ListenableFuture<GisSurveyThirdImportResultDetail<Map<String, List<GisSurveyThirdImportElement>>>> findInvalidProperties(
  64. List<Map<String, String>> points, List<Map<String, String>> lines, List<GisMetadataLayerTemplate> pointLayerTemplates
  65. , List<GisMetadataLayerTemplate> lineLayerTemplates, Boolean checkConstraint, List<GisSurveyCondition> projectConstraints) throws InterruptedException {
  66. LogPrintMgr.getInstance().printLogMsg(LogLevelFlag.LOG_INFO, mBizType, mStrClassName, "开始执行寻找无效属性 ======>");
  67. long begin = System.currentTimeMillis();
  68. //无效图层结果
  69. List<GisSurveyThirdImportElement> invalidLayersResult = new ArrayList<>();
  70. //缺失必填结果
  71. List<GisSurveyThirdImportElement> missingRequirementsResult = new ArrayList<>();
  72. //无效类型结果
  73. List<GisSurveyThirdImportElement> invalidTypesResult = new ArrayList<>();
  74. //超出范围结果
  75. List<GisSurveyThirdImportElement> outRangesResult = new ArrayList<>();
  76. //超出约束结果
  77. List<GisSurveyThirdImportElement> outConstraintResult = new ArrayList<>();
  78. //检查点属性
  79. for (Map<String, String> point : points) {
  80. //响应中断
  81. if (Thread.interrupted()) throw new InterruptedException();
  82. //获取图层
  83. GisMetadataLayerTemplate layerTemplate = ThirdImportTemplateUtils
  84. .getLayerTemplate(point, pointLayerTemplates, GisMetadataDefine.TYPE_KINE.POINT);
  85. //图层不存在则加入无效图层结果
  86. if (layerTemplate == null)
  87. invalidLayersResult.add(new GisSurveyThirdImportElement(
  88. GisMetadataDefine.TYPE_KINE.POINT,
  89. null,
  90. point.get(GisSurveyExcelDefine.FILE.POINT_LAYER),
  91. null
  92. ));
  93. else
  94. //图层存在则检查图层
  95. checkLayer(point, layerTemplate, checkConstraint, projectConstraints, missingRequirementsResult, invalidTypesResult, outConstraintResult);
  96. //检查坐标超出范围
  97. if (checkOutRanges(point, layerTemplate))
  98. outRangesResult.add(
  99. new GisSurveyThirdImportElement(
  100. GisMetadataDefine.TYPE_KINE.POINT,
  101. ThirdImportTemplateUtils.getValue(point, layerTemplate, GisSurveyExcelDefine.TEMPLATE.NO),
  102. point.get(GisSurveyExcelDefine.FILE.POINT_LAYER),
  103. null
  104. )
  105. );
  106. }
  107. //检查线属性
  108. for (Map<String, String> line : lines) {
  109. //响应中断
  110. if (Thread.interrupted()) throw new InterruptedException();
  111. //过滤图层
  112. GisMetadataLayerTemplate layerTemplate = ThirdImportTemplateUtils
  113. .getLayerTemplate(line, lineLayerTemplates, GisMetadataDefine.TYPE_KINE.LINE);
  114. //图层不存在则加入无效图层结果
  115. if (layerTemplate == null)
  116. invalidLayersResult.add(new GisSurveyThirdImportElement(
  117. GisMetadataDefine.TYPE_KINE.LINE,
  118. null,
  119. null,
  120. line.get(GisSurveyExcelDefine.FILE.LINE_LAYER),
  121. null
  122. ));
  123. else
  124. //图层存在则检查图层
  125. checkLayer(line, layerTemplate, checkConstraint, projectConstraints, missingRequirementsResult, invalidTypesResult, outConstraintResult);
  126. }
  127. long end = System.currentTimeMillis();
  128. LogPrintMgr.getInstance().printLogMsg(LogLevelFlag.LOG_INFO, mBizType, mStrClassName
  129. , String.format(
  130. "结束执行寻找无效属性,用时(毫秒):%d"
  131. , (end - begin)
  132. )
  133. );
  134. //构建结果
  135. Map<String, List<GisSurveyThirdImportElement>> result = new HashMap<>();
  136. result.put(GisSurveyExcelDefine.RESULT.INVALID_LAYERS, invalidLayersResult);
  137. result.put(GisSurveyExcelDefine.RESULT.MISSING_REQUIREMENTS, missingRequirementsResult);
  138. result.put(GisSurveyExcelDefine.RESULT.INVALID_TYPES, invalidTypesResult);
  139. result.put(GisSurveyExcelDefine.RESULT.OUT_RANGES, outRangesResult);
  140. result.put(GisSurveyExcelDefine.RESULT.OUT_CONSTRAINT, outConstraintResult);
  141. return new AsyncResult<>(new GisSurveyThirdImportResultDetail<>(true, result));
  142. }
  143. /**
  144. * 检查超出范围
  145. *
  146. * @param point 点
  147. * @return 超出范围昨状态
  148. */
  149. public Boolean checkOutRanges(Map<String, String> point, GisMetadataLayerTemplate layerTemplate) {
  150. //获取经纬度字段
  151. String latStr = ThirdImportTemplateUtils.getValue(point, layerTemplate, GisSurveyExcelDefine.TEMPLATE.LAT);
  152. String lngStr = ThirdImportTemplateUtils.getValue(point, layerTemplate, GisSurveyExcelDefine.TEMPLATE.LNG);
  153. //检查是否字符串
  154. if (StringUtils.isBlank(latStr) || StringUtils.isBlank(lngStr)) return true;
  155. //检查是否可解析
  156. if (!NumberUtils.isParsable(latStr) || !NumberUtils.isParsable(lngStr)) return true;
  157. //解析
  158. double lat = Double.parseDouble(latStr);
  159. double lng = Double.parseDouble(lngStr);
  160. //判断是否在范围
  161. return MIN_LAT >= lat || lat >= MAX_LAT || MIN_LNG >= lng || lng >= MAX_LNG;
  162. }
  163. /**
  164. * 检查图层
  165. *
  166. * @param data 数据
  167. * @param layerTemplate 图层模版
  168. * @param checkConstraint 检查超出约束
  169. * @param projectConstraints 项目约束
  170. * @param missingRequirementsResult 缺少必填结果
  171. * @param invalidTypesResult 无效类型结果
  172. * @param outConstraintResult 超出约束结果
  173. */
  174. public void checkLayer(Map<String, String> data, GisMetadataLayerTemplate layerTemplate
  175. , Boolean checkConstraint, List<GisSurveyCondition> projectConstraints, List<GisSurveyThirdImportElement> missingRequirementsResult
  176. , List<GisSurveyThirdImportElement> invalidTypesResult, List<GisSurveyThirdImportElement> outConstraintResult) {
  177. //项目约束映射
  178. Map<String, GisSurveyCondition> projectConstraintsMapping = projectConstraints.stream()
  179. .filter(constraint -> Objects.equals(layerTemplate.getKind(), constraint.getKind()))
  180. .collect(Collectors.toMap(GisSurveyCondition::getProperty, it -> it));
  181. //遍历图层属性模版
  182. for (GisMetadataPropertyTemplate propertyTemplate : layerTemplate.getPropertyTemplates()) {
  183. //排除编码
  184. if (Objects.equals(GisSurveyExcelDefine.TEMPLATE.CODE, propertyTemplate.getKey())
  185. || Objects.equals(GisSurveyExcelDefine.TEMPLATE.UP_NODE, propertyTemplate.getKey())
  186. || Objects.equals(GisSurveyExcelDefine.TEMPLATE.DOWN_NODE, propertyTemplate.getKey()))
  187. continue;
  188. //当前属性值
  189. String value = data.get(propertyTemplate.getName());
  190. //必填
  191. if (propertyTemplate.getRequired() == 1 && propertyTemplate.getStatus() == 1) {
  192. //值不存在则存入缺少必填
  193. if (StringUtils.isBlank(value)) {
  194. GisSurveyThirdImportElement gisSurveyThirdImportElement = GisSurveyThirdImportElement.create(data,
  195. layerTemplate,
  196. propertyTemplate.getName()
  197. );
  198. missingRequirementsResult.add(gisSurveyThirdImportElement);
  199. //值存在
  200. } else {
  201. //判断超出约束
  202. checkOutConstraint(
  203. projectConstraintsMapping.get(propertyTemplate.getKey()),
  204. data, layerTemplate, propertyTemplate, value, outConstraintResult
  205. );
  206. //判断数字类型
  207. if ((GisSurveyExcelDefine.DATA_TYPE.INT.equals(propertyTemplate.getType()) ||
  208. GisSurveyExcelDefine.DATA_TYPE.DOUBLE.equals(propertyTemplate.getType()))
  209. && !NumberUtils.isParsable(value)) {
  210. invalidTypesResult.add(GisSurveyThirdImportElement.create(data,
  211. layerTemplate,
  212. propertyTemplate.getName()
  213. ));
  214. }
  215. }
  216. }
  217. //非必填
  218. else {
  219. //判断超出约束
  220. if (checkConstraint && StringUtils.isNotBlank(value)) checkOutConstraint(
  221. projectConstraintsMapping.get(propertyTemplate.getKey()),
  222. data, layerTemplate, propertyTemplate, value, outConstraintResult
  223. );
  224. }
  225. }
  226. }
  227. /**
  228. * 检查超出约束
  229. *
  230. * @param projectConstraint 项目约束
  231. * @param data 数据
  232. * @param layerTemplate 图层模版
  233. * @param propertyTemplate 属性模版
  234. * @param value 值
  235. * @param outConstraintResult 超出约束结果
  236. */
  237. public void checkOutConstraint(GisSurveyCondition projectConstraint, Map<String, String> data
  238. , GisMetadataLayerTemplate layerTemplate, GisMetadataPropertyTemplate propertyTemplate
  239. , String value, List<GisSurveyThirdImportElement> outConstraintResult) {
  240. GisSurveyCondition constraint = null;
  241. //模版约束
  242. if (StringUtils.isNotBlank(propertyTemplate.getMode()) && CollectionUtils.isNotEmpty(propertyTemplate.getRanges())) {
  243. constraint = BeanUtil.copy(propertyTemplate, GisSurveyCondition.class);
  244. if (constraint != null) {
  245. constraint.setProperty(propertyTemplate.getKey());
  246. constraint.setKind(layerTemplate.getKind());
  247. }
  248. }
  249. //项目约束
  250. if (projectConstraint != null) {
  251. constraint = projectConstraint;
  252. }
  253. if (constraint == null || StringUtils.isBlank(value)) return;
  254. //约束模式
  255. String mode = constraint.getMode();
  256. //约束范围
  257. List<String> ranges = constraint.getRanges();
  258. if (StringUtils.isBlank(mode) || CollectionUtils.isEmpty(ranges)) return;
  259. //列表约束
  260. if (Objects.equals("list", constraint.getMode())) {
  261. //如列表不包含值,则超出约束
  262. if (!ranges.contains(value)) {
  263. outConstraintResult.add(GisSurveyThirdImportElement.create(data, layerTemplate,
  264. propertyTemplate.getName(), value, constraint
  265. ));
  266. }
  267. }
  268. //极值约束
  269. else if (Objects.equals("extremum", constraint.getMode())) {
  270. if (ranges.size() != 2) return;
  271. //最小值判断
  272. String minStr = ranges.get(0);
  273. if (StringUtils.isNotBlank(minStr) && NumberUtils.isParsable(minStr)) {
  274. double min = Double.parseDouble(minStr);
  275. if (!NumberUtils.isParsable(value) || Double.parseDouble(value) < min) {
  276. outConstraintResult.add(GisSurveyThirdImportElement.create(data, layerTemplate,
  277. propertyTemplate.getName(), value, constraint));
  278. }
  279. }
  280. //最大值判断
  281. String maxStr = ranges.get(1);
  282. if (StringUtils.isNotBlank(maxStr) && NumberUtils.isParsable(maxStr)) {
  283. double max = Double.parseDouble(maxStr);
  284. if (!NumberUtils.isParsable(value) || Double.parseDouble(value) > max) {
  285. outConstraintResult.add(GisSurveyThirdImportElement.create(data, layerTemplate,
  286. propertyTemplate.getName(), value, constraint));
  287. }
  288. }
  289. }
  290. }
  291. }