]> gitweb.fperrin.net Git - GpsPrune.git/blobdiff - src/tim/prune/data/TrackExtents.java
Moved source into separate src directory due to popular request
[GpsPrune.git] / src / tim / prune / data / TrackExtents.java
diff --git a/src/tim/prune/data/TrackExtents.java b/src/tim/prune/data/TrackExtents.java
new file mode 100644 (file)
index 0000000..0bf3081
--- /dev/null
@@ -0,0 +1,103 @@
+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;
+       }
+}