Index: trunk/src/org/openstreetmap/josm/data/ImageData.java
===================================================================
--- trunk/src/org/openstreetmap/josm/data/ImageData.java	(revision 19374)
+++ trunk/src/org/openstreetmap/josm/data/ImageData.java	(revision 19387)
@@ -367,4 +367,81 @@
 
     /**
+     * Update the GPS track direction of the image and trigger update.
+     * @param img the image to update
+     * @param trackDirection the new GPS track direction
+     * @since 19387
+     */
+    public void updateImageGpsTrack(ImageEntry img, double trackDirection) {
+        img.setExifGpsTrack(trackDirection);
+        afterImageUpdated(img);
+    }
+
+    /**
+     * Update the image horizontal positioning error and trigger update.
+     * @param img the image to update
+     * @param hposerr the new horizontal positionning error
+     * @since 19387
+     */
+    public void updateImageHPosErr(ImageEntry img, double hposerr) {
+        img.setExifHPosErr(hposerr);
+        afterImageUpdated(img);
+    }
+
+    /**
+     * Update the image GPS differential mode and trigger update.
+     * @param img the image to update
+     * @param gpsDiffMode the new GPS differential mode
+     * @since 19387
+     */
+    public void updateImageGpsDiffMode(ImageEntry img, Integer gpsDiffMode) {
+        img.setGpsDiffMode(gpsDiffMode);
+        afterImageUpdated(img);
+    }
+
+    /**
+     * Update the image GPS 2d/3d mode value and trigger update.
+     * @param img the image to update
+     * @param gps2d3dMode the new 2d/3d GPS mode
+     * @since 19387
+     */
+    public void updateImageGps2d3dMode(ImageEntry img, Integer gps2d3dMode) {
+        img.setGps2d3dMode(gps2d3dMode);
+        afterImageUpdated(img);
+    }
+
+    /**
+     * Update the image GPS DOP value and trigger update.
+     * @param img the image to update
+     * @param exifGpsDop the new GPS DOP value
+     * @since 19387
+     */
+    public void updateImageExifGpsDop(ImageEntry img, Double exifGpsDop) {
+        img.setExifGpsDop(exifGpsDop);
+        afterImageUpdated(img);
+    }
+
+    /**
+     * Update the image GPS datum and trigger update.
+     * @param img the image to update
+     * @param exifGpsDatum the new datum string value
+     * @since 19387
+     */
+    public void updateImageExifGpsDatum(ImageEntry img, String exifGpsDatum) {
+        img.setExifGpsDatum(exifGpsDatum);
+        afterImageUpdated(img);
+    }
+
+    /**
+     * Update the image GPS processing method and trigger update.
+     * @param img the image to update
+     * @param exifGpsProcMethod the new GPS processing method
+     * @since 19387
+     */
+    public void updateImageExifGpsProcMethod(ImageEntry img, String exifGpsProcMethod) {
+        img.setExifGpsProcMethod(exifGpsProcMethod);
+        afterImageUpdated(img);
+    }
+
+    /**
      * Manually trigger the {@link ImageDataUpdateListener#imageDataUpdated(ImageData)}
      */
Index: trunk/src/org/openstreetmap/josm/data/gpx/GpxConstants.java
===================================================================
--- trunk/src/org/openstreetmap/josm/data/gpx/GpxConstants.java	(revision 19374)
+++ trunk/src/org/openstreetmap/josm/data/gpx/GpxConstants.java	(revision 19387)
@@ -146,4 +146,9 @@
     String PT_TIME = "time";
 
+    /** True Course/Bearing angle over ground.
+     * @since 19387
+     */
+    String PT_COURSE = "course";
+
     /** Magnetic variation (in degrees) at the point. 0.0 &lt;= value &lt; 360.0 */
     String PT_MAGVAR = "magvar";
