Index: src/org/openstreetmap/josm/data/coor/LatLon.java
===================================================================
--- src/org/openstreetmap/josm/data/coor/LatLon.java	(revision 9607)
+++ src/org/openstreetmap/josm/data/coor/LatLon.java	(working copy)
@@ -8,6 +8,7 @@
 import static java.lang.Math.sin;
 import static java.lang.Math.sqrt;
 import static java.lang.Math.toRadians;
+import static org.openstreetmap.josm.tools.I18n.tr;
 import static org.openstreetmap.josm.tools.I18n.trc;
 
 import java.awt.geom.Area;
@@ -20,6 +21,7 @@
 import org.openstreetmap.gui.jmapviewer.interfaces.ICoordinate;
 import org.openstreetmap.josm.Main;
 import org.openstreetmap.josm.data.Bounds;
+import org.openstreetmap.josm.data.projection.Ellipsoid;
 import org.openstreetmap.josm.tools.Utils;
 
 /**
@@ -61,9 +63,31 @@
     public static final LatLon NORTH_POLE = new LatLon(90, 0);
     public static final LatLon SOUTH_POLE = new LatLon(-90, 0);
 
+    /**
+     * DistanceTypes
+     */
+    public enum DistanceType {
+        EUCLIDIAN,
+        GREAT_CIRCLE,
+        CURVATURE,
+        ELLIPTICAL,
+        AUTO,
+    }
+
+    public static final double EPS_MAX = Double.MAX_VALUE;
+    public static final double EPS_10M = 10.0;
+    public static final double EPS_1M  = 1.0;
+    public static final double EPS_1DM = 0.1;
+    public static final double EPS_1CM = 0.01;
+    public static final double EPS_MIN = 0.001;
+
+    /**
+     * DecimalFormats
+     */
     private static DecimalFormat cDmsMinuteFormatter = new DecimalFormat("00");
     private static DecimalFormat cDmsSecondFormatter = new DecimalFormat("00.0");
     private static DecimalFormat cDmMinuteFormatter = new DecimalFormat("00.000");
