事情的起因是,本来打算使用PostGreSQL的PostGIS,来实现计算经纬度之间的距离
然后搞了一天,写了好几种SQL,在数据库运行都是正常的,放到Java代码中就各种报错,要么函数不存在,要么geometry类型不存在
搞了,最终崩溃了,直接换成了下面的方法
但是感觉还是PostGIS更快一些,但是我太菜了,搞不定
下面是两种计算经纬度的工具类
第一种:
使用Haversine公式计算经纬度
private static final double EARTH_RADIUS_KM = 6371.0;
/**
* lat1 纬度1
* lon1 经度1
* lat2 纬度2
* lon2 经度2
*/
public static double calculateDistance(double lat1, double lon1, double lat2, double lon2) {
// 将经纬度转换为弧度
double lat1Rad = Math.toRadians(lat1);
double lon1Rad = Math.toRadians(lon1);
double lat2Rad = Math.toRadians(lat2);
double lon2Rad = Math.toRadians(lon2);
// 计算经纬度的差值
double deltaLat = lat2Rad - lat1Rad;
double deltaLon = lon2Rad - lon1Rad;
// 应用Haversine公式
double a = Math.pow(Math.sin(deltaLat / 2), 2) +
Math.cos(lat1Rad) * Math.cos(lat2Rad) *
Math.pow(Math.sin(deltaLon / 2), 2);
double c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
double distance = EARTH_RADIUS_KM * c;
return distance;
}
第二种方法Vincenty公式
private static final double EARTH_RADIUS_KM = 6371.0;
public static double calculateDistance(double lat1, double lon1, double lat2, double lon2) {
// 将经纬度转换为弧度
double lat1Rad = Math.toRadians(lat1);
double lon1Rad = Math.toRadians(lon1);
double lat2Rad = Math.toRadians(lat2);
double lon2Rad = Math.toRadians(lon2);
// 计算经纬度的差值
double deltaLon = lon2Rad - lon1Rad;
// 应用Vincenty公式
double a = Math.pow(Math.cos(lat2Rad) * Math.sin(deltaLon), 2) +
Math.pow(Math.cos(lat1Rad) * Math.sin(lat2Rad) - Math.sin(lat1Rad) * Math.cos(lat2Rad) * Math.cos(deltaLon), 2);
double b = Math.sin(lat1Rad) * Math.sin(lat2Rad) +
Math.cos(lat1Rad) * Math.cos(lat2Rad) * Math.cos(deltaLon);
double c = Math.atan2(Math.sqrt(a), b);
double distance = EARTH_RADIUS_KM * c;
return distance;
}
两种方法的区别和使用场景
1、Haversine公式:
简介:Haversine公式是一种较为简单的计算球面距离的方法,适用于较短距离的近似计算。该公式假设地球是一个完全的球体,不考虑地球的椭球形状和地球表面的高程差异。
使用场景:适用于计算两个点之间较短距离的近似球面距离,例如计算城市之间的直线距离或大致的航程距离。
2、Vincenty公式:
简介:Vincenty公式是一种较为精确的计算球面距离的方法,考虑了地球的椭球形状和地球表面的高程差异。该公式基于椭球体模型,通过迭代计算来逼近两点之间的准确距离。
使用场景:适用于计算两个点之间较长距离的准确球面距离,例如航海、航空、地理测量等领域的距离计算需求。
Vincenty公式更准确,但由于其复杂性和计算量较大,相对于Haversine公式而言,计算时间会更长,所以具体场景,具体分析,具体使用