@@ -189,6 +194,6 @@
      */
     List<String> WPT_KEYS = Collections.unmodifiableList(Arrays.asList(PT_ELE, PT_TIME, PT_MAGVAR, PT_GEOIDHEIGHT,
-            GPX_NAME, GPX_CMT, GPX_DESC, GPX_SRC, META_LINKS, PT_SYM, PT_TYPE,
-            PT_FIX, PT_SAT, PT_HDOP, PT_VDOP, PT_PDOP, PT_AGEOFDGPSDATA, PT_DGPSID, PT_STD_HDEV, PT_STD_VDEV));
+            GPX_NAME, GPX_CMT, GPX_DESC, GPX_SRC, META_LINKS, PT_SYM, PT_TYPE, PT_FIX, PT_SAT, PT_COURSE,
+            PT_HDOP, PT_VDOP, PT_PDOP, PT_AGEOFDGPSDATA, PT_DGPSID, PT_STD_HDEV, PT_STD_VDEV));
 
     /**
Index: trunk/src/org/openstreetmap/josm/data/gpx/GpxImageCorrelation.java
===================================================================
--- trunk/src/org/openstreetmap/josm/data/gpx/GpxImageCorrelation.java	(revision 19374)
+++ trunk/src/org/openstreetmap/josm/data/gpx/GpxImageCorrelation.java	(revision 19387)
@@ -2,4 +2,5 @@
 package org.openstreetmap.josm.data.gpx;
 
+import java.util.Arrays;
 import java.util.ArrayList;
 import java.util.Collection;
@@ -73,4 +74,5 @@
 
         final GpxImageDirectionPositionSettings dirpos = settings.getDirectionPositionSettings();
+        final GpxImageDatumSettings datumSettings = settings.getDatumSettings();
         final long offset = settings.getOffset();
 
@@ -142,5 +144,6 @@
                     }
                     WayPoint nextWp = i < size - 1 ? wps.get(i + 1) : null;
-                    ret += matchPoints(images, prevWp, prevWpTime, curWp, curWpTime, offset, interpolate, tagTime, nextWp, dirpos);
+                    ret += matchPoints(images, prevWp, prevWpTime, curWp, curWpTime, offset,
+                                       interpolate, tagTime, nextWp, dirpos, datumSettings);
                     prevWp = curWp;
                     prevWpTime = curWpTime;
@@ -149,5 +152,6 @@
         }
         if (trkTag && prevWp != null) {
-            ret += matchPoints(images, prevWp, prevWpTime, prevWp, prevWpTime, offset, false, trkTagTime, null, dirpos);
+            ret += matchPoints(images, prevWp, prevWpTime, prevWp, prevWpTime, offset,
+                               false, trkTagTime, null, dirpos, datumSettings);
         }
         Logging.debug("Correlated {0} total points", ret);
@@ -210,6 +214,109 @@
     }
 
-    private static int matchPoints(List<? extends GpxImageEntry> images, WayPoint prevWp, long prevWpTime, WayPoint curWp, long curWpTime,
-            long offset, boolean interpolate, int tagTime, WayPoint nextWp, GpxImageDirectionPositionSettings dirpos) {
+    static Double getHPosErr(WayPoint wp) {
+        if (wp != null) {
+            if (wp.attr.get(GpxConstants.PT_STD_HDEV) instanceof Float) {
+                Float hposerr = (Float) wp.attr.get(GpxConstants.PT_STD_HDEV);
+                if (hposerr != null) {
+                    return hposerr.doubleValue();
+                }
+            } else if (wp.attr.get(GpxConstants.PT_STD_HDEV) instanceof Double) {               
+                Double hposerr = (Double) wp.attr.get(GpxConstants.PT_STD_HDEV);
+                if (hposerr != null) {
+                    return hposerr;
+                }
+            }
+        }
+        return null;
+    }
+
+    static Double getGpsDop(WayPoint wp) {
+        if (wp != null) {
+            if (wp.attr.get(GpxConstants.PT_PDOP) != null) {
+                if (wp.attr.get(GpxConstants.PT_PDOP) instanceof Float) {
+                    Float pdopvalue = (Float) wp.attr.get(GpxConstants.PT_PDOP);
+                    return pdopvalue.doubleValue();
+                } else if (wp.attr.get(GpxConstants.PT_PDOP) instanceof Double) {
+                    Double pdopvalue = (Double) wp.attr.get(GpxConstants.PT_PDOP);
+                    return pdopvalue.doubleValue();
+                }
+            } else if (wp.attr.get(GpxConstants.PT_HDOP) != null) {
+                if (wp.attr.get(GpxConstants.PT_HDOP) instanceof Float) {
+                    Float hdopvalue = (Float) wp.attr.get(GpxConstants.PT_HDOP);
+                    return hdopvalue.doubleValue();
+                } else if (wp.attr.get(GpxConstants.PT_HDOP) instanceof Double) {
+                    Double hdopvalue = (Double) wp.attr.get(GpxConstants.PT_HDOP);
+                    return hdopvalue.doubleValue();
+                }
+            }
+        }
+        return null;
+    }
+
+    static Double getGpsTrack(WayPoint wp) {
+        if (wp != null) {
+            String trackvalue = wp.getString(GpxConstants.PT_COURSE);
+            Logging.debug("track angle value: {0}", trackvalue);
+            if (!Utils.isEmpty(trackvalue)) {
+                try {
+                    return Double.valueOf(trackvalue);
+                } catch (NumberFormatException e) {
+                    Logging.warn(e);
+                }
+            }
+        }
+        return null;
+    }
+
+    static String getGpsProcMethod(String prevGpsFixMode, final String curGpsFixMode,
+                                    final List<String> positioningModes) {
+        String gpsProcMethod = null;
+        Integer lowestProcIndex = null;
+        int lowestGnssModeIdx = 3; // 2d or higher index in positioningModes list are Gnss methods
+        try {
+            lowestProcIndex = Math.min(positioningModes.indexOf(prevGpsFixMode), positioningModes.indexOf(curGpsFixMode));
+            if (lowestProcIndex < 0) {
+                return null;
+            }
+            gpsProcMethod = "GNSS" + " " + positioningModes.get(lowestProcIndex).toUpperCase() + " " + "CORRELATION";
+            if (lowestProcIndex < lowestGnssModeIdx) {
+                gpsProcMethod = positioningModes.get(lowestProcIndex).toUpperCase() + " " + "CORRELATION";
+            } else {
+                gpsProcMethod = "GNSS" + " " + positioningModes.get(lowestProcIndex).toUpperCase() + " " + "CORRELATION";
+            }
+            gpsProcMethod = gpsProcMethod.replace("FLOAT RTK", "RTK_FLOAT");
+            gpsProcMethod = gpsProcMethod.replace(" RTK ", " RTK_FIX ");
+        } catch (ArrayIndexOutOfBoundsException ex) {
+            Logging.warn(ex);
+        }
+        return gpsProcMethod;
+    }
+
+    static Integer getGps2d3dMode(String prevGpsFixMode, final String curGpsFixMode,
+                                final List<String> positioningModes) {
+        Integer lowestMode = null;
+        lowestMode = Math.min(positioningModes.indexOf(prevGpsFixMode), positioningModes.indexOf(curGpsFixMode));
+        if (lowestMode > 3) {
+            return 3;
+        }
+        if (lowestMode > 2) {
+            return 2;
+        }
+        return null;
+    }
+
+    // CHECKSTYLE.OFF: ParameterNumber
+    private static int matchPoints(List<? extends GpxImageEntry>
+                                        images,
+                                        WayPoint prevWp,
+                                        long prevWpTime,
+                                        WayPoint curWp,
+                                        long curWpTime,
+                                        long offset,
+                                        boolean interpolate,
+                                        int tagTime,
+                                        WayPoint nextWp,
+                                        GpxImageDirectionPositionSettings dirpos,
+                                        GpxImageDatumSettings datumSettings) {
 
         final boolean isLast = nextWp == null;
@@ -237,4 +344,13 @@
         Double speed = null;
         Double prevElevation = null;
+        Double prevHPosErr = null;
+        Double prevGpsDop = null;
+        Double prevGpsTrack = null;
+        String prevGpsFixMode = null;
+        //list of differential GPS mode
+        //TODO move these lists in Gpx.Constants?
+        final List<String> diffMode = Arrays.asList("dgps", "float rtk", "rtk");
+        final List<String> positioningModes = Arrays.asList("none", "manual", "estimated", "2d", "3d", "dgps", "float rtk", "rtk");
+
 
         if (prevWp != null && interpolate) {
@@ -245,7 +361,15 @@
             }
             prevElevation = getElevation(prevWp);
+            prevHPosErr = getHPosErr(prevWp);
+            prevGpsDop = getGpsDop(prevWp);
+            prevGpsTrack = getGpsTrack(prevWp);
+            prevGpsFixMode = prevWp.getString(GpxConstants.PT_FIX);
         }
 
         final Double curElevation = getElevation(curWp);
+        final Double curHPosErr = getHPosErr(curWp);
+        final Double curGpsDop = getGpsDop(curWp);
+        final Double curGpsTrack = getGpsTrack(curWp);
+        final String curGpsFixMode = curWp.getString(GpxConstants.PT_FIX);
 
         if (!interpolate || isLast) {
@@ -267,4 +391,5 @@
                         curTmp.setPos(curWp.getCoor());
                     }
+                    //TODO fix this, nextWp doesn't exist here
                     if (nextWp != null && dirpos.isSetImageDirection()) {
                         double direction = curWp.bearing(nextWp);
@@ -318,4 +443,60 @@
                         curTmp.setElevation(prevElevation + (curElevation - prevElevation) * timeDiff + dirpos.getElevationShift());
                     }
+
+                    // Add exif GpsHPositioningerror interpolated value
+                    if (curHPosErr != null && prevHPosErr != null) {
+                        Double interpolatedValue = prevHPosErr + (curHPosErr - prevHPosErr) * timeDiff;
+                        curTmp.setExifHPosErr(Math.round(interpolatedValue*10000)/10000.0);
+                    }
+
+                    // Add exif GpsDifferentialMode
+                    // Get previous and current waypoint differential. As no interpolation is possible,
+                    // set differential mode to 0 if any waypoint isn't in differential mode.
+                    if (prevGpsFixMode != null) {
+                        if (diffMode.contains(prevGpsFixMode) && diffMode.contains(curGpsFixMode)) {
+                            curTmp.setGpsDiffMode(1);
+                        } else {
+                            curTmp.setGpsDiffMode(0);
+                        }
+                    }
+
+                    // Add exif GpsMeasureMode
+                    if (prevGpsFixMode != null && curGpsFixMode != null) {
+                        Integer gps2d3dMode = getGps2d3dMode(prevGpsFixMode, curGpsFixMode, positioningModes);
+                        if (gps2d3dMode != null) {
+                            curTmp.setGps2d3dMode(gps2d3dMode);
+                        }
+                    }
+                    
+                    // Add exif GpsProcessingMethod. As no interpolation is possible,
+                    // set processing method to the "lowest" previous and current processing method value.
+                    if (prevGpsFixMode != null && curGpsFixMode != null) {
+                        String gpsProcMethod = getGpsProcMethod(prevGpsFixMode, curGpsFixMode, positioningModes);                       
+                        if (gpsProcMethod != null) {
+                            curTmp.setExifGpsProcMethod(gpsProcMethod);
+                        }
+                    }
+
+                    // Add Exif GpsDop with interpolated GPS DOP value
+                    if (curGpsDop != null && prevGpsDop != null) {
+                        Double interpolatedValue = prevGpsDop + (curGpsDop - prevGpsDop) * timeDiff;
+                        curTmp.setExifGpsDop(Math.round(interpolatedValue*100)/100.0);
+                    }
+
+                    // Add Exif GpsTrack tag
+                    if (dirpos.isSetGpxTrackDirection()) {
+                        if (curGpsTrack != null && prevGpsTrack != null) {
+                            curTmp.setExifGpsTrack(prevGpsTrack + (curGpsTrack - prevGpsTrack) * timeDiff);
+                        }
+                    }
+                    
+                    // Add GpsDatum tag
+                    if (datumSettings.isSetImageGpsDatum()) {
+                        if (diffMode.contains(prevGpsFixMode) && diffMode.contains(curGpsFixMode)) {
+                            curTmp.setExifGpsDatum(datumSettings.getImageGpsDatum());
+                        } else //without differential mode, datum is WGS-84
+                            curTmp.setExifGpsDatum("WGS-84");
+                    }
+
                     curTmp.setGpsTime(curImg.getExifInstant().minusMillis(offset));
                     curTmp.flagNewGpsData();
@@ -331,4 +512,5 @@
         return ret;
     }
+    // CHECKSTYLE.ON: ParameterNumber
 
     private static double computeDirection(double direction, double angleOffset) {
Index: trunk/src/org/openstreetmap/josm/data/gpx/GpxImageCorrelationSettings.java
===================================================================
--- trunk/src/org/openstreetmap/josm/data/gpx/GpxImageCorrelationSettings.java	(revision 19374)
+++ trunk/src/org/openstreetmap/josm/data/gpx/GpxImageCorrelationSettings.java	(revision 19387)
@@ -13,4 +13,5 @@
     private final boolean forceTags;
     private final GpxImageDirectionPositionSettings directionPositionSettings;
+    private final GpxImageDatumSettings datumSettings;
 
     /**
@@ -20,5 +21,8 @@
      */
     public GpxImageCorrelationSettings(long offset, boolean forceTags) {
-        this(offset, forceTags, new GpxImageDirectionPositionSettings(false, 0, 0, 0, 0));
+        this(offset, forceTags,
+        new GpxImageDirectionPositionSettings(false, 0, false, 0, 0, 0),
+        new GpxImageDatumSettings(false, null)
+        );
     }
 
