Index: trunk/src/org/openstreetmap/josm/data/coor/LatLon.java
===================================================================
--- trunk/src/org/openstreetmap/josm/data/coor/LatLon.java	(revision 4573)
+++ trunk/src/org/openstreetmap/josm/data/coor/LatLon.java	(revision 4574)
@@ -244,10 +244,20 @@
      */
     public static double roundToOsmPrecision(double value) {
+        return Math.round(value / MAX_SERVER_PRECISION) * MAX_SERVER_PRECISION; // causes tiny rounding errors (see LatLonTest)
+    }
+
+    /**
+     * Returns the value rounded to OSM precisions, i.e. to
+     * LatLon.MAX_SERVER_PRECISION. The result is guaranteed to be exact, but at a great cost.
+     * This function is about 1000 times slower than roundToOsmPrecision(), use it with caution.
+     *
+     * @return rounded value
+     */
+    public static double roundToOsmPrecisionStrict(double value) {
         double absV = Math.abs(value);
         int numOfDigits = MAX_SERVER_DIGITS + (absV < 1 ? 0 : (absV < 10 ? 1 : (absV < 100 ? 2 : 3))); 
         return BigDecimal.valueOf(value).round(new MathContext(numOfDigits)).doubleValue();
-        //return Math.round(value / MAX_SERVER_PRECISION) * MAX_SERVER_PRECISION; // Old method, causes rounding errors (see LatLonTest) !
-    }
-    
+    }
+
     /**
      * Replies a clone of this lat LatLon, rounded to OSM precisions, i.e. to
@@ -260,4 +270,17 @@
                 roundToOsmPrecision(lat()),
                 roundToOsmPrecision(lon())
+        );
+    }
+
+    /**
+     * Replies a clone of this lat LatLon, rounded to OSM precisions, i.e. to
+     * MAX_SERVER_PRECISION
+     *
+     * @return a clone of this lat LatLon
+     */
+    public LatLon getRoundedToOsmPrecisionStrict() {
+        return new LatLon(
+                roundToOsmPrecisionStrict(lat()),
+                roundToOsmPrecisionStrict(lon())
         );
     }
Index: trunk/test/unit/org/openstreetmap/josm/data/coor/LatLonTest.java
===================================================================
--- trunk/test/unit/org/openstreetmap/josm/data/coor/LatLonTest.java	(revision 4573)
+++ trunk/test/unit/org/openstreetmap/josm/data/coor/LatLonTest.java	(revision 4574)
@@ -25,51 +25,51 @@
         
         for (double value : sampleValues) {
-            assertEquals(LatLon.roundToOsmPrecision(value), value, 0);
+            assertEquals(LatLon.roundToOsmPrecisionStrict(value), value, 0);
         }
         
-        assertEquals(LatLon.roundToOsmPrecision(0.0), 0.0, 0);
-        assertEquals(LatLon.roundToOsmPrecision(-0.0), 0.0, 0);
+        assertEquals(LatLon.roundToOsmPrecisionStrict(0.0), 0.0, 0);
+        assertEquals(LatLon.roundToOsmPrecisionStrict(-0.0), 0.0, 0);
         
-        assertEquals(LatLon.roundToOsmPrecision(0.12345678),  0.1234568, 0);
-        assertEquals(LatLon.roundToOsmPrecision(0.123456789), 0.1234568, 0);
+        assertEquals(LatLon.roundToOsmPrecisionStrict(0.12345678),  0.1234568, 0);
+        assertEquals(LatLon.roundToOsmPrecisionStrict(0.123456789), 0.1234568, 0);
 
-        assertEquals(LatLon.roundToOsmPrecision(1.12345678),  1.1234568, 0);
-        assertEquals(LatLon.roundToOsmPrecision(1.123456789), 1.1234568, 0);
+        assertEquals(LatLon.roundToOsmPrecisionStrict(1.12345678),  1.1234568, 0);
+        assertEquals(LatLon.roundToOsmPrecisionStrict(1.123456789), 1.1234568, 0);
 
