经纬度,表面的含义就是经纬度的平方和,然后开平方。。。一切都没问题。。
但问题不是简单的二维平面,在二维空间中,这样计算是没有问题。。。
但是。。。。。
百度上找了找,大概有三种方式,一个是根据反余弦,一个是根据sin和cosin,第三个是根据提供的一个第三方jar包计算的。。。。
具体分析在这里
https://blog.csdn.net/jk940438163/article/details/83147557#commentsedit
package com.zhiliyuchi.web.rest.util;
/**
* @创建人:Young
* @时 间: 2019/3/13
* @描 述: TODO
*/
public class Test {
private static final double EARTH_RADIUS = 6371393; // 平均半径,单位:m;不是赤道半径。赤道为6378左右
/**
* @描述 反余弦进行计算
* @参数 [lat1, lng1, lat2, lng2]
* @返回值 double
* @创建人 Young
* @创建时间 2019/3/13 20:31
**/
public static double getDistance(Double lat1,Double lng1,Double lat2,Double lng2) {
// 经纬度(角度)转弧度。弧度用作参数,以调用Math.cos和Math.sin
double radiansAX = Math.toRadians(lng1); // A经弧度
double radiansAY = Math.toRadians(lat1); // A纬弧度
double radiansBX = Math.toRadians(lng2); // B经弧度
double radiansBY = Math.toRadians(lat2); // B纬弧度
// 公式中“cosβ1cosβ2cos(α1-α2)+sinβ1sinβ2”的部分,得到∠AOB的cos值
double cos = Math.cos(radiansAY) * Math.cos(radiansBY) * Math.cos(radiansAX - radiansBX)
+ Math.sin(radiansAY) * Math.sin(radiansBY);
// System.out.println("cos = " + cos); // 值域[-1,1]
double acos = Math.acos(cos); // 反余弦值
// System.out.println("acos = " + acos); // 值域[0,π]
// System.out.println("∠AOB = " + Math.toDegrees(acos)); // 球心角 值域[0,180]
return EARTH_RADIUS * acos; // 最终结果
}
public static void main(String[] args) {
//121.717594,31.12055 121.817629,31.090867
double distance = getDistance(31.12055, 121.717594,
31.090867, 121.817629);
System.out.println("距离" + distance + "米");
}
}
package com.zhiliyuchi.web.rest.util;
/**
* @创建人:Young
* @时 间: 2019/3/13
* @描 述: 高德地图对应经纬度计算距离
*/
public class LocationUtils {
// 地球赤道半径
private static double EARTH_RADIUS = 6378.137;
private static double rad(double d) {
return d * Math.PI / 180.0;
}
/**
* @描述 经纬度获取距离,单位为米
* @参数 [lat1, lng1, lat2, lng2]
* @返回值 double
* @创建人 Young
* @创建时间 2019/3/13 20:33
**/
public static double getDistance(double lat1, double lng1, double lat2,
double lng2) {
double radLat1 = rad(lat1);
double radLat2 = rad(lat2);
double a = radLat1 - radLat2;
double b = rad(lng1) - rad(lng2);
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_RADIUS;
s = Math.round(s * 10000d) / 10000d;
s = s * 1000;
return s;
}
public static void main(String[] args) {
double distance = getDistance(31.12055, 131.717594,
21.090867, 111.817629);
System.out.println("距离" + distance + "米");
}
}
maven库导包
org.gavaghan
geodesy
1.1.3
package com.zhiliyuchi.web.rest.util;
import org.gavaghan.geodesy.Ellipsoid;
import org.gavaghan.geodesy.GeodeticCalculator;
import org.gavaghan.geodesy.GeodeticCurve;
import org.gavaghan.geodesy.GlobalCoordinates;
/**
* @创建人:Young
* @时 间: 2019/3/13
* @描 述: TODO
*/
public class test0 {
public static void main(String[] args)
{
// //121.717594,31.12055 121.817629,31.090867
GlobalCoordinates source = new GlobalCoordinates(31.12055, 121.717594);
GlobalCoordinates target = new GlobalCoordinates(31.090867, 121.817629);
double meter1 = getDistanceMeter(source, target, Ellipsoid.Sphere);
double meter2 = getDistanceMeter(source, target, Ellipsoid.WGS84);
System.out.println("Sphere坐标系计算结果:"+meter1 + "米");
System.out.println("WGS84坐标系计算结果:"+meter2 + "米");
}
public static double getDistanceMeter(GlobalCoordinates gpsFrom, GlobalCoordinates gpsTo, Ellipsoid ellipsoid)
{
//创建GeodeticCalculator,调用计算方法,传入坐标系、经纬度用于计算距离
GeodeticCurve geoCurve = new GeodeticCalculator().calculateGeodeticCurve(ellipsoid, gpsFrom, gpsTo);
return geoCurve.getEllipsoidalDistance();
}
}
进入jar中的源码
{
double a = ellipsoid.getSemiMajorAxis();
double b = ellipsoid.getSemiMinorAxis();
double f = ellipsoid.getFlattening();
double phi1 = Angle.toRadians(start.getLatitude());
double lambda1 = Angle.toRadians(start.getLongitude());
double phi2 = Angle.toRadians(end.getLatitude());
double lambda2 = Angle.toRadians(end.getLongitude());
double a2 = a * a;
double b2 = b * b;
double a2b2b2 = (a2 - b2) / b2;
double omega = lambda2 - lambda1;
double tanphi1 = Math.tan(phi1);
double tanU1 = (1.0D - f) * tanphi1;
double U1 = Math.atan(tanU1);
double sinU1 = Math.sin(U1);
double cosU1 = Math.cos(U1);
double tanphi2 = Math.tan(phi2);
double tanU2 = (1.0D - f) * tanphi2;
double U2 = Math.atan(tanU2);
double sinU2 = Math.sin(U2);
double cosU2 = Math.cos(U2);
double sinU1sinU2 = sinU1 * sinU2;
double cosU1sinU2 = cosU1 * sinU2;
double sinU1cosU2 = sinU1 * cosU2;
double cosU1cosU2 = cosU1 * cosU2;
double lambda = omega;
double A = 0.0D;
double B = 0.0D;
double sigma = 0.0D;
double deltasigma = 0.0D;
boolean converged = false;
for(int s = 0; s < 20; ++s) {
double lambda0 = lambda;
double sinlambda = Math.sin(lambda);
double coslambda = Math.cos(lambda);
double sin2sigma = cosU2 * sinlambda * cosU2 * sinlambda + (cosU1sinU2 - sinU1cosU2 * coslambda) * (cosU1sinU2 - sinU1cosU2 * coslambda);
double sinsigma = Math.sqrt(sin2sigma);
double cossigma = sinU1sinU2 + cosU1cosU2 * coslambda;
sigma = Math.atan2(sinsigma, cossigma);
double sinalpha = sin2sigma == 0.0D?0.0D:cosU1cosU2 * sinlambda / sinsigma;
double alpha = Math.asin(sinalpha);
double cosalpha = Math.cos(alpha);
double cos2alpha = cosalpha * cosalpha;
double cos2sigmam = cos2alpha == 0.0D?0.0D:cossigma - 2.0D * sinU1sinU2 / cos2alpha;
double u2 = cos2alpha * a2b2b2;
double cos2sigmam2 = cos2sigmam * cos2sigmam;
A = 1.0D + u2 / 16384.0D * (4096.0D + u2 * (-768.0D + u2 * (320.0D - 175.0D * u2)));
B = u2 / 1024.0D * (256.0D + u2 * (-128.0D + u2 * (74.0D - 47.0D * u2)));
deltasigma = B * sinsigma * (cos2sigmam + B / 4.0D * (cossigma * (-1.0D + 2.0D * cos2sigmam2) - B / 6.0D * cos2sigmam * (-3.0D + 4.0D * sin2sigma) * (-3.0D + 4.0D * cos2sigmam2)));
double C = f / 16.0D * cos2alpha * (4.0D + f * (4.0D - 3.0D * cos2alpha));
lambda = omega + (1.0D - C) * f * sinalpha * (sigma + C * sinsigma * (cos2sigmam + C * cossigma * (-1.0D + 2.0D * cos2sigmam2)));
double change = Math.abs((lambda - lambda0) / lambda);
if(s > 1 && change < 1.0E-13D) {
converged = true;
break;
}
}
double var96 = b * A * (sigma - deltasigma);
double alpha1;
double alpha2;
if(!converged) {
if(phi1 > phi2) {
alpha1 = 180.0D;
alpha2 = 0.0D;
} else if(phi1 < phi2) {
alpha1 = 0.0D;
alpha2 = 180.0D;
} else {
alpha1 = 0.0D / 0.0;
alpha2 = 0.0D / 0.0;
}
} else {
double radians = Math.atan2(cosU2 * Math.sin(lambda), cosU1sinU2 - sinU1cosU2 * Math.cos(lambda));
if(radians < 0.0D) {
radians += 6.283185307179586D;
}
alpha1 = Angle.toDegrees(radians);
radians = Math.atan2(cosU1 * Math.sin(lambda), -sinU1cosU2 + cosU1sinU2 * Math.cos(lambda)) + 3.141592653589793D;
if(radians < 0.0D) {
radians += 6.283185307179586D;
}
alpha2 = Angle.toDegrees(radians);
}
if(alpha1 >= 360.0D) {
alpha1 -= 360.0D;
}
if(alpha2 >= 360.0D) {
alpha2 -= 360.0D;
}
return new GeodeticCurve(var96, alpha1, alpha2);
}
大同小异。。但是好像地球半径给的是
有点儿疑惑了。。。各需所求吧。。。