Index: /trunk/src/org/openstreetmap/josm/data/Bounds.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/data/Bounds.java	(revision 1723)
+++ /trunk/src/org/openstreetmap/josm/data/Bounds.java	(revision 1724)
@@ -27,4 +27,9 @@
     }
 
+    public Bounds(LatLon b) {
+        this.min = b;
+        this.max = b;
+    }
+
     @Override public String toString() {
         return "Bounds["+min.lat()+","+min.lon()+","+max.lat()+","+max.lon()+"]";
@@ -34,9 +39,7 @@
      * @return Center of the bounding box.
      */
-    public LatLon center() {
-        // FIXME: not sure whether this calculation is right; maybe there is some
-        // more complex calculation needed to get a center of a spherical
-        // dimension?
-        return new LatLon((min.lat()+max.lat())/2, (min.lon()+max.lon())/2);
+    public LatLon getCenter()
+    {
+        return min.getCenter(max);
     }
 
Index: /trunk/src/org/openstreetmap/josm/data/ProjectionBounds.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/data/ProjectionBounds.java	(revision 1723)
+++ /trunk/src/org/openstreetmap/josm/data/ProjectionBounds.java	(revision 1724)
@@ -25,4 +25,8 @@
         this.max = max;
     }
+    public ProjectionBounds(EastNorth p) {
+        this.min = p;
+        this.max = p;
+    }
     public ProjectionBounds(EastNorth center, double east, double north) {
         this.min = new EastNorth(center.east()-east/2.0, center.north()-north/2.0);
@@ -32,11 +36,15 @@
     {
         if (e.east() < min.east() || e.north() < min.north())
-            min = e;
-        else if (e.east() > max.east() || e.north() > max.north())
-            max = e;
+            min = new EastNorth(Math.min(e.east(), min.east()), Math.min(e.north(), min.north()));
+        if (e.east() > max.east() || e.north() > max.north())
+            max = new EastNorth(Math.max(e.east(), max.east()), Math.max(e.north(), max.north()));
     }
     public EastNorth getCenter()
     {
-        return  new EastNorth(min.east()/2+max.east()/2, min.north()/2+max.north()/2);
+        return min.getCenter(max);
+    }
+
+    @Override public String toString() {
+        return "ProjectionBounds["+min.east()+","+min.north()+","+max.east()+","+max.north()+"]";
     }
 }
Index: /trunk/src/org/openstreetmap/josm/data/coor/CachedLatLon.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/data/coor/CachedLatLon.java	(revision 1724)
+++ /trunk/src/org/openstreetmap/josm/data/coor/CachedLatLon.java	(revision 1724)
@@ -0,0 +1,43 @@
+// License: GPL. Copyright 2007 by Immanuel Scholz and others
+package org.openstreetmap.josm.data.coor;
+
+import org.openstreetmap.josm.Main;
+import org.openstreetmap.josm.data.projection.Projection;
+
+public class CachedLatLon extends LatLon {
+    private EastNorth eastNorth;
+    private Projection proj;
+
+    public CachedLatLon(double lat, double lon) {
+        super(lat, lon);
+    }
+
+    public CachedLatLon(LatLon coor) {
+        super(coor.lat(), coor.lon());
+        proj = null;
+    }
+
+    public final void setCoor(LatLon coor) {
+        setLocation(coor.lon(), coor.lat());
+        proj = null;
+    }
+
+    public final void setEastNorth(EastNorth eastNorth) {
+        proj = Main.proj;
+        eastNorth = eastNorth;
+        LatLon l = proj.eastNorth2latlon(eastNorth);
+        setLocation(l.lat(), l.lon());
+    }
+
+    public final EastNorth getEastNorth() {
+        if(proj != Main.proj)
+        {
+            proj = Main.proj;
+            eastNorth = proj.latlon2eastNorth(this);
+        }
+        return eastNorth;
+    }
+    @Override public String toString() {
+        return "CachedLatLon[lat="+lat()+",lon="+lon()+"]";
+    }
+}
Index: /trunk/src/org/openstreetmap/josm/data/coor/EastNorth.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/data/coor/EastNorth.java	(revision 1723)
+++ /trunk/src/org/openstreetmap/josm/data/coor/EastNorth.java	(revision 1724)
@@ -30,4 +30,8 @@
         return new EastNorth(this.x + proportion * (en2.x - this.x),
             this.y + proportion * (en2.y - this.y));
+    }
+
+    public EastNorth getCenter(EastNorth en2) {
+        return new EastNorth((this.x + en2.x)/2.0, (this.y + en2.y)/2.0);
     }
 
Index: /trunk/src/org/openstreetmap/josm/data/coor/LatLon.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/data/coor/LatLon.java	(revision 1723)
+++ /trunk/src/org/openstreetmap/josm/data/coor/LatLon.java	(revision 1724)
@@ -143,4 +143,13 @@
     }
 
+    public LatLon interpolate(LatLon ll2, double proportion) {
+        return new LatLon(this.x + proportion * (ll2.x - this.x),
+            this.y + proportion * (ll2.y - this.y));
+    }
+
+    public LatLon getCenter(LatLon ll2) {
+        return new LatLon((this.x + ll2.x)/2.0, (this.y + ll2.y)/2.0);
+    }
+
     @Override public String toString() {
         return "LatLon[lat="+lat()+",lon="+lon()+"]";
Index: /trunk/src/org/openstreetmap/josm/data/gpx/GpxData.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/data/gpx/GpxData.java	(revision 1723)
+++ /trunk/src/org/openstreetmap/josm/data/gpx/GpxData.java	(revision 1724)
@@ -84,7 +84,7 @@
         for (WayPoint wpt : waypoints) {
             if (bounds == null) {
-                bounds = new Bounds(wpt.latlon, wpt.latlon);
+                bounds = new Bounds(wpt.getCoor());
             } else {
-                bounds.extend(wpt.latlon);
+                bounds.extend(wpt.getCoor());
             }
         }
@@ -92,7 +92,7 @@
             for (WayPoint wpt : rte.routePoints) {
                 if (bounds == null) {
-                    bounds = new Bounds(wpt.latlon, wpt.latlon);
+                    bounds = new Bounds(wpt.getCoor());
                 } else {
-                    bounds.extend(wpt.latlon);
+                    bounds.extend(wpt.getCoor());
                 }
             }
@@ -102,7 +102,7 @@
                 for (WayPoint wpt : trkseg) {
                     if (bounds == null) {
-                        bounds = new Bounds(wpt.latlon, wpt.latlon);
+                        bounds = new Bounds(wpt.getCoor());
                     } else {
-                        bounds.extend(wpt.latlon);
+                        bounds.extend(wpt.getCoor());
                     }
                 }
@@ -123,5 +123,5 @@
                 for (WayPoint tpt : trkseg) {
                     if(last != null){
-                        result += calcDistance(last.latlon, tpt.latlon);
+                        result += last.getCoor().greatCircleDistance(tpt.getCoor());
                     }
                     last = tpt;
@@ -132,24 +132,3 @@
         return result;
     }
-
-    /**
-     * returns the distance in meters between two LatLons
-     */
-    public static double calcDistance(LatLon p1, LatLon p2){
-        double lat1, lon1, lat2, lon2;
-        double dlon, dlat;
-
-        lat1 = p1.lat() * Math.PI / 180.0;
-        lon1 = p1.lon() * Math.PI / 180.0;
-        lat2 = p2.lat() * Math.PI / 180.0;
-        lon2 = p2.lon() * Math.PI / 180.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;
-    }
-
 }