@@ -31,9 +35,25 @@
     public GpxImageCorrelationSettings(long offset, boolean forceTags,
             GpxImageDirectionPositionSettings directionPositionSettings) {
+        this(offset, forceTags, directionPositionSettings,
+        new GpxImageDatumSettings(false, null));
+    }
+
+    /**
+     * Constructs a new {@code GpxImageCorrelationSettings}.
+     * @param offset offset in milliseconds
+     * @param forceTags force tagging of all photos, otherwise prefs are used
+     * @param directionPositionSettings direction/position settings
+     * @param datumSettings GPS datum settings
+     * @since 19387 @datumSettings was added
+     */
+    public GpxImageCorrelationSettings(long offset, boolean forceTags,
+            GpxImageDirectionPositionSettings directionPositionSettings,
+            GpxImageDatumSettings datumSettings) {
         this.offset = offset;
         this.forceTags = forceTags;
         this.directionPositionSettings = Objects.requireNonNull(directionPositionSettings);
+        this.datumSettings = Objects.requireNonNull(datumSettings);
     }
-
+    
     /**
      * Returns the offset in milliseconds.
@@ -60,8 +80,18 @@
     }
 
+    /**
+     * Returns the EXIF metadata datum settings.
+     * @return the EXIF metadata datum settings
+     * @since 19387
+     */
+    public GpxImageDatumSettings getDatumSettings() {
+        return datumSettings;
+    }
+
     @Override
     public String toString() {
         return "[offset=" + offset + ", forceTags=" + forceTags
-                + ", directionPositionSettings=" + directionPositionSettings + ']';
+                + ", directionPositionSettings=" + directionPositionSettings
+                + ", datumSettings=" + datumSettings + ']';
     }
 }
