Ticket #10853: photo_geotagging_10853.patch
| File photo_geotagging_10853.patch, 10.7 KB (added by , 11 years ago) |
|---|
-
src/org/openstreetmap/josm/plugins/photo_geotagging/ExifGPSTagger.java
9 9 import java.io.IOException; 10 10 import java.text.DecimalFormat; 11 11 import java.util.Calendar; 12 import java.util.Date; 12 13 import java.util.GregorianCalendar; 13 14 import java.util.TimeZone; 14 15 … … 33 34 * @param dst The output file. 34 35 * @param lat latitude 35 36 * @param lon longitude 36 * @param gpsTime time in milliseconds 37 * @param gpsTime time - can be null if not available 38 * @param speed speed - can be null if not available 37 39 * @param ele elevation - can be null if not available 40 * @param imgDir image direction - can be null if not available 38 41 */ 39 public static void setExifGPSTag(File jpegImageFile, File dst, double lat, double lon, long gpsTime, Double ele) throws IOException {42 public static void setExifGPSTag(File jpegImageFile, File dst, double lat, double lon, Date gpsTime, Double speed, Double ele, Double imgDir) throws IOException { 40 43 try { 41 setExifGPSTagWorker(jpegImageFile, dst, lat, lon, gpsTime, ele);44 setExifGPSTagWorker(jpegImageFile, dst, lat, lon, gpsTime, speed, ele, imgDir); 42 45 } catch (ImageReadException ire) { 43 46 throw new IOException(tr("Read error: "+ire), ire); 44 47 } catch (ImageWriteException ire2) { … … 46 49 } 47 50 } 48 51 49 public static void setExifGPSTagWorker(File jpegImageFile, File dst, double lat, double lon, long gpsTime, Double ele)52 public static void setExifGPSTagWorker(File jpegImageFile, File dst, double lat, double lon, Date gpsTime, Double speed, Double ele, Double imgDir) 50 53 throws IOException, ImageReadException, ImageWriteException { 51 54 TiffOutputSet outputSet = null; 52 55 … … 68 71 gpsDirectory.removeField(GpsTagConstants.GPS_TAG_GPS_VERSION_ID); 69 72 gpsDirectory.add(GpsTagConstants.GPS_TAG_GPS_VERSION_ID, (byte)2, (byte)3, (byte)0, (byte)0); 70 73 71 Calendar calendar = new GregorianCalendar(TimeZone.getTimeZone("UTC")); 72 calendar.setTimeInMillis(gpsTime); 74 if (gpsTime != null) { 75 Calendar calendar = new GregorianCalendar(TimeZone.getTimeZone("UTC")); 76 calendar.setTime(gpsTime); 73 77 74 final int year = calendar.get(Calendar.YEAR);75 final int month = calendar.get(Calendar.MONTH) + 1;76 final int day = calendar.get(Calendar.DAY_OF_MONTH);77 final int hour = calendar.get(Calendar.HOUR_OF_DAY);78 final int minute = calendar.get(Calendar.MINUTE);79 final int second = calendar.get(Calendar.SECOND);78 final int year = calendar.get(Calendar.YEAR); 79 final int month = calendar.get(Calendar.MONTH) + 1; 80 final int day = calendar.get(Calendar.DAY_OF_MONTH); 81 final int hour = calendar.get(Calendar.HOUR_OF_DAY); 82 final int minute = calendar.get(Calendar.MINUTE); 83 final int second = calendar.get(Calendar.SECOND); 80 84 81 DecimalFormat yearFormatter = new DecimalFormat("0000");82 DecimalFormat monthFormatter = new DecimalFormat("00");83 DecimalFormat dayFormatter = new DecimalFormat("00");85 DecimalFormat yearFormatter = new DecimalFormat("0000"); 86 DecimalFormat monthFormatter = new DecimalFormat("00"); 87 DecimalFormat dayFormatter = new DecimalFormat("00"); 84 88 85 final String yearStr = yearFormatter.format(year);86 final String monthStr = monthFormatter.format(month);87 final String dayStr = dayFormatter.format(day);88 final String dateStamp = yearStr+":"+monthStr+":"+dayStr;89 //System.err.println("date: "+dateStamp+" h/m/s: "+hour+"/"+minute+"/"+second);89 final String yearStr = yearFormatter.format(year); 90 final String monthStr = monthFormatter.format(month); 91 final String dayStr = dayFormatter.format(day); 92 final String dateStamp = yearStr+":"+monthStr+":"+dayStr; 93 //System.err.println("date: "+dateStamp+" h/m/s: "+hour+"/"+minute+"/"+second); 90 94 91 // make sure to remove old value if present (this method will92 // not fail if the tag does not exist).93 gpsDirectory.removeField(GpsTagConstants.GPS_TAG_GPS_TIME_STAMP);94 gpsDirectory.add(GpsTagConstants.GPS_TAG_GPS_TIME_STAMP,95 RationalNumber.valueOf(hour),96 RationalNumber.valueOf(minute),97 RationalNumber.valueOf(second));95 // make sure to remove old value if present (this method will 96 // not fail if the tag does not exist). 97 gpsDirectory.removeField(GpsTagConstants.GPS_TAG_GPS_TIME_STAMP); 98 gpsDirectory.add(GpsTagConstants.GPS_TAG_GPS_TIME_STAMP, 99 RationalNumber.valueOf(hour), 100 RationalNumber.valueOf(minute), 101 RationalNumber.valueOf(second)); 98 102 99 // make sure to remove old value if present (this method will 100 // not fail if the tag does not exist). 101 gpsDirectory.removeField(GpsTagConstants.GPS_TAG_GPS_DATE_STAMP); 102 gpsDirectory.add(GpsTagConstants.GPS_TAG_GPS_DATE_STAMP, dateStamp); 103 // make sure to remove old value if present (this method will 104 // not fail if the tag does not exist). 105 gpsDirectory.removeField(GpsTagConstants.GPS_TAG_GPS_DATE_STAMP); 106 gpsDirectory.add(GpsTagConstants.GPS_TAG_GPS_DATE_STAMP, dateStamp); 107 } 103 108 104 109 outputSet.setGPSInDegrees(lon, lat); 105 110 111 if (speed != null) { 112 gpsDirectory.removeField(GpsTagConstants.GPS_TAG_GPS_SPEED_REF); 113 gpsDirectory.add(GpsTagConstants.GPS_TAG_GPS_SPEED_REF, 114 GpsTagConstants.GPS_TAG_GPS_SPEED_REF_VALUE_KMPH); 115 116 gpsDirectory.removeField(GpsTagConstants.GPS_TAG_GPS_SPEED); 117 gpsDirectory.add(GpsTagConstants.GPS_TAG_GPS_SPEED, RationalNumber.valueOf(speed)); 118 } 119 106 120 if (ele != null) { 107 121 byte eleRef = ele >= 0 ? (byte) 0 : (byte) 1; 108 122 gpsDirectory.removeField(GpsTagConstants.GPS_TAG_GPS_ALTITUDE_REF); … … 111 125 gpsDirectory.removeField(GpsTagConstants.GPS_TAG_GPS_ALTITUDE); 112 126 gpsDirectory.add(GpsTagConstants.GPS_TAG_GPS_ALTITUDE, RationalNumber.valueOf(Math.abs(ele))); 113 127 } 128 129 if (imgDir != null) { 130 gpsDirectory.removeField(GpsTagConstants.GPS_TAG_GPS_IMG_DIRECTION_REF); 131 gpsDirectory.add(GpsTagConstants.GPS_TAG_GPS_IMG_DIRECTION_REF, 132 GpsTagConstants.GPS_TAG_GPS_IMG_DIRECTION_REF_VALUE_TRUE_NORTH); 133 // make sure the value is in the range 0.0...<360.0 134 if (imgDir < 0.0) { 135 imgDir %= 360.0; // >-360.0...-0.0 136 imgDir += 360.0; // >0.0...360.0 137 } 138 if (imgDir >= 360.0) { 139 imgDir %= 360.0; 140 } 141 gpsDirectory.removeField(GpsTagConstants.GPS_TAG_GPS_IMG_DIRECTION); 142 gpsDirectory.add(GpsTagConstants.GPS_TAG_GPS_IMG_DIRECTION, RationalNumber.valueOf(imgDir)); 143 } 144 114 145 try (BufferedOutputStream os = new BufferedOutputStream(new FileOutputStream(dst))) { 115 146 new ExifRewriter().updateExifMetadataLossless(jpegImageFile, os, outputSet); 116 147 } -
src/org/openstreetmap/josm/plugins/photo_geotagging/GeotaggingAction.java
13 13 import java.nio.file.Files; 14 14 import java.text.DecimalFormat; 15 15 import java.util.ArrayList; 16 import java.util.Date; 16 17 import java.util.List; 17 18 import java.util.UUID; 18 19 … … 65 66 final List<ImageEntry> images = new ArrayList<>(); 66 67 for (ImageEntry e : layer.getImages()) { 67 68 /* Only write lat/lon to the file, if the position is known and 68 we have a time from the correlation to the gpx track. */69 if (e.getPos() != null && e.hasGpsTime()) {69 the GPS data changed. */ 70 if (e.getPos() != null && (e.hasNewGpsData() || e.hasGpsTime())) { 70 71 images.add(e); 71 72 } 72 73 } … … 204 205 } 205 206 206 207 Long mTime = null; 207 if (mTimeMode == MTIME_MODE_PREVIOUS_VALUE) { 208 if (mTimeMode == MTIME_MODE_GPS) { 209 // check GPS time fields, do nothing if all fails 210 Date time; 211 if (e.hasGpsTime()) { 212 time = e.getGpsTime(); 213 } else { 214 time = e.getExifGpsTime(); 215 } 216 if (time != null) { 217 mTime = time.getTime(); 218 } 219 } 220 if ( mTimeMode == MTIME_MODE_PREVIOUS_VALUE 221 // this is also the fallback if one of the other 222 // modes failed to determine the modification time 223 || (mTimeMode != 0 && mTime == null)) { 208 224 mTime = e.getFile().lastModified(); 209 225 if (mTime.equals(0L)) 210 226 throw new IOException(tr("Could not read mtime.")); … … 212 228 213 229 chooseFiles(e.getFile()); 214 230 if (canceled) return; 215 ExifGPSTagger.setExifGPSTag(fileFrom, fileTo, e.getPos().lat(), e.getPos().lon(), e.getGpsTime().getTime(), e.getElevation()); 231 ExifGPSTagger.setExifGPSTag(fileFrom, fileTo, e.getPos().lat(), e.getPos().lon(), 232 e.getGpsTime(), e.getSpeed(), e.getElevation(), e.getExifImgDir()); 216 233 217 if (mTimeMode == MTIME_MODE_GPS) {218 mTime = e.getGpsTime().getTime();219 }220 221 234 if (mTime != null) { 222 235 if (!fileTo.setLastModified(mTime)) 223 236 throw new IOException(tr("Could not write mtime.")); … … 377 390 */ 378 391 private boolean enabled(GeoImageLayer layer) { 379 392 for (ImageEntry e : layer.getImages()) { 380 if (e.getPos() != null && e.hasGpsTime())393 if (e.getPos() != null && (e.hasNewGpsData() || e.hasGpsTime())) 381 394 return true; 382 395 } 383 396 return false;