+
     public static final DecimalFormat cDdFormatter;
     public static final DecimalFormat cDdHighPecisionFormatter;
     static {
@@ -303,13 +327,43 @@
     }
 
     /**
+     * Compute the distance, projection dependant, fixed to a simple projection that maps
+     * a square degree to a square unit in two dimensional euclidian space.
+     *
+     * This will not always find the shortest distance (wrt a sphere), since it does not
+     * wrap at projection bounds. At the poles a projected square degree is a lot larger
+     * than at the equator, this distortion is /not/ accounted for by this function.
+     *
+     * The closer the points are together (wrt euclidian space),
+     * and the less difference they have in longitude,
+     * the smaller the inaccuracy will be.
+     *
+     * @param other the other point.
+     * @return the distance.
+     */
+    public double euclidianDistance(LatLon other) {
+        double R = Main.getProjection().getEllipsoid().getMeanRadius();
+        return 2*PI*R * distance(other)/360;
+    }
+
+    /**
+     * Computes the <u>sphere</u> surface area segment given by the minimal bbox around this point and another.
+     * @param other the other point.
+     * @return the sphere surface area in square metres.
+     */
+    public double greatCircleArea(LatLon other) {
+        //double R = Main.getProjection().getEllipsoid().getAuthalicRadius();
+        return -1.0;
+    }
+
+    /**
      * Computes the distance between this lat/lon and another point on the earth.
-     * Uses Haversine formular.
+     * Uses Haversine formula.
      * @param other the other point.
-     * @return distance in metres.
+     * @return the (shortest) great circle distance to the other point in metres.
      */
     public double greatCircleDistance(LatLon other) {
-        double R = 6378135;
+        double R = Main.getProjection().getEllipsoid().getMeanRadius();
         double sinHalfLat = sin(toRadians(other.lat() - this.lat()) / 2);
         double sinHalfLon = sin(toRadians(other.lon() - this.lon()) / 2);
         double d = 2 * R * asin(
@@ -326,6 +380,52 @@
     }
 
     /**
+     * Convenience method.
+     * @param other the other point to measure distance to.
+     * @return the (shortest) distance on an approximated "great ellipse" in metres.
+     */
+    public double curvatureDistance(LatLon other) {
+        /* use EPS_MAX here if there are performance problems */
+        return curvatureDistance(other, EPS_MIN);
+    }
+
+    /**
+     * Computes the distance between this lat/lon and another point using local radii dependent on lat.
+     *
+     * The approximation is better than the plain great circle distance, because it uses <u>two</u>
+     * perpendicular "great circles" that intersect at the center LatLon coordinate (between this
+     * and the other point)to better emulate ellipsoid curvature:
+     * <ul><li>one circle with "meridional" radius, fitting the ellipsoid's curvature in north-south direction</li>
+     * <li>a second circle, fitting the ellipsoid's curvature in east-west direction</li></ul>
+     *
+     * See <a href="http://clynchg3c.com/Technote/geodesy/radiigeo.pdf">a technote</a> or
+     * <a href="https://en.wikipedia.org/wiki/Earth_radius#Radii_of_curvature">the wiki article</a>
+     * for more details.
+     *
+     * As the curvature varies with latitude the function offers recursive distance calculation
+     * of half of the distances (split using the center LatLon coordinate) until the difference
+     * between the sum of distances of both halves and the full distance is less than <code>eps</code>.
+     *
+     * @param other the other point.
+     * @param eps recurse until error is smaller than epsilon meters.
+     * @return the (shortest) distance on an approximated "great ellipse" in metres.
+     */
+    public double curvatureDistance(LatLon other, final double eps) {
+        final Ellipsoid e = Main.getProjection().getEllipsoid();
+        return new Object() {
+            private double r(LatLon a, LatLon b, double _ret) {
+                LatLon m = a.getCenter(b);
+                double mlat = toRadians(m.lat());
+                double dlat = toRadians(b.lat() - a.lat()) * e.meridionalRadiusOfCurvature(mlat);
+                double dlon = toRadians(b.lon() - a.lon()) * cos(mlat) * e.verticalRadiusOfCurvature(mlat);
+                double ret = sqrt(dlat*dlat + dlon*dlon);
+
+                return eps > Math.abs(_ret/2-ret) ? ret : r(a, m, ret)+r(m, b, ret);
+            }
+        }.r(this, other, 0);
+    }
+
+    /**
      * Returns the heading, in radians, that you have to use to get from this lat/lon to another.
      *
      * (I don't know the original source of this formula, but see
@@ -400,6 +500,37 @@
         return super.distanceSq(ll);
     }
 
+    @SuppressWarnings("javadoc")
+    public double distance(final LatLon other, final DistanceType d) {
+        switch (d) {
+        case CURVATURE:    return curvatureDistance(other);
+        case GREAT_CIRCLE: return greatCircleDistance(other);
+        case EUCLIDIAN:    return euclidianDistance(other);
+        }
+        return -1.0;
+    }
+
+    /**
+     * Calls every distance measuring method and replies the result
+     * @param other the other coordinate to measure a distance to
+     * @return the formatted output, one line for the output of each distance function
+     */
+    public String getDistanceSummary(final LatLon other) {
+        DecimalFormat df = new DecimalFormat(Main.pref.get("statusbar.decimal-format", "0.0"));
+        DecimalFormat _df = new DecimalFormat("0.000");
+        StringBuffer ret = new StringBuffer(0xFF);
+        for (DistanceType d: DistanceType.values()) {
+            double n = distance(other, d);
+            if (!(n < 0)) {
+                ret.append("      ");
+                ret.append(tr(d.name().replace("_", " ").toLowerCase() + " distance: {0} m",
+                        n < 100 ? _df.format(n) : df.format(n)));
+                ret.append("\n");
+            }
+        }
+        return ret.toString();
+    }
+
     @Override
     public String toString() {
         return "LatLon[lat="+lat()+",lon="+lon()+']';
Index: src/org/openstreetmap/josm/data/osm/Node.java
===================================================================
--- src/org/openstreetmap/josm/data/osm/Node.java	(revision 9607)
+++ src/org/openstreetmap/josm/data/osm/Node.java	(working copy)
@@ -72,6 +72,10 @@
         return new LatLon(lat, lon);
     }
 
+    public LatLon getLatLon() {
+        return getCoor();
+    }
+
     /**
      * <p>Replies the projected east/north coordinates.</p>
      *
Index: src/org/openstreetmap/josm/data/projection/Ellipsoid.java
===================================================================
--- src/org/openstreetmap/josm/data/projection/Ellipsoid.java	(revision 9607)
+++ src/org/openstreetmap/josm/data/projection/Ellipsoid.java	(working copy)
@@ -360,4 +360,27 @@
 
         return xyz;
     }
+
+    /**
+     * get earth's equatorial radius
+     */
+    public double getEquatorialRadius() {
+        return a;
+    }
+
+    /**
+     * get earth's polar radius
+     */
+    public double getPolarRadius() {
+        return b;
+    }
+
+    /**
+     * get earth's global mean radius
+     * @return mean radius
+     * @see <a href="https://en.wikipedia.org/wiki/Earth_radius#Mean_radius">mean radius on wikipedia</a>
+     */
+    public double getMeanRadius() {
+        return (2*a+b)/3;
+    }
 }
