Index: /trunk/src/org/openstreetmap/josm/tools/Geometry.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/tools/Geometry.java	(revision 9950)
+++ /trunk/src/org/openstreetmap/josm/tools/Geometry.java	(revision 9951)
@@ -31,4 +31,6 @@
 import org.openstreetmap.josm.data.osm.RelationMember;
 import org.openstreetmap.josm.data.osm.Way;
+import org.openstreetmap.josm.data.projection.Projection;
+import org.openstreetmap.josm.data.projection.Projections;
 
 /**
@@ -630,10 +632,4 @@
     /**
      * Returns area of a closed way in square meters.
-     * (approximate(?), but should be OK for small areas)
-     *
-     * Relies on the current projection: Works correctly, when
-     * one unit in projected coordinates corresponds to one meter.
-     * This is true for most projections, but not for WGS84 and
-     * Mercator (EPSG:3857).
      *
      * @param way Way to measure, should be closed (first node is the same as last node)
@@ -641,49 +637,5 @@
      */
     public static double closedWayArea(Way way) {
-
-        //http://local.wasp.uwa.edu.au/~pbourke/geometry/polyarea/
-        double area = 0;
-        Node lastN = null;
-        for (Node n : way.getNodes()) {
-            if (lastN != null) {
-                area += (calcX(n) * calcY(lastN)) - (calcY(n) * calcX(lastN));
-            }
-            lastN = n;
-        }
-        return Math.abs(area/2);
-    }
-
-    protected static double calcX(Node p1) {
-        double lat1, lon1, lat2, lon2;
-        double dlon, dlat;
-
-        lat1 = p1.getCoor().lat() * Math.PI / 180.0;
-        lon1 = p1.getCoor().lon() * Math.PI / 180.0;
-        lat2 = lat1;
-        lon2 = 0;
-
-        dlon = lon2 - lon1;
-        dlat = lat2 - lat1;
-
-        double a = Math.pow(Math.sin(dlat/2), 2) + Math.cos(lat1) * Math.cos(lat2) * Math.pow(Math.sin(dlon/2), 2);
-        double c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a));
-        return 6367000 * c;
-    }
-
-    protected static double calcY(Node p1) {
-        double lat1, lon1, lat2, lon2;
-        double dlon, dlat;
-
-        lat1 = p1.getCoor().lat() * Math.PI / 180.0;
-        lon1 = p1.getCoor().lon() * Math.PI / 180.0;
-        lat2 = 0;
-        lon2 = lon1;
-
-        dlon = lon2 - lon1;
-        dlat = lat2 - lat1;
-
-        double a = Math.pow(Math.sin(dlat/2), 2) + Math.cos(lat1) * Math.cos(lat2) * Math.pow(Math.sin(dlon/2), 2);
-        double c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a));
-        return 6367000 * c;
+        return getAreaAndPerimeter(way.getNodes(), Projections.getProjectionByCode("EPSG:54008")).getArea();
     }
 
@@ -986,4 +938,16 @@
      */
     public static AreaAndPerimeter getAreaAndPerimeter(List<Node> nodes) {
+        return getAreaAndPerimeter(nodes, null);
+    }
+
+    /**
+     * Calculate area and perimeter length of a polygon in the given projection.
+     *
+     * @param nodes the list of nodes representing the polygon
+     * @param projection the projection to use for the calculation, {@code null} defaults to {@link Main#getProjection()}
+     * @return area and perimeter
+     */
+    public static AreaAndPerimeter getAreaAndPerimeter(List<Node> nodes, Projection projection) {
+        CheckParameterUtil.ensureParameterNotNull(nodes, "nodes");
         double area = 0;
         double perimeter = 0;
@@ -991,7 +955,8 @@
             boolean closed = nodes.get(0) == nodes.get(nodes.size() - 1);
             int numSegments = closed ? nodes.size() - 1 : nodes.size();
-            EastNorth p1 = nodes.get(0).getEastNorth();
+            EastNorth p1 = projection == null ? nodes.get(0).getEastNorth() : projection.latlon2eastNorth(nodes.get(0).getCoor());
             for (int i = 1; i <= numSegments; i++) {
-                EastNorth p2 = nodes.get(i == numSegments ? 0 : i).getEastNorth();
+                final Node node = nodes.get(i == numSegments ? 0 : i);
+                final EastNorth p2 = projection == null ? node.getEastNorth() : projection.latlon2eastNorth(node.getCoor());
                 area += p1.east() * p2.north() - p2.east() * p1.north();
                 perimeter += p1.distance(p2);
Index: /trunk/test/unit/org/openstreetmap/josm/tools/GeometryTest.java
===================================================================
--- /trunk/test/unit/org/openstreetmap/josm/tools/GeometryTest.java	(revision 9950)
+++ /trunk/test/unit/org/openstreetmap/josm/tools/GeometryTest.java	(revision 9951)
@@ -71,5 +71,5 @@
             DataSet ds = OsmReader.parseDataSet(in, null);
             Way closedWay = (Way) Utils.filter(ds.allPrimitives(), SearchCompiler.compile("landuse=forest")).iterator().next();
-            Assert.assertEquals(5721923.660644531, Geometry.closedWayArea(closedWay), 1e-3);
+            Assert.assertEquals(5760015.7353515625, Geometry.closedWayArea(closedWay), 1e-3);
         }
     }