Index: trunk/src/org/openstreetmap/josm/data/gpx/GpxImageDatumSettings.java
===================================================================
--- trunk/src/org/openstreetmap/josm/data/gpx/GpxImageDatumSettings.java	(revision 19387)
+++ trunk/src/org/openstreetmap/josm/data/gpx/GpxImageDatumSettings.java	(revision 19387)
@@ -0,0 +1,39 @@
+// License: GPL. For details, see LICENSE file.
+package org.openstreetmap.josm.data.gpx;
+
+/**
+ * Image extended exif metadata settings used by {@link GpxImageCorrelationSettings}.
+ * @since 19387
+ */
+public class GpxImageDatumSettings {
+
+    private final boolean setImageGpsDatum;
+    private final String imageGpsDatum;
+    
+    /**
+     * Construcs a new {@code GpxImageDatumSettings}.
+     * @param setImageGpsDatum determines if images GPS datum must be set
+     * @param imageGpsDatum determines the GPS coordinates datum value to be set
+     */
+    public GpxImageDatumSettings(
+        boolean setImageGpsDatum, String imageGpsDatum) {
+            this.setImageGpsDatum = setImageGpsDatum;
+            this.imageGpsDatum = imageGpsDatum;
+        }
+    
+    /**
+     * Determines if image GPS datum must be set
+     * @return if the GPS datum must be set
+     */
+    public boolean isSetImageGpsDatum() {
+        return setImageGpsDatum;
+    }
+    
+    /**
+     * Return the GPS coordinates datum code.
+     * @return the datum code
+     */
+    public String getImageGpsDatum() {
+        return imageGpsDatum;
+    }
+}
Index: trunk/src/org/openstreetmap/josm/data/gpx/GpxImageDirectionPositionSettings.java
===================================================================
--- trunk/src/org/openstreetmap/josm/data/gpx/GpxImageDirectionPositionSettings.java	(revision 19374)
+++ trunk/src/org/openstreetmap/josm/data/gpx/GpxImageDirectionPositionSettings.java	(revision 19387)
@@ -10,4 +10,5 @@
     private final boolean setImageDirection;
     private final double imageDirectionAngleOffset;
