docs: Add javadoc to GpsCalculationService.java

This commit is contained in:
js0ny 2025-10-18 20:54:20 +01:00
parent 26e1c80326
commit 49a1c2ef07
2 changed files with 48 additions and 14 deletions

View file

@ -1,38 +1,73 @@
package io.github.js0ny.ilp_coursework.service; package io.github.js0ny.ilp_coursework.service;
import io.github.js0ny.ilp_coursework.data.LngLatDto; import io.github.js0ny.ilp_coursework.data.*;
import io.github.js0ny.ilp_coursework.data.RegionDto;
import java.util.List; import java.util.List;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
/**
* Class that handles calculations about Coordinates
*
* @see LngLatDto
* @see RegionDto
*/
@Service @Service
public class GpsCalculationService { public class GpsCalculationService {
/**
* Given step size
*
* @see #nextPosition(LngLatDto, double)
*/
private static final double STEP = 0.00015; private static final double STEP = 0.00015;
private static final double CLOSE_THRESHOLD = STEP; /**
* Given threshold to judge if two points are close to each other
*
* @see #isCloseTo(LngLatDto, LngLatDto)
*/
private static final double CLOSE_THRESHOLD = 0.00015;
/**
* Calculate the Euclidean distance between <code>position1</code> and <code>position2</code>, which are coordinates
* defined as {@link LngLatDto}
*
* @param position1 The coordinate of the first position
* @param position2 The coordinate of the second position
* @return The Euclidean distance between <code>position1</code> and <code>position2</code>
* @see io.github.js0ny.ilp_coursework.controller.ApiController#getDistance(DistanceRequestDto)
*/
public double calculateDistance(LngLatDto position1, LngLatDto position2) { public double calculateDistance(LngLatDto position1, LngLatDto position2) {
double lngDistance = position2.lng() - position1.lng(); double lngDistance = position2.lng() - position1.lng();
double latDistance = position2.lat() - position1.lat(); double latDistance = position2.lat() - position1.lat();
return Math.sqrt(lngDistance * lngDistance + latDistance * latDistance); return Math.sqrt(lngDistance * lngDistance + latDistance * latDistance);
} }
/**
* Check if <code>position1</code> and <code>position2</code> are close to each other, the threshold is < 0.00015
* <p>
* Note that = 0.00015 will be counted as not close to and will return <code>false</code>
*
* @param position1 The coordinate of the first position
* @param position2 The coordinate of the second position
* @return True if <code>position1</code> and <code>position2</code> are close to each other
* @see #CLOSE_THRESHOLD
* @see io.github.js0ny.ilp_coursework.controller.ApiController#getIsCloseTo(DistanceRequestDto)
*/
public boolean isCloseTo(LngLatDto position1, LngLatDto position2) { public boolean isCloseTo(LngLatDto position1, LngLatDto position2) {
double distance = calculateDistance(position1, position2); double distance = calculateDistance(position1, position2);
return distance < CLOSE_THRESHOLD; return distance < CLOSE_THRESHOLD;
} }
/** /**
* Called from <code>ApiController.getNextPosition</code>.
* <p>
* Returns the next position moved from <code>start</code> in the direction with <code>angle</code>, with step size * Returns the next position moved from <code>start</code> in the direction with <code>angle</code>, with step size
* 0.00015 * 0.00015
* *
* @param start The coordinate of the original start point. * @param start The coordinate of the original start point.
* @param angle The direction to be moved in angle. * @param angle The direction to be moved in angle.
* @return The next position moved from <code>start</code> * @return The next position moved from <code>start</code>
* @see #STEP
* @see io.github.js0ny.ilp_coursework.controller.ApiController#getNextPosition(MovementRequestDto)
*/ */
public LngLatDto nextPosition(LngLatDto start, double angle) { public LngLatDto nextPosition(LngLatDto start, double angle) {
double rad = Math.toRadians(angle); double rad = Math.toRadians(angle);
@ -42,15 +77,15 @@ public class GpsCalculationService {
} }
/** /**
* Called from <code>ApiController.getIsInRegion</code>.
* <p>
* Used to check if the given <code>position</code> * Used to check if the given <code>position</code>
* is inside the <code>region</code>, on edge and vertex is considered as inside. * is inside the <code>region</code>, on edge and vertex is considered as inside.
* *
* @param position The coordinate of the position. * @param position The coordinate of the position.
* @param region A <code>RegionDto</code> that contains name and a list of <code>LngLatDto</code> * @param region A {@link RegionDto} that contains name and a list of <code>LngLatDto</code>
* @return true if <code>position</code> is inside the <code>region</code>. * @return true if <code>position</code> is inside the <code>region</code>.
* @throws IllegalArgumentException If <code>region</code> is not closed * @throws IllegalArgumentException If <code>region</code> is not closed
* @see io.github.js0ny.ilp_coursework.controller.ApiController#getIsInRegion(RegionCheckRequestDto)
* @see RegionDto#isClosed()
*/ */
public boolean checkIsInRegion(LngLatDto position, RegionDto region) throws IllegalArgumentException { public boolean checkIsInRegion(LngLatDto position, RegionDto region) throws IllegalArgumentException {
if (!region.isClosed()) { // call method from RegionDto to check if not closed if (!region.isClosed()) { // call method from RegionDto to check if not closed
@ -69,6 +104,8 @@ public class GpsCalculationService {
* sits inside. * sits inside.
* @return If the <code>point</code> sits inside the <code>polygon</code> then * @return If the <code>point</code> sits inside the <code>polygon</code> then
* return True * return True
* @see #isPointOnEdge(LngLatDto, LngLatDto, LngLatDto)
* @see #checkIsInRegion(LngLatDto, RegionDto)
*/ */
private boolean rayCasting(LngLatDto point, List<LngLatDto> polygon) { private boolean rayCasting(LngLatDto point, List<LngLatDto> polygon) {
int intersections = 0; int intersections = 0;
@ -81,7 +118,7 @@ public class GpsCalculationService {
return true; return true;
} }
// Ensure that a is norther than b, in order to easy classification // Ensure that `a` is norther than `b`, in order to easy classification
if (a.lat() > b.lat()) { if (a.lat() > b.lat()) {
LngLatDto temp = a; LngLatDto temp = a;
a = b; a = b;
@ -100,10 +137,6 @@ public class GpsCalculationService {
double xIntersection = a.lng() + ((point.lat() - a.lat()) * (b.lng() - a.lng())) / (b.lat() - a.lat()); double xIntersection = a.lng() + ((point.lat() - a.lat()) * (b.lng() - a.lng())) / (b.lat() - a.lat());
// // The point is on the edge
// if (xIntersection == point.lng()) {
// return true;
// }
if (xIntersection > point.lng()) { if (xIntersection > point.lng()) {
++intersections; ++intersections;
@ -123,6 +156,7 @@ public class GpsCalculationService {
* @param a point that forms the edge * @param a point that forms the edge
* @param b point that forms the edge * @param b point that forms the edge
* @return boolean, if <code>p</code> is on <code>ab</code> then true * @return boolean, if <code>p</code> is on <code>ab</code> then true
* @see #rayCasting(LngLatDto, List)
*/ */
private boolean isPointOnEdge(LngLatDto p, LngLatDto a, LngLatDto b) { private boolean isPointOnEdge(LngLatDto p, LngLatDto a, LngLatDto b) {
// Cross product: (p - a) × (b - a) // Cross product: (p - a) × (b - a)

View file

@ -16,7 +16,7 @@ import static org.assertj.core.api.AssertionsForClassTypes.within;
public class GpsCalculationServiceTest { public class GpsCalculationServiceTest {
private static final double STEP = 0.00015; private static final double STEP = 0.00015;
private static final double CLOSE_THRESHOLD = STEP; // private static final double CLOSE_THRESHOLD = STEP;
private static final double PRECISION = 1e-9; private static final double PRECISION = 1e-9;
private GpsCalculationService service; private GpsCalculationService service;