-        assertEquals(LatLon.roundToOsmPrecision(10.12345678),  10.1234568, 0);
-        assertEquals(LatLon.roundToOsmPrecision(10.123456789), 10.1234568, 0);
+        assertEquals(LatLon.roundToOsmPrecisionStrict(10.12345678),  10.1234568, 0);
+        assertEquals(LatLon.roundToOsmPrecisionStrict(10.123456789), 10.1234568, 0);
 
-        assertEquals(LatLon.roundToOsmPrecision(100.12345678),  100.1234568, 0);
-        assertEquals(LatLon.roundToOsmPrecision(100.123456789), 100.1234568, 0);
+        assertEquals(LatLon.roundToOsmPrecisionStrict(100.12345678),  100.1234568, 0);
+        assertEquals(LatLon.roundToOsmPrecisionStrict(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.roundToOsmPrecisionStrict(100.00000001),  100.0000000, 0);
+        assertEquals(LatLon.roundToOsmPrecisionStrict(100.000000001),  100.0000000, 0);
+        assertEquals(LatLon.roundToOsmPrecisionStrict(100.0000000001),  100.0000000, 0);
+        assertEquals(LatLon.roundToOsmPrecisionStrict(100.00000000001),  100.0000000, 0);
+        assertEquals(LatLon.roundToOsmPrecisionStrict(100.000000000001),  100.0000000, 0);
+        assertEquals(LatLon.roundToOsmPrecisionStrict(100.0000000000001),  100.0000000, 0);
+        assertEquals(LatLon.roundToOsmPrecisionStrict(100.00000000000001),  100.0000000, 0);
+        assertEquals(LatLon.roundToOsmPrecisionStrict(100.000000000000001),  100.0000000, 0);
+        assertEquals(LatLon.roundToOsmPrecisionStrict(100.0000000000000001),  100.0000000, 0);
+        assertEquals(LatLon.roundToOsmPrecisionStrict(100.00000000000000001),  100.0000000, 0);
+        assertEquals(LatLon.roundToOsmPrecisionStrict(100.000000000000000001),  100.0000000, 0);
+        assertEquals(LatLon.roundToOsmPrecisionStrict(100.0000000000000000001),  100.0000000, 0);
+        assertEquals(LatLon.roundToOsmPrecisionStrict(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);
+        assertEquals(LatLon.roundToOsmPrecisionStrict(99.999999999999999999999),  100.0000000, 0);
+        assertEquals(LatLon.roundToOsmPrecisionStrict(99.99999999999999999999),  100.0000000, 0);
+        assertEquals(LatLon.roundToOsmPrecisionStrict(99.9999999999999999999),  100.0000000, 0);
+        assertEquals(LatLon.roundToOsmPrecisionStrict(99.999999999999999999),  100.0000000, 0);
+        assertEquals(LatLon.roundToOsmPrecisionStrict(99.99999999999999999),  100.0000000, 0);
+        assertEquals(LatLon.roundToOsmPrecisionStrict(99.9999999999999999),  100.0000000, 0);
+        assertEquals(LatLon.roundToOsmPrecisionStrict(99.999999999999999),  100.0000000, 0);
+        assertEquals(LatLon.roundToOsmPrecisionStrict(99.99999999999999),  100.0000000, 0);
+        assertEquals(LatLon.roundToOsmPrecisionStrict(99.9999999999999),  100.0000000, 0);
+        assertEquals(LatLon.roundToOsmPrecisionStrict(99.999999999999),  100.0000000, 0);
+        assertEquals(LatLon.roundToOsmPrecisionStrict(99.99999999999),  100.0000000, 0);
+        assertEquals(LatLon.roundToOsmPrecisionStrict(99.9999999999),  100.0000000, 0);
+        assertEquals(LatLon.roundToOsmPrecisionStrict(99.999999999),  100.0000000, 0);
+        assertEquals(LatLon.roundToOsmPrecisionStrict(99.99999999),  100.0000000, 0);
+        assertEquals(LatLon.roundToOsmPrecisionStrict(99.9999999),  99.9999999, 0);
     }
 }
