Browse Source

LAANC 기준 바뀜에 따른 처리

pull/6/head
지대한 1 year ago
parent
commit
a333551eff
  1. 6
      pav-server/src/main/java/com/palnet/biz/api/bas/flight/model/BasFlightPlanLaancRs.java
  2. 16
      pav-server/src/main/java/com/palnet/biz/api/bas/flight/service/BasFlightService.java
  3. 139
      pav-server/src/main/java/com/palnet/comn/utils/AirspaceUtils.java

6
pav-server/src/main/java/com/palnet/biz/api/bas/flight/model/BasFlightPlanLaancRs.java

@ -25,13 +25,15 @@ public class BasFlightPlanLaancRs {
private String acrftInsuranceYn; // 항공기보험여부 private String acrftInsuranceYn; // 항공기보험여부
private String acrftDuplicatedYn; // 기체 중복여부 private String acrftDuplicatedYn; // 기체 중복여부
private String planAreaDuplicatdYn; // 비행계획서비행구역 중복여부 private String planAreaDuplicatdYn; // 비행계획서비행구역 중복여부
private String airspaceDuplicatedYn; // 공역 중복여부 private String evaluatedTargetAreaYn; // 평가대상지역여부 - 공역과 겹칠때만
private String flightAreaYn; // LAANC 기준 비행가능여부
public boolean isValid() { public boolean isValid() {
return "Y".equals(pilotQlfcYn) return "Y".equals(pilotQlfcYn)
&& "Y".equals(acrftInsuranceYn) && "Y".equals(acrftInsuranceYn)
&& "N".equals(acrftDuplicatedYn) && "N".equals(acrftDuplicatedYn)
&& "N".equals(planAreaDuplicatdYn) && "N".equals(planAreaDuplicatdYn)
&& "N".equals(airspaceDuplicatedYn); && "Y".equals(evaluatedTargetAreaYn)
&& "Y".equals(flightAreaYn);
} }
} }

16
pav-server/src/main/java/com/palnet/biz/api/bas/flight/service/BasFlightService.java

@ -151,9 +151,10 @@ public class BasFlightService {
BasFlightPlanLaancRs rs = BasFlightPlanLaancRs.builder() BasFlightPlanLaancRs rs = BasFlightPlanLaancRs.builder()
.pilotQlfcYn("N") .pilotQlfcYn("N")
.acrftInsuranceYn("N") .acrftInsuranceYn("N")
.airspaceDuplicatedYn("N")
.acrftDuplicatedYn("N") .acrftDuplicatedYn("N")
.planAreaDuplicatdYn("N") .planAreaDuplicatdYn("N")
.evaluatedTargetAreaYn("N")
.flightAreaYn("N")
.build(); .build();
boolean isEqualsFltElev = false; boolean isEqualsFltElev = false;
@ -295,8 +296,19 @@ public class BasFlightService {
Integer fltElev = Integer.valueOf(rqArea.getFltElev()); Integer fltElev = Integer.valueOf(rqArea.getFltElev());
if(fltElev == null) fltElev = 0; if(fltElev == null) fltElev = 0;
AirspaceUtils.FeatureInfo featureInfo = new AirspaceUtils.FeatureInfo(null, null, 0, fltElev, rqGeometry); AirspaceUtils.FeatureInfo featureInfo = new AirspaceUtils.FeatureInfo(null, null, 0, fltElev, rqGeometry);
// 평가 가능 지역 판단
boolean duplicatedAirspace = airspaceUtils.isDuplicatedAirspace(featureInfo); boolean duplicatedAirspace = airspaceUtils.isDuplicatedAirspace(featureInfo);
rs.setAirspaceDuplicatedYn(duplicatedAirspace ? "Y" : "N"); rs.setEvaluatedTargetAreaYn(duplicatedAirspace ? "Y" : "N");
// 비행 가능 지역 판단
if(duplicatedAirspace){
boolean validLaancAirspace = airspaceUtils.isValidLaancAirspace(featureInfo);
rs.setFlightAreaYn(validLaancAirspace ? "Y" : "N");
} else {
rs.setFlightAreaYn("N");
}
} }
return rs; return rs;
} }

