Index: trunk/src/org/openstreetmap/josm/data/imagery/ImageryInfo.java
===================================================================
--- trunk/src/org/openstreetmap/josm/data/imagery/ImageryInfo.java	(revision 8348)
+++ trunk/src/org/openstreetmap/josm/data/imagery/ImageryInfo.java	(revision 8349)
@@ -19,4 +19,5 @@
 
 import org.openstreetmap.gui.jmapviewer.Coordinate;
+import org.openstreetmap.gui.jmapviewer.OsmMercator;
 import org.openstreetmap.gui.jmapviewer.interfaces.Attributed;
 import org.openstreetmap.gui.jmapviewer.tilesources.AbstractTileSource;
@@ -225,4 +226,5 @@
         @pref String description;
         @pref Map<String, String> noTileHeaders;
+        @pref int tileSize = OsmMercator.DEFAUL_TILE_SIZE;
 
         /**
@@ -281,4 +283,6 @@
                 noTileHeaders = i.noTileHeaders;
             }
+
+            tileSize = i.getTileSize();
         }
 
@@ -402,4 +406,5 @@
             noTileHeaders = e.noTileHeaders;
         }
+        setTileSize(e.tileSize);
     }
 
Index: trunk/src/org/openstreetmap/josm/data/imagery/ImageryLayerInfo.java
===================================================================
--- trunk/src/org/openstreetmap/josm/data/imagery/ImageryLayerInfo.java	(revision 8348)
+++ trunk/src/org/openstreetmap/josm/data/imagery/ImageryLayerInfo.java	(revision 8349)
@@ -150,8 +150,13 @@
         for (ImageryInfo def : defaultLayers) {
             // temporary migration code, so all user preferences will get updated with new settings from JOSM site (can be removed ~Dez. 2015)
-            if (def.getNoTileHeaders() != null) {
+            if (def.getNoTileHeaders() != null || def.getTileSize() > 0) {
                 for (ImageryInfo i: layers) {
                     if (isSimilar(def,  i)) {
-                        i.setNoTileHeaders(def.getNoTileHeaders());
+                        if (def.getNoTileHeaders() != null) {
+                            i.setNoTileHeaders(def.getNoTileHeaders());
+                        }
+                        if (def.getTileSize() > 0) {
+                            i.setTileSize(def.getTileSize());
+                        }
                         changed = true;
                     }
Index: trunk/src/org/openstreetmap/josm/gui/bbox/SlippyMapBBoxChooser.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/bbox/SlippyMapBBoxChooser.java	(revision 8348)
+++ trunk/src/org/openstreetmap/josm/gui/bbox/SlippyMapBBoxChooser.java	(revision 8349)
@@ -125,6 +125,6 @@
 
     // upper left and lower right corners of the selection rectangle (x/y on ZOOM_MAX)
-    private Point iSelectionRectStart;
-    private Point iSelectionRectEnd;
+    private Coordinate iSelectionRectStart;
+    private Coordinate iSelectionRectEnd;
 
     /**
@@ -210,19 +210,12 @@
             // draw selection rectangle
             if (iSelectionRectStart != null && iSelectionRectEnd != null) {
-
-                int zoomDiff = MAX_ZOOM - zoom;
-                Point tlc = getTopLeftCoordinates();
-                int x_min = (iSelectionRectStart.x >> zoomDiff) - tlc.x;
-                int y_min = (iSelectionRectStart.y >> zoomDiff) - tlc.y;
-                int x_max = (iSelectionRectEnd.x >> zoomDiff) - tlc.x;
-                int y_max = (iSelectionRectEnd.y >> zoomDiff) - tlc.y;
-
-                int w = x_max - x_min;
-                int h = y_max - y_min;
+                Rectangle box = new Rectangle(getMapPosition(iSelectionRectStart, false));
+                box.add(getMapPosition(iSelectionRectEnd, false));
+
                 g.setColor(new Color(0.9f, 0.7f, 0.7f, 0.6f));
-                g.fillRect(x_min, y_min, w, h);
+                g.fillRect(box.x, box.y, box.width, box.height);
 
                 g.setColor(Color.BLACK);
-                g.drawRect(x_min, y_min, w, h);
+                g.drawRect(box.x, box.y, box.width, box.height);
             }
         } catch (Exception e) {
@@ -257,27 +250,15 @@
         Point p_min = new Point(Math.min(aEnd.x, aStart.x), Math.min(aEnd.y, aStart.y));
 
-        Point tlc = getTopLeftCoordinates();
-        int zoomDiff = MAX_ZOOM - zoom;
-        Point pEnd = new Point(p_max.x + tlc.x, p_max.y + tlc.y);
-        Point pStart = new Point(p_min.x + tlc.x, p_min.y + tlc.y);
-
-        pEnd.x <<= zoomDiff;
-        pEnd.y <<= zoomDiff;
-        pStart.x <<= zoomDiff;
-        pStart.y <<= zoomDiff;
-
-        iSelectionRectStart = pStart;
-        iSelectionRectEnd = pEnd;
-
-        Coordinate l1 = getPosition(p_max); // lon may be outside [-180,180]
-        Coordinate l2 = getPosition(p_min); // lon may be outside [-180,180]
+        iSelectionRectStart = getPosition(p_min);
+        iSelectionRectEnd =   getPosition(p_max);
+
         Bounds b = new Bounds(
                 new LatLon(
-                        Math.min(l2.getLat(), l1.getLat()),
-                        LatLon.toIntervalLon(Math.min(l1.getLon(), l2.getLon()))
+                        Math.min(iSelectionRectStart.getLat(), iSelectionRectEnd.getLat()),
+                        LatLon.toIntervalLon(Math.min(iSelectionRectStart.getLon(), iSelectionRectEnd.getLon()))
                         ),
                         new LatLon(
-                                Math.max(l2.getLat(), l1.getLat()),
-                                LatLon.toIntervalLon(Math.max(l1.getLon(), l2.getLon())))
+                                Math.max(iSelectionRectStart.getLat(), iSelectionRectEnd.getLat()),
+                                LatLon.toIntervalLon(Math.max(iSelectionRectStart.getLon(), iSelectionRectEnd.getLon())))
                 );
         Bounds oldValue = this.bbox;
@@ -332,11 +313,6 @@
         }
 
-        int y1 = tileSource.LatToY(bbox.getMinLat(), MAX_ZOOM);
-        int y2 = tileSource.LatToY(bbox.getMaxLat(), MAX_ZOOM);
-        int x1 = tileSource.LonToX(minLon, MAX_ZOOM);
-        int x2 = tileSource.LonToX(maxLon, MAX_ZOOM);
-
-        iSelectionRectStart = new Point(Math.min(x1, x2), Math.min(y1, y2));
-        iSelectionRectEnd = new Point(Math.max(x1, x2), Math.max(y1, y2));
+        iSelectionRectStart = new Coordinate(bbox.getMinLat(), bbox.getMinLon());
+        iSelectionRectEnd = new Coordinate(bbox.getMaxLat(), bbox.getMaxLon());
 
         // calc the screen coordinates for the new selection rectangle
Index: trunk/src/org/openstreetmap/josm/gui/layer/TMSLayer.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/layer/TMSLayer.java	(revision 8348)
+++ trunk/src/org/openstreetmap/josm/gui/layer/TMSLayer.java	(revision 8349)
@@ -66,4 +66,5 @@
 import org.openstreetmap.josm.data.preferences.StringProperty;
 import org.openstreetmap.josm.data.projection.Projection;
+import org.openstreetmap.josm.gui.ExtendedDialog;
 import org.openstreetmap.josm.gui.MapFrame;
 import org.openstreetmap.josm.gui.MapView;
@@ -423,10 +424,16 @@
 
     private final int getBestZoom() {
-        double factor = getScaleFactor(1);
+        double factor = getScaleFactor(1); // check the ratio between area of tilesize at zoom 1 to current view
         double result = Math.log(factor)/Math.log(2)/2+1;
-        // In general, smaller zoom levels are more readable.  We prefer big,
-        // block, pixelated (but readable) map text to small, smeared,
-        // unreadable underzoomed text.  So, use .floor() instead of rounding
-        // to skew things a bit toward the lower zooms.
+        /*
+         * Math.log(factor)/Math.log(2) - gives log base 2 of factor
+         * We divide result by 2, as factor contains ratio between areas. We could do Math.sqrt before log, or just divide log by 2
+         * In general, smaller zoom levels are more readable.  We prefer big,
+         * block, pixelated (but readable) map text to small, smeared,
+         * unreadable underzoomed text.  So, use .floor() instead of rounding
+         * to skew things a bit toward the lower zooms.
+         * Remember, that result here, should correspond to TMSLayer.paint(...)
+         * getScaleFactor(...) is supposed to be between 0.75 and 3
+         */
         int intResult = (int)Math.floor(result);
         if (intResult > getMaxZoomLvl())
