Browse Source

feat: air area util - 근접 좌표 계산 추가

feature/change-airspace
지대한 2 months ago
parent
commit
2d32357b48
  1. 124
      pav-server/src/main/java/com/palnet/comn/utils/AirAreaUtils.java

124
pav-server/src/main/java/com/palnet/comn/utils/AirAreaUtils.java

@ -6,13 +6,16 @@ import lombok.*;
import lombok.extern.slf4j.Slf4j;
import org.geotools.geojson.feature.FeatureJSON;
import org.geotools.geojson.geom.GeometryJSON;
import org.geotools.geometry.jts.JTS;
import org.geotools.referencing.CRS;
import org.geotools.referencing.GeodeticCalculator;
import org.json.simple.JSONArray;
import org.json.simple.JSONObject;
import org.json.simple.parser.JSONParser;
import org.locationtech.jts.geom.Coordinate;
import org.locationtech.jts.geom.Geometry;
import org.locationtech.jts.geom.GeometryFactory;
import org.locationtech.jts.geom.*;
import org.opengis.feature.simple.SimpleFeature;
import org.opengis.referencing.crs.CoordinateReferenceSystem;
import org.opengis.referencing.operation.TransformException;
import org.springframework.core.io.Resource;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.core.io.support.ResourcePatternResolver;
@ -85,7 +88,9 @@ public class AirAreaUtils {
}
// TODO 초기화
/**
* 초기화
*/
private void init() {
airAreaMap = new HashMap<>();
geometryFactory = new GeometryFactory();
@ -543,7 +548,116 @@ public class AirAreaUtils {
}
// TODO 가장 가까운 거리 반환
/**
* Cartesian 식으로 변환
*
* @param lon
* @param lat
* @return
*/
public static Coordinate toCartesian(double lon, double lat) {
double radLon = Math.toRadians(lon);
double radLat = Math.toRadians(lat);
double x = Math.cos(radLat) * Math.cos(radLon);
double y = Math.cos(radLat) * Math.sin(radLon);
double z = Math.sin(radLat);
return new Coordinate(x, y, z);
}
/**
* 구형으로 변환
*
* @param cartesian
* @return
*/
public static Coordinate toSpherical(Coordinate cartesian) {
double x = cartesian.x;
double y = cartesian.y;
double z = cartesian.z;
double lon = Math.toDegrees(Math.atan2(y, x));
double hyp = Math.sqrt(x * x + y * y);
double lat = Math.toDegrees(Math.atan2(z, hyp));
return new Coordinate(lon, lat);
}
/**
* 선분과 사이의 가장 가까운 점을 구한다.(곡률 적용)
*
* @param linePointA
* @param linePointB
* @param pointP
* @return
*/
public static Coordinate getClosestPoint(Coordinate linePointA, Coordinate linePointB, Coordinate pointP) {
Coordinate A3D = toCartesian(linePointA.x, linePointA.y);
Coordinate B3D = toCartesian(linePointB.x, linePointB.y);
Coordinate P3D = toCartesian(pointP.x, pointP.y);
Coordinate AB = new Coordinate(B3D.x - A3D.x, B3D.y - A3D.y, B3D.z - A3D.z);
Coordinate AP = new Coordinate(P3D.x - A3D.x, P3D.y - A3D.y, P3D.z - A3D.z);
double t = (AP.x * AB.x + AP.y * AB.y + AP.z * AB.z) / (AB.x * AB.x + AB.y * AB.y + AB.z * AB.z);
t = Math.max(0, Math.min(1, t)); // t가 [0, 1] 범위 내에 있도록 제한
Coordinate closestPoint3D = new Coordinate(
A3D.x + t * AB.x,
A3D.y + t * AB.y,
A3D.z + t * AB.z
);
return toSpherical(closestPoint3D);
}
/**
* 점과 사이의 거리를 구한다.
*
* @param point1
* @param point2
* @return
*/
public static Double calculatePointAndPointDistance(Coordinate point1, Coordinate point2) {
CoordinateReferenceSystem crs;
try {
crs = CRS.decode("EPSG:4326");
} catch (Exception e) {
throw new RuntimeException("Error decoding CRS", e);
}
GeodeticCalculator gc = new GeodeticCalculator(crs);
try {
gc.setStartingPosition(JTS.toDirectPosition(new Coordinate(point1.getY(), point1.getX()), crs));
gc.setDestinationPosition(JTS.toDirectPosition(new Coordinate(point2.getY(), point2.getX()), crs));
} catch (TransformException e) {
throw new RuntimeException("Error setting positions for distance calculation", e);
}
return gc.getOrthodromicDistance();
}
/**
* x, y 좌표를 교환
*
* @param originalGeometry
* @return
*/
public static Geometry swapCoordinates(Geometry originalGeometry) {
GeometryFactory geometryFactory = new GeometryFactory();
Coordinate[] originalCoordinates = originalGeometry.getCoordinates();
Coordinate[] swappedCoordinates = new Coordinate[originalCoordinates.length];
for (int i = 0; i < originalCoordinates.length; i++) {
swappedCoordinates[i] = new Coordinate(originalCoordinates[i].y, originalCoordinates[i].x);
}
if (originalGeometry instanceof Point) {
return geometryFactory.createPoint(swappedCoordinates[0]);
} else if (originalGeometry instanceof LineString) {
return geometryFactory.createLineString(swappedCoordinates);
} else if (originalGeometry instanceof Polygon) {
return geometryFactory.createPolygon(swappedCoordinates);
}
// Add more geometry types as needed
return originalGeometry; // Return the original geometry if type is not handled
}
public static void main(String[] args) {

Loading…
Cancel
Save