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 能够快速准确地计算出地球上两个经纬度坐标之间的距离。
2.代码工程
实验目标
- 
1.利用数学公式计算 
- 
2.利用Java库包Geodesy 
pom.xml
<?xml version="1.0" encoding="UTF-8"?><project xmlns="http://maven.apache.org/POM/4.0.0"         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">    <parent>        <artifactId>springboot-demo</artifactId>        <groupId>com.et</groupId>        <version>1.0-SNAPSHOT</version>    </parent>    <modelVersion>4.0.0</modelVersion>
    <artifactId>geodesy</artifactId>
    <properties>        <maven.compiler.source>8</maven.compiler.source>        <maven.compiler.target>8</maven.compiler.target>    </properties>    <dependencies>
        <dependency>            <groupId>org.springframework.boot</groupId>            <artifactId>spring-boot-starter-web</artifactId>        </dependency>
        <dependency>            <groupId>org.springframework.boot</groupId>            <artifactId>spring-boot-autoconfigure</artifactId>        </dependency>        <dependency>            <groupId>org.springframework.boot</groupId>            <artifactId>spring-boot-starter-test</artifactId>            <scope>test</scope>        </dependency>        <dependency>            <groupId>org.projectlombok</groupId>            <artifactId>lombok</artifactId>        </dependency>        <dependency>            <groupId>org.gavaghan</groupId>            <artifactId>geodesy</artifactId>            <version>1.1.3</version>        </dependency>
    </dependencies></project>
数学公式计算类
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] */@UtilityClasspublic class MathDistanceUtil {
  private static final double EARTH_RADIUS = 6371393;
  private static final double DEGREES_TO_RADIANS = 0.017453292519943295;
  /**   * Calculate according to formula   *   * @param longitude1   * @param latitude1   * @param longitude2   * @param latitude2   * @return   */  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();  }
  /**   * refer:{@link Math#toRadians(double)}   *   * @param value value   * @return {double}   */  private static double toRadians(double value) {    return BigDecimal.valueOf(value).multiply(BigDecimal.valueOf(DEGREES_TO_RADIANS)).doubleValue();  }
}
库包调用
底层原理也是基于公式计算,方便大家使用才封装成包 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
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 {
    /**     *     *     * @param lonA A longitude     * @param latA A latitude     * @param lonB B longitude     * @param latB B latitude     * @param newScale The result is kept to decimal places     * @return distant (m)     */    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();    }
}
以上只是一些关键代码,所有代码请参见下面代码仓库
代码仓库
- https://github.com/Harries/springboot-demo
3.测试
编写测试类 * * * * * * * * * * *
@Testpublic 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.48distant2(m):1212391.2574948743
4.引用
- 
https://www.bytezonex.com/archives/HP5c7BSl.html 
- 
http://www.liuhaihua.cn/archives/710663.html 
 51工具盒子
51工具盒子 
                 
                             
                         
                         
                        ![[开源]一款全自研工作流引擎和自定义表单引擎,支持自定义扩展](https://img1.51tbox.com/static/2024-06-06/col/61905755a745c4238d17b1c57579c27d/a37f216f3e7b4f838a328bebbba43d5e.jpg) 
                         
                        