Index: src/org/openstreetmap/josm/data/projection/Projection.java
===================================================================
--- src/org/openstreetmap/josm/data/projection/Projection.java	(revision 9607)
+++ src/org/openstreetmap/josm/data/projection/Projection.java	(working copy)
@@ -5,6 +5,7 @@
 import org.openstreetmap.josm.data.ProjectionBounds;
 import org.openstreetmap.josm.data.coor.EastNorth;
 import org.openstreetmap.josm.data.coor.LatLon;
+import org.openstreetmap.josm.data.projection.datum.Datum;
 
 /**
  * A projection, i.e.&nbsp;a class that supports conversion from lat/lon
@@ -15,6 +16,18 @@
  */
 public interface Projection {
     /**
+     * Returns the associated {@link Datum}
+     * @return the datum of this projection
+     */
+    public Datum getDatum();
+
+    /**
+     * Returns the associated {@link Ellipsoid}
+     * @return the ellipsoid specification
+     */
+    public Ellipsoid getEllipsoid();
+
+    /**
      * The default scale factor in east/north units per pixel
      * ({@link org.openstreetmap.josm.gui.NavigatableComponent#scale})).
      * FIXME: misnomer
Index: src/org/openstreetmap/josm/gui/MapStatus.java
===================================================================
--- src/org/openstreetmap/josm/gui/MapStatus.java	(revision 9607)
+++ src/org/openstreetmap/josm/gui/MapStatus.java	(working copy)
@@ -94,6 +94,7 @@
 
     private static final DecimalFormat ONE_DECIMAL_PLACE = new DecimalFormat(
             Main.pref.get("statusbar.decimal-format", "0.0")); // change of preference requires restart
+    private static final DecimalFormat TWO_DECIMAL_PLACES = new DecimalFormat("0.00");
     private static final double DISTANCE_THRESHOLD = Main.pref.getDouble("statusbar.distance-threshold", 0.01);
 
     /**
@@ -1038,7 +1039,8 @@
      */
     public void setDist(double dist) {
         distValue = dist;
-        distText.setText(dist < 0 ? "--" : NavigatableComponent.getDistText(dist, ONE_DECIMAL_PLACE, DISTANCE_THRESHOLD));
+        distText.setText(dist < 0 ? "--" : NavigatableComponent.getDistText(dist, dist < 100
+                ? TWO_DECIMAL_PLACES : ONE_DECIMAL_PLACE, DISTANCE_THRESHOLD));
     }
 
     /**
Index: src/org/openstreetmap/josm/gui/dialogs/InspectPrimitiveDialog.java
===================================================================
--- src/org/openstreetmap/josm/gui/dialogs/InspectPrimitiveDialog.java	(revision 9607)
+++ src/org/openstreetmap/josm/gui/dialogs/InspectPrimitiveDialog.java	(working copy)
@@ -38,7 +38,6 @@
 import org.openstreetmap.josm.gui.NavigatableComponent;
 import org.openstreetmap.josm.gui.layer.OsmDataLayer;
 import org.openstreetmap.josm.gui.mappaint.Cascade;
-import org.openstreetmap.josm.gui.mappaint.styleelement.StyleElement;
 import org.openstreetmap.josm.gui.mappaint.ElemStyles;
 import org.openstreetmap.josm.gui.mappaint.MapPaintStyles;
 import org.openstreetmap.josm.gui.mappaint.MultiCascade;
@@ -46,6 +45,7 @@
 import org.openstreetmap.josm.gui.mappaint.StyleElementList;
 import org.openstreetmap.josm.gui.mappaint.StyleSource;
 import org.openstreetmap.josm.gui.mappaint.mapcss.MapCSSStyleSource;
+import org.openstreetmap.josm.gui.mappaint.styleelement.StyleElement;
 import org.openstreetmap.josm.gui.mappaint.xml.XmlStyleSource;
 import org.openstreetmap.josm.gui.util.GuiHelper;
 import org.openstreetmap.josm.gui.widgets.JosmTextArea;
@@ -274,11 +274,16 @@
         }
 
         void addWayNodes(Way w) {
+            Node last = null;
             add(tr("{0} Nodes: ", w.getNodesCount()));
             for (Node n : w.getNodes()) {
+                if (last!=null) {
+                    s.append(n.getCoor().getDistanceSummary(last.getCoor()));
+                }
                 s.append(INDENT).append(INDENT);
                 addNameAndId(n);
                 s.append(NL);
+                last = n;
             }
         }
 
