]> gitweb.fperrin.net Git - GpsPrune.git/blobdiff - tim/prune/gui/map/ScaleBar.java
Version 11, August 2010
[GpsPrune.git] / tim / prune / gui / map / ScaleBar.java
index 1daa19ebd926dc05c852290fb2e653760532c00d..fdd2949446c6b387c8c1fd7f33bedc4209ac9918 100644 (file)
@@ -16,8 +16,8 @@ public class ScaleBar extends JPanel
 {
        /** zoom level */
        private int _zoomLevel = -1;
-       /** y tile number */
-       private int _yTile = -1;
+       /** y position */
+       private double _yPos = 0.0;
 
        // Dimensions
        /** Offset from left side in pixels */
@@ -29,18 +29,14 @@ public class ScaleBar extends JPanel
        /** Margin between bar and end text in pixels */
        private static final int MARGIN_WIDTH = 8;
 
-       /** metric scales for each zoom level */
-       private static final int[] _metricScales = {10000, 5000, 2000, 2000, 1000, 500, 200, 100,
-               50, 20, 10, 5, 2, 2, 1, -2, -5, -10, -20, -50, -100, -200};
+       /** scales for each zoom level */
+       private static final int[] _scales = {10000, 5000, 2000, 2000, 1000, 500, 200, 100,
+               50, 20, 10, 5, 2, 2, 1,
+               -2, -5, -10, -20, -50, -100, -200};
        /** pixel counts for each zoom level (metric) */
-       private static final int[] _metricPixels = {64, 64, 51, 102, 102, 102, 81, 81,
-               81, 65, 65, 65, 52, 105, 105, 105, 83, 83, 83, 67, 67, 67};
-       /** imperial scales for each zoom level (num miles) */
-       private static final int[] _mileScales = {10000, 10000, 5000, 2000, 2000, 1000, 500, 200,
-               100, 50, 20, 10, 5, 2, 1, -2, -2, -5, -10, -20, -50, -100};
-       /** pixel counts for each zoom level (miles) */
-       private static final int[] _milePixels = {79, 79, 79, 64, 127, 127, 127, 102,
-               102, 102, 81, 81, 81, 65, 65, 65, 130, 104, 104, 104, 104, 83, 83};
+       private static final double[] _metricPixels = {64, 64, 51, 102, 102, 102, 81, 81,
+               81, 65, 65, 65, 52, 105, 105,
+               105, 83, 83, 83, 67, 67, 67};
 
 
        /**
@@ -64,15 +60,14 @@ public class ScaleBar extends JPanel
                {
                        try {
                                boolean useMetric = Config.getConfigBoolean(Config.KEY_METRIC_UNITS);
-                               int rightSide = LEFT_OFFSET + (useMetric?_metricPixels[_zoomLevel]:_milePixels[_zoomLevel]);
-                               int scale = (useMetric?_metricScales[_zoomLevel]:_mileScales[_zoomLevel]);
+                               double drightSide = LEFT_OFFSET + _metricPixels[_zoomLevel] * (useMetric?1:1.609);
+                               int scale = _scales[_zoomLevel];
 
-                               // work out cos(latitude) from y tile and zoom, and apply to scale
-                               final double n = Math.pow(2, _zoomLevel);
-                               final double angle = Math.PI * (1 - 2.0*_yTile/n);
+                               // work out cos(latitude) from y position, and apply to scale
+                               final double angle = Math.PI * (1 - 2*_yPos);
                                final double lat = Math.atan(Math.sinh(angle));
                                final double cosLat = Math.cos(lat);
-                               rightSide = (int) (rightSide / cosLat);
+                               int rightSide = (int) (drightSide / cosLat);
                                // Adjust if scale is too large
                                while (rightSide > 300)
                                {
@@ -81,6 +76,8 @@ public class ScaleBar extends JPanel
                                        // Abort if scale is now less than 1 unit (shouldn't ever be)
                                        if (scale < 1) {return;}
                                }
+                               // Abort if scale is negative (around poles)
+                               if (rightSide < 1) {return;}
 
                                // Determine colours to use
                                Color barColour = Config.getColourScheme().getColour(ColourScheme.IDX_TEXT);
@@ -105,8 +102,7 @@ public class ScaleBar extends JPanel
                                inG.drawLine(rightSide, Y_OFFSET+1, rightSide, Y_OFFSET-TICK_HEIGHT);
                                inG.drawLine(rightSide+1, Y_OFFSET+1, rightSide+1, Y_OFFSET-TICK_HEIGHT);
                                // text
-                               String text = (scale>0?(""+scale):("1/"+(-scale))) + " "
-                                       + I18nManager.getText(useMetric?"units.kilometres.short":"units.miles.short");
+                               String text = getScaleText(scale, useMetric);
                                inG.setColor(blankColour);
                                inG.drawString(text, rightSide+MARGIN_WIDTH-1, Y_OFFSET);
                                inG.drawString(text, rightSide+MARGIN_WIDTH+1, Y_OFFSET);
@@ -119,13 +115,35 @@ public class ScaleBar extends JPanel
                }
        }
 
+       /**
+        * Get the scale text for the given scale
+        * @param inScale scale number
+        * @param inUseMetric true to use km/m, false for miles/ft
+        * @return scale text as string
+        */
+       private static String getScaleText(int inScale, boolean inUseMetric)
+       {
+               if (inScale > 0) {
+                       // Positive scale means km or miles
+                       return "" + inScale     + " " +
+                               I18nManager.getText(inUseMetric?"units.kilometres.short":"units.miles.short");
+               }
+               if (inUseMetric) {
+                       // negative scale means m
+                       return "" + (-1000 / inScale) + " " + I18nManager.getText("units.metres.short");
+               }
+               // fallen through to feet
+               return "" + (-5280 / inScale) + " " + I18nManager.getText("units.feet.short");
+       }
+
        /**
         * Update the scale level
         * @param inZoom new zoom level
+        * @param inYPos y position, where 0 is north pole, 1 is south pole
         */
-       public void updateScale(int inZoom, int inYtile)
+       public void updateScale(int inZoom, double inYPos)
        {
                _zoomLevel = inZoom;
-               _yTile = inYtile;
+               _yPos = inYPos;
        }
 }