Index: trunk/src/org/openstreetmap/josm/tools/OsmUrlToBounds.java
===================================================================
--- trunk/src/org/openstreetmap/josm/tools/OsmUrlToBounds.java	(revision 4735)
+++ trunk/src/org/openstreetmap/josm/tools/OsmUrlToBounds.java	(revision 4736)
@@ -8,4 +8,5 @@
 import java.util.Map;
 
+import org.openstreetmap.josm.Main;
 import org.openstreetmap.josm.data.Bounds;
 import org.openstreetmap.josm.data.coor.LatLon;
@@ -60,6 +61,9 @@
             }
         } catch (NumberFormatException x) {
+            x.printStackTrace();
         } catch (NullPointerException x) {
+            x.printStackTrace();
         } catch (ArrayIndexOutOfBoundsException x) {
+            x.printStackTrace();
         }
         return b;
@@ -141,14 +145,28 @@
     }
 
+    public static final double R = 6378137.0;
+
     public static Bounds positionToBounds(final double lat, final double lon, final int zoom) {
         int tileSizeInPixels = 256;
-        int screenHeight = Toolkit.getDefaultToolkit().getScreenSize().height;
-        int screenWidth = Toolkit.getDefaultToolkit().getScreenSize().width;
-        double deltaX = screenWidth / 2. / tileSizeInPixels;
-        double deltaY = screenHeight / 2. / tileSizeInPixels;
-        Pair<Double, Double> center = getTileOfLatLon(lat, lon, zoom);
-        return new Bounds(
-                getLatLonOfTile(center.a - deltaX, center.b - deltaY, zoom),
-                getLatLonOfTile(center.a + deltaX, center.b + deltaY, zoom));
+        int height = Toolkit.getDefaultToolkit().getScreenSize().height;
+        int width = Toolkit.getDefaultToolkit().getScreenSize().width;
+        if (Main.map != null && Main.map.mapView != null) {
+            height = Main.map.mapView.getHeight();
+            width = Main.map.mapView.getWidth();
+        }
+        double scale = (1 << zoom) * tileSizeInPixels / (2 * Math.PI * R);
+        double deltaX = width / 2.0 / scale;
+        double deltaY = height / 2.0 / scale;
+        double x = Math.toRadians(lon) * R;
+        double y = mercatorY(lat);
+        return new Bounds(invMercatorY(y - deltaY), Math.toDegrees(x - deltaX) / R, invMercatorY(y + deltaY), Math.toDegrees(x + deltaX) / R);
+    }
+
+    public static double mercatorY(double lat) {
+        return Math.log(Math.tan(Math.PI/4 + Math.toRadians(lat)/2)) * R;
+    }
+
+    public static double invMercatorY(double north) {
+        return Math.toDegrees(Math.atan(Math.sinh(north / R)));
     }
 
