Ticket #24278: 24278.patch

File 24278.patch, 9.2 KB (added by StephaneP, 5 days ago)
  • src/org/openstreetmap/josm/plugins/photo_geotagging/ExifGPSTagger.java

     
    4646     * @param speed speed in km/h - can be null if not available
    4747     * @param ele elevation - can be null if not available
    4848     * @param imgDir image direction in degrees (0..360) - can be null if not available
     49     * @param gpsTrack image course direction in degrees (0...360) - can be null if not available
     50     * @param gpsDiffMode Gps differential mode (0 or 1)
     51     * @param gpsMeasureMode Gps measure mode (2 for 2d, 3 for 3d)
     52     * @param exifGpsProcMethod Gps processing method
     53     * @param exifHPosErr image horizontal position error estimation
     54     * @param exifGpsDop image gps dop value
     55     * @param exifGpsDatum image coordinates datum
    4956     * @param lossy whether to use lossy approach when writing metadata (overwriting unknown tags)
    5057     * @throws IOException in case of I/O error
     58     * @since xxx param added: gpsTrack, gpsDiffMode, gpsMeasureMode, exifGpsProcMethod, exifHPosErr, exifGpsDop, exifGpsDatum
    5159     */
     60
    5261    public static void setExifGPSTag(File imageFile, File dst, double lat, double lon, Instant gpsTime, Double speed,
    53             Double ele, Double imgDir, boolean lossy) throws IOException {
     62            Double ele, Double imgDir, Double gpsTrack, Integer gpsDiffMode, Integer gpsMeasureMode,
     63            String exifGpsProcMethod, Double exifHPosErr, Double exifGpsDop, String exifGpsDatum,
     64            boolean lossy) throws IOException {
    5465        try {
    55             setExifGPSTagWorker(imageFile, dst, lat, lon, gpsTime, speed, ele, imgDir, lossy);
     66            setExifGPSTagWorker(imageFile, dst, lat, lon, gpsTime, speed, ele, imgDir, gpsTrack, gpsDiffMode,
     67            gpsMeasureMode, exifGpsProcMethod, exifHPosErr, exifGpsDop, exifGpsDatum, lossy);
    5668        } catch (ImagingException ire) {
    5769            // This used to be two separate exceptions; ImageReadException and imageWriteException
    5870            throw new IOException(tr("Read/write error: " + ire.getMessage()), ire);
     
    5971        }
    6072    }
    6173
    62     public static void setExifGPSTagWorker(File imageFile, File dst, double lat, double lon, Instant gpsTime, Double speed,
    63             Double ele, Double imgDir, boolean lossy) throws IOException {
     74    public static void setExifGPSTagWorker(File imageFile, File dst, double lat, double lon, Instant gpsTime,
     75            Double speed, Double ele, Double imgDir, Double gpsTrack, Integer gpsDiffMode, Integer gpsMeasureMode,
     76            String exifGpsProcMethod, Double exifHPosErr, Double exifGpsDop, String exifGpsDatum,
     77            boolean lossy) throws IOException {
    6478
    6579        TiffOutputSet outputSet = null;
    6680        ImageMetadata metadata = Imaging.getMetadata(imageFile);
     
    141155            gpsDirectory.removeField(GpsTagConstants.GPS_TAG_GPS_IMG_DIRECTION_REF);
    142156            gpsDirectory.add(GpsTagConstants.GPS_TAG_GPS_IMG_DIRECTION_REF,
    143157                             GpsTagConstants.GPS_TAG_GPS_IMG_DIRECTION_REF_VALUE_TRUE_NORTH);
    144             // make sure the value is in the range 0.0...<360.0
    145             if (imgDir < 0.0) {
    146                 imgDir %= 360.0; // >-360.0...-0.0
    147                 imgDir += 360.0; // >0.0...360.0
    148             }
    149             if (imgDir >= 360.0) {
    150                 imgDir %= 360.0;
    151             }
     158            imgDir = checkAngle(imgDir);
    152159            gpsDirectory.removeField(GpsTagConstants.GPS_TAG_GPS_IMG_DIRECTION);
    153160            gpsDirectory.add(GpsTagConstants.GPS_TAG_GPS_IMG_DIRECTION, RationalNumber.valueOf(imgDir));
    154161        }
    155162
     163        if (gpsTrack != null) {
     164            gpsDirectory.removeField(GpsTagConstants.GPS_TAG_GPS_TRACK_REF);
     165            gpsDirectory.add(GpsTagConstants.GPS_TAG_GPS_TRACK_REF,
     166                             GpsTagConstants.GPS_TAG_GPS_TRACK_REF_VALUE_TRUE_NORTH);
     167            // make sure the value is in the range 0.0...<360.0
     168            gpsTrack = checkAngle(gpsTrack);
     169            gpsDirectory.removeField(GpsTagConstants.GPS_TAG_GPS_TRACK);
     170            gpsDirectory.add(GpsTagConstants.GPS_TAG_GPS_TRACK, RationalNumber.valueOf(gpsTrack));
     171        }
     172
     173        if (gpsDiffMode != null) {
     174            gpsDirectory.removeField(GpsTagConstants.GPS_TAG_GPS_DIFFERENTIAL);
     175            // make sure the gpsDiffMode value is 0 (no diffential) or 1 (differential)
     176            if (gpsDiffMode.equals(0) || gpsDiffMode.equals(1)) {
     177                gpsDirectory.add(GpsTagConstants.GPS_TAG_GPS_DIFFERENTIAL, gpsDiffMode.shortValue());
     178            }
     179        }
     180       
     181        if (gpsMeasureMode != null) {
     182            gpsDirectory.removeField(GpsTagConstants.GPS_TAG_GPS_MEASURE_MODE);
     183            gpsDirectory.add(GpsTagConstants.GPS_TAG_GPS_MEASURE_MODE, gpsMeasureMode.toString());
     184        }
     185
     186        if (exifGpsProcMethod != null ) {
     187            gpsDirectory.removeField(GpsTagConstants.GPS_TAG_GPS_PROCESSING_METHOD);
     188            gpsDirectory.add(GpsTagConstants.GPS_TAG_GPS_PROCESSING_METHOD, exifGpsProcMethod);
     189        }
     190
     191        if (exifGpsDatum != null) {
     192            gpsDirectory.removeField(GpsTagConstants.GPS_TAG_GPS_MAP_DATUM);
     193            gpsDirectory.add(GpsTagConstants.GPS_TAG_GPS_MAP_DATUM, exifGpsDatum.toString());
     194        }
     195
     196        if (exifHPosErr != null) {
     197            gpsDirectory.removeField(GpsTagConstants.GPS_TAG_GPS_HOR_POSITIONING_ERROR);
     198            gpsDirectory.add(GpsTagConstants.GPS_TAG_GPS_HOR_POSITIONING_ERROR, RationalNumber.valueOf(exifHPosErr));
     199        }
     200
     201        if (exifGpsDop != null) {
     202            gpsDirectory.removeField(GpsTagConstants.GPS_TAG_GPS_DOP);
     203            gpsDirectory.add(GpsTagConstants.GPS_TAG_GPS_DOP, RationalNumber.valueOf(exifGpsDop));
     204        }
     205
    156206        try (BufferedOutputStream os = new BufferedOutputStream(new FileOutputStream(dst))) {
    157207            if (metadata instanceof JpegImageMetadata) {
    158208                if (lossy) {
     
    165215            }
    166216        }
    167217    }
     218
     219    /**
     220     * Normalizes an angle to the range [0.0, 360.0[ degrees.
     221     * This will fix any angle value <0 and >= 360
     222     * @param angle the angle to normalize (in degrees)
     223     * @return the equivalent angle value in the range [0.0, 360.0[
     224     */
     225    private static Double checkAngle(Double angle) {
     226        if (angle < 0.0) {
     227            angle %= 360.0; // >-360.0...-0.0
     228            angle += 360.0; // >0.0...360.0
     229        }
     230        if (angle >= 360.0) {
     231            angle %= 360.0;
     232        }
     233        return angle;
     234    }
    168235}
  • src/org/openstreetmap/josm/plugins/photo_geotagging/GeotaggingAction.java

     
    371371            chooseFiles(e.getFile());
    372372            if (canceled) return;
    373373            ExifGPSTagger.setExifGPSTag(fileFrom, fileTo, e.getPos().lat(), e.getPos().lon(),
    374                     e.getGpsInstant(), e.getSpeed(), e.getElevation(), e.getExifImgDir(), lossy);
     374                    e.getGpsInstant(), e.getSpeed(), e.getElevation(), e.getExifImgDir(),
     375                    e.getExifGpsTrack(), e.getGpsDiffMode(), e.getGps2d3dMode(),
     376                    e.getExifGpsProcMethod(), e.getExifHPosErr(), e.getExifGpsDop(),
     377                    e.getExifGpsDatum(), lossy);
    375378
    376379            if (mTime != null) {
    377380                if (!fileTo.setLastModified(mTime.toEpochMilli()))
  • test/unit/org/openstreetmap/josm/plugins/photo_geotagging/ExifGPSTaggerTest.java

     
    2828    void testTicket11757() {
    2929        final File in = new File(TestUtils.getTestDataRoot(), "_DSC1234.jpg");
    3030        final File out = new File(tempFolder, in.getName());
    31         assertDoesNotThrow(() -> ExifGPSTagger.setExifGPSTag(in, out, 12, 34, Instant.now(), 12.34, Math.E, Math.PI, true));
     31        assertDoesNotThrow(() -> ExifGPSTagger.setExifGPSTag(in, out, 12, 34, Instant.now(), 12.34, Math.E, Math.PI, Math.PI, 2, 3, "GPS", 1.2, 2.5, "WGS84", true));
    3232    }
    3333
    3434    @Test
     
    4646    void testTicket11902() throws Exception {
    4747        final File in = new File(TestUtils.getTestDataRoot(), "IMG_7250_small.JPG");
    4848        final File out = new File(tempFolder, in.getName());
    49         ExifGPSTagger.setExifGPSTag(in, out, 12, 34, Instant.now(), 12.34, Math.E, Math.PI, false);
     49        ExifGPSTagger.setExifGPSTag(in, out, 12, 34, Instant.now(), 12.34, Math.E, Math.PI, Math.PI, 2, 3, "GPS", 1.2, 2.5, "WGS84", true);
    5050        final Process jhead = Runtime.getRuntime().exec(new String[]{"jhead", out.getAbsolutePath()});
    5151        final String stdout = new Scanner(jhead.getErrorStream()).useDelimiter("\\A").next();
    5252        System.out.println(stdout);