Changeset 2931 in josm for trunk/src/org/openstreetmap
- Timestamp:
- 2010-02-03T09:48:51+01:00 (15 years ago)
- Location:
- trunk/src/org/openstreetmap/josm/gui/layer/geoimage
- Files:
-
- 5 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/org/openstreetmap/josm/gui/layer/geoimage/CorrelateGpxWithImages.java
r2907 r2931 2 2 // Copyright 2007 by Christian Gallioz (aka khris78) 3 3 // Parts of code from Geotagged plugin (by Rob Neild) 4 // and the core JOSM source code (by Immanuel Scholz and others)5 4 6 5 package org.openstreetmap.josm.gui.layer.geoimage; … … 333 332 imgList = new JList(new AbstractListModel() { 334 333 public Object getElementAt(int i) { 335 return yLayer.data.get(i). file.getName();334 return yLayer.data.get(i).getFile().getName(); 336 335 } 337 336 … … 345 344 public void valueChanged(ListSelectionEvent arg0) { 346 345 int index = imgList.getSelectedIndex(); 347 imgDisp.setImage(yLayer.data.get(index). file);348 Date date = yLayer.data.get(index). time;346 imgDisp.setImage(yLayer.data.get(index).getFile()); 347 Date date = yLayer.data.get(index).getExifTime(); 349 348 if (date != null) { 350 349 lbExifTime.setText(new SimpleDateFormat("dd/MM/yyyy HH:mm:ss").format(date)); … … 649 648 return tr("No gpx selected"); 650 649 651 lastNumMatched = matchGpxTrack(dateImgLst, selGpx.data, (long) (timezone * 3600) + delta); 650 final long offset_ms = ((long) (timezone * 3600) + delta) * 1000; // in milliseconds 651 lastNumMatched = matchGpxTrack(dateImgLst, selGpx.data, offset_ms); 652 652 653 653 return trn("<html>Matched <b>{0}</b> of <b>{1}</b> photo to GPX track.</html>", … … 746 746 Main.pref.put("geoimage.showThumbs", yLayer.useThumbs); 747 747 748 yLayer.useThumbs = cbShowThumbs.isSelected(); //FIXME748 yLayer.useThumbs = cbShowThumbs.isSelected(); 749 749 yLayer.loadThumbs(); 750 750 … … 955 955 956 956 // Init variables 957 long firstExifDate = imgs.get(0). time.getTime()/1000;957 long firstExifDate = imgs.get(0).getExifTime().getTime()/1000; 958 958 959 959 long firstGPXDate = -1; … … 1041 1041 ArrayList<ImageEntry> dateImgLst = new ArrayList<ImageEntry>(yLayer.data.size()); 1042 1042 for (ImageEntry e : yLayer.data) { 1043 if (e. time== null) {1043 if (e.getExifTime() == null) { 1044 1044 continue; 1045 1045 } 1046 1046 1047 if (e. exifCoor!= null) {1047 if (e.getExifCoor() != null) { 1048 1048 if (!exif) { 1049 1049 continue; … … 1051 1051 } 1052 1052 1053 if (e.isTagged() && e. exifCoor== null) {1053 if (e.isTagged() && e.getExifCoor() == null) { 1054 1054 if (!tagged) { 1055 1055 continue; … … 1062 1062 Collections.sort(dateImgLst, new Comparator<ImageEntry>() { 1063 1063 public int compare(ImageEntry arg0, ImageEntry arg1) { 1064 return arg0. time.compareTo(arg1.time);1064 return arg0.getExifTime().compareTo(arg1.getExifTime()); 1065 1065 } 1066 1066 }); … … 1082 1082 } 1083 1083 1084 private int matchGpxTrack(ArrayList<ImageEntry> dateImgLst, GpxData selectedGpx, long offset) { 1084 /** 1085 * Match a list of photos to a gpx track with a given offset. 1086 * All images need a exifTime attribute and the List must be sorted according to these times. 1087 */ 1088 private int matchGpxTrack(ArrayList<ImageEntry> images, GpxData selectedGpx, long offset) { 1085 1089 int ret = 0; 1086 1090 … … 1090 1094 for (GpxTrackSegment segment : trk.getSegments()) { 1091 1095 1092 long prev DateWp= 0;1096 long prevWpTime = 0; 1093 1097 WayPoint prevWp = null; 1094 1098 1095 1099 for (WayPoint curWp : segment.getWayPoints()) { 1096 1100 1097 String cur DateWpStr = (String) curWp.attr.get("time");1098 if (cur DateWpStr != null) {1101 String curWpTimeStr = (String) curWp.attr.get("time"); 1102 if (curWpTimeStr != null) { 1099 1103 1100 1104 try { 1101 long cur DateWp = dateParser.parse(curDateWpStr).getTime()/1000+ offset;1102 ret += matchPoints( dateImgLst, prevWp, prevDateWp, curWp, curDateWp);1105 long curWpTime = dateParser.parse(curWpTimeStr).getTime() + offset; 1106 ret += matchPoints(images, prevWp, prevWpTime, curWp, curWpTime, offset); 1103 1107 1104 1108 prevWp = curWp; 1105 prev DateWp = curDateWp;1109 prevWpTime = curWpTime; 1106 1110 1107 1111 } catch(ParseException e) { 1108 System.err.println("Error while parsing date \"" + cur DateWpStr + '"');1112 System.err.println("Error while parsing date \"" + curWpTimeStr + '"'); 1109 1113 e.printStackTrace(); 1110 1114 prevWp = null; 1111 prev DateWp= 0;1115 prevWpTime = 0; 1112 1116 } 1113 1117 } else { 1114 1118 prevWp = null; 1115 prev DateWp= 0;1119 prevWpTime = 0; 1116 1120 } 1117 1121 } … … 1121 1125 } 1122 1126 1123 private int matchPoints(ArrayList<ImageEntry> dateImgLst, WayPoint prevWp, long prevDateWp,1124 WayPoint curWp, long cur DateWp) {1127 private int matchPoints(ArrayList<ImageEntry> images, WayPoint prevWp, long prevWpTime, 1128 WayPoint curWp, long curWpTime, long offset) { 1125 1129 // Time between the track point and the previous one, 5 sec if first point, i.e. photos take 1126 1130 // 5 sec before the first track point can be assumed to be take at the starting position 1127 long interval = prev DateWp > 0 ? ((int)Math.abs(curDateWp - prevDateWp)) : 5;1131 long interval = prevWpTime > 0 ? ((long)Math.abs(curWpTime - prevWpTime)) : 5*1000; 1128 1132 int ret = 0; 1129 1133 1130 1134 // i is the index of the timewise last photo that has the same or earlier EXIF time 1131 int i = getLastIndexOfListBefore( dateImgLst, curDateWp);1135 int i = getLastIndexOfListBefore(images, curWpTime); 1132 1136 1133 1137 // no photos match … … 1142 1146 double distance = prevWp.getCoor().greatCircleDistance(curWp.getCoor()); 1143 1147 // This is in km/h, 3.6 * m/s 1144 if (cur DateWp > prevDateWp) {1145 speed = 3.6 * distance / (cur DateWp - prevDateWp);1148 if (curWpTime > prevWpTime) { 1149 speed = 3.6 * distance / (curWpTime - prevWpTime); 1146 1150 } 1147 1151 try { … … 1156 1160 // First trackpoint, then interval is set to five seconds, i.e. photos up to five seconds 1157 1161 // before the first point will be geotagged with the starting point 1158 if(prevDateWp == 0 || curDateWp <= prevDateWp) { 1159 while(i >= 0 && (dateImgLst.get(i).time.getTime()/1000) <= curDateWp 1160 && (dateImgLst.get(i).time.getTime()/1000) >= (curDateWp - interval)) { 1161 if(dateImgLst.get(i).tmp.getPos() == null) { 1162 dateImgLst.get(i).tmp.setCoor(curWp.getCoor()); 1163 dateImgLst.get(i).tmp.setSpeed(speed); 1164 dateImgLst.get(i).tmp.setElevation(curElevation); 1162 if(prevWpTime == 0 || curWpTime <= prevWpTime) { 1163 while (true) { 1164 if (i < 0) 1165 break; 1166 final ImageEntry curImg = images.get(i); 1167 if (curImg.getExifTime().getTime() > curWpTime 1168 || curImg.getExifTime().getTime() < curWpTime - interval) 1169 break; 1170 if(curImg.tmp.getPos() == null) { 1171 curImg.tmp.setPos(curWp.getCoor()); 1172 curImg.tmp.setSpeed(speed); 1173 curImg.tmp.setElevation(curElevation); 1174 curImg.tmp.setGpsTime(new Date(curImg.getExifTime().getTime() - offset)); 1165 1175 ret++; 1166 1176 } … … 1172 1182 // This code gives a simple linear interpolation of the coordinates between current and 1173 1183 // previous track point assuming a constant speed in between 1174 long imgDate; 1175 while(i >= 0 && (imgDate = dateImgLst.get(i).time.getTime()/1000) >= prevDateWp) { 1176 1177 if(dateImgLst.get(i).tmp.getPos() == null) { 1184 while (true) { 1185 if (i < 0) 1186 break; 1187 ImageEntry curImg = images.get(i); 1188 long imgTime = curImg.getExifTime().getTime(); 1189 if (imgTime < prevWpTime) 1190 break; 1191 1192 if(curImg.tmp.getPos() == null) { 1178 1193 // The values of timeDiff are between 0 and 1, it is not seconds but a dimensionless 1179 1194 // variable 1180 double timeDiff = (double)(imgDate - prevDateWp) / interval; 1181 dateImgLst.get(i).tmp.setCoor(prevWp.getCoor().interpolate(curWp.getCoor(), timeDiff)); 1182 dateImgLst.get(i).tmp.setSpeed(speed); 1183 1195 double timeDiff = (double)(imgTime - prevWpTime) / interval; 1196 curImg.tmp.setPos(prevWp.getCoor().interpolate(curWp.getCoor(), timeDiff)); 1197 curImg.tmp.setSpeed(speed); 1184 1198 if (curElevation != null && prevElevation != null) { 1185 dateImgLst.get(i).setElevation(prevElevation + (curElevation - prevElevation) * timeDiff); 1186 } 1199 curImg.setElevation(prevElevation + (curElevation - prevElevation) * timeDiff); 1200 } 1201 curImg.tmp.setGpsTime(new Date(curImg.getExifTime().getTime() - offset)); 1187 1202 1188 1203 ret++; … … 1193 1208 } 1194 1209 1195 private int getLastIndexOfListBefore(ArrayList<ImageEntry> dateImgLst, long searchedDate) {1196 int lstSize= dateImgLst.size();1210 private int getLastIndexOfListBefore(ArrayList<ImageEntry> images, long searchedTime) { 1211 int lstSize= images.size(); 1197 1212 1198 1213 // No photos or the first photo taken is later than the search period 1199 if(lstSize == 0 || searched Date < dateImgLst.get(0).time.getTime()/1000)1214 if(lstSize == 0 || searchedTime < images.get(0).getExifTime().getTime()) 1200 1215 return -1; 1201 1216 1202 1217 // The search period is later than the last photo 1203 if (searched Date > dateImgLst.get(lstSize - 1).time.getTime() / 1000)1218 if (searchedTime > images.get(lstSize - 1).getExifTime().getTime()) 1204 1219 return lstSize-1; 1205 1220 … … 1210 1225 while (endIndex - startIndex > 1) { 1211 1226 curIndex= (endIndex + startIndex) / 2; 1212 if (searched Date > dateImgLst.get(curIndex).time.getTime()/1000) {1227 if (searchedTime > images.get(curIndex).getExifTime().getTime()) { 1213 1228 startIndex= curIndex; 1214 1229 } else { … … 1216 1231 } 1217 1232 } 1218 if (searched Date < dateImgLst.get(endIndex).time.getTime()/1000)1233 if (searchedTime < images.get(endIndex).getExifTime().getTime()) 1219 1234 return startIndex; 1220 1235 1221 1236 // This final loop is to check if photos with the exact same EXIF time follows 1222 while ((endIndex < (lstSize-1)) && ( dateImgLst.get(endIndex).time.getTime()1223 == dateImgLst.get(endIndex + 1).time.getTime())) {1237 while ((endIndex < (lstSize-1)) && (images.get(endIndex).getExifTime().getTime() 1238 == images.get(endIndex + 1).getExifTime().getTime())) { 1224 1239 endIndex++; 1225 1240 } -
trunk/src/org/openstreetmap/josm/gui/layer/geoimage/GeoImageLayer.java
r2909 r2931 146 146 147 147 try { 148 e. time = ExifReader.readTime(f);148 e.setExifTime(ExifReader.readTime(f)); 149 149 } catch (ParseException e1) { 150 e. time = null;151 } 152 e. file = f;150 e.setExifTime(null); 151 } 152 e.setFile(f); 153 153 extractExif(e); 154 154 data.add(e); … … 313 313 entries.add(new JSeparator()); 314 314 entries.add(correlateItem); 315 if (!menuAdditions.isEmpty()) { 316 entries.add(new JSeparator()); 317 } 315 318 for (LayerMenuAddition addition : menuAdditions) { 316 319 entries.add(addition.getComponent(this)); … … 365 368 for (int i = data.size() - 2; i >= 0; i--) { 366 369 cur = data.get(i); 367 if (cur. file.equals(prev.file)) {370 if (cur.getFile().equals(prev.getFile())) { 368 371 data.remove(i); 369 372 } else { … … 505 508 double lon, lat; 506 509 507 Metadata metadata = JpegMetadataReader.readMetadata(e. file);510 Metadata metadata = JpegMetadataReader.readMetadata(e.getFile()); 508 511 Directory dir = metadata.getDirectory(GpsDirectory.class); 509 512 510 513 // longitude 511 514 512 Rational[] components = dir 513 .getRationalArray(GpsDirectory.TAG_GPS_LONGITUDE); 515 Rational[] components = dir.getRationalArray(GpsDirectory.TAG_GPS_LONGITUDE); 514 516 515 517 deg = components[0].intValue(); … … 539 541 // Store values 540 542 541 e.set Coor(new LatLon(lat, lon));542 e. exifCoor = e.getPos();543 e.setExifCoor(new LatLon(lat, lon)); 544 e.setPos(e.getExifCoor()); 543 545 544 546 } catch (CompoundException p) { 545 e. exifCoor = null;547 e.setExifCoor(null); 546 548 e.setPos(null); 547 549 } … … 607 609 .setButtonIcons(new String[] {"cancel.png", "dialogs/delete.png"}) 608 610 .setContent(new JLabel(tr("<html><h3>Delete the file {0} from disk?<p>The image file will be permanently lost!</h3></html>" 609 ,toDelete. file.getName()), ImageProvider.get("dialogs/geoimage/deletefromdisk"),SwingConstants.LEFT))611 ,toDelete.getFile().getName()), ImageProvider.get("dialogs/geoimage/deletefromdisk"),SwingConstants.LEFT)) 610 612 .toggleEnable("geoimage.deleteimagefromdisk") 611 613 .setCancelButton(1) … … 626 628 } 627 629 628 if (toDelete. file.delete()) {629 System.out.println("File "+toDelete. file.toString()+" deleted. ");630 if (toDelete.getFile().delete()) { 631 System.out.println("File "+toDelete.getFile().toString()+" deleted. "); 630 632 } else { 631 633 JOptionPane.showMessageDialog( -
trunk/src/org/openstreetmap/josm/gui/layer/geoimage/ImageEntry.java
r2904 r2931 18 18 19 19 final public class ImageEntry implements Comparable<ImageEntry>, Cloneable { 20 File file; 21 Date time; 22 LatLon exifCoor; 20 private File file; 21 private LatLon exifCoor; 22 private Date exifTime; 23 Image thumbnail; 23 24 25 /** The following values are computed from the correlation with the gpx track */ 24 26 private CachedLatLon pos; 25 27 /** Speed in kilometer per second */ … … 27 29 /** Elevation (altitude) in meters */ 28 30 private Double elevation; 29 30 Image thumbnail;31 /** The time after correlation with a gpx track */ 32 private Date gpsTime; 31 33 32 34 /** … … 40 42 ImageEntry tmp; 41 43 44 /** 45 * getter methods that refer to the temporary value 46 */ 42 47 public CachedLatLon getPos() { 43 48 if (tmp != null) … … 55 60 return elevation; 56 61 } 62 public Date getGpsTime() { 63 if (tmp != null) 64 return tmp.gpsTime; 65 return gpsTime; 66 } 67 68 /** 69 * other getter methods 70 */ 71 public File getFile() { 72 return file; 73 } 74 public Date getExifTime() { 75 return exifTime; 76 } 77 LatLon getExifCoor() { 78 return exifCoor; 79 } 80 /** 81 * setter methods 82 */ 57 83 public void setPos(CachedLatLon pos) { 58 84 this.pos = pos; 85 } 86 public void setPos(LatLon pos) { 87 this.pos = new CachedLatLon(pos); 59 88 } 60 89 public void setSpeed(Double speed) { … … 64 93 this.elevation = elevation; 65 94 } 66 67 public File getFile() { 68 return file; 95 void setFile(File file) { 96 this.file = file; 97 } 98 void setExifTime(Date exifTime) { 99 this.exifTime = exifTime; 100 } 101 void setGpsTime(Date gpsTime) { 102 this.gpsTime = gpsTime; 103 } 104 void setExifCoor(LatLon exifCoor) { 105 this.exifCoor = exifCoor; 69 106 } 70 107 … … 80 117 } 81 118 82 public void setCoor(LatLon latlon)83 {84 pos = new CachedLatLon(latlon);85 }86 87 119 public int compareTo(ImageEntry image) { 88 if ( time != null && image.time != null)89 return time.compareTo(image.time);90 else if ( time == null && image.time == null)120 if (exifTime != null && image.exifTime != null) 121 return exifTime.compareTo(image.exifTime); 122 else if (exifTime == null && image.exifTime == null) 91 123 return 0; 92 else if ( time == null)124 else if (exifTime == null) 93 125 return -1; 94 126 else … … 96 128 } 97 129 98 public void applyTmp() { 99 if (tmp != null) { 100 pos = tmp.pos; 101 speed = tmp.speed; 102 elevation = tmp.elevation; 103 tmp = null; 104 } 105 } 130 /** 131 * Make a fresh copy and save it in the temporary variable. 132 */ 106 133 public void cleanTmp() { 107 134 tmp = clone(); … … 110 137 } 111 138 139 /** 140 * Copy the values from the temporary variable to the main instance. 141 */ 142 public void applyTmp() { 143 if (tmp != null) { 144 pos = tmp.pos; 145 speed = tmp.speed; 146 elevation = tmp.elevation; 147 gpsTime = tmp.gpsTime; 148 tmp = null; 149 } 150 } 151 152 /** 153 * If it has been tagged i.e. matched to a gpx track or retrieved lat/lon from exif 154 */ 112 155 public boolean isTagged() { 113 156 return pos != null; … … 115 158 116 159 /** 117 * only partial info160 * String representation. (only partial info) 118 161 */ 119 162 @Override -
trunk/src/org/openstreetmap/josm/gui/layer/geoimage/ImageViewerDialog.java
r2909 r2931 14 14 import java.awt.GridBagLayout; 15 15 import java.awt.event.ActionEvent; 16 import java.awt.event.ActionListener;17 16 import java.awt.event.KeyEvent; 18 17 import java.awt.event.WindowEvent; … … 238 237 239 238 if (entry != null) { 240 imgDisplay.setImage(entry. file);241 setTitle("Geotagged Images" + (entry. file != null ? " - " + entry.file.getName() : ""));242 StringBuffer osd = new StringBuffer(entry. file != null ? entry.file.getName() : "");239 imgDisplay.setImage(entry.getFile()); 240 setTitle("Geotagged Images" + (entry.getFile() != null ? " - " + entry.getFile().getName() : "")); 241 StringBuffer osd = new StringBuffer(entry.getFile() != null ? entry.getFile().getName() : ""); 243 242 if (entry.getElevation() != null) { 244 243 osd.append(tr("\nAltitude: {0} m", entry.getElevation().longValue())); … … 250 249 // osd.append(tr("\nlat: {0}, lon: {1}", Double.toString(entry.getPos().lat()), Double.toString(entry.getPos().lon()))); 251 250 //} 251 //osd.append(tr("\nfile mtime: {0}", Long.toString(entry.getFile().lastModified()))); 252 //osd.append(tr("\nImage exif time: {0}", Long.toString(entry.getExifTime().getTime()))); 253 //if (entry.getGpsTime() != null) { 254 // osd.append(tr("\nImage gps time: {0}", Long.toString(entry.getGpsTime().getTime()))); 255 //} 256 252 257 imgDisplay.setOsdText(osd.toString()); 253 258 } else { -
trunk/src/org/openstreetmap/josm/gui/layer/geoimage/ThumbsLoader.java
r2662 r2931 72 72 73 73 private BufferedImage loadThumb(ImageEntry entry) { 74 final String cacheIdent = entry. file.toString()+":"+maxSize;74 final String cacheIdent = entry.getFile().toString()+":"+maxSize; 75 75 76 76 if (!cacheOff) { … … 82 82 } 83 83 84 Image img = Toolkit.getDefaultToolkit().createImage(entry. file.getPath());84 Image img = Toolkit.getDefaultToolkit().createImage(entry.getFile().getPath()); 85 85 tracker.addImage(img, 0); 86 86 try {
Note:
See TracChangeset
for help on using the changeset viewer.