欢迎访问悦橙教程(wld5.com),关注java教程。悦橙教程  java问答|  每日更新
页面导航 : > > 文章正文

SpringBoot集成geodesy实现距离计算功能,

来源: javaer 分享于  点击 43066 次 点评:41

SpringBoot集成geodesy实现距离计算功能,


目录
  • 1.什么是geodesy?
  • 2.代码工程
    • 实验目标
    • pom.xml
    • 数学公式计算类
    • 库包调用
    • 代码仓库
  • 3.测试

    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]
     */
    @UtilityClass
    public 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.测试

    编写测试类

    @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

    到此这篇关于SpringBoot集成geodesy实现距离计算功能的文章就介绍到这了,更多相关SpringBoot geodesy距离计算内容请搜索3672js教程以前的文章或继续浏览下面的相关文章希望大家以后多多支持3672js教程!

    您可能感兴趣的文章:
    • springboot CompletableFuture并行计算及使用方法
    • SpringBoot+React实现计算个人所得税
    • springboot @Value实现获取计算机中绝对路径文件的内容
    • SpringBoot 集成 Nebula的操作过程
    相关栏目:

    用户点评