package tim.prune.data;
/**
* Class to hold the extents of a track, in 2d and in 3d,
* and to calculate a square area with a default border
*/
public class TrackExtents
{
/** Track object */
private Track _track = null;
/** X and Y ranges */
private DoubleRange _xRange = null, _yRange = null;
/** Border multiplier */
private static final double BORDER_MULTIPLIER = 1.1; // 10% border
/**
* Constructor
* @param inTrack track object to take extents from
*/
public TrackExtents(Track inTrack)
{
_track = inTrack;
_xRange = inTrack.getXRange().copy();
_yRange = inTrack.getYRange().copy();
}
/**
* Make the x and y ranges square with a default border around
*/
public void applySquareBorder()
{
// Find the middle of the x and y
final double midXvalue = _xRange.getMidValue();
final double midYvalue = _yRange.getMidValue();
// Find x and y range, take maximum
double xyRange = Math.max(_xRange.getRange(), _yRange.getRange()) * BORDER_MULTIPLIER;
if (getHorizontalDistanceMetres() < 10.0)
{
// all the points are near enough on the same spot, expand scale to avoid dividing by zero
xyRange = 0.1;
}
// Apply these new min and max to the ranges
_xRange.addValue(midXvalue - xyRange / 2.0);
_xRange.addValue(midXvalue + xyRange / 2.0);
_yRange.addValue(midYvalue - xyRange / 2.0);
_yRange.addValue(midYvalue + xyRange / 2.0);
}
/** @return x range */
public DoubleRange getXRange() {
return _xRange;
}
/** @return y range */
public DoubleRange getYRange() {
return _yRange;
}
/** @return altitude range */
public DoubleRange getAltitudeRange()
{
final int numPoints = _track.getNumPoints();
DoubleRange altRange = new DoubleRange();
for (int i=0; i<numPoints; i++)
{
DataPoint p = _track.getPoint(i);
if (p != null && p.hasAltitude()) {
altRange.addValue(p.getAltitude().getMetricValue());
}
}
return altRange;
}
/**
* @return the greater of the N/S and E/W extent of the track, in metres (including border)
*/
public double getHorizontalDistanceMetres()
{
DoubleRange lonRange = _track.getLonRange();
DoubleRange latRange = _track.getLatRange();
// Find horizontal and vertical extents of enclosing rectangle
DataPoint southPoint = new DataPoint(new Latitude(latRange.getMinimum(), Coordinate.FORMAT_DEG),
new Longitude(lonRange.getMidValue(), Coordinate.FORMAT_DEG), null);
DataPoint northPoint = new DataPoint(new Latitude(latRange.getMaximum(), Coordinate.FORMAT_DEG),
new Longitude(lonRange.getMidValue(), Coordinate.FORMAT_DEG), null);
double nsDist = Distance.convertRadiansToDistance(
DataPoint.calculateRadiansBetween(northPoint, southPoint), UnitSetLibrary.UNITS_METRES); // both in m
// Same again for bottom and top, take maximum
DataPoint westPoint = new DataPoint(new Latitude(latRange.getMidValue(), Coordinate.FORMAT_DEG),
new Longitude(lonRange.getMinimum(), Coordinate.FORMAT_DEG), null);
DataPoint eastPoint = new DataPoint(new Latitude(latRange.getMidValue(), Coordinate.FORMAT_DEG),
new Longitude(lonRange.getMinimum(), Coordinate.FORMAT_DEG), null);
double ewDist = Distance.convertRadiansToDistance(
DataPoint.calculateRadiansBetween(westPoint, eastPoint), UnitSetLibrary.UNITS_METRES); // both in m
final double horizDistance = Math.max(nsDist, ewDist) * BORDER_MULTIPLIER;
return horizDistance;
}
}