Index: trunk/src/org/openstreetmap/josm/data/coor/ILatLon.java
===================================================================
--- trunk/src/org/openstreetmap/josm/data/coor/ILatLon.java	(revision 12164)
+++ trunk/src/org/openstreetmap/josm/data/coor/ILatLon.java	(revision 12164)
@@ -0,0 +1,66 @@
+// License: GPL. For details, see LICENSE file.
+package org.openstreetmap.josm.data.coor;
+
+import org.openstreetmap.josm.Main;
+import org.openstreetmap.josm.data.projection.Projecting;
+
+/**
+ * This interface represents a coordinate in LatLon space.
+ * <p>
+ * It provides methods to get the coordinates. The coordinates may be unknown.
+ * In this case, both {@link #lat()} and {@link #lon()} need to return a NaN value and {@link #isLatLonKnown()} needs to return false.
+ * <p>
+ * Whether the coordinates are immutable or not is implementation specific.
+ *
+ * @author Michael Zangl
+ * @since 12161
+ */
+public interface ILatLon {
+
+    /**
+     * Returns the longitude, i.e., the east-west position in degrees.
+     * @return the longitude or NaN if {@link #isLatLonKnown()} returns false
+     */
+    public double lon();
+
+    /**
+     * Returns the latitude, i.e., the north-south position in degrees.
+     * @return the latitude or NaN if {@link #isLatLonKnown()} returns false
+     */
+    public double lat();
+
+    /**
+     * Determines if this object has valid coordinates.
+     * @return {@code true} if this object has valid coordinates
+     */
+    default boolean isLatLonKnown() {
+        return !Double.isNaN(lat()) && !Double.isNaN(lon());
+    }
+
+    /**
+     * <p>Replies the projected east/north coordinates.</p>
+     *
+     * <p>Uses the {@link Main#getProjection() global projection} to project the lan/lon-coordinates.</p>
+     *
+     * @return the east north coordinates or {@code null} if #is
+     */
+    default EastNorth getEastNorth() {
+        return getEastNorth(Main.getProjection());
+    }
+
+    /**
+     * Replies the projected east/north coordinates.
+     * <p>
+     * The result of the last conversion may be cached. Null is returned in case this object is invalid.
+     * @param projecting The projection to use.
+     * @return The projected east/north coordinates
+     * @since 10827
+     */
+    default EastNorth getEastNorth(Projecting projecting) {
+        if (!isLatLonKnown()) {
+            return null;
+        } else {
+            return projecting.latlon2eastNorth(this);
+        }
+    }
+}
Index: trunk/src/org/openstreetmap/josm/data/gpx/GpxData.java
===================================================================
--- trunk/src/org/openstreetmap/josm/data/gpx/GpxData.java	(revision 12163)
+++ trunk/src/org/openstreetmap/josm/data/gpx/GpxData.java	(revision 12164)
@@ -40,7 +40,7 @@
     public String creator;
 
-    private ArrayList<GpxTrack> privateTracks = new ArrayList<>();
-    private ArrayList<GpxRoute> privateRoutes = new ArrayList<>();
-    private ArrayList<WayPoint> privateWaypoints = new ArrayList<>();
+    private final ArrayList<GpxTrack> privateTracks = new ArrayList<>();
+    private final ArrayList<GpxRoute> privateRoutes = new ArrayList<>();
+    private final ArrayList<WayPoint> privateWaypoints = new ArrayList<>();
     private final GpxTrackChangeListener proxy = e -> fireInvalidate();
 
@@ -580,8 +580,8 @@
         final int prime = 31;
         int result = 1;
-        result = prime * result + ((dataSources == null) ? 0 : dataSources.hashCode());
-        result = prime * result + ((routes == null) ? 0 : routes.hashCode());
-        result = prime * result + ((tracks == null) ? 0 : tracks.hashCode());
-        result = prime * result + ((waypoints == null) ? 0 : waypoints.hashCode());
+        result = prime * result + dataSources.hashCode();
+        result = prime * result + privateRoutes.hashCode();
+        result = prime * result + privateTracks.hashCode();
+        result = prime * result + privateWaypoints.hashCode();
         return result;
     }
@@ -601,18 +601,18 @@
         } else if (!dataSources.equals(other.dataSources))
             return false;
-        if (routes == null) {
-            if (other.routes != null)
+        if (privateRoutes == null) {
+            if (other.privateRoutes != null)
                 return false;
-        } else if (!routes.equals(other.routes))
+        } else if (!privateRoutes.equals(other.privateRoutes))
             return false;
-        if (tracks == null) {
-            if (other.tracks != null)
+        if (privateTracks == null) {
+            if (other.privateTracks != null)
                 return false;
-        } else if (!tracks.equals(other.tracks))
+        } else if (!privateTracks.equals(other.privateTracks))
             return false;
-        if (waypoints == null) {
-            if (other.waypoints != null)
+        if (privateWaypoints == null) {
+            if (other.privateWaypoints != null)
                 return false;
-        } else if (!waypoints.equals(other.waypoints))
+        } else if (!privateWaypoints.equals(other.privateWaypoints))
             return false;
         return true;
