地理位置坐标工具类
package com.wzw.util;
import org.apache.commons.lang3.StringUtils;
import org.gavaghan.geodesy.Ellipsoid;
import org.gavaghan.geodesy.GeodeticCalculator;
import org.gavaghan.geodesy.GeodeticCurve;
import org.gavaghan.geodesy.GlobalCoordinates;
import java.awt.geom.GeneralPath;
import java.awt.geom.Point2D;
import java.util.ArrayList;
import java.util.List;
public class PositionUtil {
public static final double EQUATOR_RADIUS = 6378137;
private static final double EARTH_AVG_RADIUS = 6371000;
public static double getDistance1(double longitude1, double latitude1, double longitude2, double latitude2) {
double lat1 = Math.toRadians(latitude1);
double lat2 = Math.toRadians(latitude2);
double lon1 = Math.toRadians(longitude1);
double lon2 = Math.toRadians(longitude2);
double a = lat1 - lat2;
double b = lon1 - lon2;
double s = 2 * Math.asin(Math.sqrt(Math.pow(Math.sin(a / 2), 2) + Math.cos(lat1) * Math.cos(lat2) * Math.pow(Math.sin(b / 2), 2)));
s = s * EQUATOR_RADIUS;
return s;
}
public static double getDistance2(double longitude1, double latitude1, double longitude2, double latitude2) {
double radiansAX = Math.toRadians(longitude1);
double radiansAY = Math.toRadians(latitude1);
double radiansBX = Math.toRadians(longitude2);
double radiansBY = Math.toRadians(latitude2);
double cos = Math.cos(radiansAY) * Math.cos(radiansBY) * Math.cos(radiansAX - radiansBX) + Math.sin(radiansAY) * Math.sin(radiansBY);
double acos = Math.acos(cos);
return EARTH_AVG_RADIUS * acos;
}
private static double rad(double d) {
return d * Math.PI / 180.0;
}
public static double getDistance3(double longitude1, double latitude1, double longitude2, double latitude2) {
double radLat1 = rad(latitude1);
double radLat2 = rad(latitude2);
double a = radLat1 - radLat2;
double b = rad(longitude1) - rad(longitude2);
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)));
s = s * EARTH_AVG_RADIUS;
s = Math.round(s * 10000d) / 10000d;
return s;
}
public static Double getDistance4(double longitude1, double latitude1, double longitude2, double latitude2) {
if (longitude1 == 0 || latitude1 == 0 || latitude2 == 0 || longitude2 == 0) {
return -1.0;
}
longitude1 *= 0.01745329251994329;
latitude1 *= 0.01745329251994329;
longitude2 *= 0.01745329251994329;
latitude2 *= 0.01745329251994329;
double var1 = Math.sin(longitude1);
double var2 = Math.sin(latitude1);
double var3 = Math.cos(longitude1);
double var4 = Math.cos(latitude1);
double var5 = Math.sin(longitude2);
double var6 = Math.sin(latitude2);
double var7 = Math.cos(longitude2);
double var8 = Math.cos(latitude2);
double[] var10 = new double[3];
double[] var20 = new double[3];
var10[0] = var4 * var3;
var10[1] = var4 * var1;
var10[2] = var2;
var20[0] = var8 * var7;
var20[1] = var8 * var5;
var20[2] = var6;
return Math.asin(Math.sqrt((var10[0] - var20[0]) * (var10[0] - var20[0]) + (var10[1] - var20[1]) * (var10[1] - var20[1]) + (var10[2] - var20[2]) * (var10[2] - var20[2])) / 2.0) * 1.27420015798544E7;
}
public static double getDistance4(double longitude1, double latitude1, double longitude2, double latitude2, Ellipsoid ellipsoid) {
GlobalCoordinates firstPoint = new GlobalCoordinates(latitude1, longitude1);
GlobalCoordinates secondPoint = new GlobalCoordinates(latitude2, longitude2);
GeodeticCurve geoCurve = new GeodeticCalculator().calculateGeodeticCurve(ellipsoid, firstPoint, secondPoint);
return geoCurve.getEllipsoidalDistance();
}
public static boolean isInCircle(double longitude1, double latitude1, double longitude2, double latitude2, String radius) {
if (StringUtils.isBlank(radius)) {
throw new RuntimeException("请输入范围半径");
}
return getDistance1(longitude1, latitude1, longitude2, latitude2) > Double.parseDouble(radius);
}
public static boolean isInPolygon(double pointLon, double pointLat, double[] lon, double[] lat) {
Point2D.Double point = new Point2D.Double(pointLon, pointLat);
List<Point2D.Double> pointList = new ArrayList<>();
double polygonPointToX;
double polygonPointToY;
for (int i = 0; i < lon.length; i++) {
polygonPointToX = lon[i];
polygonPointToY = lat[i];
Point2D.Double polygonPoint = new Point2D.Double(polygonPointToX, polygonPointToY);
pointList.add(polygonPoint);
}
return check(point, pointList);
}
private static boolean check(Point2D.Double point, List<Point2D.Double> polygon) {
GeneralPath generalPath = new GeneralPath();
Point2D.Double first = polygon.get(0);
generalPath.moveTo(first.x, first.y);
polygon.remove(0);
for (Point2D.Double d : polygon) {
generalPath.lineTo(d.x, d.y);
}
generalPath.lineTo(first.x, first.y);
generalPath.closePath();
return generalPath.contains(point);
}
}
测试
import com.wzw.util.PositionUtil;
import org.gavaghan.geodesy.Ellipsoid;
import org.junit.jupiter.api.Test;
public class TestPosition {
@Test
public void test() {
double longitude1 = 103.811321;
double latitude1 = 36.09315;
double longitude2 = 103.816741;
double latitude2 = 36.059691;
double distance1 = PositionUtil.getDistance1(longitude1, latitude1, longitude2, latitude2);
double distance2 = PositionUtil.getDistance2(longitude1, latitude1, longitude2, latitude2);
double distance3 = PositionUtil.getDistance3(longitude1, latitude1, longitude2, latitude2);
double distance4 = PositionUtil.getDistance4(longitude1, latitude1, longitude2, latitude2);
double distance5 = PositionUtil.getDistance4(longitude1, latitude1, longitude2, latitude2, Ellipsoid.Sphere);
double distance6 = PositionUtil.getDistance4(longitude1, latitude1, longitude2, latitude2, Ellipsoid.WGS84);
System.out.println("方法1算出的距离:" + distance1);
System.out.println("方法2算出的距离:" + distance2);
System.out.println("方法3算出的距离:" + distance3);
System.out.println("方法4算出的距离:" + distance4);
System.out.println("方法4-Sphere算出的距离:" + distance5);
System.out.println("方法4-WGS84算出的距离:" + distance6);
}
@Test
public void test2() {
double longitude1 = 103.811321;
double latitude1 = 36.09315;
double longitude2 = 103.816741;
double latitude2 = 36.059691;
String radius = "500";
System.out.println(PositionUtil.isInCircle(longitude1, latitude1, longitude2, latitude2, radius));
}
@Test
public void test3() {
double pointLon = 117.34232;
double pointLat = 31.778682;
double[] lon = {117.333976,117.336846, 117.358674,117.349062};
double[] lat = {31.78532,31.773234, 31.77295,31.785377};
boolean a = PositionUtil.isInPolygon(pointLon, pointLat, lon, lat);
System.out.println("校验坐标是否在多边形范围内:" + a);
}
}
