Spring Boot integrates geodesy to implement distance calculation

HBLOG
3 min readJun 4, 2024

--

1. What is geodesy?

In the vast universe, the earth is the home we rely on for survival. Since ancient times, humans have been fascinated by the location on the planet and the distance from each other. Whether it’s a seafaring expedition, a trade exchange, or a scientific research, it is crucial to accurately calculate the distance between two locations. Geodesy: The Magical Power of Geodesy Geodesy, also known as geodesy, is a discipline that studies the shape, size, and gravitational field of the Earth. It plays a crucial role in the calculation of distance to the earth. The principle of Geodesy is based on spherical geometry. First, Geodesy approximates the Earth as a smooth sphere. Then, based on latitude and longitude coordinates, the two locations are treated as two points on the sphere. Finally, use the spherical distance formula:

d = R * arccos(sin(φ1) * sin(φ2) + cos(φ1) * cos(φ2) * cos(λ1 - λ2))

where R is the radius of the earth, φ1 and φ2 are the latitudes of the two locations, λ1 and λ2 are the longitudes of the two locations, and d is the distance between the two points. With this formula, Geodesy is able to quickly and accurately calculate the distance between two latitude and longitude coordinates on Earth.

2. Code engineering

purpose of the experiment

  • 1. Calculate using mathematical formulas
  • 2. Make use of the Java library package 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>

Mathematical formula calculation class

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();
}

}

Library package calls

The underlying principle is also based on formula calculation, which is convenient for everyone to use before encapsulating into a package

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();
}
}

The above are just some of the key codes, all of which can be found in the repositories below

Code repositories

3. Testing

Write a test class

@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);
}

Running the unit test, it was found that the error of the two calculation methods was not large

distant1(m):1212316.48
distant2(m):1212391.2574948743

4. References

--

--

HBLOG
HBLOG

Written by HBLOG

talk is cheap ,show me your code

No responses yet