+    private final boolean setGpxTrackDirection;
     private final double shiftImageX;
     private final double shiftImageY;
@@ -18,12 +19,16 @@
      * @param setImageDirection determines if image direction must be set towards the next GPX waypoint
      * @param imageDirectionAngleOffset direction angle offset in degrees
+     * @param setGpxTrackDirection determines if image course direction must be set
      * @param shiftImageX image shift on X axis relative to the direction in meters
      * @param shiftImageY image shift on Y axis relative to the direction in meters
      * @param elevationShift image elevation shift in meters
+     * @since 19387 @setGpsTrackDirection was added
      */
     public GpxImageDirectionPositionSettings(
-            boolean setImageDirection, double imageDirectionAngleOffset, double shiftImageX, double shiftImageY, double elevationShift) {
+            boolean setImageDirection, double imageDirectionAngleOffset, boolean setGpxTrackDirection, 
+            double shiftImageX, double shiftImageY, double elevationShift) {
         this.setImageDirection = setImageDirection;
         this.imageDirectionAngleOffset = imageDirectionAngleOffset;
+        this.setGpxTrackDirection = setGpxTrackDirection;
         this.shiftImageX = shiftImageX;
         this.shiftImageY = shiftImageY;
@@ -45,4 +50,13 @@
     public double getImageDirectionAngleOffset() {
         return imageDirectionAngleOffset;
+    }
+
+    /**
+     * Determines if GPS course direction must be set. Angle value is from the gpx trace.
+     * @return {@code true} if image GPS course must be set
+     * @since 19387
+     */
+    public boolean isSetGpxTrackDirection() {
+        return setGpxTrackDirection;
     }
 
@@ -74,6 +88,9 @@
     public String toString() {
         return "[setImageDirection=" + setImageDirection
-                + ", imageDirectionAngleOffset=" + imageDirectionAngleOffset + ", shiftImageX=" + shiftImageX
-                + ", shiftImageY=" + shiftImageY + ", elevationShift=" + elevationShift + ']';
+                + ", imageDirectionAngleOffset=" + imageDirectionAngleOffset
+                + ", setImageGpxTrackDirection=" + setGpxTrackDirection
+                + ", shiftImageX=" + shiftImageX
+                + ", shiftImageY=" + shiftImageY
+                + ", elevationShift=" + elevationShift + ']';
     }
 }
