diff --git a/pav-server/src/main/java/com/palnet/biz/config/InitRunner.java b/pav-server/src/main/java/com/palnet/biz/config/InitRunner.java index a9ccbe37..f79a9b6c 100644 --- a/pav-server/src/main/java/com/palnet/biz/config/InitRunner.java +++ b/pav-server/src/main/java/com/palnet/biz/config/InitRunner.java @@ -1,5 +1,6 @@ package com.palnet.biz.config; +import com.palnet.comn.utils.AirAreaUtils; import com.palnet.comn.utils.AirspaceUtils; import com.palnet.comn.utils.CoordUtils; import com.palnet.comn.utils.DigitalElevationModelUtils; @@ -8,6 +9,9 @@ import org.springframework.boot.ApplicationArguments; import org.springframework.boot.ApplicationRunner; import org.springframework.stereotype.Component; +import java.util.List; +import java.util.Map; + @Slf4j @Component public class InitRunner implements ApplicationRunner { @@ -33,8 +37,17 @@ public class InitRunner implements ApplicationRunner { CoordUtils coordUtils = CoordUtils.getInstance(); log.info("coord size : {}", coordUtils.getSize()); } catch (Exception e) { - log.warn("===== InitRunner run error[AirspaceUtils] : {}", e.getMessage()); + log.warn("===== InitRunner run error[CoordUtils] : {}", e.getMessage()); + } + try { + AirAreaUtils aaUtils = AirAreaUtils.getInstance(); + log.info("Air Area Count : {}", aaUtils.getSize()); + Map> airMap = aaUtils.getAirAreaMap(); + airMap.forEach((k, v) -> { + log.info("{} - {}", k, v.size()); + }); + } catch (Exception e) { + log.warn("===== InitRunner run error[AirAreaUtils] : {}", e.getMessage()); } - } } diff --git a/pav-server/src/main/java/com/palnet/comn/utils/AirAreaUtils.java b/pav-server/src/main/java/com/palnet/comn/utils/AirAreaUtils.java index 4d401595..86695ee6 100644 --- a/pav-server/src/main/java/com/palnet/comn/utils/AirAreaUtils.java +++ b/pav-server/src/main/java/com/palnet/comn/utils/AirAreaUtils.java @@ -13,9 +13,15 @@ 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.operation.buffer.BufferOp; +import org.locationtech.jts.operation.buffer.BufferParameters; +import org.locationtech.proj4j.BasicCoordinateTransform; +import org.locationtech.proj4j.CRSFactory; +import org.locationtech.proj4j.ProjCoordinate; import org.opengis.feature.simple.SimpleFeature; import org.opengis.referencing.crs.CoordinateReferenceSystem; import org.opengis.referencing.operation.TransformException; +import org.springframework.cache.annotation.Cacheable; import org.springframework.core.io.Resource; import org.springframework.core.io.support.PathMatchingResourcePatternResolver; import org.springframework.core.io.support.ResourcePatternResolver; @@ -26,10 +32,7 @@ import java.io.InputStream; import java.io.InputStreamReader; import java.math.BigDecimal; import java.nio.charset.StandardCharsets; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; +import java.util.*; import java.util.stream.Collectors; // TODO areaUtils, airspaceUtils merge @@ -659,25 +662,102 @@ public class AirAreaUtils { return originalGeometry; // Return the original geometry if type is not handled } + // ---------------------- AreaUtils ---------------------- + + /** + * 좌표계 변환 + * + * @param coordList + * @param from + * @param to + * @return + */ + @Cacheable(value = "coordTransform") + public List transform(List coordList, String from, String to) { + CRSFactory factory = new CRSFactory(); + + org.locationtech.proj4j.CoordinateReferenceSystem srcCRS = factory.createFromName(from); + org.locationtech.proj4j.CoordinateReferenceSystem tgtCRS = factory.createFromName(to); + + BasicCoordinateTransform transform = new BasicCoordinateTransform(srcCRS, tgtCRS); + + List result = new ArrayList<>(); + + for(Coordinate coord : coordList) { + ProjCoordinate projCoordinate = new ProjCoordinate(coord.getX(), coord.getY()); + ProjCoordinate projTrasform = transform.transform(projCoordinate, new ProjCoordinate()); + + Coordinate target = new Coordinate(projTrasform.x, projTrasform.y); + + result.add(target); + } + + return result; + } + + /** + * 비행 구역 - Buffer 영역 생성 + * + * @param coordList + * @param bufferZone + * @return + */ + public List buffer(List coordList, double bufferZone) { + + LineString line = geometryFactory.createLineString(coordList.toArray(new Coordinate[] {})); + Geometry geometry = geometryFactory.createGeometry(line); + + // buffer + int nSegments = 10; + int cap = BufferParameters.CAP_SQUARE; + int join = BufferParameters.JOIN_ROUND; + + BufferParameters bufferParam = new BufferParameters(nSegments, cap, join, join); + BufferOp ops = new BufferOp(geometry, bufferParam); + +// Geometry bufTrans = ops.getResultGeometry((bufferZone/177763.63662580872)*2); + Geometry bufTrans = ops.getResultGeometry(bufferZone); + + Coordinate[] coords = bufTrans.getCoordinates(); + + return new ArrayList<>(Arrays.asList(coords)); + } public static void main(String[] args) { AirAreaUtils utils = AirAreaUtils.getInstance(); log.info("utils: {}", utils); - AirAreaUtils utils2 = AirAreaUtils.getInstance(); - log.info("utils2: {}", utils2); - log.info("utils == utils2: {}", utils == utils2); - List list = List.of(1, 2, 3, 4, 5); - boolean b = list.stream().anyMatch(i -> i == 3); - log.info("b:: {}", b); - List list2 = new ArrayList<>(); - boolean b2 = list2.stream().anyMatch(i -> i == 3); - log.info("b2:: {}", b2); +// AirAreaUtils utils2 = AirAreaUtils.getInstance(); +// log.info("utils2: {}", utils2); +// log.info("utils == utils2: {}", utils == utils2); +// +// List list = List.of(1, 2, 3, 4, 5); +// boolean b = list.stream().anyMatch(i -> i == 3); +// log.info("b:: {}", b); +// List list2 = new ArrayList<>(); +// boolean b2 = list2.stream().anyMatch(i -> i == 3); +// log.info("b2:: {}", b2); Map> airMap = utils.getAirAreaMap(); airMap.forEach((k, v) -> { log.info("{} - {}", k, v.size()); }); + List beforeCoordinates = List.of( + new Coordinate(126.0, 37.0), + new Coordinate(126.0, 38.0), + new Coordinate(127.0, 38.0), + new Coordinate(127.0, 37.0), + new Coordinate(126.0, 37.0) + ); + + + List transCoordList = utils.transform(beforeCoordinates, "EPSG:4326", "EPSG:5181"); + + List bufferList = utils.buffer(transCoordList, 50); // buffer 영역 생성 + + List transBufferList = utils.transform(bufferList, "EPSG:5181", "EPSG:4326"); // buffer 영역 좌표계 변환 + log.info("transBufferList: {}", transBufferList); + } } diff --git a/pav-server/src/main/java/com/palnet/comn/utils/KmlUtils.java b/pav-server/src/main/java/com/palnet/comn/utils/KmlUtils.java new file mode 100644 index 00000000..8c229603 --- /dev/null +++ b/pav-server/src/main/java/com/palnet/comn/utils/KmlUtils.java @@ -0,0 +1,136 @@ +package com.palnet.comn.utils; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +import javax.xml.bind.annotation.XmlAttribute; +import javax.xml.bind.annotation.XmlRootElement; +import java.util.List; + +public class KmlUtils { + +// public static void main(String[] args) { +// KmlPlacemark placemark = new KmlPlacemark(); +// placemark.setName("Test"); +// placemark.setDescription("This is a test placemark"); +// placemark.setLatitude(37.5665); +// placemark.setLongitude(126.9780); +// placemark.setElevation(0.0); +// +// String kml = convertToKml(placemark); +// System.out.println(kml); +// } +// public static String convertToKml(KmlPlacemark placemark) { +// try { +// JAXBContext jaxbContext = JAXBContext.newInstance(KmlPlacemark.class); +// Marshaller marshaller = jaxbContext.createMarshaller(); +// +// marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE); +// +// StringWriter writer = new StringWriter(); +// marshaller.marshal(placemark, writer); +// +// return writer.toString(); +// } catch (JAXBException e) { +// e.printStackTrace(); +// return null; +// } +// } + + @Data + @NoArgsConstructor + @AllArgsConstructor + @Builder + @XmlRootElement(name = "kml", namespace = "http://www.opengis.net/kml/2.2") + public static class KmlRoot { + T kml; + } + + @Data + @NoArgsConstructor + @AllArgsConstructor + @Builder + @XmlRootElement(name = "Document") + public static class KmlDocument { + private String name; + private String open; + private String description; + private List styles; + private List folders; + } + + @Data + @NoArgsConstructor + @AllArgsConstructor + @Builder + @XmlRootElement(name = "Style") + public static class KmlStyle { + @XmlAttribute(name = "id") + private String id; + private KmlLineStyle LineStyle; + private KmlPolyStyle PolyStyle; + } + + @Data + @NoArgsConstructor + @AllArgsConstructor + @Builder + @XmlRootElement(name = "LineStyle") + public static class KmlLineStyle { + private String color; + private String width; + } + + @Data + @NoArgsConstructor + @AllArgsConstructor + @Builder + @XmlRootElement(name = "PolyStyle") + public static class KmlPolyStyle { + private String color; + } + + @Data + @NoArgsConstructor + @AllArgsConstructor + @Builder + @XmlRootElement(name = "Folder") + public static class KmlFolder { + private String name; + private String description; + private KmlLookAt lookAt; + } + + @Data + @NoArgsConstructor + @AllArgsConstructor + @Builder + @XmlRootElement(name = "LookAt") + public static class KmlLookAt { + double longitude; + double latitude; + @Builder.Default + double altitude = 0; + @Builder.Default + double heading = 0; + double tilt; + double range; + } + + @Data + @NoArgsConstructor + @AllArgsConstructor + @Builder + @XmlRootElement(name = "Placemark") + public static class KmlPlacemark { + private String name; + private String description; + @Builder.Default + private int visibility = 1; + private String styleUrl; + private KmlLookAt lookAt; + + } +}