docs: Add javadoc to GpsCalculationService.java
This commit is contained in:
parent
26e1c80326
commit
49a1c2ef07
2 changed files with 48 additions and 14 deletions
|
|
@ -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)
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue