Browse Source

feat: 결과에 최대 허용고도 추가

feature/address-coordinate
지대한 4 months ago
parent
commit
3c5ceecb63
  1. 3
      pav-server/src/main/java/com/palnet/biz/api/bas/dos/model/BasDosPlanAreaRs.java
  2. 3
      pav-server/src/main/java/com/palnet/biz/api/bas/dos/service/BasDosService.java
  3. 17
      pav-server/src/main/java/com/palnet/biz/api/external/model/DosApprovalResult.java
  4. 52
      pav-server/src/main/java/com/palnet/biz/api/external/service/DronOneStopService.java
  5. 3
      pav-server/src/main/java/com/palnet/biz/jpa/entity/DosFltPlanResult.java
  6. 56
      pav-server/src/test/java/com/palnet/biz/api/external/service/DronOneStopServiceTest.java

3
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;
// 경도

3
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<DosFltPlanResult> 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);

17
pav-server/src/main/java/com/palnet/biz/api/external/model/DosApprovalResult.java vendored

@ -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;
}

52
pav-server/src/main/java/com/palnet/biz/api/external/service/DronOneStopService.java vendored

@ -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<AirspaceUtils.FeatureInfo> 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;
}
}

3
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;

56
pav-server/src/test/java/com/palnet/biz/api/external/service/DronOneStopServiceTest.java vendored

@ -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<DosFltPlanResult> 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<DosFltPlanArea> areaList = dosFltPlanAreaRepository.findAll();
List<DosFltPlanResult> 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<DosFltPlanResult> 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);
}
}
}
}
Loading…
Cancel
Save