Index: trunk/src/org/openstreetmap/josm/data/gpx/GpxImageEntry.java
===================================================================
--- trunk/src/org/openstreetmap/josm/data/gpx/GpxImageEntry.java	(revision 19374)
+++ trunk/src/org/openstreetmap/josm/data/gpx/GpxImageEntry.java	(revision 19387)
@@ -33,4 +33,7 @@
     private LatLon exifCoor;
     private Double exifImgDir;
+    private Double exifGpsTrack;
+    private Double exifHPosErr;
+    private Double exifGpsDop;
     private Instant exifTime;
     private Projections cameraProjection = Projections.UNKNOWN;
@@ -58,4 +61,12 @@
     /** Elevation (altitude) in meters */
     private Double elevation;
+    /** GPS Differential mode */
+    private Integer gpsDiffMode;
+    /** GPS Measure mode */
+    private Integer gps2d3dMode;
+    /** GPS Datum */
+    private String exifGpsDatum;
+    /** GPS processing method */
+    private String exifGpsProcMethod;
     /** The time after correlation with a gpx track */
     private Instant gpsTime;
@@ -89,4 +100,11 @@
         exifCoor = other.exifCoor;
         exifImgDir = other.exifImgDir;
+        exifGpsTrack = other.exifGpsTrack;
+        exifHPosErr = other.exifHPosErr;
+        gpsDiffMode = other.gpsDiffMode;
+        gps2d3dMode = other.gps2d3dMode;
+        exifGpsDop = other.exifGpsDop;
+        exifGpsDatum = other.exifGpsDatum;
+        exifGpsProcMethod = other.exifGpsProcMethod;
         exifTime = other.exifTime;
         isNewGpsData = other.isNewGpsData;
@@ -171,4 +189,67 @@
 
     /**
+     * Return the GPS Differential mode value. The GPS Differential mode value from the temporary
+     * copy is returned if that copy exists. 
+     * @return the differential mode value
+     * @since 19387
+     */
+    @Override
+    public Integer getGpsDiffMode() {
+        if (tmp != null)
+            return tmp.gpsDiffMode;
+        return gpsDiffMode;
+    }
+
+    /**
+     * Return the GPS 2d or 3d mode value. The GPS mode value form the temporary
+     * copy is returned if that copy exists. 
+     * @return the GPS 2d/3d mode value
+     * @since 19387
+     */
+    @Override
+    public Integer getGps2d3dMode() {
+        if (tmp != null)
+            return tmp.gps2d3dMode;
+        return gps2d3dMode;
+    }
+
+    /**
+     * Return the GPS DOP value. The GPS DOP value from the temporary
+     * copy is returned if that copy exists. 
+     * @return the DOP value
+     * @since 19387
+     */
+    @Override
+    public Double getExifGpsDop() {
+        if (tmp != null)
+            return tmp.exifGpsDop;
+        return exifGpsDop;
+    }
+
+    /**
+     * Return the exif GPS coordinates datum value.
+     * @return The datum value
+     * @since 19387
+     */
+    @Override
+    public String getExifGpsDatum() {
+        if (tmp != null)
+            return tmp.exifGpsDatum;
+        return exifGpsDatum;
+    }
+
+    /**
+     * Return the exif GPS processing method string
+     * @return the processing method string
+     * @since 19387
+     */
+    @Override
+    public String getExifGpsProcMethod() {
+        if (tmp != null)
+            return tmp.exifGpsProcMethod;
+        return exifGpsProcMethod;
+    }
+
+    /**
      * Returns the GPS time value. The GPS time value from the temporary copy
      * is returned if that copy exists.
@@ -272,4 +353,30 @@
             return tmp.exifImgDir;
         return exifImgDir;
+    }
+    
+    /**
+     * Convenient way to determine if this entry has a EXIF GPS track angle value,
+     * without the cost of building a defensive copy.
+     * @return {@code true} if this entry has a EXIF track angle value
+     * @since 19387
+     */
+    @Override
+    public Double getExifGpsTrack() {
+        if (tmp != null)
+            return tmp.exifGpsTrack;
+        return exifGpsTrack;
+    }
+
+    /**
+     * Convenient way to determine if this entry has a EXIF GPS horizontal positionning error value,
+     * without the cost of building a defensive copy.
+     * @return {@code true} if this entry has a EXIF GPS horizontal positionning error value
+     * @since 19387
+     */
+    @Override
+    public Double getExifHPosErr() {
+        if (tmp != null)
+            return tmp.exifHPosErr;
+        return exifHPosErr;
     }
 
