Changeset 2931 in josm for trunk/src/org/openstreetmap/josm/gui/layer/geoimage/CorrelateGpxWithImages.java
- Timestamp:
- 03.02.2010 09:48:51 (2 years ago)
- File:
-
- 1 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 }
Note: See TracChangeset
for help on using the changeset viewer.
