package com.moon.server.helper; import com.moon.server.entity.all.StaticData; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.gdal.osr.SpatialReference; import org.geotools.geometry.DirectPosition2D; import org.geotools.geometry.jts.JTS; import org.geotools.referencing.CRS; import org.geotools.referencing.GeodeticCalculator; import org.locationtech.jts.geom.Geometry; import org.locationtech.jts.io.WKTReader; import org.opengis.referencing.crs.CRSAuthorityFactory; import org.opengis.referencing.crs.CoordinateReferenceSystem; import org.opengis.referencing.operation.MathTransform; import java.awt.geom.Point2D; @SuppressWarnings("ALL") public class GeoHelper { public static SpatialReference sr4326; public static SpatialReference sr4490; public static SpatialReference sr104903; public final static double MOON_RADIUS = 1738000; public static CoordinateReferenceSystem crs104903; private final static Log log = LogFactory.getLog(GeoHelper.class); public static void initSr() { try { sr4326 = new SpatialReference(); sr4326.ImportFromEPSG(StaticData.I4326); sr4490 = new SpatialReference(); sr4490.ImportFromEPSG(StaticData.I4490); sr104903 = new SpatialReference(StaticData.MOON_2000_WKT); crs104903 = CRS.parseWKT(StaticData.MOON_2000_WKT); } catch (Exception ex) { log.error(ex.getMessage(), ex); } } public static double getDistance(double x1, double y1, double x2, double y2) { GeodeticCalculator geodeticCalculator = new GeodeticCalculator(crs104903); geodeticCalculator.setStartingGeographicPoint(x1, y1); geodeticCalculator.setDestinationGeographicPoint(x2, y2); return geodeticCalculator.getOrthodromicDistance(); } public static double getDistance2(double lon1, double lat1, double lon2, double lat2) { double radLat1 = Math.toRadians(lat1); double radLat2 = Math.toRadians(lat2); double a = radLat1 - radLat2; double b = Math.toRadians(lon1) - Math.toRadians(lon2); double s = 2 * Math.asin(Math.sqrt(Math.pow(Math.sin(a / 2), 2) + Math.cos(radLat1) * Math.cos(radLat2) * Math.pow(Math.sin(b / 2), 2))); return s * MOON_RADIUS; } public static double getBearing(double x1, double y1, double x2, double y2) { return (90 - Math.toDegrees(Math.atan2(x2 - x1, y2 - y1)) + 360) % 360; } public static double getAngle(double x1, double y1, double x2, double y2) { DirectPosition2D p1 = new DirectPosition2D(crs104903, x1, y1); DirectPosition2D p2 = new DirectPosition2D(crs104903, x2, y2); GeodeticCalculator gc = new GeodeticCalculator(); gc.setStartingGeographicPoint(p1); gc.setDestinationGeographicPoint(p2); return gc.getAzimuth(); } public static double getAngle2(double x1, double y1, double x2, double y2) { DirectPosition2D p1 = new DirectPosition2D(x1, y1); DirectPosition2D p2 = new DirectPosition2D(x2, y2); GeodeticCalculator gc = new GeodeticCalculator(); gc.setStartingGeographicPoint(p1); gc.setDestinationGeographicPoint(p2); return gc.getAzimuth(); } public static Point2D getPointByDistanceAndAngle(double x, double y, double angle, double distance) { DirectPosition2D p1 = new DirectPosition2D(x, y); GeodeticCalculator gc = new GeodeticCalculator(); gc.setStartingGeographicPoint(p1); gc.setDirection(angle, distance); return gc.getDestinationGeographicPoint(); } public static double[] csTransform(double x, double y, int epsg) throws Exception { CRSAuthorityFactory factory = CRS.getAuthorityFactory(true); CoordinateReferenceSystem target = factory.createCoordinateReferenceSystem("EPSG:4326"); CoordinateReferenceSystem sourceCrs = CRS.decode("EPSG:" + epsg); CoordinateReferenceSystem targetCrs = CRS.decode("EPSG:4326"); MathTransform transform = CRS.findMathTransform(sourceCrs, targetCrs, true); WKTReader reader = new WKTReader(); Geometry geometry = reader.read("POINT (" + x + " " + y + ")"); geometry.setSRID(epsg); Geometry geo = JTS.transform(geometry, transform); return new double[]{geo.getCoordinate().x, geo.getCoordinate().y}; } }