Changeset 15045 in josm for trunk/src/org/openstreetmap
- Timestamp:
- 2019-05-04T14:17:27+02:00 (6 years ago)
- Location:
- trunk/src/org/openstreetmap/josm
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/org/openstreetmap/josm/gui/layer/geoimage/CorrelateGpxWithImages.java
r14981 r15045 29 29 import java.util.ArrayList; 30 30 import java.util.Arrays; 31 import java.util.Collection;32 31 import java.util.Collections; 33 32 import java.util.Comparator; … … 37 36 import java.util.List; 38 37 import java.util.Objects; 39 import java.util.Optional;40 38 import java.util.TimeZone; 41 39 import java.util.concurrent.TimeUnit; … … 108 106 * This class displays the window to select the GPX file and the offset (timezone + delta). 109 107 * Then it correlates the images of the layer with that GPX file. 108 * @since 2566 110 109 */ 111 110 public class CorrelateGpxWithImages extends AbstractAction { … … 541 540 */ 542 541 private class SetOffsetActionListener implements ActionListener { 543 544 @Override 545 public void actionPerformed(ActionEvent arg0) { 542 JCheckBox ckDst; 543 ImageDisplay imgDisp; 544 JLabel lbExifTime; 545 JosmTextField tfGpsTime; 546 547 class TimeZoneItem implements Comparable<TimeZoneItem> { 548 private final TimeZone tz; 549 private String rawString; 550 private String dstString; 551 552 TimeZoneItem(TimeZone tz) { 553 this.tz = tz; 554 } 555 556 public String getFormattedString() { 557 if (ckDst.isSelected()) { 558 return getDstString(); 559 } else { 560 return getRawString(); 561 } 562 } 563 564 public String getDstString() { 565 if (dstString == null) { 566 dstString = formatTimezone(tz.getRawOffset() + tz.getDSTSavings()); 567 } 568 return dstString; 569 } 570 571 public String getRawString() { 572 if (rawString == null) { 573 rawString = formatTimezone(tz.getRawOffset()); 574 } 575 return rawString; 576 } 577 578 public String getID() { 579 return tz.getID(); 580 } 581 582 @Override 583 public String toString() { 584 return getID() + " (" + getFormattedString() + ')'; 585 } 586 587 @Override 588 public int compareTo(TimeZoneItem o) { 589 return getID().compareTo(o.getID()); 590 } 591 592 private String formatTimezone(int offset) { 593 return new GpxTimezone((double) offset / TimeUnit.HOURS.toMillis(1)).formatTimezone(); 594 } 595 } 596 597 @Override 598 public void actionPerformed(ActionEvent e) { 546 599 SimpleDateFormat dateFormat = (SimpleDateFormat) DateUtils.getDateTimeFormat(DateFormat.SHORT, DateFormat.MEDIUM); 547 600 … … 552 605 BorderLayout.NORTH); 553 606 554 ImageDisplayimgDisp = new ImageDisplay();607 imgDisp = new ImageDisplay(); 555 608 imgDisp.setPreferredSize(new Dimension(300, 225)); 556 609 panel.add(imgDisp, BorderLayout.CENTER); … … 566 619 panelTf.add(new JLabel(tr("Photo time (from exif):")), gc); 567 620 568 JLabellbExifTime = new JLabel();621 lbExifTime = new JLabel(); 569 622 gc.gridx = 1; 570 623 gc.weightx = 1.0; … … 581 634 panelTf.add(new JLabel(tr("Gps time (read from the above photo): ")), gc); 582 635 583 JosmTextFieldtfGpsTime = new JosmTextField(12);636 tfGpsTime = new JosmTextField(12); 584 637 tfGpsTime.setEnabled(false); 585 638 tfGpsTime.setMinimumSize(new Dimension(155, tfGpsTime.getMinimumSize().height)); … … 599 652 gc.fill = GridBagConstraints.NONE; 600 653 gc.anchor = GridBagConstraints.WEST; 601 panelTf.add(new JLabel(tr("I am in the timezone of: ")), gc); 654 panelTf.add(new JLabel(tr("Photo taken in the timezone of: ")), gc); 655 656 ckDst = new JCheckBox(tr("Use daylight saving time (where applicable)"), Config.getPref().getBoolean("geoimage.timezoneid.dst")); 602 657 603 658 String[] tmp = TimeZone.getAvailableIDs(); 604 List<String> vtTimezones = new ArrayList<>(tmp.length); 659 List<TimeZoneItem> vtTimezones = new ArrayList<>(tmp.length); 660 661 String defTzStr = Config.getPref().get("geoimage.timezoneid", ""); 662 if (defTzStr.isEmpty()) { 663 defTzStr = TimeZone.getDefault().getID(); 664 } 665 TimeZoneItem defTzItem = null; 605 666 606 667 for (String tzStr : tmp) { 607 TimeZone tz = TimeZone.getTimeZone(tzStr); 608 609 String tzDesc = tzStr + " (" + 610 new GpxTimezone(((double) tz.getRawOffset()) / TimeUnit.HOURS.toMillis(1)).formatTimezone() + 611 ')'; 612 vtTimezones.add(tzDesc); 668 TimeZoneItem tz = new TimeZoneItem(TimeZone.getTimeZone(tzStr)); 669 vtTimezones.add(tz); 670 if (defTzStr.equals(tzStr)) { 671 defTzItem = tz; 672 } 613 673 } 614 674 615 675 Collections.sort(vtTimezones); 616 676 617 JosmComboBox<String> cbTimezones = new JosmComboBox<>(vtTimezones.toArray(new String[0])); 618 619 String tzId = Config.getPref().get("geoimage.timezoneid", ""); 620 TimeZone defaultTz; 621 if (tzId.isEmpty()) { 622 defaultTz = TimeZone.getDefault(); 623 } else { 624 defaultTz = TimeZone.getTimeZone(tzId); 625 } 626 627 cbTimezones.setSelectedItem(defaultTz.getID() + " (" + 628 new GpxTimezone(((double) defaultTz.getRawOffset()) / TimeUnit.HOURS.toMillis(1)).formatTimezone() + 629 ')'); 677 JosmComboBox<TimeZoneItem> cbTimezones = new JosmComboBox<>(vtTimezones.toArray(new TimeZoneItem[0])); 678 679 if (defTzItem != null) { 680 cbTimezones.setSelectedItem(defTzItem); 681 } 630 682 631 683 gc.gridx = 1; … … 635 687 panelTf.add(cbTimezones, gc); 636 688 689 gc.gridy = 3; 690 panelTf.add(ckDst, gc); 691 692 ckDst.addActionListener(x -> cbTimezones.repaint()); 693 637 694 panel.add(panelTf, BorderLayout.SOUTH); 638 695 … … 654 711 int index = imgList.getSelectedIndex(); 655 712 ImageEntry img = yLayer.getImageData().getImages().get(index); 656 imgDisp.setImage(img); 657 Date date = img.getExifTime(); 658 if (date != null) { 659 DateFormat df = DateUtils.getDateTimeFormat(DateFormat.SHORT, DateFormat.MEDIUM); 660 lbExifTime.setText(df.format(date)); 661 tfGpsTime.setText(df.format(date)); 662 tfGpsTime.setCaretPosition(tfGpsTime.getText().length()); 663 tfGpsTime.setEnabled(true); 664 tfGpsTime.requestFocus(); 665 } else { 666 lbExifTime.setText(tr("No date")); 667 tfGpsTime.setText(""); 668 tfGpsTime.setEnabled(false); 669 } 713 updateExifComponents(img); 670 714 }); 671 715 panelLst.add(new JScrollPane(imgList), BorderLayout.CENTER); … … 679 723 ImageEntry entry = new ImageEntry(fc.getSelectedFile()); 680 724 entry.extractExif(); 681 imgDisp.setImage(entry); 682 683 Date date = entry.getExifTime(); 684 if (date != null) { 685 lbExifTime.setText(DateUtils.getDateTimeFormat(DateFormat.SHORT, DateFormat.MEDIUM).format(date)); 686 tfGpsTime.setText(DateUtils.getDateFormat(DateFormat.SHORT).format(date)+' '); 687 tfGpsTime.setEnabled(true); 688 } else { 689 lbExifTime.setText(tr("No date")); 690 tfGpsTime.setText(""); 691 tfGpsTime.setEnabled(false); 692 } 725 updateExifComponents(entry); 693 726 }); 694 727 panelLst.add(openButton, BorderLayout.PAGE_END); … … 711 744 try { 712 745 delta = dateFormat.parse(lbExifTime.getText()).getTime() 713 - dateFormat.parse(tfGpsTime.getText()).getTime();714 } catch (ParseException e ) {746 - dateFormat.parse(tfGpsTime.getText()).getTime(); 747 } catch (ParseException ex) { 715 748 JOptionPane.showMessageDialog(MainApplication.getMainFrame(), tr("Error while parsing the date.\n" 716 749 + "Please use the requested format"), … … 719 752 } 720 753 721 String selectedTz = (String) cbTimezones.getSelectedItem(); 722 int pos = selectedTz.lastIndexOf('('); 723 tzId = selectedTz.substring(0, pos - 1); 724 String tzValue = selectedTz.substring(pos + 1, selectedTz.length() - 1); 725 726 Config.getPref().put("geoimage.timezoneid", tzId); 754 TimeZoneItem selectedTz = (TimeZoneItem) cbTimezones.getSelectedItem(); 755 756 Config.getPref().put("geoimage.timezoneid", selectedTz.getID()); 757 Config.getPref().putBoolean("geoimage.timezoneid.dst", ckDst.isSelected()); 727 758 tfOffset.setText(GpxTimeOffset.milliseconds(delta).formatOffset()); 728 tfTimezone.setText( tzValue);759 tfTimezone.setText(selectedTz.getFormattedString()); 729 760 730 761 isOk = true; … … 733 764 statusBarUpdater.updateStatusBar(); 734 765 yLayer.updateBufferAndRepaint(); 766 } 767 768 void updateExifComponents(ImageEntry img) { 769 imgDisp.setImage(img); 770 Date date = img.getExifTime(); 771 if (date != null) { 772 DateFormat df = DateUtils.getDateTimeFormat(DateFormat.SHORT, DateFormat.MEDIUM); 773 df.setTimeZone(DateUtils.UTC); // EXIF data does not contain timezone information and is read as UTC 774 lbExifTime.setText(df.format(date)); 775 tfGpsTime.setText(df.format(date)); 776 tfGpsTime.setCaretPosition(tfGpsTime.getText().length()); 777 tfGpsTime.setEnabled(true); 778 tfGpsTime.requestFocus(); 779 } else { 780 lbExifTime.setText(tr("No date")); 781 tfGpsTime.setText(""); 782 tfGpsTime.setEnabled(false); 783 } 735 784 } 736 785 } … … 769 818 public void actionPerformed(ActionEvent ae) { 770 819 // Construct the list of loaded GPX tracks 771 Collection<Layer> layerLst = MainApplication.getLayerManager().getLayers();772 820 gpxLst.clear(); 773 821 GpxDataWrapper defaultItem = null; 774 for (Layer cur : layerLst) { 775 if (cur instanceof GpxLayer) { 776 GpxLayer curGpx = (GpxLayer) cur; 777 GpxDataWrapper gdw = new GpxDataWrapper(curGpx.getName(), curGpx.data, curGpx.data.storageFile); 778 gpxLst.add(gdw); 779 if (cur == yLayer.gpxLayer) { 780 defaultItem = gdw; 781 } 822 for (GpxLayer cur : MainApplication.getLayerManager().getLayersOfType(GpxLayer.class)) { 823 GpxDataWrapper gdw = new GpxDataWrapper(cur.getName(), cur.data, cur.data.storageFile); 824 gpxLst.add(gdw); 825 if (cur == yLayer.gpxLayer) { 826 defaultItem = gdw; 782 827 } 783 828 } … … 801 846 } else { 802 847 // select first GPX track associated to a file 803 for (GpxDataWrapper item : gpxLst) { 804 if (item.file != null) { 805 cbGpx.setSelectedItem(item); 806 break; 807 } 808 } 848 gpxLst.stream().filter(i -> i.file != null).findFirst().ifPresent(cbGpx::setSelectedItem); 809 849 } 810 850 cbGpx.addActionListener(statusBarUpdaterWithRepaint); … … 818 858 819 859 try { 820 timezone = GpxTimezone.parseTimezone(Optional.ofNullable(Config.getPref().get("geoimage.timezone", "0:00")).orElse("0:00")); 860 String tz = Config.getPref().get("geoimage.timezone"); 861 if (!tz.isEmpty()) { 862 timezone = GpxTimezone.parseTimezone(tz); 863 } else { 864 timezone = new GpxTimezone(TimeUnit.MILLISECONDS.toMinutes(TimeZone.getDefault().getRawOffset()) / 60.); //hours is double 865 } 821 866 } catch (ParseException e) { 822 867 timezone = GpxTimezone.ZERO; … … 837 882 tfOffset.setText(delta.formatOffset()); 838 883 839 JButton buttonViewGpsPhoto = new JButton(tr("<html>Use photo of an accurate clock,<br>" 840 + "e.g. GPS receiver display</html>")); 884 JButton buttonViewGpsPhoto = new JButton(tr("<html>Use photo of an accurate clock,<br>e.g. GPS receiver display</html>")); 841 885 buttonViewGpsPhoto.setIcon(ImageProvider.get("clock")); 842 886 buttonViewGpsPhoto.addActionListener(new SetOffsetActionListener()); … … 1055 1099 return tr("No gpx selected"); 1056 1100 1057 final long offsetMs = ((long) (timezone.getHours() * TimeUnit.HOURS.toMillis( -1))) + delta.getMilliseconds(); // in milliseconds1101 final long offsetMs = ((long) (timezone.getHours() * TimeUnit.HOURS.toMillis(1))) + delta.getMilliseconds(); // in milliseconds 1058 1102 lastNumMatched = GpxImageCorrelation.matchGpxTrack(dateImgLst, selGpx.data, offsetMs, forceTags); 1059 1103 -
trunk/src/org/openstreetmap/josm/tools/date/DateUtils.java
r14434 r15045 7 7 import java.time.DateTimeException; 8 8 import java.time.Instant; 9 import java.time.ZoneId;10 9 import java.time.ZoneOffset; 11 10 import java.time.ZonedDateTime; … … 101 100 parsePart2(str, 17), 102 101 0, 103 // consider EXIF date in default timezone 104 checkLayout(str, "xxxx:xx:xx xx:xx:xx") ? ZoneId.systemDefault() : ZoneOffset.UTC 102 ZoneOffset.UTC 105 103 ); 106 104 if (str.length() == 22 || str.length() == 25) { … … 123 121 parsePart2(str, 17), 124 122 parsePart3(str, 20) * 1_000_000, 125 // consider EXIF date in default timezone 126 checkLayout(str, "xxxx:xx:xx xx:xx:xx.xxx") ? ZoneId.systemDefault() : ZoneOffset.UTC 123 ZoneOffset.UTC 127 124 ); 128 125 if (str.length() == 29) {
Note:
See TracChangeset
for help on using the changeset viewer.