]> gitweb.fperrin.net Git - GpsPrune.git/blobdiff - src/tim/prune/data/PointScaler.java
Moved source into separate src directory due to popular request
[GpsPrune.git] / src / tim / prune / data / PointScaler.java
diff --git a/src/tim/prune/data/PointScaler.java b/src/tim/prune/data/PointScaler.java
new file mode 100644 (file)
index 0000000..446c0a2
--- /dev/null
@@ -0,0 +1,174 @@
+package tim.prune.data;
+
+/**
+ * Class to manage the scaling of points, used by the ThreeDModel
+ */
+public class PointScaler
+{
+       /** Original data */
+       private Track _track = null;
+       /** Secondary data for terrain grid */
+       private Track _terrainTrack = null;
+       // Scaled values for data track
+       private double[] _xValues = null;
+       private double[] _yValues = null;
+       private double[] _altValues = null;
+       // Scaled values for terrain track, if any
+       private double[] _terrainxValues = null;
+       private double[] _terrainyValues = null;
+       private double[] _terrainAltValues = null;
+       // Altitude range
+       private double _altitudeRange = 0.0;
+       private double _minAltitudeMetres = 0.0;
+       // Horizontal distance
+       private double _horizDistanceMetres = 0.0;
+
+
+       /**
+        * Constructor
+        * @param inTrack Track object
+        */
+       public PointScaler(Track inTrack)
+       {
+               _track = inTrack;
+       }
+
+       /**
+        * @param inTrack terrain track to add
+        */
+       public void addTerrain(Track inTrack)
+       {
+               _terrainTrack = inTrack;
+       }
+
+       /**
+        * Scale the points
+        */
+       public void scale()
+       {
+               // Work out extents
+               TrackExtents extents = new TrackExtents(_track);
+               extents.applySquareBorder();
+               _horizDistanceMetres = Math.max(extents.getHorizontalDistanceMetres(), 1.0);
+               final int numPoints = _track.getNumPoints();
+
+               // Find altitude range (including terrain)
+               DoubleRange altRangeMetres = extents.getAltitudeRange();
+               if (_terrainTrack != null) {
+                       altRangeMetres.combine(new TrackExtents(_terrainTrack).getAltitudeRange());
+               }
+               _altitudeRange = altRangeMetres.getRange() / _horizDistanceMetres;
+               _minAltitudeMetres = altRangeMetres.getMinimum();
+
+               // create new arrays for scaled values
+               if (_xValues == null || _xValues.length != numPoints)
+               {
+                       _xValues = new double[numPoints];
+                       _yValues = new double[numPoints];
+                       _altValues = new double[numPoints];
+                       if (_terrainTrack != null)
+                       {
+                               _terrainxValues = new double[_terrainTrack.getNumPoints()];
+                               _terrainyValues = new double[_terrainTrack.getNumPoints()];
+                               _terrainAltValues = new double[_terrainTrack.getNumPoints()];
+                       }
+               }
+
+               final double midXvalue = extents.getXRange().getMidValue();
+               final double midYvalue = extents.getYRange().getMidValue();
+               final double xyRange   = extents.getXRange().getRange();
+
+               // Calculate scaled values
+               for (int p=0; p<numPoints; p++)
+               {
+                       DataPoint point = _track.getPoint(p);
+                       if (point != null)
+                       {
+                               _xValues[p] = (_track.getX(p) - midXvalue) / xyRange;
+                               _yValues[p] = (midYvalue - _track.getY(p)) / xyRange; // y values have to be inverted
+                               _altValues[p] = (point.getAltitude().getMetricValue() - _minAltitudeMetres) / _horizDistanceMetres;
+                       }
+               }
+               if (_terrainTrack != null)
+               {
+                       for (int p=0; p<_terrainTrack.getNumPoints(); p++)
+                       {
+                               _terrainxValues[p] = (_terrainTrack.getX(p) - midXvalue) / xyRange;
+                               _terrainyValues[p] = (midYvalue - _terrainTrack.getY(p)) / xyRange; // y values have to be inverted
+                               _terrainAltValues[p] = (_terrainTrack.getPoint(p).getAltitude().getMetricValue() - _minAltitudeMetres) / _horizDistanceMetres;
+                       }
+               }
+       }
+
+
+
+       /**
+        * Get the horizontal value for the specified point
+        * @param inIndex index of point, starting at 0
+        * @return scaled horizontal value
+        */
+       public double getHorizValue(int inIndex)
+       {
+               return _xValues[inIndex];
+       }
+
+       /**
+        * Get the vertical value for the specified point
+        * @param inIndex index of point, starting at 0
+        * @return scaled vertical value
+        */
+       public double getVertValue(int inIndex)
+       {
+               return _yValues[inIndex];
+       }
+
+       /**
+        * Get the altitude value for the specified point
+        * @param inIndex index of point, starting at 0
+        * @return scaled altitude value
+        */
+       public double getAltValue(int inIndex)
+       {
+               return _altValues[inIndex];
+       }
+
+       /**
+        * @return altitude range as fraction of horizontal range
+        */
+       public double getAltitudeRange()
+       {
+               return _altitudeRange;
+       }
+
+       /**
+        * Get the horizontal value for the specified point
+        * @param inIndex index of point, starting at 0
+        * @return scaled horizontal value
+        */
+       public double getTerrainHorizValue(int inIndex)
+       {
+               return _terrainxValues[inIndex];
+       }
+
+       /**
+        * Get the vertical value for the specified point
+        * @param inIndex index of point, starting at 0
+        * @return scaled vertical value
+        */
+       public double getTerrainVertValue(int inIndex)
+       {
+               return _terrainyValues[inIndex];
+       }
+
+       /**
+        * @param inIndex index of point in terrain track
+        * @return scaled altitude value for the specified terrain point
+        */
+       public double getTerrainAltValue(int inIndex)
+       {
+               if (_terrainAltValues != null) {
+                       return _terrainAltValues[inIndex];
+               }
+               return 0.0;
+       }
+}