Ticket #24278: 24278.patch
File 24278.patch, 9.2 KB (added by , 5 days ago) |
---|
-
src/org/openstreetmap/josm/plugins/photo_geotagging/ExifGPSTagger.java
46 46 * @param speed speed in km/h - can be null if not available 47 47 * @param ele elevation - can be null if not available 48 48 * @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 49 56 * @param lossy whether to use lossy approach when writing metadata (overwriting unknown tags) 50 57 * @throws IOException in case of I/O error 58 * @since xxx param added: gpsTrack, gpsDiffMode, gpsMeasureMode, exifGpsProcMethod, exifHPosErr, exifGpsDop, exifGpsDatum 51 59 */ 60 52 61 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 { 54 65 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); 56 68 } catch (ImagingException ire) { 57 69 // This used to be two separate exceptions; ImageReadException and imageWriteException 58 70 throw new IOException(tr("Read/write error: " + ire.getMessage()), ire); … … 59 71 } 60 72 } 61 73 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 { 64 78 65 79 TiffOutputSet outputSet = null; 66 80 ImageMetadata metadata = Imaging.getMetadata(imageFile); … … 141 155 gpsDirectory.removeField(GpsTagConstants.GPS_TAG_GPS_IMG_DIRECTION_REF); 142 156 gpsDirectory.add(GpsTagConstants.GPS_TAG_GPS_IMG_DIRECTION_REF, 143 157 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); 152 159 gpsDirectory.removeField(GpsTagConstants.GPS_TAG_GPS_IMG_DIRECTION); 153 160 gpsDirectory.add(GpsTagConstants.GPS_TAG_GPS_IMG_DIRECTION, RationalNumber.valueOf(imgDir)); 154 161 } 155 162 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 156 206 try (BufferedOutputStream os = new BufferedOutputStream(new FileOutputStream(dst))) { 157 207 if (metadata instanceof JpegImageMetadata) { 158 208 if (lossy) { … … 165 215 } 166 216 } 167 217 } 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 } 168 235 } -
src/org/openstreetmap/josm/plugins/photo_geotagging/GeotaggingAction.java
371 371 chooseFiles(e.getFile()); 372 372 if (canceled) return; 373 373 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); 375 378 376 379 if (mTime != null) { 377 380 if (!fileTo.setLastModified(mTime.toEpochMilli())) -
test/unit/org/openstreetmap/josm/plugins/photo_geotagging/ExifGPSTaggerTest.java
28 28 void testTicket11757() { 29 29 final File in = new File(TestUtils.getTestDataRoot(), "_DSC1234.jpg"); 30 30 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)); 32 32 } 33 33 34 34 @Test … … 46 46 void testTicket11902() throws Exception { 47 47 final File in = new File(TestUtils.getTestDataRoot(), "IMG_7250_small.JPG"); 48 48 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); 50 50 final Process jhead = Runtime.getRuntime().exec(new String[]{"jhead", out.getAbsolutePath()}); 51 51 final String stdout = new Scanner(jhead.getErrorStream()).useDelimiter("\\A").next(); 52 52 System.out.println(stdout);