package tim.prune.data; /** * Class to manage the scaling of points */ public class PointScaler { // Original data private Track _track = null; // Range information private AltitudeRange _altRange = null; private DoubleRange _latRange = null; private DoubleRange _lonRange = null; private double _latMedian = 0.0; private double _lonMedian = 0.0; private int _minAltitude = 0; private int _maxAltitude = 0; // Scaling information private double _longFactor = 0.0; // Scaled points private double[] _xValues = null; private double[] _yValues = null; private int[] _altValues = null; private double _maxX = 0.0; private double _maxY = 0.0; // lat/long lines private double[] _latLinesDegs = null; private double[] _lonLinesDegs = null; private double[] _latLinesScaled = null; private double[] _lonLinesScaled = null; // Constants private static final double[] COORD_SEPARATIONS = { 1.0, // 1deg 30.0/60.0, 20.0/60.0, // 30min, 20min 10.0/60.0, 5.0/60.0, // 10min, 5min 3.0/60.0, 2.0/60.0, 1.0/60.0 // 3min, 2min, 1min }; private static final int MAX_COORD_SEPARATION_INDEX = COORD_SEPARATIONS.length - 1; /** * Constructor * @param inTrack Track object */ public PointScaler(Track inTrack) { _track = inTrack; _altRange = new AltitudeRange(); _latRange = new DoubleRange(); _lonRange = new DoubleRange(); } /** * Scale the points */ public void scale() { // Clear data _altRange.clear(); _latRange.clear(); _lonRange.clear(); int numPoints = 0; int p = 0; DataPoint point = null; // Find limits of data if (_track != null && (numPoints = _track.getNumPoints()) > 0) { for (p=0; p getMaximumVert() ? getMaximumHoriz():getMaximumVert(); // calculate boundaries in degrees double minLong = getUnscaledLongitude(-maxValue); double maxLong = getUnscaledLongitude(maxValue); double minLat = getUnscaledLatitude(-maxValue); double maxLat = getUnscaledLatitude(maxValue); // work out what line separation to use to give at least two lines int sepIndex = -1; double separation; int numLatLines = 0, numLonLines = 0; do { sepIndex++; separation = COORD_SEPARATIONS[sepIndex]; numLatLines = getNumLinesBetween(minLat, maxLat, separation); numLonLines = getNumLinesBetween(minLong, maxLong, separation); } while ((numLonLines <= 1 || numLatLines <= 1) && sepIndex < MAX_COORD_SEPARATION_INDEX); // create lines based on this separation _latLinesDegs = getLines(minLat, maxLat, separation, numLatLines); _lonLinesDegs = getLines(minLong, maxLong, separation, numLonLines); // scale lines also _latLinesScaled = new double[numLatLines]; for (int i=0; i= inMin) numLines++; value += inSeparation; } return numLines; } /** * Get the line values in the given range using the specified separation * @param inMin minimum value * @param inMax maximum value * @param inSeparation line separation * @param inCount number of lines already counted * @return array of line values */ private static double[] getLines(double inMin, double inMax, double inSeparation, int inCount) { double[] values = new double[inCount]; // Start looking from round number of degrees below minimum double value = (int) inMin; if (inMin < 0.0) value = value - 1.0; // Loop until bigger than maximum int numLines = 0; while (value < inMax) { if (value >= inMin) { values[numLines] = value; numLines++; } value += inSeparation; } return values; } /** * @return array of latitude lines in degrees */ public double[] getLatitudeLines() { return _latLinesDegs; } /** * @return array of longitude lines in degrees */ public double[] getLongitudeLines() { return _lonLinesDegs; } /** * @return array of latitude lines in scaled units */ public double[] getScaledLatitudeLines() { return _latLinesScaled; } /** * @return array of longitude lines in scaled units */ public double[] getScaledLongitudeLines() { return _lonLinesScaled; } }