SpringBoot集成geodesy實現(xiàn)距離計算功能
1.什么是geodesy?
浩瀚的宇宙中,地球是我們賴以生存的家園。自古以來,人類一直對星球上的位置和彼此的距離著迷。無論是航海探險、貿(mào)易往來還是科學(xué)研究,精確計算兩個地點之間的距離都是至關(guān)重要的。 Geodesy:大地測量學(xué)的神奇力量 Geodesy,又稱大地測量學(xué),是一門研究地球形狀、大小及其重力場的學(xué)科。在地球距離計算中,它扮演著至關(guān)重要的角色。Geodesy 的原理基于球面幾何。 首先,Geodesy 將地球近似為一個光滑的球體。然后,根據(jù)經(jīng)緯度坐標(biāo),將兩個地點視為球面上的兩點。最后,使用球面距離公式:
d = R * arccos(sin(φ1) * sin(φ2) + cos(φ1) * cos(φ2) * cos(λ1 - λ2))
其中,R 是地球半徑,φ1 和 φ2 分別是兩個地點的緯度,λ1 和 λ2 是兩個地點的經(jīng)度,d 是兩點之間的距離。 通過這個公式,Geodesy 能夠快速準(zhǔn)確地計算出地球上兩個經(jīng)緯度坐標(biāo)之間的距離。
2.代碼工程
實驗?zāi)繕?biāo)
- 1.利用數(shù)學(xué)公式計算
- 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ù)學(xué)公式計算類
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)文章
SpringBoot AOP注解失效問題排查與解決(調(diào)用內(nèi)部方法)
這篇文章主要介紹了SpringBoot AOP注解失效問題排查與解決(調(diào)用內(nèi)部方法),文中通過代碼示例介紹的非常詳細,對大家的學(xué)習(xí)或工作有一定的幫助,需要的朋友可以參考下2024-04-04mybatis interceptor 處理查詢參數(shù)及查詢結(jié)果的實例代碼
這篇文章主要介紹了mybatis interceptor 處理查詢參數(shù)及查詢結(jié)果,非常不錯,具有參考借鑒價值,需要的朋友可以參考下2017-01-01java8 filter方法、Predicate接口的使用方式
這篇文章主要介紹了java8 filter方法、Predicate接口的使用方式,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2024-07-07