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.components.GisSurveySystemCheckResultManager;
import com.shkpr.service.alambizplugin.constants.GisSurveySystemCheckResultPath;
import com.shkpr.service.alambizplugin.constants.LogFlagBusiType;
import com.shkpr.service.alambizplugin.dto.GisSurveyLayerApplyLine;
import com.shkpr.service.alambizplugin.dto.GisSurveyLayerApplyPoint;
import com.shkpr.service.alambizplugin.dto.GisSurveySystemCheckElement;
import com.shkpr.service.alambizplugin.dto.GisSurveySystemCheckId;
import com.shkpr.service.alambizplugin.dto.GisSurveySystemCheckResultDetail;
import org.apache.commons.lang3.StringUtils;
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.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Objects;
import java.util.Set;
import java.util.stream.Collectors;
/**
* 寻找孤立点
*/
@Component
public class IsolatedPointsFinder {
/**
* log
*/
private final String mStrClassName;
private final String mBizType;
private final GisSurveySystemCheckResultManager systemCheckResultManager;
public IsolatedPointsFinder(GisSurveySystemCheckResultManager systemCheckResultManager) {
mStrClassName = "IsolatedPointsFinder";
mBizType = LogFlagBusiType.BUSI_GIS_SURVEY.toStrValue();
this.systemCheckResultManager = systemCheckResultManager;
}
/**
* 寻找孤立点
*
根据 {@code code} 上下游匹配,不涉及拓扑点
标识: {@code code} 唯一
*
* @param points 点集合
* @param lines 线集合
* @param systemCheckId 系统检查id
* @return 孤立点集合
*/
@Async
public ListenableFuture findIsolatedPoints(List points
, List lines, GisSurveySystemCheckId systemCheckId) throws InterruptedException {
LogPrintMgr.getInstance().printLogMsg(LogLevelFlag.LOG_INFO, mBizType, mStrClassName, "开始执行寻找孤立点========>");
long begin = System.currentTimeMillis();
//线为空,点不为空,则全孤立点
if (lines.isEmpty() && !points.isEmpty()) {
List elements = points.parallelStream()
//转为返回元素
.map(point -> BeanUtil.copy(point, GisSurveySystemCheckElement.class))
.collect(Collectors.toList());
return new AsyncResult<>(createResult(elements, systemCheckId, begin));
}
//线为空,点也为空,则无孤立点
if (lines.isEmpty()) return new AsyncResult<>(createResult(Collections.emptyList(), systemCheckId, begin));
//点为空,则无孤立点
if (points.isEmpty()) return new AsyncResult<>(createResult(Collections.emptyList(), systemCheckId, begin));
//计算预期最大容量,避免频繁扩容
int expectedMaxSize = (int) (((long) lines.size() << 1) / .75f + 1);
//联通点code
Set connectedPoints = new HashSet<>(expectedMaxSize);
//遍历所有线,标记参与的点
for (GisSurveyLayerApplyLine line : lines) {
//响应中断
if (Thread.interrupted()) throw new InterruptedException();
//上下游节点判空
if (StringUtils.isBlank(line.getUpNode()) || StringUtils.isBlank(line.getDownNode())) continue;
connectedPoints.add(line.getUpNode());
connectedPoints.add(line.getDownNode());
}
//使用并行流找出孤立点
List elements = points.parallelStream()
//转为返回元素
.map(point -> BeanUtil.copy(point, GisSurveySystemCheckElement.class))
//过滤连通点
.filter(element -> Objects.nonNull(element) && !connectedPoints.contains(element.getCode()))
.collect(Collectors.toList());
return new AsyncResult<>(createResult(elements, systemCheckId, begin));
}
/**
* 创建结果
*
* @param data 数据
* @param systemCheckId 系统检查id
* @param begin 开始时间
* @return 结果
*/
private GisSurveySystemCheckResultDetail createResult(List data
, GisSurveySystemCheckId systemCheckId, long begin) {
//数据大小
final int size = data.size();
//写入路径
String path = GisSurveySystemCheckResultPath.ISOLATED_POINTS;
//写入文件
systemCheckResultManager.writeResult(data, systemCheckId, path);
long end = System.currentTimeMillis();
LogPrintMgr.getInstance().printLogMsg(LogLevelFlag.LOG_INFO, mBizType, mStrClassName
, String.format(
"结束执行寻找孤立点,用时(毫秒):%d"
, (end - begin)
)
);
//构建结果
return new GisSurveySystemCheckResultDetail(true, GisSurveySystemCheckResultPath.relativePath(systemCheckId, path), size);
}
}