@@ -347,4 +454,54 @@
 
     /**
+     * Sets GPS Differential mode.
+     * @param gpsDiffMode GPS Differential mode
+     * @since 19387
+     */
+    @Override
+    public void setGpsDiffMode(Integer gpsDiffMode) {
+        this.gpsDiffMode = gpsDiffMode;
+    }
+
+    /**
+     * Sets GPS 2d/3d mode.
+     * @param gps2d3dMode GPS 2d/3d mode value
+     * @since 19387
+     */
+    @Override
+    public void setGps2d3dMode(Integer gps2d3dMode) {
+        this.gps2d3dMode = gps2d3dMode;
+    }
+
+    /**
+     * Sets GPS DOP value.
+     * @param exifGpsDop GPS DOP value
+     * @since 19387
+     */
+    @Override
+    public void setExifGpsDop(Double exifGpsDop) {
+        this.exifGpsDop = exifGpsDop;
+    }
+
+    /**
+     * Sets the GPS Datum.
+     * @param exifGpsDatum GPS Datum
+     * @since 19387
+     */
+    @Override
+    public void setExifGpsDatum(String exifGpsDatum) {
+        this.exifGpsDatum = exifGpsDatum;
+    }
+
+    /**
+     * Sets the GPS Processing Method.
+     * @param exifGpsProcMethod GPS Processing Method
+     * @since 19387
+     */
+    @Override
+    public void setExifGpsProcMethod(String exifGpsProcMethod) {
+        this.exifGpsProcMethod = exifGpsProcMethod;
+    }
+
+    /**
      * Sets associated file.
      * @param file associated file
@@ -411,4 +568,24 @@
     public void setExifImgDir(Double exifDir) {
         this.exifImgDir = exifDir;
+    }
+
+    /**
+     * Sets the exif GPS track (move direction angle)
+     * @param exifGpsTrack the exif GPS track angle
+     * @since 19387
+     */
+    @Override
+    public void setExifGpsTrack(Double exifGpsTrack) {
+        this.exifGpsTrack = exifGpsTrack;
+    }
+
+    /**
+     * Sets the exif horizontal positioning error
+     * @param exifHposErr the Exif horizontal positionning error
+     * @since 19387
+     */
+    @Override
+    public void setExifHPosErr(Double exifHPosErr) {
+        this.exifHPosErr = exifHPosErr;
     }
 
@@ -508,7 +685,8 @@
     public int hashCode() {
         return Objects.hash(height, width, isNewGpsData,
-            elevation, exifCoor, exifGpsTime, exifImgDir, exifOrientation, exifTime,
-            iptcCaption, iptcHeadline, iptcKeywords, iptcObjectName,
-            file, gpsTime, pos, speed, tmp, cameraProjection);
+            elevation, exifCoor, exifGpsTime, exifImgDir, exifGpsTrack, exifHPosErr,
+            exifGpsDop, gpsDiffMode, gps2d3dMode, exifGpsDatum, exifGpsProcMethod,
+            exifOrientation, exifTime, iptcCaption, iptcHeadline, iptcKeywords,
+            iptcObjectName, file, gpsTime, pos, speed, tmp, cameraProjection);
     }
 
