目录
1 Geodesy
1.1 什么是geodesy
浩瀚的宇宙中,地球是我们赖以生存的家园。自古以来,人类一直对星球上的位置和彼此的距离着迷。无论是航海探险、贸易往来还是科学研究,精确计算两个地点之间的距离都是至关重要的。 Geodesy
:大地测量学的神奇力量 Geodesy
,又称大地测量学,是一门研究地球形状、大小及其重力场的学科。在地球距离计算中,它扮演着至关重要的角色。Geodesy
的原理基于球面几何。 首先,Geodesy
将地球近似为一个光滑的球体。然后,根据经纬度坐标,将两个地点视为球面上的两点。最后,使用球面距离公式:
$$
d = R * arccos(sin(φ1) * sin(φ2) + cos(φ1) * cos(φ2) * cos(λ1 - λ2))
$$
其中,R 是地球半径,φ1
和 φ2
分别是两个地点的纬度,λ1
和 λ2
是两个地点的经度,d
是两点之间的距离。 通过这个公式,Geodesy
能够快速准确地计算出地球上两个经纬度坐标之间的距离。
1.2 操作实践
1.2.1 pom.xml
<dependency>
<groupId>org.gavaghan</groupId>
<artifactId>geodesy</artifactId>
<version>1.1.3</version>
</dependency>
1.2.2 数学公式计算类
package com.et.geodesy.util;
import lombok.experimental.UtilityClass;
import java.math.BigDecimal;
/**
* <p>formula:S=R·arccos[cosβ1·cosβ·2cos(α1-α2)+sinβ1·sinβ2]
*/
@UtilityClass
public class MathDistanceUtil {
private static final double EARTH_RADIUS = 6371393;
private static final double DEGREES_TO_RADIANS = 0.017453292519943295;
public static double getDistance(
Double longitude1, Double latitude1, Double longitude2, Double latitude2) {
double radiansLongitude1 = toRadians(longitude1);
double radiansLatitude1 = toRadians(latitude1);
double radiansLongitude2 = toRadians(longitude2);
double radiansLatitude2 = Math.toRadians(latitude2);
final double cos =
BigDecimal.valueOf(Math.cos(radiansLatitude1))
.multiply(BigDecimal.valueOf(Math.cos(radiansLatitude2)))
.multiply(
BigDecimal.valueOf(
Math.cos(
BigDecimal.valueOf(radiansLongitude1)
.subtract(BigDecimal.valueOf(radiansLongitude2))
.doubleValue())))
.add(
BigDecimal.valueOf(Math.sin(radiansLatitude1))
.multiply(BigDecimal.valueOf(Math.sin(radiansLatitude2))))
.doubleValue();
double acos = Math.acos(cos);
return BigDecimal.valueOf(EARTH_RADIUS).multiply(BigDecimal.valueOf(acos)).doubleValue();
}
private static double toRadians(double value) {
return BigDecimal.valueOf(value).multiply(BigDecimal.valueOf(DEGREES_TO_RADIANS)).doubleValue();
}
}
1.2.3 库包调用
底层原理也是基于公式计算,方便大家使用才封装成包
package com.et.geodesy.util;
import org.gavaghan.geodesy.Ellipsoid;
import org.gavaghan.geodesy.GeodeticCalculator;
import org.gavaghan.geodesy.GeodeticCurve;
import org.gavaghan.geodesy.GlobalCoordinates;
import java.math.BigDecimal;
import java.math.RoundingMode;
public class GeodsyDistanceUtils {
public static double getDistance(Double lonA, Double latA, Double lonB, Double latB,int newScale) {
GlobalCoordinates source = new GlobalCoordinates(latA, lonA);
GlobalCoordinates target = new GlobalCoordinates(latB, lonB);
GeodeticCurve geoCurve = new GeodeticCalculator().calculateGeodeticCurve(Ellipsoid.Sphere, source, target);
double distance = geoCurve.getEllipsoidalDistance();
BigDecimal distanceBig = new BigDecimal(distance).setScale(newScale, RoundingMode.UP);
return distanceBig.doubleValue();
}
}
以上只是一些关键代码,所有代码请参见下面代码仓库
1.2.4 测试
编写测试类
@Test
public void getDistance() {
// source (113.324553,23.106414)
// target (121.499718, 31.239703)
double distance1 = GeodsyDistanceUtils.getDistance(113.324553,23.106414,
121.499718, 31.239703,2);
System.out.println("distant1(m):" + distance1);
double distance2 = MathDistanceUtil.getDistance(113.324553, 23.106414, 121.499718, 31.239703);
System.out.println("distant2(m):" + distance2);
}
运行单元测试,发现2种计算方式误差不大
distant1(m):1212316.48
distant2(m):1212391.2574948743
标签:cos,BigDecimal,1.2,double,valueOf,Boot,Geodesy,Spring,import
From: https://www.cnblogs.com/jingzh/p/18239390