Changeset 9726 in josm
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/org/openstreetmap/josm/gui/layer/geoimage/CorrelateGpxWithImages.java
r9698 r9726 80 80 import org.openstreetmap.josm.tools.GBC; 81 81 import org.openstreetmap.josm.tools.ImageProvider; 82 import org.openstreetmap.josm.tools.Pair; 82 83 import org.openstreetmap.josm.tools.Utils; 83 84 import org.openstreetmap.josm.tools.date.DateUtils; … … 1000 1001 } 1001 1002 1003 static class NoGpxTimestamps extends Exception { 1004 } 1005 1006 /** 1007 * Tries to auto-guess the timezone and offset. 1008 * 1009 * @param imgs the images to correlate 1010 * @param gpx the gpx track to correlate to 1011 * @return a pair of timezone (in hours) and offset (in seconds) 1012 * @throws IndexOutOfBoundsException when there are no images 1013 * @throws NoGpxTimestamps when the gpx track does not contain a timestamp 1014 */ 1015 static Pair<Double, Long> autoGuess(List<ImageEntry> imgs, GpxData gpx) throws IndexOutOfBoundsException, NoGpxTimestamps { 1016 1017 // Init variables 1018 long firstExifDate = imgs.get(0).getExifTime().getTime() / 1000; 1019 1020 long firstGPXDate = -1; 1021 // Finds first GPX point 1022 outer: for (GpxTrack trk : gpx.tracks) { 1023 for (GpxTrackSegment segment : trk.getSegments()) { 1024 for (WayPoint curWp : segment.getWayPoints()) { 1025 try { 1026 final Date parsedTime = curWp.setTimeFromAttribute(); 1027 if (parsedTime != null) { 1028 firstGPXDate = parsedTime.getTime() / 1000; 1029 break outer; 1030 } 1031 } catch (Exception e) { 1032 Main.warn(e); 1033 } 1034 } 1035 } 1036 } 1037 1038 if (firstGPXDate < 0) { 1039 throw new NoGpxTimestamps(); 1040 } 1041 1042 // seconds 1043 long diff = firstExifDate - firstGPXDate; 1044 1045 double diffInH = (double) diff / (60 * 60); // hours 1046 1047 // Find day difference 1048 int dayOffset = (int) Math.round(diffInH / 24); // days 1049 double tz = diff - dayOffset * 24 * 60 * 60L; // seconds 1050 1051 // In hours, rounded to two decimal places 1052 tz = (double) Math.round(tz * 100 / (60 * 60)) / 100; 1053 1054 // Due to imprecise clocks we might get a "+3:28" timezone, which should obviously be 3:30 with 1055 // -2 minutes offset. This determines the real timezone and finds offset. 1056 final double timezone = (double) Math.round(tz * 2) / 2; // hours, rounded to one decimal place 1057 final long delta = Math.round(diff - timezone * 60 * 60); // seconds 1058 return Pair.create(timezone, delta); 1059 } 1060 1002 1061 private class AutoGuessActionListener implements ActionListener { 1003 1062 … … 1011 1070 List<ImageEntry> imgs = getSortedImgList(); 1012 1071 1013 // no images found, exit 1014 if (imgs.isEmpty()) { 1072 try { 1073 final Pair<Double, Long> r = autoGuess(imgs, gpx); 1074 timezone = r.a; 1075 delta = r.b; 1076 } catch (IndexOutOfBoundsException ex) { 1015 1077 JOptionPane.showMessageDialog(Main.parent, 1016 1078 tr("The selected photos do not contain time information."), 1017 1079 tr("Photos do not contain time information"), JOptionPane.WARNING_MESSAGE); 1018 1080 return; 1019 } 1020 1021 // Init variables 1022 long firstExifDate = imgs.get(0).getExifTime().getTime()/1000; 1023 1024 long firstGPXDate = -1; 1025 // Finds first GPX point 1026 outer: for (GpxTrack trk : gpx.tracks) { 1027 for (GpxTrackSegment segment : trk.getSegments()) { 1028 for (WayPoint curWp : segment.getWayPoints()) { 1029 try { 1030 final Date parsedTime = curWp.setTimeFromAttribute(); 1031 if (parsedTime != null) { 1032 firstGPXDate = parsedTime.getTime(); 1033 break outer; 1034 } 1035 } catch (Exception e) { 1036 Main.warn(e); 1037 } 1038 } 1039 } 1040 } 1041 1042 // No GPX timestamps found, exit 1043 if (firstGPXDate < 0) { 1081 } catch (NoGpxTimestamps ex) { 1044 1082 JOptionPane.showMessageDialog(Main.parent, 1045 1083 tr("The selected GPX track does not contain timestamps. Please select another one."), … … 1047 1085 return; 1048 1086 } 1049 1050 // seconds1051 long diff = firstExifDate - firstGPXDate;1052 1053 double diffInH = (double) diff/(60*60); // hours1054 1055 // Find day difference1056 int dayOffset = (int) Math.round(diffInH / 24); // days1057 double tz = diff - dayOffset*24*60*60L; // seconds1058 1059 // In hours, rounded to two decimal places1060 tz = (double) Math.round(tz*100/(60*60)) / 100;1061 1062 // Due to imprecise clocks we might get a "+3:28" timezone, which should obviously be 3:30 with1063 // -2 minutes offset. This determines the real timezone and finds offset.1064 timezone = (double) Math.round(tz * 2)/2; // hours, rounded to one decimal place1065 delta = Math.round(diff - timezone*60*60); // seconds1066 1087 1067 1088 tfTimezone.getDocument().removeDocumentListener(statusBarUpdater); -
trunk/test/unit/org/openstreetmap/josm/gui/layer/geoimage/CorrelateGpxWithImagesTest.java
r9669 r9726 5 5 6 6 import java.util.Arrays; 7 import java.util.Collections; 7 8 import java.util.TimeZone; 8 9 … … 12 13 import org.openstreetmap.josm.data.gpx.GpxData; 13 14 import org.openstreetmap.josm.io.GpxReaderTest; 15 import org.openstreetmap.josm.tools.Pair; 14 16 import org.openstreetmap.josm.tools.date.DateUtils; 15 17 import org.openstreetmap.josm.tools.date.DateUtilsTest; … … 59 61 i2.getPos()); // interpolated 60 62 } 63 64 /** 65 * Tests automatic guessing of timezone/offset 66 * @throws Exception if an error occurs 67 */ 68 @Test 69 public void testAutoGuess() throws Exception { 70 final GpxData gpx = GpxReaderTest.parseGpxData("data_nodist/2094047.gpx"); 71 final ImageEntry i0 = new ImageEntry(); 72 i0.setExifTime(DateUtils.fromString("2016:01:03 11:59:54")); // 4 sec before start of GPX 73 i0.createTmp(); 74 assertEquals(Pair.create(0.0, -4L), CorrelateGpxWithImages.autoGuess(Collections.singletonList(i0), gpx)); 75 } 61 76 }
Note:
See TracChangeset
for help on using the changeset viewer.