|
@@ -0,0 +1,391 @@
|
|
|
+package com.utic.ptis.server.service;
|
|
|
+
|
|
|
+import com.utic.common.utils.Elapsed;
|
|
|
+import com.utic.ptis.server.dto.LinkCollectDto;
|
|
|
+import com.utic.ptis.server.dto.LinkCollectResultDto;
|
|
|
+import com.utic.ptis.server.dto.LinkDto;
|
|
|
+import com.utic.ptis.server.dto.LinkTrafState;
|
|
|
+import com.utic.ptis.server.dto.utic.TrafficGrade;
|
|
|
+import lombok.Getter;
|
|
|
+import lombok.RequiredArgsConstructor;
|
|
|
+import lombok.extern.slf4j.Slf4j;
|
|
|
+import org.springframework.stereotype.Service;
|
|
|
+
|
|
|
+import java.util.ArrayList;
|
|
|
+import java.util.Optional;
|
|
|
+import java.util.concurrent.atomic.AtomicInteger;
|
|
|
+
|
|
|
+@Slf4j
|
|
|
+@Getter
|
|
|
+@RequiredArgsConstructor
|
|
|
+@Service
|
|
|
+public class LinkTrafMissingService implements AbstractProcessService {
|
|
|
+
|
|
|
+ private final LinkRepositoryService linkRepo;
|
|
|
+ private final LinkTrafParamService trafParamService;
|
|
|
+ private final LinkTrafCollectService collectService;
|
|
|
+
|
|
|
+ private void initialize() {
|
|
|
+ log.info("[MISSING] LinkTrafMissingService.initialize: start.");
|
|
|
+ Elapsed elapsed = new Elapsed();
|
|
|
+ log.info("[MISSING] LinkTrafMissingService.initialize: ..end. {}", Elapsed.elapsedStr(elapsed.nanoSeconds()));
|
|
|
+ }
|
|
|
+ public int processing() {
|
|
|
+ log.info("[MISSING] LinkTrafMissingService.processing: start.");
|
|
|
+ Elapsed elapsed = new Elapsed();
|
|
|
+
|
|
|
+ // 0. 결측 초기화
|
|
|
+ initialize();
|
|
|
+
|
|
|
+ // 모든 결측 알고리즘에 대해 결측 처리를 수행하고
|
|
|
+ // 최종 선택된 결측 알고리즘으로 결측을 수행한다.
|
|
|
+
|
|
|
+ // 1. PSD 알고리즘
|
|
|
+ missingLinkPsd();
|
|
|
+
|
|
|
+ // 2. 레벨1 구간 소통정보를 이용하여 레벨4 구간 소통정보 생성
|
|
|
+ groupLinkTrafficCreate(4, "P");
|
|
|
+
|
|
|
+ // 3. 레벨4 링크를 이용하여 레벨1 링크 PSD 결측정보 처리
|
|
|
+ missingGroupPsd();
|
|
|
+
|
|
|
+ // 4. 결측된 구간에 대하여 결측 알고리즘을 이용하여 속도 계산
|
|
|
+ missingLinkCorrect();
|
|
|
+
|
|
|
+ // 5. 패턴을 이용하여 결측 처리
|
|
|
+ missingLinkPattern();
|
|
|
+
|
|
|
+ // 6. 외부 연계 소통정보를 이용하여 결측 처리
|
|
|
+ missingLinkExternal();
|
|
|
+
|
|
|
+ // 7. 국토부 민간소통정보를 이용한 결측
|
|
|
+ // - 외부연계퓨전은 국토부 민간소통정보를 이용하여 결측처리하지 않으므로외부연계퓨전처리 완료후 결측을 처리함
|
|
|
+ missingLinkMoct();
|
|
|
+
|
|
|
+ // 8. 결측 처리된 레벨1 소통정보를 이용하여 상위레벨 소통정보를 생성(레벨2,3,4)
|
|
|
+ for (int ii = 2; ii <= 4; ii++) {
|
|
|
+ groupLinkTrafficCreate(ii, "P");
|
|
|
+ }
|
|
|
+
|
|
|
+ log.info("[MISSING] LinkTrafMissingService.processing: ..end. {}", Elapsed.elapsedStr(elapsed.nanoSeconds()));
|
|
|
+ return 0;
|
|
|
+ }
|
|
|
+
|
|
|
+ private int missingLinkMoct() {
|
|
|
+ log.info("[MISSING] LinkTrafMissingService.missingLinkMoct: start.");
|
|
|
+ Elapsed elapsed = new Elapsed();
|
|
|
+
|
|
|
+ // 결측처리 방식: 국토부 민간소통정보를 이용하여 결측
|
|
|
+ LinkCollectResultDto collectMOCT = Optional.ofNullable(this.collectService.get(LinkTrafCollectSetupService.MOCT))
|
|
|
+ .orElseGet(() -> LinkCollectResultDto.builder().clctSystCd(LinkTrafCollectSetupService.MOCT).lists(new ArrayList<>()).build());
|
|
|
+
|
|
|
+ int nCalCnt = 0;
|
|
|
+ for (LinkCollectDto clctTraf: collectMOCT.getLists()) {
|
|
|
+ LinkDto link = this.linkRepo.getLink(clctTraf.getLinkId());
|
|
|
+ if (link == null) {
|
|
|
+ log.error("[MISSING] LinkTrafMissingService.missingLinkMoct: {} link not found.", clctTraf.getLinkId());
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (link.getTrafFsn().getState().isState()) {
|
|
|
+ // 퓨전 소통정보가 존재하면 처리하지 않음
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ if (clctTraf.getSpeed() > 0) {
|
|
|
+ TrafficGrade grade = Optional.ofNullable(this.trafParamService.getTrafGradeMap().get(link.getLinkId()))
|
|
|
+ .orElseGet(() -> TrafficGrade.builder().roadRank("999").minSpeed(30).maxSpeed(49).build());
|
|
|
+ link.getTrafFsn().getState().setCrtDataType(LinkTrafState.TRAFFIC_CRT_DATA_TYPE.CRT_DATA_MISSING);
|
|
|
+ link.getTrafFsn().setTraffic(clctTraf.getCenterId(), clctTraf.getSpeed(), clctTraf.getMissValueYn(), clctTraf.getDataResType());
|
|
|
+ link.getTrafExt().trafficCorrect(link.getLength(), link.getMaxSpeed(), grade.getMinSpeed(), grade.getMaxSpeed());
|
|
|
+ nCalCnt++;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ log.info("[MISSING] LinkTrafMissingService.missingLinkMoct: ..end. {} EA. {}", nCalCnt, Elapsed.elapsedStr(elapsed.nanoSeconds()));
|
|
|
+ return nCalCnt;
|
|
|
+ }
|
|
|
+
|
|
|
+ private int missingLinkExternal() {
|
|
|
+ log.info("[MISSING] LinkTrafMissingService.missingLinkExternal: start.");
|
|
|
+ Elapsed elapsed = new Elapsed();
|
|
|
+
|
|
|
+ // 결측처리 방식: 구간의 현재 패턴정보를 이용
|
|
|
+ AtomicInteger nCalCnt = new AtomicInteger();
|
|
|
+ this.linkRepo.getLinkMap().values().parallelStream()
|
|
|
+ .filter(link -> link.getLinkLevel() == 1)
|
|
|
+ .forEach(link -> {
|
|
|
+ // 구간의 연계소통정보가 존재하면 처리하지 않음
|
|
|
+ if (link.getTrafExt().getState().isState()) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ // 구간의 퓨전소통정보가 존재하지 않으면 처리하지 못함
|
|
|
+ if (!link.getTrafFsn().getState().isState()) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 동부데이터가 들어가 있는것은 제외하여야 한다.
|
|
|
+ // 즉, 정상적으로 수집된 정보는 제외한다.(동부정보가 들어가있으므로)
|
|
|
+ if (link.getTrafFsn().getState().getCrtDataType() == LinkTrafState.TRAFFIC_CRT_DATA_TYPE.CRT_DATA_NORMAL) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ link.getTrafExt().copy(link.getTrafFsn());
|
|
|
+ nCalCnt.incrementAndGet();
|
|
|
+ }
|
|
|
+ );
|
|
|
+
|
|
|
+ log.info("[MISSING] LinkTrafMissingService.missingLinkExternal: ..end. {} EA. {}", nCalCnt.get(), Elapsed.elapsedStr(elapsed.nanoSeconds()));
|
|
|
+ return nCalCnt.get();
|
|
|
+ }
|
|
|
+
|
|
|
+ private int missingLinkPattern() {
|
|
|
+ log.info("[MISSING] LinkTrafMissingService.missingLinkPattern: start.");
|
|
|
+ Elapsed elapsed = new Elapsed();
|
|
|
+
|
|
|
+ // 결측처리 방식: 구간의 현재 패턴정보를 이용
|
|
|
+ AtomicInteger nCalCnt = new AtomicInteger();
|
|
|
+ this.linkRepo.getLinkMap().values().parallelStream()
|
|
|
+ .filter(link -> link.getLinkLevel() == 1)
|
|
|
+ .forEach(link -> {
|
|
|
+ // 구간의 퓨전소통정보가 존재하면 처리하지 않음
|
|
|
+ if (link.getTrafFsn().getState().isState()) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ // 구간의 패턴소통정보가 존재하지 않으면 처리하지 못함
|
|
|
+ if (!link.getTrafPtrn().getState().isState()) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (link.getTrafPtrn().getSpeed() > 0) {
|
|
|
+ TrafficGrade grade = Optional.ofNullable(this.trafParamService.getTrafGradeMap().get(link.getLinkId()))
|
|
|
+ .orElseGet(() -> TrafficGrade.builder().roadRank("999").minSpeed(30).maxSpeed(49).build());
|
|
|
+ link.getTrafFsn().getState().setCrtDataType(LinkTrafState.TRAFFIC_CRT_DATA_TYPE.CRT_DATA_MISSING);
|
|
|
+ link.getTrafFsn().setTraffic("C00", link.getTrafPtrn().getSpeed(), "T", "P");
|
|
|
+ link.getTrafExt().trafficCorrect(link.getLength(), link.getMaxSpeed(), grade.getMinSpeed(), grade.getMaxSpeed());
|
|
|
+ nCalCnt.incrementAndGet();
|
|
|
+ }
|
|
|
+ }
|
|
|
+ );
|
|
|
+
|
|
|
+ log.info("[MISSING] LinkTrafMissingService.missingLinkPattern: ..end. {} EA. {}", nCalCnt.get(), Elapsed.elapsedStr(elapsed.nanoSeconds()));
|
|
|
+ return nCalCnt.get();
|
|
|
+ }
|
|
|
+
|
|
|
+ private int missingLinkCorrect() {
|
|
|
+ log.info("[MISSING] LinkTrafMissingService.missingLinkCorrect: start.");
|
|
|
+ Elapsed elapsed = new Elapsed();
|
|
|
+
|
|
|
+ // 결측처리 방식: 우선순위, KNN(사용하지 않음)
|
|
|
+ AtomicInteger nCalCnt = new AtomicInteger();
|
|
|
+ this.linkRepo.getLinkMap().values().parallelStream()
|
|
|
+ .filter(link -> link.getLinkLevel() == 1)
|
|
|
+ .forEach(link -> {
|
|
|
+ // 구간의 퓨전소통정보가 존재하면 처리하지 않음
|
|
|
+ if (link.getTrafFsn().getState().isState()) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (link.getMissPsd().getSpeed() > 0) {
|
|
|
+ TrafficGrade grade = Optional.ofNullable(this.trafParamService.getTrafGradeMap().get(link.getLinkId()))
|
|
|
+ .orElseGet(() -> TrafficGrade.builder().roadRank("999").minSpeed(30).maxSpeed(49).build());
|
|
|
+ link.getTrafFsn().getState().setCrtDataType(LinkTrafState.TRAFFIC_CRT_DATA_TYPE.CRT_DATA_MISSING);
|
|
|
+ link.getTrafFsn().setTraffic("C00", link.getMissPsd().getSpeed(), link.getMissPsd().getMissValueYn(), "P");
|
|
|
+ link.getTrafExt().trafficCorrect(link.getLength(), link.getMaxSpeed(), grade.getMinSpeed(), grade.getMaxSpeed());
|
|
|
+ nCalCnt.incrementAndGet();
|
|
|
+ }
|
|
|
+ }
|
|
|
+ );
|
|
|
+
|
|
|
+ log.info("[MISSING] LinkTrafMissingService.missingLinkCorrect: ..end. {} EA. {}", nCalCnt.get(), Elapsed.elapsedStr(elapsed.nanoSeconds()));
|
|
|
+ return nCalCnt.get();
|
|
|
+ }
|
|
|
+
|
|
|
+ private int missingLinkPsd() {
|
|
|
+ log.info("[MISSING] LinkTrafMissingService.missingLinkPsd: start.");
|
|
|
+ Elapsed elapsed = new Elapsed();
|
|
|
+
|
|
|
+ /* PSD 알고리즘 결측정보 처리
|
|
|
+ * 1. 레벨1 구간에 대한 처리
|
|
|
+ * 2. 결측된 링크의 현재 패턴정보가 존재해야 처리할 수 있음.
|
|
|
+ * 3. 상/하류 구간의 현재/패턴 정보가 존재해야함.
|
|
|
+ * 3.1 상/하류 구간 정보가 모두 존재하는 경우
|
|
|
+ * 결측속도 = 결측구간 패턴속도 * { [AVG(상류부현재속도+하류부현재속도)] / [AVG(상류부패턴속도+하류부패턴속도)] }
|
|
|
+ * 3.2 상/하류 구간 중 하나의 구간 정보 만 존해하는 경우
|
|
|
+ * 결측속도 = 결측구간 패턴속도 * { 상/하류구간현재속도 / 상/하류구간패턴속도 }
|
|
|
+ * 4. 3항에서 결측한 결측 속도를 포함한 레벨4 구간의 속도정보를 계산
|
|
|
+ * 5. 결측이 발생한 레벨1 구간에 대해
|
|
|
+ * 결측속도 = 결측구간 패턴속도 * { 레벨4현재속도 / 레벨4패턴속도 }
|
|
|
+ */
|
|
|
+ AtomicInteger nCalCnt = new AtomicInteger();
|
|
|
+ this.linkRepo.getLinkMap().values().parallelStream()
|
|
|
+ .filter(link -> link.getLinkLevel() == 1)
|
|
|
+ .forEach(link -> {
|
|
|
+ // 구간의 패턴정보가 존재하지 않는 다면 결측 처리 못함
|
|
|
+ if (!link.getTrafPtrn().getState().isState()) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ LinkDto upLink = this.linkRepo.getLink(link.getUpLinkId());
|
|
|
+ LinkDto dnLink = this.linkRepo.getLink(link.getDnLinkId());
|
|
|
+
|
|
|
+ int step, speed;
|
|
|
+ float cSpeed, pSpeed, ptrnSpeed;
|
|
|
+ step = speed = 0;
|
|
|
+ cSpeed = pSpeed = 0F;
|
|
|
+ ptrnSpeed = (float)link.getTrafPtrn().getSpeed();
|
|
|
+
|
|
|
+ if (upLink != null) {
|
|
|
+ if (upLink.getTrafFsn().getState().isState() && upLink.getTrafPtrn().getState().isState()) {
|
|
|
+ // 상류 구간의 현재속도 정보와 패턴정보가 존재한다.
|
|
|
+ step += 1;
|
|
|
+ cSpeed += (float)upLink.getTrafFsn().getSpeed();
|
|
|
+ pSpeed += (float)upLink.getTrafPtrn().getSpeed();
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if (dnLink != null) {
|
|
|
+ if (dnLink.getTrafFsn().getState().isState() && dnLink.getTrafPtrn().getState().isState()) {
|
|
|
+ // 상류 구간의 현재속도 정보와 패턴정보가 존재한다.
|
|
|
+ step += 2;
|
|
|
+ cSpeed += (float)dnLink.getTrafFsn().getSpeed();
|
|
|
+ pSpeed += (float)dnLink.getTrafPtrn().getSpeed();
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ String missValueYn = "";
|
|
|
+ if (step == 1 || step == 2) {
|
|
|
+ // 상류부(H) 또는 하류부(L) 소통정보 만 존재하는 경우
|
|
|
+ speed = (int)( (ptrnSpeed * (cSpeed / pSpeed)) + 0.5 );
|
|
|
+ missValueYn = (step == 1) ? "H" : "L";
|
|
|
+ }
|
|
|
+ else if (step == 3) {
|
|
|
+ // 상/하류부 소통정보가 모두 존재하는 경우 'Y'
|
|
|
+ speed = (int)( (ptrnSpeed * ((cSpeed/2.) / (pSpeed/2.))) + 0.5 );
|
|
|
+ missValueYn = "Y";
|
|
|
+ }
|
|
|
+ if (speed > 0) {
|
|
|
+ if (speed > link.getMaxSpeed()) {
|
|
|
+ speed = link.getMaxSpeed();
|
|
|
+ }
|
|
|
+ link.getMissPsd().setTraffic(missValueYn, speed);
|
|
|
+ nCalCnt.incrementAndGet();
|
|
|
+ }
|
|
|
+ }
|
|
|
+ );
|
|
|
+
|
|
|
+ log.info("[MISSING] LinkTrafMissingService.missingLinkPsd: ..end. {} EA. {}", nCalCnt.get(), Elapsed.elapsedStr(elapsed.nanoSeconds()));
|
|
|
+ return nCalCnt.get();
|
|
|
+ }
|
|
|
+
|
|
|
+ private int groupLinkTrafficCreate(int linkLevel, String dataResType) {
|
|
|
+ log.info("[MISSING] LinkTrafMissingService.groupLinkTrafficCreate[Level:{}]: start.", linkLevel);
|
|
|
+ Elapsed elapsed = new Elapsed();
|
|
|
+ AtomicInteger nCalCnt = new AtomicInteger();
|
|
|
+
|
|
|
+ this.linkRepo.getLinkMap().values().parallelStream()
|
|
|
+ .filter(link -> link.getLinkLevel() == linkLevel)
|
|
|
+ .forEach(link -> {
|
|
|
+ // 링크그룹에 속한 레벨1 링크의 소통정보를 이용하여 링크그룹 소통정보를 생성한다.
|
|
|
+ if (link.getLinkIds() == null || link.getLinkIds().isEmpty()) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ float sumSpeed, sumLength, sumSpeedExt, sumLengthExt;
|
|
|
+ int clctCnt, clctCntExt;
|
|
|
+
|
|
|
+ sumSpeed = sumLength = sumSpeedExt = sumLengthExt = 0.F;
|
|
|
+ clctCntExt = clctCnt = 0;
|
|
|
+ for (String linkId : link.getLinkIds()) {
|
|
|
+ LinkDto subLink = this.linkRepo.getLink(linkId);
|
|
|
+ if (subLink == null) {
|
|
|
+ log.error("[MISSING] LinkTrafMissingService.groupLinkTrafficCreate[Level:{}]: {} link not found.", linkLevel, linkId);
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ if (!subLink.getTrafFsn().getState().isState()) {
|
|
|
+ // 퓨전 소통정보 생성
|
|
|
+ if (subLink.getTrafFsn().getSpeed() > 0) {
|
|
|
+ sumSpeed += subLink.getTrafFsn().getSpeed() * subLink.getLength();
|
|
|
+ sumLength += subLink.getLength();
|
|
|
+ clctCnt++;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if (!subLink.getTrafExt().getState().isState()) {
|
|
|
+ // 외부연계 소통정보 생성
|
|
|
+ if (subLink.getTrafExt().getSpeed() > 0) {
|
|
|
+ sumSpeedExt += subLink.getTrafExt().getSpeed() * subLink.getLength();
|
|
|
+ sumLengthExt += subLink.getLength();
|
|
|
+ clctCntExt++;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ TrafficGrade grade = Optional.ofNullable(this.trafParamService.getTrafGradeMap().get(link.getLinkId()))
|
|
|
+ .orElseGet(() -> TrafficGrade.builder().roadRank("999").minSpeed(30).maxSpeed(49).build());
|
|
|
+ if (sumSpeed > 0. && sumLength > 0. && clctCnt > 0) {
|
|
|
+ int speed = (int)( (sumSpeed / sumLength) + 0.5 );
|
|
|
+ link.getTrafFsn().setTraffic("C00", speed, "M", dataResType);
|
|
|
+ link.getTrafFsn().trafficCorrect(link.getLength(), link.getMaxSpeed(), grade.getMinSpeed(), grade.getMaxSpeed());
|
|
|
+ nCalCnt.incrementAndGet();
|
|
|
+ }
|
|
|
+ if (sumSpeedExt > 0. && sumLengthExt > 0. && clctCntExt > 0) {
|
|
|
+ int speedExt = (int)( (sumSpeedExt / sumLengthExt) + 0.5 );
|
|
|
+ link.getTrafExt().setTraffic("C00", speedExt, "M", dataResType);
|
|
|
+ link.getTrafExt().trafficCorrect(link.getLength(), link.getMaxSpeed(), grade.getMinSpeed(), grade.getMaxSpeed());
|
|
|
+ }
|
|
|
+ }
|
|
|
+ );
|
|
|
+
|
|
|
+ log.info("[MISSING] LinkTrafMissingService.groupLinkTrafficCreate[Level:{}]: ..end. {} EA. {}", linkLevel, nCalCnt.get(), Elapsed.elapsedStr(elapsed.nanoSeconds()));
|
|
|
+ return nCalCnt.get();
|
|
|
+ }
|
|
|
+
|
|
|
+ private int missingGroupPsd() {
|
|
|
+ log.info("[MISSING] LinkTrafMissingService.missingGroupPsd: start.");
|
|
|
+ Elapsed elapsed = new Elapsed();
|
|
|
+ AtomicInteger nCalCnt = new AtomicInteger();
|
|
|
+
|
|
|
+ // 레벨4 구간을 이용한 PSD 결측정보 처리
|
|
|
+ // 레벨1은 모든 구간에 대하여 PSD 알고리즘을 수행하고
|
|
|
+ // 레벨4 소통정보 다운 알고리즘은 생성되지 않은 레벨1 구간에 대하여 수행함
|
|
|
+ // PSD 상/하위 구간으로 처리하지 못한 구간에 대하여 4레벨 다운 소통정보를 생성
|
|
|
+ // 레벨1 PSD 속도 = 레벨1 패턴속도 * (레벨4 퓨전속도 / 레벨4 패턴속도)
|
|
|
+ this.linkRepo.getLinkMap().values().parallelStream()
|
|
|
+ .filter(link -> link.getLinkLevel() == 4)
|
|
|
+ .forEach(link -> {
|
|
|
+ if (link.getLinkIds() == null || link.getLinkIds().isEmpty()) {
|
|
|
+ // 레벨4 구간에 속한 레벨1 구간이 존재하지 않음
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (!link.getTrafFsn().getState().isState() || !link.getTrafPtrn().getState().isState()) {
|
|
|
+ // 레벨4 구간의 퓨전속도 또는 패턴속도가 존재하지 않으면 결측처리를 수행할 수 없다.
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ for (String linkId : link.getLinkIds()) {
|
|
|
+ LinkDto subLink = this.linkRepo.getLink(linkId);
|
|
|
+ if (subLink == null) {
|
|
|
+ log.error("[MISSING] LinkTrafMissingService.missingGroupPsd: {} link not found.", linkId);
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ if (subLink.getMissPsd().getSpeed() > 0) {
|
|
|
+ // 레벨1 구간의 PSD 속도정보가 존재하면 결측처리 수행하지 않음
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ if (!subLink.getTrafPtrn().getState().isState()) {
|
|
|
+ // 레벨1 구간의 패턴속도가 존재하지 않으면 결측처리 수행하지 않음
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ int speed = (int)( (subLink.getTrafPtrn().getSpeed() * ((double) link.getTrafFsn().getSpeed() / link.getTrafPtrn().getSpeed())) + 0.5 );
|
|
|
+ subLink.getMissPsd().setSpeed(speed);
|
|
|
+ subLink.getMissPsd().setMissValueYn("K");
|
|
|
+ if (subLink.getMissPsd().getSpeed() > subLink.getMaxSpeed()) {
|
|
|
+ subLink.getMissPsd().setSpeed(subLink.getMaxSpeed());
|
|
|
+ }
|
|
|
+ nCalCnt.incrementAndGet();
|
|
|
+ }
|
|
|
+ }
|
|
|
+ );
|
|
|
+
|
|
|
+ log.info("[MISSING] LinkTrafMissingService.missingGroupPsd: ..end. {} EA. {}", nCalCnt.get(), Elapsed.elapsedStr(elapsed.nanoSeconds()));
|
|
|
+ return nCalCnt.get();
|
|
|
+ }
|
|
|
+
|
|
|
+}
|