@@ -527,4 +705,11 @@
             && Objects.equals(exifGpsTime, other.exifGpsTime)
             && Objects.equals(exifImgDir, other.exifImgDir)
+            && Objects.equals(exifGpsTrack, other.exifGpsTrack)
+            && Objects.equals(exifHPosErr, other.exifHPosErr)
+            && Objects.equals(gpsDiffMode, other.gpsDiffMode)
+            && Objects.equals(gps2d3dMode, other.gps2d3dMode)
+            && Objects.equals(exifGpsDop, other.exifGpsDop)
+            && Objects.equals(exifGpsDatum, other.exifGpsDatum)
+            && Objects.equals(exifGpsProcMethod, other.exifGpsProcMethod)
             && Objects.equals(exifOrientation, other.exifOrientation)
             && Objects.equals(exifTime, other.exifTime)
@@ -571,4 +756,5 @@
      * temporary variable is deleted.
      * @see #discardTmp()
+     * @since 19387 exifGpsTrack, exifHPosErr, gpsDiffMode, gps2d3dMode, exifGpsDop, exifGpsDatum, exifGpsProcMethod added
      */
     public void applyTmp() {
@@ -579,4 +765,11 @@
             gpsTime = tmp.gpsTime;
             exifImgDir = tmp.exifImgDir;
+            exifGpsTrack = tmp.exifGpsTrack;
+            exifHPosErr = tmp.exifHPosErr;
+            gpsDiffMode = tmp.gpsDiffMode;
+            gps2d3dMode = tmp.gps2d3dMode;
+            exifGpsDop = tmp.exifGpsDop;
+            exifGpsDatum = tmp.exifGpsDatum;
+            exifGpsProcMethod = tmp.exifGpsProcMethod;
             isNewGpsData = isNewGpsData || tmp.isNewGpsData;
             tmp = null;
Index: trunk/src/org/openstreetmap/josm/data/imagery/street_level/IImageEntry.java
===================================================================
--- trunk/src/org/openstreetmap/josm/data/imagery/street_level/IImageEntry.java	(revision 19374)
+++ trunk/src/org/openstreetmap/josm/data/imagery/street_level/IImageEntry.java	(revision 19387)
@@ -220,4 +220,44 @@
 
     /**
+     * Return the GPS Differential mode value. The differential mode value from the temporary
+     * copy is returned if that copy exists. 
+     * @return the fix mode value
+     * @since 19387
+     */
+    Integer getGpsDiffMode();
+
+    /**
+     * Return the GPS 2d/3d mode value. The 2d/3d mode value from the temporary
+     * copy is returned if that copy exists.
+     * @return the 2d/3d mode value
+     * @since 19387
+     */
+    Integer getGps2d3dMode();
+
+    /**
+     * Return the GPS DOP value. The GPS DOP value from the temporary
+     * copy is return if that copy exists.
+     * @return the GPS DOP value
+     * @since 19387
+     */
+    Double getExifGpsDop();
+
+    /**
+     * Return the GPS datum value. The GPS datum value from the temporary
+     * copy is return if that copy exists. 
+     * @return the GPS datum value
+     * @since 19387
+     */
+    String getExifGpsDatum();
+
+    /**
+     * Return the GPS processing method. The processing method value from the temporary
+     * copy is return if that copy exists.
+     * @return the GPS processing method
+     * @since 19387
+     */
+    String getExifGpsProcMethod();
+
+    /**
      * Returns the image direction. The image direction from the temporary
      * copy is returned if that copy exists.
@@ -225,5 +265,21 @@
      */
     Double getExifImgDir();
-
+    
+    /**
+     * Returns the image GPS track direction. The GPS track direction from the temporary
+     * copy is returned if that copy exists.
+     * @return the image GPS track direction angle
+     * @since 19387
+     */
+    Double getExifGpsTrack();
+
+    /**
+     * Returns the image horizontal positionning error. The image positionning error
+     * from the temporary copy is returned if that copy exists.
+     * @return the image horizontal positionning error
+     * @since 19387
+     */
+    Double getExifHPosErr();
+    
     /**
      * Convenient way to determine if this entry has a EXIF time, without the cost of building a defensive copy.
@@ -253,4 +309,12 @@
 
     /**
+     * Returns the Exif GPS Time value. The Exif GPS time value from the temporary copy
+     * is returned if that copy exists.
+     * @return the Exif GPS time value
+     * @since 19387
+     */
+    Instant getExifGpsInstant();
+
+    /**
      * Returns the IPTC caption.
      * @return the IPTC caption
