Index: /trunk/src/org/openstreetmap/josm/data/Bounds.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/data/Bounds.java	(revision 12817)
+++ /trunk/src/org/openstreetmap/josm/data/Bounds.java	(revision 12818)
@@ -570,5 +570,7 @@
      * @param visitor A function to call for the points on the edge.
      * @since 10806
-     */
+     * @deprecated use {@link Projection#visitOutline(Bounds, Consumer)}
+     */
+    @Deprecated
     public void visitEdge(Projection projection, Consumer<LatLon> visitor) {
         double width = getWidth();
Index: /trunk/src/org/openstreetmap/josm/data/ProjectionBounds.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/data/ProjectionBounds.java	(revision 12817)
+++ /trunk/src/org/openstreetmap/josm/data/ProjectionBounds.java	(revision 12818)
@@ -75,4 +75,21 @@
         this.maxEast = maxEast;
         this.maxNorth = maxNorth;
+    }
+
+    /**
+     * Construct uninitialized bounds.
+     * <p>
+     * At least one call to {@link #extend(EastNorth)} or {@link #extend(ProjectionBounds)}
+     * is required immediately after construction to initialize the {@code ProjectionBounds}
+     * instance and make it valid.
+     * <p>
+     * Uninitialized {@code ProjectionBounds} must not be passed to other methods
+     * or used in any way other than initializing it.
+     */
+    public ProjectionBounds() {
+        this.minEast = Double.POSITIVE_INFINITY;
+        this.minNorth = Double.POSITIVE_INFINITY;
+        this.maxEast = Double.NEGATIVE_INFINITY;
+        this.maxNorth = Double.NEGATIVE_INFINITY;
     }
 
Index: /trunk/src/org/openstreetmap/josm/data/osm/visitor/BoundingXYVisitor.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/data/osm/visitor/BoundingXYVisitor.java	(revision 12817)
+++ /trunk/src/org/openstreetmap/josm/data/osm/visitor/BoundingXYVisitor.java	(revision 12818)
@@ -56,5 +56,5 @@
     public void visit(Bounds b) {
         if (b != null) {
-            b.visitEdge(Main.getProjection(), this::visit);
+            Main.getProjection().visitOutline(b, this::visit);
         }
     }
Index: /trunk/src/org/openstreetmap/josm/data/projection/AbstractProjection.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/data/projection/AbstractProjection.java	(revision 12817)
+++ /trunk/src/org/openstreetmap/josm/data/projection/AbstractProjection.java	(revision 12818)
@@ -5,4 +5,5 @@
 import java.util.HashMap;
 import java.util.Map;
+import java.util.function.Consumer;
 import java.util.function.DoubleUnaryOperator;
 
@@ -204,22 +205,7 @@
                 result = projectionBoundsBox;
                 if (result == null) {
-                    Bounds b = getWorldBoundsLatLon();
-                    // add 4 corners
-                    result = new ProjectionBounds(latlon2eastNorth(b.getMin()));
-                    result.extend(latlon2eastNorth(b.getMax()));
-                    result.extend(latlon2eastNorth(new LatLon(b.getMinLat(), b.getMaxLon())));
-                    result.extend(latlon2eastNorth(new LatLon(b.getMaxLat(), b.getMinLon())));
-                    // and trace along the outline
-                    double dLon = (b.getMaxLon() - b.getMinLon()) / 1000;
-                    double dLat = (b.getMaxLat() - b.getMinLat()) / 1000;
-                    for (double lon = b.getMinLon(); lon < b.getMaxLon(); lon += dLon) {
-                        result.extend(latlon2eastNorth(new LatLon(b.getMinLat(), lon)));
-                        result.extend(latlon2eastNorth(new LatLon(b.getMaxLat(), lon)));
-                    }
-                    for (double lat = b.getMinLat(); lat < b.getMaxLat(); lat += dLat) {
-                        result.extend(latlon2eastNorth(new LatLon(lat, b.getMinLon())));
-                        result.extend(latlon2eastNorth(new LatLon(lat, b.getMaxLon())));
-                    }
-                    projectionBoundsBox = result;
+                    ProjectionBounds bds = new ProjectionBounds();
+                    visitOutline(getWorldBoundsLatLon(), bds::extend);
+                    projectionBoundsBox = bds;
                 }
             }
@@ -232,3 +218,35 @@
         return this;
     }
+
+    @Override
+    public void visitOutline(Bounds b, Consumer<EastNorth> visitor) {
+        visitOutline(b, 100, visitor);
+    }
+
+    private void visitOutline(Bounds b, int nPoints, Consumer<EastNorth> visitor) {
+        double minlon = b.getMinLon();
+        if (b.crosses180thMeridian()) {
+            minlon -= 360.0;
+        }
+        double spanLon = b.getMaxLon() - minlon;
+        double spanLat = b.getMaxLat() - b.getMinLat();
+
+        //TODO: Use projection to see if there is any need for doing this along each axis.
+        for (int step = 0; step < nPoints; step++) {
+            visitor.accept(latlon2eastNorth(
+                    new LatLon(b.getMinLat(), minlon + spanLon * step / nPoints)));
+        }
+        for (int step = 0; step < nPoints; step++) {
+            visitor.accept(latlon2eastNorth(
+                    new LatLon(b.getMinLat() + spanLat * step / nPoints, b.getMaxLon())));
+        }
+        for (int step = 0; step < nPoints; step++) {
+            visitor.accept(latlon2eastNorth(
+                    new LatLon(b.getMaxLat(), b.getMaxLon() - spanLon * step / nPoints)));
+        }
+        for (int step = 0; step < nPoints; step++) {
+            visitor.accept(latlon2eastNorth(
+                    new LatLon(b.getMaxLat() - spanLat * step / nPoints, minlon)));
+        }
+    }
 }
Index: /trunk/src/org/openstreetmap/josm/data/projection/Projection.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/data/projection/Projection.java	(revision 12817)
+++ /trunk/src/org/openstreetmap/josm/data/projection/Projection.java	(revision 12818)
@@ -1,4 +1,6 @@
 // License: GPL. For details, see LICENSE file.
 package org.openstreetmap.josm.data.projection;
+
+import java.util.function.Consumer;
 
 import org.openstreetmap.josm.data.Bounds;
@@ -121,3 +123,14 @@
      */
     boolean switchXY();
+
+    /**
+     * Visit points along the edge of this bounds instance.
+     * <p>
+     * Depending on the shape in east/north space, it may simply visit the 4 corners
+     * or (more generally) several points along the curved edges.
+     * @param bounds the lat/lon rectangle to trace
+     * @param visitor a function to call for the points on the edge.
+     * @since 12818
+     */
+    void visitOutline(Bounds bounds, Consumer<EastNorth> visitor);
 }
Index: /trunk/src/org/openstreetmap/josm/gui/MapViewState.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/gui/MapViewState.java	(revision 12817)
+++ /trunk/src/org/openstreetmap/josm/gui/MapViewState.java	(revision 12818)
@@ -302,6 +302,6 @@
     public Area getArea(Bounds bounds) {
         Path2D area = new Path2D.Double();
-        bounds.visitEdge(getProjection(), latlon -> {
-            MapViewPoint point = getPointFor(latlon);
+        getProjection().visitOutline(bounds, en -> {
+            MapViewPoint point = getPointFor(en);
             if (area.getCurrentPoint() == null) {
                 area.moveTo(point.getInViewX(), point.getInViewY());