@@ -514,6 +521,17 @@
             public void actionPerformed(ActionEvent ae) {
                 if (clickedTile != null) {
-                    showMetadataTile = clickedTile;
-                    redraw();
+                    ExtendedDialog ed = new ExtendedDialog(Main.parent, tr("Tile Info"), new String[]{tr("OK")});
+                    ed.setIcon(JOptionPane.INFORMATION_MESSAGE);
+                    StringBuilder content = new StringBuilder();
+                    content.append("Tile name: ").append(clickedTile.getKey()).append("\n");
+                    try {
+                        content.append("Tile url: ").append(clickedTile.getUrl()).append("\n");
+                    } catch (IOException e) {
+                    }
+                    content.append("Tile size: ").append(clickedTile.getTileSource().getTileSize()).append("x").append(clickedTile.getTileSource().getTileSize()).append("\n");
+                    Rectangle displaySize = tileToRect(clickedTile);
+                    content.append("Tile display size: ").append(displaySize.width).append("x").append(displaySize.height).append("\n");
+                    ed.setContent(content.toString());
+                    ed.showDialog();
                 }
             }
@@ -1384,5 +1402,5 @@
             myDrawString(g, tr("Display zoom: {0}", displayZoomLevel), 50, 155);
             myDrawString(g, tr("Pixel scale: {0}", getScaleFactor(currentZoomLevel)), 50, 170);
