Changeset 18045 in josm for trunk/src/org
- Timestamp:
- 2021-07-16T23:15:08+02:00 (3 years ago)
- Location:
- trunk/src/org/openstreetmap/josm/gui/layer/geoimage
- Files:
-
- 1 added
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/org/openstreetmap/josm/gui/layer/geoimage/AdvancedCorrelationSettingsDialog.java
r18044 r18045 52 52 * Constructs a new {@code AdvancedCorrelationSettingsDialog}. 53 53 * @param parent The parent element that will be used for position and maximum size 54 * @param forceTags 54 * @param forceTags Initial value of forced tagging of all pictures 55 55 */ 56 56 public AdvancedCorrelationSettingsDialog(Component parent, boolean forceTags) { -
trunk/src/org/openstreetmap/josm/gui/layer/geoimage/CorrelateGpxWithImages.java
r18044 r18045 7 7 import java.awt.BorderLayout; 8 8 import java.awt.Cursor; 9 import java.awt.Dimension;10 9 import java.awt.FlowLayout; 11 10 import java.awt.Font; … … 24 23 import java.beans.PropertyChangeListener; 25 24 import java.io.File; 26 import java.text.DateFormat;27 25 import java.text.ParseException; 28 import java.text.SimpleDateFormat;29 import java.time.Instant;30 import java.util.ArrayList;31 import java.util.Collections;32 26 import java.util.Comparator; 33 import java.util.Date;34 27 import java.util.List; 35 28 import java.util.TimeZone; … … 39 32 40 33 import javax.swing.AbstractAction; 41 import javax.swing.AbstractListModel;42 34 import javax.swing.BorderFactory; 43 35 import javax.swing.DefaultComboBoxModel; 44 36 import javax.swing.JButton; 45 37 import javax.swing.JCheckBox; 46 import javax.swing.JFileChooser;47 38 import javax.swing.JLabel; 48 import javax.swing.JList;49 39 import javax.swing.JOptionPane; 50 40 import javax.swing.JPanel; 51 import javax.swing.JScrollPane;52 41 import javax.swing.JSeparator; 53 import javax.swing.ListSelectionModel;54 42 import javax.swing.MutableComboBoxModel; 55 43 import javax.swing.SwingConstants; … … 57 45 import javax.swing.event.DocumentListener; 58 46 59 import org.openstreetmap.josm.actions.DiskAccessAction;60 47 import org.openstreetmap.josm.data.gpx.GpxData; 61 48 import org.openstreetmap.josm.data.gpx.GpxImageCorrelation; … … 67 54 import org.openstreetmap.josm.gui.ExtendedDialog; 68 55 import org.openstreetmap.josm.gui.MainApplication; 69 import org.openstreetmap.josm.gui.io.importexport.ImageImporter;70 56 import org.openstreetmap.josm.gui.layer.GpxLayer; 71 57 import org.openstreetmap.josm.gui.layer.Layer; … … 75 61 import org.openstreetmap.josm.gui.layer.LayerManager.LayerRemoveEvent; 76 62 import org.openstreetmap.josm.gui.layer.geoimage.AdjustTimezoneAndOffsetDialog.AdjustListener; 63 import org.openstreetmap.josm.gui.layer.geoimage.SynchronizeTimeFromPhotoDialog.TimeZoneItem; 77 64 import org.openstreetmap.josm.gui.layer.gpx.GpxDataHelper; 78 import org.openstreetmap.josm.gui.widgets.AbstractFileChooser;79 65 import org.openstreetmap.josm.gui.widgets.JosmComboBox; 80 66 import org.openstreetmap.josm.gui.widgets.JosmTextField; … … 85 71 import org.openstreetmap.josm.tools.Logging; 86 72 import org.openstreetmap.josm.tools.Pair; 87 import org.openstreetmap.josm.tools.date.DateUtils;88 73 89 74 /** … … 305 290 */ 306 291 private class SetOffsetActionListener implements ActionListener { 307 private JCheckBox ckDst;308 private ImageDisplay imgDisp;309 private JLabel lbExifTime;310 private JosmTextField tfGpsTime;311 312 class TimeZoneItem implements Comparable<TimeZoneItem> {313 private final TimeZone tz;314 private String rawString;315 private String dstString;316 317 TimeZoneItem(TimeZone tz) {318 this.tz = tz;319 }320 321 public String getFormattedString() {322 if (ckDst.isSelected()) {323 return getDstString();324 } else {325 return getRawString();326 }327 }328 329 public String getDstString() {330 if (dstString == null) {331 dstString = formatTimezone(tz.getRawOffset() + tz.getDSTSavings());332 }333 return dstString;334 }335 336 public String getRawString() {337 if (rawString == null) {338 rawString = formatTimezone(tz.getRawOffset());339 }340 return rawString;341 }342 343 public String getID() {344 return tz.getID();345 }346 347 @Override348 public String toString() {349 return getID() + " (" + getFormattedString() + ')';350 }351 352 @Override353 public int compareTo(TimeZoneItem o) {354 return getID().compareTo(o.getID());355 }356 357 private String formatTimezone(int offset) {358 return new GpxTimezone((double) offset / TimeUnit.HOURS.toMillis(1)).formatTimezone();359 }360 }361 362 private SimpleDateFormat getDateTimeFormat() {363 return (SimpleDateFormat) DateUtils.getDateTimeFormat(DateFormat.SHORT, DateFormat.MEDIUM);364 }365 292 366 293 @Override 367 294 public void actionPerformed(ActionEvent e) { 368 SimpleDateFormat dateFormat = getDateTimeFormat();369 370 JPanel panel = new JPanel(new BorderLayout());371 panel.add(new JLabel(tr("<html>Take a photo of your GPS receiver while it displays the time.<br>"372 + "Display that photo here.<br>"373 + "And then, simply capture the time you read on the photo and select a timezone<hr></html>")),374 BorderLayout.NORTH);375 376 imgDisp = new ImageDisplay();377 imgDisp.setPreferredSize(new Dimension(300, 225));378 panel.add(imgDisp, BorderLayout.CENTER);379 380 JPanel panelTf = new JPanel(new GridBagLayout());381 382 GridBagConstraints gc = new GridBagConstraints();383 gc.gridx = gc.gridy = 0;384 gc.gridwidth = gc.gridheight = 1;385 gc.weightx = gc.weighty = 0.0;386 gc.fill = GridBagConstraints.NONE;387 gc.anchor = GridBagConstraints.LINE_START;388 panelTf.add(new JLabel(tr("Photo time (from exif):")), gc);389 390 lbExifTime = new JLabel();391 gc.gridx = 1;392 gc.weightx = 1.0;393 gc.fill = GridBagConstraints.HORIZONTAL;394 gc.gridwidth = 2;395 panelTf.add(lbExifTime, gc);396 397 gc.gridx = 0;398 gc.gridy = 1;399 gc.gridwidth = gc.gridheight = 1;400 gc.weightx = gc.weighty = 0.0;401 gc.fill = GridBagConstraints.NONE;402 gc.anchor = GridBagConstraints.LINE_START;403 panelTf.add(new JLabel(tr("Gps time (read from the above photo): ")), gc);404 405 tfGpsTime = new JosmTextField(12);406 tfGpsTime.setEnabled(false);407 tfGpsTime.setMinimumSize(new Dimension(155, tfGpsTime.getMinimumSize().height));408 gc.gridx = 1;409 gc.weightx = 1.0;410 gc.fill = GridBagConstraints.HORIZONTAL;411 panelTf.add(tfGpsTime, gc);412 413 gc.gridx = 2;414 gc.weightx = 0.2;415 panelTf.add(new JLabel(" ["+dateFormat.toLocalizedPattern()+']'), gc);416 417 gc.gridx = 0;418 gc.gridy = 2;419 gc.gridwidth = gc.gridheight = 1;420 gc.weightx = gc.weighty = 0.0;421 gc.fill = GridBagConstraints.NONE;422 gc.anchor = GridBagConstraints.LINE_START;423 panelTf.add(new JLabel(tr("Photo taken in the timezone of: ")), gc);424 425 ckDst = new JCheckBox(tr("Use daylight saving time (where applicable)"), Config.getPref().getBoolean("geoimage.timezoneid.dst"));426 427 String[] tmp = TimeZone.getAvailableIDs();428 List<TimeZoneItem> vtTimezones = new ArrayList<>(tmp.length);429 430 String defTzStr = Config.getPref().get("geoimage.timezoneid", "");431 if (defTzStr.isEmpty()) {432 defTzStr = TimeZone.getDefault().getID();433 }434 TimeZoneItem defTzItem = null;435 436 for (String tzStr : tmp) {437 TimeZoneItem tz = new TimeZoneItem(TimeZone.getTimeZone(tzStr));438 vtTimezones.add(tz);439 if (defTzStr.equals(tzStr)) {440 defTzItem = tz;441 }442 }443 444 Collections.sort(vtTimezones);445 446 JosmComboBox<TimeZoneItem> cbTimezones = new JosmComboBox<>(vtTimezones.toArray(new TimeZoneItem[0]));447 448 if (defTzItem != null) {449 cbTimezones.setSelectedItem(defTzItem);450 }451 452 gc.gridx = 1;453 gc.weightx = 1.0;454 gc.gridwidth = 2;455 gc.fill = GridBagConstraints.HORIZONTAL;456 panelTf.add(cbTimezones, gc);457 458 gc.gridy = 3;459 panelTf.add(ckDst, gc);460 461 ckDst.addActionListener(x -> cbTimezones.repaint());462 463 panel.add(panelTf, BorderLayout.SOUTH);464 465 JPanel panelLst = new JPanel(new BorderLayout());466 467 JList<String> imgList = new JList<>(new AbstractListModel<String>() {468 @Override469 public String getElementAt(int i) {470 return yLayer.getImageData().getImages().get(i).getDisplayName();471 }472 473 @Override474 public int getSize() {475 return yLayer.getImageData().getImages().size();476 }477 });478 imgList.getSelectionModel().setSelectionMode(ListSelectionModel.SINGLE_SELECTION);479 imgList.getSelectionModel().addListSelectionListener(evt -> {480 int index = imgList.getSelectedIndex();481 ImageEntry img = yLayer.getImageData().getImages().get(index);482 updateExifComponents(img);483 });484 panelLst.add(new JScrollPane(imgList), BorderLayout.CENTER);485 486 JButton openButton = new JButton(tr("Open another photo"));487 openButton.addActionListener(ae -> {488 AbstractFileChooser fc = DiskAccessAction.createAndOpenFileChooser(true, false, null,489 ImageImporter.FILE_FILTER_WITH_FOLDERS, JFileChooser.FILES_ONLY, "geoimage.lastdirectory");490 if (fc == null)491 return;492 ImageEntry entry = new ImageEntry(fc.getSelectedFile());493 entry.extractExif();494 updateExifComponents(entry);495 });496 panelLst.add(openButton, BorderLayout.PAGE_END);497 498 panel.add(panelLst, BorderLayout.LINE_START);499 500 295 boolean isOk = false; 501 296 while (!isOk) { 502 int answer = JOptionPane.showConfirmDialog( 503 MainApplication.getMainFrame(), panel, 504 tr("Synchronize time from a photo of the GPS receiver"), 505 JOptionPane.OK_CANCEL_OPTION, 506 JOptionPane.QUESTION_MESSAGE 507 ); 508 if (answer != JOptionPane.OK_OPTION) 297 SynchronizeTimeFromPhotoDialog ed = new SynchronizeTimeFromPhotoDialog( 298 MainApplication.getMainFrame(), yLayer.getImageData().getImages()); 299 int answer = ed.showDialog().getValue(); 300 if (answer != 1) 509 301 return; 510 302 … … 512 304 513 305 try { 514 delta = dateFormat.parse(lbExifTime.getText()).getTime() 515 - dateFormat.parse(tfGpsTime.getText()).getTime(); 306 delta = ed.getDelta(); 516 307 } catch (ParseException ex) { 517 308 JOptionPane.showMessageDialog(MainApplication.getMainFrame(), tr("Error while parsing the date.\n" … … 521 312 } 522 313 523 TimeZoneItem selectedTz = (TimeZoneItem) cbTimezones.getSelectedItem();314 TimeZoneItem selectedTz = ed.getTimeZoneItem(); 524 315 525 316 Config.getPref().put("geoimage.timezoneid", selectedTz.getID()); 526 Config.getPref().putBoolean("geoimage.timezoneid.dst", ckDst.isSelected());317 Config.getPref().putBoolean("geoimage.timezoneid.dst", ed.isDstSelected()); 527 318 tfOffset.setText(GpxTimeOffset.milliseconds(delta).formatOffset()); 528 319 tfTimezone.setText(selectedTz.getFormattedString()); 529 320 530 321 isOk = true; 531 532 322 } 533 323 statusBarUpdater.matchAndUpdateStatusBar(); 534 324 yLayer.updateBufferAndRepaint(); 535 }536 537 void updateExifComponents(ImageEntry img) {538 imgDisp.setImage(img);539 Instant date = img.getExifInstant();540 if (date != null) {541 DateFormat df = getDateTimeFormat();542 df.setTimeZone(DateUtils.UTC); // EXIF data does not contain timezone information and is read as UTC543 lbExifTime.setText(df.format(Date.from(date)));544 tfGpsTime.setText(df.format(Date.from(date)));545 tfGpsTime.setCaretPosition(tfGpsTime.getText().length());546 tfGpsTime.setEnabled(true);547 tfGpsTime.requestFocus();548 } else {549 lbExifTime.setText(tr("No date"));550 tfGpsTime.setText("");551 tfGpsTime.setEnabled(false);552 }553 325 } 554 326 }
Note:
See TracChangeset
for help on using the changeset viewer.