You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
105 lines
4.2 KiB
105 lines
4.2 KiB
package visualiser.utils;
|
|
|
|
import shared.dataInput.RaceDataSource;
|
|
import shared.model.GPSCoordinate;
|
|
import visualiser.model.GraphCoordinate;
|
|
|
|
/**
|
|
* Converts GPS coordinates to view volume coordinates. Longitudes are equally spaced at all latitudes,
|
|
* which leads to inaccurate distance measurements close to the poles. This is acceptable as races are
|
|
* not likely to be set there.
|
|
*/
|
|
public class GPSConverter {
|
|
private double longRight;
|
|
private double longLeft;
|
|
private double latBottom;
|
|
private double latTop;
|
|
/**
|
|
* Conversion factor from longitude to view units
|
|
*/
|
|
private double longitudeFactor;
|
|
/**
|
|
* Conversion factor from latitude to view units
|
|
*/
|
|
private double latitudeFactor;
|
|
|
|
/**
|
|
* Set up projection with default view boundaries from RaceDataSource
|
|
* @param source for view boundaries
|
|
* @param longitudeFactor separation of a degree of longitude in view units
|
|
* @param latitudeFactor separation of a degree of latitude in view units
|
|
*/
|
|
public GPSConverter(RaceDataSource source, double longitudeFactor, double latitudeFactor) {
|
|
this.latTop = source.getMapTopLeft().getLatitude();
|
|
this.longLeft = source.getMapTopLeft().getLongitude();
|
|
this.latBottom = source.getMapBottomRight().getLatitude();
|
|
this.longRight = source.getMapBottomRight().getLongitude();
|
|
this.longitudeFactor = longitudeFactor;
|
|
this.latitudeFactor = latitudeFactor;
|
|
}
|
|
|
|
/**
|
|
* Converts GPS coordinates to coordinates for container.
|
|
* It is assumed that the provided GPSCoordinate will always be within the GPSCoordinate boundaries of the RaceMap.
|
|
*
|
|
* @param lat GPS latitude
|
|
* @param lon GPS longitude
|
|
* @return GraphCoordinate (pair of doubles)
|
|
* @see GraphCoordinate
|
|
*/
|
|
private GraphCoordinate convertGPS(double lat, double lon) {
|
|
|
|
//Calculate the width/height, in gps coordinates, of the map.
|
|
double longWidth = longRight - longLeft;
|
|
double latHeight = latBottom - latTop;
|
|
|
|
//Calculate the distance between the specified coordinate and the edge of the map.
|
|
double longDelta = lon - longLeft;
|
|
double latDelta = lat - latTop;
|
|
|
|
//Calculate the proportion along horizontally, from the left, the coordinate should be.
|
|
double longProportion = longDelta / longWidth;
|
|
//Calculate the proportion along vertically, from the top, the coordinate should be.
|
|
double latProportion = latDelta / latHeight;
|
|
|
|
//Check which metric dimension of our map is smaller. We use this to ensure that any rendered stuff retains its correct aspect ratio, and that everything is visible on screen.
|
|
double smallerDimension = Math.min(longitudeFactor, latitudeFactor);
|
|
|
|
//Calculate the x and y pixel coordinates.
|
|
//We take the complement of latProportion to flip it.
|
|
int x = (int) (longProportion * smallerDimension);
|
|
int y = (int) (latProportion * smallerDimension);
|
|
|
|
//Because we try to maintain the correct aspect ratio, we will end up with "spare" pixels along the larger dimension (e.g., width 800, height 600, 200 extra pixels along width).
|
|
double extraDistance = Math.abs(longitudeFactor - latitudeFactor);
|
|
//We therefore "center" the coordinates along this larger dimension, by adding half of the extra pixels.
|
|
if (longitudeFactor > latitudeFactor) {
|
|
x += extraDistance / 2;
|
|
} else {
|
|
y += extraDistance / 2;
|
|
}
|
|
|
|
|
|
//Finally, create the GraphCoordinate.
|
|
GraphCoordinate graphCoordinate = new GraphCoordinate(x, y);
|
|
|
|
|
|
return graphCoordinate;
|
|
|
|
}
|
|
|
|
/**
|
|
* Converts the GPS Coordinate to GraphCoordinate.
|
|
* It is assumed that the provided GPSCoordinate will always be within the GPSCoordinate boundaries of the RaceMap.
|
|
*
|
|
* @param coordinate GPSCoordinate representation of Latitude and Longitude.
|
|
* @return GraphCoordinate that the GPS is coordinates are to be displayed on the map.
|
|
* @see GraphCoordinate
|
|
* @see GPSCoordinate
|
|
*/
|
|
public GraphCoordinate convertGPS(GPSCoordinate coordinate) {
|
|
return convertGPS(coordinate.getLatitude(), coordinate.getLongitude());
|
|
}
|
|
|
|
}
|