diff --git a/pav-server/src/main/java/com/palnet/biz/api/bas/dos/model/BasDosPlanAreaRs.java b/pav-server/src/main/java/com/palnet/biz/api/bas/dos/model/BasDosPlanAreaRs.java index 601c2a8f..f8f0eec8 100644 --- a/pav-server/src/main/java/com/palnet/biz/api/bas/dos/model/BasDosPlanAreaRs.java +++ b/pav-server/src/main/java/com/palnet/biz/api/bas/dos/model/BasDosPlanAreaRs.java @@ -4,7 +4,6 @@ import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; import lombok.NoArgsConstructor; -import org.locationtech.jts.geom.Coordinate; import java.time.Instant; import java.util.List; @@ -25,6 +24,8 @@ public class BasDosPlanAreaRs { private Double bufferZone; // 고도 private Double fltElev; + // 허용최대고도 + private Double fltElevMax; // 위도 private Double lat; // 경도 diff --git a/pav-server/src/main/java/com/palnet/biz/api/bas/dos/service/BasDosService.java b/pav-server/src/main/java/com/palnet/biz/api/bas/dos/service/BasDosService.java index 0a165118..2732a2be 100644 --- a/pav-server/src/main/java/com/palnet/biz/api/bas/dos/service/BasDosService.java +++ b/pav-server/src/main/java/com/palnet/biz/api/bas/dos/service/BasDosService.java @@ -65,9 +65,11 @@ public class BasDosService { if (area.getPlanSno().equals(planSno)) { Optional first = resultList.stream().filter(result -> result.getPlanAreaSno().equals(area.getPlanAreaSno())).findFirst(); String approvalCd = ""; + Double fltElevMax = null; if(first.isPresent()){ DosFltPlanResult dosFltPlanResult = first.get(); approvalCd = dosFltPlanResult.getApprovalCd(); + fltElevMax = dosFltPlanResult.getFltElevMax(); } if (rq.getApprovalCd() != null && !rq.getApprovalCd().equals(approvalCd)) { @@ -83,6 +85,7 @@ public class BasDosService { .lat(area.getLat()) .lon(area.getLon()) .approvalCd(approvalCd) + .fltElevMax(fltElevMax) .bufferCoordList(getBufferCoords(area)) .build(); areaRsList.add(areaRs); diff --git a/pav-server/src/main/java/com/palnet/biz/api/external/model/DosApprovalResult.java b/pav-server/src/main/java/com/palnet/biz/api/external/model/DosApprovalResult.java new file mode 100644 index 00000000..0b3fb73b --- /dev/null +++ b/pav-server/src/main/java/com/palnet/biz/api/external/model/DosApprovalResult.java @@ -0,0 +1,17 @@ +package com.palnet.biz.api.external.model; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@NoArgsConstructor +@AllArgsConstructor +@Builder +public class DosApprovalResult { + // 승인 코드 + private ApprovalCd approvalCd; + // 허용최대고도 + private Double fltElevMax; +} diff --git a/pav-server/src/main/java/com/palnet/biz/api/external/service/DronOneStopService.java b/pav-server/src/main/java/com/palnet/biz/api/external/service/DronOneStopService.java index 36100ae5..188fcc03 100644 --- a/pav-server/src/main/java/com/palnet/biz/api/external/service/DronOneStopService.java +++ b/pav-server/src/main/java/com/palnet/biz/api/external/service/DronOneStopService.java @@ -1,6 +1,7 @@ package com.palnet.biz.api.external.service; import com.palnet.biz.api.external.model.ApprovalCd; +import com.palnet.biz.api.external.model.DosApprovalResult; import com.palnet.biz.api.external.model.DosPlanRq; import com.palnet.biz.api.external.model.DosPlanRs; import com.palnet.biz.jpa.entity.DosFltPlanArea; @@ -102,8 +103,9 @@ public class DronOneStopService { // 좌표 추출 - 중심 좌표 Coordinate centerPoint = new Coordinate((Double) saveZone.get("lon"), (Double) saveZone.get("lat")); - ApprovalCd approvalCd = getApprovalCd(bufferZone, fltElev, centerPoint); - saveZone.put("approvalCd", approvalCd.getCode()); + DosApprovalResult approvalResult = getApprovalResult(bufferZone, fltElev, centerPoint); + saveZone.put("approvalCd", approvalResult.getApprovalCd().getCode()); + saveZone.put("fltElevMax", approvalResult.getFltElevMax()); }); // Laanc 결과 저장 @@ -112,6 +114,7 @@ public class DronOneStopService { .planSno((Long) saveZone.get("planSno")) .planAreaSno((Long) saveZone.get("planAreaSno")) .approvalCd((String) saveZone.get("approvalCd")) + .fltElevMax((Double) saveZone.get("fltElevMax")) .updateDt(Instant.now()) .createDt(Instant.now()) .build(); @@ -154,7 +157,8 @@ public class DronOneStopService { return rs; } - protected ApprovalCd getApprovalCd(Double bufferZone, Double fltElev, Coordinate centerPoint) { + protected DosApprovalResult getApprovalResult(Double bufferZone, Double fltElev, Coordinate centerPoint) { + DosApprovalResult result = new DosApprovalResult(); // Circle만 체크 // 좌표 추출 - 중심 좌표 // Buffer 추출 - 테두리 좌표 @@ -181,29 +185,35 @@ public class DronOneStopService { final double targetHighElev = targetfeatureInfo.getHighElev() != null ? targetfeatureInfo.getHighElev() : 0; Geometry targetGeometry = targetfeatureInfo.getGeometry(); - boolean isDuplicated = airspaces.stream().anyMatch(featureInfo -> { - Geometry featureGeometry = featureInfo.getGeometry(); - return featureGeometry.intersects(targetGeometry); - }); + // 중복되는 공역 추출 + List duplicatedAirspaces = airspaces.stream() + .filter(featureInfo -> featureInfo.getGeometry().intersects(targetGeometry)) + .collect(ArrayList::new, ArrayList::add, ArrayList::addAll); - // 공역(금지구역)과 겹치지 않을 경우는 "미대상 지역" - if (!isDuplicated) { - return ApprovalCd.UNTARGETED_AREA; + // 중복되는 공역이 없을 경우 "미대상 지역" + if(duplicatedAirspaces.isEmpty()) { + result.setApprovalCd(ApprovalCd.UNTARGETED_AREA); + return result; } - // 겹칠 경우 공역과 비교 - for (AirspaceUtils.FeatureInfo featureInfo : airspaces) { - Geometry airspaceGeometry = featureInfo.getGeometry(); - double airspaceHighElev = featureInfo.getHighElev() != null ? featureInfo.getHighElev() : 0; - // 0~최대고도 기준으로 검증 - if (airspaceHighElev == 0 || airspaceHighElev < targetHighElev) { - if (airspaceGeometry.intersects(targetGeometry)) { - return ApprovalCd.UNAPPROVED; - } - } + // 중복되는 공역으로 부터 가장 낮은 허용고도 추출 + double minHighElev = duplicatedAirspaces.stream() + .mapToDouble(AirspaceUtils.FeatureInfo::getHighElev) + .min() + .orElse(0); + + // 가장 낮음 허용고도보다 신청 고도가 낮을 경우 승인 처리 + result.setFltElevMax(minHighElev); + + if(targetHighElev > minHighElev) { + result.setApprovalCd(ApprovalCd.UNAPPROVED); + } else { + result.setApprovalCd(ApprovalCd.APPROVAL); } + return result; - return ApprovalCd.APPROVAL; } + + } diff --git a/pav-server/src/main/java/com/palnet/biz/jpa/entity/DosFltPlanResult.java b/pav-server/src/main/java/com/palnet/biz/jpa/entity/DosFltPlanResult.java index fdeb1dee..5db0b405 100644 --- a/pav-server/src/main/java/com/palnet/biz/jpa/entity/DosFltPlanResult.java +++ b/pav-server/src/main/java/com/palnet/biz/jpa/entity/DosFltPlanResult.java @@ -25,6 +25,9 @@ public class DosFltPlanResult { // 승인코드 @Column(name = "APPROVAL_CD") private String approvalCd; + // 허용최대고도 + @Column(name = "FLT_ELEV_MAX") + private Double fltElevMax; // 수정일시 @Column(name = "UPDATE_DT", columnDefinition = "TIMESTAMP") private Instant updateDt; diff --git a/pav-server/src/test/java/com/palnet/biz/api/external/service/DronOneStopServiceTest.java b/pav-server/src/test/java/com/palnet/biz/api/external/service/DronOneStopServiceTest.java index 93e06de7..1d6cf789 100644 --- a/pav-server/src/test/java/com/palnet/biz/api/external/service/DronOneStopServiceTest.java +++ b/pav-server/src/test/java/com/palnet/biz/api/external/service/DronOneStopServiceTest.java @@ -1,6 +1,6 @@ package com.palnet.biz.api.external.service; -import com.palnet.biz.api.external.model.ApprovalCd; +import com.palnet.biz.api.external.model.DosApprovalResult; import com.palnet.biz.jpa.entity.DosFltPlanArea; import com.palnet.biz.jpa.entity.DosFltPlanResult; import com.palnet.biz.jpa.repository.dos.DosFltPlanAreaRepository; @@ -16,7 +16,7 @@ import java.time.Instant; import java.util.List; import java.util.stream.Collectors; -@ActiveProfiles("prod") +@ActiveProfiles("local") @Slf4j @SpringBootTest class DronOneStopServiceTest { @@ -43,18 +43,18 @@ class DronOneStopServiceTest { Coordinate centerPoint = new Coordinate(area.getLon(), area.getLat()); // 검증 - ApprovalCd approvalCd = dronOneStopService.getApprovalCd(bufferZone, fltElev, centerPoint); + DosApprovalResult approvalResult = dronOneStopService.getApprovalResult(bufferZone, fltElev, centerPoint); List rList = resultList.stream().filter(result -> result.getPlanSno().equals(area.getPlanSno()) && result.getPlanAreaSno().equals(area.getPlanAreaSno())).collect(Collectors.toList()); log.info("rList size: {}", rList.size()); if(!rList.isEmpty()){ rList.forEach(r -> { - if(r.getApprovalCd().equals(approvalCd.getCode())) { + if(r.getApprovalCd().equals(approvalResult.getApprovalCd().getCode())) { log.info("approvalCd is same"); } else { - log.info("approvalCd is different{} -> {}", r.getApprovalCd(), approvalCd.getCode()); - r.setApprovalCd(approvalCd.getCode()); + log.info("approvalCd is different{} -> {}", r.getApprovalCd(), approvalResult.getApprovalCd().getCode()); + r.setApprovalCd(approvalResult.getApprovalCd().getCode()); r.setUpdateDt(Instant.now()); DosFltPlanResult save = dosFltPlanResultRepository.save(r); log.info("update: {}", save); @@ -66,16 +66,58 @@ class DronOneStopServiceTest { DosFltPlanResult dosFltPlanResultInsert = DosFltPlanResult.builder() .planSno(area.getPlanSno()) .planAreaSno(area.getPlanAreaSno()) - .approvalCd(approvalCd.getCode()) + .approvalCd(approvalResult.getApprovalCd().getCode()) .updateDt(Instant.now()) .createDt(Instant.now()) .build(); DosFltPlanResult save = dosFltPlanResultRepository.save(dosFltPlanResultInsert); log.info("insert: {}", save); } + } + } + + @Test + void updateFltElevMax() { + List areaList = dosFltPlanAreaRepository.findAll(); + List resultList = dosFltPlanResultRepository.findAll(); + + for(DosFltPlanArea area : areaList) { + // Circle만 체크 + Double bufferZone = area.getBufferZone(); + Double fltElev = area.getFltElev() != null ? area.getFltElev() : 0; + // 좌표 추출 - 중심 좌표 + Coordinate centerPoint = new Coordinate(area.getLon(), area.getLat()); + // 검증 + DosApprovalResult approvalResult = dronOneStopService.getApprovalResult(bufferZone, fltElev, centerPoint); + List rList = resultList.stream().filter(result -> result.getPlanSno().equals(area.getPlanSno()) && result.getPlanAreaSno().equals(area.getPlanAreaSno())).collect(Collectors.toList()); + log.info("rList size: {}", rList.size()); + if(!rList.isEmpty()){ + rList.forEach(r -> { + + if(r.getFltElevMax() == null){ + log.info("fltElevMax is null"); + r.setFltElevMax(approvalResult.getFltElevMax()); + r.setUpdateDt(Instant.now()); + DosFltPlanResult save = dosFltPlanResultRepository.save(r); + log.info("update: {}", save); + } + }); + } else { + log.info("result is empty"); + DosFltPlanResult dosFltPlanResultInsert = DosFltPlanResult.builder() + .planSno(area.getPlanSno()) + .planAreaSno(area.getPlanAreaSno()) + .approvalCd(approvalResult.getApprovalCd().getCode()) + .fltElevMax(approvalResult.getFltElevMax()) + .updateDt(Instant.now()) + .createDt(Instant.now()) + .build(); + DosFltPlanResult save = dosFltPlanResultRepository.save(dosFltPlanResultInsert); + log.info("insert: {}", save); + } } } } \ No newline at end of file