-            myDrawString(g, tr("Best zoom: {0}", Math.log(getScaleFactor(1))/Math.log(2)/2+1), 50, 185);
+            myDrawString(g, tr("Best zoom: {0}", getBestZoom()), 50, 185);
             if(tileLoader instanceof TMSCachedTileLoader) {
                 TMSCachedTileLoader cachedTileLoader = (TMSCachedTileLoader)tileLoader;
Index: trunk/src/org/openstreetmap/josm/io/imagery/ImageryReader.java
===================================================================
--- trunk/src/org/openstreetmap/josm/io/imagery/ImageryReader.java	(revision 8348)
+++ trunk/src/org/openstreetmap/josm/io/imagery/ImageryReader.java	(revision 8349)
@@ -138,4 +138,5 @@
                         "country-code",
                         "icon",
+                        "tile-size",
                 }).contains(qName)) {
                     newState = State.ENTRY_ATTRIBUTE;
@@ -300,4 +301,17 @@
                     entry.setIcon(accumulator.toString());
                     break;
+                case "tile-size":
+                    Integer tileSize = null;
+                    try {
+                        tileSize  = Integer.parseInt(accumulator.toString());
+                    } catch(NumberFormatException e) {
+                        tileSize = null;
+                    }
+                    if (tileSize == null) {
+                        skipEntry = true;
+                    } else {
+                        entry.setTileSize(tileSize.intValue());
+                    }
+                    break;
                 }
                 break;
