package com.shkpr.service.alambizplugin.components.checker; import com.global.base.log.LogLevelFlag; import com.global.base.log.LogPrintMgr; import com.shkpr.service.alambizplugin.commtools.BeanUtil; import com.shkpr.service.alambizplugin.commtools.ThirdImportTemplateUtils; import com.shkpr.service.alambizplugin.constants.GisMetadataDefine; import com.shkpr.service.alambizplugin.constants.GisSurveyExcelDefine; import com.shkpr.service.alambizplugin.constants.LogFlagBusiType; import com.shkpr.service.alambizplugin.dto.GisMetadataLayerTemplate; import com.shkpr.service.alambizplugin.dto.GisMetadataPropertyTemplate; import com.shkpr.service.alambizplugin.dto.GisSurveyCondition; import com.shkpr.service.alambizplugin.dto.GisSurveyThirdImportElement; import com.shkpr.service.alambizplugin.dto.GisSurveyThirdImportResultDetail; import org.apache.commons.collections4.CollectionUtils; import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.math.NumberUtils; import org.springframework.scheduling.annotation.Async; import org.springframework.scheduling.annotation.AsyncResult; import org.springframework.stereotype.Component; import org.springframework.util.concurrent.ListenableFuture; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Objects; import java.util.stream.Collectors; /** * 无效属性查找器 * * @author 欧阳劲驰 * @since 1.0.0 */ @Component public class InvalidPropertiesFinder { /** * 中国经纬度范围 */ private static final Double MIN_LNG = 73.62; private static final Double MAX_LNG = 134.77; private static final Double MIN_LAT = 16.7; private static final Double MAX_LAT = 53.56; /** * log */ private final String mStrClassName; private final String mBizType; public InvalidPropertiesFinder() { mStrClassName = "InvalidPropertiesFinder"; mBizType = LogFlagBusiType.BUSI_GIS_SURVEY.toStrValue(); } /** * 寻找无效属性 * * @param points 点集合 * @param lines 线集合 * @param pointLayerTemplates 点图层模版集合 * @param lineLayerTemplates 线图层模版集合 * @param checkConstraint 检查约束 * @param projectConstraints 项目约束条件 * @return 重复点 */ @Async public ListenableFuture>>> findInvalidProperties( List> points, List> lines, List pointLayerTemplates , List lineLayerTemplates, Boolean checkConstraint, List projectConstraints) throws InterruptedException { LogPrintMgr.getInstance().printLogMsg(LogLevelFlag.LOG_INFO, mBizType, mStrClassName, "开始执行寻找无效属性 ======>"); long begin = System.currentTimeMillis(); //无效图层结果 List invalidLayersResult = new ArrayList<>(); //缺失必填结果 List missingRequirementsResult = new ArrayList<>(); //无效类型结果 List invalidTypesResult = new ArrayList<>(); //超出范围结果 List outRangesResult = new ArrayList<>(); //超出约束结果 List outConstraintResult = new ArrayList<>(); //检查点属性 for (Map point : points) { //响应中断 if (Thread.interrupted()) throw new InterruptedException(); //获取图层 GisMetadataLayerTemplate layerTemplate = ThirdImportTemplateUtils .getLayerTemplate(point, pointLayerTemplates, GisMetadataDefine.TYPE_KINE.POINT); //图层不存在则加入无效图层结果 if (layerTemplate == null) invalidLayersResult.add(new GisSurveyThirdImportElement( GisMetadataDefine.TYPE_KINE.POINT, null, point.get(GisSurveyExcelDefine.FILE.POINT_LAYER), null )); else //图层存在则检查图层 checkLayer(point, layerTemplate, checkConstraint, projectConstraints, missingRequirementsResult, invalidTypesResult, outConstraintResult); //检查坐标超出范围 if (checkOutRanges(point, layerTemplate)) outRangesResult.add( new GisSurveyThirdImportElement( GisMetadataDefine.TYPE_KINE.POINT, ThirdImportTemplateUtils.getValue(point, layerTemplate, GisSurveyExcelDefine.TEMPLATE.NO), point.get(GisSurveyExcelDefine.FILE.POINT_LAYER), null ) ); } //检查线属性 for (Map line : lines) { //响应中断 if (Thread.interrupted()) throw new InterruptedException(); //过滤图层 GisMetadataLayerTemplate layerTemplate = ThirdImportTemplateUtils .getLayerTemplate(line, lineLayerTemplates, GisMetadataDefine.TYPE_KINE.LINE); //图层不存在则加入无效图层结果 if (layerTemplate == null) invalidLayersResult.add(new GisSurveyThirdImportElement( GisMetadataDefine.TYPE_KINE.LINE, null, null, line.get(GisSurveyExcelDefine.FILE.LINE_LAYER), null )); else //图层存在则检查图层 checkLayer(line, layerTemplate, checkConstraint, projectConstraints, missingRequirementsResult, invalidTypesResult, outConstraintResult); } long end = System.currentTimeMillis(); LogPrintMgr.getInstance().printLogMsg(LogLevelFlag.LOG_INFO, mBizType, mStrClassName , String.format( "结束执行寻找无效属性,用时(毫秒):%d" , (end - begin) ) ); //构建结果 Map> result = new HashMap<>(); result.put(GisSurveyExcelDefine.RESULT.INVALID_LAYERS, invalidLayersResult); result.put(GisSurveyExcelDefine.RESULT.MISSING_REQUIREMENTS, missingRequirementsResult); result.put(GisSurveyExcelDefine.RESULT.INVALID_TYPES, invalidTypesResult); result.put(GisSurveyExcelDefine.RESULT.OUT_RANGES, outRangesResult); result.put(GisSurveyExcelDefine.RESULT.OUT_CONSTRAINT, outConstraintResult); return new AsyncResult<>(new GisSurveyThirdImportResultDetail<>(true, result)); } /** * 检查超出范围 * * @param point 点 * @return 超出范围昨状态 */ public Boolean checkOutRanges(Map point, GisMetadataLayerTemplate layerTemplate) { //获取经纬度字段 String latStr = ThirdImportTemplateUtils.getValue(point, layerTemplate, GisSurveyExcelDefine.TEMPLATE.LAT); String lngStr = ThirdImportTemplateUtils.getValue(point, layerTemplate, GisSurveyExcelDefine.TEMPLATE.LNG); //检查是否字符串 if (StringUtils.isBlank(latStr) || StringUtils.isBlank(lngStr)) return true; //检查是否可解析 if (!NumberUtils.isParsable(latStr) || !NumberUtils.isParsable(lngStr)) return true; //解析 double lat = Double.parseDouble(latStr); double lng = Double.parseDouble(lngStr); //判断是否在范围 return MIN_LAT >= lat || lat >= MAX_LAT || MIN_LNG >= lng || lng >= MAX_LNG; } /** * 检查图层 * * @param data 数据 * @param layerTemplate 图层模版 * @param checkConstraint 检查超出约束 * @param projectConstraints 项目约束 * @param missingRequirementsResult 缺少必填结果 * @param invalidTypesResult 无效类型结果 * @param outConstraintResult 超出约束结果 */ public void checkLayer(Map data, GisMetadataLayerTemplate layerTemplate , Boolean checkConstraint, List projectConstraints, List missingRequirementsResult , List invalidTypesResult, List outConstraintResult) { //项目约束映射 Map projectConstraintsMapping = projectConstraints.stream() .filter(constraint -> Objects.equals(layerTemplate.getKind(), constraint.getKind())) .collect(Collectors.toMap(GisSurveyCondition::getProperty, it -> it)); //遍历图层属性模版 for (GisMetadataPropertyTemplate propertyTemplate : layerTemplate.getPropertyTemplates()) { //排除编码 if (Objects.equals(GisSurveyExcelDefine.TEMPLATE.CODE, propertyTemplate.getKey()) || Objects.equals(GisSurveyExcelDefine.TEMPLATE.UP_NODE, propertyTemplate.getKey()) || Objects.equals(GisSurveyExcelDefine.TEMPLATE.DOWN_NODE, propertyTemplate.getKey())) continue; //当前属性值 String value = data.get(propertyTemplate.getName()); //必填 if (propertyTemplate.getRequired() == 1 && propertyTemplate.getStatus() == 1) { //值不存在则存入缺少必填 if (StringUtils.isBlank(value)) { GisSurveyThirdImportElement gisSurveyThirdImportElement = GisSurveyThirdImportElement.create(data, layerTemplate, propertyTemplate.getName() ); missingRequirementsResult.add(gisSurveyThirdImportElement); //值存在 } else { //判断超出约束 checkOutConstraint( projectConstraintsMapping.get(propertyTemplate.getKey()), data, layerTemplate, propertyTemplate, value, outConstraintResult ); //判断数字类型 if ((GisSurveyExcelDefine.DATA_TYPE.INT.equals(propertyTemplate.getType()) || GisSurveyExcelDefine.DATA_TYPE.DOUBLE.equals(propertyTemplate.getType())) && !NumberUtils.isParsable(value)) { invalidTypesResult.add(GisSurveyThirdImportElement.create(data, layerTemplate, propertyTemplate.getName() )); } } } //非必填 else { //判断超出约束 if (checkConstraint && StringUtils.isNotBlank(value)) checkOutConstraint( projectConstraintsMapping.get(propertyTemplate.getKey()), data, layerTemplate, propertyTemplate, value, outConstraintResult ); } } } /** * 检查超出约束 * * @param projectConstraint 项目约束 * @param data 数据 * @param layerTemplate 图层模版 * @param propertyTemplate 属性模版 * @param value 值 * @param outConstraintResult 超出约束结果 */ public void checkOutConstraint(GisSurveyCondition projectConstraint, Map data , GisMetadataLayerTemplate layerTemplate, GisMetadataPropertyTemplate propertyTemplate , String value, List outConstraintResult) { GisSurveyCondition constraint = null; //模版约束 if (StringUtils.isNotBlank(propertyTemplate.getMode()) && CollectionUtils.isNotEmpty(propertyTemplate.getRanges())) { constraint = BeanUtil.copy(propertyTemplate, GisSurveyCondition.class); if (constraint != null) { constraint.setProperty(propertyTemplate.getKey()); constraint.setKind(layerTemplate.getKind()); } } //项目约束 if (projectConstraint != null) { constraint = projectConstraint; } if (constraint == null || StringUtils.isBlank(value)) return; //约束模式 String mode = constraint.getMode(); //约束范围 List ranges = constraint.getRanges(); if (StringUtils.isBlank(mode) || CollectionUtils.isEmpty(ranges)) return; //列表约束 if (Objects.equals("list", constraint.getMode())) { //如列表不包含值,则超出约束 if (!ranges.contains(value)) { outConstraintResult.add(GisSurveyThirdImportElement.create(data, layerTemplate, propertyTemplate.getName(), value, constraint )); } } //极值约束 else if (Objects.equals("extremum", constraint.getMode())) { if (ranges.size() != 2) return; //最小值判断 String minStr = ranges.get(0); if (StringUtils.isNotBlank(minStr) && NumberUtils.isParsable(minStr)) { double min = Double.parseDouble(minStr); if (!NumberUtils.isParsable(value) || Double.parseDouble(value) < min) { outConstraintResult.add(GisSurveyThirdImportElement.create(data, layerTemplate, propertyTemplate.getName(), value, constraint)); } } //最大值判断 String maxStr = ranges.get(1); if (StringUtils.isNotBlank(maxStr) && NumberUtils.isParsable(maxStr)) { double max = Double.parseDouble(maxStr); if (!NumberUtils.isParsable(value) || Double.parseDouble(value) > max) { outConstraintResult.add(GisSurveyThirdImportElement.create(data, layerTemplate, propertyTemplate.getName(), value, constraint)); } } } } }