Browse Source

공역 유틸 생성 - singleton pattern

pull/6/head
지대한 1 year ago
parent
commit
6724b4f49a
  1. 456
      pav-server/src/main/java/com/palnet/comn/utils/AirspaceUtils.java
  2. 6
      pav-server/src/main/java/com/palnet/comn/utils/AreaUtils.java
  3. 14781
      pav-server/src/main/resources/air/airgeo.json
  4. 25326
      pav-server/src/main/resources/air/elev2d/airgeo-elev.json
  5. 5891
      pav-server/src/main/resources/air/elev2d/gimpo-airport-2d-elev.json
  6. 5
      pav-server/src/main/resources/air/sample/airgeo-3d.json
  7. 1820
      pav-server/src/main/resources/air/sample/airgeo-gimpo-airport.json
  8. 14786
      pav-server/src/main/resources/air/sample/gimpo-airport-2d-square.json
  9. 5
      pav-server/src/main/resources/air/sample/gimpo-airport-3d.json

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

@ -0,0 +1,456 @@
package com.palnet.comn.utils;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.geotools.geojson.feature.FeatureJSON;
import org.geotools.geojson.geom.GeometryJSON;
import org.json.simple.JSONArray;
import org.json.simple.JSONObject;
import org.json.simple.parser.JSONParser;
import org.locationtech.jts.geom.*;
import org.opengis.feature.simple.SimpleFeature;
import org.springframework.core.io.ClassPathResource;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.math.BigDecimal;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
/**
* packageName : com.palnet.comn.utils
* fileName : AirspaceUtils
* author : dhji
* date : 2023-09-20(020)
* description :
* ===========================================================
* DATE AUTHOR NOTE
* -----------------------------------------------------------
* 2023-09-20(020) dhji 최초 생성
*/
@Slf4j
public class AirspaceUtils {
private final String CLASS_PATH = "air/elev2d";
private final GeometryFactory geometryFactory = new GeometryFactory();
private List<FeatureInfo> airspaces;
private AirspaceUtils() {
log.info(">>> AirspaceUtils init...");
// 초기화
this.getResourceAirspace();
}
public static AirspaceUtils getInstance() {
return LazyHolder.INSTANCE;
}
private static class LazyHolder {
private static final AirspaceUtils INSTANCE = new AirspaceUtils();
}
// 공역 중복 검사
public boolean isDuplicatedAirspace(FeatureInfo target) {
if (this.airspaces == null || this.airspaces.isEmpty()) return true;
Integer targetHighElev = target.getHighElev();
if (targetHighElev == null) targetHighElev = 0;
Geometry targetGeometry = target.getGeometry();
for (FeatureInfo airspace : this.airspaces) {
Integer airspaceHighElev = airspace.getHighElev();
Geometry airspaceGeometry = airspace.getGeometry();
// 임시로 0~최대고도 기준으로 검증
if(airspaceHighElev <= targetHighElev) {
if (airspaceGeometry.intersects(targetGeometry)) {
return true;
}
}
}
return false;
}
public Geometry createGeometryByCoordinate(List<Coordinate> target) {
return this.createGeometryByCoordinate(target, "Polygon");
}
public Geometry createGeometryByCoordinate(List<Coordinate> target, String type) {
Geometry geometry = null;
if ("Polygon".equals(type)) {
geometry = this.geometryFactory.createPolygon(target.toArray(new Coordinate[0]));
} else if ("LineString".equals(type)) {
geometry = this.geometryFactory.createLineString(target.toArray(new Coordinate[0]));
} else if ("Point".equals(type)) {
geometry = this.geometryFactory.createPoint(target.get(0));
}
return geometry;
}
// get geometry
private List<Geometry> getAirspaceGeometry() {
return this.airspaces.stream().map(FeatureInfo::getGeometry).collect(Collectors.toList());
}
// 파일에서 공역 데이터 가져와서 geometry로 변환 - 초기화.
private void getResourceAirspace() {
ClassPathResource resource = new ClassPathResource(CLASS_PATH);
log.debug(">>> {}", resource);
List<File> geoJsonFiles = new ArrayList<>();
try {
File folder = resource.getFile();
log.debug(">>> {}", folder);
File[] files = folder.listFiles();
for (File file : files) {
if (file.isFile() && file.getName().endsWith("elev.json")) {
log.debug(">>> {}", file.getName());
geoJsonFiles.add(file);
}
}
} catch (IOException e) {
throw new RuntimeException(e);
}
List<FeatureInfo> featureInfos = new ArrayList<>();
for (File file : geoJsonFiles) {
log.debug("============ {} ===================", file.getName());
try (InputStreamReader isr = new InputStreamReader(new FileInputStream(file), StandardCharsets.UTF_8)) {
JSONParser jsonParser = new JSONParser();
JSONObject jsonObject = (JSONObject) jsonParser.parse(isr);
List<FeatureInfo> convertFeatureInfos = convertGeoJsonToGeometry(jsonObject);
featureInfos.addAll(convertFeatureInfos);
} catch (Exception e) {
log.error("ERROR : ", e);
featureInfos = null;
}
if (featureInfos != null && featureInfos.isEmpty()) {
featureInfos = null;
}
}
this.airspaces = featureInfos;
}
private List<FeatureInfo> convertGeoJsonToGeometry(JSONObject jsonObject) {
List<FeatureInfo> featureInfos = new ArrayList<>();
String type = (String) jsonObject.get("type");
if ("FeatureCollection".equals(type)) {
List<JSONObject> features = (List<JSONObject>) jsonObject.get("features");
// log.debug(">>> features size : {}", features.size());
for (JSONObject feature : features) {
JSONObject geometryObject = (JSONObject) feature.get("geometry");
String geometryType = String.valueOf(geometryObject.get("type"));
List<JSONObject> coordinatesObject = (List<JSONObject>) geometryObject.get("coordinates");
if ("Polygon".equals(geometryType)) {
List<JSONArray> innerObject = (List<JSONArray>) coordinatesObject.get(0);
JSONArray firstCoords = innerObject.get(0);
JSONArray lastCoords = innerObject.get(innerObject.size() - 1);
BigDecimal ff = new BigDecimal(String.valueOf(firstCoords.get(0)));
BigDecimal fl = new BigDecimal(String.valueOf(firstCoords.get(1)));
BigDecimal lf = new BigDecimal(String.valueOf(lastCoords.get(0)));
BigDecimal ll = new BigDecimal(String.valueOf(lastCoords.get(1)));
if (!ff.equals(lf) || !fl.equals(ll)) {
JSONObject propertiesObject = (JSONObject) feature.get("properties");
// String nameObject = String.valueOf(propertiesObject.get("name"));
// String descriptionObject = String.valueOf(propertiesObject.get("description"));
// log.info("coords first and last coords not eqauls : name/descriion = {}/{}", nameObject, descriptionObject);
innerObject.add(firstCoords);
}
}
try {
FeatureJSON featureJSON = new FeatureJSON();
SimpleFeature simpleFeature = null;
simpleFeature = featureJSON.readFeature(feature.toJSONString());
Boolean use = Boolean.valueOf(String.valueOf(simpleFeature.getAttribute("use")));
if (use) {
String name = String.valueOf(simpleFeature.getAttribute("name"));
String description = String.valueOf(simpleFeature.getAttribute("description"));
Integer lowElev = Integer.parseInt(String.valueOf(simpleFeature.getAttribute("lowElev")));
Integer highElev = Integer.parseInt(String.valueOf(simpleFeature.getAttribute("highElev")));
Geometry geometry = (Geometry) simpleFeature.getDefaultGeometry();
// log.debug(">>> name, description, use, lowElev, highElev : {}, {}, {}, {}, {}", name, description, use, lowElev, highElev);
FeatureInfo info = new FeatureInfo(name, description, lowElev, highElev, geometry);
featureInfos.add(info);
}
} catch (IOException e) {
log.error("geometry json read error : {}", e.getMessage());
}
}
} else if ("Feature".equals(type)) {
FeatureJSON featureJSON = new FeatureJSON();
try {
SimpleFeature simpleFeature = featureJSON.readFeature(jsonObject.toJSONString());
Boolean use = Boolean.valueOf(String.valueOf(simpleFeature.getAttribute("use")));
if (use) {
String name = String.valueOf(simpleFeature.getAttribute("name"));
String description = String.valueOf(simpleFeature.getAttribute("description"));
Integer lowElev = Integer.parseInt(String.valueOf(simpleFeature.getAttribute("lowElev")));
Integer highElev = Integer.parseInt(String.valueOf(simpleFeature.getAttribute("highElev")));
Geometry geometry = (Geometry) simpleFeature.getDefaultGeometry();
FeatureInfo info = new FeatureInfo(name, description, lowElev, highElev, geometry);
featureInfos.add(info);
}
} catch (IOException e) {
log.error("geometry json read error : {}", e.getMessage());
}
} else {
GeometryJSON geoJson = new GeometryJSON();
try {
Geometry geometry = geoJson.read(jsonObject.toJSONString());
FeatureInfo info = new FeatureInfo(null, null, null, null, geometry);
} catch (IOException e) {
log.error("geometry json read error : {}", e.getMessage());
}
}
return featureInfos;
}
@Data
@NoArgsConstructor
@AllArgsConstructor
public static class FeatureInfo {
private String name;
private String description;
private Integer lowElev;
private Integer highElev;
private Geometry geometry;
}
public static void main(String[] args) {
AirspaceUtils airspaceUtils = AirspaceUtils.getInstance();
GeometryFactory geometryFactory = new GeometryFactory();
/*
126.6186219,37.4260888
126.7662507,37.4473521
126.7223054,37.3578964
126.6186219,37.4260888
126.6828233,37.4553499
126.7456514,37.5082038
126.7796403,37.4414491
126.6828233,37.4553499
126.6750825,37.5134229
126.7804826,37.5168269
126.7679513,37.4853679
126.6750825,37.5134229
126.7679513,37.4853679
126.8074335,37.5572547
126.9097436,37.4477632
126.7679513,37.4853679
*/
log.info("=== 김포 정상 ===");
Coordinate[] polygonCoordinates6 = new Coordinate[]{
new Coordinate(126.6186219,37.4260888),
new Coordinate(126.7662507,37.4473521),
new Coordinate(126.7223054,37.3578964),
new Coordinate(126.6186219,37.4260888)
};
LinearRing linearRing6 = geometryFactory.createLinearRing(polygonCoordinates6);
Polygon polygon6 = geometryFactory.createPolygon(linearRing6);
FeatureInfo target6 = new FeatureInfo();
target6.setHighElev(0);
target6.setLowElev(0);
target6.setGeometry(polygon6);
boolean duplicatedAirspace6 = airspaceUtils.isDuplicatedAirspace(target6);
log.info(">>> duplicatedAirspace : {}", duplicatedAirspace6);
log.info("=== 김포 120m 걸침 - 100 ===");
Coordinate[] polygonCoordinates7 = new Coordinate[]{
new Coordinate(126.6828233,37.4553499),
new Coordinate(126.7456514,37.5082038),
new Coordinate(126.7796403,37.4414491),
new Coordinate(126.6828233,37.4553499)
};
LinearRing linearRing7 = geometryFactory.createLinearRing(polygonCoordinates7);
Polygon polygon7 = geometryFactory.createPolygon(linearRing7);
FeatureInfo target7 = new FeatureInfo();
target7.setHighElev(100);
target7.setLowElev(0);
target7.setGeometry(polygon7);
boolean duplicatedAirspace7 = airspaceUtils.isDuplicatedAirspace(target7);
log.info(">>> duplicatedAirspace : {}", duplicatedAirspace7);
log.info("=== 김포 120m 걸침 - 150 ===");
Coordinate[] polygonCoordinates8 = new Coordinate[]{
new Coordinate(126.6828233,37.4553499),
new Coordinate(126.7456514,37.5082038),
new Coordinate(126.7796403,37.4414491),
new Coordinate(126.6828233,37.4553499)
};
LinearRing linearRing8 = geometryFactory.createLinearRing(polygonCoordinates8);
Polygon polygon8 = geometryFactory.createPolygon(linearRing8);
FeatureInfo target8 = new FeatureInfo();
target8.setHighElev(150);
target8.setLowElev(0);
target8.setGeometry(polygon8);
boolean duplicatedAirspace8 = airspaceUtils.isDuplicatedAirspace(target8);
log.info(">>> duplicatedAirspace : {}", duplicatedAirspace8);
log.info("=== 김포 120m 걸침 - 120 ===");
Coordinate[] polygonCoordinates9 = new Coordinate[]{
new Coordinate(126.6828233,37.4553499),
new Coordinate(126.7456514,37.5082038),
new Coordinate(126.7796403,37.4414491),
new Coordinate(126.6828233,37.4553499)
};
LinearRing linearRing9 = geometryFactory.createLinearRing(polygonCoordinates9);
Polygon polygon9 = geometryFactory.createPolygon(linearRing9);
FeatureInfo target9 = new FeatureInfo();
target9.setHighElev(120);
target9.setLowElev(0);
target9.setGeometry(polygon9);
boolean duplicatedAirspace9 = airspaceUtils.isDuplicatedAirspace(target9);
log.info(">>> duplicatedAirspace : {}", duplicatedAirspace9);
log.info("=== 김포 40m 걸침 - 20 ===");
Coordinate[] polygonCoordinates10 = new Coordinate[]{
new Coordinate(126.6750825,37.5134229),
new Coordinate(126.7804826,37.5168269),
new Coordinate(126.7679513,37.4853679),
new Coordinate(126.6750825,37.5134229)
};
LinearRing linearRing10 = geometryFactory.createLinearRing(polygonCoordinates10);
Polygon polygon10 = geometryFactory.createPolygon(linearRing10);
FeatureInfo target10 = new FeatureInfo();
target10.setHighElev(20);
target10.setLowElev(0);
target10.setGeometry(polygon10);
boolean duplicatedAirspace10 = airspaceUtils.isDuplicatedAirspace(target10);
log.info(">>> duplicatedAirspace : {}", duplicatedAirspace10);
log.info("=== 김포 40m 걸침 - 100 ===");
Coordinate[] polygonCoordinates11 = new Coordinate[]{
new Coordinate(126.6750825,37.5134229),
new Coordinate(126.7804826,37.5168269),
new Coordinate(126.7679513,37.4853679),
new Coordinate(126.6750825,37.5134229)
};
LinearRing linearRing11 = geometryFactory.createLinearRing(polygonCoordinates11);
Polygon polygon11 = geometryFactory.createPolygon(linearRing11);
FeatureInfo target11 = new FeatureInfo();
target11.setHighElev(100);
target11.setLowElev(0);
target11.setGeometry(polygon11);
boolean duplicatedAirspace11 = airspaceUtils.isDuplicatedAirspace(target11);
log.info(">>> duplicatedAirspace : {}", duplicatedAirspace11);
log.info("=== 김포 40m 걸침 - 40 ===");
Coordinate[] polygonCoordinates12 = new Coordinate[]{
new Coordinate(126.6750825,37.5134229),
new Coordinate(126.7804826,37.5168269),
new Coordinate(126.7679513,37.4853679),
new Coordinate(126.6750825,37.5134229)
};
LinearRing linearRing12 = geometryFactory.createLinearRing(polygonCoordinates12);
Polygon polygon12 = geometryFactory.createPolygon(linearRing12);
FeatureInfo target12 = new FeatureInfo();
target12.setHighElev(40);
target12.setLowElev(0);
target12.setGeometry(polygon12);
boolean duplicatedAirspace12 = airspaceUtils.isDuplicatedAirspace(target12);
log.info(">>> duplicatedAirspace : {}", duplicatedAirspace12);
log.info("=== 김포 0 ===");
Coordinate[] polygonCoordinates13 = new Coordinate[]{
new Coordinate(126.7679513,37.4853679),
new Coordinate(126.8074335,37.5572547),
new Coordinate(126.9097436,37.4477632),
new Coordinate(126.7679513,37.4853679)
};
LinearRing linearRing13 = geometryFactory.createLinearRing(polygonCoordinates13);
Polygon polygon13 = geometryFactory.createPolygon(linearRing13);
FeatureInfo target13 = new FeatureInfo();
target13.setHighElev(0);
target13.setLowElev(0);
target13.setGeometry(polygon13);
boolean duplicatedAirspace13 = airspaceUtils.isDuplicatedAirspace(target13);
log.info(">>> duplicatedAirspace : {}", duplicatedAirspace13);
// 김포
// log.info("=== 김포 걸침 ===");
// Coordinate[] polygonCoordinates = new Coordinate[]{
// new Coordinate(126.6932891, 37.4789188),
// new Coordinate(126.7343162, 37.4989414),
// new Coordinate(126.729853, 37.4676111),
// new Coordinate(126.6932891, 37.4789188)
// };
// LinearRing linearRing = geometryFactory.createLinearRing(polygonCoordinates);
// Polygon polygon = geometryFactory.createPolygon(linearRing);
// FeatureInfo target = new FeatureInfo();
// target.setHighElev(0);
// target.setLowElev(0);
// target.setGeometry(polygon);
// boolean duplicatedAirspace = airspaceUtils.isDuplicatedAirspace(target);
// log.info(">>> duplicatedAirspace : {}", duplicatedAirspace);
//
// // 인천공항
// log.info("=== 인천공항 걸침 ===");
// Coordinate[] polygonCoordinates2 = new Coordinate[]{
// new Coordinate(126.57605, 37.3278721),
// new Coordinate(126.4181215, 37.4691545),
// new Coordinate(126.6351015, 37.5203648),
// new Coordinate(126.57605, 37.3278721)
// };
// LinearRing linearRing2 = geometryFactory.createLinearRing(polygonCoordinates2);
// Polygon polygon2 = geometryFactory.createPolygon(linearRing2);
// FeatureInfo target2 = new FeatureInfo();
// target2.setHighElev(0);
// target2.setLowElev(0);
// target2.setGeometry(polygon2);
// boolean duplicatedAirspace2 = airspaceUtils.isDuplicatedAirspace(target2);
// log.info(">>> duplicatedAirspace : {}", duplicatedAirspace2);
//
//
//
// // 정상
// log.info("=== 정상(안겹침) ===");
// Coordinate[] polygonCoordinates3 = new Coordinate[]{
// new Coordinate(126.6879518, 37.4444476),
// new Coordinate(126.6179139, 37.3462549),
// new Coordinate(126.7820222, 37.3528051),
// new Coordinate(126.6879518, 37.4444476)
// };
// LinearRing linearRing3 = geometryFactory.createLinearRing(polygonCoordinates3);
// Polygon polygon3 = geometryFactory.createPolygon(linearRing3);
// FeatureInfo target3 = new FeatureInfo();
// target3.setHighElev(0);
// target3.setLowElev(0);
// target3.setGeometry(polygon3);
// boolean duplicatedAirspace3 = airspaceUtils.isDuplicatedAirspace(target3);
// log.info(">>> duplicatedAirspace : {}", duplicatedAirspace3);
//
//
// // 수원 완전 포함
// log.info("=== 수원 포함 ===");
// Coordinate[] polygonCoordinates4 = new Coordinate[]{
// new Coordinate(126.9475038,37.2212829),
// new Coordinate(127.0226914,37.2857752),
// new Coordinate(127.0525605,37.192845),
// new Coordinate(126.9475038,37.2212829)
// };
// LinearRing linearRing4 = geometryFactory.createLinearRing(polygonCoordinates4);
// Polygon polygon4 = geometryFactory.createPolygon(linearRing4);
// FeatureInfo target4 = new FeatureInfo();
// target4.setHighElev(0);
// target4.setLowElev(0);
// target4.setGeometry(polygon4);
// boolean duplicatedAirspace4 = airspaceUtils.isDuplicatedAirspace(target4);
// log.info(">>> duplicatedAirspace : {}", duplicatedAirspace4);
}
}

