SpringBoot集成geodesy實現(xiàn)距離計算功能
1.什么是geodesy?
浩瀚的宇宙中,地球是我們賴以生存的家園。自古以來,人類一直對星球上的位置和彼此的距離著迷。無論是航海探險、貿(mào)易往來還是科學研究,精確計算兩個地點之間的距離都是至關(guān)重要的。 Geodesy:大地測量學的神奇力量 Geodesy,又稱大地測量學,是一門研究地球形狀、大小及其重力場的學科。在地球距離計算中,它扮演著至關(guān)重要的角色。Geodesy 的原理基于球面幾何。 首先,Geodesy 將地球近似為一個光滑的球體。然后,根據(jù)經(jīng)緯度坐標,將兩個地點視為球面上的兩點。最后,使用球面距離公式:
d = R * arccos(sin(φ1) * sin(φ2) + cos(φ1) * cos(φ2) * cos(λ1 - λ2))
其中,R 是地球半徑,φ1 和 φ2 分別是兩個地點的緯度,λ1 和 λ2 是兩個地點的經(jīng)度,d 是兩點之間的距離。 通過這個公式,Geodesy 能夠快速準確地計算出地球上兩個經(jīng)緯度坐標之間的距離。
2.代碼工程
實驗?zāi)繕?/h3>
- 1.利用數(shù)學公式計算
- 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>
數(shù)學公式計算類
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();
}
}
庫包調(diào)用
底層原理也是基于公式計算,方便大家使用才封裝成包
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();
}
}
以上只是一些關(guān)鍵代碼,所有代碼請參見下面代碼倉庫
代碼倉庫
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);
}
運行單元測試,發(fā)現(xiàn)2種計算方式誤差不大
distant1(m):1212316.48
distant2(m):1212391.2574948743
到此這篇關(guān)于SpringBoot集成geodesy實現(xiàn)距離計算功能的文章就介紹到這了,更多相關(guān)SpringBoot geodesy距離計算內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
JAVA基于Arrays.sort()實現(xiàn)數(shù)組升序和降序
這篇文章主要介紹了JAVA基于Arrays.sort()實現(xiàn)數(shù)組升序和降序,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下2020-06-06
劍指Offer之Java算法習題精講N叉樹的遍歷及數(shù)組與字符串
跟著思路走,之后從簡單題入手,反復(fù)去看,做過之后可能會忘記,之后再做一次,記不住就反復(fù)做,反復(fù)尋求思路和規(guī)律,慢慢積累就會發(fā)現(xiàn)質(zhì)的變化2022-03-03
springboot使用@KafkaListener監(jiān)聽多個kafka配置實現(xiàn)
當服務(wù)中需要監(jiān)聽多個kafka時,?需要配置多個kafka,本文主要介紹了springboot使用@KafkaListener監(jiān)聽多個kafka配置實現(xiàn),具有一定的參考價值,感興趣的可以了解一下2024-04-04
深入理解Java虛擬機 JVM 內(nèi)存結(jié)構(gòu)
本節(jié)將會介紹一下JVM的內(nèi)存結(jié)構(gòu),JVM運行時數(shù)據(jù)區(qū)的各個組成部分:堆,方法區(qū),程序計數(shù)器,Java虛擬機棧,本地方法棧,還會對Java堆的分代劃分做個簡單的介紹2021-09-09

