Add geographic-to-grid and grid-to-geographic projection methods in CoordinateConverter
- Introduced `toGrid` method enabling projection of geographic coordinates to grid coordinates with altitude source handling. - Added `toCoordinate` method for inverse projection, converting grid coordinates back to geographic coordinates. - Improved internal handling of altitude and ellipsoidal height for transformations.
This commit is contained in:
@@ -1,5 +1,9 @@
|
|||||||
package dev.coph.flightscore.backend.map;
|
package dev.coph.flightscore.backend.map;
|
||||||
|
|
||||||
|
import dev.coph.flightscore.backend.competition.AltitudeSource;
|
||||||
|
import dev.coph.flightscore.backend.coordinate.Altitude;
|
||||||
|
import dev.coph.flightscore.backend.coordinate.Coordinate;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* High precision conversion utility between any combination of {@link MapDatum}
|
* High precision conversion utility between any combination of {@link MapDatum}
|
||||||
* and {@link MapGrid}.
|
* and {@link MapGrid}.
|
||||||
@@ -32,7 +36,9 @@ package dev.coph.flightscore.backend.map;
|
|||||||
public final class CoordinateConverter {
|
public final class CoordinateConverter {
|
||||||
|
|
||||||
private static final double ARCSEC_TO_RAD = Math.PI / (180.0 * 3600.0);
|
private static final double ARCSEC_TO_RAD = Math.PI / (180.0 * 3600.0);
|
||||||
/** Iteration tolerance for the Newton/fixed-point solvers (radians). */
|
/**
|
||||||
|
* Iteration tolerance for the Newton/fixed-point solvers (radians).
|
||||||
|
*/
|
||||||
private static final double TOLERANCE = 1.0e-14;
|
private static final double TOLERANCE = 1.0e-14;
|
||||||
private static final int MAX_ITERATIONS = 100;
|
private static final int MAX_ITERATIONS = 100;
|
||||||
|
|
||||||
@@ -47,11 +53,11 @@ public final class CoordinateConverter {
|
|||||||
* Converts a grid coordinate from one {@code (datum, grid)} combination into
|
* Converts a grid coordinate from one {@code (datum, grid)} combination into
|
||||||
* any other {@code (datum, grid)} combination.
|
* any other {@code (datum, grid)} combination.
|
||||||
*
|
*
|
||||||
* @param source the coordinate in the source grid
|
* @param source the coordinate in the source grid
|
||||||
* @param sourceDatum datum the source coordinate is referenced to
|
* @param sourceDatum datum the source coordinate is referenced to
|
||||||
* @param sourceGrid grid the source coordinate is projected with
|
* @param sourceGrid grid the source coordinate is projected with
|
||||||
* @param targetDatum datum the result shall be referenced to
|
* @param targetDatum datum the result shall be referenced to
|
||||||
* @param targetGrid grid the result shall be projected with
|
* @param targetGrid grid the result shall be projected with
|
||||||
* @return the coordinate expressed in the target {@code (datum, grid)} combination
|
* @return the coordinate expressed in the target {@code (datum, grid)} combination
|
||||||
*/
|
*/
|
||||||
public static GridCoordinate convert(GridCoordinate source,
|
public static GridCoordinate convert(GridCoordinate source,
|
||||||
@@ -73,6 +79,36 @@ public final class CoordinateConverter {
|
|||||||
return toGrid(transformDatum(source, sourceDatum, targetDatum), targetDatum, targetGrid);
|
return toGrid(transformDatum(source, sourceDatum, targetDatum), targetDatum, targetGrid);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Projects a {@link Coordinate} (referenced to {@code datum}) onto {@code grid}.
|
||||||
|
* <p>
|
||||||
|
* The {@link Coordinate#gpsAltitude() GPS altitude} is taken as the ellipsoidal
|
||||||
|
* height since it is the GNSS-derived height and therefore the closest match;
|
||||||
|
* the barometric altitude is used as a fallback and {@code 0} if neither is set.
|
||||||
|
*/
|
||||||
|
public static GridCoordinate toGrid(Coordinate coordinate, AltitudeSource altitudeSource, MapDatum datum, MapGrid grid) {
|
||||||
|
return toGrid(toGeographicCoordinate(coordinate, altitudeSource), datum, grid);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Inverse projection of a grid coordinate onto a {@link Coordinate}. The
|
||||||
|
* resulting ellipsoidal height is stored as the coordinate's altitude.
|
||||||
|
*/
|
||||||
|
public static Coordinate toCoordinate(GridCoordinate grid, MapDatum datum, MapGrid mapGrid) {
|
||||||
|
GeographicCoordinate geographic = toGeographic(grid, datum, mapGrid);
|
||||||
|
return new Coordinate(geographic.latitude(), geographic.longitude(),
|
||||||
|
Altitude.fromMeters(geographic.ellipsoidalHeight()));
|
||||||
|
}
|
||||||
|
|
||||||
|
private static GeographicCoordinate toGeographicCoordinate(Coordinate coordinate, AltitudeSource source) {
|
||||||
|
Altitude altitude = switch (source) {
|
||||||
|
case GPS -> coordinate.gpsAltitude();
|
||||||
|
case BAROMETRIC -> coordinate.barometricAltitude();
|
||||||
|
};
|
||||||
|
double height = altitude != null ? altitude.meters() : 0.0;
|
||||||
|
return new GeographicCoordinate(coordinate.latitude(), coordinate.longitude(), height);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Projects a geographic coordinate (referenced to {@code datum}) onto {@code grid}.
|
* Projects a geographic coordinate (referenced to {@code datum}) onto {@code grid}.
|
||||||
*/
|
*/
|
||||||
|
|||||||
Reference in New Issue
Block a user