139
pav-server/src/main/java/com/palnet/comn/utils/AirspaceUtils.java

@ -4,6 +4,7 @@ import lombok.AllArgsConstructor;
import lombok.Data; import lombok.Data;
import lombok.NoArgsConstructor; import lombok.NoArgsConstructor;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.apache.tomcat.util.modeler.FeatureInfo;
import org.geotools.geojson.feature.FeatureJSON; import org.geotools.geojson.feature.FeatureJSON;
import org.geotools.geojson.geom.GeometryJSON; import org.geotools.geojson.geom.GeometryJSON;
import org.json.simple.JSONArray; import org.json.simple.JSONArray;
@ -56,8 +57,17 @@ public class AirspaceUtils {
private static final AirspaceUtils INSTANCE = new AirspaceUtils(); private static final AirspaceUtils INSTANCE = new AirspaceUtils();
} }
// 공역 중복 검사 // 공영 중복 검사 - 고도x
public boolean isDuplicatedAirspace(FeatureInfo target) { public boolean isDuplicatedAirspace(FeatureInfo target) {
Geometry targetGeometry = target.getGeometry();
return this.airspaces.stream().anyMatch(featureInfo -> {
Geometry featureGeometry = featureInfo.getGeometry();
return featureGeometry.intersects(targetGeometry);
});
}
// 공역 중복 검사
public boolean isDuplicatedAirspaceElev(FeatureInfo target) {
if (this.airspaces == null || this.airspaces.isEmpty()) return true; if (this.airspaces == null || this.airspaces.isEmpty()) return true;
Integer targetHighElev = target.getHighElev(); Integer targetHighElev = target.getHighElev();
if (targetHighElev == null) targetHighElev = 0; if (targetHighElev == null) targetHighElev = 0;
@ -68,16 +78,47 @@ public class AirspaceUtils {
Geometry airspaceGeometry = airspace.getGeometry(); Geometry airspaceGeometry = airspace.getGeometry();
// 임시로 0~최대고도 기준으로 검증 // 임시로 0~최대고도 기준으로 검증
if(airspaceHighElev <= targetHighElev) { if (airspaceHighElev <= targetHighElev) {
if (airspaceGeometry.intersects(targetGeometry)) { if (airspaceGeometry.intersects(targetGeometry)) {
return true; return true;
} }
} }
} }
return false; return false;
} }
/*
LAANC 공역 검사
- 비행구역이 공역(금지구역) 접근할 경우만 검사 - 통과 true, 실패 false
- 겹치지 않을 경우는 실패로 처리 - false
*/
public boolean isValidLaancAirspace(FeatureInfo target) {
if (this.airspaces == null || this.airspaces.isEmpty()) return true;
final int targetHighElev = target.getHighElev() != null ? target.getHighElev() : 0;
Geometry targetGeometry = target.getGeometry();
boolean isDuplicated = this.airspaces.stream().anyMatch(featureInfo -> {
Geometry featureGeometry = featureInfo.getGeometry();
return featureGeometry.intersects(targetGeometry);
});
// 공역(금지구역)과 겹치지 않을 경우는 실패로 처리
if (!isDuplicated) return false;
// 겹칠 경우 공역과 비교
for (FeatureInfo featureInfo : this.airspaces) {
Geometry airspaceGeometry = featureInfo.getGeometry();
int airspaceHighElev = featureInfo.getHighElev() != null ? featureInfo.getHighElev() : 0;
// 임시로 0~최대고도 기준으로 검증
if (airspaceHighElev == 0 || airspaceHighElev < targetHighElev) {
if (airspaceGeometry.intersects(targetGeometry)) {
return false;
}
}
}
return true;
}
public Geometry createGeometryByCoordinate(List<Coordinate> target) { public Geometry createGeometryByCoordinate(List<Coordinate> target) {
return this.createGeometryByCoordinate(target, "Polygon"); return this.createGeometryByCoordinate(target, "Polygon");
} }
@ -102,11 +143,9 @@ public class AirspaceUtils {
// 파일에서 공역 데이터 가져와서 geometry로 변환 - 초기화. // 파일에서 공역 데이터 가져와서 geometry로 변환 - 초기화.
private void getResourceAirspace() { private void getResourceAirspace() {
ClassPathResource resource = new ClassPathResource(CLASS_PATH); ClassPathResource resource = new ClassPathResource(CLASS_PATH);
log.debug(">>> {}", resource);
List<File> geoJsonFiles = new ArrayList<>(); List<File> geoJsonFiles = new ArrayList<>();
try { try {
File folder = resource.getFile(); File folder = resource.getFile();
log.debug(">>> {}", folder);
File[] files = folder.listFiles(); File[] files = folder.listFiles();
for (File file : files) { for (File file : files) {
if (file.isFile() && file.getName().endsWith("elev.json")) { if (file.isFile() && file.getName().endsWith("elev.json")) {
@ -120,7 +159,6 @@ public class AirspaceUtils {
List<FeatureInfo> featureInfos = new ArrayList<>(); List<FeatureInfo> featureInfos = new ArrayList<>();
for (File file : geoJsonFiles) { for (File file : geoJsonFiles) {
log.debug("============ {} ===================", file.getName());
try (InputStreamReader isr = new InputStreamReader(new FileInputStream(file), StandardCharsets.UTF_8)) { try (InputStreamReader isr = new InputStreamReader(new FileInputStream(file), StandardCharsets.UTF_8)) {
JSONParser jsonParser = new JSONParser(); JSONParser jsonParser = new JSONParser();
JSONObject jsonObject = (JSONObject) jsonParser.parse(isr); JSONObject jsonObject = (JSONObject) jsonParser.parse(isr);
@ -253,12 +291,13 @@ public class AirspaceUtils {
*/ */
log.info("=== 김포 정상 ==="); log.info("=== 김포 정상 ===");
Coordinate[] polygonCoordinates6 = new Coordinate[]{ Coordinate[] polygonCoordinates6 = new Coordinate[]{
new Coordinate(126.6186219,37.4260888), new Coordinate(126.6186219, 37.4260888),
new Coordinate(126.7662507,37.4473521), new Coordinate(126.7662507, 37.4473521),
new Coordinate(126.7223054,37.3578964), new Coordinate(126.7223054, 37.3578964),
new Coordinate(126.6186219,37.4260888) new Coordinate(126.6186219, 37.4260888)
}; };
LinearRing linearRing6 = geometryFactory.createLinearRing(polygonCoordinates6); LinearRing linearRing6 = geometryFactory.createLinearRing(polygonCoordinates6);
Polygon polygon6 = geometryFactory.createPolygon(linearRing6); Polygon polygon6 = geometryFactory.createPolygon(linearRing6);
@ -266,15 +305,16 @@ public class AirspaceUtils {
target6.setHighElev(0); target6.setHighElev(0);
target6.setLowElev(0); target6.setLowElev(0);
target6.setGeometry(polygon6); target6.setGeometry(polygon6);
boolean duplicatedAirspace6 = airspaceUtils.isDuplicatedAirspace(target6); // boolean duplicatedAirspace6 = airspaceUtils.isDuplicatedAirspace(target6);
boolean duplicatedAirspace6 = airspaceUtils.isValidLaancAirspace(target6);
log.info(">>> duplicatedAirspace : {}", duplicatedAirspace6); log.info(">>> duplicatedAirspace : {}", duplicatedAirspace6);
log.info("=== 김포 120m 걸침 - 100 ==="); log.info("=== 김포 120m 걸침 - 100 ===");
Coordinate[] polygonCoordinates7 = new Coordinate[]{ Coordinate[] polygonCoordinates7 = new Coordinate[]{
new Coordinate(126.6828233,37.4553499), new Coordinate(126.6828233, 37.4553499),
new Coordinate(126.7456514,37.5082038), new Coordinate(126.7456514, 37.5082038),
new Coordinate(126.7796403,37.4414491), new Coordinate(126.7796403, 37.4414491),
new Coordinate(126.6828233,37.4553499) new Coordinate(126.6828233, 37.4553499)
}; };
LinearRing linearRing7 = geometryFactory.createLinearRing(polygonCoordinates7); LinearRing linearRing7 = geometryFactory.createLinearRing(polygonCoordinates7);
Polygon polygon7 = geometryFactory.createPolygon(linearRing7); Polygon polygon7 = geometryFactory.createPolygon(linearRing7);
@ -282,15 +322,16 @@ public class AirspaceUtils {
target7.setHighElev(100); target7.setHighElev(100);
target7.setLowElev(0); target7.setLowElev(0);
target7.setGeometry(polygon7); target7.setGeometry(polygon7);
boolean duplicatedAirspace7 = airspaceUtils.isDuplicatedAirspace(target7); // boolean duplicatedAirspace7 = airspaceUtils.isDuplicatedAirspace(target7);
boolean duplicatedAirspace7 = airspaceUtils.isValidLaancAirspace(target7);
log.info(">>> duplicatedAirspace : {}", duplicatedAirspace7); log.info(">>> duplicatedAirspace : {}", duplicatedAirspace7);
log.info("=== 김포 120m 걸침 - 150 ==="); log.info("=== 김포 120m 걸침 - 150 ===");
Coordinate[] polygonCoordinates8 = new Coordinate[]{ Coordinate[] polygonCoordinates8 = new Coordinate[]{
new Coordinate(126.6828233,37.4553499), new Coordinate(126.6828233, 37.4553499),
new Coordinate(126.7456514,37.5082038), new Coordinate(126.7456514, 37.5082038),
new Coordinate(126.7796403,37.4414491), new Coordinate(126.7796403, 37.4414491),
new Coordinate(126.6828233,37.4553499) new Coordinate(126.6828233, 37.4553499)
}; };
LinearRing linearRing8 = geometryFactory.createLinearRing(polygonCoordinates8); LinearRing linearRing8 = geometryFactory.createLinearRing(polygonCoordinates8);
Polygon polygon8 = geometryFactory.createPolygon(linearRing8); Polygon polygon8 = geometryFactory.createPolygon(linearRing8);
@ -298,15 +339,16 @@ public class AirspaceUtils {
target8.setHighElev(150); target8.setHighElev(150);
target8.setLowElev(0); target8.setLowElev(0);
target8.setGeometry(polygon8); target8.setGeometry(polygon8);
boolean duplicatedAirspace8 = airspaceUtils.isDuplicatedAirspace(target8); // boolean duplicatedAirspace8 = airspaceUtils.isDuplicatedAirspace(target8);
boolean duplicatedAirspace8 = airspaceUtils.isValidLaancAirspace(target8);
log.info(">>> duplicatedAirspace : {}", duplicatedAirspace8); log.info(">>> duplicatedAirspace : {}", duplicatedAirspace8);
log.info("=== 김포 120m 걸침 - 120 ==="); log.info("=== 김포 120m 걸침 - 120 ===");
Coordinate[] polygonCoordinates9 = new Coordinate[]{ Coordinate[] polygonCoordinates9 = new Coordinate[]{
new Coordinate(126.6828233,37.4553499), new Coordinate(126.6828233, 37.4553499),
new Coordinate(126.7456514,37.5082038), new Coordinate(126.7456514, 37.5082038),
new Coordinate(126.7796403,37.4414491), new Coordinate(126.7796403, 37.4414491),
new Coordinate(126.6828233,37.4553499) new Coordinate(126.6828233, 37.4553499)
}; };
LinearRing linearRing9 = geometryFactory.createLinearRing(polygonCoordinates9); LinearRing linearRing9 = geometryFactory.createLinearRing(polygonCoordinates9);
Polygon polygon9 = geometryFactory.createPolygon(linearRing9); Polygon polygon9 = geometryFactory.createPolygon(linearRing9);
@ -314,15 +356,16 @@ public class AirspaceUtils {
target9.setHighElev(120); target9.setHighElev(120);
target9.setLowElev(0); target9.setLowElev(0);
target9.setGeometry(polygon9); target9.setGeometry(polygon9);
boolean duplicatedAirspace9 = airspaceUtils.isDuplicatedAirspace(target9); // boolean duplicatedAirspace9 = airspaceUtils.isDuplicatedAirspace(target9);
boolean duplicatedAirspace9 = airspaceUtils.isValidLaancAirspace(target9);
log.info(">>> duplicatedAirspace : {}", duplicatedAirspace9); log.info(">>> duplicatedAirspace : {}", duplicatedAirspace9);
log.info("=== 김포 40m 걸침 - 20 ==="); log.info("=== 김포 40m 걸침 - 20 ===");
Coordinate[] polygonCoordinates10 = new Coordinate[]{ Coordinate[] polygonCoordinates10 = new Coordinate[]{
new Coordinate(126.6750825,37.5134229), new Coordinate(126.6750825, 37.5134229),
new Coordinate(126.7804826,37.5168269), new Coordinate(126.7804826, 37.5168269),
new Coordinate(126.7679513,37.4853679), new Coordinate(126.7679513, 37.4853679),
new Coordinate(126.6750825,37.5134229) new Coordinate(126.6750825, 37.5134229)
}; };
LinearRing linearRing10 = geometryFactory.createLinearRing(polygonCoordinates10); LinearRing linearRing10 = geometryFactory.createLinearRing(polygonCoordinates10);
Polygon polygon10 = geometryFactory.createPolygon(linearRing10); Polygon polygon10 = geometryFactory.createPolygon(linearRing10);
@ -330,15 +373,16 @@ public class AirspaceUtils {
target10.setHighElev(20); target10.setHighElev(20);
target10.setLowElev(0); target10.setLowElev(0);
target10.setGeometry(polygon10); target10.setGeometry(polygon10);
boolean duplicatedAirspace10 = airspaceUtils.isDuplicatedAirspace(target10); // boolean duplicatedAirspace10 = airspaceUtils.isDuplicatedAirspace(target10);
boolean duplicatedAirspace10 = airspaceUtils.isValidLaancAirspace(target10);
log.info(">>> duplicatedAirspace : {}", duplicatedAirspace10); log.info(">>> duplicatedAirspace : {}", duplicatedAirspace10);
log.info("=== 김포 40m 걸침 - 100 ==="); log.info("=== 김포 40m 걸침 - 100 ===");
Coordinate[] polygonCoordinates11 = new Coordinate[]{ Coordinate[] polygonCoordinates11 = new Coordinate[]{
new Coordinate(126.6750825,37.5134229), new Coordinate(126.6750825, 37.5134229),
new Coordinate(126.7804826,37.5168269), new Coordinate(126.7804826, 37.5168269),
new Coordinate(126.7679513,37.4853679), new Coordinate(126.7679513, 37.4853679),
new Coordinate(126.6750825,37.5134229) new Coordinate(126.6750825, 37.5134229)
}; };
LinearRing linearRing11 = geometryFactory.createLinearRing(polygonCoordinates11); LinearRing linearRing11 = geometryFactory.createLinearRing(polygonCoordinates11);
Polygon polygon11 = geometryFactory.createPolygon(linearRing11); Polygon polygon11 = geometryFactory.createPolygon(linearRing11);
@ -346,15 +390,16 @@ public class AirspaceUtils {
target11.setHighElev(100); target11.setHighElev(100);
target11.setLowElev(0); target11.setLowElev(0);
target11.setGeometry(polygon11); target11.setGeometry(polygon11);
boolean duplicatedAirspace11 = airspaceUtils.isDuplicatedAirspace(target11); // boolean duplicatedAirspace11 = airspaceUtils.isDuplicatedAirspace(target11);
boolean duplicatedAirspace11 = airspaceUtils.isValidLaancAirspace(target11);
log.info(">>> duplicatedAirspace : {}", duplicatedAirspace11); log.info(">>> duplicatedAirspace : {}", duplicatedAirspace11);
log.info("=== 김포 40m 걸침 - 40 ==="); log.info("=== 김포 40m 걸침 - 40 ===");
Coordinate[] polygonCoordinates12 = new Coordinate[]{ Coordinate[] polygonCoordinates12 = new Coordinate[]{
new Coordinate(126.6750825,37.5134229), new Coordinate(126.6750825, 37.5134229),
new Coordinate(126.7804826,37.5168269), new Coordinate(126.7804826, 37.5168269),
new Coordinate(126.7679513,37.4853679), new Coordinate(126.7679513, 37.4853679),
new Coordinate(126.6750825,37.5134229) new Coordinate(126.6750825, 37.5134229)
}; };
LinearRing linearRing12 = geometryFactory.createLinearRing(polygonCoordinates12); LinearRing linearRing12 = geometryFactory.createLinearRing(polygonCoordinates12);
Polygon polygon12 = geometryFactory.createPolygon(linearRing12); Polygon polygon12 = geometryFactory.createPolygon(linearRing12);
@ -362,15 +407,16 @@ public class AirspaceUtils {
target12.setHighElev(40); target12.setHighElev(40);
target12.setLowElev(0); target12.setLowElev(0);
target12.setGeometry(polygon12); target12.setGeometry(polygon12);
boolean duplicatedAirspace12 = airspaceUtils.isDuplicatedAirspace(target12); // boolean duplicatedAirspace12 = airspaceUtils.isDuplicatedAirspace(target12);
boolean duplicatedAirspace12 = airspaceUtils.isValidLaancAirspace(target12);
log.info(">>> duplicatedAirspace : {}", duplicatedAirspace12); log.info(">>> duplicatedAirspace : {}", duplicatedAirspace12);
log.info("=== 김포 0 ==="); log.info("=== 김포 0 ===");
Coordinate[] polygonCoordinates13 = new Coordinate[]{ Coordinate[] polygonCoordinates13 = new Coordinate[]{
new Coordinate(126.7679513,37.4853679), new Coordinate(126.7679513, 37.4853679),
new Coordinate(126.8074335,37.5572547), new Coordinate(126.8074335, 37.5572547),
new Coordinate(126.9097436,37.4477632), new Coordinate(126.9097436, 37.4477632),
new Coordinate(126.7679513,37.4853679) new Coordinate(126.7679513, 37.4853679)
}; };
LinearRing linearRing13 = geometryFactory.createLinearRing(polygonCoordinates13); LinearRing linearRing13 = geometryFactory.createLinearRing(polygonCoordinates13);
Polygon polygon13 = geometryFactory.createPolygon(linearRing13); Polygon polygon13 = geometryFactory.createPolygon(linearRing13);
@ -378,7 +424,8 @@ public class AirspaceUtils {
target13.setHighElev(0); target13.setHighElev(0);
target13.setLowElev(0); target13.setLowElev(0);
target13.setGeometry(polygon13); target13.setGeometry(polygon13);
boolean duplicatedAirspace13 = airspaceUtils.isDuplicatedAirspace(target13); // boolean duplicatedAirspace13 = airspaceUtils.isDuplicatedAirspace(target13);
boolean duplicatedAirspace13 = airspaceUtils.isValidLaancAirspace(target13);
log.info(">>> duplicatedAirspace : {}", duplicatedAirspace13); log.info(">>> duplicatedAirspace : {}", duplicatedAirspace13);
// 김포 // 김포

Loading…
Cancel
Save