6
pav-server/src/main/java/com/palnet/comn/utils/AreaUtils.java

@ -6,7 +6,6 @@ import org.json.simple.JSONArray;
import org.json.simple.JSONObject;
import org.json.simple.parser.JSONParser;
import org.locationtech.jts.geom.*;
import org.locationtech.jts.geom.impl.CoordinateArraySequence;
import org.locationtech.jts.operation.buffer.BufferOp;
import org.locationtech.jts.operation.buffer.BufferParameters;
import org.locationtech.jts.util.GeometricShapeFactory;
@ -16,10 +15,11 @@ import org.locationtech.proj4j.CoordinateReferenceSystem;
import org.locationtech.proj4j.ProjCoordinate;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
import org.springframework.stereotype.Component;
import java.io.*;
import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

14781
pav-server/src/main/resources/air/airgeo.json

File diff suppressed because it is too large Load Diff

25326
pav-server/src/main/resources/air/elev2d/airgeo-elev.json

File diff suppressed because it is too large Load Diff

5891
pav-server/src/main/resources/air/elev2d/gimpo-airport-2d-elev.json

File diff suppressed because it is too large Load Diff

5
pav-server/src/main/resources/air/sample/airgeo-3d.json

@ -0,0 +1,5 @@
{
"type": "FeatureCollection",
"features": [
]
}

1820
pav-server/src/main/resources/air/sample/airgeo-gimpo-airport.json

File diff suppressed because it is too large Load Diff

14786
pav-server/src/main/resources/air/sample/gimpo-airport-2d-square.json

File diff suppressed because it is too large Load Diff

5
pav-server/src/main/resources/air/sample/gimpo-airport-3d.json

@ -0,0 +1,5 @@
{
"type": "FeatureCollection",
"features": [
]
}
Loading…
Cancel
Save