Index: /trunk/src/org/openstreetmap/josm/data/Bounds.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/data/Bounds.java	(revision 4572)
+++ /trunk/src/org/openstreetmap/josm/data/Bounds.java	(revision 4573)
@@ -44,5 +44,9 @@
 
     public Bounds(LatLon b) {
-        this(b, b);
+        // Do not call this(b, b) to avoid GPX performance issue (see #7028) until roundToOsmPrecision() is improved
+        this.minLat = LatLon.roundToOsmPrecision(b.lat());
+        this.minLon = LatLon.roundToOsmPrecision(b.lon());
+        this.maxLat = this.minLat;
+        this.maxLon = this.minLon;
     }
 
Index: /trunk/test/performance/org/openstreetmap/josm/data/osm/RoundingPerformanceTest.java
===================================================================
--- /trunk/test/performance/org/openstreetmap/josm/data/osm/RoundingPerformanceTest.java	(revision 4573)
+++ /trunk/test/performance/org/openstreetmap/josm/data/osm/RoundingPerformanceTest.java	(revision 4573)
@@ -0,0 +1,40 @@
+package org.openstreetmap.josm.data.osm;
+
+import org.junit.Test;
+import org.openstreetmap.josm.data.coor.LatLon;
+import org.openstreetmap.josm.data.coor.LatLonTest;
+
+import static org.junit.Assert.assertTrue;
+
+public class RoundingPerformanceTest extends LatLonTest {
+    
+    private static double oldRoundToOsmPrecision(double value) {
+        return Math.round(value / LatLon.MAX_SERVER_PRECISION) * LatLon.MAX_SERVER_PRECISION; // Old method, causes rounding errors, but efficient
+    }
+
+    @Test
+    public void test() {
+        final int n = 1000000;
+        long start = System.nanoTime();
+        for (int i = 0; i < n; i++) {
+            for (double value : sampleValues) {
+                oldRoundToOsmPrecision(value);
+            }
+        }
+        long end = System.nanoTime();
+        long oldTime = end-start;
+        System.out.println("Old time: "+oldTime/1000000.0 + " ms");
+        
+        start = System.nanoTime();
+        for (int i = 0; i < n; i++) {
+            for (double value : sampleValues) {
+                LatLon.roundToOsmPrecision(value);
+            }
+        }
+        end = System.nanoTime();
+        long newTime = end-start;
+        System.out.println("New time: "+newTime/1000000.0 + " ms");
+        
+        assertTrue(newTime <= oldTime*10);
+    }
+}
Index: /trunk/test/unit/org/openstreetmap/josm/data/coor/LatLonTest.java
===================================================================
--- /trunk/test/unit/org/openstreetmap/josm/data/coor/LatLonTest.java	(revision 4572)
+++ /trunk/test/unit/org/openstreetmap/josm/data/coor/LatLonTest.java	(revision 4573)
@@ -12,15 +12,17 @@
 public class LatLonTest {
 
+    protected static final double[] sampleValues = new double[]{
+            -180.0, -179.9, -179.6, -179.5, -179.4, -179.1, -179.0, -100.0, -99.9, -10.0, -9.9, -1.0, -0.1,
+            180.0,  179.9,  179.6,  179.5,  179.4,  179.1,  179.0,  100.0,  99.9,  10.0,  9.9,  1.0,  0.1,
+            0.12, 0.123, 0.1234, 0.12345, 0.123456, 0.1234567,
+            1.12, 1.123, 1.1234, 1.12345, 1.123456, 1.1234567,
+            10.12, 10.123, 10.1234, 10.12345, 10.123456, 10.1234567,
+            100.12, 100.123, 100.1234, 100.12345, 100.123456, 100.1234567
+           };
+    
     @Test
     public void roundingTests() {
         
-        for (double value : new double[]{
-                -180.0, -179.9, -179.6, -179.5, -179.4, -179.1, -179.0, -100.0, -99.9, -10.0, -9.9, -1.0, -0.1,
-                 180.0,  179.9,  179.6,  179.5,  179.4,  179.1,  179.0,  100.0,  99.9,  10.0,  9.9,  1.0,  0.1,
-                 0.12, 0.123, 0.1234, 0.12345, 0.123456, 0.1234567,
-                 1.12, 1.123, 1.1234, 1.12345, 1.123456, 1.1234567,
-                 10.12, 10.123, 10.1234, 10.12345, 10.123456, 10.1234567,
-                 100.12, 100.123, 100.1234, 100.12345, 100.123456, 100.1234567
-                }) {
+        for (double value : sampleValues) {
             assertEquals(LatLon.roundToOsmPrecision(value), value, 0);
         }
@@ -40,4 +42,34 @@
         assertEquals(LatLon.roundToOsmPrecision(100.12345678),  100.1234568, 0);
         assertEquals(LatLon.roundToOsmPrecision(100.123456789), 100.1234568, 0);
+
+        assertEquals(LatLon.roundToOsmPrecision(100.00000001),  100.0000000, 0);
+        assertEquals(LatLon.roundToOsmPrecision(100.000000001),  100.0000000, 0);
+        assertEquals(LatLon.roundToOsmPrecision(100.0000000001),  100.0000000, 0);
+        assertEquals(LatLon.roundToOsmPrecision(100.00000000001),  100.0000000, 0);
+        assertEquals(LatLon.roundToOsmPrecision(100.000000000001),  100.0000000, 0);
+        assertEquals(LatLon.roundToOsmPrecision(100.0000000000001),  100.0000000, 0);
+        assertEquals(LatLon.roundToOsmPrecision(100.00000000000001),  100.0000000, 0);
+        assertEquals(LatLon.roundToOsmPrecision(100.000000000000001),  100.0000000, 0);
+        assertEquals(LatLon.roundToOsmPrecision(100.0000000000000001),  100.0000000, 0);
+        assertEquals(LatLon.roundToOsmPrecision(100.00000000000000001),  100.0000000, 0);
+        assertEquals(LatLon.roundToOsmPrecision(100.000000000000000001),  100.0000000, 0);
+        assertEquals(LatLon.roundToOsmPrecision(100.0000000000000000001),  100.0000000, 0);
+        assertEquals(LatLon.roundToOsmPrecision(100.00000000000000000001),  100.0000000, 0);
+
+        assertEquals(LatLon.roundToOsmPrecision(99.999999999999999999999),  100.0000000, 0);
+        assertEquals(LatLon.roundToOsmPrecision(99.99999999999999999999),  100.0000000, 0);
+        assertEquals(LatLon.roundToOsmPrecision(99.9999999999999999999),  100.0000000, 0);
+        assertEquals(LatLon.roundToOsmPrecision(99.999999999999999999),  100.0000000, 0);
+        assertEquals(LatLon.roundToOsmPrecision(99.99999999999999999),  100.0000000, 0);
+        assertEquals(LatLon.roundToOsmPrecision(99.9999999999999999),  100.0000000, 0);
+        assertEquals(LatLon.roundToOsmPrecision(99.999999999999999),  100.0000000, 0);
+        assertEquals(LatLon.roundToOsmPrecision(99.99999999999999),  100.0000000, 0);
+        assertEquals(LatLon.roundToOsmPrecision(99.9999999999999),  100.0000000, 0);
+        assertEquals(LatLon.roundToOsmPrecision(99.999999999999),  100.0000000, 0);
+        assertEquals(LatLon.roundToOsmPrecision(99.99999999999),  100.0000000, 0);
+        assertEquals(LatLon.roundToOsmPrecision(99.9999999999),  100.0000000, 0);
+        assertEquals(LatLon.roundToOsmPrecision(99.999999999),  100.0000000, 0);
+        assertEquals(LatLon.roundToOsmPrecision(99.99999999),  100.0000000, 0);
+        assertEquals(LatLon.roundToOsmPrecision(99.9999999),  99.9999999, 0);
     }
 }