Index: /trunk/src/org/openstreetmap/josm/data/gpx/WayPoint.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/data/gpx/WayPoint.java	(revision 1723)
+++ /trunk/src/org/openstreetmap/josm/data/gpx/WayPoint.java	(revision 1724)
@@ -4,18 +4,16 @@
 package org.openstreetmap.josm.data.gpx;
 
-import java.text.ParsePosition;
-import java.text.SimpleDateFormat;
 import java.util.Date;
-import java.util.regex.Pattern;
 import java.awt.Color;
 
 import org.openstreetmap.josm.Main;
+import org.openstreetmap.josm.data.coor.CachedLatLon;
 import org.openstreetmap.josm.data.coor.EastNorth;
 import org.openstreetmap.josm.data.coor.LatLon;
+import org.openstreetmap.josm.data.projection.Projection;
+import org.openstreetmap.josm.tools.DateUtils;
 
 public class WayPoint extends WithAttributes implements Comparable<WayPoint>
 {
-    public final LatLon latlon;
-    public final EastNorth eastNorth;
     public double time;
     public Color customColoring;
@@ -23,12 +21,21 @@
     public int dir;
 
+    private CachedLatLon coor;
+
+    public final LatLon getCoor() {
+        return coor;
+    }
+
+    public final EastNorth getEastNorth() {
+        return coor.getEastNorth();
+    }
+
     public WayPoint(LatLon ll) {
-        latlon = ll;
-        eastNorth = Main.proj.latlon2eastNorth(ll);
+        coor = new CachedLatLon(ll);
     }
 
     @Override
     public String toString() {
-        return "WayPoint (" + (attr.containsKey("name") ? attr.get("name") + ", " :"") + latlon.toString() + ", " + attr + ")";
+        return "WayPoint (" + (attr.containsKey("name") ? attr.get("name") + ", " :"") + coor.toString() + ", " + attr + ")";
     }
 
@@ -36,68 +43,16 @@
      * Convert the time stamp of the waypoint into seconds from the epoch
      */
-    public final static SimpleDateFormat GPXTIMEFMT =
-        new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS");
-    public final static SimpleDateFormat GPXTIMEFMT_nofrac =
-        new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss");
-    public final static SimpleDateFormat GPXTIMEFMT_tz =
-        new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZ");
-    public final static SimpleDateFormat GPXTIMEFMT_tz_nofrac =
-        new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ");
-
-	private final static Pattern colontz = Pattern.compile(".*[+-][0-9][0-9]:[0-9][0-9]\\z"); 
-	private final static Pattern colontzreplacement = Pattern.compile("([+-][0-9][0-9]):([0-9][0-9])\\z"); 
-
-	public void setTime() {
-        if (! attr.containsKey("time")) {
-            return;
-        }
-        String timestring = attr.get("time").toString();
-        
-        /* make the string timzeone be conanonical - unfortunately the allowed timezone in a 
-         * GPX is Z or +/-hh:mm whereas in simpledateformat it is +/-hhmm only (no colon) 
-         * If no timezone is given, the time will be interpreted as local time by parse. */
-        if (timestring.substring(timestring.length() - 1).equals("Z")) { 
-        	timestring = timestring.substring(0, timestring.length() - 1) + "+0000";
-        } else if (colontz.matcher(timestring).matches()) {
-        	timestring = colontzreplacement.matcher(timestring).replaceFirst("$1$2");
-        }
-        Date d = GPXTIMEFMT_tz.parse(timestring, new ParsePosition(0));
-        if (d == null) {
-        	d = GPXTIMEFMT_tz_nofrac.parse(timestring, new ParsePosition(0));
-        	if (d == null) {
-        		/* try without a zimezone indication */
-        		d = GPXTIMEFMT.parse(timestring, new ParsePosition(0));            	
-        		if (d == null) {
-        			d = GPXTIMEFMT_nofrac.parse(timestring, new ParsePosition(0));            	
-        		}
-               	// date has parsed in local time, and been adjusted to UTC by parse
+    public void setTime() {
+        for(String key : new String[]{"time", "cmt", "desc"})
+        {
+            if(attr.containsKey("time"))
+            {
+                double t = DateUtils.fromString(attr.get("time").toString()).getTime();
+                if(t != 0.0)
+                {
+                    time = t / 1000.0; /* ms => seconds */
+                    break;
+                }
             }
-        }
-        if (d != null /* parsing ok */) {
-            time = d.getTime() / 1000.0; /* ms => seconds */
-        }
-}
-    /**
-     * Convert a time stamp of the waypoint from the <cmt> or <desc> field
-     * into seconds from the epoch. Handles the date format as it is used by
-     * Garmin handhelds. Does not overwrite an existing timestamp (!= 0.0).
-     * A value of <time> fields overwrites values set with by method.
-     * Does nothing if specified key does not exist or text cannot be parsed.
-     *
-     * @param key The key that contains the text to convert.
-     */
-    public void setGarminCommentTime(String key) {
-        // do not overwrite time if already set
-        if (time != 0.0) {
-            return;
-        }
-        if (! attr.containsKey(key)) {
-            return;
-        }
-        // example date format "18-AUG-08 13:33:03"
-        SimpleDateFormat f = new SimpleDateFormat("dd-MMM-yy HH:mm:ss"); // Garmin wpts have no timezone
-        Date d = f.parse(attr.get(key).toString(), new ParsePosition(0));
-        if (d != null /* parsing OK */) {
-            time = d.getTime() / 1000.0; /* ms => seconds */
         }
     }
Index: /trunk/src/org/openstreetmap/josm/data/osm/Node.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/data/osm/Node.java	(revision 1723)
+++ /trunk/src/org/openstreetmap/josm/data/osm/Node.java	(revision 1724)
@@ -6,4 +6,5 @@
 import org.openstreetmap.josm.Main;
 import org.openstreetmap.josm.data.coor.EastNorth;
+import org.openstreetmap.josm.data.coor.CachedLatLon;
 import org.openstreetmap.josm.data.coor.LatLon;
 import org.openstreetmap.josm.data.coor.LatLon.CoordinateFormat;
@@ -11,5 +12,4 @@
 import org.openstreetmap.josm.data.osm.visitor.Visitor;
 import org.openstreetmap.josm.data.osm.Node;
-
 
 /**
@@ -20,13 +20,11 @@
 public final class Node extends OsmPrimitive {
 
-    private LatLon coor;
-
-    private EastNorth eastNorth;
-    private Projection proj;
-
+    private CachedLatLon coor;
 
     public final void setCoor(LatLon coor) {
-        this.coor = coor;
-        proj = null;
+        if(this.coor == null)
+            this.coor = new CachedLatLon(coor);
+        else
+            this.coor.setCoor(coor);
     }
 
@@ -36,16 +34,9 @@
 
     public final void setEastNorth(EastNorth eastNorth) {
-        proj = Main.proj;
-        eastNorth = eastNorth;
-        this.coor = proj.eastNorth2latlon(eastNorth);
+        coor.setEastNorth(eastNorth);
     }
 
     public final EastNorth getEastNorth() {
-        if(proj != Main.proj)
-        {
-            proj = Main.proj;
-            eastNorth = proj.latlon2eastNorth(coor);
-        }
-        return eastNorth;
+        return coor.getEastNorth();
     }
 
Index: /trunk/src/org/openstreetmap/josm/data/osm/visitor/BoundingXYVisitor.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/data/osm/visitor/BoundingXYVisitor.java	(revision 1723)
+++ /trunk/src/org/openstreetmap/josm/data/osm/visitor/BoundingXYVisitor.java	(revision 1724)
@@ -6,4 +6,5 @@
 import org.openstreetmap.josm.data.ProjectionBounds;
 import org.openstreetmap.josm.data.coor.EastNorth;
+import org.openstreetmap.josm.data.coor.CachedLatLon;
 import org.openstreetmap.josm.data.coor.LatLon;
 import org.openstreetmap.josm.data.osm.Node;
@@ -42,6 +43,6 @@
         if(b != null)
         {
-            visit(Main.proj.latlon2eastNorth(b.min));
-            visit(Main.proj.latlon2eastNorth(b.max));
+            visit(b.min);
+            visit(b.max);
         }
     }
@@ -49,5 +50,18 @@
     public void visit(ProjectionBounds b) {
         if(b != null)
-            bounds = new ProjectionBounds(b.min, b.max);
+        {
+            visit(b.min);
+            visit(b.max);
+        }
+    }
+
+    public void visit(LatLon latlon) {
+        if(latlon != null)
+        {
+            if(latlon instanceof CachedLatLon)
+                visit(((CachedLatLon)latlon).getEastNorth());
+            else
+                visit(Main.proj.latlon2eastNorth(latlon));
+        }
     }
 
@@ -55,5 +69,5 @@
         if (eastNorth != null) {
             if (bounds == null)
-                bounds = new ProjectionBounds(eastNorth, eastNorth);
+                bounds = new ProjectionBounds(eastNorth);
             else
                 bounds.extend(eastNorth);
@@ -98,3 +112,7 @@
         Main.proj.latlon2eastNorth(new LatLon(maxLatlon.lat() + enlargeDegree, maxLatlon.lon() + enlargeDegree)));
     }
+
+    @Override public String toString() {
+        return "BoundingXYVisitor["+bounds+"]";
+    }
 }
Index: /trunk/src/org/openstreetmap/josm/data/projection/Epsg4326.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/data/projection/Epsg4326.java	(revision 1723)
+++ /trunk/src/org/openstreetmap/josm/data/projection/Epsg4326.java	(revision 1724)
@@ -25,5 +25,5 @@
 
     @Override public String toString() {
-        return tr("EPSG:4326");
+        return tr("WGS84 Geographisch");
     }
 
@@ -34,8 +34,4 @@
     public String getCacheDirectoryName() {
         return "epsg4326";
-    }
-
-    @Override public boolean equals(Object o) {
-        return o instanceof Epsg4326;
     }
 
Index: /trunk/src/org/openstreetmap/josm/data/projection/Lambert.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/data/projection/Lambert.java	(revision 1723)
+++ /trunk/src/org/openstreetmap/josm/data/projection/Lambert.java	(revision 1724)
@@ -158,9 +158,4 @@
     }
 
-    @Override
-    public boolean equals(Object o) {
-        return o instanceof Lambert;
-    }
-
     /**
      * Initializes from geographic coordinates. Note that reference ellipsoid
Index: /trunk/src/org/openstreetmap/josm/data/projection/LambertEST.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/data/projection/LambertEST.java	(revision 1723)
+++ /trunk/src/org/openstreetmap/josm/data/projection/LambertEST.java	(revision 1724)
@@ -107,9 +107,4 @@
     }
 
-    @Override
-    public boolean equals(Object o) {
-        return o instanceof LambertEST;
-    }
-
     public ProjectionBounds getWorldBounds()
     {
Index: /trunk/src/org/openstreetmap/josm/data/projection/Mercator.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/data/projection/Mercator.java	(revision 1723)
+++ /trunk/src/org/openstreetmap/josm/data/projection/Mercator.java	(revision 1724)
@@ -47,8 +47,4 @@
     }
 
-    @Override public boolean equals(Object o) {
-        return o instanceof Mercator;
-    }
-
     public ProjectionBounds getWorldBounds()
     {
Index: /trunk/src/org/openstreetmap/josm/data/projection/SwissGrid.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/data/projection/SwissGrid.java	(revision 1723)
+++ /trunk/src/org/openstreetmap/josm/data/projection/SwissGrid.java	(revision 1724)
@@ -101,9 +101,4 @@
     }
 
-    @Override
-    public boolean equals(Object o) {
-        return o instanceof SwissGrid;
-    }
-
     public ProjectionBounds getWorldBounds()
     {
Index: /trunk/src/org/openstreetmap/josm/data/projection/UTM.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/data/projection/UTM.java	(revision 1723)
+++ /trunk/src/org/openstreetmap/josm/data/projection/UTM.java	(revision 1724)
@@ -345,8 +345,4 @@
     }
 
-    @Override public boolean equals(Object o) {
-        return o instanceof UTM;
-    }
-
     public ProjectionBounds getWorldBounds()
     {
Index: /trunk/src/org/openstreetmap/josm/gui/layer/GeoImageLayer.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/gui/layer/GeoImageLayer.java	(revision 1723)
+++ /trunk/src/org/openstreetmap/josm/gui/layer/GeoImageLayer.java	(revision 1724)
@@ -63,5 +63,5 @@
 import org.openstreetmap.josm.Main;
 import org.openstreetmap.josm.actions.RenameLayerAction;
-import org.openstreetmap.josm.data.coor.EastNorth;
+import org.openstreetmap.josm.data.coor.CachedLatLon;
 import org.openstreetmap.josm.data.coor.LatLon;
 import org.openstreetmap.josm.data.gpx.GpxTrack;
@@ -244,8 +244,6 @@
         final File image;
         ImageLoader.Entry icon;
-
         Date time;
-        LatLon coor;
-        EastNorth pos;
+        CachedLatLon pos;
 
         public ImageEntry(File image) {
@@ -290,13 +288,14 @@
                 for (Collection<WayPoint> segment : trk.trackSegs) {
                     for (WayPoint p : segment) {
+                        LatLon c = p.getCoor();
                         if (!p.attr.containsKey("time"))
-                            throw new IOException(tr("No time for point {0} x {1}",p.latlon.lat(),p.latlon.lon()));
+                            throw new IOException(tr("No time for point {0} x {1}",c.lat(),c.lon()));
                         Date d = null;
                         try {
                             d = DateParser.parse((String) p.attr.get("time"));
                         } catch (ParseException e) {
-                            throw new IOException(tr("Cannot read time \"{0}\" from point {1} x {2}",p.attr.get("time"),p.latlon.lat(),p.latlon.lon()));
+                            throw new IOException(tr("Cannot read time \"{0}\" from point {1} x {2}",p.attr.get("time"),c.lat(),c.lon()));
                         }
-                        gps.add(new TimedPoint(d, p.eastNorth));
+                        gps.add(new TimedPoint(d, c));
                     }
                 }
@@ -364,8 +363,9 @@
     private static final class TimedPoint implements Comparable<TimedPoint> {
         Date time;
-        EastNorth pos;
-        public TimedPoint(Date time, EastNorth pos) {
+        CachedLatLon pos;
+
+        public TimedPoint(Date time, LatLon pos) {
             this.time = time;
-            this.pos = pos;
+            this.pos.setCoor(pos);
         }
         public int compareTo(TimedPoint point) {
@@ -404,5 +404,5 @@
                     if (e.pos == null)
                         continue;
-                    Point p = Main.map.mapView.getPoint(e.pos);
+                    Point p = Main.map.mapView.getPoint(e.pos.getEastNorth());
                     Rectangle r = new Rectangle(p.x-ICON_SIZE/2, p.y-ICON_SIZE/2, ICON_SIZE, ICON_SIZE);
                     if (r.contains(ev.getPoint())) {
@@ -536,8 +536,8 @@
 
             if (centerToggle.getModel().isSelected())
-                Main.map.mapView.zoomTo(currentImageEntry.pos);
+                Main.map.mapView.zoomTo(currentImageEntry.pos.getEastNorth());
 
             dlg.setTitle(currentImageEntry.image +
-                    " (" + currentImageEntry.coor.toDisplayString() + ")");
+                    " (" + currentImageEntry.pos.toDisplayString() + ")");
             dlg.setCursor(Cursor.getDefaultCursor());
         }
@@ -612,5 +612,5 @@
                 }
 
-                Point p = mv.getPoint(e.pos);
+                Point p = mv.getPoint(e.pos.getEastNorth());
                 Rectangle r = new Rectangle(p.x-ICON_SIZE / 2, p.y-ICON_SIZE / 2, ICON_SIZE, ICON_SIZE);
                 if (r.contains(mousePosition)) {
@@ -624,5 +624,5 @@
             ImageEntry e = data.get(i);
             if (e.pos != null) {
-                Point p = mv.getPoint(e.pos);
+                Point p = mv.getPoint(e.pos.getEastNorth());
                 Rectangle r = new Rectangle(p.x-ICON_SIZE / 2, p.y-ICON_SIZE / 2, ICON_SIZE, ICON_SIZE);
                 g.drawImage(e.getIcon(), r.x, r.y, null);
@@ -686,7 +686,5 @@
                 Date time = new Date(tp.time.getTime() - (delta+gpstimezone));
                 if (time.after(e.time) && lastTP != null) {
-                    double x = (lastTP.pos.east()+tp.pos.east())/2;
-                    double y = (lastTP.pos.north()+tp.pos.north())/2;
-                    e.pos = new EastNorth(x,y);
+                    e.pos.setCoor(lastTP.pos.getCenter(tp.pos));
                     break;
                 }
@@ -696,5 +694,4 @@
                 e.pos = gps.getLast().pos;
             }
-            e.coor = Main.proj.eastNorth2latlon(e.pos);
         }
     }
Index: /trunk/src/org/openstreetmap/josm/gui/layer/GpxLayer.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/gui/layer/GpxLayer.java	(revision 1723)
+++ /trunk/src/org/openstreetmap/josm/gui/layer/GpxLayer.java	(revision 1724)
@@ -459,10 +459,11 @@
                 for (Collection<WayPoint> segment : trk.trackSegs) {
                     for (WayPoint trkPnt : segment) {
-                        if (Double.isNaN(trkPnt.latlon.lat()) || Double.isNaN(trkPnt.latlon.lon())) {
+                        LatLon c = trkPnt.getCoor();
+                        if (Double.isNaN(c.lat()) || Double.isNaN(c.lon())) {
                             continue;
                         }
                         trkPnt.customColoring = neutralColor;
                         if (oldWp != null) {
-                            double dist = trkPnt.latlon.greatCircleDistance(oldWp.latlon);
+                            double dist = c.greatCircleDistance(oldWp.getCoor());
 
                             switch(colored) {
@@ -495,5 +496,5 @@
                             if (maxLineLength == -1 || dist <= maxLineLength) {
                                 trkPnt.drawLine = true;
-                                trkPnt.dir = (int)(Math.atan2(-trkPnt.eastNorth.north()+oldWp.eastNorth.north(), trkPnt.eastNorth.east()-oldWp.eastNorth.east()) / Math.PI * 4 + 3.5); // crude but works
+                                trkPnt.dir = (int)oldWp.getCoor().heading(trkPnt.getCoor());
                             } else {
                                 trkPnt.drawLine = false;
@@ -517,7 +518,8 @@
             for (Collection<WayPoint> segment : trk.trackSegs) {
                 for (WayPoint trkPnt : segment) {
-                    if (Double.isNaN(trkPnt.latlon.lat()) || Double.isNaN(trkPnt.latlon.lon()))
+                    LatLon c = trkPnt.getCoor();
+                    if (Double.isNaN(c.lat()) || Double.isNaN(c.lon()))
                         continue;
-                    Point screen = mv.getPoint(trkPnt.eastNorth);
+                    Point screen = mv.getPoint(trkPnt.getEastNorth());
                         if (trkPnt.drawLine) {
                             // skip points that are on the same screenposition
@@ -542,8 +544,9 @@
                 for (Collection<WayPoint> segment : trk.trackSegs) {
                     for (WayPoint trkPnt : segment) {
-                        if (Double.isNaN(trkPnt.latlon.lat()) || Double.isNaN(trkPnt.latlon.lon()))
+                        LatLon c = trkPnt.getCoor();
+                        if (Double.isNaN(c.lat()) || Double.isNaN(c.lon()))
                             continue;
                         if (trkPnt.drawLine) {
-                            Point screen = mv.getPoint(trkPnt.eastNorth);
+                            Point screen = mv.getPoint(trkPnt.getEastNorth());
                             // skip points that are on the same screenposition
                             if (old != null && (oldA == null || screen.x < oldA.x-delta || screen.x > oldA.x+delta || screen.y < oldA.y-delta || screen.y > oldA.y+delta)) {
@@ -572,8 +575,9 @@
                 for (Collection<WayPoint> segment : trk.trackSegs) {
                     for (WayPoint trkPnt : segment) {
-                        if (Double.isNaN(trkPnt.latlon.lat()) || Double.isNaN(trkPnt.latlon.lon()))
+                        LatLon c = trkPnt.getCoor();
+                        if (Double.isNaN(c.lat()) || Double.isNaN(c.lon()))
                             continue;
                         if (trkPnt.drawLine) {
-                            Point screen = mv.getPoint(trkPnt.eastNorth);
+                            Point screen = mv.getPoint(trkPnt.getEastNorth());
                             // skip points that are on the same screenposition
                             if (old != null && (oldA == null || screen.x < oldA.x-delta || screen.x > oldA.x+delta || screen.y < oldA.y-delta || screen.y > oldA.y+delta)) {
@@ -598,7 +602,8 @@
                 for (Collection<WayPoint> segment : trk.trackSegs) {
                     for (WayPoint trkPnt : segment) {
-                        if (Double.isNaN(trkPnt.latlon.lat()) || Double.isNaN(trkPnt.latlon.lon()))
+                        LatLon c = trkPnt.getCoor();
+                        if (Double.isNaN(c.lat()) || Double.isNaN(c.lon()))
                             continue;
-                        Point screen = mv.getPoint(trkPnt.eastNorth);
+                        Point screen = mv.getPoint(trkPnt.getEastNorth());
                         g.setColor(trkPnt.customColoring);
                         g.fillRect(screen.x-1, screen.y-1, 3, 3);
@@ -616,8 +621,9 @@
                 for (Collection<WayPoint> segment : trk.trackSegs) {
                     for (WayPoint trkPnt : segment) {
-                        if (Double.isNaN(trkPnt.latlon.lat()) || Double.isNaN(trkPnt.latlon.lon()))
+                        LatLon c = trkPnt.getCoor();
+                        if (Double.isNaN(c.lat()) || Double.isNaN(c.lon()))
                             continue;
                         if (!trkPnt.drawLine) {
-                            Point screen = mv.getPoint(trkPnt.eastNorth);
+                            Point screen = mv.getPoint(trkPnt.getEastNorth());
                         g.drawRect(screen.x, screen.y, 0, 0);
                     }
@@ -635,7 +641,8 @@
                 for (Collection<WayPoint> segment : trk.trackSegs) {
                     for (WayPoint trkPnt : segment) {
-                        if (Double.isNaN(trkPnt.latlon.lat()) || Double.isNaN(trkPnt.latlon.lon()))
+                        LatLon c = trkPnt.getCoor();
+                        if (Double.isNaN(c.lat()) || Double.isNaN(c.lon()))
                             continue;
-                        Point screen = mv.getPoint(trkPnt.eastNorth);
+                        Point screen = mv.getPoint(trkPnt.getEastNorth());
                         g.setColor(trkPnt.customColoring);
                         g.drawRect(screen.x, screen.y, 0, 0);
@@ -650,21 +657,5 @@
 
     @Override public void visitBoundingBox(BoundingXYVisitor v) {
-        for (WayPoint p : data.waypoints)
-            v.visit(p.eastNorth);
-
-        for (GpxRoute rte : data.routes) {
-            Collection<WayPoint> r = rte.routePoints;
-            for (WayPoint p : r) {
-                v.visit(p.eastNorth);
-            }
-        }
-
-        for (GpxTrack trk : data.tracks) {
-            for (Collection<WayPoint> seg : trk.trackSegs) {
-                for (WayPoint p : seg) {
-                    v.visit(p.eastNorth);
-                }
-            }
-        }
+        v.visit(data.recalculateBounds());
     }
 
@@ -684,5 +675,5 @@
                     Way w = new Way();
                     for (WayPoint p : segment) {
-                        Node n = new Node(p.latlon);
+                        Node n = new Node(p.getCoor());
                         String timestr = p.getString("time");
                         if(timestr != null)
@@ -748,5 +739,5 @@
                 for (Collection<WayPoint> segment : trk.trackSegs) {
                     for (WayPoint p : segment) {
-                        latsum += p.latlon.lat();
+                        latsum += p.getCoor().lat();
                         latcnt ++;
                     }
@@ -782,9 +773,10 @@
                 for (Collection<WayPoint> segment : trk.trackSegs) {
                     for (WayPoint p : segment) {
-                        if (previous == null || p.latlon.greatCircleDistance(previous) > buffer_dist) {
+                        LatLon c = p.getCoor();
+                        if (previous == null || c.greatCircleDistance(previous) > buffer_dist) {
                             // we add a buffer around the point.
-                            r.setRect(p.latlon.lon()-buffer_x, p.latlon.lat()-buffer_y, 2*buffer_x, 2*buffer_y);
+                            r.setRect(c.lon()-buffer_x, c.lat()-buffer_y, 2*buffer_x, 2*buffer_y);
                             a.add(new Area(r));
-                            previous = p.latlon;
+                            previous = c;
                         }
                     }
@@ -917,7 +909,7 @@
             for (WayPoint w : data.waypoints) {
                 if (waypoints.contains(w)) { continue; }
-                WayPoint wNear = nearestPointOnTrack(w.eastNorth, snapDistance);
+                WayPoint wNear = nearestPointOnTrack(w.getEastNorth(), snapDistance);
                 if (wNear != null) {
-                    WayPoint wc = new WayPoint(w.latlon);
+                    WayPoint wc = new WayPoint(w.getCoor());
                     wc.time = wNear.time;
                     if (w.attr.containsKey("name")) wc.attr.put("name", w.getString("name"));
@@ -974,8 +966,6 @@
                 timedMarkersOmitted = true;
             } else {
-                EastNorth eastNorth = w1.eastNorth.interpolate(
-                            w2.eastNorth,
-                            (startTime - w1.time)/(w2.time - w1.time));
-                wayPointFromTimeStamp = new WayPoint(Main.proj.eastNorth2latlon(eastNorth));
+                wayPointFromTimeStamp = new WayPoint(w1.getCoor().interpolate(
+                    w2.getCoor(), (startTime - w1.time)/(w2.time - w1.time)));
                 wayPointFromTimeStamp.time = startTime;
                 String name = wavFile.getName();
@@ -998,5 +988,5 @@
                 for (Collection<WayPoint> seg : track.trackSegs) {
                     for (WayPoint w : seg) {
-                        WayPoint wStart = new WayPoint(w.latlon);
+                        WayPoint wStart = new WayPoint(w.getCoor());
                         wStart.attr.put("name", "start");
                         wStart.time = w.time;
@@ -1030,5 +1020,5 @@
             else
                 name = AudioMarker.inventName(offset);
-            AudioMarker am = AudioMarker.create(w.latlon,
+            AudioMarker am = AudioMarker.create(w.getCoor(),
                     name, uri, ml, w.time, offset);
             /* timeFromAudio intended for future use to shift markers of this type on synchronization */
@@ -1104,7 +1094,8 @@
                 for (WayPoint S : seg) {
                     if (R == null) {
+                        EastNorth c = R.getEastNorth();
                         R = S;
-                        rx = R.eastNorth.east();
-                        ry = R.eastNorth.north();
+                        rx = c.east();
+                        ry = c.north();
                         x = px - rx;
                         y = py - ry;
@@ -1112,10 +1103,11 @@
                         if (PRsq < PNminsq) {
                             PNminsq = PRsq;
-                            bestEN = R.eastNorth;
+                            bestEN = c;
                             bestTime = R.time;
                         }
                     } else {
-                        sx = S.eastNorth.east();
-                        sy = S.eastNorth.north();
+                        EastNorth c = S.getEastNorth();
+                        sx = c.east();
+                        sy = c.north();
                         double A = sy - ry;
                         double B = rx - sx;
@@ -1147,7 +1139,8 @@
                 }
                 if (R != null) {
+                    EastNorth c = R.getEastNorth();
                     /* if there is only one point in the seg, it will do this twice, but no matter */
-                    rx = R.eastNorth.east();
-                    ry = R.eastNorth.north();
+                    rx = c.east();
+                    ry = c.north();
                     x = px - rx;
                     y = py - ry;
@@ -1155,5 +1148,5 @@
                     if (PRsq < PNminsq) {
                         PNminsq = PRsq;
-                        bestEN = R.eastNorth;
+                        bestEN = c;
                         bestTime = R.time;
                     }
Index: /trunk/src/org/openstreetmap/josm/gui/layer/markerlayer/ButtonMarker.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/gui/layer/markerlayer/ButtonMarker.java	(revision 1723)
+++ /trunk/src/org/openstreetmap/josm/gui/layer/markerlayer/ButtonMarker.java	(revision 1724)
@@ -36,5 +36,5 @@
 
     @Override public boolean containsPoint(Point p) {
-        Point screen = Main.map.mapView.getPoint(eastNorth);
+        Point screen = Main.map.mapView.getPoint(getEastNorth());
         buttonRectangle.setLocation(screen.x+4, screen.y+2);
         return buttonRectangle.contains(p);
@@ -46,5 +46,5 @@
             return;
         }
-        Point screen = mv.getPoint(eastNorth);
+        Point screen = mv.getPoint(getEastNorth());
         buttonRectangle.setLocation(screen.x+4, screen.y+2);
         symbol.paintIcon(mv, g, screen.x+4, screen.y+2);
Index: /trunk/src/org/openstreetmap/josm/gui/layer/markerlayer/Marker.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/gui/layer/markerlayer/Marker.java	(revision 1723)
+++ /trunk/src/org/openstreetmap/josm/gui/layer/markerlayer/Marker.java	(revision 1724)
@@ -15,4 +15,5 @@
 
 import org.openstreetmap.josm.Main;
+import org.openstreetmap.josm.data.coor.CachedLatLon;
 import org.openstreetmap.josm.data.coor.EastNorth;
 import org.openstreetmap.josm.data.coor.LatLon;
@@ -59,12 +60,31 @@
  */
 public class Marker implements ActionListener {
-
-    public EastNorth eastNorth;
     public final String text;
     public final Icon symbol;
     public final MarkerLayer parentLayer;
-    public double time; /* avbsolute time of marker since epocj */
+    public double time; /* absolute time of marker since epoch */
     public double offset; /* time offset in seconds from the gpx point from which it was derived,
                              may be adjusted later to sync with other data, so not final */
+
+    private CachedLatLon coor;
+
+    public final void setCoor(LatLon coor) {
+        if(this.coor == null)
+            this.coor = new CachedLatLon(coor);
+        else
+            this.coor.setCoor(coor);
+    }
+
+    public final LatLon getCoor() {
+        return coor;
+    }
+
+    public final void setEastNorth(EastNorth eastNorth) {
+        coor.setEastNorth(eastNorth);
+    }
+
+    public final EastNorth getEastNorth() {
+        return coor.getEastNorth();
+    }
 
     /**
@@ -101,11 +121,11 @@
 
                 if (uri == null)
-                    return new Marker(wpt.latlon, name_desc, wpt.getString("symbol"), parentLayer, time, offset);
+                    return new Marker(wpt.getCoor(), name_desc, wpt.getString("symbol"), parentLayer, time, offset);
                 else if (uri.endsWith(".wav"))
-                    return AudioMarker.create(wpt.latlon, name_desc, uri, parentLayer, time, offset);
+                    return AudioMarker.create(wpt.getCoor(), name_desc, uri, parentLayer, time, offset);
                 else if (uri.endsWith(".png") || uri.endsWith(".jpg") || uri.endsWith(".jpeg") || uri.endsWith(".gif"))
-                    return ImageMarker.create(wpt.latlon, uri, parentLayer, time, offset);
+                    return ImageMarker.create(wpt.getCoor(), uri, parentLayer, time, offset);
                 else
-                    return WebMarker.create(wpt.latlon, uri, parentLayer, time, offset);
+                    return WebMarker.create(wpt.getCoor(), uri, parentLayer, time, offset);
             }
 
@@ -122,5 +142,5 @@
 
     public Marker(LatLon ll, String text, String iconName, MarkerLayer parentLayer, double time, double offset) {
-        eastNorth = Main.proj.latlon2eastNorth(ll);
+        setCoor(ll);
         this.text = text;
         this.offset = offset;
@@ -162,5 +182,5 @@
      */
     public void paint(Graphics g, MapView mv, boolean mousePressed, String show) {
-        Point screen = mv.getPoint(eastNorth);
+        Point screen = mv.getPoint(getEastNorth());
         if (symbol != null && show.equalsIgnoreCase("show")) {
             symbol.paintIcon(mv, g, screen.x-symbol.getIconWidth()/2, screen.y-symbol.getIconHeight()/2);
@@ -205,5 +225,5 @@
 
     public AudioMarker audioMarkerFromMarker(String uri) {
-        AudioMarker audioMarker = AudioMarker.create(Main.proj.eastNorth2latlon(this.eastNorth), this.text, uri, this.parentLayer, this.time, this.offset);
+        AudioMarker audioMarker = AudioMarker.create(getCoor(), this.text, uri, this.parentLayer, this.time, this.offset);
         return audioMarker;
     }
Index: /trunk/src/org/openstreetmap/josm/gui/layer/markerlayer/MarkerLayer.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/gui/layer/markerlayer/MarkerLayer.java	(revision 1723)
+++ /trunk/src/org/openstreetmap/josm/gui/layer/markerlayer/MarkerLayer.java	(revision 1724)
@@ -28,5 +28,5 @@
 import org.openstreetmap.josm.Main;
 import org.openstreetmap.josm.actions.RenameLayerAction;
-import org.openstreetmap.josm.data.coor.EastNorth;
+import org.openstreetmap.josm.data.coor.LatLon;
 import org.openstreetmap.josm.data.gpx.GpxData;
 import org.openstreetmap.josm.data.gpx.GpxLink;
@@ -184,5 +184,5 @@
     @Override public void visitBoundingBox(BoundingXYVisitor v) {
         for (Marker mkr : data)
-            v.visit(mkr.eastNorth);
+            v.visit(mkr.getEastNorth());
     }
 
@@ -242,5 +242,5 @@
                 if (playHeadMarker == null)
                     return;
-                addAudioMarker(playHeadMarker.time, playHeadMarker.eastNorth);
+                addAudioMarker(playHeadMarker.time, playHeadMarker.getCoor());
                 Main.map.mapView.repaint();
             }
@@ -296,5 +296,5 @@
     }
 
-    public AudioMarker addAudioMarker(double time, EastNorth en) {
+    public AudioMarker addAudioMarker(double time, LatLon coor) {
         // find first audio marker to get absolute start time
         double offset = 0.0;
@@ -313,5 +313,5 @@
 
         // make our new marker
-        AudioMarker newAudioMarker = AudioMarker.create(Main.proj.eastNorth2latlon(en),
+        AudioMarker newAudioMarker = AudioMarker.create(coor,
             AudioMarker.inventName(offset), AudioPlayer.url().toString(), this, time, offset);
 
Index: /trunk/src/org/openstreetmap/josm/gui/layer/markerlayer/PlayHeadMarker.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/gui/layer/markerlayer/PlayHeadMarker.java	(revision 1723)
+++ /trunk/src/org/openstreetmap/josm/gui/layer/markerlayer/PlayHeadMarker.java	(revision 1724)
@@ -43,5 +43,5 @@
     static private PlayHeadMarker playHead = null;
     private MapMode oldMode = null;
-    private EastNorth oldEastNorth;
+    private LatLon oldCoor;
     private boolean enabled;
     private boolean wasPlaying = false;
@@ -75,5 +75,5 @@
                      * getting confused with other drag operations (like select) */
                     oldMode = Main.map.mapMode;
-                    oldEastNorth = eastNorth;
+                    oldCoor = getCoor();
                     PlayHeadDragMode playHeadDragMode = new PlayHeadDragMode(playHead);
                     Main.map.selectMapMode(playHeadDragMode);
@@ -85,5 +85,5 @@
 
     @Override public boolean containsPoint(Point p) {
-        Point screen = Main.map.mapView.getPoint(eastNorth);
+        Point screen = Main.map.mapView.getPoint(getEastNorth());
         Rectangle r = new Rectangle(screen.x, screen.y, symbol.getIconWidth(),
         symbol.getIconHeight());
@@ -106,5 +106,5 @@
 
     /**
-     * reinstate the old map mode after swuitching temporarily to do a play head drag
+     * reinstate the old map mode after switching temporarily to do a play head drag
      */
     private void endDrag(boolean reset) {
@@ -113,5 +113,5 @@
             catch (Exception ex) { AudioPlayer.audioMalfunction(ex);}
         if (reset)
-            eastNorth = oldEastNorth;
+            setCoor(oldCoor);
         Main.map.selectMapMode(oldMode);
         Main.map.mapView.repaint();
@@ -124,5 +124,5 @@
      */
     public void drag(EastNorth en) {
-        eastNorth = en;
+        setEastNorth(en);
         Main.map.mapView.repaint();
     }
@@ -135,5 +135,4 @@
      */
     public void reposition(EastNorth en) {
-        // eastNorth = en;
         WayPoint cw = null;
         AudioMarker recent = AudioMarker.recentlyPlayedMarker();
@@ -167,5 +166,5 @@
             endDrag(true);
         } else {
-            eastNorth = cw.eastNorth;
+            setCoor(cw.getCoor());
             ca.play(cw.time - ca.time);
             endDrag(false);
@@ -193,5 +192,5 @@
             for (Marker m : recent.parentLayer.data) {
                 if (m instanceof AudioMarker) {
-                    double distanceSquared = m.eastNorth.distanceSq(en);
+                    double distanceSquared = m.getEastNorth().distanceSq(en);
                     if (distanceSquared < closestAudioMarkerDistanceSquared) {
                         ca = (AudioMarker) m;
@@ -216,5 +215,5 @@
                 return;
             }
-            ca = recent.parentLayer.addAudioMarker(cw.time, cw.eastNorth);
+            ca = recent.parentLayer.addAudioMarker(cw.time, cw.getCoor());
         }
 
@@ -227,5 +226,5 @@
         else if (recent.parentLayer.synchronizeAudioMarkers(ca)) {
             JOptionPane.showMessageDialog(Main.parent, tr("Audio synchronized at point {0}.", ca.text));
-            eastNorth = ca.eastNorth;
+            setCoor(ca.getCoor());
             endDrag(false);
         } else {
@@ -237,5 +236,5 @@
     public void paint(Graphics g, MapView mv /*, boolean mousePressed */) {
         if (time < 0.0) return;
-        Point screen = mv.getPoint(eastNorth);
+        Point screen = mv.getPoint(getEastNorth());
         symbol.paintIcon(mv, g, screen.x, screen.y);
     }
@@ -297,8 +296,8 @@
         if (w1 == null)
             return;
-        eastNorth = w2 == null ?
-            w1.eastNorth :
-            w1.eastNorth.interpolate(w2.eastNorth,
-                    (audioTime - w1.time)/(w2.time - w1.time));
+        setEastNorth(w2 == null ?
+            w1.getEastNorth() :
+            w1.getEastNorth().interpolate(w2.getEastNorth(),
+                    (audioTime - w1.time)/(w2.time - w1.time)));
         time = audioTime;
         Main.map.mapView.repaint();
Index: /trunk/src/org/openstreetmap/josm/io/GpxReader.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/io/GpxReader.java	(revision 1723)
+++ /trunk/src/org/openstreetmap/josm/io/GpxReader.java	(revision 1724)
@@ -262,5 +262,5 @@
                 } else if (qName.equals("cmt") || qName.equals("desc")) {
                     currentWayPoint.attr.put(qName, accumulator.toString());
-                    currentWayPoint.setGarminCommentTime(qName);
+                    currentWayPoint.setTime();
                 } else if (qName.equals("rtept")) {
                     currentState = states.pop();
Index: /trunk/src/org/openstreetmap/josm/io/GpxWriter.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/io/GpxWriter.java	(revision 1723)
+++ /trunk/src/org/openstreetmap/josm/io/GpxWriter.java	(revision 1724)
@@ -11,4 +11,5 @@
 
 import org.openstreetmap.josm.data.Bounds;
+import org.openstreetmap.josm.data.coor.LatLon;
 import org.openstreetmap.josm.data.gpx.GpxData;
 import org.openstreetmap.josm.data.gpx.GpxLink;
@@ -237,5 +238,6 @@
         }
         if (pnt != null) {
-            openAtt(type, "lat=\"" + pnt.latlon.lat() + "\" lon=\"" + pnt.latlon.lon() + "\"");
+            LatLon c =pnt.getCoor();
+            openAtt(type, "lat=\"" + c.lat() + "\" lon=\"" + c.lon() + "\"");
             writeAttr(pnt.attr);
             closeln(type);
Index: /trunk/src/org/openstreetmap/josm/io/NmeaReader.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/io/NmeaReader.java	(revision 1723)
+++ /trunk/src/org/openstreetmap/josm/io/NmeaReader.java	(revision 1724)
@@ -18,4 +18,5 @@
 import org.openstreetmap.josm.data.gpx.GpxTrack;
 import org.openstreetmap.josm.data.gpx.WayPoint;
+import org.openstreetmap.josm.tools.DateUtils;
 
 /**
@@ -285,6 +286,5 @@
                     // As this sentence has no complete time only use it
                     // if there is no time so far
-                    String gpxdate = WayPoint.GPXTIMEFMT.format(d);
-                    currentwp.attr.put("time", gpxdate);
+                    currentwp.attr.put("time", DateUtils.fromDate(d));
                 }
                 // elevation
@@ -390,6 +390,5 @@
                 }
                 // time: this sentence has complete time so always use it.
-                String gpxdate = WayPoint.GPXTIMEFMT.format(d);
-                currentwp.attr.put("time", gpxdate);
+                currentwp.attr.put("time", DateUtils.fromDate(d));
                 // speed
                 accu = e[GPRMC.SPEED.position];
Index: /trunk/src/org/openstreetmap/josm/tools/DateUtils.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/tools/DateUtils.java	(revision 1723)
+++ /trunk/src/org/openstreetmap/josm/tools/DateUtils.java	(revision 1724)
@@ -19,4 +19,6 @@
 package org.openstreetmap.josm.tools;
 
+import java.text.ParsePosition;
+import java.text.SimpleDateFormat;
 import java.util.Calendar;
 import java.util.Date;
@@ -61,4 +63,5 @@
         // "2007-07-25T09:26:24{Z|{+|-}01:00}"
         if (checkLayout(str, "xxxx-xx-xxTxx:xx:xxZ") ||
+                checkLayout(str, "xxxx-xx-xxTxx:xx:xx") ||
                 checkLayout(str, "xxxx-xx-xxTxx:xx:xx+xx:00") ||
                 checkLayout(str, "xxxx-xx-xxTxx:xx:xx-xx:00")) {
@@ -78,4 +81,30 @@
 
             return calendar.getTime();
+        }
+        else if(checkLayout(str, "xxxx-xx-xxTxx:xx:xx.xxxZ") ||
+                checkLayout(str, "xxxx-xx-xxTxx:xx:xx.xxx") ||
+                checkLayout(str, "xxxx-xx-xxTxx:xx:xx.xxx+xx:00") ||
+                checkLayout(str, "xxxx-xx-xxTxx:xx:xx.xxx-xx:00")) {
+            calendar.set(
+                parsePart(str, 0, 4),
+                parsePart(str, 5, 2)-1,
+                parsePart(str, 8, 2),
+                parsePart(str, 11, 2),
+                parsePart(str, 14,2),
+                parsePart(str, 17, 2));
+            long millis = parsePart(str, 20, 3);
+            if (str.length() == 29)
+                millis += parsePart(str, 24, 2) * (str.charAt(23) == '+' ? -3600000 : 3600000);
+            calendar.setTimeInMillis(calendar.getTimeInMillis()+millis);
+
+            return calendar.getTime();
+        }
+        else
+        {
+            // example date format "18-AUG-08 13:33:03"
+            SimpleDateFormat f = new SimpleDateFormat("dd-MMM-yy HH:mm:ss");
+            Date d = f.parse(str, new ParsePosition(0));
+            if(d != null)
+                return d;
         }
 
@@ -97,6 +126,8 @@
         if (text.length() != pattern.length()) return false;
         for (int i=0; i<pattern.length(); i++) {
-            if (pattern.charAt(i) == 'x') continue;
-            if (pattern.charAt(i) != text.charAt(i)) return false;
+            char pc = pattern.charAt(i);
+            char tc = text.charAt(i);
+            if(pc == 'x' && tc >= '0' && tc <= '9') continue;
+            else if(pc == 'x' || pc != tc) return false;
         }
         return true;
Index: /trunk/src/org/openstreetmap/josm/tools/OsmUrlToBounds.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/tools/OsmUrlToBounds.java	(revision 1723)
+++ /trunk/src/org/openstreetmap/josm/tools/OsmUrlToBounds.java	(revision 1724)
@@ -74,5 +74,5 @@
     static public String getURL(Bounds b)
     {
-        return getURL(b.center(), getZoom(b));
+        return getURL(b.getCenter(), getZoom(b));
     }
 
