Changeset 31350 in osm for applications


Ignore:
Timestamp:
2015-07-07T16:07:45+02:00 (9 years ago)
Author:
nokutu
Message:

Now the timezone to show the image cration time is taken from the System settings. Also, changed indentation to 2 and new lines to UNIX style.

Location:
applications/editors/josm/plugins/mapillary/src/org/openstreetmap/josm/plugins/mapillary
Files:
38 edited

Legend:

Unmodified
Added
Removed
  • applications/editors/josm/plugins/mapillary/src/org/openstreetmap/josm/plugins/mapillary/MapillaryAbstractImage.java

    r31333 r31350  
    55import java.text.SimpleDateFormat;
    66import java.util.Calendar;
    7 import java.util.TimeZone;
    87import java.util.concurrent.locks.Lock;
    98import java.util.concurrent.locks.ReentrantLock;
     
    1514 * Abstract superclass for all image objects. At the moment there is just 2,
    1615 * {@code MapillaryImportedImage} and {@code MapillaryImage}.
    17  * 
     16 *
    1817 * @author nokutu
    1918 *
     
    2120public abstract class MapillaryAbstractImage {
    2221
    23     public static Lock lock = new ReentrantLock();
    24 
    25     /** The time the image was captured, in Epoch format */
    26     private long capturedAt;
    27     /** Position of the picture */
    28     public final LatLon latLon;
    29     /** Direction of the picture */
    30     public final double ca;
    31     public boolean isModified = false;
    32     /** Temporal position of the picture until it is uploaded */
    33     public LatLon tempLatLon;
    34     /**
    35      * When the object is being dragged in the map, the temporal position is
    36      * stored here
    37      */
    38     public LatLon movingLatLon;
    39     /** Temporal direction of the picture until it is uploaded */
    40     public double tempCa;
    41     /**
    42      * When the object direction is being moved in the map, the temporal
    43      * direction is stored here
    44      */
    45     protected double movingCa;
    46     private boolean visible;
    47 
    48     public MapillaryAbstractImage(double lat, double lon, double ca) {
    49         this.latLon = new LatLon(lat, lon);
    50         this.tempLatLon = this.latLon;
    51         this.movingLatLon = this.latLon;
    52         this.ca = ca;
    53         this.tempCa = ca;
    54         this.movingCa = ca;
    55         this.visible = true;
     22  public static Lock lock = new ReentrantLock();
     23
     24  /** The time the image was captured, in Epoch format */
     25  private long capturedAt;
     26  /** Position of the picture */
     27  public final LatLon latLon;
     28  /** Direction of the picture */
     29  public final double ca;
     30  public boolean isModified = false;
     31  /** Temporal position of the picture until it is uploaded */
     32  public LatLon tempLatLon;
     33  /**
     34   * When the object is being dragged in the map, the temporal position is
     35   * stored here
     36   */
     37  public LatLon movingLatLon;
     38  /** Temporal direction of the picture until it is uploaded */
     39  public double tempCa;
     40  /**
     41   * When the object direction is being moved in the map, the temporal direction
     42   * is stored here
     43   */
     44  protected double movingCa;
     45  private boolean visible;
     46
     47  public MapillaryAbstractImage(double lat, double lon, double ca) {
     48    this.latLon = new LatLon(lat, lon);
     49    this.tempLatLon = this.latLon;
     50    this.movingLatLon = this.latLon;
     51    this.ca = ca;
     52    this.tempCa = ca;
     53    this.movingCa = ca;
     54    this.visible = true;
     55  }
     56
     57  /**
     58   * Returns whether the object has been modified or not.
     59   *
     60   * @return true if the object has been modified; false otherwise.
     61   */
     62  public boolean isModified() {
     63    return this.isModified;
     64  }
     65
     66  /**
     67   * Returns a LatLon object containing the current coordinates of the object.
     68   * When you are dragging the image this changes.
     69   *
     70   * @return The LatLon object with the position of the object.
     71   */
     72  public LatLon getLatLon() {
     73    return movingLatLon;
     74  }
     75
     76  /**
     77   * Returns whether the image is visible on the map or not.
     78   *
     79   * @return True if the image is visible; false otherwise.
     80   */
     81  public boolean isVisible() {
     82    return visible;
     83  }
     84
     85  public void setVisible(boolean visible) {
     86    this.visible = visible;
     87  }
     88
     89  /**
     90   * Returns the last fixed coordinates of the object.
     91   *
     92   * @return A LatLon object containing.
     93   */
     94  public LatLon getTempLatLon() {
     95    return tempLatLon;
     96  }
     97
     98  /**
     99   * Moves the image temporally to another position
     100   *
     101   * @param x
     102   *          The movement of the image in longitude units.
     103   * @param y
     104   *          The movement of the image in latitude units.
     105   */
     106  public void move(double x, double y) {
     107    this.movingLatLon = new LatLon(this.tempLatLon.getY() + y,
     108        this.tempLatLon.getX() + x);
     109    this.isModified = true;
     110  }
     111
     112  /**
     113   * Turns the image direction.
     114   *
     115   * @param ca
     116   *          The angle the image is moving.
     117   */
     118  public void turn(double ca) {
     119    this.movingCa = this.tempCa + ca;
     120    this.isModified = true;
     121  }
     122
     123  /**
     124   * Called when the mouse button is released, meaning that the picture has
     125   * stopped being dragged.
     126   */
     127  public void stopMoving() {
     128    this.tempLatLon = this.movingLatLon;
     129    this.tempCa = this.movingCa;
     130  }
     131
     132  /**
     133   * Returns the direction towards the image has been taken.
     134   *
     135   * @return The direction of the image (0 means north and goes clockwise).
     136   */
     137  public double getCa() {
     138    return movingCa;
     139  }
     140
     141  /**
     142   * Returns the last fixed direction of the object.
     143   *
     144   * @return The last fixed direction of the object. 0 means north.
     145   */
     146  public double getTempCa() {
     147    return tempCa;
     148  }
     149
     150  /**
     151   * Returns the date the picture was taken in DMY format.
     152   *
     153   * @return A String object containing the date when the picture was taken.
     154   */
     155  public String getDate() {
     156    String format = "";
     157    if (Main.pref.getBoolean("iso.dates"))
     158      format += "yyyy-MM-dd";
     159    else
     160      format += "dd/MM/yyyy";
     161    if (Main.pref.getBoolean("mapillary.display-hour", true)) {
     162      if (Main.pref.getBoolean("mapillary.format-24"))
     163        format += " - HH:mm:ss (z)";
     164      else
     165        format += " - h:mm:ss a (z)";
    56166    }
    57 
    58     /**
    59      * Returns whether the object has been modified or not.
    60      *
    61      * @return true if the object has been modified; false otherwise.
    62      */
    63     public boolean isModified() {
    64         return this.isModified;
     167    return getDate(format);
     168  }
     169
     170  public void setCapturedAt(long capturedAt) {
     171    this.capturedAt = capturedAt;
     172  }
     173
     174  public long getCapturedAt() {
     175    return capturedAt;
     176  }
     177
     178  /**
     179   * Returns the date the picture was taken in the given format.
     180   *
     181   * @param format
     182   * @return
     183   */
     184  public String getDate(String format) {
     185    Date date = new Date(getCapturedAt());
     186
     187    SimpleDateFormat formatter = new SimpleDateFormat(format);
     188    formatter.setTimeZone(Calendar.getInstance().getTimeZone());
     189    return formatter.format(date);
     190  }
     191
     192  /**
     193   * Parses a string with a given format and returns the Epoch time.
     194   *
     195   * @param date
     196   *          The string containing the date.
     197   * @param format
     198   *          The format of the date.
     199   * @return The date in Epoch format.
     200   */
     201  public long getEpoch(String date, String format) {
     202
     203    SimpleDateFormat formatter = new SimpleDateFormat(format);
     204    try {
     205      Date dateTime = (Date) formatter.parse(date);
     206      return dateTime.getTime();
     207    } catch (ParseException e) {
     208      Main.error(e);
    65209    }
    66 
    67     /**
    68      * Returns a LatLon object containing the current coordinates of the object.
    69      * When you are dragging the image this changes.
    70      *
    71      * @return The LatLon object with the position of the object.
    72      */
    73     public LatLon getLatLon() {
    74         return movingLatLon;
    75     }
    76 
    77     /**
    78      * Returns whether the image is visible on the map or not.
    79      *
    80      * @return True if the image is visible; false otherwise.
    81      */
    82     public boolean isVisible() {
    83         return visible;
    84     }
    85 
    86     public void setVisible(boolean visible) {
    87         this.visible = visible;
    88     }
    89 
    90     /**
    91      * Returns the last fixed coordinates of the object.
    92      *
    93      * @return A LatLon object containing.
    94      */
    95     public LatLon getTempLatLon() {
    96         return tempLatLon;
    97     }
    98 
    99     /**
    100      * Moves the image temporally to another position
    101      *
    102      * @param x
    103      *            The movement of the image in longitude units.
    104      * @param y
    105      *            The movement of the image in latitude units.
    106      */
    107     public void move(double x, double y) {
    108         this.movingLatLon = new LatLon(this.tempLatLon.getY() + y,
    109                 this.tempLatLon.getX() + x);
    110         this.isModified = true;
    111     }
    112 
    113     /**
    114      * Turns the image direction.
    115      *
    116      * @param ca
    117      *            The angle the image is moving.
    118      */
    119     public void turn(double ca) {
    120         this.movingCa = this.tempCa + ca;
    121         this.isModified = true;
    122     }
    123 
    124     /**
    125      * Called when the mouse button is released, meaning that the picture has
    126      * stopped being dragged.
    127      */
    128     public void stopMoving() {
    129         this.tempLatLon = this.movingLatLon;
    130         this.tempCa = this.movingCa;
    131     }
    132 
    133     /**
    134      * Returns the direction towards the image has been taken.
    135      *
    136      * @return The direction of the image (0 means north and goes clockwise).
    137      */
    138     public double getCa() {
    139         return movingCa;
    140     }
    141 
    142     /**
    143      * Returns the last fixed direction of the object.
    144      *
    145      * @return The last fixed direction of the object. 0 means north.
    146      */
    147     public double getTempCa() {
    148         return tempCa;
    149     }
    150 
    151     /**
    152      * Returns the date the picture was taken in DMY format.
    153      *
    154      * @return A String object containing the date when the picture was taken.
    155      */
    156     public String getDate() {
    157         String format = "";
    158         if (Main.pref.getBoolean("iso.dates"))
    159             format += "yyyy-MM-dd";
    160         else
    161             format += "dd/MM/yyyy";
    162         if (Main.pref.getBoolean("mapillary.display-hour", true)) {
    163             if (Main.pref.getBoolean("mapillary.format-24"))
    164                 format += " - HH:mm:ss (z)";
    165             else
    166                 format += " - h:mm:ss a (z)";
    167         }
    168         return getDate(format);
    169     }
    170 
    171     public void setCapturedAt(long capturedAt) {
    172         this.capturedAt = capturedAt;
    173     }
    174 
    175     public long getCapturedAt() {
    176         return capturedAt;
    177     }
    178 
    179     /**
    180      * Returns the date the picture was taken in the given format.
    181      *
    182      * @param format
    183      * @return
    184      */
    185     public String getDate(String format) {
    186         Date date = new Date(getCapturedAt());
    187 
    188         SimpleDateFormat formatter = new SimpleDateFormat(format);
    189         formatter.setTimeZone(TimeZone.getTimeZone("GMT"));
    190         return formatter.format(date);
    191     }
    192 
    193     /**
    194      * Parses a string with a given format and returns the Epoch time.
    195      *
    196      * @param date
    197      *            The string containing the date.
    198      * @param format
    199      *            The format of the date.
    200      * @return The date in Epoch format.
    201      */
    202     public long getEpoch(String date, String format) {
    203 
    204         SimpleDateFormat formatter = new SimpleDateFormat(format);
    205         try {
    206             Date dateTime = (Date) formatter.parse(date);
    207             return dateTime.getTime();
    208         } catch (ParseException e) {
    209             Main.error(e);
    210         }
    211         return currentTime();
    212     }
    213 
    214     /**
    215      * Returns current time in Epoch format
    216      *
    217      * @return The current date in Epoch format.
    218      */
    219     private long currentTime() {
    220         Calendar cal = Calendar.getInstance();
    221         return cal.getTimeInMillis();
    222     }
     210    return currentTime();
     211  }
     212
     213  /**
     214   * Returns current time in Epoch format
     215   *
     216   * @return The current date in Epoch format.
     217   */
     218  private long currentTime() {
     219    Calendar cal = Calendar.getInstance();
     220    return cal.getTimeInMillis();
     221  }
    223222}
  • applications/editors/josm/plugins/mapillary/src/org/openstreetmap/josm/plugins/mapillary/MapillaryData.java

    r31341 r31350  
    2020 */
    2121public class MapillaryData implements ICachedLoaderListener {
    22     public volatile static MapillaryData INSTANCE;
    23     public static boolean TEST_MODE = false;
    24 
    25     private final List<MapillaryAbstractImage> images;
    26     private MapillaryAbstractImage selectedImage;
    27     /** The image under the cursor */
    28     private MapillaryAbstractImage highlightedImage;
    29     private final List<MapillaryAbstractImage> multiSelectedImages;
    30 
    31     private List<MapillaryDataListener> listeners = new ArrayList<>();
    32 
    33     public MapillaryData() {
    34         images = new CopyOnWriteArrayList<>();
    35         multiSelectedImages = new ArrayList<>();
    36         selectedImage = null;
    37     }
    38 
    39     public static MapillaryData getInstance() {
    40         if (INSTANCE == null) {
    41             INSTANCE = new MapillaryData();
     22  public volatile static MapillaryData INSTANCE;
     23  public static boolean TEST_MODE = false;
     24
     25  private final List<MapillaryAbstractImage> images;
     26  private MapillaryAbstractImage selectedImage;
     27  /** The image under the cursor */
     28  private MapillaryAbstractImage highlightedImage;
     29  private final List<MapillaryAbstractImage> multiSelectedImages;
     30
     31  private List<MapillaryDataListener> listeners = new ArrayList<>();
     32
     33  public MapillaryData() {
     34    images = new CopyOnWriteArrayList<>();
     35    multiSelectedImages = new ArrayList<>();
     36    selectedImage = null;
     37  }
     38
     39  public static MapillaryData getInstance() {
     40    if (INSTANCE == null) {
     41      INSTANCE = new MapillaryData();
     42    }
     43    return INSTANCE;
     44  }
     45
     46  /**
     47   * Adds a set of MapillaryImages to the object, and then repaints mapView.
     48   *
     49   * @param images
     50   *          The set of images to be added.
     51   */
     52  public synchronized void add(List<MapillaryAbstractImage> images) {
     53    for (MapillaryAbstractImage image : images) {
     54      add(image);
     55    }
     56  }
     57
     58  /**
     59   * Adds an MapillaryImage to the object, and then repaints mapView.
     60   *
     61   * @param image
     62   *          The image to be added.
     63   */
     64  public synchronized void add(MapillaryAbstractImage image) {
     65    if (!images.contains(image)) {
     66      this.images.add(image);
     67    }
     68    dataUpdated();
     69    fireImagesAdded();
     70  }
     71
     72  public void addListener(MapillaryDataListener lis) {
     73    listeners.add(lis);
     74  }
     75
     76  public void removeListener(MapillaryDataListener lis) {
     77    listeners.remove(lis);
     78  }
     79
     80  /**
     81   * Adds a set of MapillaryImages to the object, but doesn't repaint mapView.
     82   * This is needed for concurrency.
     83   *
     84   * @param images
     85   *          The set of images to be added.
     86   */
     87  public synchronized void addWithoutUpdate(List<MapillaryAbstractImage> images) {
     88    for (MapillaryAbstractImage image : images) {
     89      addWithoutUpdate(image);
     90    }
     91  }
     92
     93  /**
     94   * Highlights the image under the cursor.
     95   *
     96   * @param image
     97   *          The image under the cursor.
     98   */
     99  public void setHighlightedImage(MapillaryAbstractImage image) {
     100    highlightedImage = image;
     101  }
     102
     103  /**
     104   * Returns the image under the mouse cursor.
     105   *
     106   * @return The image under the mouse cursor.
     107   */
     108  public MapillaryAbstractImage getHoveredImage() {
     109    return highlightedImage;
     110  }
     111
     112  /**
     113   * Adds a MapillaryImage to the object, but doesn't repaint mapView. This is
     114   * needed for concurrency.
     115   *
     116   * @param image
     117   *          The image to be added.
     118   */
     119  public synchronized void addWithoutUpdate(MapillaryAbstractImage image) {
     120    if (!images.contains(image)) {
     121      this.images.add(image);
     122    }
     123    fireImagesAdded();
     124  }
     125
     126  /**
     127   * Repaints mapView object.
     128   */
     129  public synchronized void dataUpdated() {
     130    if (!TEST_MODE)
     131      Main.map.mapView.repaint();
     132  }
     133
     134  /**
     135   * Returns a List containing all images.
     136   *
     137   * @return A List object containing all images.
     138   */
     139  public List<MapillaryAbstractImage> getImages() {
     140    return images;
     141  }
     142
     143  /**
     144   * Returns the MapillaryImage object that is currently selected.
     145   *
     146   * @return The selected MapillaryImage object.
     147   */
     148  public MapillaryAbstractImage getSelectedImage() {
     149    return selectedImage;
     150  }
     151
     152  private void fireImagesAdded() {
     153    if (listeners.isEmpty())
     154      return;
     155    for (MapillaryDataListener lis : listeners)
     156      lis.imagesAdded();
     157  }
     158
     159  /**
     160   * If the selected MapillaryImage is part of a MapillarySequence then the
     161   * following visible MapillaryImage is selected. In case there is none, does
     162   * nothing.
     163   */
     164  public void selectNext() {
     165    if (getSelectedImage() instanceof MapillaryImage) {
     166      if (getSelectedImage() == null)
     167        return;
     168      if (((MapillaryImage) getSelectedImage()).getSequence() == null)
     169        return;
     170      if (selectedImage instanceof MapillaryImage
     171          && ((MapillaryImage) selectedImage).getSequence() != null) {
     172        MapillaryImage tempImage = (MapillaryImage) selectedImage;
     173        while (tempImage.next() != null) {
     174          tempImage = tempImage.next();
     175          if (tempImage.isVisible()) {
     176            setSelectedImage(tempImage,
     177                Main.pref.getBoolean("mapillary.move-to-picture", true));
     178            break;
     179          }
    42180        }
    43         return INSTANCE;
    44     }
    45 
    46     /**
    47      * Adds a set of MapillaryImages to the object, and then repaints mapView.
    48      *
    49      * @param images
    50      *            The set of images to be added.
    51      */
    52     public synchronized void add(List<MapillaryAbstractImage> images) {
    53         for (MapillaryAbstractImage image : images) {
    54             add(image);
     181      }
     182    }
     183  }
     184
     185  /**
     186   * If the selected MapillaryImage is part of a MapillarySequence then the
     187   * previous visible MapillaryImage is selected. In case there is none, does
     188   * nothing.
     189   */
     190  public void selectPrevious() {
     191    if (getSelectedImage() instanceof MapillaryImage) {
     192      if (getSelectedImage() == null)
     193        return;
     194      if (((MapillaryImage) getSelectedImage()).getSequence() == null)
     195        throw new IllegalStateException();
     196      if (selectedImage instanceof MapillaryImage
     197          && ((MapillaryImage) selectedImage).getSequence() != null) {
     198        MapillaryImage tempImage = (MapillaryImage) selectedImage;
     199        while (tempImage.previous() != null) {
     200          tempImage = tempImage.previous();
     201          if (tempImage.isVisible()) {
     202            setSelectedImage(tempImage,
     203                Main.pref.getBoolean("mapillary.move-to-picture", true));
     204            break;
     205          }
    55206        }
    56     }
    57 
    58     /**
    59      * Adds an MapillaryImage to the object, and then repaints mapView.
    60      *
    61      * @param image
    62      *            The image to be added.
    63      */
    64     public synchronized void add(MapillaryAbstractImage image) {
    65         if (!images.contains(image)) {
    66             this.images.add(image);
     207      }
     208    }
     209  }
     210
     211  /**
     212   * Selects a new image and then starts a new
     213   * {@link MapillaryImageDownloadThread} thread in order to download its
     214   * surrounding thumbnails. If the user does ctrl+click, this isn't triggered.
     215   *
     216   * @param image
     217   *          The MapillaryImage which is going to be selected
     218   */
     219  public void setSelectedImage(MapillaryAbstractImage image) {
     220    setSelectedImage(image, false);
     221  }
     222
     223  /**
     224   * Selects a new image and then starts a new
     225   * {@link MapillaryImageDownloadThread} thread in order to download its
     226   * surrounding thumbnails. If the user does ctrl+click, this isn't triggered.
     227   * You can choose whether to center the view on the new image or not.
     228   *
     229   * @param image
     230   *          The {@link MapillaryImage} which is going to be selected.
     231   * @param zoom
     232   *          True if the view must be centered on the image; false otherwise.
     233   */
     234  public void setSelectedImage(MapillaryAbstractImage image, boolean zoom) {
     235    MapillaryAbstractImage oldImage = selectedImage;
     236    selectedImage = image;
     237    multiSelectedImages.clear();
     238    multiSelectedImages.add(image);
     239    if (image != null) {
     240      if (image instanceof MapillaryImage) {
     241        MapillaryImage mapillaryImage = (MapillaryImage) image;
     242        // Donwloadins thumbnails of surrounding pictures.
     243        if (mapillaryImage.next() != null) {
     244          new MapillaryCache(mapillaryImage.next().getKey(),
     245              MapillaryCache.Type.THUMBNAIL).submit(this, false);
     246          if (mapillaryImage.next().next() != null)
     247            new MapillaryCache(mapillaryImage.next().next().getKey(),
     248                MapillaryCache.Type.THUMBNAIL).submit(this, false);
    67249        }
    68         dataUpdated();
    69         fireImagesAdded();
    70     }
    71 
    72     public void addListener(MapillaryDataListener lis) {
    73         listeners.add(lis);
    74     }
    75 
    76     public void removeListener(MapillaryDataListener lis) {
    77         listeners.remove(lis);
    78     }
    79 
    80     /**
    81      * Adds a set of MapillaryImages to the object, but doesn't repaint mapView.
    82      * This is needed for concurrency.
    83      *
    84      * @param images
    85      *            The set of images to be added.
    86      */
    87     public synchronized void addWithoutUpdate(
    88             List<MapillaryAbstractImage> images) {
    89         for (MapillaryAbstractImage image : images) {
    90             addWithoutUpdate(image);
     250        if (mapillaryImage.previous() != null) {
     251          new MapillaryCache(mapillaryImage.previous().getKey(),
     252              MapillaryCache.Type.THUMBNAIL).submit(this, false);
     253          if (mapillaryImage.previous().previous() != null)
     254            new MapillaryCache(mapillaryImage.previous().previous().getKey(),
     255                MapillaryCache.Type.THUMBNAIL).submit(this, false);
    91256        }
    92     }
    93 
    94     /**
    95      * Highlights the image under the cursor.
    96      *
    97      * @param image
    98      *            The image under the cursor.
    99      */
    100     public void setHighlightedImage(MapillaryAbstractImage image) {
    101         highlightedImage = image;
    102     }
    103 
    104     /**
    105      * Returns the image under the mouse cursor.
    106      *
    107      * @return The image under the mouse cursor.
    108      */
    109     public MapillaryAbstractImage getHoveredImage() {
    110         return highlightedImage;
    111     }
    112 
    113     /**
    114      * Adds a MapillaryImage to the object, but doesn't repaint mapView. This is
    115      * needed for concurrency.
    116      *
    117      * @param image
    118      *            The image to be added.
    119      */
    120     public synchronized void addWithoutUpdate(MapillaryAbstractImage image) {
    121         if (!images.contains(image)) {
    122             this.images.add(image);
    123         }
    124         fireImagesAdded();
    125     }
    126 
    127     /**
    128      * Repaints mapView object.
    129      */
    130     public synchronized void dataUpdated() {
    131         if (!TEST_MODE)
    132             Main.map.mapView.repaint();
    133     }
    134 
    135     /**
    136      * Returns a List containing all images.
    137      *
    138      * @return A List object containing all images.
    139      */
    140     public List<MapillaryAbstractImage> getImages() {
    141         return images;
    142     }
    143 
    144     /**
    145      * Returns the MapillaryImage object that is currently selected.
    146      *
    147      * @return The selected MapillaryImage object.
    148      */
    149     public MapillaryAbstractImage getSelectedImage() {
    150         return selectedImage;
    151     }
    152 
    153     private void fireImagesAdded() {
    154         if (listeners.isEmpty())
    155             return;
    156         for (MapillaryDataListener lis : listeners)
    157             lis.imagesAdded();
    158     }
    159 
    160     /**
    161      * If the selected MapillaryImage is part of a MapillarySequence then the
    162      * following visible MapillaryImage is selected. In case there is none, does
    163      * nothing.
    164      */
    165     public void selectNext() {
    166         if (getSelectedImage() instanceof MapillaryImage) {
    167             if (getSelectedImage() == null)
    168                 return;
    169             if (((MapillaryImage) getSelectedImage()).getSequence() == null)
    170                 return;
    171             if (selectedImage instanceof MapillaryImage
    172                     && ((MapillaryImage) selectedImage).getSequence() != null) {
    173                 MapillaryImage tempImage = (MapillaryImage) selectedImage;
    174                 while (tempImage.next() != null) {
    175                     tempImage = tempImage.next();
    176                     if (tempImage.isVisible()) {
    177                         setSelectedImage(tempImage, Main.pref.getBoolean(
    178                                 "mapillary.move-to-picture", true));
    179                         break;
    180                     }
    181                 }
    182             }
    183         }
    184     }
    185 
    186     /**
    187      * If the selected MapillaryImage is part of a MapillarySequence then the
    188      * previous visible MapillaryImage is selected. In case there is none, does
    189      * nothing.
    190      */
    191     public void selectPrevious() {
    192         if (getSelectedImage() instanceof MapillaryImage) {
    193             if (getSelectedImage() == null)
    194                 return;
    195             if (((MapillaryImage) getSelectedImage()).getSequence() == null)
    196                 throw new IllegalStateException();
    197             if (selectedImage instanceof MapillaryImage
    198                     && ((MapillaryImage) selectedImage).getSequence() != null) {
    199                 MapillaryImage tempImage = (MapillaryImage) selectedImage;
    200                 while (tempImage.previous() != null) {
    201                     tempImage = tempImage.previous();
    202                     if (tempImage.isVisible()) {
    203                         setSelectedImage(tempImage, Main.pref.getBoolean(
    204                                 "mapillary.move-to-picture", true));
    205                         break;
    206                     }
    207                 }
    208             }
    209         }
    210     }
    211 
    212     /**
    213      * Selects a new image and then starts a new
    214      * {@link MapillaryImageDownloadThread} thread in order to download its
    215      * surrounding thumbnails. If the user does ctrl+click, this isn't
    216      * triggered.
    217      *
    218      * @param image
    219      *            The MapillaryImage which is going to be selected
    220      */
    221     public void setSelectedImage(MapillaryAbstractImage image) {
    222         setSelectedImage(image, false);
    223     }
    224 
    225     /**
    226      * Selects a new image and then starts a new
    227      * {@link MapillaryImageDownloadThread} thread in order to download its
    228      * surrounding thumbnails. If the user does ctrl+click, this isn't
    229      * triggered. You can choose whether to center the view on the new image or
    230      * not.
    231      *
    232      * @param image
    233      *            The {@link MapillaryImage} which is going to be selected.
    234      * @param zoom
    235      *            True if the view must be centered on the image; false
    236      *            otherwise.
    237      */
    238     public void setSelectedImage(MapillaryAbstractImage image, boolean zoom) {
    239         MapillaryAbstractImage oldImage = selectedImage;
    240         selectedImage = image;
    241         multiSelectedImages.clear();
    242         multiSelectedImages.add(image);
    243         if (image != null) {
    244             if (image instanceof MapillaryImage) {
    245                 MapillaryImage mapillaryImage = (MapillaryImage) image;
    246                 // Donwloadins thumbnails of surrounding pictures.
    247                 if (mapillaryImage.next() != null) {
    248                     new MapillaryCache(mapillaryImage.next().getKey(),
    249                             MapillaryCache.Type.THUMBNAIL).submit(this, false);
    250                     if (mapillaryImage.next().next() != null)
    251                         new MapillaryCache(mapillaryImage.next().next()
    252                                 .getKey(), MapillaryCache.Type.THUMBNAIL)
    253                                 .submit(this, false);
    254                 }
    255                 if (mapillaryImage.previous() != null) {
    256                     new MapillaryCache(mapillaryImage.previous().getKey(),
    257                             MapillaryCache.Type.THUMBNAIL).submit(this, false);
    258                     if (mapillaryImage.previous().previous() != null)
    259                         new MapillaryCache(mapillaryImage.previous().previous()
    260                                 .getKey(), MapillaryCache.Type.THUMBNAIL)
    261                                 .submit(this, false);
    262                 }
    263             }
    264         }
    265         if (zoom)
    266             Main.map.mapView.zoomTo(MapillaryData.getInstance()
    267                     .getSelectedImage().getLatLon());
    268         if (Main.map != null)
    269             Main.map.mapView.repaint();
    270         fireSelectedImageChanged(oldImage, selectedImage);
    271     }
    272 
    273     private void fireSelectedImageChanged(MapillaryAbstractImage oldImage,
    274             MapillaryAbstractImage newImage) {
    275         if (listeners.isEmpty())
    276             return;
    277         for (MapillaryDataListener lis : listeners)
    278             lis.selectedImageChanged(oldImage, newImage);
    279     }
    280 
    281     /**
    282      * Adds a MapillaryImage object to the list of selected images, (when ctrl +
    283      * click)
    284      *
    285      * @param image
    286      *            The MapillaryImage object to be added.
    287      */
    288     public void addMultiSelectedImage(MapillaryAbstractImage image) {
    289         if (!this.multiSelectedImages.contains(image)) {
    290             if (this.getSelectedImage() != null)
    291                 this.multiSelectedImages.add(image);
    292             else
    293                 this.setSelectedImage(image);
    294         }
    295         Main.map.mapView.repaint();
    296     }
    297 
    298     /**
    299      * Adds a set of {@code MapillaryAbstractImage} objects to the list of
    300      * selected images.
    301      *
    302      * @param images
    303      *            A List object containing the set of images to be added.
    304      */
    305     public void addMultiSelectedImage(List<MapillaryAbstractImage> images) {
    306         for (MapillaryAbstractImage image : images)
    307             if (!this.multiSelectedImages.contains(image)) {
    308                 if (this.getSelectedImage() != null)
    309                     this.multiSelectedImages.add(image);
    310                 else
    311                     this.setSelectedImage(image);
    312             }
    313         Main.map.mapView.repaint();
    314     }
    315 
    316     /**
    317      * Returns a List containing all {@code MapillaryAbstractImage} objects
    318      * selected with ctrl + click
    319      *
    320      * @return A List object containing all the images selected.
    321      */
    322     public List<MapillaryAbstractImage> getMultiSelectedImages() {
    323         return multiSelectedImages;
    324     }
    325 
    326     /**
    327      * This is empty because it is used just to make sure that certain images
    328      * have already been downloaded.
    329      */
    330     @Override
    331     public void loadingFinished(CacheEntry data,
    332             CacheEntryAttributes attributes, LoadResult result) {
    333         // DO NOTHING
    334     }
    335 
    336     /**
    337      * Returns the amount of images contained by this object.
    338      *
    339      * @return The amount of images in stored.
    340      */
    341     public int size() {
    342         return images.size();
    343     }
     257      }
     258    }
     259    if (zoom)
     260      Main.map.mapView.zoomTo(MapillaryData.getInstance().getSelectedImage()
     261          .getLatLon());
     262    if (Main.map != null)
     263      Main.map.mapView.repaint();
     264    fireSelectedImageChanged(oldImage, selectedImage);
     265  }
     266
     267  private void fireSelectedImageChanged(MapillaryAbstractImage oldImage,
     268      MapillaryAbstractImage newImage) {
     269    if (listeners.isEmpty())
     270      return;
     271    for (MapillaryDataListener lis : listeners)
     272      lis.selectedImageChanged(oldImage, newImage);
     273  }
     274
     275  /**
     276   * Adds a MapillaryImage object to the list of selected images, (when ctrl +
     277   * click)
     278   *
     279   * @param image
     280   *          The MapillaryImage object to be added.
     281   */
     282  public void addMultiSelectedImage(MapillaryAbstractImage image) {
     283    if (!this.multiSelectedImages.contains(image)) {
     284      if (this.getSelectedImage() != null)
     285        this.multiSelectedImages.add(image);
     286      else
     287        this.setSelectedImage(image);
     288    }
     289    Main.map.mapView.repaint();
     290  }
     291
     292  /**
     293   * Adds a set of {@code MapillaryAbstractImage} objects to the list of
     294   * selected images.
     295   *
     296   * @param images
     297   *          A List object containing the set of images to be added.
     298   */
     299  public void addMultiSelectedImage(List<MapillaryAbstractImage> images) {
     300    for (MapillaryAbstractImage image : images)
     301      if (!this.multiSelectedImages.contains(image)) {
     302        if (this.getSelectedImage() != null)
     303          this.multiSelectedImages.add(image);
     304        else
     305          this.setSelectedImage(image);
     306      }
     307    Main.map.mapView.repaint();
     308  }
     309
     310  /**
     311   * Returns a List containing all {@code MapillaryAbstractImage} objects
     312   * selected with ctrl + click
     313   *
     314   * @return A List object containing all the images selected.
     315   */
     316  public List<MapillaryAbstractImage> getMultiSelectedImages() {
     317    return multiSelectedImages;
     318  }
     319
     320  /**
     321   * This is empty because it is used just to make sure that certain images have
     322   * already been downloaded.
     323   */
     324  @Override
     325  public void loadingFinished(CacheEntry data, CacheEntryAttributes attributes,
     326      LoadResult result) {
     327    // DO NOTHING
     328  }
     329
     330  /**
     331   * Returns the amount of images contained by this object.
     332   *
     333   * @return The amount of images in stored.
     334   */
     335  public int size() {
     336    return images.size();
     337  }
    344338}
  • applications/editors/josm/plugins/mapillary/src/org/openstreetmap/josm/plugins/mapillary/MapillaryDataListener.java

    r31333 r31350  
    33public interface MapillaryDataListener {
    44
    5     /**
    6      * Fired when any image is added to the database.
    7      */
    8     public void imagesAdded();
     5  /**
     6   * Fired when any image is added to the database.
     7   */
     8  public void imagesAdded();
    99
    10     /**
    11      * Fired when the selected image is changed by something different from
    12      * manually clicking on the icon.
    13      */
    14     public void selectedImageChanged(MapillaryAbstractImage oldImage,
    15             MapillaryAbstractImage newImage);
     10  /**
     11   * Fired when the selected image is changed by something different from
     12   * manually clicking on the icon.
     13   */
     14  public void selectedImageChanged(MapillaryAbstractImage oldImage,
     15      MapillaryAbstractImage newImage);
    1616
    1717}
  • applications/editors/josm/plugins/mapillary/src/org/openstreetmap/josm/plugins/mapillary/MapillaryImage.java

    r31333 r31350  
    1212 */
    1313public class MapillaryImage extends MapillaryAbstractImage {
    14     /** Unique identifier of the object */
    15     private final String key;
    16     /** Sequence of pictures containing this object */
    17     private MapillarySequence sequence;
     14  /** Unique identifier of the object */
     15  private final String key;
     16  /** Sequence of pictures containing this object */
     17  private MapillarySequence sequence;
    1818
    19     /** The user that made the image */
    20     private String user;
    21     /** Set of traffic signs in the image */
    22     private List<String> signs;
    23     private String location;
     19  /** The user that made the image */
     20  private String user;
     21  /** Set of traffic signs in the image */
     22  private List<String> signs;
     23  private String location;
    2424
    25     public String getLocation() {
    26         return location;
     25  public String getLocation() {
     26    return location;
     27  }
     28
     29  public void setLocation(String location) {
     30    this.location = location;
     31  }
     32
     33  /**
     34   * Main contructor of the class MapillaryImage
     35   *
     36   * @param key
     37   *          The unique identifier of the image.
     38   * @param lat
     39   *          The latitude where it is positioned.
     40   * @param lon
     41   *          The longitude where it is positioned.
     42   * @param ca
     43   *          The direction of the images in degrees, meaning 0 north.
     44   */
     45  public MapillaryImage(String key, double lat, double lon, double ca) {
     46    super(lat, lon, ca);
     47    this.key = key;
     48    this.signs = new ArrayList<>();
     49  }
     50
     51  /**
     52   * Returns the unique identifier of the object.
     53   *
     54   * @return A String containing the unique identifier of the object.
     55   */
     56  public String getKey() {
     57    return this.key;
     58  }
     59
     60  /**
     61   * Adds a new sign to the set of signs.
     62   *
     63   * @param sign
     64   *          A String that identifies the type of sign.
     65   */
     66  public void addSign(String sign) {
     67    signs.add(sign);
     68  }
     69
     70  /**
     71   * Returns a List containing the signs assigned to this image.
     72   *
     73   * @return A List object containing the signs assigned to this image.
     74   */
     75  public List<String> getSigns() {
     76    return signs;
     77  }
     78
     79  /**
     80   * Sets the username of the person who took the image.
     81   *
     82   * @param user
     83   *          A String containing the username of the person who took the image.
     84   */
     85  public void setUser(String user) {
     86    this.user = user;
     87  }
     88
     89  public String getUser() {
     90    return user;
     91  }
     92
     93  /**
     94   * Sets the MapillarySequence object which contains the MapillaryImage.
     95   *
     96   * @param sequence
     97   *          The MapillarySequence that contains the MapillaryImage.
     98   */
     99  public void setSequence(MapillarySequence sequence) {
     100    this.sequence = sequence;
     101  }
     102
     103  /**
     104   * Returns the sequence which contains this image.
     105   *
     106   * @return The MapillarySequence object that contains this MapillaryImage.
     107   */
     108  public MapillarySequence getSequence() {
     109    return this.sequence;
     110  }
     111
     112  public String toString() {
     113    return "Image[key=" + this.key + ";lat=" + this.latLon.lat() + ";lon="
     114        + this.latLon.lon() + ";ca=" + this.ca + "]";
     115  }
     116
     117  /**
     118   * If the MapillaryImage belongs to a MapillarySequence, returns the next
     119   * MapillarySequence in it.
     120   *
     121   * @return The following MapillaryImage, or null if there is none.
     122   */
     123  public MapillaryImage next() {
     124    synchronized (lock) {
     125      if (this.getSequence() == null)
     126        return null;
     127      return this.getSequence().next(this);
    27128    }
     129  }
    28130
    29     public void setLocation(String location) {
    30         this.location = location;
     131  /**
     132   * If the MapillaryImage belongs to a MapillarySequence, returns the previous
     133   * MapillarySequence in it.
     134   *
     135   * @return The previous MapillaryImage, or null if there is none.
     136   */
     137  public MapillaryImage previous() {
     138    synchronized (lock) {
     139      if (this.getSequence() == null)
     140        return null;
     141      return this.getSequence().previous(this);
    31142    }
     143  }
    32144
    33     /**
    34      * Main contructor of the class MapillaryImage
    35      *
    36      * @param key
    37      *            The unique identifier of the image.
    38      * @param lat
    39      *            The latitude where it is positioned.
    40      * @param lon
    41      *            The longitude where it is positioned.
    42      * @param ca
    43      *            The direction of the images in degrees, meaning 0 north.
    44      */
    45     public MapillaryImage(String key, double lat, double lon, double ca) {
    46         super(lat, lon, ca);
    47         this.key = key;
    48         this.signs = new ArrayList<>();
    49     }
     145  @Override
     146  public boolean equals(Object object) {
     147    if (object instanceof MapillaryImage)
     148      return this.key.equals(((MapillaryImage) object).getKey());
     149    return false;
     150  }
    50151
    51     /**
    52      * Returns the unique identifier of the object.
    53      *
    54      * @return A String containing the unique identifier of the object.
    55      */
    56     public String getKey() {
    57         return this.key;
    58     }
    59 
    60     /**
    61      * Adds a new sign to the set of signs.
    62      *
    63      * @param sign
    64      *            A String that identifies the type of sign.
    65      */
    66     public void addSign(String sign) {
    67         signs.add(sign);
    68     }
    69 
    70     /**
    71      * Returns a List containing the signs assigned to this image.
    72      *
    73      * @return A List object containing the signs assigned to this image.
    74      */
    75     public List<String> getSigns() {
    76         return signs;
    77     }
    78 
    79     /**
    80      * Sets the username of the person who took the image.
    81      * @param user A String containing the username of the person who took the image.
    82      */
    83     public void setUser(String user) {
    84         this.user = user;
    85     }
    86 
    87     public String getUser() {
    88         return user;
    89     }
    90 
    91     /**
    92      * Sets the MapillarySequence object which contains the MapillaryImage.
    93      *
    94      * @param sequence
    95      *            The MapillarySequence that contains the MapillaryImage.
    96      */
    97     public void setSequence(MapillarySequence sequence) {
    98         this.sequence = sequence;
    99     }
    100 
    101     /**
    102      * Returns the sequence which contains this image.
    103      *
    104      * @return The MapillarySequence object that contains this MapillaryImage.
    105      */
    106     public MapillarySequence getSequence() {
    107         return this.sequence;
    108     }
    109 
    110     public String toString() {
    111         return "Image[key=" + this.key + ";lat=" + this.latLon.lat() + ";lon="
    112                 + this.latLon.lon() + ";ca=" + this.ca + "]";
    113     }
    114 
    115     /**
    116      * If the MapillaryImage belongs to a MapillarySequence, returns the next
    117      * MapillarySequence in it.
    118      *
    119      * @return The following MapillaryImage, or null if there is none.
    120      */
    121     public MapillaryImage next() {
    122         synchronized (lock) {
    123             if (this.getSequence() == null)
    124                 return null;
    125             return this.getSequence().next(this);
    126         }
    127     }
    128 
    129     /**
    130      * If the MapillaryImage belongs to a MapillarySequence, returns the
    131      * previous MapillarySequence in it.
    132      *
    133      * @return The previous MapillaryImage, or null if there is none.
    134      */
    135     public MapillaryImage previous() {
    136         synchronized (lock) {
    137             if (this.getSequence() == null)
    138                 return null;
    139             return this.getSequence().previous(this);
    140         }
    141     }
    142 
    143     @Override
    144     public boolean equals(Object object) {
    145         if (object instanceof MapillaryImage)
    146             return this.key.equals(((MapillaryImage) object).getKey());
    147         return false;
    148     }
    149 
    150     @Override
    151     public int hashCode() {
    152         return this.key.hashCode();
    153     }
     152  @Override
     153  public int hashCode() {
     154    return this.key.hashCode();
     155  }
    154156}
  • applications/editors/josm/plugins/mapillary/src/org/openstreetmap/josm/plugins/mapillary/MapillaryImportedImage.java

    r31348 r31350  
    1111public class MapillaryImportedImage extends MapillaryAbstractImage {
    1212
    13     /**
    14      * The picture file.
    15      */
    16     protected File file;
    17     public final long datetimeOriginal;
     13  /**
     14   * The picture file.
     15   */
     16  protected File file;
     17  public final long datetimeOriginal;
    1818
    19     public MapillaryImportedImage(double lat, double lon, double ca, File file) {
    20         this(lat, lon, ca, file, currentDate());
    21     }
     19  public MapillaryImportedImage(double lat, double lon, double ca, File file) {
     20    this(lat, lon, ca, file, currentDate());
     21  }
    2222
    23     public MapillaryImportedImage(double lat, double lon, double ca, File file,
    24             String datetimeOriginal) {
    25         super(lat, lon, ca);
    26         this.file = file;
    27         this.datetimeOriginal = getEpoch(datetimeOriginal,
    28                 "yyyy:MM:dd hh:mm:ss");
    29     }
     23  public MapillaryImportedImage(double lat, double lon, double ca, File file,
     24      String datetimeOriginal) {
     25    super(lat, lon, ca);
     26    this.file = file;
     27    this.datetimeOriginal = getEpoch(datetimeOriginal, "yyyy:MM:dd hh:mm:ss");
     28  }
    3029
    31     /**
    32      * Returns the pictures of the file.
    33      *
    34      * @return A BufferedImage object containing the pictures.
    35      * @throws IOException
    36      * @throws IllegalArgumentException if file is currently set to null
    37      */
    38     public BufferedImage getImage() throws IOException {
    39         return ImageIO.read(file);
    40     }
     30  /**
     31   * Returns the pictures of the file.
     32   *
     33   * @return A BufferedImage object containing the pictures.
     34   * @throws IOException
     35   * @throws IllegalArgumentException
     36   *           if file is currently set to null
     37   */
     38  public BufferedImage getImage() throws IOException {
     39    return ImageIO.read(file);
     40  }
    4141
    42     /**
    43      * Returns the File object where the picture is located.
    44      * @return The File object where the picture is located.
    45      */
    46     public File getFile() {
    47         return file;
    48     }
     42  /**
     43   * Returns the File object where the picture is located.
     44   *
     45   * @return The File object where the picture is located.
     46   */
     47  public File getFile() {
     48    return file;
     49  }
    4950
    50     @Override
    51     public boolean equals(Object object) {
    52         if (object instanceof MapillaryImportedImage)
    53             return this.file.equals(((MapillaryImportedImage) object).file);
    54         return false;
    55     }
     51  @Override
     52  public boolean equals(Object object) {
     53    if (object instanceof MapillaryImportedImage)
     54      return this.file.equals(((MapillaryImportedImage) object).file);
     55    return false;
     56  }
    5657
    57     @Override
    58     public int hashCode() {
    59         return this.file.hashCode();
    60     }
     58  @Override
     59  public int hashCode() {
     60    return this.file.hashCode();
     61  }
    6162
    62     private static String currentDate() {
    63         Calendar cal = Calendar.getInstance();
     63  private static String currentDate() {
     64    Calendar cal = Calendar.getInstance();
    6465
    65         SimpleDateFormat formatter = new SimpleDateFormat("yyyy:MM:dd hh:mm:ss");
    66         return formatter.format(cal.getTime());
     66    SimpleDateFormat formatter = new SimpleDateFormat("yyyy:MM:dd hh:mm:ss");
     67    return formatter.format(cal.getTime());
    6768
    68     }
     69  }
    6970}
  • applications/editors/josm/plugins/mapillary/src/org/openstreetmap/josm/plugins/mapillary/MapillaryLayer.java

    r31347 r31350  
    5959
    6060public class MapillaryLayer extends AbstractModifiableLayer implements
    61         DataSetListener, EditLayerChangeListener, LayerChangeListener {
    62 
    63     public final static int SEQUENCE_MAX_JUMP_DISTANCE = Main.pref.getInteger(
    64             "mapillary.sequence-max-jump-distance", 100);
    65 
    66     private boolean TEMP_MANUAL = false;
    67 
    68     public static MapillaryLayer INSTANCE;
    69     public static CacheAccess<String, BufferedImageCacheEntry> CACHE;
    70     public static MapillaryImage BLUE;
    71     public static MapillaryImage RED;
    72 
    73     public final MapillaryData data = MapillaryData.getInstance();
    74 
    75     public ArrayList<Bounds> bounds;
    76 
    77     private MouseAdapter mouseAdapter;
    78 
    79     private int highlightPointRadius = Main.pref.getInteger(
    80             "mappaint.highlight.radius", 7);
    81     private int highlightStep = Main.pref.getInteger("mappaint.highlight.step",
    82             4);
    83 
    84     private volatile TexturePaint hatched;
    85 
    86     private MapillaryLayer() {
    87         super(tr("Mapillary Images"));
    88         bounds = new ArrayList<>();
    89         init();
    90     }
    91 
    92     /**
    93      * Initializes the Layer.
    94      */
    95     private void init() {
    96         mouseAdapter = new MapillaryMouseAdapter();
    97         try {
    98             CACHE = JCSCacheManager.getCache("Mapillary");
    99         } catch (IOException e) {
    100             Main.error(e);
     61    DataSetListener, EditLayerChangeListener, LayerChangeListener {
     62
     63  public final static int SEQUENCE_MAX_JUMP_DISTANCE = Main.pref.getInteger(
     64      "mapillary.sequence-max-jump-distance", 100);
     65
     66  private boolean TEMP_MANUAL = false;
     67
     68  public static MapillaryLayer INSTANCE;
     69  public static CacheAccess<String, BufferedImageCacheEntry> CACHE;
     70  public static MapillaryImage BLUE;
     71  public static MapillaryImage RED;
     72
     73  public final MapillaryData data = MapillaryData.getInstance();
     74
     75  public ArrayList<Bounds> bounds;
     76
     77  private MouseAdapter mouseAdapter;
     78
     79  private int highlightPointRadius = Main.pref.getInteger(
     80      "mappaint.highlight.radius", 7);
     81  private int highlightStep = Main.pref
     82      .getInteger("mappaint.highlight.step", 4);
     83
     84  private volatile TexturePaint hatched;
     85
     86  private MapillaryLayer() {
     87    super(tr("Mapillary Images"));
     88    bounds = new ArrayList<>();
     89    init();
     90  }
     91
     92  /**
     93   * Initializes the Layer.
     94   */
     95  private void init() {
     96    mouseAdapter = new MapillaryMouseAdapter();
     97    try {
     98      CACHE = JCSCacheManager.getCache("Mapillary");
     99    } catch (IOException e) {
     100      Main.error(e);
     101    }
     102    if (Main.map != null && Main.map.mapView != null) {
     103      Main.map.mapView.addMouseListener(mouseAdapter);
     104      Main.map.mapView.addMouseMotionListener(mouseAdapter);
     105      Main.map.mapView.addLayer(this);
     106      MapView.addEditLayerChangeListener(this, false);
     107      MapView.addLayerChangeListener(this);
     108      if (Main.map.mapView.getEditLayer() != null)
     109        Main.map.mapView.getEditLayer().data.addDataSetListener(this);
     110    }
     111    if (MapillaryPlugin.EXPORT_MENU != null) { // Does not execute when in
     112                                               // headless mode
     113      MapillaryPlugin.setMenuEnabled(MapillaryPlugin.EXPORT_MENU, true);
     114      if (!MapillaryMainDialog.getInstance().isShowing())
     115        MapillaryMainDialog.getInstance().getButton().doClick();
     116    }
     117
     118    createHatchTexture();
     119    data.dataUpdated();
     120  }
     121
     122  public synchronized static MapillaryLayer getInstance() {
     123    if (MapillaryLayer.INSTANCE == null)
     124      MapillaryLayer.INSTANCE = new MapillaryLayer();
     125    return MapillaryLayer.INSTANCE;
     126  }
     127
     128  /**
     129   * Downloads all images of the area covered by the OSM data. This is only just
     130   * for automatic download.
     131   */
     132  public void download() {
     133    checkAreaTooBig();
     134    if (Main.pref.getBoolean("mapillary.download-manually") || TEMP_MANUAL)
     135      return;
     136    for (Bounds bounds : Main.map.mapView.getEditLayer().data
     137        .getDataSourceBounds()) {
     138      if (!this.bounds.contains(bounds)) {
     139        this.bounds.add(bounds);
     140        new MapillaryDownloader().getImages(bounds.getMin(), bounds.getMax());
     141      }
     142    }
     143  }
     144
     145  /**
     146   * Checks if the area of the OSM data is too big. This means that probably
     147   * lots of Mapillary images are going to be downloaded, slowing down the
     148   * program too much. To solve this the automatic is stopped, an alert is shown
     149   * and you will have to download areas manually.
     150   */
     151  private void checkAreaTooBig() {
     152    double area = 0;
     153    for (Bounds bounds : Main.map.mapView.getEditLayer().data
     154        .getDataSourceBounds()) {
     155      area += bounds.getArea();
     156    }
     157    if (area > MapillaryDownloadViewAction.MAX_AREA) {
     158      TEMP_MANUAL = true;
     159      MapillaryPlugin.setMenuEnabled(MapillaryPlugin.DOWNLOAD_VIEW_MENU, true);
     160      JOptionPane
     161          .showMessageDialog(
     162              Main.parent,
     163              tr("The downloaded OSM area is too big. Download mode has been changed to manual until the layer is restarted."));
     164    }
     165  }
     166
     167  /**
     168   * Returns the MapillaryData object, which acts as the database of the Layer.
     169   *
     170   * @return
     171   */
     172  public MapillaryData getMapillaryData() {
     173    return data;
     174  }
     175
     176  /**
     177   * Method invoked when the layer is destroyed.
     178   */
     179  @Override
     180  public void destroy() {
     181    MapillaryMainDialog.getInstance().setImage(null);
     182    MapillaryMainDialog.getInstance().updateImage();
     183    data.getImages().clear();
     184    MapillaryLayer.INSTANCE = null;
     185    MapillaryData.INSTANCE = null;
     186    MapillaryPlugin.setMenuEnabled(MapillaryPlugin.EXPORT_MENU, false);
     187    MapillaryPlugin.setMenuEnabled(MapillaryPlugin.ZOOM_MENU, false);
     188    Main.map.mapView.removeMouseListener(mouseAdapter);
     189    Main.map.mapView.removeMouseMotionListener(mouseAdapter);
     190    MapView.removeEditLayerChangeListener(this);
     191    if (Main.map.mapView.getEditLayer() != null)
     192      Main.map.mapView.getEditLayer().data.removeDataSetListener(this);
     193    super.destroy();
     194  }
     195
     196  /**
     197   * Returns true any of the images from the database has been modified.
     198   */
     199  @Override
     200  public boolean isModified() {
     201    for (MapillaryAbstractImage image : data.getImages())
     202      if (image.isModified())
     203        return true;
     204    return false;
     205  }
     206
     207  @Override
     208  public void setVisible(boolean visible) {
     209    super.setVisible(visible);
     210    for (MapillaryAbstractImage img : data.getImages())
     211      img.setVisible(visible);
     212    MapillaryFilterDialog.getInstance().refresh();
     213  }
     214
     215  /**
     216   * Replies background color for downloaded areas.
     217   *
     218   * @return background color for downloaded areas. Black by default
     219   */
     220  private Color getBackgroundColor() {
     221    return Main.pref.getColor(marktr("background"), Color.BLACK);
     222  }
     223
     224  /**
     225   * Replies background color for non-downloaded areas.
     226   *
     227   * @return background color for non-downloaded areas. Yellow by default
     228   */
     229  private Color getOutsideColor() {
     230    return Main.pref.getColor(marktr("outside downloaded area"), Color.YELLOW);
     231  }
     232
     233  /**
     234   * Initialize the hatch pattern used to paint the non-downloaded area
     235   */
     236  private void createHatchTexture() {
     237    BufferedImage bi = new BufferedImage(15, 15, BufferedImage.TYPE_INT_ARGB);
     238    Graphics2D big = bi.createGraphics();
     239    big.setColor(getBackgroundColor());
     240    Composite comp = AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.3f);
     241    big.setComposite(comp);
     242    big.fillRect(0, 0, 15, 15);
     243    big.setColor(getOutsideColor());
     244    big.drawLine(0, 15, 15, 0);
     245    Rectangle r = new Rectangle(0, 0, 15, 15);
     246    hatched = new TexturePaint(bi, r);
     247  }
     248
     249  /**
     250   * Paints the database in the map.
     251   */
     252  @Override
     253  public synchronized void paint(Graphics2D g, MapView mv, Bounds box) {
     254    if (Main.map.mapView.getActiveLayer() == this) {
     255      Rectangle b = mv.getBounds();
     256      // on some platforms viewport bounds seem to be offset from the
     257      // left,
     258      // over-grow it just to be sure
     259      b.grow(100, 100);
     260      Area a = new Area(b);
     261      // now successively subtract downloaded areas
     262      for (Bounds bounds : this.bounds) {
     263        Point p1 = mv.getPoint(bounds.getMin());
     264        Point p2 = mv.getPoint(bounds.getMax());
     265        Rectangle r = new Rectangle(Math.min(p1.x, p2.x), Math.min(p1.y, p2.y),
     266            Math.abs(p2.x - p1.x), Math.abs(p2.y - p1.y));
     267        a.subtract(new Area(r));
     268      }
     269      // paint remainder
     270      g.setPaint(hatched);
     271      g.fill(a);
     272    }
     273
     274    // Draw colored lines
     275    MapillaryLayer.BLUE = null;
     276    MapillaryLayer.RED = null;
     277    MapillaryMainDialog.getInstance().blueButton.setEnabled(false);
     278    MapillaryMainDialog.getInstance().redButton.setEnabled(false);
     279
     280    // Sets blue and red lines and enables/disables the buttons
     281    if (data.getSelectedImage() != null) {
     282      MapillaryImage[] closestImages = getClosestImagesFromDifferentSequences();
     283      Point selected = mv.getPoint(data.getSelectedImage().getLatLon());
     284      if (closestImages[0] != null) {
     285        MapillaryLayer.BLUE = closestImages[0];
     286        g.setColor(Color.BLUE);
     287        g.drawLine(mv.getPoint(closestImages[0].getLatLon()).x,
     288            mv.getPoint(closestImages[0].getLatLon()).y, selected.x, selected.y);
     289        MapillaryMainDialog.getInstance().blueButton.setEnabled(true);
     290      }
     291      if (closestImages[1] != null) {
     292        MapillaryLayer.RED = closestImages[1];
     293        g.setColor(Color.RED);
     294        g.drawLine(mv.getPoint(closestImages[1].getLatLon()).x,
     295            mv.getPoint(closestImages[1].getLatLon()).y, selected.x, selected.y);
     296        MapillaryMainDialog.getInstance().redButton.setEnabled(true);
     297      }
     298    }
     299    g.setColor(Color.WHITE);
     300    for (MapillaryAbstractImage imageAbs : data.getImages()) {
     301      if (!imageAbs.isVisible())
     302        continue;
     303      Point p = mv.getPoint(imageAbs.getLatLon());
     304      if (imageAbs instanceof MapillaryImage) {
     305        MapillaryImage image = (MapillaryImage) imageAbs;
     306        Point nextp = null;
     307        // Draw sequence line
     308        if (image.getSequence() != null) {
     309          MapillaryImage tempImage = image.next();
     310          while (tempImage != null) {
     311            if (tempImage.isVisible()) {
     312              nextp = mv.getPoint(tempImage.getLatLon());
     313              break;
     314            }
     315            tempImage = tempImage.next();
     316          }
     317          if (nextp != null)
     318            g.drawLine(p.x, p.y, nextp.x, nextp.y);
    101319        }
    102         if (Main.map != null && Main.map.mapView != null) {
    103             Main.map.mapView.addMouseListener(mouseAdapter);
    104             Main.map.mapView.addMouseMotionListener(mouseAdapter);
    105             Main.map.mapView.addLayer(this);
    106             MapView.addEditLayerChangeListener(this, false);
    107             MapView.addLayerChangeListener(this);
    108             if (Main.map.mapView.getEditLayer() != null)
    109                 Main.map.mapView.getEditLayer().data.addDataSetListener(this);
     320
     321        ImageIcon icon;
     322        if (!data.getMultiSelectedImages().contains(image))
     323          icon = MapillaryPlugin.MAP_ICON;
     324        else
     325          icon = MapillaryPlugin.MAP_ICON_SELECTED;
     326        draw(g, image, icon, p);
     327        if (!image.getSigns().isEmpty()) {
     328          g.drawImage(MapillaryPlugin.MAP_SIGN.getImage(),
     329              p.x + icon.getIconWidth() / 2, p.y - icon.getIconHeight() / 2,
     330              Main.map.mapView);
    110331        }
    111         if (MapillaryPlugin.EXPORT_MENU != null) { // Does not execute when in headless mode
    112             MapillaryPlugin.setMenuEnabled(MapillaryPlugin.EXPORT_MENU, true);
    113             if (!MapillaryMainDialog.getInstance().isShowing())
    114                 MapillaryMainDialog.getInstance().getButton().doClick();
     332      } else if (imageAbs instanceof MapillaryImportedImage) {
     333        MapillaryImportedImage image = (MapillaryImportedImage) imageAbs;
     334        ImageIcon icon;
     335        if (!data.getMultiSelectedImages().contains(image))
     336          icon = MapillaryPlugin.MAP_ICON_IMPORTED;
     337        else
     338          icon = MapillaryPlugin.MAP_ICON_SELECTED;
     339        draw(g, image, icon, p);
     340      }
     341    }
     342  }
     343
     344  /**
     345   * Draws the highlight of the icon.
     346   *
     347   * @param g
     348   * @param p
     349   * @param size
     350   */
     351  private void drawPointHighlight(Graphics2D g, Point p, int size) {
     352    Color oldColor = g.getColor();
     353    Color highlightColor = PaintColors.HIGHLIGHT.get();
     354    Color highlightColorTransparent = new Color(highlightColor.getRed(),
     355        highlightColor.getGreen(), highlightColor.getBlue(), 100);
     356    g.setColor(highlightColorTransparent);
     357    int s = size + highlightPointRadius;
     358    while (s >= size) {
     359      int r = (int) Math.floor(s / 2d);
     360      g.fillRoundRect(p.x - r, p.y - r, s, s, r, r);
     361      s -= highlightStep;
     362    }
     363    g.setColor(oldColor);
     364  }
     365
     366  /**
     367   * Draws the given icon of an image. Also checks if the mouse is over the
     368   * image.
     369   *
     370   * @param g
     371   * @param image
     372   * @param icon
     373   * @param p
     374   */
     375  private void draw(Graphics2D g, MapillaryAbstractImage image, ImageIcon icon,
     376      Point p) {
     377    Image imagetemp = icon.getImage();
     378    BufferedImage bi = (BufferedImage) imagetemp;
     379    int width = icon.getIconWidth();
     380    int height = icon.getIconHeight();
     381
     382    // Rotate the image
     383    double rotationRequired = Math.toRadians(image.getCa());
     384    double locationX = width / 2;
     385    double locationY = height / 2;
     386    AffineTransform tx = AffineTransform.getRotateInstance(rotationRequired,
     387        locationX, locationY);
     388    AffineTransformOp op = new AffineTransformOp(tx,
     389        AffineTransformOp.TYPE_BILINEAR);
     390
     391    g.drawImage(op.filter(bi, null), p.x - (width / 2), p.y - (height / 2),
     392        Main.map.mapView);
     393    if (data.getHoveredImage() == image) {
     394      drawPointHighlight(g, p, 16);
     395    }
     396  }
     397
     398  @Override
     399  public Icon getIcon() {
     400    return MapillaryPlugin.ICON16;
     401  }
     402
     403  @Override
     404  public boolean isMergable(Layer other) {
     405    return false;
     406  }
     407
     408  @Override
     409  public void mergeFrom(Layer from) {
     410    throw new UnsupportedOperationException(
     411        "This layer does not support merging yet");
     412  }
     413
     414  @Override
     415  public Action[] getMenuEntries() {
     416    List<Action> actions = new ArrayList<>();
     417    actions.add(LayerListDialog.getInstance().createShowHideLayerAction());
     418    actions.add(LayerListDialog.getInstance().createDeleteLayerAction());
     419    actions.add(new LayerListPopup.InfoAction(this));
     420    return actions.toArray(new Action[actions.size()]);
     421  }
     422
     423  /**
     424   * Returns the 2 closest images belonging to a different sequence.
     425   *
     426   * @return
     427   */
     428  private MapillaryImage[] getClosestImagesFromDifferentSequences() {
     429    if (!(data.getSelectedImage() instanceof MapillaryImage))
     430      return new MapillaryImage[2];
     431    MapillaryImage selected = (MapillaryImage) data.getSelectedImage();
     432    MapillaryImage[] ret = new MapillaryImage[2];
     433    double[] distances = { SEQUENCE_MAX_JUMP_DISTANCE,
     434        SEQUENCE_MAX_JUMP_DISTANCE };
     435    LatLon selectedCoords = data.getSelectedImage().getLatLon();
     436    for (MapillaryAbstractImage imagePrev : data.getImages()) {
     437      if (!(imagePrev instanceof MapillaryImage))
     438        continue;
     439      if (!imagePrev.isVisible())
     440        continue;
     441      MapillaryImage image = (MapillaryImage) imagePrev;
     442      if (image.getLatLon().greatCircleDistance(selectedCoords) < SEQUENCE_MAX_JUMP_DISTANCE
     443          && selected.getSequence() != image.getSequence()) {
     444        if ((ret[0] == null && ret[1] == null)
     445            || (image.getLatLon().greatCircleDistance(selectedCoords) < distances[0] && (ret[1] == null || image
     446                .getSequence() != ret[1].getSequence()))) {
     447          ret[0] = image;
     448          distances[0] = image.getLatLon().greatCircleDistance(selectedCoords);
     449        } else if ((ret[1] == null || image.getLatLon().greatCircleDistance(
     450            selectedCoords) < distances[1])
     451            && image.getSequence() != ret[0].getSequence()) {
     452          ret[1] = image;
     453          distances[1] = image.getLatLon().greatCircleDistance(selectedCoords);
    115454        }
    116 
    117         createHatchTexture();
    118         data.dataUpdated();
    119     }
    120 
    121     public synchronized static MapillaryLayer getInstance() {
    122         if (MapillaryLayer.INSTANCE == null)
    123             MapillaryLayer.INSTANCE = new MapillaryLayer();
    124         return MapillaryLayer.INSTANCE;
    125     }
    126 
    127     /**
    128      * Downloads all images of the area covered by the OSM data. This is only
    129      * just for automatic download.
    130      */
    131     public void download() {
    132         checkAreaTooBig();
    133         if (Main.pref.getBoolean("mapillary.download-manually") || TEMP_MANUAL)
    134             return;
    135         for (Bounds bounds : Main.map.mapView.getEditLayer().data
    136                 .getDataSourceBounds()) {
    137             if (!this.bounds.contains(bounds)) {
    138                 this.bounds.add(bounds);
    139                 new MapillaryDownloader().getImages(bounds.getMin(),
    140                         bounds.getMax());
    141             }
    142         }
    143     }
    144 
    145     /**
    146      * Checks if the area of the OSM data is too big. This means that probably
    147      * lots of Mapillary images are going to be downloaded, slowing down the
    148      * program too much. To solve this the automatic is stopped, an alert is
    149      * shown and you will have to download areas manually.
    150      */
    151     private void checkAreaTooBig() {
    152         double area = 0;
    153         for (Bounds bounds : Main.map.mapView.getEditLayer().data
    154                 .getDataSourceBounds()) {
    155             area += bounds.getArea();
    156         }
    157         if (area > MapillaryDownloadViewAction.MAX_AREA) {
    158             TEMP_MANUAL = true;
    159             MapillaryPlugin.setMenuEnabled(MapillaryPlugin.DOWNLOAD_VIEW_MENU,
    160                     true);
    161             JOptionPane
    162                     .showMessageDialog(
    163                             Main.parent,
    164                             tr("The downloaded OSM area is too big. Download mode has been changed to manual until the layer is restarted."));
    165         }
    166     }
    167 
    168     /**
    169      * Returns the MapillaryData object, which acts as the database of the
    170      * Layer.
    171      *
    172      * @return
    173      */
    174     public MapillaryData getMapillaryData() {
    175         return data;
    176     }
    177 
    178     /**
    179      * Method invoked when the layer is destroyed.
    180      */
     455      }
     456    }
     457    // Predownloads the thumbnails
     458    if (ret[0] != null)
     459      new MapillaryCache(ret[0].getKey(), MapillaryCache.Type.THUMBNAIL)
     460          .submit(data, false);
     461    if (ret[1] != null)
     462      new MapillaryCache(ret[1].getKey(), MapillaryCache.Type.THUMBNAIL)
     463          .submit(data, false);
     464    return ret;
     465  }
     466
     467  @Override
     468  public Object getInfoComponent() {
     469    StringBuilder sb = new StringBuilder();
     470    sb.append(tr("Mapillary layer"));
     471    sb.append("\n");
     472    sb.append(tr("Total images:"));
     473    sb.append(" ");
     474    sb.append(data.size());
     475    sb.append("\n");
     476    return sb.toString();
     477  }
     478
     479  @Override
     480  public String getToolTipText() {
     481    return data.size() + " " + tr("images");
     482  }
     483
     484  // EditDataLayerChanged
     485  @Override
     486  public void editLayerChanged(OsmDataLayer oldLayer, OsmDataLayer newLayer) {
     487    if (oldLayer == null && newLayer != null) {
     488      newLayer.data.addDataSetListener(this);
     489
     490    } else if (oldLayer != null && newLayer == null) {
     491      oldLayer.data.removeDataSetListener(this);
     492    }
     493  }
     494
     495  /**
     496   * When more data is downloaded, a delayed update is thrown, in order to wait
     497   * for the data bounds to be set.
     498   *
     499   * @param event
     500   */
     501  @Override
     502  public void dataChanged(DataChangedEvent event) {
     503    Main.worker.submit(new delayedDownload());
     504  }
     505
     506  private class delayedDownload extends Thread {
     507
    181508    @Override
    182     public void destroy() {
    183         MapillaryMainDialog.getInstance().setImage(null);
    184         MapillaryMainDialog.getInstance().updateImage();
    185         data.getImages().clear();
    186         MapillaryLayer.INSTANCE = null;
    187         MapillaryData.INSTANCE = null;
    188         MapillaryPlugin.setMenuEnabled(MapillaryPlugin.EXPORT_MENU, false);
    189         MapillaryPlugin.setMenuEnabled(MapillaryPlugin.ZOOM_MENU, false);
    190         Main.map.mapView.removeMouseListener(mouseAdapter);
    191         Main.map.mapView.removeMouseMotionListener(mouseAdapter);
    192         MapView.removeEditLayerChangeListener(this);
    193         if (Main.map.mapView.getEditLayer() != null)
    194             Main.map.mapView.getEditLayer().data.removeDataSetListener(this);
    195         super.destroy();
    196     }
    197 
    198     /**
    199      * Returns true any of the images from the database has been modified.
    200      */
    201     @Override
    202     public boolean isModified() {
    203         for (MapillaryAbstractImage image : data.getImages())
    204             if (image.isModified())
    205                 return true;
    206         return false;
    207     }
    208 
    209     @Override
    210     public void setVisible(boolean visible) {
    211         super.setVisible(visible);
    212         for (MapillaryAbstractImage img : data.getImages())
    213             img.setVisible(visible);
    214         MapillaryFilterDialog.getInstance().refresh();
    215     }
    216 
    217     /**
    218      * Replies background color for downloaded areas.
    219      *
    220      * @return background color for downloaded areas. Black by default
    221      */
    222     private Color getBackgroundColor() {
    223         return Main.pref.getColor(marktr("background"), Color.BLACK);
    224     }
    225 
    226     /**
    227      * Replies background color for non-downloaded areas.
    228      *
    229      * @return background color for non-downloaded areas. Yellow by default
    230      */
    231     private Color getOutsideColor() {
    232         return Main.pref.getColor(marktr("outside downloaded area"),
    233                 Color.YELLOW);
    234     }
    235 
    236     /**
    237      * Initialize the hatch pattern used to paint the non-downloaded area
    238      */
    239     private void createHatchTexture() {
    240         BufferedImage bi = new BufferedImage(15, 15,
    241                 BufferedImage.TYPE_INT_ARGB);
    242         Graphics2D big = bi.createGraphics();
    243         big.setColor(getBackgroundColor());
    244         Composite comp = AlphaComposite.getInstance(AlphaComposite.SRC_OVER,
    245                 0.3f);
    246         big.setComposite(comp);
    247         big.fillRect(0, 0, 15, 15);
    248         big.setColor(getOutsideColor());
    249         big.drawLine(0, 15, 15, 0);
    250         Rectangle r = new Rectangle(0, 0, 15, 15);
    251         hatched = new TexturePaint(bi, r);
    252     }
    253 
    254     /**
    255      * Paints the database in the map.
    256      */
    257     @Override
    258     public synchronized void paint(Graphics2D g, MapView mv, Bounds box) {
    259         if (Main.map.mapView.getActiveLayer() == this) {
    260             Rectangle b = mv.getBounds();
    261             // on some platforms viewport bounds seem to be offset from the
    262             // left,
    263             // over-grow it just to be sure
    264             b.grow(100, 100);
    265             Area a = new Area(b);
    266             // now successively subtract downloaded areas
    267             for (Bounds bounds : this.bounds) {
    268                 Point p1 = mv.getPoint(bounds.getMin());
    269                 Point p2 = mv.getPoint(bounds.getMax());
    270                 Rectangle r = new Rectangle(Math.min(p1.x, p2.x), Math.min(
    271                         p1.y, p2.y), Math.abs(p2.x - p1.x), Math.abs(p2.y
    272                         - p1.y));
    273                 a.subtract(new Area(r));
    274             }
    275             // paint remainder
    276             g.setPaint(hatched);
    277             g.fill(a);
    278         }
    279 
    280         // Draw colored lines
    281         MapillaryLayer.BLUE = null;
    282         MapillaryLayer.RED = null;
    283         MapillaryMainDialog.getInstance().blueButton.setEnabled(false);
    284         MapillaryMainDialog.getInstance().redButton.setEnabled(false);
    285 
    286         // Sets blue and red lines and enables/disables the buttons
    287         if (data.getSelectedImage() != null) {
    288             MapillaryImage[] closestImages = getClosestImagesFromDifferentSequences();
    289             Point selected = mv.getPoint(data.getSelectedImage().getLatLon());
    290             if (closestImages[0] != null) {
    291                 MapillaryLayer.BLUE = closestImages[0];
    292                 g.setColor(Color.BLUE);
    293                 g.drawLine(mv.getPoint(closestImages[0].getLatLon()).x,
    294                         mv.getPoint(closestImages[0].getLatLon()).y,
    295                         selected.x, selected.y);
    296                 MapillaryMainDialog.getInstance().blueButton.setEnabled(true);
    297             }
    298             if (closestImages[1] != null) {
    299                 MapillaryLayer.RED = closestImages[1];
    300                 g.setColor(Color.RED);
    301                 g.drawLine(mv.getPoint(closestImages[1].getLatLon()).x,
    302                         mv.getPoint(closestImages[1].getLatLon()).y,
    303                         selected.x, selected.y);
    304                 MapillaryMainDialog.getInstance().redButton.setEnabled(true);
    305             }
    306         }
    307         g.setColor(Color.WHITE);
    308         for (MapillaryAbstractImage imageAbs : data.getImages()) {
    309             if (!imageAbs.isVisible())
    310                 continue;
    311             Point p = mv.getPoint(imageAbs.getLatLon());
    312             if (imageAbs instanceof MapillaryImage) {
    313                 MapillaryImage image = (MapillaryImage) imageAbs;
    314                 Point nextp = null;
    315                 // Draw sequence line
    316                 if (image.getSequence() != null) {
    317                     MapillaryImage tempImage = image.next();
    318                     while (tempImage != null) {
    319                         if (tempImage.isVisible()) {
    320                             nextp = mv.getPoint(tempImage.getLatLon());
    321                             break;
    322                         }
    323                         tempImage = tempImage.next();
    324                     }
    325                     if (nextp != null)
    326                         g.drawLine(p.x, p.y, nextp.x, nextp.y);
    327                 }
    328 
    329                 ImageIcon icon;
    330                 if (!data.getMultiSelectedImages().contains(image))
    331                     icon = MapillaryPlugin.MAP_ICON;
    332                 else
    333                     icon = MapillaryPlugin.MAP_ICON_SELECTED;
    334                 draw(g, image, icon, p);
    335                 if (!image.getSigns().isEmpty()) {
    336                     g.drawImage(MapillaryPlugin.MAP_SIGN.getImage(),
    337                             p.x + icon.getIconWidth() / 2,
    338                             p.y - icon.getIconHeight() / 2, Main.map.mapView);
    339                 }
    340             } else if (imageAbs instanceof MapillaryImportedImage) {
    341                 MapillaryImportedImage image = (MapillaryImportedImage) imageAbs;
    342                 ImageIcon icon;
    343                 if (!data.getMultiSelectedImages().contains(image))
    344                     icon = MapillaryPlugin.MAP_ICON_IMPORTED;
    345                 else
    346                     icon = MapillaryPlugin.MAP_ICON_SELECTED;
    347                 draw(g, image, icon, p);
    348             }
    349         }
    350     }
    351 
    352     /**
    353      * Draws the highlight of the icon.
    354      *
    355      * @param g
    356      * @param p
    357      * @param size
    358      */
    359     private void drawPointHighlight(Graphics2D g, Point p, int size) {
    360         Color oldColor = g.getColor();
    361         Color highlightColor = PaintColors.HIGHLIGHT.get();
    362         Color highlightColorTransparent = new Color(highlightColor.getRed(),
    363                 highlightColor.getGreen(), highlightColor.getBlue(), 100);
    364         g.setColor(highlightColorTransparent);
    365         int s = size + highlightPointRadius;
    366         while (s >= size) {
    367             int r = (int) Math.floor(s / 2d);
    368             g.fillRoundRect(p.x - r, p.y - r, s, s, r, r);
    369             s -= highlightStep;
    370         }
    371         g.setColor(oldColor);
    372     }
    373 
    374     /**
    375      * Draws the given icon of an image. Also checks if the mouse is over the
    376      * image.
    377      *
    378      * @param g
    379      * @param image
    380      * @param icon
    381      * @param p
    382      */
    383     private void draw(Graphics2D g, MapillaryAbstractImage image,
    384             ImageIcon icon, Point p) {
    385         Image imagetemp = icon.getImage();
    386         BufferedImage bi = (BufferedImage) imagetemp;
    387         int width = icon.getIconWidth();
    388         int height = icon.getIconHeight();
    389 
    390         // Rotate the image
    391         double rotationRequired = Math.toRadians(image.getCa());
    392         double locationX = width / 2;
    393         double locationY = height / 2;
    394         AffineTransform tx = AffineTransform.getRotateInstance(
    395                 rotationRequired, locationX, locationY);
    396         AffineTransformOp op = new AffineTransformOp(tx,
    397                 AffineTransformOp.TYPE_BILINEAR);
    398 
    399         g.drawImage(op.filter(bi, null), p.x - (width / 2), p.y - (height / 2),
    400                 Main.map.mapView);
    401         if (data.getHoveredImage() == image) {
    402             drawPointHighlight(g, p, 16);
    403         }
    404     }
    405 
    406     @Override
    407     public Icon getIcon() {
    408         return MapillaryPlugin.ICON16;
    409     }
    410 
    411     @Override
    412     public boolean isMergable(Layer other) {
    413         return false;
    414     }
    415 
    416     @Override
    417     public void mergeFrom(Layer from) {
    418         throw new UnsupportedOperationException(
    419                 "This layer does not support merging yet");
    420     }
    421 
    422     @Override
    423     public Action[] getMenuEntries() {
    424         List<Action> actions = new ArrayList<>();
    425         actions.add(LayerListDialog.getInstance().createShowHideLayerAction());
    426         actions.add(LayerListDialog.getInstance().createDeleteLayerAction());
    427         actions.add(new LayerListPopup.InfoAction(this));
    428         return actions.toArray(new Action[actions.size()]);
    429     }
    430 
    431     /**
    432      * Returns the 2 closest images belonging to a different sequence.
    433      *
    434      * @return
    435      */
    436     private MapillaryImage[] getClosestImagesFromDifferentSequences() {
    437         if (!(data.getSelectedImage() instanceof MapillaryImage))
    438             return new MapillaryImage[2];
    439         MapillaryImage selected = (MapillaryImage) data.getSelectedImage();
    440         MapillaryImage[] ret = new MapillaryImage[2];
    441         double[] distances = { SEQUENCE_MAX_JUMP_DISTANCE,
    442                 SEQUENCE_MAX_JUMP_DISTANCE };
    443         LatLon selectedCoords = data.getSelectedImage().getLatLon();
    444         for (MapillaryAbstractImage imagePrev : data.getImages()) {
    445             if (!(imagePrev instanceof MapillaryImage))
    446                 continue;
    447             if (!imagePrev.isVisible())
    448                 continue;
    449             MapillaryImage image = (MapillaryImage) imagePrev;
    450             if (image.getLatLon().greatCircleDistance(selectedCoords) < SEQUENCE_MAX_JUMP_DISTANCE
    451                     && selected.getSequence() != image.getSequence()) {
    452                 if ((ret[0] == null && ret[1] == null)
    453                         || (image.getLatLon().greatCircleDistance(
    454                                 selectedCoords) < distances[0] && (ret[1] == null || image
    455                                 .getSequence() != ret[1].getSequence()))) {
    456                     ret[0] = image;
    457                     distances[0] = image.getLatLon().greatCircleDistance(
    458                             selectedCoords);
    459                 } else if ((ret[1] == null || image.getLatLon()
    460                         .greatCircleDistance(selectedCoords) < distances[1])
    461                         && image.getSequence() != ret[0].getSequence()) {
    462                     ret[1] = image;
    463                     distances[1] = image.getLatLon().greatCircleDistance(
    464                             selectedCoords);
    465                 }
    466             }
    467         }
    468         // Predownloads the thumbnails
    469         if (ret[0] != null)
    470             new MapillaryCache(ret[0].getKey(), MapillaryCache.Type.THUMBNAIL)
    471                     .submit(data, false);
    472         if (ret[1] != null)
    473             new MapillaryCache(ret[1].getKey(), MapillaryCache.Type.THUMBNAIL)
    474                     .submit(data, false);
    475         return ret;
    476     }
    477 
    478     @Override
    479     public Object getInfoComponent() {
    480         StringBuilder sb = new StringBuilder();
    481         sb.append(tr("Mapillary layer"));
    482         sb.append("\n");
    483         sb.append(tr("Total images:"));
    484         sb.append(" ");
    485         sb.append(data.size());
    486         sb.append("\n");
    487         return sb.toString();
    488     }
    489 
    490     @Override
    491     public String getToolTipText() {
    492         return data.size() + " " + tr("images");
    493     }
    494 
    495     // EditDataLayerChanged
    496     @Override
    497     public void editLayerChanged(OsmDataLayer oldLayer, OsmDataLayer newLayer) {
    498         if (oldLayer == null && newLayer != null) {
    499             newLayer.data.addDataSetListener(this);
    500 
    501         } else if (oldLayer != null && newLayer == null) {
    502             oldLayer.data.removeDataSetListener(this);
    503         }
    504     }
    505 
    506     /**
    507      * When more data is downloaded, a delayed update is thrown, in order to
    508      * wait for the data bounds to be set.
    509      *
    510      * @param event
    511      */
    512     @Override
    513     public void dataChanged(DataChangedEvent event) {
    514         Main.worker.submit(new delayedDownload());
    515     }
    516 
    517     private class delayedDownload extends Thread {
    518 
    519         @Override
    520         public void run() {
    521             try {
    522                 sleep(1000);
    523             } catch (InterruptedException e) {
    524                 Main.error(e);
    525             }
    526             MapillaryLayer.getInstance().download();
    527         }
    528     }
    529 
    530     @Override
    531     public void primitivesAdded(PrimitivesAddedEvent event) {
    532     }
    533 
    534     @Override
    535     public void primitivesRemoved(PrimitivesRemovedEvent event) {
    536     }
    537 
    538     @Override
    539     public void tagsChanged(TagsChangedEvent event) {
    540     }
    541 
    542     @Override
    543     public void nodeMoved(NodeMovedEvent event) {
    544     }
    545 
    546     @Override
    547     public void wayNodesChanged(WayNodesChangedEvent event) {
    548     }
    549 
    550     @Override
    551     public void relationMembersChanged(RelationMembersChangedEvent event) {
    552     }
    553 
    554     @Override
    555     public void otherDatasetChange(AbstractDatasetChangedEvent event) {
    556     }
    557 
    558     @Override
    559     public void visitBoundingBox(BoundingXYVisitor v) {
    560     }
    561 
    562     @Override
    563     public void activeLayerChange(Layer oldLayer, Layer newLayer) {
    564         if (newLayer == this) {
    565             if (data.size() > 0)
    566                 Main.map.statusLine.setHelpText(tr("Total images: {0}",
    567                         data.size()));
    568             else
    569                 Main.map.statusLine.setHelpText(tr("No images found"));
    570         }
    571     }
    572 
    573     @Override
    574     public void layerAdded(Layer newLayer) {
    575     }
    576 
    577     @Override
    578     public void layerRemoved(Layer oldLayer) {
    579     }
     509    public void run() {
     510      try {
     511        sleep(1000);
     512      } catch (InterruptedException e) {
     513        Main.error(e);
     514      }
     515      MapillaryLayer.getInstance().download();
     516    }
     517  }
     518
     519  @Override
     520  public void primitivesAdded(PrimitivesAddedEvent event) {
     521  }
     522
     523  @Override
     524  public void primitivesRemoved(PrimitivesRemovedEvent event) {
     525  }
     526
     527  @Override
     528  public void tagsChanged(TagsChangedEvent event) {
     529  }
     530
     531  @Override
     532  public void nodeMoved(NodeMovedEvent event) {
     533  }
     534
     535  @Override
     536  public void wayNodesChanged(WayNodesChangedEvent event) {
     537  }
     538
     539  @Override
     540  public void relationMembersChanged(RelationMembersChangedEvent event) {
     541  }
     542
     543  @Override
     544  public void otherDatasetChange(AbstractDatasetChangedEvent event) {
     545  }
     546
     547  @Override
     548  public void visitBoundingBox(BoundingXYVisitor v) {
     549  }
     550
     551  @Override
     552  public void activeLayerChange(Layer oldLayer, Layer newLayer) {
     553    if (newLayer == this) {
     554      if (data.size() > 0)
     555        Main.map.statusLine.setHelpText(tr("Total images: {0}", data.size()));
     556      else
     557        Main.map.statusLine.setHelpText(tr("No images found"));
     558    }
     559  }
     560
     561  @Override
     562  public void layerAdded(Layer newLayer) {
     563  }
     564
     565  @Override
     566  public void layerRemoved(Layer oldLayer) {
     567  }
    580568}
  • applications/editors/josm/plugins/mapillary/src/org/openstreetmap/josm/plugins/mapillary/MapillaryMouseAdapter.java

    r31333 r31350  
    2222 */
    2323public class MapillaryMouseAdapter extends MouseAdapter {
    24     private Point start;
    25     private int lastButton;
    26     private MapillaryAbstractImage closest;
    27     private MapillaryAbstractImage lastClicked;
    28     private MapillaryData mapillaryData;
    29     private MapillaryRecord record;
    30 
    31     private boolean nothingHighlighted;
    32     private boolean imageHighlighted = false;
    33 
    34     public MapillaryMouseAdapter() {
    35         mapillaryData = MapillaryData.getInstance();
    36         record = MapillaryRecord.getInstance();
    37     }
    38 
    39     @Override
    40     public void mousePressed(MouseEvent e) {
    41         lastButton = e.getButton();
    42         if (e.getButton() != MouseEvent.BUTTON1)
    43             return;
    44         MapillaryAbstractImage closestTemp = getClosest(e.getPoint());
    45         if (Main.map.mapView.getActiveLayer() instanceof OsmDataLayer
    46                 && closestTemp != null
    47                 && Main.map.mapMode == Main.map.mapModeSelect) {
    48             this.lastClicked = this.closest;
    49             MapillaryData.getInstance().setSelectedImage(closestTemp);
    50             return;
    51         } else if (Main.map.mapView.getActiveLayer() != MapillaryLayer
    52                 .getInstance())
    53             return;
    54         if (closestTemp instanceof MapillaryImage || closestTemp == null) {
    55             MapillaryImage closest = (MapillaryImage) closestTemp;
    56             // Doube click
    57             if (e.getClickCount() == 2
    58                     && mapillaryData.getSelectedImage() != null
    59                     && closest != null) {
    60                 for (MapillaryAbstractImage img : closest.getSequence()
    61                         .getImages()) {
    62                     mapillaryData.addMultiSelectedImage(img);
    63                 }
    64             }
    65             this.start = e.getPoint();
    66             this.lastClicked = this.closest;
    67             this.closest = closest;
    68             if (mapillaryData.getMultiSelectedImages().contains(closest))
    69                 return;
    70             // ctrl+click
    71             if (e.getModifiers() == (MouseEvent.BUTTON1_MASK | MouseEvent.CTRL_MASK)
    72                     && closest != null)
    73                 mapillaryData.addMultiSelectedImage(closest);
    74             // shift + click
    75             else if (e.getModifiers() == (MouseEvent.BUTTON1_MASK | MouseEvent.SHIFT_MASK)
    76                     && this.closest instanceof MapillaryImage
    77                     && this.lastClicked instanceof MapillaryImage) {
    78                 if (this.closest != null
    79                         && this.lastClicked != null
    80                         && ((MapillaryImage) this.closest).getSequence() == ((MapillaryImage) this.lastClicked)
    81                                 .getSequence()) {
    82                     int i = ((MapillaryImage) this.closest).getSequence()
    83                             .getImages().indexOf(this.closest);
    84                     int j = ((MapillaryImage) this.lastClicked).getSequence()
    85                             .getImages().indexOf(this.lastClicked);
    86                     if (i < j)
    87                         mapillaryData
    88                                 .addMultiSelectedImage(new ArrayList<MapillaryAbstractImage>(
    89                                         ((MapillaryImage) this.closest)
    90                                                 .getSequence().getImages()
    91                                                 .subList(i, j + 1)));
    92                     else
    93                         mapillaryData
    94                                 .addMultiSelectedImage(new ArrayList<MapillaryAbstractImage>(
    95                                         ((MapillaryImage) this.closest)
    96                                                 .getSequence().getImages()
    97                                                 .subList(j, i + 1)));
    98                 }
    99                 // click
    100             } else
    101                 mapillaryData.setSelectedImage(closest);
    102             // If you select an imported image
    103         } else if (closestTemp instanceof MapillaryImportedImage) {
    104             MapillaryImportedImage closest = (MapillaryImportedImage) closestTemp;
    105             this.start = e.getPoint();
    106             this.lastClicked = this.closest;
    107             this.closest = closest;
    108             if (mapillaryData.getMultiSelectedImages().contains(closest))
    109                 return;
    110             if (e.getModifiers() == (MouseEvent.BUTTON1_MASK | MouseEvent.CTRL_MASK)
    111                     && closest != null)
    112                 mapillaryData.addMultiSelectedImage(closest);
    113             else
    114                 mapillaryData.setSelectedImage(closest);
    115         }
    116     }
    117 
    118     private MapillaryAbstractImage getClosest(Point clickPoint) {
    119         double snapDistance = 10;
    120         double minDistance = Double.MAX_VALUE;
    121         MapillaryAbstractImage closest = null;
    122         for (MapillaryAbstractImage image : mapillaryData.getImages()) {
    123             Point imagePoint = Main.map.mapView.getPoint(image.getLatLon());
    124             imagePoint.setLocation(imagePoint.getX(), imagePoint.getY());
    125             double dist = clickPoint.distanceSq(imagePoint);
    126             if (minDistance > dist
    127                     && clickPoint.distance(imagePoint) < snapDistance
    128                     && image.isVisible()) {
    129                 minDistance = dist;
    130                 closest = image;
    131             }
    132         }
    133         return closest;
    134     }
    135 
    136     @Override
    137     public void mouseDragged(MouseEvent e) {
    138         if (Main.map.mapView.getActiveLayer() != MapillaryLayer.getInstance())
    139             return;
    140 
    141         if (!Main.pref.getBoolean("mapillary.developer"))
    142             for (MapillaryAbstractImage img : MapillaryData.getInstance()
    143                     .getMultiSelectedImages()) {
    144                 if (img instanceof MapillaryImage)
    145                     return;
    146             }
    147         if (MapillaryData.getInstance().getSelectedImage() != null) {
    148             if (lastButton == MouseEvent.BUTTON1 && !e.isShiftDown()) {
    149                 LatLon to = Main.map.mapView.getLatLon(e.getX(), e.getY());
    150                 LatLon from = Main.map.mapView.getLatLon(start.getX(),
    151                         start.getY());
    152                 for (MapillaryAbstractImage img : MapillaryData.getInstance()
    153                         .getMultiSelectedImages()) {
    154 
    155                     img.move(to.getX() - from.getX(), to.getY() - from.getY());
    156                 }
    157                 Main.map.repaint();
    158             } else if (lastButton == MouseEvent.BUTTON1 && e.isShiftDown()) {
    159                 this.closest.turn(Math.toDegrees(Math.atan2(
    160                         (e.getX() - start.x), -(e.getY() - start.y)))
    161                         - closest.getTempCa());
    162                 for (MapillaryAbstractImage img : MapillaryData.getInstance()
    163                         .getMultiSelectedImages()) {
    164                     img.turn(Math.toDegrees(Math.atan2((e.getX() - start.x),
    165                             -(e.getY() - start.y))) - closest.getTempCa());
    166                 }
    167                 Main.map.repaint();
    168             }
    169         }
    170     }
    171 
    172     @Override
    173     public void mouseReleased(MouseEvent e) {
    174         if (mapillaryData.getSelectedImage() == null)
    175             return;
    176         if (mapillaryData.getSelectedImage().getTempCa() != mapillaryData
    177                 .getSelectedImage().getCa()) {
    178             double from = mapillaryData.getSelectedImage().getTempCa();
    179             double to = mapillaryData.getSelectedImage().getCa();
    180             record.addCommand(new CommandTurnImage(mapillaryData
    181                     .getMultiSelectedImages(), to - from));
    182         } else if (mapillaryData.getSelectedImage().getTempLatLon() != mapillaryData
    183                 .getSelectedImage().getLatLon()) {
    184             LatLon from = mapillaryData.getSelectedImage().getTempLatLon();
    185             LatLon to = mapillaryData.getSelectedImage().getLatLon();
    186             record.addCommand(new CommandMoveImage(mapillaryData
    187                     .getMultiSelectedImages(), to.getX() - from.getX(), to
    188                     .getY() - from.getY()));
    189         }
    190         for (MapillaryAbstractImage img : mapillaryData
    191                 .getMultiSelectedImages()) {
    192             if (img != null)
    193                 img.stopMoving();
    194         }
    195     }
    196 
    197     /**
    198      * Checks if the mouse is over pictures.
    199      */
    200     @Override
    201     public void mouseMoved(MouseEvent e) {
    202         MapillaryAbstractImage closestTemp = getClosest(e.getPoint());
    203         if (Main.map.mapView.getActiveLayer() instanceof OsmDataLayer
    204                 && Main.map.mapMode != Main.map.mapModeSelect)
    205             return;
    206         if (closestTemp != null
    207                 && Main.map.mapView.getActiveLayer() instanceof OsmDataLayer
    208                 && !imageHighlighted) {
    209             Main.map.mapMode.putValue("active", Boolean.FALSE);
    210             imageHighlighted = true;
    211 
    212         } else if (closestTemp == null
    213                 && Main.map.mapView.getActiveLayer() instanceof OsmDataLayer
    214                 && imageHighlighted && nothingHighlighted) {
    215             nothingHighlighted = false;
    216             Main.map.mapMode.putValue("active", Boolean.TRUE);
    217 
    218         } else if (imageHighlighted && !nothingHighlighted
    219                 && Main.map.mapView != null
    220                 && Main.map.mapView.getEditLayer().data != null
    221                 && Main.map.mapView.getActiveLayer() instanceof OsmDataLayer) {
    222 
    223             for (OsmPrimitive primivitive : Main.map.mapView.getEditLayer().data
    224                     .allPrimitives()) {
    225                 primivitive.setHighlighted(false);
    226             }
    227             imageHighlighted = false;
    228             nothingHighlighted = true;
    229         }
    230 
    231         if (MapillaryData.getInstance().getHoveredImage() != closestTemp
    232                 && closestTemp != null) {
    233             MapillaryData.getInstance().setHighlightedImage(closestTemp);
    234             MapillaryMainDialog.getInstance().setImage(closestTemp);
    235             MapillaryMainDialog.getInstance().updateImage();
    236         } else if (MapillaryData.getInstance().getHoveredImage() != closestTemp
    237                 && closestTemp == null) {
    238             MapillaryData.getInstance().setHighlightedImage(null);
    239             MapillaryMainDialog.getInstance().setImage(
    240                     MapillaryData.getInstance().getSelectedImage());
    241             MapillaryMainDialog.getInstance().updateImage();
    242         }
    243         MapillaryData.getInstance().dataUpdated();
    244     }
     24  private Point start;
     25  private int lastButton;
     26  private MapillaryAbstractImage closest;
     27  private MapillaryAbstractImage lastClicked;
     28  private MapillaryData mapillaryData;
     29  private MapillaryRecord record;
     30
     31  private boolean nothingHighlighted;
     32  private boolean imageHighlighted = false;
     33
     34  public MapillaryMouseAdapter() {
     35    mapillaryData = MapillaryData.getInstance();
     36    record = MapillaryRecord.getInstance();
     37  }
     38
     39  @Override
     40  public void mousePressed(MouseEvent e) {
     41    lastButton = e.getButton();
     42    if (e.getButton() != MouseEvent.BUTTON1)
     43      return;
     44    MapillaryAbstractImage closestTemp = getClosest(e.getPoint());
     45    if (Main.map.mapView.getActiveLayer() instanceof OsmDataLayer
     46        && closestTemp != null && Main.map.mapMode == Main.map.mapModeSelect) {
     47      this.lastClicked = this.closest;
     48      MapillaryData.getInstance().setSelectedImage(closestTemp);
     49      return;
     50    } else if (Main.map.mapView.getActiveLayer() != MapillaryLayer
     51        .getInstance())
     52      return;
     53    if (closestTemp instanceof MapillaryImage || closestTemp == null) {
     54      MapillaryImage closest = (MapillaryImage) closestTemp;
     55      // Doube click
     56      if (e.getClickCount() == 2 && mapillaryData.getSelectedImage() != null
     57          && closest != null) {
     58        for (MapillaryAbstractImage img : closest.getSequence().getImages()) {
     59          mapillaryData.addMultiSelectedImage(img);
     60        }
     61      }
     62      this.start = e.getPoint();
     63      this.lastClicked = this.closest;
     64      this.closest = closest;
     65      if (mapillaryData.getMultiSelectedImages().contains(closest))
     66        return;
     67      // ctrl+click
     68      if (e.getModifiers() == (MouseEvent.BUTTON1_MASK | MouseEvent.CTRL_MASK)
     69          && closest != null)
     70        mapillaryData.addMultiSelectedImage(closest);
     71      // shift + click
     72      else if (e.getModifiers() == (MouseEvent.BUTTON1_MASK | MouseEvent.SHIFT_MASK)
     73          && this.closest instanceof MapillaryImage
     74          && this.lastClicked instanceof MapillaryImage) {
     75        if (this.closest != null
     76            && this.lastClicked != null
     77            && ((MapillaryImage) this.closest).getSequence() == ((MapillaryImage) this.lastClicked)
     78                .getSequence()) {
     79          int i = ((MapillaryImage) this.closest).getSequence().getImages()
     80              .indexOf(this.closest);
     81          int j = ((MapillaryImage) this.lastClicked).getSequence().getImages()
     82              .indexOf(this.lastClicked);
     83          if (i < j)
     84            mapillaryData
     85                .addMultiSelectedImage(new ArrayList<MapillaryAbstractImage>(
     86                    ((MapillaryImage) this.closest).getSequence().getImages()
     87                        .subList(i, j + 1)));
     88          else
     89            mapillaryData
     90                .addMultiSelectedImage(new ArrayList<MapillaryAbstractImage>(
     91                    ((MapillaryImage) this.closest).getSequence().getImages()
     92                        .subList(j, i + 1)));
     93        }
     94        // click
     95      } else
     96        mapillaryData.setSelectedImage(closest);
     97      // If you select an imported image
     98    } else if (closestTemp instanceof MapillaryImportedImage) {
     99      MapillaryImportedImage closest = (MapillaryImportedImage) closestTemp;
     100      this.start = e.getPoint();
     101      this.lastClicked = this.closest;
     102      this.closest = closest;
     103      if (mapillaryData.getMultiSelectedImages().contains(closest))
     104        return;
     105      if (e.getModifiers() == (MouseEvent.BUTTON1_MASK | MouseEvent.CTRL_MASK)
     106          && closest != null)
     107        mapillaryData.addMultiSelectedImage(closest);
     108      else
     109        mapillaryData.setSelectedImage(closest);
     110    }
     111  }
     112
     113  private MapillaryAbstractImage getClosest(Point clickPoint) {
     114    double snapDistance = 10;
     115    double minDistance = Double.MAX_VALUE;
     116    MapillaryAbstractImage closest = null;
     117    for (MapillaryAbstractImage image : mapillaryData.getImages()) {
     118      Point imagePoint = Main.map.mapView.getPoint(image.getLatLon());
     119      imagePoint.setLocation(imagePoint.getX(), imagePoint.getY());
     120      double dist = clickPoint.distanceSq(imagePoint);
     121      if (minDistance > dist && clickPoint.distance(imagePoint) < snapDistance
     122          && image.isVisible()) {
     123        minDistance = dist;
     124        closest = image;
     125      }
     126    }
     127    return closest;
     128  }
     129
     130  @Override
     131  public void mouseDragged(MouseEvent e) {
     132    if (Main.map.mapView.getActiveLayer() != MapillaryLayer.getInstance())
     133      return;
     134
     135    if (!Main.pref.getBoolean("mapillary.developer"))
     136      for (MapillaryAbstractImage img : MapillaryData.getInstance()
     137          .getMultiSelectedImages()) {
     138        if (img instanceof MapillaryImage)
     139          return;
     140      }
     141    if (MapillaryData.getInstance().getSelectedImage() != null) {
     142      if (lastButton == MouseEvent.BUTTON1 && !e.isShiftDown()) {
     143        LatLon to = Main.map.mapView.getLatLon(e.getX(), e.getY());
     144        LatLon from = Main.map.mapView.getLatLon(start.getX(), start.getY());
     145        for (MapillaryAbstractImage img : MapillaryData.getInstance()
     146            .getMultiSelectedImages()) {
     147
     148          img.move(to.getX() - from.getX(), to.getY() - from.getY());
     149        }
     150        Main.map.repaint();
     151      } else if (lastButton == MouseEvent.BUTTON1 && e.isShiftDown()) {
     152        this.closest.turn(Math.toDegrees(Math.atan2((e.getX() - start.x),
     153            -(e.getY() - start.y)))
     154            - closest.getTempCa());
     155        for (MapillaryAbstractImage img : MapillaryData.getInstance()
     156            .getMultiSelectedImages()) {
     157          img.turn(Math.toDegrees(Math.atan2((e.getX() - start.x),
     158              -(e.getY() - start.y))) - closest.getTempCa());
     159        }
     160        Main.map.repaint();
     161      }
     162    }
     163  }
     164
     165  @Override
     166  public void mouseReleased(MouseEvent e) {
     167    if (mapillaryData.getSelectedImage() == null)
     168      return;
     169    if (mapillaryData.getSelectedImage().getTempCa() != mapillaryData
     170        .getSelectedImage().getCa()) {
     171      double from = mapillaryData.getSelectedImage().getTempCa();
     172      double to = mapillaryData.getSelectedImage().getCa();
     173      record.addCommand(new CommandTurnImage(mapillaryData
     174          .getMultiSelectedImages(), to - from));
     175    } else if (mapillaryData.getSelectedImage().getTempLatLon() != mapillaryData
     176        .getSelectedImage().getLatLon()) {
     177      LatLon from = mapillaryData.getSelectedImage().getTempLatLon();
     178      LatLon to = mapillaryData.getSelectedImage().getLatLon();
     179      record.addCommand(new CommandMoveImage(mapillaryData
     180          .getMultiSelectedImages(), to.getX() - from.getX(), to.getY()
     181          - from.getY()));
     182    }
     183    for (MapillaryAbstractImage img : mapillaryData.getMultiSelectedImages()) {
     184      if (img != null)
     185        img.stopMoving();
     186    }
     187  }
     188
     189  /**
     190   * Checks if the mouse is over pictures.
     191   */
     192  @Override
     193  public void mouseMoved(MouseEvent e) {
     194    MapillaryAbstractImage closestTemp = getClosest(e.getPoint());
     195    if (Main.map.mapView.getActiveLayer() instanceof OsmDataLayer
     196        && Main.map.mapMode != Main.map.mapModeSelect)
     197      return;
     198    if (closestTemp != null
     199        && Main.map.mapView.getActiveLayer() instanceof OsmDataLayer
     200        && !imageHighlighted) {
     201      Main.map.mapMode.putValue("active", Boolean.FALSE);
     202      imageHighlighted = true;
     203
     204    } else if (closestTemp == null
     205        && Main.map.mapView.getActiveLayer() instanceof OsmDataLayer
     206        && imageHighlighted && nothingHighlighted) {
     207      nothingHighlighted = false;
     208      Main.map.mapMode.putValue("active", Boolean.TRUE);
     209
     210    } else if (imageHighlighted && !nothingHighlighted
     211        && Main.map.mapView != null
     212        && Main.map.mapView.getEditLayer().data != null
     213        && Main.map.mapView.getActiveLayer() instanceof OsmDataLayer) {
     214
     215      for (OsmPrimitive primivitive : Main.map.mapView.getEditLayer().data
     216          .allPrimitives()) {
     217        primivitive.setHighlighted(false);
     218      }
     219      imageHighlighted = false;
     220      nothingHighlighted = true;
     221    }
     222
     223    if (MapillaryData.getInstance().getHoveredImage() != closestTemp
     224        && closestTemp != null) {
     225      MapillaryData.getInstance().setHighlightedImage(closestTemp);
     226      MapillaryMainDialog.getInstance().setImage(closestTemp);
     227      MapillaryMainDialog.getInstance().updateImage();
     228    } else if (MapillaryData.getInstance().getHoveredImage() != closestTemp
     229        && closestTemp == null) {
     230      MapillaryData.getInstance().setHighlightedImage(null);
     231      MapillaryMainDialog.getInstance().setImage(
     232          MapillaryData.getInstance().getSelectedImage());
     233      MapillaryMainDialog.getInstance().updateImage();
     234    }
     235    MapillaryData.getInstance().dataUpdated();
     236  }
    245237}
  • applications/editors/josm/plugins/mapillary/src/org/openstreetmap/josm/plugins/mapillary/MapillaryPlugin.java

    r31347 r31350  
    3333public class MapillaryPlugin extends Plugin implements EditLayerChangeListener {
    3434
    35     public static final ImageIcon ICON24 = new ImageProvider("icon24.png")
    36             .get();
    37     public static final ImageIcon ICON16 = new ImageProvider("icon16.png")
    38             .get();
    39     public static final ImageIcon MAP_ICON = new ImageProvider("mapicon.png")
    40             .get();
    41     public static final ImageIcon MAP_ICON_SELECTED = new ImageProvider(
    42             "mapiconselected.png").get();
    43     public static final ImageIcon MAP_ICON_IMPORTED = new ImageProvider(
    44             "mapiconimported.png").get();
    45     public static final ImageIcon MAP_SIGN = new ImageProvider("sign.png")
    46             .get();
    47     public static final int ICON_SIZE = 24;
     35  public static final ImageIcon ICON24 = new ImageProvider("icon24.png").get();
     36  public static final ImageIcon ICON16 = new ImageProvider("icon16.png").get();
     37  public static final ImageIcon MAP_ICON = new ImageProvider("mapicon.png")
     38      .get();
     39  public static final ImageIcon MAP_ICON_SELECTED = new ImageProvider(
     40      "mapiconselected.png").get();
     41  public static final ImageIcon MAP_ICON_IMPORTED = new ImageProvider(
     42      "mapiconimported.png").get();
     43  public static final ImageIcon MAP_SIGN = new ImageProvider("sign.png").get();
     44  public static final int ICON_SIZE = 24;
    4845
    49     public static CacheAccess<String, BufferedImageCacheEntry> CACHE;
     46  public static CacheAccess<String, BufferedImageCacheEntry> CACHE;
    5047
    51     private final MapillaryDownloadAction downloadAction;
    52     private final MapillaryExportAction exportAction;
    53     private final MapillaryImportAction importAction;
    54     private final MapillaryZoomAction zoomAction;
    55     private final MapillaryDownloadViewAction downloadViewAction;
     48  private final MapillaryDownloadAction downloadAction;
     49  private final MapillaryExportAction exportAction;
     50  private final MapillaryImportAction importAction;
     51  private final MapillaryZoomAction zoomAction;
     52  private final MapillaryDownloadViewAction downloadViewAction;
    5653
    57     public static JMenuItem DOWNLOAD_MENU;
    58     public static JMenuItem EXPORT_MENU;
    59     public static JMenuItem IMPORT_MENU;
    60     public static JMenuItem ZOOM_MENU;
    61     public static JMenuItem DOWNLOAD_VIEW_MENU;
     54  public static JMenuItem DOWNLOAD_MENU;
     55  public static JMenuItem EXPORT_MENU;
     56  public static JMenuItem IMPORT_MENU;
     57  public static JMenuItem ZOOM_MENU;
     58  public static JMenuItem DOWNLOAD_VIEW_MENU;
    6259
    63     public MapillaryPlugin(PluginInformation info) {
    64         super(info);
    65         downloadAction = new MapillaryDownloadAction();
    66         exportAction = new MapillaryExportAction();
    67         importAction = new MapillaryImportAction();
    68         zoomAction = new MapillaryZoomAction();
    69         downloadViewAction = new MapillaryDownloadViewAction();
     60  public MapillaryPlugin(PluginInformation info) {
     61    super(info);
     62    downloadAction = new MapillaryDownloadAction();
     63    exportAction = new MapillaryExportAction();
     64    importAction = new MapillaryImportAction();
     65    zoomAction = new MapillaryZoomAction();
     66    downloadViewAction = new MapillaryDownloadViewAction();
    7067
    71         if (Main.main != null) { // important for headless mode
    72             DOWNLOAD_MENU = MainMenu.add(Main.main.menu.imageryMenu,
    73                     downloadAction, false);
    74             EXPORT_MENU = MainMenu.add(Main.main.menu.fileMenu, exportAction,
    75                     false, 14);
    76             IMPORT_MENU = MainMenu.add(Main.main.menu.fileMenu, importAction,
    77                     false, 14);
    78             ZOOM_MENU = MainMenu
    79                     .add(Main.main.menu.viewMenu, zoomAction, false, 15);
    80             DOWNLOAD_VIEW_MENU = MainMenu.add(Main.main.menu.fileMenu,
    81                     downloadViewAction, false, 14);
    82         }
    83 
    84         EXPORT_MENU.setEnabled(false);
    85         DOWNLOAD_MENU.setEnabled(false);
    86         IMPORT_MENU.setEnabled(false);
    87         ZOOM_MENU.setEnabled(false);
    88         DOWNLOAD_VIEW_MENU.setEnabled(false);
    89 
    90         MapView.addEditLayerChangeListener(this);
    91         try {
    92             CACHE = JCSCacheManager.getCache("mapillary", 10, 10000,
    93                     this.getPluginDir() + "/cache/");
    94         } catch (IOException e) {
    95             Main.error(e);
    96         }
     68    if (Main.main != null) { // important for headless mode
     69      DOWNLOAD_MENU = MainMenu.add(Main.main.menu.imageryMenu, downloadAction,
     70          false);
     71      EXPORT_MENU = MainMenu.add(Main.main.menu.fileMenu, exportAction, false,
     72          14);
     73      IMPORT_MENU = MainMenu.add(Main.main.menu.fileMenu, importAction, false,
     74          14);
     75      ZOOM_MENU = MainMenu.add(Main.main.menu.viewMenu, zoomAction, false, 15);
     76      DOWNLOAD_VIEW_MENU = MainMenu.add(Main.main.menu.fileMenu,
     77          downloadViewAction, false, 14);
    9778    }
    9879
    99     /**
    100      * Called when the JOSM map frame is created or destroyed.
    101      */
    102     @Override
    103     public void mapFrameInitialized(MapFrame oldFrame, MapFrame newFrame) {
    104         if (oldFrame == null && newFrame != null) { // map frame added
    105             Main.map.addToggleDialog(MapillaryMainDialog.getInstance(), false);
    106             Main.map.addToggleDialog(MapillaryHistoryDialog.getInstance(),
    107                     false);
    108             Main.map.addToggleDialog(MapillaryFilterDialog.getInstance(), false);
    109             setMenuEnabled(DOWNLOAD_MENU, true);
    110             if (Main.pref.getBoolean("mapillary.download-manually"))
    111                 setMenuEnabled(DOWNLOAD_VIEW_MENU, true);
    112             setMenuEnabled(IMPORT_MENU, true);
    113         }
    114         if (oldFrame != null && newFrame == null) { // map frame destroyed
    115             MapillaryMainDialog.destroyInstance();
    116             MapillaryHistoryDialog.destroyInstance();
    117             MapillaryFilterDialog.destroyInstance();
    118             setMenuEnabled(DOWNLOAD_MENU, false);
    119             setMenuEnabled(DOWNLOAD_VIEW_MENU, false);
    120             setMenuEnabled(IMPORT_MENU, false);
    121         }
     80    EXPORT_MENU.setEnabled(false);
     81    DOWNLOAD_MENU.setEnabled(false);
     82    IMPORT_MENU.setEnabled(false);
     83    ZOOM_MENU.setEnabled(false);
     84    DOWNLOAD_VIEW_MENU.setEnabled(false);
     85
     86    MapView.addEditLayerChangeListener(this);
     87    try {
     88      CACHE = JCSCacheManager.getCache("mapillary", 10, 10000,
     89          this.getPluginDir() + "/cache/");
     90    } catch (IOException e) {
     91      Main.error(e);
    12292    }
     93  }
    12394
    124     public static void setMenuEnabled(JMenuItem menu, boolean value) {
    125         menu.setEnabled(value);
    126         menu.getAction().setEnabled(value);
     95  /**
     96   * Called when the JOSM map frame is created or destroyed.
     97   */
     98  @Override
     99  public void mapFrameInitialized(MapFrame oldFrame, MapFrame newFrame) {
     100    if (oldFrame == null && newFrame != null) { // map frame added
     101      Main.map.addToggleDialog(MapillaryMainDialog.getInstance(), false);
     102      Main.map.addToggleDialog(MapillaryHistoryDialog.getInstance(), false);
     103      Main.map.addToggleDialog(MapillaryFilterDialog.getInstance(), false);
     104      setMenuEnabled(DOWNLOAD_MENU, true);
     105      if (Main.pref.getBoolean("mapillary.download-manually"))
     106        setMenuEnabled(DOWNLOAD_VIEW_MENU, true);
     107      setMenuEnabled(IMPORT_MENU, true);
    127108    }
     109    if (oldFrame != null && newFrame == null) { // map frame destroyed
     110      MapillaryMainDialog.destroyInstance();
     111      MapillaryHistoryDialog.destroyInstance();
     112      MapillaryFilterDialog.destroyInstance();
     113      setMenuEnabled(DOWNLOAD_MENU, false);
     114      setMenuEnabled(DOWNLOAD_VIEW_MENU, false);
     115      setMenuEnabled(IMPORT_MENU, false);
     116    }
     117  }
    128118
    129     @Override
    130     public PreferenceSetting getPreferenceSetting() {
    131         return new MapillaryPreferenceSetting();
     119  public static void setMenuEnabled(JMenuItem menu, boolean value) {
     120    menu.setEnabled(value);
     121    menu.getAction().setEnabled(value);
     122  }
     123
     124  @Override
     125  public PreferenceSetting getPreferenceSetting() {
     126    return new MapillaryPreferenceSetting();
     127  }
     128
     129  @Override
     130  public void editLayerChanged(OsmDataLayer oldLayer, OsmDataLayer newLayer) {
     131    if (oldLayer == null && newLayer != null) {
     132    } else if (oldLayer != null && newLayer == null) {
    132133    }
    133 
    134     @Override
    135     public void editLayerChanged(OsmDataLayer oldLayer, OsmDataLayer newLayer) {
    136         if (oldLayer == null && newLayer != null) {
    137         } else if (oldLayer != null && newLayer == null) {
    138         }
    139     }
     134  }
    140135}
  • applications/editors/josm/plugins/mapillary/src/org/openstreetmap/josm/plugins/mapillary/MapillarySequence.java

    r31278 r31350  
    1212 */
    1313public class MapillarySequence {
    14     private final List<MapillaryImage> images;
    15     private final String key;
    16     private final long created_at;
     14  private final List<MapillaryImage> images;
     15  private final String key;
     16  private final long created_at;
    1717
    18     public MapillarySequence(String key, long created_at) {
    19         this.images = new ArrayList<>();
    20         this.key = key;
    21         this.created_at = created_at;
    22     }
     18  public MapillarySequence(String key, long created_at) {
     19    this.images = new ArrayList<>();
     20    this.key = key;
     21    this.created_at = created_at;
     22  }
    2323
    24     /**
    25      * Returns all MapillaryImages objects contained by this object.
    26      *
    27      * @return
    28      */
    29     public List<MapillaryImage> getImages() {
    30         return this.images;
    31     }
     24  /**
     25   * Returns all MapillaryImages objects contained by this object.
     26   *
     27   * @return
     28   */
     29  public List<MapillaryImage> getImages() {
     30    return this.images;
     31  }
    3232
    33     public long getCreatedAt() {
    34         return created_at;
    35     }
     33  public long getCreatedAt() {
     34    return created_at;
     35  }
    3636
    37     /**
    38      * Adds a new MapillaryImage object to this object.
    39      *
    40      * @param image
    41      */
    42     public synchronized void add(MapillaryImage image) {
    43         this.images.add(image);
    44     }
     37  /**
     38   * Adds a new MapillaryImage object to this object.
     39   *
     40   * @param image
     41   */
     42  public synchronized void add(MapillaryImage image) {
     43    this.images.add(image);
     44  }
    4545
    46     public String getKey() {
    47         return this.key;
    48     }
     46  public String getKey() {
     47    return this.key;
     48  }
    4949
    50     /**
    51      * Adds a set of MapillaryImage objects to this object.
    52      *
    53      * @param images
    54      */
    55     public synchronized void add(List<MapillaryImage> images) {
    56         for (MapillaryImage image : images)
    57             add(image);
    58     }
     50  /**
     51   * Adds a set of MapillaryImage objects to this object.
     52   *
     53   * @param images
     54   */
     55  public synchronized void add(List<MapillaryImage> images) {
     56    for (MapillaryImage image : images)
     57      add(image);
     58  }
    5959
    60     /**
    61      * Removes a MapillaryImage object from this object.
    62      *
    63      * @param image
    64      */
    65     public void remove(MapillaryImage image) {
    66         this.images.remove(image);
    67     }
     60  /**
     61   * Removes a MapillaryImage object from this object.
     62   *
     63   * @param image
     64   */
     65  public void remove(MapillaryImage image) {
     66    this.images.remove(image);
     67  }
    6868
    69     /**
    70      * Returns the next MapillaryImage in the sequence.
    71      *
    72      * @param image
    73      * @return
    74      */
    75     public MapillaryImage next(MapillaryImage image) {
    76         if (!images.contains(image))
    77             throw new IllegalArgumentException();
    78         int i = images.indexOf(image);
    79         if (i == images.size() - 1)
    80             return null;
    81         else
    82             return images.get(i + 1);
    83     }
     69  /**
     70   * Returns the next MapillaryImage in the sequence.
     71   *
     72   * @param image
     73   * @return
     74   */
     75  public MapillaryImage next(MapillaryImage image) {
     76    if (!images.contains(image))
     77      throw new IllegalArgumentException();
     78    int i = images.indexOf(image);
     79    if (i == images.size() - 1)
     80      return null;
     81    else
     82      return images.get(i + 1);
     83  }
    8484
    85     /**
    86      * Returns the previous MapillaryImage in the sequence.
    87      *
    88      * @param image
    89      * @return
    90      */
    91     public MapillaryImage previous(MapillaryImage image) {
    92         if (!images.contains(image))
    93             throw new IllegalArgumentException();
    94         int i = images.indexOf(image);
    95         if (i == 0)
    96             return null;
    97         else
    98             return images.get(i - 1);
    99     }
     85  /**
     86   * Returns the previous MapillaryImage in the sequence.
     87   *
     88   * @param image
     89   * @return
     90   */
     91  public MapillaryImage previous(MapillaryImage image) {
     92    if (!images.contains(image))
     93      throw new IllegalArgumentException();
     94    int i = images.indexOf(image);
     95    if (i == 0)
     96      return null;
     97    else
     98      return images.get(i - 1);
     99  }
    100100
    101     /**
    102      * Returns the difference of index between two MapillaryImage objects
    103      * belonging to the same MapillarySequence.
    104      *
    105      * @param image1
    106      * @param image2
    107      * @return
    108      */
    109     public int getDistance(MapillaryImage image1, MapillaryImage image2) {
    110         if (!this.images.contains(image1) || !this.images.contains(image2))
    111             throw new IllegalArgumentException();
    112         return Math.abs(this.images.indexOf(image1)
    113                 - this.images.indexOf(image2));
    114     }
     101  /**
     102   * Returns the difference of index between two MapillaryImage objects
     103   * belonging to the same MapillarySequence.
     104   *
     105   * @param image1
     106   * @param image2
     107   * @return
     108   */
     109  public int getDistance(MapillaryImage image1, MapillaryImage image2) {
     110    if (!this.images.contains(image1) || !this.images.contains(image2))
     111      throw new IllegalArgumentException();
     112    return Math.abs(this.images.indexOf(image1) - this.images.indexOf(image2));
     113  }
    115114
    116     @Override
    117     public boolean equals(Object obj) {
    118         if (obj instanceof MapillarySequence)
    119             return this.getKey().equals(((MapillarySequence) obj).getKey());
    120         return false;
    121     }
     115  @Override
     116  public boolean equals(Object obj) {
     117    if (obj instanceof MapillarySequence)
     118      return this.getKey().equals(((MapillarySequence) obj).getKey());
     119    return false;
     120  }
    122121
    123     @Override
    124     public int hashCode() {
    125         return this.key.hashCode();
    126     }
     122  @Override
     123  public int hashCode() {
     124    return this.key.hashCode();
     125  }
    127126}
  • applications/editors/josm/plugins/mapillary/src/org/openstreetmap/josm/plugins/mapillary/actions/MapillaryDownloadAction.java

    r31331 r31350  
    1818 * Action that triggers the plugin. If in automatic mode, it will automatically
    1919 * download the images in the areas where there is OSM data.
    20  * 
     20 *
    2121 * @author nokutu
    2222 *
     
    2424public class MapillaryDownloadAction extends JosmAction {
    2525
    26     public MapillaryDownloadAction() {
    27         super(tr("Mapillary"), new ImageProvider("icon24.png"),
    28                 tr("Create Mapillary layer"), Shortcut.registerShortcut(
    29                         "Mapillary", tr("Start Mapillary layer"),
    30                         KeyEvent.VK_COMMA, Shortcut.SHIFT), false,
    31                 "mapillaryDownload", false);
    32         this.setEnabled(false);
     26  public MapillaryDownloadAction() {
     27    super(tr("Mapillary"), new ImageProvider("icon24.png"),
     28        tr("Create Mapillary layer"), Shortcut.registerShortcut("Mapillary",
     29            tr("Start Mapillary layer"), KeyEvent.VK_COMMA, Shortcut.SHIFT),
     30        false, "mapillaryDownload", false);
     31    this.setEnabled(false);
     32  }
     33
     34  @Override
     35  public void actionPerformed(ActionEvent arg0) {
     36    if (MapillaryLayer.INSTANCE == null) {
     37      if (Main.map.mapView.getEditLayer() != null)
     38        MapillaryLayer.getInstance().download();
     39    } else {
     40      if (Main.map.mapView.getActiveLayer() != MapillaryLayer.getInstance())
     41        Main.map.mapView.setActiveLayer(MapillaryLayer.getInstance());
     42      else
     43        Main.map.mapView.setActiveLayer(Main.map.mapView.getEditLayer());
    3344    }
    34 
    35     @Override
    36     public void actionPerformed(ActionEvent arg0) {
    37         if (MapillaryLayer.INSTANCE == null) {
    38             if (Main.map.mapView.getEditLayer() != null)
    39                 MapillaryLayer.getInstance().download();
    40         } else {
    41             if (Main.map.mapView.getActiveLayer() != MapillaryLayer
    42                     .getInstance())
    43                 Main.map.mapView.setActiveLayer(MapillaryLayer.getInstance());
    44             else
    45                 Main.map.mapView
    46                         .setActiveLayer(Main.map.mapView.getEditLayer());
    47         }
    48     }
     45  }
    4946}
  • applications/editors/josm/plugins/mapillary/src/org/openstreetmap/josm/plugins/mapillary/actions/MapillaryDownloadViewAction.java

    r31341 r31350  
    2323public class MapillaryDownloadViewAction extends JosmAction {
    2424
    25     public static final double MAX_AREA = Main.pref.getDouble(
    26             "mapillary.max-download-area", 0.020);
     25  public static final double MAX_AREA = Main.pref.getDouble(
     26      "mapillary.max-download-area", 0.020);
    2727
    28     public MapillaryDownloadViewAction() {
    29         super(tr("Download Mapillary images in current view"),
    30                 new ImageProvider("icon24.png"),
    31                 tr("Download Mapillary images in current view"),
    32                 Shortcut.registerShortcut("Mapillary area",
    33                         tr("Download Mapillary images in current view"),
    34                         KeyEvent.VK_PERIOD, Shortcut.SHIFT), false,
    35                 "mapillaryArea", false);
    36         this.setEnabled(false);
     28  public MapillaryDownloadViewAction() {
     29    super(tr("Download Mapillary images in current view"), new ImageProvider(
     30        "icon24.png"), tr("Download Mapillary images in current view"),
     31        Shortcut.registerShortcut("Mapillary area",
     32            tr("Download Mapillary images in current view"),
     33            KeyEvent.VK_PERIOD, Shortcut.SHIFT), false, "mapillaryArea", false);
     34    this.setEnabled(false);
     35  }
     36
     37  @Override
     38  public void actionPerformed(ActionEvent arg0) {
     39    MapillaryLayer.getInstance().bounds.add(Main.map.mapView.getRealBounds());
     40    if (Main.map.mapView.getRealBounds().getArea() <= MAX_AREA) {
     41      new MapillaryDownloader().getImages(Main.map.mapView.getRealBounds());
     42    } else {
     43      JOptionPane.showMessageDialog(Main.parent,
     44          tr("This area is too big to be downloaded"));
    3745    }
    38 
    39     @Override
    40     public void actionPerformed(ActionEvent arg0) {
    41         MapillaryLayer.getInstance().bounds.add(Main.map.mapView
    42                 .getRealBounds());
    43         if (Main.map.mapView.getRealBounds().getArea() <= MAX_AREA) {
    44             new MapillaryDownloader().getImages(Main.map.mapView
    45                     .getRealBounds());
    46         } else {
    47             JOptionPane.showMessageDialog(Main.parent,
    48                     tr("This area is too big to be downloaded"));
    49         }
    50     }
     46  }
    5147}
  • applications/editors/josm/plugins/mapillary/src/org/openstreetmap/josm/plugins/mapillary/actions/MapillaryExportAction.java

    r31331 r31350  
    3232public class MapillaryExportAction extends JosmAction {
    3333
    34     MapillaryExportDialog dialog;
     34  MapillaryExportDialog dialog;
    3535
    36     public MapillaryExportAction() {
    37         super(tr("Export pictures"), new ImageProvider("icon24.png"),
    38                 tr("Export pictures"), Shortcut.registerShortcut(
    39                         "Export Mapillary", tr("Export Mapillary pictures"),
    40                         KeyEvent.CHAR_UNDEFINED, Shortcut.NONE), false,
    41                 "mapillaryExport", false);
    42         this.setEnabled(false);
     36  public MapillaryExportAction() {
     37    super(tr("Export pictures"), new ImageProvider("icon24.png"),
     38        tr("Export pictures"), Shortcut.registerShortcut("Export Mapillary",
     39            tr("Export Mapillary pictures"), KeyEvent.CHAR_UNDEFINED,
     40            Shortcut.NONE), false, "mapillaryExport", false);
     41    this.setEnabled(false);
     42  }
     43
     44  @Override
     45  public void actionPerformed(ActionEvent e) {
     46    dialog = new MapillaryExportDialog();
     47    JOptionPane pane = new JOptionPane(dialog, JOptionPane.PLAIN_MESSAGE,
     48        JOptionPane.OK_CANCEL_OPTION);
     49    JDialog dlg = pane.createDialog(Main.parent, tr("Export images"));
     50    dlg.setMinimumSize(new Dimension(400, 150));
     51    dlg.setVisible(true);
     52
     53    // Checks if the inputs are correct and starts the export process.
     54    if (pane.getValue() != null
     55        && (int) pane.getValue() == JOptionPane.OK_OPTION
     56        && dialog.chooser != null) {
     57      if (dialog.group.isSelected(dialog.all.getModel())) {
     58        export(MapillaryData.getInstance().getImages());
     59      } else if (dialog.group.isSelected(dialog.sequence.getModel())) {
     60        ArrayList<MapillaryAbstractImage> images = new ArrayList<>();
     61        for (MapillaryAbstractImage image : MapillaryData.getInstance()
     62            .getMultiSelectedImages())
     63          if (image instanceof MapillaryImage) {
     64            if (!images.contains(image))
     65              images.addAll(((MapillaryImage) image).getSequence().getImages());
     66          } else
     67            images.add(image);
     68        export(images);
     69      } else if (dialog.group.isSelected(dialog.selected.getModel())) {
     70        export(MapillaryData.getInstance().getMultiSelectedImages());
     71      }
     72      // This option ignores the selected directory.
     73    } else if (dialog.group.isSelected(dialog.rewrite.getModel())) {
     74      ArrayList<MapillaryImportedImage> images = new ArrayList<>();
     75      for (MapillaryAbstractImage image : MapillaryData.getInstance()
     76          .getImages())
     77        if (image instanceof MapillaryImportedImage) {
     78          images.add(((MapillaryImportedImage) image));
     79        }
     80      try {
     81        Main.worker.submit(new Thread(new MapillaryExportManager(images)));
     82      } catch (IOException e1) {
     83        Main.error(e1);
     84      }
    4385    }
     86    dlg.dispose();
     87  }
    4488
    45     @Override
    46     public void actionPerformed(ActionEvent e) {
    47         dialog = new MapillaryExportDialog();
    48         JOptionPane pane = new JOptionPane(dialog, JOptionPane.PLAIN_MESSAGE,
    49                 JOptionPane.OK_CANCEL_OPTION);
    50         JDialog dlg = pane.createDialog(Main.parent, tr("Export images"));
    51         dlg.setMinimumSize(new Dimension(400, 150));
    52         dlg.setVisible(true);
    53 
    54         // Checks if the inputs are correct and starts the export process.
    55         if (pane.getValue() != null
    56                 && (int) pane.getValue() == JOptionPane.OK_OPTION
    57                 && dialog.chooser != null) {
    58             if (dialog.group.isSelected(dialog.all.getModel())) {
    59                 export(MapillaryData.getInstance().getImages());
    60             } else if (dialog.group.isSelected(dialog.sequence.getModel())) {
    61                 ArrayList<MapillaryAbstractImage> images = new ArrayList<>();
    62                 for (MapillaryAbstractImage image : MapillaryData.getInstance()
    63                         .getMultiSelectedImages())
    64                     if (image instanceof MapillaryImage) {
    65                         if (!images.contains(image))
    66                             images.addAll(((MapillaryImage) image)
    67                                     .getSequence().getImages());
    68                     } else
    69                         images.add(image);
    70                 export(images);
    71             } else if (dialog.group.isSelected(dialog.selected.getModel())) {
    72                 export(MapillaryData.getInstance().getMultiSelectedImages());
    73             }
    74             // This option ignores the selected directory.
    75         } else if (dialog.group.isSelected(dialog.rewrite.getModel())) {
    76             ArrayList<MapillaryImportedImage> images = new ArrayList<>();
    77             for (MapillaryAbstractImage image : MapillaryData.getInstance()
    78                     .getImages())
    79                 if (image instanceof MapillaryImportedImage) {
    80                     images.add(((MapillaryImportedImage) image));
    81                 }
    82             try {
    83                 Main.worker.submit(new Thread(
    84                         new MapillaryExportManager(images)));
    85             } catch (IOException e1) {
    86                 Main.error(e1);
    87             }
    88         }
    89         dlg.dispose();
    90     }
    91 
    92     /**
    93      * Exports the given images from the database.
    94      */
    95     public void export(List<MapillaryAbstractImage> images) {
    96         Main.worker.submit(new Thread(new MapillaryExportManager(images,
    97                 dialog.chooser.getSelectedFile().toString())));
    98     }
     89  /**
     90   * Exports the given images from the database.
     91   */
     92  public void export(List<MapillaryAbstractImage> images) {
     93    Main.worker.submit(new Thread(new MapillaryExportManager(images,
     94        dialog.chooser.getSelectedFile().toString())));
     95  }
    9996
    10097}
  • applications/editors/josm/plugins/mapillary/src/org/openstreetmap/josm/plugins/mapillary/actions/MapillaryImportAction.java

    r31328 r31350  
    3030/**
    3131 * Imports a set of picture files into JOSM. They must be in jpg or png format.
    32  * 
     32 *
    3333 * @author nokutu
    3434 *
     
    3636public class MapillaryImportAction extends JosmAction {
    3737
    38     public JFileChooser chooser;
     38  public JFileChooser chooser;
    3939
    40     /**
    41      * Amount of pictures without the proper EXIF tags.
    42      */
    43     private int noTagsPics = 0;
     40  /**
     41   * Amount of pictures without the proper EXIF tags.
     42   */
     43  private int noTagsPics = 0;
    4444
    45     public MapillaryImportAction() {
    46         super(tr("Import pictures"), new ImageProvider("icon24.png"),
    47                 tr("Import local pictures"), Shortcut.registerShortcut(
    48                         "Import Mapillary",
    49                         tr("Import pictures into Mapillary layer"),
    50                         KeyEvent.CHAR_UNDEFINED, Shortcut.NONE), false,
    51                 "mapillaryImport", false);
    52         this.setEnabled(false);
     45  public MapillaryImportAction() {
     46    super(tr("Import pictures"), new ImageProvider("icon24.png"),
     47        tr("Import local pictures"), Shortcut.registerShortcut(
     48            "Import Mapillary", tr("Import pictures into Mapillary layer"),
     49            KeyEvent.CHAR_UNDEFINED, Shortcut.NONE), false, "mapillaryImport",
     50        false);
     51    this.setEnabled(false);
     52  }
     53
     54  @Override
     55  public void actionPerformed(ActionEvent e) {
     56    chooser = new JFileChooser();
     57    chooser.setCurrentDirectory(new java.io.File(System
     58        .getProperty("user.home")));
     59    chooser.setDialogTitle(tr("Select pictures"));
     60    chooser.setFileSelectionMode(JFileChooser.FILES_AND_DIRECTORIES);
     61    chooser.setAcceptAllFileFilterUsed(false);
     62    chooser.addChoosableFileFilter(new FileNameExtensionFilter("images", "jpg",
     63        "jpeg", "png"));
     64    chooser.setMultiSelectionEnabled(true);
     65    if (chooser.showOpenDialog(Main.parent) == JFileChooser.APPROVE_OPTION) {
     66      for (int i = 0; i < chooser.getSelectedFiles().length; i++) {
     67        File file = chooser.getSelectedFiles()[i];
     68        if (file.isDirectory()) {
     69
     70        } else {
     71          MapillaryLayer.getInstance();
     72          if (file.getPath().substring(file.getPath().length() - 4)
     73              .equals(".jpg")
     74              || file.getPath().substring(file.getPath().length() - 5)
     75                  .equals(".jpeg")) {
     76            try {
     77              readJPG(file);
     78            } catch (ImageReadException ex) {
     79              Main.error(ex);
     80            } catch (IOException ex) {
     81              Main.error(ex);
     82            }
     83          } else if (file.getPath().substring(file.getPath().length() - 4)
     84              .equals(".png")) {
     85            readPNG(file);
     86          }
     87        }
     88      }
    5389    }
     90  }
    5491
    55     @Override
    56     public void actionPerformed(ActionEvent e) {
    57         chooser = new JFileChooser();
    58         chooser.setCurrentDirectory(new java.io.File(System
    59                 .getProperty("user.home")));
    60         chooser.setDialogTitle(tr("Select pictures"));
    61         chooser.setFileSelectionMode(JFileChooser.FILES_AND_DIRECTORIES);
    62         chooser.setAcceptAllFileFilterUsed(false);
    63         chooser.addChoosableFileFilter(new FileNameExtensionFilter("images",
    64                 "jpg", "jpeg", "png"));
    65         chooser.setMultiSelectionEnabled(true);
    66         if (chooser.showOpenDialog(Main.parent) == JFileChooser.APPROVE_OPTION) {
    67             for (int i = 0; i < chooser.getSelectedFiles().length; i++) {
    68                 File file = chooser.getSelectedFiles()[i];
    69                 if (file.isDirectory()) {
     92  /**
     93   * Reads a jpg pictures that contains the needed GPS information (position and
     94   * direction) and creates a new icon in that position.
     95   *
     96   * @param file
     97   * @throws ImageReadException
     98   * @throws IOException
     99   */
     100  public void readJPG(File file) throws ImageReadException, IOException {
     101    final ImageMetadata metadata = Imaging.getMetadata(file);
     102    if (metadata instanceof JpegImageMetadata) {
     103      final JpegImageMetadata jpegMetadata = (JpegImageMetadata) metadata;
     104      final TiffField lat_ref = jpegMetadata
     105          .findEXIFValueWithExactMatch(GpsTagConstants.GPS_TAG_GPS_LATITUDE_REF);
     106      final TiffField lat = jpegMetadata
     107          .findEXIFValueWithExactMatch(GpsTagConstants.GPS_TAG_GPS_LATITUDE);
     108      final TiffField lon_ref = jpegMetadata
     109          .findEXIFValueWithExactMatch(GpsTagConstants.GPS_TAG_GPS_LONGITUDE_REF);
     110      final TiffField lon = jpegMetadata
     111          .findEXIFValueWithExactMatch(GpsTagConstants.GPS_TAG_GPS_LONGITUDE);
     112      final TiffField ca = jpegMetadata
     113          .findEXIFValueWithExactMatch(GpsTagConstants.GPS_TAG_GPS_IMG_DIRECTION);
     114      final TiffField datetimeOriginal = jpegMetadata
     115          .findEXIFValueWithExactMatch(ExifTagConstants.EXIF_TAG_DATE_TIME_ORIGINAL);
     116      if (lat_ref == null || lat == null || lon == null || lon_ref == null) {
     117        readNoTags(file);
     118        return;
     119      }
     120      double latValue = 0;
     121      double lonValue = 0;
     122      double caValue = 0;
     123      if (lat != null && lat.getValue() instanceof RationalNumber[])
     124        latValue = DegMinSecToDouble((RationalNumber[]) lat.getValue(), lat_ref
     125            .getValue().toString());
     126      if (lon != null && lon.getValue() instanceof RationalNumber[])
     127        lonValue = DegMinSecToDouble((RationalNumber[]) lon.getValue(), lon_ref
     128            .getValue().toString());
     129      if (ca != null && ca.getValue() instanceof RationalNumber)
     130        caValue = ((RationalNumber) ca.getValue()).doubleValue();
     131      if (lat_ref.getValue().toString().equals("S"))
     132        latValue = -latValue;
     133      if (lon_ref.getValue().toString().equals("W"))
     134        lonValue = -lonValue;
     135      if (datetimeOriginal != null)
     136        MapillaryData.getInstance().add(
     137            new MapillaryImportedImage(latValue, lonValue, caValue, file,
     138                datetimeOriginal.getStringValue()));
     139      else
     140        MapillaryData.getInstance().add(
     141            new MapillaryImportedImage(latValue, lonValue, caValue, file));
     142    }
     143  }
    70144
    71                 } else {
    72                     MapillaryLayer.getInstance();
    73                     if (file.getPath().substring(file.getPath().length() - 4)
    74                             .equals(".jpg")
    75                             || file.getPath()
    76                                     .substring(file.getPath().length() - 5)
    77                                     .equals(".jpeg")) {
    78                         try {
    79                             readJPG(file);
    80                         } catch (ImageReadException ex) {
    81                             Main.error(ex);
    82                         } catch (IOException ex) {
    83                             Main.error(ex);
    84                         }
    85                     } else if (file.getPath()
    86                             .substring(file.getPath().length() - 4)
    87                             .equals(".png")) {
    88                         readPNG(file);
    89                     }
    90                 }
    91             }
    92         }
    93     }
     145  /**
     146   * Reads a image file that doesn't contain the needed GPS information. And
     147   * creates a new icon in the middle of the map.
     148   *
     149   * @param file
     150   */
     151  private void readNoTags(File file) {
     152    double HORIZONTAL_DISTANCE = 0.0001;
     153    double horDev;
     154    if (noTagsPics % 2 == 0)
     155      horDev = HORIZONTAL_DISTANCE * noTagsPics / 2;
     156    else
     157      horDev = -HORIZONTAL_DISTANCE * ((noTagsPics + 1) / 2);
     158    LatLon pos = Main.map.mapView.getProjection().eastNorth2latlon(
     159        Main.map.mapView.getCenter());
     160    MapillaryData.getInstance().add(
     161        new MapillaryImportedImage(pos.lat(), pos.lon() + horDev, 0, file));
     162    noTagsPics++;
     163  }
    94164
    95     /**
    96      * Reads a jpg pictures that contains the needed GPS information (position
    97      * and direction) and creates a new icon in that position.
    98      *
    99      * @param file
    100      * @throws ImageReadException
    101      * @throws IOException
    102      */
    103     public void readJPG(File file) throws ImageReadException, IOException {
    104         final ImageMetadata metadata = Imaging.getMetadata(file);
    105         if (metadata instanceof JpegImageMetadata) {
    106             final JpegImageMetadata jpegMetadata = (JpegImageMetadata) metadata;
    107             final TiffField lat_ref = jpegMetadata
    108                     .findEXIFValueWithExactMatch(GpsTagConstants.GPS_TAG_GPS_LATITUDE_REF);
    109             final TiffField lat = jpegMetadata
    110                     .findEXIFValueWithExactMatch(GpsTagConstants.GPS_TAG_GPS_LATITUDE);
    111             final TiffField lon_ref = jpegMetadata
    112                     .findEXIFValueWithExactMatch(GpsTagConstants.GPS_TAG_GPS_LONGITUDE_REF);
    113             final TiffField lon = jpegMetadata
    114                     .findEXIFValueWithExactMatch(GpsTagConstants.GPS_TAG_GPS_LONGITUDE);
    115             final TiffField ca = jpegMetadata
    116                     .findEXIFValueWithExactMatch(GpsTagConstants.GPS_TAG_GPS_IMG_DIRECTION);
    117             final TiffField datetimeOriginal = jpegMetadata
    118                     .findEXIFValueWithExactMatch(ExifTagConstants.EXIF_TAG_DATE_TIME_ORIGINAL);
    119             if (lat_ref == null || lat == null || lon == null
    120                     || lon_ref == null) {
    121                 readNoTags(file);
    122                 return;
    123             }
    124             double latValue = 0;
    125             double lonValue = 0;
    126             double caValue = 0;
    127             if (lat != null && lat.getValue() instanceof RationalNumber[])
    128                 latValue = DegMinSecToDouble((RationalNumber[]) lat.getValue(),
    129                         lat_ref.getValue().toString());
    130             if (lon != null && lon.getValue() instanceof RationalNumber[])
    131                 lonValue = DegMinSecToDouble((RationalNumber[]) lon.getValue(),
    132                         lon_ref.getValue().toString());
    133             if (ca != null && ca.getValue() instanceof RationalNumber)
    134                 caValue = ((RationalNumber) ca.getValue()).doubleValue();
    135             if (lat_ref.getValue().toString().equals("S"))
    136                 latValue = -latValue;
    137             if (lon_ref.getValue().toString().equals("W"))
    138                 lonValue = -lonValue;
    139             if (datetimeOriginal != null)
    140                 MapillaryData.getInstance().add(
    141                         new MapillaryImportedImage(latValue, lonValue, caValue,
    142                                 file, datetimeOriginal.getStringValue()));
    143             else
    144                 MapillaryData.getInstance().add(
    145                         new MapillaryImportedImage(latValue, lonValue, caValue,
    146                                 file));
    147         }
    148     }
     165  private void readPNG(File file) {
     166    readNoTags(file);
     167  }
    149168
    150     /**
    151      * Reads a image file that doesn't contain the needed GPS information. And
    152      * creates a new icon in the middle of the map.
    153      *
    154      * @param file
    155      */
    156     private void readNoTags(File file) {
    157         double HORIZONTAL_DISTANCE = 0.0001;
    158         double horDev;
    159         if (noTagsPics % 2 == 0)
    160             horDev = HORIZONTAL_DISTANCE * noTagsPics / 2;
    161         else
    162             horDev = -HORIZONTAL_DISTANCE * ((noTagsPics + 1) / 2);
    163         LatLon pos = Main.map.mapView.getProjection().eastNorth2latlon(
    164                 Main.map.mapView.getCenter());
    165         MapillaryData.getInstance().add(
    166                 new MapillaryImportedImage(pos.lat(), pos.lon() + horDev, 0,
    167                         file));
    168         noTagsPics++;
    169     }
    170 
    171     private void readPNG(File file) {
    172         readNoTags(file);
    173     }
    174 
    175     private double DegMinSecToDouble(RationalNumber[] degMinSec, String ref) {
    176         RationalNumber deg = degMinSec[0];
    177         RationalNumber min = degMinSec[1];
    178         RationalNumber sec = degMinSec[2];
    179         return deg.doubleValue() + min.doubleValue() / 60 + sec.doubleValue()
    180                 / 3600;
    181     }
     169  private double DegMinSecToDouble(RationalNumber[] degMinSec, String ref) {
     170    RationalNumber deg = degMinSec[0];
     171    RationalNumber min = degMinSec[1];
     172    RationalNumber sec = degMinSec[2];
     173    return deg.doubleValue() + min.doubleValue() / 60 + sec.doubleValue()
     174        / 3600;
     175  }
    182176}
  • applications/editors/josm/plugins/mapillary/src/org/openstreetmap/josm/plugins/mapillary/actions/MapillaryZoomAction.java

    r31313 r31350  
    2222 */
    2323public class MapillaryZoomAction extends JosmAction implements
    24         MapillaryDataListener {
     24    MapillaryDataListener {
    2525
    26     public MapillaryZoomAction() {
    27         super(tr("Zoom to selected image"), new ImageProvider("icon24.png"),
    28                 tr("Zoom to selected image"), Shortcut.registerShortcut(
    29                         "Zoom Mapillary",
    30                         tr("Zoom to the currently selected Mapillary image"),
    31                         KeyEvent.CHAR_UNDEFINED, Shortcut.NONE), false,
    32                 "mapillaryZoom", false);
    33         MapillaryData.getInstance().addListener(this);
    34         this.setEnabled(false);
    35     }
     26  public MapillaryZoomAction() {
     27    super(tr("Zoom to selected image"), new ImageProvider("icon24.png"),
     28        tr("Zoom to selected image"), Shortcut.registerShortcut(
     29            "Zoom Mapillary",
     30            tr("Zoom to the currently selected Mapillary image"),
     31            KeyEvent.CHAR_UNDEFINED, Shortcut.NONE), false, "mapillaryZoom",
     32        false);
     33    MapillaryData.getInstance().addListener(this);
     34    this.setEnabled(false);
     35  }
    3636
    37     @Override
    38     public void actionPerformed(ActionEvent arg0) {
    39         if (MapillaryData.getInstance().getSelectedImage() == null)
    40             throw new IllegalStateException();
    41         Main.map.mapView.zoomTo(MapillaryData.getInstance().getSelectedImage()
    42                 .getLatLon());
    43     }
     37  @Override
     38  public void actionPerformed(ActionEvent arg0) {
     39    if (MapillaryData.getInstance().getSelectedImage() == null)
     40      throw new IllegalStateException();
     41    Main.map.mapView.zoomTo(MapillaryData.getInstance().getSelectedImage()
     42        .getLatLon());
     43  }
    4444
    45     @Override
    46     public void selectedImageChanged(MapillaryAbstractImage oldImage,
    47             MapillaryAbstractImage newImage) {
    48         if (oldImage == null && newImage != null)
    49             MapillaryPlugin.setMenuEnabled(MapillaryPlugin.ZOOM_MENU, true);
    50         else if (oldImage != null && newImage == null)
    51             MapillaryPlugin.setMenuEnabled(MapillaryPlugin.ZOOM_MENU, false);
    52     }
     45  @Override
     46  public void selectedImageChanged(MapillaryAbstractImage oldImage,
     47      MapillaryAbstractImage newImage) {
     48    if (oldImage == null && newImage != null)
     49      MapillaryPlugin.setMenuEnabled(MapillaryPlugin.ZOOM_MENU, true);
     50    else if (oldImage != null && newImage == null)
     51      MapillaryPlugin.setMenuEnabled(MapillaryPlugin.ZOOM_MENU, false);
     52  }
    5353
    54     @Override
    55     public void imagesAdded() {
    56     }
     54  @Override
     55  public void imagesAdded() {
     56  }
    5757}
  • applications/editors/josm/plugins/mapillary/src/org/openstreetmap/josm/plugins/mapillary/cache/MapillaryCache.java

    r31328 r31350  
    1111
    1212public class MapillaryCache extends
    13         JCSCachedTileLoaderJob<String, BufferedImageCacheEntry> {
     13    JCSCachedTileLoaderJob<String, BufferedImageCacheEntry> {
    1414
    15     private volatile URL url;
    16     private volatile String key;
     15  private volatile URL url;
     16  private volatile String key;
    1717
    18     public static enum Type {
    19         FULL_IMAGE, THUMBNAIL
     18  public static enum Type {
     19    FULL_IMAGE, THUMBNAIL
     20  }
     21
     22  public MapillaryCache(String key, Type type) {
     23    super(MapillaryPlugin.CACHE, 50000, 50000, new HashMap<String, String>());
     24    this.key = key;
     25    try {
     26      if (type == Type.FULL_IMAGE) {
     27        url = new URL("https://d1cuyjsrcm0gby.cloudfront.net/" + key
     28            + "/thumb-2048.jpg");
     29        this.key += ".FULL_IMAGE";
     30
     31      } else if (type == Type.THUMBNAIL) {
     32        url = new URL("https://d1cuyjsrcm0gby.cloudfront.net/" + key
     33            + "/thumb-320.jpg");
     34        this.key += ".THUMBNAIL";
     35      }
     36    } catch (MalformedURLException e) {
     37      Main.error(e);
    2038    }
     39  }
    2140
    22     public MapillaryCache(String key, Type type) {
    23         super(MapillaryPlugin.CACHE, 50000, 50000,
    24                 new HashMap<String, String>());
    25         this.key = key;
    26         try {
    27             if (type == Type.FULL_IMAGE) {
    28                 url = new URL("https://d1cuyjsrcm0gby.cloudfront.net/" + key
    29                         + "/thumb-2048.jpg");
    30                 this.key += ".FULL_IMAGE";
     41  @Override
     42  public String getCacheKey() {
     43    return key;
     44  }
    3145
    32             } else if (type == Type.THUMBNAIL) {
    33                 url = new URL("https://d1cuyjsrcm0gby.cloudfront.net/" + key
    34                         + "/thumb-320.jpg");
    35                 this.key += ".THUMBNAIL";
    36             }
    37         } catch (MalformedURLException e) {
    38             Main.error(e);
    39         }
    40     }
     46  @Override
     47  public URL getUrl() {
     48    return url;
     49  }
    4150
    42     @Override
    43     public String getCacheKey() {
    44         return key;
    45     }
     51  @Override
     52  protected BufferedImageCacheEntry createCacheEntry(byte[] content) {
     53    return new BufferedImageCacheEntry(content);
     54  }
    4655
    47     @Override
    48     public URL getUrl() {
    49         return url;
    50     }
     56  @Override
     57  protected boolean isObjectLoadable() {
     58    if (cacheData == null)
     59      return false;
     60    byte[] content = cacheData.getContent();
     61    return content != null && content.length > 0;
     62  }
    5163
    52     @Override
    53     protected BufferedImageCacheEntry createCacheEntry(byte[] content) {
    54         return new BufferedImageCacheEntry(content);
    55     }
    56 
    57     @Override
    58     protected boolean isObjectLoadable() {
    59         if (cacheData == null)
    60             return false;
    61         byte[] content = cacheData.getContent();
    62         return content != null && content.length > 0;
    63     }
    64 
    65     // @Override
    66     protected boolean handleNotFound() {
    67         return false;
    68     }
     64  // @Override
     65  protected boolean handleNotFound() {
     66    return false;
     67  }
    6968}
  • applications/editors/josm/plugins/mapillary/src/org/openstreetmap/josm/plugins/mapillary/commands/CommandMoveImage.java

    r31317 r31350  
    1616 */
    1717public class CommandMoveImage extends MapillaryCommand {
    18     private double x;
    19     private double y;
     18  private double x;
     19  private double y;
    2020
    21     public CommandMoveImage(List<MapillaryAbstractImage> images, double x,
    22             double y) {
    23         this.images = new ArrayList<>(images);
    24         this.x = x;
    25         this.y = y;
     21  public CommandMoveImage(List<MapillaryAbstractImage> images, double x,
     22      double y) {
     23    this.images = new ArrayList<>(images);
     24    this.x = x;
     25    this.y = y;
     26  }
     27
     28  @Override
     29  public void undo() {
     30    for (MapillaryAbstractImage image : images) {
     31      image.move(-x, -y);
     32      image.stopMoving();
    2633    }
     34    checkModified();
     35    Main.map.repaint();
     36  }
    2737
    28     @Override
    29     public void undo() {
    30         for (MapillaryAbstractImage image : images) {
    31             image.move(-x, -y);
    32             image.stopMoving();
    33         }
    34         checkModified();
    35         Main.map.repaint();
     38  @Override
     39  public void redo() {
     40    for (MapillaryAbstractImage image : images) {
     41      image.move(x, y);
     42      image.stopMoving();
    3643    }
     44    checkModified();
     45    Main.map.repaint();
     46  }
    3747
    38     @Override
    39     public void redo() {
    40         for (MapillaryAbstractImage image : images) {
    41             image.move(x, y);
    42             image.stopMoving();
    43         }
    44         checkModified();
    45         Main.map.repaint();
     48  public String toString() {
     49    return trn("Moved {0} image", "Moved {0} images", images.size(),
     50        images.size());
     51  }
     52
     53  @Override
     54  public void sum(MapillaryCommand command) {
     55    if (command instanceof CommandMoveImage) {
     56      this.x += ((CommandMoveImage) command).x;
     57      this.y += ((CommandMoveImage) command).y;
    4658    }
    47 
    48     public String toString() {
    49         return trn("Moved {0} image", "Moved {0} images", images.size(),
    50                 images.size());
    51     }
    52 
    53     @Override
    54     public void sum(MapillaryCommand command) {
    55         if (command instanceof CommandMoveImage) {
    56             this.x += ((CommandMoveImage) command).x;
    57             this.y += ((CommandMoveImage) command).y;
    58         }
    59     }
     59  }
    6060}
  • applications/editors/josm/plugins/mapillary/src/org/openstreetmap/josm/plugins/mapillary/commands/CommandTurnImage.java

    r31331 r31350  
    1616 */
    1717public class CommandTurnImage extends MapillaryCommand {
    18     private double ca;
     18  private double ca;
    1919
    20     public CommandTurnImage(List<MapillaryAbstractImage> images, double ca) {
    21         this.images = new ArrayList<>(images);
    22         this.ca = ca;
     20  public CommandTurnImage(List<MapillaryAbstractImage> images, double ca) {
     21    this.images = new ArrayList<>(images);
     22    this.ca = ca;
     23  }
     24
     25  @Override
     26  public void undo() {
     27    for (MapillaryAbstractImage image : images) {
     28      image.turn(-ca);
     29      image.stopMoving();
    2330    }
     31    checkModified();
     32    Main.map.repaint();
     33  }
    2434
    25     @Override
    26     public void undo() {
    27         for (MapillaryAbstractImage image : images) {
    28             image.turn(-ca);
    29             image.stopMoving();
    30         }
    31         checkModified();
    32         Main.map.repaint();
     35  @Override
     36  public void redo() {
     37    for (MapillaryAbstractImage image : images) {
     38      image.turn(ca);
     39      image.stopMoving();
    3340    }
     41    checkModified();
     42    Main.map.repaint();
     43  }
    3444
    35     @Override
    36     public void redo() {
    37         for (MapillaryAbstractImage image : images) {
    38             image.turn(ca);
    39             image.stopMoving();
    40         }
    41         checkModified();
    42         Main.map.repaint();
     45  public String toString() {
     46    return trn("Turned {0} image", "Turned {0} images", this.images.size(),
     47        this.images.size());
     48  }
     49
     50  @Override
     51  public void sum(MapillaryCommand command) {
     52    if (command instanceof CommandTurnImage) {
     53      this.ca += ((CommandTurnImage) command).ca;
    4354    }
    44 
    45     public String toString() {
    46         return trn("Turned {0} image", "Turned {0} images", this.images.size(),
    47                 this.images.size());
    48     }
    49 
    50     @Override
    51     public void sum(MapillaryCommand command) {
    52         if (command instanceof CommandTurnImage) {
    53             this.ca += ((CommandTurnImage) command).ca;
    54         }
    55     }
     55  }
    5656}
  • applications/editors/josm/plugins/mapillary/src/org/openstreetmap/josm/plugins/mapillary/commands/MapillaryCommand.java

    r31278 r31350  
    1212 */
    1313public abstract class MapillaryCommand {
    14     protected List<MapillaryAbstractImage> images;
     14  protected List<MapillaryAbstractImage> images;
    1515
    16     public abstract void undo();
     16  public abstract void undo();
    1717
    18     public abstract void redo();
     18  public abstract void redo();
    1919
    20     /**
    21      * If two equal commands are applied consecutively to the same set of
    22      * images, they are summed in order to reduce them to just one command.
    23      *
    24      * @param command
    25      */
    26     public abstract void sum(MapillaryCommand command);
     20  /**
     21   * If two equal commands are applied consecutively to the same set of images,
     22   * they are summed in order to reduce them to just one command.
     23   *
     24   * @param command
     25   */
     26  public abstract void sum(MapillaryCommand command);
    2727
    28     /**
    29      * Checks if the image has been modified, compairing with its original
    30      * values.
    31      */
    32     public void checkModified() {
    33         for (MapillaryAbstractImage image : images)
    34             image.isModified = (image.tempLatLon == image.latLon || image.tempCa == image.ca);
    35     }
     28  /**
     29   * Checks if the image has been modified, compairing with its original values.
     30   */
     31  public void checkModified() {
     32    for (MapillaryAbstractImage image : images)
     33      image.isModified = (image.tempLatLon == image.latLon || image.tempCa == image.ca);
     34  }
    3635}
  • applications/editors/josm/plugins/mapillary/src/org/openstreetmap/josm/plugins/mapillary/commands/MapillaryRecord.java

    r31331 r31350  
    1212 */
    1313public class MapillaryRecord {
    14     public static MapillaryRecord INSTANCE;
     14  public static MapillaryRecord INSTANCE;
    1515
    16     private ArrayList<MapillaryRecordListener> listeners;
     16  private ArrayList<MapillaryRecordListener> listeners;
    1717
    18     public ArrayList<MapillaryCommand> commandList;
    19     /** Last written command */
    20     public int position;
     18  public ArrayList<MapillaryCommand> commandList;
     19  /** Last written command */
     20  public int position;
    2121
    22     public MapillaryRecord() {
    23         commandList = new ArrayList<>();
    24         position = -1;
    25         listeners = new ArrayList<>();
     22  public MapillaryRecord() {
     23    commandList = new ArrayList<>();
     24    position = -1;
     25    listeners = new ArrayList<>();
     26  }
     27
     28  public static synchronized MapillaryRecord getInstance() {
     29    if (MapillaryRecord.INSTANCE == null)
     30      MapillaryRecord.INSTANCE = new MapillaryRecord();
     31    return MapillaryRecord.INSTANCE;
     32  }
     33
     34  public void addListener(MapillaryRecordListener lis) {
     35    this.listeners.add(lis);
     36  }
     37
     38  public void removeListener(MapillaryRecordListener lis) {
     39    this.listeners.remove(lis);
     40  }
     41
     42  /**
     43   * Adds a new command to the list.
     44   *
     45   * @param command
     46   */
     47  public void addCommand(MapillaryCommand command) {
     48    // Checks if it is a continuation of last command
     49    if (position != -1) {
     50      boolean equalSets = true;
     51      for (MapillaryAbstractImage img : commandList.get(position).images)
     52        if (!command.images.contains(img))
     53          equalSets = false;
     54      if (equalSets
     55          && commandList.get(position).getClass() == command.getClass()) {
     56        commandList.get(position).sum(command);
     57        fireRecordChanged();
     58        return;
     59      }
    2660    }
     61    // Adds the command to the las position of the list.
     62    commandList.add(position + 1, command);
     63    position++;
     64    while (commandList.size() > position + 1) {
     65      commandList.remove(position + 1);
     66    }
     67    fireRecordChanged();
     68  }
    2769
    28     public static synchronized MapillaryRecord getInstance() {
    29         if (MapillaryRecord.INSTANCE == null)
    30             MapillaryRecord.INSTANCE = new MapillaryRecord();
    31         return MapillaryRecord.INSTANCE;
    32     }
     70  /**
     71   * Undo latest command.
     72   */
     73  public void undo() {
     74    if (position == -1)
     75      return;
     76    commandList.get(position).undo();
     77    position--;
     78    fireRecordChanged();
     79  }
    3380
    34     public void addListener(MapillaryRecordListener lis) {
    35         this.listeners.add(lis);
    36     }
     81  /**
     82   * Redo latest undoed action.
     83   */
     84  public void redo() {
     85    if (position + 1 >= commandList.size())
     86      return;
     87    position++;
     88    commandList.get(position).redo();
     89    fireRecordChanged();
     90  }
    3791
    38     public void removeListener(MapillaryRecordListener lis) {
    39         this.listeners.remove(lis);
    40     }
    41 
    42     /**
    43      * Adds a new command to the list.
    44      *
    45      * @param command
    46      */
    47     public void addCommand(MapillaryCommand command) {
    48         // Checks if it is a continuation of last command
    49         if (position != -1) {
    50             boolean equalSets = true;
    51             for (MapillaryAbstractImage img : commandList.get(position).images)
    52                 if (!command.images.contains(img))
    53                     equalSets = false;
    54             if (equalSets
    55                     && commandList.get(position).getClass() == command
    56                             .getClass()) {
    57                 commandList.get(position).sum(command);
    58                 fireRecordChanged();
    59                 return;
    60             }
    61         }
    62         // Adds the command to the las position of the list.
    63         commandList.add(position + 1, command);
    64         position++;
    65         while (commandList.size() > position + 1) {
    66             commandList.remove(position + 1);
    67         }
    68         fireRecordChanged();
    69     }
    70 
    71     /**
    72      * Undo latest command.
    73      */
    74     public void undo() {
    75         if (position == -1)
    76             return;
    77         commandList.get(position).undo();
    78         position--;
    79         fireRecordChanged();
    80     }
    81 
    82     /**
    83      * Redo latest undoed action.
    84      */
    85     public void redo() {
    86         if (position + 1 >= commandList.size())
    87             return;
    88         position++;
    89         commandList.get(position).redo();
    90         fireRecordChanged();
    91     }
    92 
    93     private void fireRecordChanged() {
    94         for (MapillaryRecordListener lis : listeners)
    95             if (lis != null)
    96                 lis.recordChanged();
    97     }
     92  private void fireRecordChanged() {
     93    for (MapillaryRecordListener lis : listeners)
     94      if (lis != null)
     95        lis.recordChanged();
     96  }
    9897}
  • applications/editors/josm/plugins/mapillary/src/org/openstreetmap/josm/plugins/mapillary/commands/MapillaryRecordListener.java

    r31278 r31350  
    22
    33public interface MapillaryRecordListener {
    4     public void recordChanged();
     4  public void recordChanged();
    55}
  • applications/editors/josm/plugins/mapillary/src/org/openstreetmap/josm/plugins/mapillary/downloads/MapillaryDownloader.java

    r31331 r31350  
    1919public class MapillaryDownloader {
    2020
    21     public final static String BASE_URL = "https://a.mapillary.com/v2/";
    22     public final static String CLIENT_ID = "NzNRM2otQkR2SHJzaXJmNmdQWVQ0dzo1YTA2NmNlODhlNWMwOTBm";
    23     public final static Executor EXECUTOR = Executors.newSingleThreadExecutor();
     21  public final static String BASE_URL = "https://a.mapillary.com/v2/";
     22  public final static String CLIENT_ID = "NzNRM2otQkR2SHJzaXJmNmdQWVQ0dzo1YTA2NmNlODhlNWMwOTBm";
     23  public final static Executor EXECUTOR = Executors.newSingleThreadExecutor();
    2424
    25     private String[] parameters = { "lat", "lon", "distance", "limit",
    26             "min_lat", "min_lon", "max_lat", "max_lon" };
     25  private String[] parameters = { "lat", "lon", "distance", "limit", "min_lat",
     26      "min_lon", "max_lat", "max_lon" };
    2727
    28     public MapillaryDownloader() {
     28  public MapillaryDownloader() {
     29  }
     30
     31  /**
     32   * Gets all the images in a square. It downloads all the images of all the
     33   * sequences that pass through the given rectangle.
     34   *
     35   * @param minLatLon
     36   *          The minimum latitude and longitude of the rectangle.
     37   * @param maxLatLon
     38   *          The maximum latitude and longitude of the rectangle
     39   */
     40  public void getImages(LatLon minLatLon, LatLon maxLatLon) {
     41    String url1 = BASE_URL;
     42    String url2 = BASE_URL;
     43    String url3 = BASE_URL;
     44    url1 += "search/im/";
     45    url2 += "search/s/";
     46    url3 += "search/im/or";
     47    ConcurrentHashMap<String, Double> hash = new ConcurrentHashMap<>();
     48    hash.put("min_lat", minLatLon.lat());
     49    hash.put("min_lon", minLatLon.lon());
     50    hash.put("max_lat", maxLatLon.lat());
     51    hash.put("max_lon", maxLatLon.lon());
     52    url1 += buildParameters(hash);
     53    url2 += buildParameters(hash);
     54    url3 += buildParameters(hash);
     55
     56    try {
     57      Main.info("GET " + url2 + " (Mapillary plugin)");
     58      EXECUTOR.execute(new MapillarySquareDownloadManagerThread(url1, url2,
     59          url3, MapillaryLayer.getInstance()));
     60    } catch (Exception e) {
     61      Main.error(e);
    2962    }
     63  }
    3064
    31     /**
    32      * Gets all the images in a square. It downloads all the images of all the
    33      * sequences that pass through the given rectangle.
    34      *
    35      * @param minLatLon
    36      *            The minimum latitude and longitude of the rectangle.
    37      * @param maxLatLon
    38      *            The maximum latitude and longitude of the rectangle
    39      */
    40     public void getImages(LatLon minLatLon, LatLon maxLatLon) {
    41         String url1 = BASE_URL;
    42         String url2 = BASE_URL;
    43         String url3 = BASE_URL;
    44         url1 += "search/im/";
    45         url2 += "search/s/";
    46         url3 += "search/im/or";
    47         ConcurrentHashMap<String, Double> hash = new ConcurrentHashMap<>();
    48         hash.put("min_lat", minLatLon.lat());
    49         hash.put("min_lon", minLatLon.lon());
    50         hash.put("max_lat", maxLatLon.lat());
    51         hash.put("max_lon", maxLatLon.lon());
    52         url1 += buildParameters(hash);
    53         url2 += buildParameters(hash);
    54         url3 += buildParameters(hash);
     65  /**
     66   * Gets the images within the given bounds.
     67   *
     68   * @param bounds
     69   */
     70  public void getImages(Bounds bounds) {
     71    getImages(bounds.getMin(), bounds.getMax());
     72  }
    5573
    56         try {
    57             Main.info("GET " + url2 + " (Mapillary plugin)");
    58             EXECUTOR.execute(new MapillarySquareDownloadManagerThread(url1,
    59                     url2, url3, MapillaryLayer.getInstance()));
    60         } catch (Exception e) {
    61             Main.error(e);
    62         }
    63     }
    64 
    65     /**
    66      * Gets the images within the given bounds.
    67      *
    68      * @param bounds
    69      */
    70     public void getImages(Bounds bounds) {
    71         getImages(bounds.getMin(), bounds.getMax());
    72     }
    73 
    74     private String buildParameters(ConcurrentHashMap<String, Double> hash) {
    75         String ret = "?client_id=" + CLIENT_ID;
    76         for (int i = 0; i < parameters.length; i++)
    77             if (hash.get(parameters[i]) != null)
    78                 ret += "&" + parameters[i] + "=" + hash.get(parameters[i]);
    79         return ret;
    80     }
     74  private String buildParameters(ConcurrentHashMap<String, Double> hash) {
     75    String ret = "?client_id=" + CLIENT_ID;
     76    for (int i = 0; i < parameters.length; i++)
     77      if (hash.get(parameters[i]) != null)
     78        ret += "&" + parameters[i] + "=" + hash.get(parameters[i]);
     79    return ret;
     80  }
    8181}
  • applications/editors/josm/plugins/mapillary/src/org/openstreetmap/josm/plugins/mapillary/downloads/MapillaryExportDownloadThread.java

    r31331 r31350  
    2525 */
    2626public class MapillaryExportDownloadThread extends Thread implements
    27         ICachedLoaderListener {
     27    ICachedLoaderListener {
    2828
    29     String url;
    30     ArrayBlockingQueue<BufferedImage> queue;
    31     ArrayBlockingQueue<MapillaryAbstractImage> queueImages;
     29  String url;
     30  ArrayBlockingQueue<BufferedImage> queue;
     31  ArrayBlockingQueue<MapillaryAbstractImage> queueImages;
    3232
    33     ProgressMonitor monitor;
    34     MapillaryImage image;
     33  ProgressMonitor monitor;
     34  MapillaryImage image;
    3535
    36     public MapillaryExportDownloadThread(MapillaryImage image,
    37             ArrayBlockingQueue<BufferedImage> queue,
    38             ArrayBlockingQueue<MapillaryAbstractImage> queueImages) {
    39         url = "https://d1cuyjsrcm0gby.cloudfront.net/" + image.getKey()
    40                 + "/thumb-2048.jpg";
    41         this.queue = queue;
    42         this.image = image;
    43         this.queueImages = queueImages;
     36  public MapillaryExportDownloadThread(MapillaryImage image,
     37      ArrayBlockingQueue<BufferedImage> queue,
     38      ArrayBlockingQueue<MapillaryAbstractImage> queueImages) {
     39    url = "https://d1cuyjsrcm0gby.cloudfront.net/" + image.getKey()
     40        + "/thumb-2048.jpg";
     41    this.queue = queue;
     42    this.image = image;
     43    this.queueImages = queueImages;
     44  }
     45
     46  @Override
     47  public void run() {
     48    new MapillaryCache(image.getKey(), MapillaryCache.Type.FULL_IMAGE).submit(
     49        this, false);
     50  }
     51
     52  @Override
     53  public void loadingFinished(CacheEntry data, CacheEntryAttributes attributes,
     54      LoadResult result) {
     55    try {
     56      queue.put(ImageIO.read(new ByteArrayInputStream(data.getContent())));
     57      queueImages.put(image);
     58
     59    } catch (InterruptedException e) {
     60      Main.error(e);
     61    } catch (IOException e) {
     62      Main.error(e);
    4463    }
    45 
    46     @Override
    47     public void run() {
    48         new MapillaryCache(image.getKey(), MapillaryCache.Type.FULL_IMAGE)
    49                 .submit(this, false);
    50     }
    51 
    52     @Override
    53     public void loadingFinished(CacheEntry data,
    54             CacheEntryAttributes attributes, LoadResult result) {
    55         try {
    56             queue.put(ImageIO.read(new ByteArrayInputStream(data.getContent())));
    57             queueImages.put(image);
    58 
    59         } catch (InterruptedException e) {
    60             Main.error(e);
    61         } catch (IOException e) {
    62             Main.error(e);
    63         }
    64     }
     64  }
    6565}
  • applications/editors/josm/plugins/mapillary/src/org/openstreetmap/josm/plugins/mapillary/downloads/MapillaryExportManager.java

    r31331 r31350  
    3232public class MapillaryExportManager extends PleaseWaitRunnable {
    3333
    34     ArrayBlockingQueue<BufferedImage> queue;
    35     ArrayBlockingQueue<MapillaryAbstractImage> queueImages;
     34  ArrayBlockingQueue<BufferedImage> queue;
     35  ArrayBlockingQueue<MapillaryAbstractImage> queueImages;
    3636
    37     final int amount;
    38     List<MapillaryAbstractImage> images;
    39     String path;
    40    
    41     private Thread writer;
    42     private ThreadPoolExecutor ex;
     37  final int amount;
     38  List<MapillaryAbstractImage> images;
     39  String path;
    4340
    44     public MapillaryExportManager(List<MapillaryAbstractImage> images,
    45             String path) {
    46         super(tr("Downloading") + "...", new PleaseWaitProgressMonitor(
    47                 "Exporting Mapillary Images"), true);
    48         queue = new ArrayBlockingQueue<>(10);
    49         queueImages = new ArrayBlockingQueue<>(10);
     41  private Thread writer;
     42  private ThreadPoolExecutor ex;
    5043
    51         this.images = images;
    52         amount = images.size();
    53         this.path = path;
     44  public MapillaryExportManager(List<MapillaryAbstractImage> images, String path) {
     45    super(tr("Downloading") + "...", new PleaseWaitProgressMonitor(
     46        "Exporting Mapillary Images"), true);
     47    queue = new ArrayBlockingQueue<>(10);
     48    queueImages = new ArrayBlockingQueue<>(10);
     49
     50    this.images = images;
     51    amount = images.size();
     52    this.path = path;
     53  }
     54
     55  /**
     56   * Constructor used to rewrite imported images.
     57   *
     58   * @param images
     59   * @throws IOException
     60   */
     61  public MapillaryExportManager(List<MapillaryImportedImage> images)
     62      throws IOException {
     63    super(tr("Downloading") + "...", new PleaseWaitProgressMonitor(
     64        "Exporting Mapillary Images"), true);
     65    queue = new ArrayBlockingQueue<>(10);
     66    queueImages = new ArrayBlockingQueue<>(10);
     67    for (MapillaryImportedImage image : images) {
     68      queue.add(image.getImage());
     69      queueImages.add(image);
     70    }
     71    amount = images.size();
     72  }
     73
     74  @Override
     75  protected void cancel() {
     76    writer.interrupt();
     77    ex.shutdown();
     78  }
     79
     80  @Override
     81  protected void realRun() throws SAXException, IOException,
     82      OsmTransferException {
     83    // Starts a writer thread in order to write the pictures on the disk.
     84    writer = new MapillaryExportWriterThread(path, queue, queueImages, amount,
     85        this.getProgressMonitor());
     86    writer.start();
     87    if (path == null) {
     88      try {
     89        writer.join();
     90      } catch (InterruptedException e) {
     91        Main.error(e);
     92      }
     93      return;
     94    }
     95    ex = new ThreadPoolExecutor(20, 35, 25, TimeUnit.SECONDS,
     96        new ArrayBlockingQueue<Runnable>(10));
     97    for (MapillaryAbstractImage image : images) {
     98      if (image instanceof MapillaryImage) {
     99        try {
     100          ex.execute(new MapillaryExportDownloadThread((MapillaryImage) image,
     101              queue, queueImages));
     102        } catch (Exception e) {
     103          Main.error(e);
     104        }
     105      } else if (image instanceof MapillaryImportedImage) {
     106        try {
     107          queue.put(((MapillaryImportedImage) image).getImage());
     108          queueImages.put((MapillaryImportedImage) image);
     109        } catch (InterruptedException e) {
     110          Main.error(e);
     111        }
     112      }
     113      try {
     114        // If the queue is full, waits for it to have more space
     115        // available before executing anything else.
     116        while (ex.getQueue().remainingCapacity() == 0)
     117          Thread.sleep(100);
     118      } catch (Exception e) {
     119        Main.error(e);
     120      }
     121    }
     122    try {
     123      writer.join();
     124    } catch (InterruptedException e) {
     125      Main.error(e);
    54126    }
    55127
    56     /**
    57      * Constructor used to rewrite imported images.
    58      *
    59      * @param images
    60      * @throws IOException
    61      */
    62     public MapillaryExportManager(List<MapillaryImportedImage> images)
    63             throws IOException {
    64         super(tr("Downloading") + "...", new PleaseWaitProgressMonitor(
    65                 "Exporting Mapillary Images"), true);
    66         queue = new ArrayBlockingQueue<>(10);
    67         queueImages = new ArrayBlockingQueue<>(10);
    68         for (MapillaryImportedImage image : images) {
    69             queue.add(image.getImage());
    70             queueImages.add(image);
    71         }
    72         amount = images.size();
    73     }
     128  }
    74129
    75     @Override
    76     protected void cancel() {
    77         writer.interrupt();
    78         ex.shutdown();
    79     }
    80 
    81     @Override
    82     protected void realRun() throws SAXException, IOException,
    83             OsmTransferException {
    84         // Starts a writer thread in order to write the pictures on the disk.
    85         writer = new MapillaryExportWriterThread(path, queue,
    86                 queueImages, amount, this.getProgressMonitor());
    87         writer.start();
    88         if (path == null) {
    89             try {
    90                 writer.join();
    91             } catch (InterruptedException e) {
    92                 Main.error(e);
    93             }
    94             return;
    95         }
    96         ex = new ThreadPoolExecutor(20, 35, 25,
    97                 TimeUnit.SECONDS, new ArrayBlockingQueue<Runnable>(10));
    98         for (MapillaryAbstractImage image : images) {
    99             if (image instanceof MapillaryImage) {
    100                 try {
    101                     ex.execute(new MapillaryExportDownloadThread(
    102                             (MapillaryImage) image, queue, queueImages));
    103                 } catch (Exception e) {
    104                     Main.error(e);
    105                 }
    106             } else if (image instanceof MapillaryImportedImage) {
    107                 try {
    108                     queue.put(((MapillaryImportedImage) image).getImage());
    109                     queueImages.put((MapillaryImportedImage) image);
    110                 } catch (InterruptedException e) {
    111                     Main.error(e);
    112                 }
    113             }
    114             try {
    115                 // If the queue is full, waits for it to have more space
    116                 // available before executing anything else.
    117                 while (ex.getQueue().remainingCapacity() == 0)
    118                     Thread.sleep(100);
    119             } catch (Exception e) {
    120                 Main.error(e);
    121             }
    122         }
    123         try {
    124             writer.join();
    125         } catch (InterruptedException e) {
    126             Main.error(e);
    127         }
    128 
    129     }
    130 
    131     @Override
    132     protected void finish() {
    133         // TODO Auto-generated method stub
    134     }
     130  @Override
     131  protected void finish() {
     132    // TODO Auto-generated method stub
     133  }
    135134}
  • applications/editors/josm/plugins/mapillary/src/org/openstreetmap/josm/plugins/mapillary/downloads/MapillaryExportWriterThread.java

    r31331 r31350  
    3434public class MapillaryExportWriterThread extends Thread {
    3535
    36     private final String path;
    37     private final ArrayBlockingQueue<BufferedImage> queue;
    38     private final ArrayBlockingQueue<MapillaryAbstractImage> queueImages;
    39     private final int amount;
    40     private final ProgressMonitor monitor;
     36  private final String path;
     37  private final ArrayBlockingQueue<BufferedImage> queue;
     38  private final ArrayBlockingQueue<MapillaryAbstractImage> queueImages;
     39  private final int amount;
     40  private final ProgressMonitor monitor;
    4141
    42     public MapillaryExportWriterThread(String path,
    43             ArrayBlockingQueue<BufferedImage> queue,
    44             ArrayBlockingQueue<MapillaryAbstractImage> queueImages, int amount,
    45             ProgressMonitor monitor) {
    46         this.path = path;
    47         this.queue = queue;
    48         this.queueImages = queueImages;
    49         this.amount = amount;
    50         this.monitor = monitor;
     42  public MapillaryExportWriterThread(String path,
     43      ArrayBlockingQueue<BufferedImage> queue,
     44      ArrayBlockingQueue<MapillaryAbstractImage> queueImages, int amount,
     45      ProgressMonitor monitor) {
     46    this.path = path;
     47    this.queue = queue;
     48    this.queueImages = queueImages;
     49    this.amount = amount;
     50    this.monitor = monitor;
     51  }
     52
     53  @Override
     54  public void run() {
     55    monitor.setCustomText("Downloaded 0/" + amount);
     56    File tempFile = null;
     57    BufferedImage img;
     58    MapillaryAbstractImage mimg = null;
     59    String finalPath = "";
     60    for (int i = 0; i < amount; i++) {
     61      try {
     62        img = queue.take();
     63        mimg = queueImages.take();
     64        if (path == null && mimg instanceof MapillaryImportedImage) {
     65          String path = ((MapillaryImportedImage) mimg).getFile().getPath();
     66          finalPath = path.substring(0, path.lastIndexOf('.'));
     67        } else if (mimg instanceof MapillaryImage)
     68          finalPath = path + "/" + ((MapillaryImage) mimg).getKey();
     69        else
     70          finalPath = path + "/" + i;
     71        // Creates a temporal file that is going to be deleted after
     72        // writing the EXIF tags.
     73        tempFile = new File(finalPath + ".tmp");
     74        ImageIO.write(img, "jpg", tempFile);
     75
     76        // Write EXIF tags
     77        TiffOutputSet outputSet = new TiffOutputSet();
     78        TiffOutputDirectory exifDirectory = outputSet
     79            .getOrCreateExifDirectory();
     80        exifDirectory.add(GpsTagConstants.GPS_TAG_GPS_IMG_DIRECTION_REF,
     81            GpsTagConstants.GPS_TAG_GPS_IMG_DIRECTION_REF_VALUE_TRUE_NORTH);
     82        exifDirectory.add(GpsTagConstants.GPS_TAG_GPS_IMG_DIRECTION,
     83            RationalNumber.valueOf(mimg.getCa()));
     84        if (mimg instanceof MapillaryImportedImage) {
     85          exifDirectory.add(ExifTagConstants.EXIF_TAG_DATE_TIME_ORIGINAL,
     86              ((MapillaryImportedImage) mimg).getDate("yyyy/MM/dd hh:mm:ss"));
     87        } else if (mimg instanceof MapillaryImage)
     88          exifDirectory.add(ExifTagConstants.EXIF_TAG_DATE_TIME_ORIGINAL,
     89              ((MapillaryImage) mimg).getDate("yyyy/MM/dd hh/mm/ss"));
     90        outputSet.setGPSInDegrees(mimg.getLatLon().lon(), mimg.getLatLon()
     91            .lat());
     92        OutputStream os = new BufferedOutputStream(new FileOutputStream(
     93            finalPath + ".jpg"));
     94        new ExifRewriter().updateExifMetadataLossless(tempFile, os, outputSet);
     95        tempFile.delete();
     96        os.close();
     97      } catch (InterruptedException e) {
     98        Main.info("Mapillary export cancelled");
     99        return;
     100      } catch (IOException e) {
     101        Main.error(e);
     102      } catch (ImageWriteException e) {
     103        Main.error(e);
     104      } catch (ImageReadException e) {
     105        Main.error(e);
     106      }
     107
     108      // Increases the progress bar.
     109      monitor.worked(PleaseWaitProgressMonitor.PROGRESS_BAR_MAX / amount);
     110      monitor.setCustomText("Downloaded " + (i + 1) + "/" + amount);
    51111    }
    52 
    53     @Override
    54     public void run() {
    55         monitor.setCustomText("Downloaded 0/" + amount);
    56         File tempFile = null;
    57         BufferedImage img;
    58         MapillaryAbstractImage mimg = null;
    59         String finalPath = "";
    60         for (int i = 0; i < amount; i++) {
    61             try {
    62                 img = queue.take();
    63                 mimg = queueImages.take();
    64                 if (path == null && mimg instanceof MapillaryImportedImage) {
    65                     String path = ((MapillaryImportedImage) mimg).getFile()
    66                             .getPath();
    67                     finalPath = path.substring(0, path.lastIndexOf('.'));
    68                 } else if (mimg instanceof MapillaryImage)
    69                     finalPath = path + "/" + ((MapillaryImage) mimg).getKey();
    70                 else
    71                     finalPath = path + "/" + i;
    72                 // Creates a temporal file that is going to be deleted after
    73                 // writing the EXIF tags.
    74                 tempFile = new File(finalPath + ".tmp");
    75                 ImageIO.write(img, "jpg", tempFile);
    76 
    77                 // Write EXIF tags
    78                 TiffOutputSet outputSet = new TiffOutputSet();
    79                 TiffOutputDirectory exifDirectory = outputSet
    80                         .getOrCreateExifDirectory();
    81                 exifDirectory
    82                         .add(GpsTagConstants.GPS_TAG_GPS_IMG_DIRECTION_REF,
    83                                 GpsTagConstants.GPS_TAG_GPS_IMG_DIRECTION_REF_VALUE_TRUE_NORTH);
    84                 exifDirectory.add(GpsTagConstants.GPS_TAG_GPS_IMG_DIRECTION,
    85                         RationalNumber.valueOf(mimg.getCa()));
    86                 if (mimg instanceof MapillaryImportedImage) {
    87                     exifDirectory.add(
    88                             ExifTagConstants.EXIF_TAG_DATE_TIME_ORIGINAL,
    89                             ((MapillaryImportedImage) mimg)
    90                                     .getDate("yyyy/MM/dd hh:mm:ss"));
    91                 } else if (mimg instanceof MapillaryImage)
    92                     exifDirectory.add(
    93                             ExifTagConstants.EXIF_TAG_DATE_TIME_ORIGINAL,
    94                             ((MapillaryImage) mimg)
    95                                     .getDate("yyyy/MM/dd hh/mm/ss"));
    96                 outputSet.setGPSInDegrees(mimg.getLatLon().lon(), mimg
    97                         .getLatLon().lat());
    98                 OutputStream os = new BufferedOutputStream(
    99                         new FileOutputStream(finalPath + ".jpg"));
    100                 new ExifRewriter().updateExifMetadataLossless(tempFile, os,
    101                         outputSet);
    102                 tempFile.delete();
    103                 os.close();
    104             } catch (InterruptedException e) {
    105                 Main.info("Mapillary export cancelled");
    106                 return;
    107             } catch (IOException e) {
    108                 Main.error(e);
    109             } catch (ImageWriteException e) {
    110                 Main.error(e);
    111             } catch (ImageReadException e) {
    112                 Main.error(e);
    113             }
    114 
    115             // Increases the progress bar.
    116             monitor.worked(PleaseWaitProgressMonitor.PROGRESS_BAR_MAX / amount);
    117             monitor.setCustomText("Downloaded " + (i + 1) + "/" + amount);
    118         }
    119     }
     112  }
    120113}
  • applications/editors/josm/plugins/mapillary/src/org/openstreetmap/josm/plugins/mapillary/downloads/MapillaryImageInfoDownloaderThread.java

    r31341 r31350  
    2525 */
    2626public class MapillaryImageInfoDownloaderThread extends Thread {
    27     private final String url;
    28     private final ExecutorService ex;
    29     private final MapillaryLayer layer;
     27  private final String url;
     28  private final ExecutorService ex;
     29  private final MapillaryLayer layer;
    3030
    31     public MapillaryImageInfoDownloaderThread(ExecutorService ex, String url,
    32             MapillaryLayer layer) {
    33         this.ex = ex;
    34         this.url = url;
    35         this.layer = layer;
     31  public MapillaryImageInfoDownloaderThread(ExecutorService ex, String url,
     32      MapillaryLayer layer) {
     33    this.ex = ex;
     34    this.url = url;
     35    this.layer = layer;
     36  }
     37
     38  public void run() {
     39    try {
     40      BufferedReader br = new BufferedReader(new InputStreamReader(
     41          new URL(url).openStream(), "UTF-8"));
     42      JsonObject jsonobj = Json.createReader(br).readObject();
     43      if (!jsonobj.getBoolean("more"))
     44        ex.shutdown();
     45      JsonArray jsonarr = jsonobj.getJsonArray("ims");
     46      JsonObject data;
     47      for (int i = 0; i < jsonarr.size(); i++) {
     48        data = jsonarr.getJsonObject(i);
     49        String key = data.getString("key");
     50        for (MapillaryAbstractImage image : layer.data.getImages()) {
     51          if (image instanceof MapillaryImage) {
     52            if (((MapillaryImage) image).getKey().equals(key)
     53                && ((MapillaryImage) image).getUser() == null) {
     54              ((MapillaryImage) image).setUser(data.getString("user"));
     55              ((MapillaryImage) image).setCapturedAt(data.getJsonNumber(
     56                  "captured_at").longValue());
     57            }
     58          }
     59        }
     60      }
     61    } catch (MalformedURLException e) {
     62      Main.error(e);
     63    } catch (IOException e) {
     64      Main.error(e);
    3665    }
    37 
    38     public void run() {
    39         try {
    40             BufferedReader br = new BufferedReader(new InputStreamReader(
    41                     new URL(url).openStream(), "UTF-8"));
    42             JsonObject jsonobj = Json.createReader(br).readObject();
    43             if (!jsonobj.getBoolean("more"))
    44                 ex.shutdown();
    45             JsonArray jsonarr = jsonobj.getJsonArray("ims");
    46             JsonObject data;
    47             for (int i = 0; i < jsonarr.size(); i++) {
    48                 data = jsonarr.getJsonObject(i);
    49                 String key = data.getString("key");
    50                 for (MapillaryAbstractImage image : layer.data.getImages()) {
    51                     if (image instanceof MapillaryImage) {
    52                         if (((MapillaryImage) image).getKey().equals(key)
    53                                 && ((MapillaryImage) image).getUser() == null) {
    54                             ((MapillaryImage) image).setUser(data
    55                                     .getString("user"));
    56                             ((MapillaryImage) image).setCapturedAt(data
    57                                     .getJsonNumber("captured_at").longValue());
    58                         }
    59                     }
    60                 }
    61             }
    62         } catch (MalformedURLException e) {
    63             Main.error(e);
    64         } catch (IOException e) {
    65             Main.error(e);
    66         }
    67     }
     66  }
    6867}
  • applications/editors/josm/plugins/mapillary/src/org/openstreetmap/josm/plugins/mapillary/downloads/MapillarySequenceDownloadThread.java

    r31346 r31350  
    3131public class MapillarySequenceDownloadThread extends Thread {
    3232
    33     private final String url;
    34     private final ExecutorService ex;
    35     private final List<Bounds> bounds;
    36     private final MapillaryLayer layer;
    37     private final MapillarySquareDownloadManagerThread manager;
     33  private final String url;
     34  private final ExecutorService ex;
     35  private final List<Bounds> bounds;
     36  private final MapillaryLayer layer;
     37  private final MapillarySquareDownloadManagerThread manager;
    3838
    39     public MapillarySequenceDownloadThread(ExecutorService ex, String url,
    40             MapillaryLayer layer, MapillarySquareDownloadManagerThread manager) {
    41         this.url = url;
    42         this.ex = ex;
    43         this.bounds = layer.bounds;
    44         this.layer = layer;
    45         this.manager = manager;
     39  public MapillarySequenceDownloadThread(ExecutorService ex, String url,
     40      MapillaryLayer layer, MapillarySquareDownloadManagerThread manager) {
     41    this.url = url;
     42    this.ex = ex;
     43    this.bounds = layer.bounds;
     44    this.layer = layer;
     45    this.manager = manager;
     46  }
     47
     48  public void run() {
     49    try {
     50      BufferedReader br;
     51      br = new BufferedReader(new InputStreamReader(new URL(url).openStream(),
     52          "UTF-8"));
     53      JsonObject jsonall = Json.createReader(br).readObject();
     54
     55      if (!jsonall.getBoolean("more") && !ex.isShutdown())
     56        ex.shutdown();
     57      JsonArray jsonseq = jsonall.getJsonArray("ss");
     58      boolean isSequenceWrong = false;
     59      for (int i = 0; i < jsonseq.size(); i++) {
     60        JsonObject jsonobj = jsonseq.getJsonObject(i);
     61        JsonArray cas = jsonobj.getJsonArray("cas");
     62        JsonArray coords = jsonobj.getJsonArray("coords");
     63        JsonArray keys = jsonobj.getJsonArray("keys");
     64        ArrayList<MapillaryImage> images = new ArrayList<>();
     65        for (int j = 0; j < cas.size(); j++) {
     66          try {
     67            images.add(new MapillaryImage(keys.getString(j), coords
     68                .getJsonArray(j).getJsonNumber(1).doubleValue(), coords
     69                .getJsonArray(j).getJsonNumber(0).doubleValue(), cas
     70                .getJsonNumber(j).doubleValue()));
     71          } catch (IndexOutOfBoundsException e) {
     72            Main.warn("Mapillary bug at " + url);
     73            isSequenceWrong = true;
     74          }
     75        }
     76        if (isSequenceWrong)
     77          break;
     78        MapillarySequence sequence = new MapillarySequence(
     79            jsonobj.getString("key"), jsonobj.getJsonNumber("captured_at")
     80                .longValue());
     81
     82        List<MapillaryImage> finalImages = new ArrayList<>(images);
     83        // Here it gets only those images which are in the downloaded
     84        // area.
     85        for (MapillaryAbstractImage img : images) {
     86          if (!isInside(img))
     87            finalImages.remove(img);
     88        }
     89
     90        boolean imagesAdded = false;
     91        MapillaryImage.lock.lock();
     92        for (MapillaryImage img : finalImages) {
     93          if (layer.data.getImages().contains(img)) {
     94            sequence.add(img);
     95            ((MapillaryImage) layer.data.getImages().get(
     96                layer.data.getImages().indexOf(img))).setSequence(sequence);
     97            finalImages.set(
     98                finalImages.indexOf(img),
     99                (MapillaryImage) layer.data.getImages().get(
     100                    layer.data.getImages().indexOf(img)));
     101          } else {
     102            img.setSequence(sequence);
     103            imagesAdded = true;
     104            sequence.add(img);
     105          }
     106        }
     107        MapillaryImage.lock.unlock();
     108        if (manager != null) {
     109          manager.imagesAdded = imagesAdded;
     110        }
     111        layer.data.addWithoutUpdate(new ArrayList<MapillaryAbstractImage>(
     112            finalImages));
     113      }
     114    } catch (IOException e) {
     115      Main.error("Error reading the url " + url
     116          + " might be a Mapillary problem.");
    46117    }
     118  }
    47119
    48     public void run() {
    49         try {
    50             BufferedReader br;
    51             br = new BufferedReader(new InputStreamReader(
    52                     new URL(url).openStream(), "UTF-8"));
    53             JsonObject jsonall = Json.createReader(br).readObject();
    54 
    55             if (!jsonall.getBoolean("more") && !ex.isShutdown())
    56                 ex.shutdown();
    57             JsonArray jsonseq = jsonall.getJsonArray("ss");
    58             boolean isSequenceWrong = false;
    59             for (int i = 0; i < jsonseq.size(); i++) {
    60                 JsonObject jsonobj = jsonseq.getJsonObject(i);
    61                 JsonArray cas = jsonobj.getJsonArray("cas");
    62                 JsonArray coords = jsonobj.getJsonArray("coords");
    63                 JsonArray keys = jsonobj.getJsonArray("keys");
    64                 ArrayList<MapillaryImage> images = new ArrayList<>();
    65                 for (int j = 0; j < cas.size(); j++) {
    66                     try {
    67                         images.add(new MapillaryImage(keys.getString(j),
    68                                 coords.getJsonArray(j).getJsonNumber(1)
    69                                         .doubleValue(), coords.getJsonArray(j)
    70                                         .getJsonNumber(0).doubleValue(), cas
    71                                         .getJsonNumber(j).doubleValue()));
    72                     } catch (IndexOutOfBoundsException e) {
    73                         Main.warn("Mapillary bug at " + url);
    74                         isSequenceWrong = true;
    75                     }
    76                 }
    77                 if (isSequenceWrong)
    78                     break;
    79                 MapillarySequence sequence = new MapillarySequence(
    80                         jsonobj.getString("key"), jsonobj.getJsonNumber(
    81                                 "captured_at").longValue());
    82 
    83                 List<MapillaryImage> finalImages = new ArrayList<>(images);
    84                 // Here it gets only those images which are in the downloaded
    85                 // area.
    86                 for (MapillaryAbstractImage img : images) {
    87                     if (!isInside(img))
    88                         finalImages.remove(img);
    89                 }
    90 
    91                 boolean imagesAdded = false;
    92                 MapillaryImage.lock.lock();
    93                 for (MapillaryImage img : finalImages) {
    94                     if (layer.data.getImages().contains(img)) {
    95                         sequence.add(img);
    96                         ((MapillaryImage) layer.data.getImages().get(
    97                                 layer.data.getImages().indexOf(img)))
    98                                 .setSequence(sequence);
    99                         finalImages.set(
    100                                 finalImages.indexOf(img),
    101                                 (MapillaryImage) layer.data.getImages().get(
    102                                         layer.data.getImages().indexOf(img)));
    103                     } else {
    104                         img.setSequence(sequence);
    105                         imagesAdded = true;
    106                         sequence.add(img);
    107                     }
    108                 }
    109                 MapillaryImage.lock.unlock();
    110                 if (manager != null) {
    111                         manager.imagesAdded = imagesAdded;
    112                 }
    113                 layer.data
    114                         .addWithoutUpdate(new ArrayList<MapillaryAbstractImage>(
    115                                 finalImages));
    116             }
    117         } catch (IOException e) {
    118             Main.error("Error reading the url " + url
    119                     + " might be a Mapillary problem.");
    120         }
    121     }
    122 
    123     private boolean isInside(MapillaryAbstractImage image) {
    124         for (int i = 0; i < bounds.size(); i++)
    125             if (bounds.get(i).contains(image.getLatLon()))
    126                 return true;
    127         return false;
    128     }
     120  private boolean isInside(MapillaryAbstractImage image) {
     121    for (int i = 0; i < bounds.size(); i++)
     122      if (bounds.get(i).contains(image.getLatLon()))
     123        return true;
     124    return false;
     125  }
    129126}
  • applications/editors/josm/plugins/mapillary/src/org/openstreetmap/josm/plugins/mapillary/downloads/MapillarySignDownloaderThread.java

    r31341 r31350  
    1919public class MapillarySignDownloaderThread extends Thread {
    2020
    21     private final String url;
    22     private final ExecutorService ex;
    23     private final MapillaryLayer layer;
     21  private final String url;
     22  private final ExecutorService ex;
     23  private final MapillaryLayer layer;
    2424
    25     public MapillarySignDownloaderThread(ExecutorService ex, String url,
    26             MapillaryLayer layer) {
    27         this.ex = ex;
    28         this.url = url;
    29         this.layer = layer;
     25  public MapillarySignDownloaderThread(ExecutorService ex, String url,
     26      MapillaryLayer layer) {
     27    this.ex = ex;
     28    this.url = url;
     29    this.layer = layer;
     30  }
     31
     32  @Override
     33  public void run() {
     34    BufferedReader br;
     35    try {
     36      br = new BufferedReader(new InputStreamReader(new URL(url).openStream(),
     37          "UTF-8"));
     38      JsonObject jsonobj = Json.createReader(br).readObject();
     39      if (!jsonobj.getBoolean("more")) {
     40        ex.shutdown();
     41      }
     42      JsonArray jsonarr = jsonobj.getJsonArray("ims");
     43      for (int i = 0; i < jsonarr.size(); i++) {
     44        JsonArray rects = jsonarr.getJsonObject(i).getJsonArray("rects");
     45        JsonArray rectversions = jsonarr.getJsonObject(i).getJsonArray(
     46            "rectversions");
     47        String key = jsonarr.getJsonObject(i).getString("key");
     48        if (rectversions != null) {
     49          for (int j = 0; j < rectversions.size(); j++) {
     50            rects = rectversions.getJsonObject(j).getJsonArray("rects");
     51            for (int k = 0; k < rects.size(); k++) {
     52              JsonObject data = rects.getJsonObject(k);
     53              for (MapillaryAbstractImage image : layer.data.getImages())
     54                if (image instanceof MapillaryImage
     55                    && ((MapillaryImage) image).getKey().equals(key))
     56                  ((MapillaryImage) image).addSign(data.getString("type"));
     57            }
     58          }
     59        }
     60
     61        // Just one sign on the picture
     62        else if (rects != null) {
     63          for (int j = 0; j < rects.size(); j++) {
     64            JsonObject data = rects.getJsonObject(j);
     65            for (MapillaryAbstractImage image : layer.data.getImages())
     66              if (image instanceof MapillaryImage
     67                  && ((MapillaryImage) image).getKey().equals(key))
     68                ((MapillaryImage) image).addSign(data.getString("type"));
     69          }
     70        }
     71      }
     72    } catch (MalformedURLException e) {
     73      Main.error(e);
     74    } catch (IOException e) {
     75      Main.error(e);
    3076    }
    31 
    32     @Override
    33     public void run() {
    34         BufferedReader br;
    35         try {
    36             br = new BufferedReader(new InputStreamReader(
    37                     new URL(url).openStream(), "UTF-8"));
    38             JsonObject jsonobj = Json.createReader(br).readObject();
    39             if (!jsonobj.getBoolean("more")) {
    40                 ex.shutdown();
    41             }
    42             JsonArray jsonarr = jsonobj.getJsonArray("ims");
    43             for (int i = 0; i < jsonarr.size(); i++) {
    44                 JsonArray rects = jsonarr.getJsonObject(i)
    45                         .getJsonArray("rects");
    46                 JsonArray rectversions = jsonarr.getJsonObject(i).getJsonArray(
    47                         "rectversions");
    48                 String key = jsonarr.getJsonObject(i).getString("key");
    49                 if (rectversions != null) {
    50                     for (int j = 0; j < rectversions.size(); j++) {
    51                         rects = rectversions.getJsonObject(j).getJsonArray(
    52                                 "rects");
    53                         for (int k = 0; k < rects.size(); k++) {
    54                             JsonObject data = rects.getJsonObject(k);
    55                             for (MapillaryAbstractImage image : layer.data
    56                                     .getImages())
    57                                 if (image instanceof MapillaryImage
    58                                         && ((MapillaryImage) image).getKey()
    59                                                 .equals(key))
    60                                     ((MapillaryImage) image).addSign(data
    61                                             .getString("type"));
    62                         }
    63                     }
    64                 }
    65 
    66                 // Just one sign on the picture
    67                 else if (rects != null) {
    68                     for (int j = 0; j < rects.size(); j++) {
    69                         JsonObject data = rects.getJsonObject(j);
    70                         for (MapillaryAbstractImage image : layer.data
    71                                 .getImages())
    72                             if (image instanceof MapillaryImage
    73                                     && ((MapillaryImage) image).getKey()
    74                                             .equals(key))
    75                                 ((MapillaryImage) image).addSign(data
    76                                         .getString("type"));
    77                     }
    78                 }
    79             }
    80         } catch (MalformedURLException e) {
    81             Main.error(e);
    82         } catch (IOException e) {
    83             Main.error(e);
    84         }
    85     }
     77  }
    8678}
  • applications/editors/josm/plugins/mapillary/src/org/openstreetmap/josm/plugins/mapillary/downloads/MapillarySquareDownloadManagerThread.java

    r31346 r31350  
    1414/**
    1515 * This Class is needed to create an indeterminate amount of downloads, because
    16  * the Mapillary API has a parameter called page which is needed when the
    17  * amount of requested images is quite big.
     16 * the Mapillary API has a parameter called page which is needed when the amount
     17 * of requested images is quite big.
    1818 *
    1919 * @author nokutu
     
    2323public class MapillarySquareDownloadManagerThread extends Thread {
    2424
    25     private final String urlImages;
    26     private final String urlSequences;
    27     private final String urlSigns;
    28     private final MapillaryLayer layer;
    29     public boolean imagesAdded = false;
     25  private final String urlImages;
     26  private final String urlSequences;
     27  private final String urlSigns;
     28  private final MapillaryLayer layer;
     29  public boolean imagesAdded = false;
    3030
    31     public MapillarySquareDownloadManagerThread(String urlImages,
    32             String urlSequences, String urlSigns, MapillaryLayer layer) {
    33         this.urlImages = urlImages;
    34         this.urlSequences = urlSequences;
    35         this.urlSigns = urlSigns;
    36         this.layer = layer;
     31  public MapillarySquareDownloadManagerThread(String urlImages,
     32      String urlSequences, String urlSigns, MapillaryLayer layer) {
     33    this.urlImages = urlImages;
     34    this.urlSequences = urlSequences;
     35    this.urlSigns = urlSigns;
     36    this.layer = layer;
     37  }
     38
     39  public void run() {
     40    Main.map.statusLine.setHelpText("Downloading images from Mapillary");
     41    try {
     42      downloadSequences();
     43      if (imagesAdded) {
     44        Main.map.statusLine.setHelpText("Downloading image's information");
     45        completeImages();
     46        MapillaryMainDialog.getInstance().updateTitle();
     47        Main.map.statusLine.setHelpText("Downloading signs");
     48        downloadSigns();
     49      }
     50    } catch (InterruptedException e) {
     51      Main.error(e);
    3752    }
     53    if (layer.data.getImages().size() > 0)
     54      Main.map.statusLine.setHelpText(tr("Total images: ")
     55          + layer.data.getImages().size());
     56    else
     57      Main.map.statusLine.setHelpText(tr("No images found"));
     58    layer.data.dataUpdated();
     59    MapillaryFilterDialog.getInstance().refresh();
     60    MapillaryMainDialog.getInstance().updateImage();
     61  }
    3862
    39     public void run() {
    40         Main.map.statusLine.setHelpText("Downloading images from Mapillary");
    41         try {
    42             downloadSequences();
    43             if (imagesAdded) {
    44                 Main.map.statusLine
    45                         .setHelpText("Downloading image's information");
    46                 completeImages();
    47                 MapillaryMainDialog.getInstance().updateTitle();
    48                 Main.map.statusLine.setHelpText("Downloading signs");
    49                 downloadSigns();
    50             }
    51         } catch (InterruptedException e) {
    52             Main.error(e);
    53         }
    54         if (layer.data.getImages().size() > 0)
    55             Main.map.statusLine.setHelpText(tr("Total images: ")
    56                     + layer.data.getImages().size());
    57         else
    58             Main.map.statusLine.setHelpText(tr("No images found"));
    59         layer.data.dataUpdated();
    60         MapillaryFilterDialog.getInstance().refresh();
    61         MapillaryMainDialog.getInstance().updateImage();
     63  private void downloadSequences() throws InterruptedException {
     64    ThreadPoolExecutor ex = new ThreadPoolExecutor(3, 5, 25, TimeUnit.SECONDS,
     65        new ArrayBlockingQueue<Runnable>(5));
     66    int page = 0;
     67    while (!ex.isShutdown()) {
     68      ex.execute(new MapillarySequenceDownloadThread(ex, urlSequences
     69          + "&page=" + page + "&limit=10", layer, this));
     70      while (ex.getQueue().remainingCapacity() == 0)
     71        Thread.sleep(500);
     72      page++;
    6273    }
     74    ex.awaitTermination(15, TimeUnit.SECONDS);
     75    layer.data.dataUpdated();
     76  }
    6377
    64     private void downloadSequences() throws InterruptedException {
    65         ThreadPoolExecutor ex = new ThreadPoolExecutor(3, 5, 25,
    66                 TimeUnit.SECONDS, new ArrayBlockingQueue<Runnable>(5));
    67         int page = 0;
    68         while (!ex.isShutdown()) {
    69             ex.execute(new MapillarySequenceDownloadThread(ex, urlSequences
    70                     + "&page=" + page + "&limit=10", layer, this));
    71             while (ex.getQueue().remainingCapacity() == 0)
    72                 Thread.sleep(500);
    73             page++;
    74         }
    75         ex.awaitTermination(15, TimeUnit.SECONDS);
    76         layer.data.dataUpdated();
     78  private void completeImages() throws InterruptedException {
     79    ThreadPoolExecutor ex = new ThreadPoolExecutor(3, 5, 25, TimeUnit.SECONDS,
     80        new ArrayBlockingQueue<Runnable>(5));
     81    int page = 0;
     82    while (!ex.isShutdown()) {
     83      ex.execute(new MapillaryImageInfoDownloaderThread(ex, urlImages
     84          + "&page=" + page + "&limit=20", layer));
     85      while (ex.getQueue().remainingCapacity() == 0)
     86        Thread.sleep(100);
     87      page++;
    7788    }
     89    ex.awaitTermination(15, TimeUnit.SECONDS);
     90  }
    7891
    79     private void completeImages() throws InterruptedException {
    80         ThreadPoolExecutor ex = new ThreadPoolExecutor(3, 5, 25,
    81                 TimeUnit.SECONDS, new ArrayBlockingQueue<Runnable>(5));
    82         int page = 0;
    83         while (!ex.isShutdown()) {
    84             ex.execute(new MapillaryImageInfoDownloaderThread(ex, urlImages
    85                     + "&page=" + page + "&limit=20", layer));
    86             while (ex.getQueue().remainingCapacity() == 0)
    87                 Thread.sleep(100);
    88             page++;
    89         }
    90         ex.awaitTermination(15, TimeUnit.SECONDS);
     92  private void downloadSigns() throws InterruptedException {
     93    ThreadPoolExecutor ex = new ThreadPoolExecutor(3, 5, 25, TimeUnit.SECONDS,
     94        new ArrayBlockingQueue<Runnable>(5));
     95    int page = 0;
     96    while (!ex.isShutdown()) {
     97      ex.execute(new MapillarySignDownloaderThread(ex, urlSigns + "&page="
     98          + page + "&limit=20", layer));
     99      while (ex.getQueue().remainingCapacity() == 0)
     100        Thread.sleep(100);
     101      page++;
    91102    }
    92 
    93     private void downloadSigns() throws InterruptedException {
    94         ThreadPoolExecutor ex = new ThreadPoolExecutor(3, 5, 25,
    95                 TimeUnit.SECONDS, new ArrayBlockingQueue<Runnable>(5));
    96         int page = 0;
    97         while (!ex.isShutdown()) {
    98             ex.execute(new MapillarySignDownloaderThread(ex, urlSigns
    99                     + "&page=" + page + "&limit=20", layer));
    100             while (ex.getQueue().remainingCapacity() == 0)
    101                 Thread.sleep(100);
    102             page++;
    103         }
    104         ex.awaitTermination(15, TimeUnit.SECONDS);
    105     }
     103    ex.awaitTermination(15, TimeUnit.SECONDS);
     104  }
    106105}
  • applications/editors/josm/plugins/mapillary/src/org/openstreetmap/josm/plugins/mapillary/gui/HyperlinkLabel.java

    r31278 r31350  
    2121public class HyperlinkLabel extends JLabel implements ActionListener {
    2222
    23     private String text;
    24     private URL url;
     23  private String text;
     24  private URL url;
    2525
    26     /**
    27      * Creates a new HyperlinlLabel.
    28      */
    29     public HyperlinkLabel() {
    30         super(tr("View in website"), SwingUtilities.RIGHT);
    31         this.addActionListener(this);
    32         setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
     26  /**
     27   * Creates a new HyperlinlLabel.
     28   */
     29  public HyperlinkLabel() {
     30    super(tr("View in website"), SwingUtilities.RIGHT);
     31    this.addActionListener(this);
     32    setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
    3333
    34         enableEvents(MouseEvent.MOUSE_EVENT_MASK);
     34    enableEvents(MouseEvent.MOUSE_EVENT_MASK);
     35  }
     36
     37  /**
     38   * Sets the text of the label.
     39   */
     40  public void setText(String text) {
     41    super
     42        .setText("<html><font color=\"#0000CF\" size=\"2\">" + text + "</font></html>"); //$NON-NLS-1$ //$NON-NLS-2$
     43    this.text = text;
     44  }
     45
     46  /**
     47   * Sets a new URL, just pass the key of the image or null if there is none.
     48   *
     49   * @param key
     50   */
     51  public void setURL(String key) {
     52    if (key == null) {
     53      this.url = null;
     54      return;
    3555    }
     56    try {
     57      this.url = new URL("http://www.mapillary.com/map/im/" + key);
     58    } catch (MalformedURLException e) {
     59      Main.error(e);
     60    }
     61  }
    3662
    37     /**
    38      * Sets the text of the label.
    39      */
    40     public void setText(String text) {
    41         super.setText("<html><font color=\"#0000CF\" size=\"2\">" + text + "</font></html>"); //$NON-NLS-1$ //$NON-NLS-2$
    42         this.text = text;
     63  /**
     64   * Returns the text set by the user.
     65   */
     66  public String getNormalText() {
     67    return text;
     68  }
     69
     70  /**
     71   * Processes mouse events and responds to clicks.
     72   */
     73  protected void processMouseEvent(MouseEvent evt) {
     74    super.processMouseEvent(evt);
     75    if (evt.getID() == MouseEvent.MOUSE_CLICKED)
     76      fireActionPerformed(new ActionEvent(this, ActionEvent.ACTION_PERFORMED,
     77          getNormalText()));
     78  }
     79
     80  /**
     81   * Adds an ActionListener to the list of listeners receiving notifications
     82   * when the label is clicked.
     83   */
     84  public void addActionListener(ActionListener listener) {
     85    listenerList.add(ActionListener.class, listener);
     86  }
     87
     88  /**
     89   * Removes the given ActionListener from the list of listeners receiving
     90   * notifications when the label is clicked.
     91   */
     92  public void removeActionListener(ActionListener listener) {
     93    listenerList.remove(ActionListener.class, listener);
     94  }
     95
     96  /**
     97   * Fires an ActionEvent to all interested listeners.
     98   */
     99  protected void fireActionPerformed(ActionEvent evt) {
     100    Object[] listeners = listenerList.getListenerList();
     101    for (int i = 0; i < listeners.length; i += 2) {
     102      if (listeners[i] == ActionListener.class) {
     103        ActionListener listener = (ActionListener) listeners[i + 1];
     104        listener.actionPerformed(evt);
     105      }
    43106    }
     107  }
    44108
    45     /**
    46      * Sets a new URL, just pass the key of the image or null if there is none.
    47      *
    48      * @param key
    49      */
    50     public void setURL(String key) {
    51         if (key == null) {
    52             this.url = null;
    53             return;
    54         }
    55         try {
    56             this.url = new URL("http://www.mapillary.com/map/im/" + key);
    57         } catch (MalformedURLException e) {
    58             Main.error(e);
    59         }
     109  @Override
     110  public void actionPerformed(ActionEvent e) {
     111    if (this.url == null)
     112      return;
     113    Desktop desktop = Desktop.getDesktop();
     114    try {
     115      desktop.browse(url.toURI());
     116    } catch (IOException | URISyntaxException ex) {
     117      ex.printStackTrace();
     118    } catch (UnsupportedOperationException ex) {
     119      Runtime runtime = Runtime.getRuntime();
     120      try {
     121        runtime.exec("xdg-open " + url);
     122      } catch (IOException exc) {
     123        exc.printStackTrace();
     124      }
    60125    }
    61 
    62     /**
    63      * Returns the text set by the user.
    64      */
    65     public String getNormalText() {
    66         return text;
    67     }
    68 
    69     /**
    70      * Processes mouse events and responds to clicks.
    71      */
    72     protected void processMouseEvent(MouseEvent evt) {
    73         super.processMouseEvent(evt);
    74         if (evt.getID() == MouseEvent.MOUSE_CLICKED)
    75             fireActionPerformed(new ActionEvent(this,
    76                     ActionEvent.ACTION_PERFORMED, getNormalText()));
    77     }
    78 
    79     /**
    80      * Adds an ActionListener to the list of listeners receiving notifications
    81      * when the label is clicked.
    82      */
    83     public void addActionListener(ActionListener listener) {
    84         listenerList.add(ActionListener.class, listener);
    85     }
    86 
    87     /**
    88      * Removes the given ActionListener from the list of listeners receiving
    89      * notifications when the label is clicked.
    90      */
    91     public void removeActionListener(ActionListener listener) {
    92         listenerList.remove(ActionListener.class, listener);
    93     }
    94 
    95     /**
    96      * Fires an ActionEvent to all interested listeners.
    97      */
    98     protected void fireActionPerformed(ActionEvent evt) {
    99         Object[] listeners = listenerList.getListenerList();
    100         for (int i = 0; i < listeners.length; i += 2) {
    101             if (listeners[i] == ActionListener.class) {
    102                 ActionListener listener = (ActionListener) listeners[i + 1];
    103                 listener.actionPerformed(evt);
    104             }
    105         }
    106     }
    107 
    108     @Override
    109     public void actionPerformed(ActionEvent e) {
    110         if (this.url == null)
    111             return;
    112         Desktop desktop = Desktop.getDesktop();
    113         try {
    114             desktop.browse(url.toURI());
    115         } catch (IOException | URISyntaxException ex) {
    116             ex.printStackTrace();
    117         } catch (UnsupportedOperationException ex) {
    118             Runtime runtime = Runtime.getRuntime();
    119             try {
    120                 runtime.exec("xdg-open " + url);
    121             } catch (IOException exc) {
    122                 exc.printStackTrace();
    123             }
    124         }
    125     }
     126  }
    126127}
  • applications/editors/josm/plugins/mapillary/src/org/openstreetmap/josm/plugins/mapillary/gui/MapillaryExportDialog.java

    r31331 r31350  
    3030public class MapillaryExportDialog extends JPanel implements ActionListener {
    3131
    32     protected JOptionPane optionPane;
    33     /** Button to export all downloaded images. */
    34     public JRadioButton all;
    35     /**
    36      * Button to export all images in the sequence of the selected
    37      * MapillaryImage.
    38      */
    39     public JRadioButton sequence;
    40     /**
    41      * Button to export all images belonging to the selected MapillaryImage
    42      * objects.
    43      */
    44     public JRadioButton selected;
    45     public JRadioButton rewrite;
    46     public ButtonGroup group;
    47     protected JButton choose;
    48     protected JLabel path;
    49     public JFileChooser chooser;
    50     protected String exportDirectory;
     32  protected JOptionPane optionPane;
     33  /** Button to export all downloaded images. */
     34  public JRadioButton all;
     35  /**
     36   * Button to export all images in the sequence of the selected MapillaryImage.
     37   */
     38  public JRadioButton sequence;
     39  /**
     40   * Button to export all images belonging to the selected MapillaryImage
     41   * objects.
     42   */
     43  public JRadioButton selected;
     44  public JRadioButton rewrite;
     45  public ButtonGroup group;
     46  protected JButton choose;
     47  protected JLabel path;
     48  public JFileChooser chooser;
     49  protected String exportDirectory;
    5150
    52     public MapillaryExportDialog() {
    53         setLayout(new BoxLayout(this, BoxLayout.PAGE_AXIS));
    54        
    55         RewriteButtonAction action = new RewriteButtonAction(this);
    56         group = new ButtonGroup();
    57         all = new JRadioButton(action);
    58         all.setText(tr("Export all images"));
    59         sequence = new JRadioButton(action);
    60         sequence.setText(tr("Export selected sequence"));
    61         selected = new JRadioButton(action);
    62         selected.setText(tr("Export selected images"));
    63         rewrite = new JRadioButton(action);
    64         rewrite.setText(tr("Rewrite imported images"));
    65         group.add(all);
    66         group.add(sequence);
    67         group.add(selected);
    68         group.add(rewrite);
    69         // Some options are disabled depending on the circumstances
    70         if (MapillaryData.getInstance().getSelectedImage() == null
    71                 || !(MapillaryData.getInstance().getSelectedImage() instanceof MapillaryImage && ((MapillaryImage) MapillaryData
    72                         .getInstance().getSelectedImage()).getSequence() != null)) {
    73             sequence.setEnabled(false);
    74         }
    75         if (MapillaryData.getInstance().getMultiSelectedImages().isEmpty()) {
    76             selected.setEnabled(false);
    77         }
    78         rewrite.setEnabled(false);
    79         for (MapillaryAbstractImage img : MapillaryData.getInstance().getImages())
    80             if (img instanceof MapillaryImportedImage)
    81                 rewrite.setEnabled(true);
    82        
    83         path = new JLabel(tr("Select a folder"));
    84         choose = new JButton(tr("Explore"));
    85         choose.addActionListener(this);
     51  public MapillaryExportDialog() {
     52    setLayout(new BoxLayout(this, BoxLayout.PAGE_AXIS));
    8653
    87         // All options belong to the same jpanel so the are in line.
    88         JPanel jpanel = new JPanel();
    89         jpanel.setLayout(new BoxLayout(jpanel, BoxLayout.PAGE_AXIS));
    90         jpanel.add(all);
    91         jpanel.add(sequence);
    92         jpanel.add(selected);
    93         jpanel.add(rewrite);
    94         jpanel.setAlignmentX(Component.CENTER_ALIGNMENT);
    95         path.setAlignmentX(Component.CENTER_ALIGNMENT);
    96         choose.setAlignmentX(Component.CENTER_ALIGNMENT);
     54    RewriteButtonAction action = new RewriteButtonAction(this);
     55    group = new ButtonGroup();
     56    all = new JRadioButton(action);
     57    all.setText(tr("Export all images"));
     58    sequence = new JRadioButton(action);
     59    sequence.setText(tr("Export selected sequence"));
     60    selected = new JRadioButton(action);
     61    selected.setText(tr("Export selected images"));
     62    rewrite = new JRadioButton(action);
     63    rewrite.setText(tr("Rewrite imported images"));
     64    group.add(all);
     65    group.add(sequence);
     66    group.add(selected);
     67    group.add(rewrite);
     68    // Some options are disabled depending on the circumstances
     69    if (MapillaryData.getInstance().getSelectedImage() == null
     70        || !(MapillaryData.getInstance().getSelectedImage() instanceof MapillaryImage && ((MapillaryImage) MapillaryData
     71            .getInstance().getSelectedImage()).getSequence() != null)) {
     72      sequence.setEnabled(false);
     73    }
     74    if (MapillaryData.getInstance().getMultiSelectedImages().isEmpty()) {
     75      selected.setEnabled(false);
     76    }
     77    rewrite.setEnabled(false);
     78    for (MapillaryAbstractImage img : MapillaryData.getInstance().getImages())
     79      if (img instanceof MapillaryImportedImage)
     80        rewrite.setEnabled(true);
    9781
    98         add(jpanel);
    99         add(path);
    100         add(choose);
     82    path = new JLabel(tr("Select a folder"));
     83    choose = new JButton(tr("Explore"));
     84    choose.addActionListener(this);
     85
     86    // All options belong to the same jpanel so the are in line.
     87    JPanel jpanel = new JPanel();
     88    jpanel.setLayout(new BoxLayout(jpanel, BoxLayout.PAGE_AXIS));
     89    jpanel.add(all);
     90    jpanel.add(sequence);
     91    jpanel.add(selected);
     92    jpanel.add(rewrite);
     93    jpanel.setAlignmentX(Component.CENTER_ALIGNMENT);
     94    path.setAlignmentX(Component.CENTER_ALIGNMENT);
     95    choose.setAlignmentX(Component.CENTER_ALIGNMENT);
     96
     97    add(jpanel);
     98    add(path);
     99    add(choose);
     100  }
     101
     102  /**
     103   * Creates the folder choser GUI.
     104   */
     105  @Override
     106  public void actionPerformed(ActionEvent e) {
     107    chooser = new JFileChooser();
     108    chooser.setCurrentDirectory(new java.io.File(System
     109        .getProperty("user.home")));
     110    chooser.setDialogTitle(tr("Select a directory"));
     111    chooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
     112    chooser.setAcceptAllFileFilterUsed(false);
     113
     114    if (chooser.showOpenDialog(this) == JFileChooser.APPROVE_OPTION) {
     115      path.setText(chooser.getSelectedFile().toString());
     116      this.updateUI();
     117    }
     118  }
     119
     120  public class RewriteButtonAction extends AbstractAction {
     121
     122    private String lastPath;
     123    private MapillaryExportDialog dlg;
     124
     125    public RewriteButtonAction(MapillaryExportDialog dlg) {
     126      this.dlg = dlg;
    101127    }
    102128
    103     /**
    104      * Creates the folder choser GUI.
    105      */
    106129    @Override
    107     public void actionPerformed(ActionEvent e) {
    108         chooser = new JFileChooser();
    109         chooser.setCurrentDirectory(new java.io.File(System
    110                 .getProperty("user.home")));
    111         chooser.setDialogTitle(tr("Select a directory"));
    112         chooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
    113         chooser.setAcceptAllFileFilterUsed(false);
     130    public void actionPerformed(ActionEvent arg0) {
     131      choose.setEnabled(!rewrite.isSelected());
     132      if (rewrite.isSelected()) {
     133        lastPath = dlg.path.getText();
     134        dlg.path.setText(" ");
     135      } else if (lastPath != null) {
     136        dlg.path.setText(lastPath);
     137      }
    114138
    115         if (chooser.showOpenDialog(this) == JFileChooser.APPROVE_OPTION) {
    116             path.setText(chooser.getSelectedFile().toString());
    117             this.updateUI();
    118         }
    119139    }
    120    
    121     public class RewriteButtonAction extends AbstractAction {
    122140
    123         private String lastPath;
    124         private MapillaryExportDialog dlg;
    125        
    126         public RewriteButtonAction(MapillaryExportDialog dlg) {
    127             this.dlg = dlg;
    128         }
    129        
    130         @Override
    131         public void actionPerformed(ActionEvent arg0) {
    132            choose.setEnabled(!rewrite.isSelected());
    133            if (rewrite.isSelected()) {
    134                lastPath = dlg.path.getText();
    135                dlg.path.setText(" ");
    136            }
    137            else if (lastPath != null){
    138                dlg.path.setText(lastPath);
    139            }
    140            
    141         }
    142        
    143     }
     141  }
    144142}
  • applications/editors/josm/plugins/mapillary/src/org/openstreetmap/josm/plugins/mapillary/gui/MapillaryFilterChooseSigns.java

    r31328 r31350  
    1414
    1515public class MapillaryFilterChooseSigns extends JPanel implements
    16         ActionListener {
     16    ActionListener {
    1717
    18     public final JCheckBox maxspeed = new JCheckBox();
    19     public final JCheckBox stop = new JCheckBox();
    20     public final JCheckBox giveWay = new JCheckBox();
    21     public final JCheckBox roundabout = new JCheckBox();
    22     public final JCheckBox access = new JCheckBox();
    23     public final JCheckBox intersection = new JCheckBox();
    24     public final JCheckBox direction = new JCheckBox();
    25     public final JCheckBox uneven = new JCheckBox();
    26     public final JCheckBox noParking = new JCheckBox();
    27     public final JCheckBox noOvertaking = new JCheckBox();
    28     public final JCheckBox crossing = new JCheckBox();
    29     public final JCheckBox noTurn = new JCheckBox();
     18  public final JCheckBox maxspeed = new JCheckBox();
     19  public final JCheckBox stop = new JCheckBox();
     20  public final JCheckBox giveWay = new JCheckBox();
     21  public final JCheckBox roundabout = new JCheckBox();
     22  public final JCheckBox access = new JCheckBox();
     23  public final JCheckBox intersection = new JCheckBox();
     24  public final JCheckBox direction = new JCheckBox();
     25  public final JCheckBox uneven = new JCheckBox();
     26  public final JCheckBox noParking = new JCheckBox();
     27  public final JCheckBox noOvertaking = new JCheckBox();
     28  public final JCheckBox crossing = new JCheckBox();
     29  public final JCheckBox noTurn = new JCheckBox();
    3030
    31     private static MapillaryFilterChooseSigns INSTANCE;
     31  private static MapillaryFilterChooseSigns INSTANCE;
    3232
    33     public MapillaryFilterChooseSigns() {
    34         maxspeed.setSelected(true);
    35         stop.setSelected(true);
    36         giveWay.setSelected(true);
    37         roundabout.setSelected(true);
    38         access.setSelected(true);
    39         intersection.setSelected(true);
    40         direction.setSelected(true);
    41         uneven.setSelected(true);
    42         noParking.setSelected(true);
    43         noOvertaking.setSelected(true);
    44         crossing.setSelected(true);
    45         noTurn.setSelected(true);
     33  public MapillaryFilterChooseSigns() {
     34    maxspeed.setSelected(true);
     35    stop.setSelected(true);
     36    giveWay.setSelected(true);
     37    roundabout.setSelected(true);
     38    access.setSelected(true);
     39    intersection.setSelected(true);
     40    direction.setSelected(true);
     41    uneven.setSelected(true);
     42    noParking.setSelected(true);
     43    noOvertaking.setSelected(true);
     44    crossing.setSelected(true);
     45    noTurn.setSelected(true);
    4646
    47         // Max speed sign
    48         JPanel maxspeedPanel = new JPanel();
    49         JLabel maxspeedLabel = new JLabel(tr("Speed limit"));
    50         maxspeedLabel.setIcon(new ImageProvider("signs/speed.png").get());
    51         maxspeedPanel.add(maxspeedLabel);
    52         maxspeedPanel.add(maxspeed);
    53         this.add(maxspeedPanel);
     47    // Max speed sign
     48    JPanel maxspeedPanel = new JPanel();
     49    JLabel maxspeedLabel = new JLabel(tr("Speed limit"));
     50    maxspeedLabel.setIcon(new ImageProvider("signs/speed.png").get());
     51    maxspeedPanel.add(maxspeedLabel);
     52    maxspeedPanel.add(maxspeed);
     53    this.add(maxspeedPanel);
    5454
    55         // Stop sign
    56         JPanel stopPanel = new JPanel();
    57         JLabel stopLabel = new JLabel(tr("Stop"));
    58         stopLabel.setIcon(new ImageProvider("signs/stop.png").get());
    59         stopPanel.add(stopLabel);
    60         stopPanel.add(stop);
    61         this.add(stopPanel);
     55    // Stop sign
     56    JPanel stopPanel = new JPanel();
     57    JLabel stopLabel = new JLabel(tr("Stop"));
     58    stopLabel.setIcon(new ImageProvider("signs/stop.png").get());
     59    stopPanel.add(stopLabel);
     60    stopPanel.add(stop);
     61    this.add(stopPanel);
    6262
    63         // Give way sign
    64         JPanel giveWayPanel = new JPanel();
    65         JLabel giveWayLabel = new JLabel(tr("Give way"));
    66         giveWayLabel.setIcon(new ImageProvider("signs/right_of_way.png").get());
    67         giveWayPanel.add(giveWayLabel);
    68         giveWayPanel.add(giveWay);
    69         this.add(giveWayPanel);
     63    // Give way sign
     64    JPanel giveWayPanel = new JPanel();
     65    JLabel giveWayLabel = new JLabel(tr("Give way"));
     66    giveWayLabel.setIcon(new ImageProvider("signs/right_of_way.png").get());
     67    giveWayPanel.add(giveWayLabel);
     68    giveWayPanel.add(giveWay);
     69    this.add(giveWayPanel);
    7070
    71         // Roundabout sign
    72         JPanel roundaboutPanel = new JPanel();
    73         JLabel roundaboutLabel = new JLabel(tr("Give way"));
    74         roundaboutLabel.setIcon(new ImageProvider("signs/roundabout_right.png")
    75                 .get());
    76         roundaboutPanel.add(roundaboutLabel);
    77         roundaboutPanel.add(roundabout);
    78         this.add(roundaboutPanel);
     71    // Roundabout sign
     72    JPanel roundaboutPanel = new JPanel();
     73    JLabel roundaboutLabel = new JLabel(tr("Give way"));
     74    roundaboutLabel.setIcon(new ImageProvider("signs/roundabout_right.png")
     75        .get());
     76    roundaboutPanel.add(roundaboutLabel);
     77    roundaboutPanel.add(roundabout);
     78    this.add(roundaboutPanel);
    7979
    80         // No entry sign
    81         JPanel noEntryPanel = new JPanel();
    82         JLabel noEntryLabel = new JLabel(tr("No entry"));
    83         noEntryLabel.setIcon(new ImageProvider("signs/no_entry.png").get());
    84         noEntryPanel.add(noEntryLabel);
    85         noEntryPanel.add(access);
    86         this.add(noEntryPanel);
     80    // No entry sign
     81    JPanel noEntryPanel = new JPanel();
     82    JLabel noEntryLabel = new JLabel(tr("No entry"));
     83    noEntryLabel.setIcon(new ImageProvider("signs/no_entry.png").get());
     84    noEntryPanel.add(noEntryLabel);
     85    noEntryPanel.add(access);
     86    this.add(noEntryPanel);
    8787
    88         // Danger intersection
    89         JPanel intersectionPanel = new JPanel();
    90         JLabel intersectionLabel = new JLabel(tr("Intersection danger"));
    91         intersectionLabel.setIcon(new ImageProvider(
    92                 "signs/intersection_danger.png").get());
    93         intersectionPanel.add(intersectionLabel);
    94         intersectionPanel.add(intersection);
    95         this.add(intersectionPanel);
     88    // Danger intersection
     89    JPanel intersectionPanel = new JPanel();
     90    JLabel intersectionLabel = new JLabel(tr("Intersection danger"));
     91    intersectionLabel
     92        .setIcon(new ImageProvider("signs/intersection_danger.png").get());
     93    intersectionPanel.add(intersectionLabel);
     94    intersectionPanel.add(intersection);
     95    this.add(intersectionPanel);
    9696
    97         // Mandatory direction
    98         JPanel directionPanel = new JPanel();
    99         JLabel directionLabel = new JLabel(tr("Mandatory direction (any)"));
    100         directionLabel.setIcon(new ImageProvider("signs/only_straight_on.png")
    101                 .get());
    102         directionPanel.add(directionLabel);
    103         directionPanel.add(direction);
    104         this.add(directionPanel);
     97    // Mandatory direction
     98    JPanel directionPanel = new JPanel();
     99    JLabel directionLabel = new JLabel(tr("Mandatory direction (any)"));
     100    directionLabel.setIcon(new ImageProvider("signs/only_straight_on.png")
     101        .get());
     102    directionPanel.add(directionLabel);
     103    directionPanel.add(direction);
     104    this.add(directionPanel);
    105105
    106         // No turn
    107         JPanel noTurnPanel = new JPanel();
    108         JLabel noTurnLabel = new JLabel(tr("No turn"));
    109         noTurnLabel.setIcon(new ImageProvider("signs/no_turn.png").get());
    110         noTurnPanel.add(noTurnLabel);
    111         noTurnPanel.add(noTurn);
    112         this.add(noTurnPanel);
     106    // No turn
     107    JPanel noTurnPanel = new JPanel();
     108    JLabel noTurnLabel = new JLabel(tr("No turn"));
     109    noTurnLabel.setIcon(new ImageProvider("signs/no_turn.png").get());
     110    noTurnPanel.add(noTurnLabel);
     111    noTurnPanel.add(noTurn);
     112    this.add(noTurnPanel);
    113113
    114         // Uneven road
    115         JPanel unevenPanel = new JPanel();
    116         JLabel unevenLabel = new JLabel(tr("Uneven road"));
    117         unevenLabel.setIcon(new ImageProvider("signs/uneaven.png").get());
    118         unevenPanel.add(unevenLabel);
    119         unevenPanel.add(uneven);
    120         this.add(unevenPanel);
     114    // Uneven road
     115    JPanel unevenPanel = new JPanel();
     116    JLabel unevenLabel = new JLabel(tr("Uneven road"));
     117    unevenLabel.setIcon(new ImageProvider("signs/uneaven.png").get());
     118    unevenPanel.add(unevenLabel);
     119    unevenPanel.add(uneven);
     120    this.add(unevenPanel);
    121121
    122         // No parking
    123         JPanel noParkingPanel = new JPanel();
    124         JLabel noParkingLabel = new JLabel(tr("No parking"));
    125         noParkingLabel.setIcon(new ImageProvider("signs/no_parking.png").get());
    126         noParkingPanel.add(noParkingLabel);
    127         noParkingPanel.add(noParking);
    128         this.add(noParkingPanel);
     122    // No parking
     123    JPanel noParkingPanel = new JPanel();
     124    JLabel noParkingLabel = new JLabel(tr("No parking"));
     125    noParkingLabel.setIcon(new ImageProvider("signs/no_parking.png").get());
     126    noParkingPanel.add(noParkingLabel);
     127    noParkingPanel.add(noParking);
     128    this.add(noParkingPanel);
    129129
    130         // No overtaking
    131         JPanel noOvertakingPanel = new JPanel();
    132         JLabel noOvertakingLabel = new JLabel(tr("No overtaking"));
    133         noOvertakingLabel.setIcon(new ImageProvider("signs/no_overtaking.png")
    134                 .get());
    135         noOvertakingPanel.add(noOvertakingLabel);
    136         noOvertakingPanel.add(noOvertaking);
    137         this.add(noOvertakingPanel);
     130    // No overtaking
     131    JPanel noOvertakingPanel = new JPanel();
     132    JLabel noOvertakingLabel = new JLabel(tr("No overtaking"));
     133    noOvertakingLabel.setIcon(new ImageProvider("signs/no_overtaking.png")
     134        .get());
     135    noOvertakingPanel.add(noOvertakingLabel);
     136    noOvertakingPanel.add(noOvertaking);
     137    this.add(noOvertakingPanel);
    138138
    139         // Pedestrian crossing
    140         JPanel crossingPanel = new JPanel();
    141         JLabel crossingLabel = new JLabel(tr("Pedestrian crossing"));
    142         crossingLabel.setIcon(new ImageProvider("signs/crossing.png").get());
    143         crossingPanel.add(crossingLabel);
    144         crossingPanel.add(crossing);
    145         this.add(crossingPanel);
     139    // Pedestrian crossing
     140    JPanel crossingPanel = new JPanel();
     141    JLabel crossingLabel = new JLabel(tr("Pedestrian crossing"));
     142    crossingLabel.setIcon(new ImageProvider("signs/crossing.png").get());
     143    crossingPanel.add(crossingLabel);
     144    crossingPanel.add(crossing);
     145    this.add(crossingPanel);
    146146
    147         this.setPreferredSize(new Dimension(600, 150));
    148     }
     147    this.setPreferredSize(new Dimension(600, 150));
     148  }
    149149
    150     public static MapillaryFilterChooseSigns getInstance() {
    151         if (INSTANCE == null)
    152             INSTANCE = new MapillaryFilterChooseSigns();
    153         return INSTANCE;
    154     }
     150  public static MapillaryFilterChooseSigns getInstance() {
     151    if (INSTANCE == null)
     152      INSTANCE = new MapillaryFilterChooseSigns();
     153    return INSTANCE;
     154  }
    155155
    156     @Override
    157     public void actionPerformed(ActionEvent arg0) {
    158         // TODO Auto-generated method stub
     156  @Override
     157  public void actionPerformed(ActionEvent arg0) {
     158    // TODO Auto-generated method stub
    159159
    160     }
     160  }
    161161
    162162}
  • applications/editors/josm/plugins/mapillary/src/org/openstreetmap/josm/plugins/mapillary/gui/MapillaryFilterDialog.java

    r31334 r31350  
    3838 */
    3939public class MapillaryFilterDialog extends ToggleDialog implements
    40         MapillaryDataListener {
    41 
    42     public static MapillaryFilterDialog INSTANCE;
    43 
    44     private final static String[] TIME_LIST = { tr("All time"),
    45             tr("This year"), tr("This month"), tr("This week") };
    46 
    47     private final static int ROWS = 0;
    48     private final static int COLUMNS = 3;
    49 
    50     private final JPanel panel = new JPanel(new GridLayout(ROWS, COLUMNS));
    51 
    52     public final JCheckBox imported = new JCheckBox("Imported images");
    53     public final JCheckBox downloaded = new JCheckBox(
    54             new downloadCheckBoxAction());
    55     public final JCheckBox onlySigns = new JCheckBox(new OnlySignsAction());
    56     public final JComboBox<String> time;
    57     public final JTextField user;
    58 
    59     public final SideButton updateButton = new SideButton(new UpdateAction());
    60     public final SideButton resetButton = new SideButton(new ResetAction());
    61     public final JButton signChooser = new JButton(new SignChooserAction());
    62 
    63     public final MapillaryFilterChooseSigns signFilter = MapillaryFilterChooseSigns
    64             .getInstance();
    65 
    66     /** The list of sign names */
    67     private final String[] SIGN_TAGS = { "prohibitory_speed_limit",
    68             "priority_stop", "other_give_way", "mandatory_roundabout",
    69             "other_no_entry", "prohibitory_no_traffic_both_ways",
    70             "danger_intersection", "mandatory_go", "mandatory_keep",
    71             "danger_priority_next_intersection", "danger_uneven_road",
    72             "prohibitory_no_parking", "prohibitory_on_overtaking",
    73             "danger_pedestrian_crossing", "prohibitory_no_u_turn",
    74             "prohibitory_noturn" };
    75     /** The the {@link JCheckBox} where the respective tag should be searched */
    76     private final JCheckBox[] SIGN_CHECKBOXES = { signFilter.maxspeed,
    77             signFilter.stop, signFilter.giveWay, signFilter.roundabout,
    78             signFilter.access, signFilter.access, signFilter.intersection,
    79             signFilter.direction, signFilter.direction,
    80             signFilter.intersection, signFilter.uneven, signFilter.noParking,
    81             signFilter.noOvertaking, signFilter.crossing, signFilter.noTurn,
    82             signFilter.noTurn };
    83 
    84     public MapillaryFilterDialog() {
    85         super(tr("Mapillary filter"), "mapillaryfilter.png",
    86                 tr("Open Mapillary filter dialog"), Shortcut.registerShortcut(
    87                         tr("Mapillary filter"),
    88                         tr("Open Mapillary filter dialog"), KeyEvent.VK_M,
    89                         Shortcut.NONE), 200);
    90 
    91         signChooser.setEnabled(false);
    92         JPanel signChooserPanel = new JPanel();
    93         signChooserPanel.setLayout(new FlowLayout(FlowLayout.LEFT));
    94         signChooserPanel.add(signChooser);
    95 
    96         JPanel fromPanel = new JPanel();
    97         fromPanel.setLayout(new FlowLayout(FlowLayout.LEFT));
    98         fromPanel.add(new JLabel("From"));
    99         time = new JComboBox<>(TIME_LIST);
    100         fromPanel.add(time);
    101 
    102         JPanel userSearchPanel = new JPanel();
    103         userSearchPanel.setLayout(new FlowLayout(FlowLayout.LEFT));
    104         user = new JTextField(10);
    105         user.addActionListener(new UpdateAction());
    106         userSearchPanel.add(new JLabel("User"));
    107         userSearchPanel.add(user);
    108 
    109         imported.setSelected(true);
    110         downloaded.setSelected(true);
    111 
    112         panel.add(downloaded);
    113         panel.add(imported);
    114         panel.add(onlySigns);
    115         panel.add(fromPanel);
    116         panel.add(userSearchPanel);
    117         panel.add(signChooserPanel);
    118 
    119         createLayout(panel, true,
    120                 Arrays.asList(new SideButton[] { updateButton, resetButton }));
    121     }
    122 
    123     public static MapillaryFilterDialog getInstance() {
    124         if (INSTANCE == null)
    125             INSTANCE = new MapillaryFilterDialog();
    126         return INSTANCE;
    127     }
    128 
    129     @Override
    130     public void imagesAdded() {
    131         refresh();
    132     }
    133 
    134     @Override
    135     public void selectedImageChanged(MapillaryAbstractImage oldImage,
    136             MapillaryAbstractImage newImage) {
    137     }
    138 
    139     /**
    140      * Resets the dialog to its default state.
    141      */
    142     public void reset() {
    143         imported.setSelected(true);
    144         downloaded.setSelected(true);
    145         onlySigns.setEnabled(true);
    146         onlySigns.setSelected(false);
    147         user.setText("");
    148         time.setSelectedItem(TIME_LIST[0]);
    149         refresh();
    150     }
    151 
    152     /**
    153      * Applies the selected filter.
    154      */
    155     public synchronized void refresh() {
    156         boolean imported = this.imported.isSelected();
    157         boolean downloaded = this.downloaded.isSelected();
    158         boolean onlySigns = this.onlySigns.isSelected();
    159 
    160         for (MapillaryAbstractImage img : MapillaryData.getInstance()
    161                 .getImages()) {
    162             img.setVisible(true);
    163             if (img instanceof MapillaryImportedImage) {
    164                 if (!imported)
    165                     img.setVisible(false);
    166                 continue;
    167             } else if (img instanceof MapillaryImage) {
    168                 if (!downloaded) {
    169                     img.setVisible(false);
    170                     continue;
    171                 }
    172                 if (onlySigns) {
    173                     if (((MapillaryImage) img).getSigns().isEmpty()) {
    174                         img.setVisible(false);
    175                         continue;
    176                     }
    177                     if (!checkSigns((MapillaryImage) img)) {
    178                         img.setVisible(false);
    179                         continue;
    180                     }
    181                 }
    182                 if (!user.getText().equals("")
    183                         && !user.getText().equals(
    184                                 ((MapillaryImage) img).getUser())) {
    185                     img.setVisible(false);
    186                     continue;
    187                 }
    188             }
    189             // Calculates the amount of days since the image was taken
    190             Long currentTime = currentTime();
    191             if (time.getSelectedItem() == TIME_LIST[1]) {
    192                 if ((currentTime - img.getCapturedAt()) / (24 * 60 * 60 * 1000) > 365) {
    193                     img.setVisible(false);
    194                     continue;
    195                 }
    196             }
    197             if (time.getSelectedItem() == TIME_LIST[2]) {
    198                 if ((currentTime - img.getCapturedAt()) / (24 * 60 * 60 * 1000) > 30) {
    199                     img.setVisible(false);
    200                     continue;
    201                 }
    202             }
    203             if (time.getSelectedItem() == TIME_LIST[3]) {
    204                 if ((currentTime - img.getCapturedAt()) / (24 * 60 * 60 * 1000) > 7) {
    205                     img.setVisible(false);
    206                     continue;
    207                 }
    208             }
    209         }
    210         Main.map.repaint();
    211     }
    212 
    213     /**
    214      * Checks if the image fulfills the sign conditions.
    215      *
    216      * @param img
    217      *            The {@link MapillaryAbstractImage} object that is going to be
    218      *            checked.
    219      * @return {@code true} if it fulfills the conditions; {@code false}
    220      *         otherwise.
    221      */
    222     private boolean checkSigns(MapillaryImage img) {
    223         for (int i = 0; i < SIGN_TAGS.length; i++) {
    224             if (checkSign(img, SIGN_CHECKBOXES[i], SIGN_TAGS[i]))
    225                 return true;
    226         }
    227         return false;
    228     }
    229 
    230     private boolean checkSign(MapillaryImage img, JCheckBox signCheckBox,
    231             String singString) {
    232         boolean contains = false;
    233         for (String sign : img.getSigns()) {
    234             if (sign.contains(singString))
    235                 contains = true;
    236         }
    237         if (contains == signCheckBox.isSelected() && contains)
    238             return true;
    239         return false;
    240     }
    241 
    242     private long currentTime() {
    243         Calendar cal = Calendar.getInstance();
    244         return cal.getTimeInMillis();
    245     }
    246 
    247     private class downloadCheckBoxAction extends AbstractAction {
    248 
    249         public downloadCheckBoxAction() {
    250             putValue(NAME, tr("Downloaded images"));
    251         }
    252 
    253         @Override
    254         public void actionPerformed(ActionEvent arg0) {
    255             onlySigns.setEnabled(downloaded.isSelected());
    256         }
    257     }
    258 
    259     private class UpdateAction extends AbstractAction {
    260         public UpdateAction() {
    261             putValue(NAME, tr("Update"));
    262         }
    263 
    264         @Override
    265         public void actionPerformed(ActionEvent arg0) {
    266             MapillaryFilterDialog.getInstance().refresh();
    267         }
    268     }
    269 
    270     private class ResetAction extends AbstractAction {
    271         public ResetAction() {
    272             putValue(NAME, tr("Reset"));
    273         }
    274 
    275         @Override
    276         public void actionPerformed(ActionEvent arg0) {
    277             MapillaryFilterDialog.getInstance().reset();
    278         }
    279     }
    280 
    281     private class OnlySignsAction extends AbstractAction {
    282         public OnlySignsAction() {
    283             putValue(NAME, tr("Only images with signs"));
    284         }
    285 
    286         @Override
    287         public void actionPerformed(ActionEvent arg0) {
    288             signChooser.setEnabled(onlySigns.isSelected());
    289         }
    290     }
    291 
    292     /**
    293      * Opens a new window where you can specifically filter signs.
    294      *
    295      * @author nokutu
    296      *
    297      */
    298     private class SignChooserAction extends AbstractAction {
    299         public SignChooserAction() {
    300             putValue(NAME, tr("Choose signs"));
    301         }
    302 
    303         @Override
    304         public void actionPerformed(ActionEvent arg0) {
    305             JPanel dialog = MapillaryFilterChooseSigns.getInstance();
    306             JOptionPane pane = new JOptionPane(dialog,
    307                     JOptionPane.PLAIN_MESSAGE, JOptionPane.OK_CANCEL_OPTION);
    308             JDialog dlg = pane.createDialog(Main.parent, tr("Choose signs"));
    309             dlg.setVisible(true);
    310             if ((int) pane.getValue() == JOptionPane.OK_OPTION)
    311                 MapillaryFilterDialog.getInstance().refresh();
    312             dlg.dispose();
    313         }
    314     }
    315 
    316     public static void destroyInstance() {
    317         MapillaryFilterDialog.INSTANCE = null;
    318     }
     40    MapillaryDataListener {
     41
     42  public static MapillaryFilterDialog INSTANCE;
     43
     44  private final static String[] TIME_LIST = { tr("All time"), tr("This year"),
     45      tr("This month"), tr("This week") };
     46
     47  private final static int ROWS = 0;
     48  private final static int COLUMNS = 3;
     49
     50  private final JPanel panel = new JPanel(new GridLayout(ROWS, COLUMNS));
     51
     52  public final JCheckBox imported = new JCheckBox("Imported images");
     53  public final JCheckBox downloaded = new JCheckBox(
     54      new downloadCheckBoxAction());
     55  public final JCheckBox onlySigns = new JCheckBox(new OnlySignsAction());
     56  public final JComboBox<String> time;
     57  public final JTextField user;
     58
     59  public final SideButton updateButton = new SideButton(new UpdateAction());
     60  public final SideButton resetButton = new SideButton(new ResetAction());
     61  public final JButton signChooser = new JButton(new SignChooserAction());
     62
     63  public final MapillaryFilterChooseSigns signFilter = MapillaryFilterChooseSigns
     64      .getInstance();
     65
     66  /** The list of sign names */
     67  private final String[] SIGN_TAGS = { "prohibitory_speed_limit",
     68      "priority_stop", "other_give_way", "mandatory_roundabout",
     69      "other_no_entry", "prohibitory_no_traffic_both_ways",
     70      "danger_intersection", "mandatory_go", "mandatory_keep",
     71      "danger_priority_next_intersection", "danger_uneven_road",
     72      "prohibitory_no_parking", "prohibitory_on_overtaking",
     73      "danger_pedestrian_crossing", "prohibitory_no_u_turn",
     74      "prohibitory_noturn" };
     75  /** The the {@link JCheckBox} where the respective tag should be searched */
     76  private final JCheckBox[] SIGN_CHECKBOXES = { signFilter.maxspeed,
     77      signFilter.stop, signFilter.giveWay, signFilter.roundabout,
     78      signFilter.access, signFilter.access, signFilter.intersection,
     79      signFilter.direction, signFilter.direction, signFilter.intersection,
     80      signFilter.uneven, signFilter.noParking, signFilter.noOvertaking,
     81      signFilter.crossing, signFilter.noTurn, signFilter.noTurn };
     82
     83  public MapillaryFilterDialog() {
     84    super(tr("Mapillary filter"), "mapillaryfilter.png",
     85        tr("Open Mapillary filter dialog"), Shortcut.registerShortcut(
     86            tr("Mapillary filter"), tr("Open Mapillary filter dialog"),
     87            KeyEvent.VK_M, Shortcut.NONE), 200);
     88
     89    signChooser.setEnabled(false);
     90    JPanel signChooserPanel = new JPanel();
     91    signChooserPanel.setLayout(new FlowLayout(FlowLayout.LEFT));
     92    signChooserPanel.add(signChooser);
     93
     94    JPanel fromPanel = new JPanel();
     95    fromPanel.setLayout(new FlowLayout(FlowLayout.LEFT));
     96    fromPanel.add(new JLabel("From"));
     97    time = new JComboBox<>(TIME_LIST);
     98    fromPanel.add(time);
     99
     100    JPanel userSearchPanel = new JPanel();
     101    userSearchPanel.setLayout(new FlowLayout(FlowLayout.LEFT));
     102    user = new JTextField(10);
     103    user.addActionListener(new UpdateAction());
     104    userSearchPanel.add(new JLabel("User"));
     105    userSearchPanel.add(user);
     106
     107    imported.setSelected(true);
     108    downloaded.setSelected(true);
     109
     110    panel.add(downloaded);
     111    panel.add(imported);
     112    panel.add(onlySigns);
     113    panel.add(fromPanel);
     114    panel.add(userSearchPanel);
     115    panel.add(signChooserPanel);
     116
     117    createLayout(panel, true,
     118        Arrays.asList(new SideButton[] { updateButton, resetButton }));
     119  }
     120
     121  public static MapillaryFilterDialog getInstance() {
     122    if (INSTANCE == null)
     123      INSTANCE = new MapillaryFilterDialog();
     124    return INSTANCE;
     125  }
     126
     127  @Override
     128  public void imagesAdded() {
     129    refresh();
     130  }
     131
     132  @Override
     133  public void selectedImageChanged(MapillaryAbstractImage oldImage,
     134      MapillaryAbstractImage newImage) {
     135  }
     136
     137  /**
     138   * Resets the dialog to its default state.
     139   */
     140  public void reset() {
     141    imported.setSelected(true);
     142    downloaded.setSelected(true);
     143    onlySigns.setEnabled(true);
     144    onlySigns.setSelected(false);
     145    user.setText("");
     146    time.setSelectedItem(TIME_LIST[0]);
     147    refresh();
     148  }
     149
     150  /**
     151   * Applies the selected filter.
     152   */
     153  public synchronized void refresh() {
     154    boolean imported = this.imported.isSelected();
     155    boolean downloaded = this.downloaded.isSelected();
     156    boolean onlySigns = this.onlySigns.isSelected();
     157
     158    for (MapillaryAbstractImage img : MapillaryData.getInstance().getImages()) {
     159      img.setVisible(true);
     160      if (img instanceof MapillaryImportedImage) {
     161        if (!imported)
     162          img.setVisible(false);
     163        continue;
     164      } else if (img instanceof MapillaryImage) {
     165        if (!downloaded) {
     166          img.setVisible(false);
     167          continue;
     168        }
     169        if (onlySigns) {
     170          if (((MapillaryImage) img).getSigns().isEmpty()) {
     171            img.setVisible(false);
     172            continue;
     173          }
     174          if (!checkSigns((MapillaryImage) img)) {
     175            img.setVisible(false);
     176            continue;
     177          }
     178        }
     179        if (!user.getText().equals("")
     180            && !user.getText().equals(((MapillaryImage) img).getUser())) {
     181          img.setVisible(false);
     182          continue;
     183        }
     184      }
     185      // Calculates the amount of days since the image was taken
     186      Long currentTime = currentTime();
     187      if (time.getSelectedItem() == TIME_LIST[1]) {
     188        if ((currentTime - img.getCapturedAt()) / (24 * 60 * 60 * 1000) > 365) {
     189          img.setVisible(false);
     190          continue;
     191        }
     192      }
     193      if (time.getSelectedItem() == TIME_LIST[2]) {
     194        if ((currentTime - img.getCapturedAt()) / (24 * 60 * 60 * 1000) > 30) {
     195          img.setVisible(false);
     196          continue;
     197        }
     198      }
     199      if (time.getSelectedItem() == TIME_LIST[3]) {
     200        if ((currentTime - img.getCapturedAt()) / (24 * 60 * 60 * 1000) > 7) {
     201          img.setVisible(false);
     202          continue;
     203        }
     204      }
     205    }
     206    Main.map.repaint();
     207  }
     208
     209  /**
     210   * Checks if the image fulfills the sign conditions.
     211   *
     212   * @param img
     213   *          The {@link MapillaryAbstractImage} object that is going to be
     214   *          checked.
     215   * @return {@code true} if it fulfills the conditions; {@code false}
     216   *         otherwise.
     217   */
     218  private boolean checkSigns(MapillaryImage img) {
     219    for (int i = 0; i < SIGN_TAGS.length; i++) {
     220      if (checkSign(img, SIGN_CHECKBOXES[i], SIGN_TAGS[i]))
     221        return true;
     222    }
     223    return false;
     224  }
     225
     226  private boolean checkSign(MapillaryImage img, JCheckBox signCheckBox,
     227      String singString) {
     228    boolean contains = false;
     229    for (String sign : img.getSigns()) {
     230      if (sign.contains(singString))
     231        contains = true;
     232    }
     233    if (contains == signCheckBox.isSelected() && contains)
     234      return true;
     235    return false;
     236  }
     237
     238  private long currentTime() {
     239    Calendar cal = Calendar.getInstance();
     240    return cal.getTimeInMillis();
     241  }
     242
     243  private class downloadCheckBoxAction extends AbstractAction {
     244
     245    public downloadCheckBoxAction() {
     246      putValue(NAME, tr("Downloaded images"));
     247    }
     248
     249    @Override
     250    public void actionPerformed(ActionEvent arg0) {
     251      onlySigns.setEnabled(downloaded.isSelected());
     252    }
     253  }
     254
     255  private class UpdateAction extends AbstractAction {
     256    public UpdateAction() {
     257      putValue(NAME, tr("Update"));
     258    }
     259
     260    @Override
     261    public void actionPerformed(ActionEvent arg0) {
     262      MapillaryFilterDialog.getInstance().refresh();
     263    }
     264  }
     265
     266  private class ResetAction extends AbstractAction {
     267    public ResetAction() {
     268      putValue(NAME, tr("Reset"));
     269    }
     270
     271    @Override
     272    public void actionPerformed(ActionEvent arg0) {
     273      MapillaryFilterDialog.getInstance().reset();
     274    }
     275  }
     276
     277  private class OnlySignsAction extends AbstractAction {
     278    public OnlySignsAction() {
     279      putValue(NAME, tr("Only images with signs"));
     280    }
     281
     282    @Override
     283    public void actionPerformed(ActionEvent arg0) {
     284      signChooser.setEnabled(onlySigns.isSelected());
     285    }
     286  }
     287
     288  /**
     289   * Opens a new window where you can specifically filter signs.
     290   *
     291   * @author nokutu
     292   *
     293   */
     294  private class SignChooserAction extends AbstractAction {
     295    public SignChooserAction() {
     296      putValue(NAME, tr("Choose signs"));
     297    }
     298
     299    @Override
     300    public void actionPerformed(ActionEvent arg0) {
     301      JPanel dialog = MapillaryFilterChooseSigns.getInstance();
     302      JOptionPane pane = new JOptionPane(dialog, JOptionPane.PLAIN_MESSAGE,
     303          JOptionPane.OK_CANCEL_OPTION);
     304      JDialog dlg = pane.createDialog(Main.parent, tr("Choose signs"));
     305      dlg.setVisible(true);
     306      if ((int) pane.getValue() == JOptionPane.OK_OPTION)
     307        MapillaryFilterDialog.getInstance().refresh();
     308      dlg.dispose();
     309    }
     310  }
     311
     312  public static void destroyInstance() {
     313    MapillaryFilterDialog.INSTANCE = null;
     314  }
    319315}
  • applications/editors/josm/plugins/mapillary/src/org/openstreetmap/josm/plugins/mapillary/gui/MapillaryHistoryDialog.java

    r31334 r31350  
    3131
    3232/**
    33  * Toggle dialog that shows you the latest {@link MapillaryCommand} done and allows the user to
    34  * revert them.
     33 * Toggle dialog that shows you the latest {@link MapillaryCommand} done and
     34 * allows the user to revert them.
    3535 *
    3636 * @see MapillaryRecord
     
    4040 */
    4141public class MapillaryHistoryDialog extends ToggleDialog implements
    42         MapillaryRecordListener {
     42    MapillaryRecordListener {
    4343
    44     public static MapillaryHistoryDialog INSTANCE;
     44  public static MapillaryHistoryDialog INSTANCE;
    4545
    46     private final DefaultTreeModel undoTreeModel = new DefaultTreeModel(
    47             new DefaultMutableTreeNode());
    48     private final DefaultTreeModel redoTreeModel = new DefaultTreeModel(
    49             new DefaultMutableTreeNode());
    50     private final JTree undoTree = new JTree(undoTreeModel);
    51     private final JTree redoTree = new JTree(redoTreeModel);
     46  private final DefaultTreeModel undoTreeModel = new DefaultTreeModel(
     47      new DefaultMutableTreeNode());
     48  private final DefaultTreeModel redoTreeModel = new DefaultTreeModel(
     49      new DefaultMutableTreeNode());
     50  private final JTree undoTree = new JTree(undoTreeModel);
     51  private final JTree redoTree = new JTree(redoTreeModel);
    5252
    53     private JSeparator separator = new JSeparator();
    54     private Component spacer = Box.createRigidArea(new Dimension(0, 3));
     53  private JSeparator separator = new JSeparator();
     54  private Component spacer = Box.createRigidArea(new Dimension(0, 3));
    5555
    56     private SideButton undoButton;
    57     private SideButton redoButton;
     56  private SideButton undoButton;
     57  private SideButton redoButton;
    5858
    59     public MapillaryHistoryDialog() {
    60         super(tr("Mapillary history"), "mapillaryhistory.png",
    61                 tr("Open Mapillary history dialog"), Shortcut.registerShortcut(
    62                         tr("Mapillary history"),
    63                         tr("Open Mapillary history dialog"), KeyEvent.VK_M,
    64                         Shortcut.NONE), 200);
     59  public MapillaryHistoryDialog() {
     60    super(tr("Mapillary history"), "mapillaryhistory.png",
     61        tr("Open Mapillary history dialog"), Shortcut.registerShortcut(
     62            tr("Mapillary history"), tr("Open Mapillary history dialog"),
     63            KeyEvent.VK_M, Shortcut.NONE), 200);
    6564
    66         MapillaryRecord.getInstance().addListener(this);
     65    MapillaryRecord.getInstance().addListener(this);
    6766
    68         undoTree.expandRow(0);
    69         undoTree.setShowsRootHandles(true);
    70         undoTree.setRootVisible(false);
    71         undoTree.setCellRenderer(new MapillaryCellRenderer());
    72         redoTree.expandRow(0);
    73         redoTree.setCellRenderer(new MapillaryCellRenderer());
    74         redoTree.setShowsRootHandles(true);
    75         redoTree.setRootVisible(false);
     67    undoTree.expandRow(0);
     68    undoTree.setShowsRootHandles(true);
     69    undoTree.setRootVisible(false);
     70    undoTree.setCellRenderer(new MapillaryCellRenderer());
     71    redoTree.expandRow(0);
     72    redoTree.setCellRenderer(new MapillaryCellRenderer());
     73    redoTree.setShowsRootHandles(true);
     74    redoTree.setRootVisible(false);
    7675
    77         JPanel treesPanel = new JPanel(new GridBagLayout());
    78         treesPanel.add(spacer, GBC.eol());
    79         spacer.setVisible(false);
    80         treesPanel.add(undoTree, GBC.eol().fill(GBC.HORIZONTAL));
    81         separator.setVisible(false);
    82         treesPanel.add(separator, GBC.eol().fill(GBC.HORIZONTAL));
    83         treesPanel.add(redoTree, GBC.eol().fill(GBC.HORIZONTAL));
    84         treesPanel.add(Box.createRigidArea(new Dimension(0, 0)), GBC.std()
    85                 .weight(0, 1));
    86         treesPanel.setBackground(redoTree.getBackground());
     76    JPanel treesPanel = new JPanel(new GridBagLayout());
     77    treesPanel.add(spacer, GBC.eol());
     78    spacer.setVisible(false);
     79    treesPanel.add(undoTree, GBC.eol().fill(GBC.HORIZONTAL));
     80    separator.setVisible(false);
     81    treesPanel.add(separator, GBC.eol().fill(GBC.HORIZONTAL));
     82    treesPanel.add(redoTree, GBC.eol().fill(GBC.HORIZONTAL));
     83    treesPanel.add(Box.createRigidArea(new Dimension(0, 0)),
     84        GBC.std().weight(0, 1));
     85    treesPanel.setBackground(redoTree.getBackground());
    8786
    88         undoButton = new SideButton(new UndoAction());
    89         redoButton = new SideButton(new RedoAction());
     87    undoButton = new SideButton(new UndoAction());
     88    redoButton = new SideButton(new RedoAction());
    9089
    91         createLayout(treesPanel, true,
    92                 Arrays.asList(new SideButton[] { undoButton, redoButton }));
     90    createLayout(treesPanel, true,
     91        Arrays.asList(new SideButton[] { undoButton, redoButton }));
     92  }
     93
     94  public static MapillaryHistoryDialog getInstance() {
     95    if (INSTANCE == null)
     96      INSTANCE = new MapillaryHistoryDialog();
     97    return INSTANCE;
     98  }
     99
     100  private void buildTree() {
     101    redoButton.setEnabled(true);
     102    undoButton.setEnabled(true);
     103    ArrayList<MapillaryCommand> commands = MapillaryRecord.getInstance().commandList;
     104    int position = MapillaryRecord.getInstance().position;
     105    ArrayList<MapillaryCommand> undoCommands = new ArrayList<>();
     106    if (position >= 0)
     107      undoCommands = new ArrayList<>(commands.subList(0, position + 1));
     108    else
     109      undoButton.setEnabled(false);
     110    ArrayList<MapillaryCommand> redoCommands = new ArrayList<>();
     111    if (commands.size() > 0 && position + 1 < commands.size())
     112      redoCommands = new ArrayList<>(commands.subList(position + 1,
     113          commands.size()));
     114    else
     115      redoButton.setEnabled(false);
     116
     117    DefaultMutableTreeNode redoRoot = new DefaultMutableTreeNode();
     118    DefaultMutableTreeNode undoRoot = new DefaultMutableTreeNode();
     119
     120    for (MapillaryCommand command : undoCommands) {
     121      if (command != null)
     122        undoRoot.add(new DefaultMutableTreeNode(command.toString()));
     123    }
     124    for (MapillaryCommand command : redoCommands) {
     125      if (command != null)
     126        redoRoot.add(new DefaultMutableTreeNode(command.toString()));
    93127    }
    94128
    95     public static MapillaryHistoryDialog getInstance() {
    96         if (INSTANCE == null)
    97             INSTANCE = new MapillaryHistoryDialog();
    98         return INSTANCE;
    99     }
     129    separator.setVisible(!undoCommands.isEmpty() || !redoCommands.isEmpty());
     130    spacer.setVisible(undoCommands.isEmpty() && !redoCommands.isEmpty());
    100131
    101     private void buildTree() {
    102         redoButton.setEnabled(true);
    103         undoButton.setEnabled(true);
    104         ArrayList<MapillaryCommand> commands = MapillaryRecord.getInstance().commandList;
    105         int position = MapillaryRecord.getInstance().position;
    106         ArrayList<MapillaryCommand> undoCommands = new ArrayList<>();
    107         if (position >= 0)
    108             undoCommands = new ArrayList<>(commands.subList(0, position + 1));
    109         else
    110             undoButton.setEnabled(false);
    111         ArrayList<MapillaryCommand> redoCommands = new ArrayList<>();
    112         if (commands.size() > 0 && position + 1 < commands.size())
    113             redoCommands = new ArrayList<>(commands.subList(position + 1,
    114                     commands.size()));
    115         else
    116             redoButton.setEnabled(false);
     132    undoTreeModel.setRoot(undoRoot);
     133    redoTreeModel.setRoot(redoRoot);
     134  }
    117135
    118         DefaultMutableTreeNode redoRoot = new DefaultMutableTreeNode();
    119         DefaultMutableTreeNode undoRoot = new DefaultMutableTreeNode();
     136  @Override
     137  public void recordChanged() {
     138    buildTree();
     139  }
    120140
    121         for (MapillaryCommand command : undoCommands) {
    122             if (command != null)
    123                 undoRoot.add(new DefaultMutableTreeNode(command.toString()));
    124         }
    125         for (MapillaryCommand command : redoCommands) {
    126             if (command != null)
    127                 redoRoot.add(new DefaultMutableTreeNode(command.toString()));
    128         }
     141  private class UndoAction extends AbstractAction {
    129142
    130         separator
    131                 .setVisible(!undoCommands.isEmpty() || !redoCommands.isEmpty());
    132         spacer.setVisible(undoCommands.isEmpty() && !redoCommands.isEmpty());
    133 
    134         undoTreeModel.setRoot(undoRoot);
    135         redoTreeModel.setRoot(redoRoot);
     143    public UndoAction() {
     144      putValue(NAME, tr("Undo"));
     145      putValue(SMALL_ICON, ImageProvider.get("undo"));
    136146    }
    137147
    138148    @Override
    139     public void recordChanged() {
    140         buildTree();
     149    public void actionPerformed(ActionEvent arg0) {
     150      MapillaryRecord.getInstance().undo();
    141151    }
    142152
    143     private class UndoAction extends AbstractAction {
     153  }
    144154
    145         public UndoAction() {
    146             putValue(NAME, tr("Undo"));
    147             putValue(SMALL_ICON, ImageProvider.get("undo"));
    148         }
    149 
    150         @Override
    151         public void actionPerformed(ActionEvent arg0) {
    152             MapillaryRecord.getInstance().undo();
    153         }
    154 
     155  private class RedoAction extends AbstractAction {
     156    public RedoAction() {
     157      putValue(NAME, tr("Redo"));
     158      putValue(SMALL_ICON, ImageProvider.get("redo"));
    155159    }
    156160
    157     private class RedoAction extends AbstractAction {
    158         public RedoAction() {
    159             putValue(NAME, tr("Redo"));
    160             putValue(SMALL_ICON, ImageProvider.get("redo"));
    161         }
    162 
    163         @Override
    164         public void actionPerformed(ActionEvent arg0) {
    165             MapillaryRecord.getInstance().redo();
    166         }
    167 
     161    @Override
     162    public void actionPerformed(ActionEvent arg0) {
     163      MapillaryRecord.getInstance().redo();
    168164    }
    169165
    170     private static class MapillaryCellRenderer extends DefaultTreeCellRenderer {
    171         @Override
    172         public Component getTreeCellRendererComponent(JTree tree, Object value,
    173                 boolean sel, boolean expanded, boolean leaf, int row,
    174                 boolean hasFocus) {
    175             super.getTreeCellRendererComponent(tree, value, sel, expanded,
    176                     leaf, row, hasFocus);
    177             setIcon(ImageProvider.get("data/node.png"));
    178             return this;
    179         }
     166  }
     167
     168  private static class MapillaryCellRenderer extends DefaultTreeCellRenderer {
     169    @Override
     170    public Component getTreeCellRendererComponent(JTree tree, Object value,
     171        boolean sel, boolean expanded, boolean leaf, int row, boolean hasFocus) {
     172      super.getTreeCellRendererComponent(tree, value, sel, expanded, leaf, row,
     173          hasFocus);
     174      setIcon(ImageProvider.get("data/node.png"));
     175      return this;
    180176    }
     177  }
    181178
    182     public static void destroyInstance() {
    183         MapillaryHistoryDialog.INSTANCE = null;
    184     }
     179  public static void destroyInstance() {
     180    MapillaryHistoryDialog.INSTANCE = null;
     181  }
    185182}
  • applications/editors/josm/plugins/mapillary/src/org/openstreetmap/josm/plugins/mapillary/gui/MapillaryImageDisplay.java

    r31334 r31350  
    3333public class MapillaryImageDisplay extends JComponent {
    3434
    35     private static final int DRAG_BUTTON = Main.pref.getInteger(
    36             "mapillary.picture-drag-button", 3);
    37     private static final int OPTION_BUTTON = Main.pref.getInteger(
    38             "mapillary.picture-option-button", 2);
    39     private static final int ZOOM_BUTTON = Main.pref.getInteger(
    40             "mapillary.picture-zoom-button", 1);
    41 
    42     /** The image currently displayed */
    43     private transient BufferedImage image = null;
     35  private static final int DRAG_BUTTON = Main.pref.getInteger(
     36      "mapillary.picture-drag-button", 3);
     37  private static final int OPTION_BUTTON = Main.pref.getInteger(
     38      "mapillary.picture-option-button", 2);
     39  private static final int ZOOM_BUTTON = Main.pref.getInteger(
     40      "mapillary.picture-zoom-button", 1);
     41
     42  /** The image currently displayed */
     43  private transient BufferedImage image = null;
     44
     45  /**
     46   * The rectangle (in image coordinates) of the image that is visible. This
     47   * rectangle is calculated each time the zoom is modified
     48   */
     49  private Rectangle visibleRect = null;
     50
     51  /**
     52   * When a selection is done, the rectangle of the selection (in image
     53   * coordinates)
     54   */
     55  private Rectangle selectedRect = null;
     56
     57  public HyperlinkLabel hyperlink;
     58
     59  private class ImgDisplayMouseListener implements MouseListener,
     60      MouseWheelListener, MouseMotionListener {
     61    private boolean mouseIsDragging = false;
     62    private long lastTimeForMousePoint = 0L;
     63    private Point mousePointInImg = null;
    4464
    4565    /**
    46      * The rectangle (in image coordinates) of the image that is visible. This
    47      * rectangle is calculated each time the zoom is modified
     66     * Zoom in and out, trying to preserve the point of the image that was under
     67     * the mouse cursor at the same place
    4868     */
    49     private Rectangle visibleRect = null;
     69    @Override
     70    public void mouseWheelMoved(MouseWheelEvent e) {
     71      Image image;
     72      Rectangle visibleRect;
     73      synchronized (MapillaryImageDisplay.this) {
     74        image = MapillaryImageDisplay.this.image;
     75        visibleRect = MapillaryImageDisplay.this.visibleRect;
     76      }
     77      mouseIsDragging = false;
     78      selectedRect = null;
     79      if (image == null)
     80        return;
     81      // Calculate the mouse cursor position in image coordinates, so that
     82      // we can center the zoom
     83      // on that mouse position.
     84      // To avoid issues when the user tries to zoom in on the image
     85      // borders, this point is not calculated
     86      // again if there was less than 1.5seconds since the last event.
     87      if (e.getWhen() - lastTimeForMousePoint > 1500 || mousePointInImg == null) {
     88        lastTimeForMousePoint = e.getWhen();
     89        mousePointInImg = comp2imgCoord(visibleRect, e.getX(), e.getY());
     90      }
     91      // Applicate the zoom to the visible rectangle in image coordinates
     92      if (e.getWheelRotation() > 0) {
     93        visibleRect.width = visibleRect.width * 3 / 2;
     94        visibleRect.height = visibleRect.height * 3 / 2;
     95      } else {
     96        visibleRect.width = visibleRect.width * 2 / 3;
     97        visibleRect.height = visibleRect.height * 2 / 3;
     98      }
     99      // Check that the zoom doesn't exceed 2:1
     100      if (visibleRect.width < getSize().width / 2) {
     101        visibleRect.width = getSize().width / 2;
     102      }
     103      if (visibleRect.height < getSize().height / 2) {
     104        visibleRect.height = getSize().height / 2;
     105      }
     106      // Set the same ratio for the visible rectangle and the display area
     107      int hFact = visibleRect.height * getSize().width;
     108      int wFact = visibleRect.width * getSize().height;
     109      if (hFact > wFact) {
     110        visibleRect.width = hFact / getSize().height;
     111      } else {
     112        visibleRect.height = wFact / getSize().width;
     113      }
     114      // The size of the visible rectangle is limited by the image size.
     115      checkVisibleRectSize(image, visibleRect);
     116      // Set the position of the visible rectangle, so that the mouse
     117      // cursor doesn't move on the image.
     118      Rectangle drawRect = calculateDrawImageRectangle(visibleRect);
     119      visibleRect.x = mousePointInImg.x
     120          + ((drawRect.x - e.getX()) * visibleRect.width) / drawRect.width;
     121      visibleRect.y = mousePointInImg.y
     122          + ((drawRect.y - e.getY()) * visibleRect.height) / drawRect.height;
     123      // The position is also limited by the image size
     124      checkVisibleRectPos(image, visibleRect);
     125      synchronized (MapillaryImageDisplay.this) {
     126        MapillaryImageDisplay.this.visibleRect = visibleRect;
     127      }
     128      MapillaryImageDisplay.this.repaint();
     129    }
     130
     131    /** Center the display on the point that has been clicked */
     132    @Override
     133    public void mouseClicked(MouseEvent e) {
     134      // Move the center to the clicked point.
     135      Image image;
     136      Rectangle visibleRect;
     137      synchronized (MapillaryImageDisplay.this) {
     138        image = MapillaryImageDisplay.this.image;
     139        visibleRect = MapillaryImageDisplay.this.visibleRect;
     140      }
     141      if (image == null)
     142        return;
     143      if (e.getButton() == OPTION_BUTTON) {
     144        if (!MapillaryImageDisplay.this.visibleRect.equals(new Rectangle(0, 0,
     145            image.getWidth(null), image.getHeight(null))))
     146          // Zooms to 1:1
     147          MapillaryImageDisplay.this.visibleRect = new Rectangle(0, 0,
     148              image.getWidth(null), image.getHeight(null));
     149        else
     150          // Zooms to best fit.
     151          MapillaryImageDisplay.this.visibleRect = new Rectangle(0,
     152              (image.getHeight(null) - (image.getWidth(null) * getHeight())
     153                  / getWidth()) / 2, image.getWidth(null),
     154              (image.getWidth(null) * getHeight()) / getWidth());
     155        MapillaryImageDisplay.this.repaint();
     156        return;
     157      } else if (e.getButton() != DRAG_BUTTON)
     158        return;
     159      // Calculate the translation to set the clicked point the center of
     160      // the view.
     161      Point click = comp2imgCoord(visibleRect, e.getX(), e.getY());
     162      Point center = getCenterImgCoord(visibleRect);
     163      visibleRect.x += click.x - center.x;
     164      visibleRect.y += click.y - center.y;
     165      checkVisibleRectPos(image, visibleRect);
     166      synchronized (MapillaryImageDisplay.this) {
     167        MapillaryImageDisplay.this.visibleRect = visibleRect;
     168      }
     169      MapillaryImageDisplay.this.repaint();
     170    }
    50171
    51172    /**
    52      * When a selection is done, the rectangle of the selection (in image
    53      * coordinates)
     173     * Initialize the dragging, either with button 1 (simple dragging) or button
     174     * 3 (selection of a picture part)
    54175     */
    55     private Rectangle selectedRect = null;
    56 
    57     public HyperlinkLabel hyperlink;
    58 
    59     private class ImgDisplayMouseListener implements MouseListener,
    60             MouseWheelListener, MouseMotionListener {
    61         private boolean mouseIsDragging = false;
    62         private long lastTimeForMousePoint = 0L;
    63         private Point mousePointInImg = null;
    64 
    65         /**
    66          * Zoom in and out, trying to preserve the point of the image that was
    67          * under the mouse cursor at the same place
    68          */
    69         @Override
    70         public void mouseWheelMoved(MouseWheelEvent e) {
    71             Image image;
    72             Rectangle visibleRect;
    73             synchronized (MapillaryImageDisplay.this) {
    74                 image = MapillaryImageDisplay.this.image;
    75                 visibleRect = MapillaryImageDisplay.this.visibleRect;
    76             }
    77             mouseIsDragging = false;
    78             selectedRect = null;
    79             if (image == null)
    80                 return;
    81             // Calculate the mouse cursor position in image coordinates, so that
    82             // we can center the zoom
    83             // on that mouse position.
    84             // To avoid issues when the user tries to zoom in on the image
    85             // borders, this point is not calculated
    86             // again if there was less than 1.5seconds since the last event.
    87             if (e.getWhen() - lastTimeForMousePoint > 1500
    88                     || mousePointInImg == null) {
    89                 lastTimeForMousePoint = e.getWhen();
    90                 mousePointInImg = comp2imgCoord(visibleRect, e.getX(), e.getY());
    91             }
    92             // Applicate the zoom to the visible rectangle in image coordinates
    93             if (e.getWheelRotation() > 0) {
    94                 visibleRect.width = visibleRect.width * 3 / 2;
    95                 visibleRect.height = visibleRect.height * 3 / 2;
    96             } else {
    97                 visibleRect.width = visibleRect.width * 2 / 3;
    98                 visibleRect.height = visibleRect.height * 2 / 3;
    99             }
    100             // Check that the zoom doesn't exceed 2:1
    101             if (visibleRect.width < getSize().width / 2) {
    102                 visibleRect.width = getSize().width / 2;
    103             }
    104             if (visibleRect.height < getSize().height / 2) {
    105                 visibleRect.height = getSize().height / 2;
    106             }
    107             // Set the same ratio for the visible rectangle and the display area
    108             int hFact = visibleRect.height * getSize().width;
    109             int wFact = visibleRect.width * getSize().height;
    110             if (hFact > wFact) {
    111                 visibleRect.width = hFact / getSize().height;
    112             } else {
    113                 visibleRect.height = wFact / getSize().width;
    114             }
    115             // The size of the visible rectangle is limited by the image size.
    116             checkVisibleRectSize(image, visibleRect);
    117             // Set the position of the visible rectangle, so that the mouse
    118             // cursor doesn't move on the image.
    119             Rectangle drawRect = calculateDrawImageRectangle(visibleRect);
    120             visibleRect.x = mousePointInImg.x
    121                     + ((drawRect.x - e.getX()) * visibleRect.width)
    122                     / drawRect.width;
    123             visibleRect.y = mousePointInImg.y
    124                     + ((drawRect.y - e.getY()) * visibleRect.height)
    125                     / drawRect.height;
    126             // The position is also limited by the image size
    127             checkVisibleRectPos(image, visibleRect);
    128             synchronized (MapillaryImageDisplay.this) {
    129                 MapillaryImageDisplay.this.visibleRect = visibleRect;
    130             }
    131             MapillaryImageDisplay.this.repaint();
    132         }
    133 
    134         /** Center the display on the point that has been clicked */
    135         @Override
    136         public void mouseClicked(MouseEvent e) {
    137             // Move the center to the clicked point.
    138             Image image;
    139             Rectangle visibleRect;
    140             synchronized (MapillaryImageDisplay.this) {
    141                 image = MapillaryImageDisplay.this.image;
    142                 visibleRect = MapillaryImageDisplay.this.visibleRect;
    143             }
    144             if (image == null)
    145                 return;
    146             if (e.getButton() == OPTION_BUTTON) {
    147                 if (!MapillaryImageDisplay.this.visibleRect
    148                         .equals(new Rectangle(0, 0, image.getWidth(null), image
    149                                 .getHeight(null))))
    150                     // Zooms to 1:1
    151                     MapillaryImageDisplay.this.visibleRect = new Rectangle(0,
    152                             0, image.getWidth(null), image.getHeight(null));
    153                 else
    154                     // Zooms to best fit.
    155                     MapillaryImageDisplay.this.visibleRect = new Rectangle(
    156                             0,
    157                             (image.getHeight(null) - (image.getWidth(null) * getHeight())
    158                                     / getWidth()) / 2, image.getWidth(null),
    159                             (image.getWidth(null) * getHeight()) / getWidth());
    160                 MapillaryImageDisplay.this.repaint();
    161                 return;
    162             } else if (e.getButton() != DRAG_BUTTON)
    163                 return;
    164             // Calculate the translation to set the clicked point the center of
    165             // the view.
    166             Point click = comp2imgCoord(visibleRect, e.getX(), e.getY());
    167             Point center = getCenterImgCoord(visibleRect);
    168             visibleRect.x += click.x - center.x;
    169             visibleRect.y += click.y - center.y;
    170             checkVisibleRectPos(image, visibleRect);
    171             synchronized (MapillaryImageDisplay.this) {
    172                 MapillaryImageDisplay.this.visibleRect = visibleRect;
    173             }
    174             MapillaryImageDisplay.this.repaint();
    175         }
    176 
    177         /**
    178          * Initialize the dragging, either with button 1 (simple dragging) or
    179          * button 3 (selection of a picture part)
    180          */
    181         @Override
    182         public void mousePressed(MouseEvent e) {
    183             if (image == null) {
    184                 mouseIsDragging = false;
    185                 selectedRect = null;
    186                 return;
    187             }
    188             Image image;
    189             Rectangle visibleRect;
    190             synchronized (MapillaryImageDisplay.this) {
    191                 image = MapillaryImageDisplay.this.image;
    192                 visibleRect = MapillaryImageDisplay.this.visibleRect;
    193             }
    194             if (image == null)
    195                 return;
    196             if (e.getButton() == DRAG_BUTTON) {
    197                 mousePointInImg = comp2imgCoord(visibleRect, e.getX(), e.getY());
    198                 mouseIsDragging = true;
    199                 selectedRect = null;
    200             } else if (e.getButton() == ZOOM_BUTTON) {
    201                 mousePointInImg = comp2imgCoord(visibleRect, e.getX(), e.getY());
    202                 checkPointInVisibleRect(mousePointInImg, visibleRect);
    203                 mouseIsDragging = false;
    204                 selectedRect = new Rectangle(mousePointInImg.x,
    205                         mousePointInImg.y, 0, 0);
    206                 MapillaryImageDisplay.this.repaint();
    207             } else {
    208                 mouseIsDragging = false;
    209                 selectedRect = null;
    210             }
    211         }
    212 
    213         @Override
    214         public void mouseDragged(MouseEvent e) {
    215             if (!mouseIsDragging && selectedRect == null)
    216                 return;
    217             Image image;
    218             Rectangle visibleRect;
    219             synchronized (MapillaryImageDisplay.this) {
    220                 image = MapillaryImageDisplay.this.image;
    221                 visibleRect = MapillaryImageDisplay.this.visibleRect;
    222             }
    223             if (image == null) {
    224                 mouseIsDragging = false;
    225                 selectedRect = null;
    226                 return;
    227             }
    228             if (mouseIsDragging) {
    229                 Point p = comp2imgCoord(visibleRect, e.getX(), e.getY());
    230                 visibleRect.x += mousePointInImg.x - p.x;
    231                 visibleRect.y += mousePointInImg.y - p.y;
    232                 checkVisibleRectPos(image, visibleRect);
    233                 synchronized (MapillaryImageDisplay.this) {
    234                     MapillaryImageDisplay.this.visibleRect = visibleRect;
    235                 }
    236                 MapillaryImageDisplay.this.repaint();
    237             } else if (selectedRect != null) {
    238                 Point p = comp2imgCoord(visibleRect, e.getX(), e.getY());
    239                 checkPointInVisibleRect(p, visibleRect);
    240                 Rectangle rect = new Rectangle(p.x < mousePointInImg.x ? p.x
    241                         : mousePointInImg.x, p.y < mousePointInImg.y ? p.y
    242                         : mousePointInImg.y,
    243                         p.x < mousePointInImg.x ? mousePointInImg.x - p.x : p.x
    244                                 - mousePointInImg.x,
    245                         p.y < mousePointInImg.y ? mousePointInImg.y - p.y : p.y
    246                                 - mousePointInImg.y);
    247                 checkVisibleRectSize(image, rect);
    248                 checkVisibleRectPos(image, rect);
    249                 MapillaryImageDisplay.this.selectedRect = rect;
    250                 MapillaryImageDisplay.this.repaint();
    251             }
    252         }
    253 
    254         @Override
    255         public void mouseReleased(MouseEvent e) {
    256             if (!mouseIsDragging && selectedRect == null)
    257                 return;
    258             Image image;
    259             synchronized (MapillaryImageDisplay.this) {
    260                 image = MapillaryImageDisplay.this.image;
    261             }
    262             if (image == null) {
    263                 mouseIsDragging = false;
    264                 selectedRect = null;
    265                 return;
    266             }
    267             if (mouseIsDragging) {
    268                 mouseIsDragging = false;
    269             } else if (selectedRect != null) {
    270                 int oldWidth = selectedRect.width;
    271                 int oldHeight = selectedRect.height;
    272                 // Check that the zoom doesn't exceed 2:1
    273                 if (selectedRect.width < getSize().width / 2) {
    274                     selectedRect.width = getSize().width / 2;
    275                 }
    276                 if (selectedRect.height < getSize().height / 2) {
    277                     selectedRect.height = getSize().height / 2;
    278                 }
    279                 // Set the same ratio for the visible rectangle and the display
    280                 // area
    281                 int hFact = selectedRect.height * getSize().width;
    282                 int wFact = selectedRect.width * getSize().height;
    283                 if (hFact > wFact) {
    284                     selectedRect.width = hFact / getSize().height;
    285                 } else {
    286                     selectedRect.height = wFact / getSize().width;
    287                 }
    288                 // Keep the center of the selection
    289                 if (selectedRect.width != oldWidth) {
    290                     selectedRect.x -= (selectedRect.width - oldWidth) / 2;
    291                 }
    292                 if (selectedRect.height != oldHeight) {
    293                     selectedRect.y -= (selectedRect.height - oldHeight) / 2;
    294                 }
    295                 checkVisibleRectSize(image, selectedRect);
    296                 checkVisibleRectPos(image, selectedRect);
    297                 synchronized (MapillaryImageDisplay.this) {
    298                     MapillaryImageDisplay.this.visibleRect = selectedRect;
    299                 }
    300                 selectedRect = null;
    301                 MapillaryImageDisplay.this.repaint();
    302             }
    303         }
    304 
    305         @Override
    306         public void mouseEntered(MouseEvent e) {
    307         }
    308 
    309         @Override
    310         public void mouseExited(MouseEvent e) {
    311         }
    312 
    313         @Override
    314         public void mouseMoved(MouseEvent e) {
    315         }
    316 
    317         private void checkPointInVisibleRect(Point p, Rectangle visibleRect) {
    318             if (p.x < visibleRect.x) {
    319                 p.x = visibleRect.x;
    320             }
    321             if (p.x > visibleRect.x + visibleRect.width) {
    322                 p.x = visibleRect.x + visibleRect.width;
    323             }
    324             if (p.y < visibleRect.y) {
    325                 p.y = visibleRect.y;
    326             }
    327             if (p.y > visibleRect.y + visibleRect.height) {
    328                 p.y = visibleRect.y + visibleRect.height;
    329             }
    330         }
    331     }
    332 
    333     public MapillaryImageDisplay() {
    334         ImgDisplayMouseListener mouseListener = new ImgDisplayMouseListener();
    335         addMouseListener(mouseListener);
    336         addMouseWheelListener(mouseListener);
    337         addMouseMotionListener(mouseListener);
    338         this.setLayout(new BorderLayout());
    339         JPanel southPanel = new JPanel();
    340         southPanel.setLayout(new BorderLayout());
    341         hyperlink = new HyperlinkLabel();
    342         southPanel.add(hyperlink, BorderLayout.EAST);
    343         southPanel.setOpaque(false);
    344 
    345         add(southPanel, BorderLayout.SOUTH);
    346     }
    347 
    348     /**
    349      * Sets a new picture to be displayed.
    350      *
    351      * @param image
    352      */
    353     public void setImage(BufferedImage image) {
    354         synchronized (this) {
    355             this.image = image;
    356             selectedRect = null;
    357             if (image != null)
    358                 this.visibleRect = new Rectangle(0, 0, image.getWidth(null),
    359                         image.getHeight(null));
    360         }
    361         repaint();
    362     }
    363 
    364     /**
    365      * Returns the picture that is being displayerd
    366      *
    367      * @return
    368      */
    369     public BufferedImage getImage() {
    370         return this.image;
    371     }
    372 
    373     /**
    374      * Paints the visible part of the picture.
    375      */
    376     public void paintComponent(Graphics g) {
    377         Image image;
    378         Rectangle visibleRect;
    379         synchronized (this) {
    380             image = this.image;
    381             visibleRect = this.visibleRect;
    382         }
    383         if (image == null) {
    384             g.setColor(Color.black);
    385             String noImageStr = tr("No image");
    386             Rectangle2D noImageSize = g.getFontMetrics(g.getFont())
    387                     .getStringBounds(noImageStr, g);
    388             Dimension size = getSize();
    389             g.drawString(noImageStr,
    390                     (int) ((size.width - noImageSize.getWidth()) / 2),
    391                     (int) ((size.height - noImageSize.getHeight()) / 2));
     176    @Override
     177    public void mousePressed(MouseEvent e) {
     178      if (image == null) {
     179        mouseIsDragging = false;
     180        selectedRect = null;
     181        return;
     182      }
     183      Image image;
     184      Rectangle visibleRect;
     185      synchronized (MapillaryImageDisplay.this) {
     186        image = MapillaryImageDisplay.this.image;
     187        visibleRect = MapillaryImageDisplay.this.visibleRect;
     188      }
     189      if (image == null)
     190        return;
     191      if (e.getButton() == DRAG_BUTTON) {
     192        mousePointInImg = comp2imgCoord(visibleRect, e.getX(), e.getY());
     193        mouseIsDragging = true;
     194        selectedRect = null;
     195      } else if (e.getButton() == ZOOM_BUTTON) {
     196        mousePointInImg = comp2imgCoord(visibleRect, e.getX(), e.getY());
     197        checkPointInVisibleRect(mousePointInImg, visibleRect);
     198        mouseIsDragging = false;
     199        selectedRect = new Rectangle(mousePointInImg.x, mousePointInImg.y, 0, 0);
     200        MapillaryImageDisplay.this.repaint();
     201      } else {
     202        mouseIsDragging = false;
     203        selectedRect = null;
     204      }
     205    }
     206
     207    @Override
     208    public void mouseDragged(MouseEvent e) {
     209      if (!mouseIsDragging && selectedRect == null)
     210        return;
     211      Image image;
     212      Rectangle visibleRect;
     213      synchronized (MapillaryImageDisplay.this) {
     214        image = MapillaryImageDisplay.this.image;
     215        visibleRect = MapillaryImageDisplay.this.visibleRect;
     216      }
     217      if (image == null) {
     218        mouseIsDragging = false;
     219        selectedRect = null;
     220        return;
     221      }
     222      if (mouseIsDragging) {
     223        Point p = comp2imgCoord(visibleRect, e.getX(), e.getY());
     224        visibleRect.x += mousePointInImg.x - p.x;
     225        visibleRect.y += mousePointInImg.y - p.y;
     226        checkVisibleRectPos(image, visibleRect);
     227        synchronized (MapillaryImageDisplay.this) {
     228          MapillaryImageDisplay.this.visibleRect = visibleRect;
     229        }
     230        MapillaryImageDisplay.this.repaint();
     231      } else if (selectedRect != null) {
     232        Point p = comp2imgCoord(visibleRect, e.getX(), e.getY());
     233        checkPointInVisibleRect(p, visibleRect);
     234        Rectangle rect = new Rectangle(p.x < mousePointInImg.x ? p.x
     235            : mousePointInImg.x, p.y < mousePointInImg.y ? p.y
     236            : mousePointInImg.y, p.x < mousePointInImg.x ? mousePointInImg.x
     237            - p.x : p.x - mousePointInImg.x,
     238            p.y < mousePointInImg.y ? mousePointInImg.y - p.y : p.y
     239                - mousePointInImg.y);
     240        checkVisibleRectSize(image, rect);
     241        checkVisibleRectPos(image, rect);
     242        MapillaryImageDisplay.this.selectedRect = rect;
     243        MapillaryImageDisplay.this.repaint();
     244      }
     245    }
     246
     247    @Override
     248    public void mouseReleased(MouseEvent e) {
     249      if (!mouseIsDragging && selectedRect == null)
     250        return;
     251      Image image;
     252      synchronized (MapillaryImageDisplay.this) {
     253        image = MapillaryImageDisplay.this.image;
     254      }
     255      if (image == null) {
     256        mouseIsDragging = false;
     257        selectedRect = null;
     258        return;
     259      }
     260      if (mouseIsDragging) {
     261        mouseIsDragging = false;
     262      } else if (selectedRect != null) {
     263        int oldWidth = selectedRect.width;
     264        int oldHeight = selectedRect.height;
     265        // Check that the zoom doesn't exceed 2:1
     266        if (selectedRect.width < getSize().width / 2) {
     267          selectedRect.width = getSize().width / 2;
     268        }
     269        if (selectedRect.height < getSize().height / 2) {
     270          selectedRect.height = getSize().height / 2;
     271        }
     272        // Set the same ratio for the visible rectangle and the display
     273        // area
     274        int hFact = selectedRect.height * getSize().width;
     275        int wFact = selectedRect.width * getSize().height;
     276        if (hFact > wFact) {
     277          selectedRect.width = hFact / getSize().height;
    392278        } else {
    393             Rectangle target = calculateDrawImageRectangle(visibleRect);
    394             g.drawImage(image, target.x, target.y, target.x + target.width,
    395                     target.y + target.height, visibleRect.x, visibleRect.y,
    396                     visibleRect.x + visibleRect.width, visibleRect.y
    397                             + visibleRect.height, null);
    398             if (selectedRect != null) {
    399                 Point topLeft = img2compCoord(visibleRect, selectedRect.x,
    400                         selectedRect.y);
    401                 Point bottomRight = img2compCoord(visibleRect, selectedRect.x
    402                         + selectedRect.width, selectedRect.y
    403                         + selectedRect.height);
    404                 g.setColor(new Color(128, 128, 128, 180));
    405                 g.fillRect(target.x, target.y, target.width, topLeft.y
    406                         - target.y);
    407                 g.fillRect(target.x, target.y, topLeft.x - target.x,
    408                         target.height);
    409                 g.fillRect(bottomRight.x, target.y, target.x + target.width
    410                         - bottomRight.x, target.height);
    411                 g.fillRect(target.x, bottomRight.y, target.width, target.y
    412                         + target.height - bottomRight.y);
    413                 g.setColor(Color.black);
    414                 g.drawRect(topLeft.x, topLeft.y, bottomRight.x - topLeft.x,
    415                         bottomRight.y - topLeft.y);
    416             }
    417         }
    418     }
    419 
    420     private final Point img2compCoord(Rectangle visibleRect, int xImg, int yImg) {
    421         Rectangle drawRect = calculateDrawImageRectangle(visibleRect);
    422         return new Point(drawRect.x + ((xImg - visibleRect.x) * drawRect.width)
    423                 / visibleRect.width, drawRect.y
    424                 + ((yImg - visibleRect.y) * drawRect.height)
    425                 / visibleRect.height);
    426     }
    427 
    428     private final Point comp2imgCoord(Rectangle visibleRect, int xComp,
    429             int yComp) {
    430         Rectangle drawRect = calculateDrawImageRectangle(visibleRect);
    431         return new Point(visibleRect.x
    432                 + ((xComp - drawRect.x) * visibleRect.width) / drawRect.width,
    433                 visibleRect.y + ((yComp - drawRect.y) * visibleRect.height)
    434                         / drawRect.height);
    435     }
    436 
    437     private final Point getCenterImgCoord(Rectangle visibleRect) {
    438         return new Point(visibleRect.x + visibleRect.width / 2, visibleRect.y
    439                 + visibleRect.height / 2);
    440     }
    441 
    442     private Rectangle calculateDrawImageRectangle(Rectangle visibleRect) {
    443         return calculateDrawImageRectangle(visibleRect, new Rectangle(0, 0,
    444                 getSize().width, getSize().height));
    445     }
    446 
    447     /**
    448      * calculateDrawImageRectangle
    449      *
    450      * @param imgRect
    451      *            the part of the image that should be drawn (in image
    452      *            coordinates)
    453      * @param compRect
    454      *            the part of the component where the image should be drawn (in
    455      *            component coordinates)
    456      * @return the part of compRect with the same width/height ratio as the
    457      *         image
    458      */
    459     static Rectangle calculateDrawImageRectangle(Rectangle imgRect,
    460             Rectangle compRect) {
    461         int x, y, w, h;
    462         x = 0;
    463         y = 0;
    464         w = compRect.width;
    465         h = compRect.height;
    466         int wFact = w * imgRect.height;
    467         int hFact = h * imgRect.width;
    468         if (wFact != hFact) {
    469             if (wFact > hFact) {
    470                 w = hFact / imgRect.height;
    471                 x = (compRect.width - w) / 2;
    472             } else {
    473                 h = wFact / imgRect.width;
    474                 y = (compRect.height - h) / 2;
    475             }
    476         }
    477         return new Rectangle(x + compRect.x, y + compRect.y, w, h);
    478     }
    479 
    480     /**
    481      * Zooms to 1:1 and, if it is already in 1:1, to best fit.
    482      */
    483     public void zoomBestFitOrOne() {
    484         Image image;
    485         Rectangle visibleRect;
    486         synchronized (this) {
    487             image = MapillaryImageDisplay.this.image;
    488             visibleRect = MapillaryImageDisplay.this.visibleRect;
    489         }
    490         if (image == null)
    491             return;
    492         if (visibleRect.width != image.getWidth(null)
    493                 || visibleRect.height != image.getHeight(null)) {
    494             // The display is not at best fit. => Zoom to best fit
    495             visibleRect = new Rectangle(0, 0, image.getWidth(null),
    496                     image.getHeight(null));
    497         } else {
    498             // The display is at best fit => zoom to 1:1
    499             Point center = getCenterImgCoord(visibleRect);
    500             visibleRect = new Rectangle(center.x - getWidth() / 2, center.y
    501                     - getHeight() / 2, getWidth(), getHeight());
    502             checkVisibleRectPos(image, visibleRect);
    503         }
    504         synchronized (this) {
    505             this.visibleRect = visibleRect;
    506         }
    507         repaint();
    508     }
    509 
    510     private final void checkVisibleRectPos(Image image, Rectangle visibleRect) {
    511         if (visibleRect.x < 0) {
    512             visibleRect.x = 0;
    513         }
    514         if (visibleRect.y < 0) {
    515             visibleRect.y = 0;
    516         }
    517         if (visibleRect.x + visibleRect.width > image.getWidth(null)) {
    518             visibleRect.x = image.getWidth(null) - visibleRect.width;
    519         }
    520         if (visibleRect.y + visibleRect.height > image.getHeight(null)) {
    521             visibleRect.y = image.getHeight(null) - visibleRect.height;
    522         }
    523     }
    524 
    525     private void checkVisibleRectSize(Image image, Rectangle visibleRect) {
    526         if (visibleRect.width > image.getWidth(null)) {
    527             visibleRect.width = image.getWidth(null);
    528         }
    529         if (visibleRect.height > image.getHeight(null)) {
    530             visibleRect.height = image.getHeight(null);
    531         }
    532     }
     279          selectedRect.height = wFact / getSize().width;
     280        }
     281        // Keep the center of the selection
     282        if (selectedRect.width != oldWidth) {
     283          selectedRect.x -= (selectedRect.width - oldWidth) / 2;
     284        }
     285        if (selectedRect.height != oldHeight) {
     286          selectedRect.y -= (selectedRect.height - oldHeight) / 2;
     287        }
     288        checkVisibleRectSize(image, selectedRect);
     289        checkVisibleRectPos(image, selectedRect);
     290        synchronized (MapillaryImageDisplay.this) {
     291          MapillaryImageDisplay.this.visibleRect = selectedRect;
     292        }
     293        selectedRect = null;
     294        MapillaryImageDisplay.this.repaint();
     295      }
     296    }
     297
     298    @Override
     299    public void mouseEntered(MouseEvent e) {
     300    }
     301
     302    @Override
     303    public void mouseExited(MouseEvent e) {
     304    }
     305
     306    @Override
     307    public void mouseMoved(MouseEvent e) {
     308    }
     309
     310    private void checkPointInVisibleRect(Point p, Rectangle visibleRect) {
     311      if (p.x < visibleRect.x) {
     312        p.x = visibleRect.x;
     313      }
     314      if (p.x > visibleRect.x + visibleRect.width) {
     315        p.x = visibleRect.x + visibleRect.width;
     316      }
     317      if (p.y < visibleRect.y) {
     318        p.y = visibleRect.y;
     319      }
     320      if (p.y > visibleRect.y + visibleRect.height) {
     321        p.y = visibleRect.y + visibleRect.height;
     322      }
     323    }
     324  }
     325
     326  public MapillaryImageDisplay() {
     327    ImgDisplayMouseListener mouseListener = new ImgDisplayMouseListener();
     328    addMouseListener(mouseListener);
     329    addMouseWheelListener(mouseListener);
     330    addMouseMotionListener(mouseListener);
     331    this.setLayout(new BorderLayout());
     332    JPanel southPanel = new JPanel();
     333    southPanel.setLayout(new BorderLayout());
     334    hyperlink = new HyperlinkLabel();
     335    southPanel.add(hyperlink, BorderLayout.EAST);
     336    southPanel.setOpaque(false);
     337
     338    add(southPanel, BorderLayout.SOUTH);
     339  }
     340
     341  /**
     342   * Sets a new picture to be displayed.
     343   *
     344   * @param image
     345   */
     346  public void setImage(BufferedImage image) {
     347    synchronized (this) {
     348      this.image = image;
     349      selectedRect = null;
     350      if (image != null)
     351        this.visibleRect = new Rectangle(0, 0, image.getWidth(null),
     352            image.getHeight(null));
     353    }
     354    repaint();
     355  }
     356
     357  /**
     358   * Returns the picture that is being displayerd
     359   *
     360   * @return
     361   */
     362  public BufferedImage getImage() {
     363    return this.image;
     364  }
     365
     366  /**
     367   * Paints the visible part of the picture.
     368   */
     369  public void paintComponent(Graphics g) {
     370    Image image;
     371    Rectangle visibleRect;
     372    synchronized (this) {
     373      image = this.image;
     374      visibleRect = this.visibleRect;
     375    }
     376    if (image == null) {
     377      g.setColor(Color.black);
     378      String noImageStr = tr("No image");
     379      Rectangle2D noImageSize = g.getFontMetrics(g.getFont()).getStringBounds(
     380          noImageStr, g);
     381      Dimension size = getSize();
     382      g.drawString(noImageStr,
     383          (int) ((size.width - noImageSize.getWidth()) / 2),
     384          (int) ((size.height - noImageSize.getHeight()) / 2));
     385    } else {
     386      Rectangle target = calculateDrawImageRectangle(visibleRect);
     387      g.drawImage(image, target.x, target.y, target.x + target.width, target.y
     388          + target.height, visibleRect.x, visibleRect.y, visibleRect.x
     389          + visibleRect.width, visibleRect.y + visibleRect.height, null);
     390      if (selectedRect != null) {
     391        Point topLeft = img2compCoord(visibleRect, selectedRect.x,
     392            selectedRect.y);
     393        Point bottomRight = img2compCoord(visibleRect, selectedRect.x
     394            + selectedRect.width, selectedRect.y + selectedRect.height);
     395        g.setColor(new Color(128, 128, 128, 180));
     396        g.fillRect(target.x, target.y, target.width, topLeft.y - target.y);
     397        g.fillRect(target.x, target.y, topLeft.x - target.x, target.height);
     398        g.fillRect(bottomRight.x, target.y, target.x + target.width
     399            - bottomRight.x, target.height);
     400        g.fillRect(target.x, bottomRight.y, target.width, target.y
     401            + target.height - bottomRight.y);
     402        g.setColor(Color.black);
     403        g.drawRect(topLeft.x, topLeft.y, bottomRight.x - topLeft.x,
     404            bottomRight.y - topLeft.y);
     405      }
     406    }
     407  }
     408
     409  private final Point img2compCoord(Rectangle visibleRect, int xImg, int yImg) {
     410    Rectangle drawRect = calculateDrawImageRectangle(visibleRect);
     411    return new Point(drawRect.x + ((xImg - visibleRect.x) * drawRect.width)
     412        / visibleRect.width, drawRect.y
     413        + ((yImg - visibleRect.y) * drawRect.height) / visibleRect.height);
     414  }
     415
     416  private final Point comp2imgCoord(Rectangle visibleRect, int xComp, int yComp) {
     417    Rectangle drawRect = calculateDrawImageRectangle(visibleRect);
     418    return new Point(visibleRect.x + ((xComp - drawRect.x) * visibleRect.width)
     419        / drawRect.width, visibleRect.y
     420        + ((yComp - drawRect.y) * visibleRect.height) / drawRect.height);
     421  }
     422
     423  private final Point getCenterImgCoord(Rectangle visibleRect) {
     424    return new Point(visibleRect.x + visibleRect.width / 2, visibleRect.y
     425        + visibleRect.height / 2);
     426  }
     427
     428  private Rectangle calculateDrawImageRectangle(Rectangle visibleRect) {
     429    return calculateDrawImageRectangle(visibleRect, new Rectangle(0, 0,
     430        getSize().width, getSize().height));
     431  }
     432
     433  /**
     434   * calculateDrawImageRectangle
     435   *
     436   * @param imgRect
     437   *          the part of the image that should be drawn (in image coordinates)
     438   * @param compRect
     439   *          the part of the component where the image should be drawn (in
     440   *          component coordinates)
     441   * @return the part of compRect with the same width/height ratio as the image
     442   */
     443  static Rectangle calculateDrawImageRectangle(Rectangle imgRect,
     444      Rectangle compRect) {
     445    int x, y, w, h;
     446    x = 0;
     447    y = 0;
     448    w = compRect.width;
     449    h = compRect.height;
     450    int wFact = w * imgRect.height;
     451    int hFact = h * imgRect.width;
     452    if (wFact != hFact) {
     453      if (wFact > hFact) {
     454        w = hFact / imgRect.height;
     455        x = (compRect.width - w) / 2;
     456      } else {
     457        h = wFact / imgRect.width;
     458        y = (compRect.height - h) / 2;
     459      }
     460    }
     461    return new Rectangle(x + compRect.x, y + compRect.y, w, h);
     462  }
     463
     464  /**
     465   * Zooms to 1:1 and, if it is already in 1:1, to best fit.
     466   */
     467  public void zoomBestFitOrOne() {
     468    Image image;
     469    Rectangle visibleRect;
     470    synchronized (this) {
     471      image = MapillaryImageDisplay.this.image;
     472      visibleRect = MapillaryImageDisplay.this.visibleRect;
     473    }
     474    if (image == null)
     475      return;
     476    if (visibleRect.width != image.getWidth(null)
     477        || visibleRect.height != image.getHeight(null)) {
     478      // The display is not at best fit. => Zoom to best fit
     479      visibleRect = new Rectangle(0, 0, image.getWidth(null),
     480          image.getHeight(null));
     481    } else {
     482      // The display is at best fit => zoom to 1:1
     483      Point center = getCenterImgCoord(visibleRect);
     484      visibleRect = new Rectangle(center.x - getWidth() / 2, center.y
     485          - getHeight() / 2, getWidth(), getHeight());
     486      checkVisibleRectPos(image, visibleRect);
     487    }
     488    synchronized (this) {
     489      this.visibleRect = visibleRect;
     490    }
     491    repaint();
     492  }
     493
     494  private final void checkVisibleRectPos(Image image, Rectangle visibleRect) {
     495    if (visibleRect.x < 0) {
     496      visibleRect.x = 0;
     497    }
     498    if (visibleRect.y < 0) {
     499      visibleRect.y = 0;
     500    }
     501    if (visibleRect.x + visibleRect.width > image.getWidth(null)) {
     502      visibleRect.x = image.getWidth(null) - visibleRect.width;
     503    }
     504    if (visibleRect.y + visibleRect.height > image.getHeight(null)) {
     505      visibleRect.y = image.getHeight(null) - visibleRect.height;
     506    }
     507  }
     508
     509  private void checkVisibleRectSize(Image image, Rectangle visibleRect) {
     510    if (visibleRect.width > image.getWidth(null)) {
     511      visibleRect.width = image.getWidth(null);
     512    }
     513    if (visibleRect.height > image.getHeight(null)) {
     514      visibleRect.height = image.getHeight(null);
     515    }
     516  }
    533517}
  • applications/editors/josm/plugins/mapillary/src/org/openstreetmap/josm/plugins/mapillary/gui/MapillaryMainDialog.java

    r31334 r31350  
    4545 */
    4646public class MapillaryMainDialog extends ToggleDialog implements
    47         ICachedLoaderListener, MapillaryDataListener {
    48 
    49     public final static String BASE_TITLE = "Mapillary picture";
    50 
    51     public static MapillaryMainDialog INSTANCE;
    52 
    53     public volatile MapillaryAbstractImage image;
    54 
    55     public final SideButton nextButton = new SideButton(new nextPictureAction());
    56     public final SideButton previousButton = new SideButton(
    57             new previousPictureAction());
    58     public final SideButton redButton = new SideButton(new redAction());
    59     public final SideButton blueButton = new SideButton(new blueAction());
    60 
    61     private JPanel buttonsPanel;
    62 
    63     public MapillaryImageDisplay mapillaryImageDisplay;
    64 
    65     private MapillaryCache imageCache;
    66     private MapillaryCache thumbnailCache;
    67 
    68     public MapillaryMainDialog() {
    69         super(tr(BASE_TITLE), "mapillary.png", tr("Open Mapillary window"),
    70                 Shortcut.registerShortcut(tr("Mapillary dialog"),
    71                         tr("Open Mapillary main dialog"), KeyEvent.VK_M,
    72                         Shortcut.NONE), 200, false,
    73                 MapillaryPreferenceSetting.class);
    74         MapillaryData.getInstance().addListener(this);
    75         addShortcuts();
    76         mapillaryImageDisplay = new MapillaryImageDisplay();
    77 
    78         blueButton.setForeground(Color.BLUE);
    79         redButton.setForeground(Color.RED);
    80 
    81         createLayout(
    82                 mapillaryImageDisplay,
    83                 Arrays.asList(new SideButton[] { blueButton, previousButton,
    84                         nextButton, redButton }),
    85                 Main.pref.getBoolean("mapillary.reverse-buttons"));
     47    ICachedLoaderListener, MapillaryDataListener {
     48
     49  public final static String BASE_TITLE = "Mapillary picture";
     50
     51  public static MapillaryMainDialog INSTANCE;
     52
     53  public volatile MapillaryAbstractImage image;
     54
     55  public final SideButton nextButton = new SideButton(new nextPictureAction());
     56  public final SideButton previousButton = new SideButton(
     57      new previousPictureAction());
     58  public final SideButton redButton = new SideButton(new redAction());
     59  public final SideButton blueButton = new SideButton(new blueAction());
     60
     61  private JPanel buttonsPanel;
     62
     63  public MapillaryImageDisplay mapillaryImageDisplay;
     64
     65  private MapillaryCache imageCache;
     66  private MapillaryCache thumbnailCache;
     67
     68  public MapillaryMainDialog() {
     69    super(tr(BASE_TITLE), "mapillary.png", tr("Open Mapillary window"),
     70        Shortcut.registerShortcut(tr("Mapillary dialog"),
     71            tr("Open Mapillary main dialog"), KeyEvent.VK_M, Shortcut.NONE),
     72        200, false, MapillaryPreferenceSetting.class);
     73    MapillaryData.getInstance().addListener(this);
     74    addShortcuts();
     75    mapillaryImageDisplay = new MapillaryImageDisplay();
     76
     77    blueButton.setForeground(Color.BLUE);
     78    redButton.setForeground(Color.RED);
     79
     80    createLayout(
     81        mapillaryImageDisplay,
     82        Arrays.asList(new SideButton[] { blueButton, previousButton,
     83            nextButton, redButton }),
     84        Main.pref.getBoolean("mapillary.reverse-buttons"));
     85    disableAllButtons();
     86
     87  }
     88
     89  /**
     90   * Adds the shortcuts to the buttons.
     91   */
     92  private void addShortcuts() {
     93    nextButton.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(
     94        KeyStroke.getKeyStroke("PAGE_DOWN"), "next");
     95    nextButton.getActionMap().put("next", new nextPictureAction());
     96    previousButton.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(
     97        KeyStroke.getKeyStroke("PAGE_UP"), "previous");
     98    previousButton.getActionMap().put("previous", new previousPictureAction());
     99    blueButton.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(
     100        KeyStroke.getKeyStroke("control PAGE_UP"), "blue");
     101    blueButton.getActionMap().put("blue", new blueAction());
     102    redButton.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(
     103        KeyStroke.getKeyStroke("control PAGE_DOWN"), "red");
     104    redButton.getActionMap().put("red", new redAction());
     105  }
     106
     107  public static MapillaryMainDialog getInstance() {
     108    if (INSTANCE == null)
     109      INSTANCE = new MapillaryMainDialog();
     110    return INSTANCE;
     111  }
     112
     113  public static void destroyInstance() {
     114    INSTANCE = null;
     115  }
     116
     117  /**
     118   * Downloads the image of the selected MapillaryImage and sets in the
     119   * MapillaryImageDisplay object.
     120   */
     121  public synchronized void updateImage() {
     122    if (!SwingUtilities.isEventDispatchThread()) {
     123      SwingUtilities.invokeLater(new Runnable() {
     124        @Override
     125        public void run() {
     126          updateImage();
     127        }
     128      });
     129    } else {
     130      if (MapillaryLayer.INSTANCE == null) {
     131        return;
     132      }
     133      if (this.image == null) {
     134        mapillaryImageDisplay.setImage(null);
     135        setTitle(tr(BASE_TITLE));
    86136        disableAllButtons();
    87 
    88     }
    89 
    90     /**
    91      * Adds the shortcuts to the buttons.
    92      */
    93     private void addShortcuts() {
    94         nextButton.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(
    95                 KeyStroke.getKeyStroke("PAGE_DOWN"), "next");
    96         nextButton.getActionMap().put("next", new nextPictureAction());
    97         previousButton.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(
    98                 KeyStroke.getKeyStroke("PAGE_UP"), "previous");
    99         previousButton.getActionMap().put("previous",
    100                 new previousPictureAction());
    101         blueButton.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(
    102                 KeyStroke.getKeyStroke("control PAGE_UP"), "blue");
    103         blueButton.getActionMap().put("blue", new blueAction());
    104         redButton.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(
    105                 KeyStroke.getKeyStroke("control PAGE_DOWN"), "red");
    106         redButton.getActionMap().put("red", new redAction());
    107     }
    108 
    109     public static MapillaryMainDialog getInstance() {
    110         if (INSTANCE == null)
    111             INSTANCE = new MapillaryMainDialog();
    112         return INSTANCE;
    113     }
    114 
    115     public static void destroyInstance() {
    116         INSTANCE = null;
    117     }
    118 
    119     /**
    120      * Downloads the image of the selected MapillaryImage and sets in the
    121      * MapillaryImageDisplay object.
    122      */
    123     public synchronized void updateImage() {
    124         if (!SwingUtilities.isEventDispatchThread()) {
    125             SwingUtilities.invokeLater(new Runnable() {
    126                 @Override
    127                 public void run() {
    128                     updateImage();
    129                 }
    130             });
    131         } else {
    132             if (MapillaryLayer.INSTANCE == null) {
    133                 return;
     137        return;
     138      }
     139      if (image instanceof MapillaryImage) {
     140        mapillaryImageDisplay.hyperlink.setVisible(true);
     141        MapillaryImage mapillaryImage = (MapillaryImage) this.image;
     142        updateTitle();
     143        // Enables/disables next/previous buttons
     144        this.nextButton.setEnabled(false);
     145        this.previousButton.setEnabled(false);
     146        if (((MapillaryImage) image).getSequence() != null) {
     147          MapillaryImage tempImage = (MapillaryImage) image;
     148          while (tempImage.next() != null) {
     149            tempImage = tempImage.next();
     150            if (tempImage.isVisible()) {
     151              this.nextButton.setEnabled(true);
     152              break;
    134153            }
    135             if (this.image == null) {
    136                 mapillaryImageDisplay.setImage(null);
    137                 setTitle(tr(BASE_TITLE));
    138                 disableAllButtons();
    139                 return;
     154          }
     155        }
     156        if (((MapillaryImage) image).getSequence() != null) {
     157          MapillaryImage tempImage = (MapillaryImage) image;
     158          while (tempImage.previous() != null) {
     159            tempImage = tempImage.previous();
     160            if (tempImage.isVisible()) {
     161              this.previousButton.setEnabled(true);
     162              break;
    140163            }
    141             if (image instanceof MapillaryImage) {
    142                 mapillaryImageDisplay.hyperlink.setVisible(true);
    143                 MapillaryImage mapillaryImage = (MapillaryImage) this.image;
    144                 updateTitle();
    145                 // Enables/disables next/previous buttons
    146                 this.nextButton.setEnabled(false);
    147                 this.previousButton.setEnabled(false);
    148                 if (((MapillaryImage) image).getSequence() != null) {
    149                     MapillaryImage tempImage = (MapillaryImage) image;
    150                     while (tempImage.next() != null) {
    151                         tempImage = tempImage.next();
    152                         if (tempImage.isVisible()) {
    153                             this.nextButton.setEnabled(true);
    154                             break;
    155                         }
    156                     }
    157                 }
    158                 if (((MapillaryImage) image).getSequence() != null) {
    159                     MapillaryImage tempImage = (MapillaryImage) image;
    160                     while (tempImage.previous() != null) {
    161                         tempImage = tempImage.previous();
    162                         if (tempImage.isVisible()) {
    163                             this.previousButton.setEnabled(true);
    164                             break;
    165                         }
    166                     }
    167                 }
    168 
    169                 mapillaryImageDisplay.hyperlink.setURL(mapillaryImage.getKey());
    170                 // Downloads the thumbnail.
    171                 this.mapillaryImageDisplay.setImage(null);
    172                 if (thumbnailCache != null)
    173                     thumbnailCache.cancelOutstandingTasks();
    174                 thumbnailCache = new MapillaryCache(mapillaryImage.getKey(),
    175                         MapillaryCache.Type.THUMBNAIL);
    176                 thumbnailCache.submit(this, false);
    177 
    178                 // Downloads the full resolution image.
    179                 if (imageCache != null)
    180                     imageCache.cancelOutstandingTasks();
    181                 imageCache = new MapillaryCache(mapillaryImage.getKey(),
    182                         MapillaryCache.Type.FULL_IMAGE);
    183                 imageCache.submit(this, false);
    184             } else if (image instanceof MapillaryImportedImage) {
    185                 mapillaryImageDisplay.hyperlink.setVisible(false);
    186                 this.nextButton.setEnabled(false);
    187                 this.previousButton.setEnabled(false);
    188                 MapillaryImportedImage mapillaryImage = (MapillaryImportedImage) this.image;
    189                 try {
    190                     mapillaryImageDisplay.setImage(mapillaryImage.getImage());
    191                 } catch (IOException e) {
    192                     Main.error(e);
    193                 }
    194                 mapillaryImageDisplay.hyperlink.setURL(null);
    195             }
    196         }
    197     }
    198 
    199     private void disableAllButtons() {
    200         nextButton.setEnabled(false);
    201         previousButton.setEnabled(false);
    202         blueButton.setEnabled(false);
    203         redButton.setEnabled(false);
     164          }
     165        }
     166
     167        mapillaryImageDisplay.hyperlink.setURL(mapillaryImage.getKey());
     168        // Downloads the thumbnail.
     169        this.mapillaryImageDisplay.setImage(null);
     170        if (thumbnailCache != null)
     171          thumbnailCache.cancelOutstandingTasks();
     172        thumbnailCache = new MapillaryCache(mapillaryImage.getKey(),
     173            MapillaryCache.Type.THUMBNAIL);
     174        thumbnailCache.submit(this, false);
     175
     176        // Downloads the full resolution image.
     177        if (imageCache != null)
     178          imageCache.cancelOutstandingTasks();
     179        imageCache = new MapillaryCache(mapillaryImage.getKey(),
     180            MapillaryCache.Type.FULL_IMAGE);
     181        imageCache.submit(this, false);
     182      } else if (image instanceof MapillaryImportedImage) {
    204183        mapillaryImageDisplay.hyperlink.setVisible(false);
    205     }
    206 
    207     /**
    208      * Sets a new MapillaryImage to be shown.
    209      *
    210      * @param image
    211      */
    212     public synchronized void setImage(MapillaryAbstractImage image) {
    213         this.image = image;
    214     }
    215 
    216     /**
    217      * Updates the title of the dialog.
    218      */
    219     public synchronized void updateTitle() {
    220         if (!SwingUtilities.isEventDispatchThread()) {
    221             SwingUtilities.invokeLater(new Runnable() {
    222                 @Override
    223                 public void run() {
    224                     updateTitle();
    225                 }
    226             });
    227         } else {
    228             if (this.image != null) {
    229                 MapillaryImage mapillaryImage = (MapillaryImage) this.image;
    230                 String title = tr(BASE_TITLE);
    231                 if (mapillaryImage.getUser() != null)
    232                     title += " -- " + mapillaryImage.getUser();
    233                 if (mapillaryImage.getCapturedAt() != 0)
    234                     title += " -- " + mapillaryImage.getDate();
    235                 setTitle(title);
    236             }
    237         }
    238     }
    239 
    240     /**
    241      * Returns the MapillaryImage objects which is being shown.
    242      *
    243      * @return
    244      */
    245     public synchronized MapillaryAbstractImage getImage() {
    246         return this.image;
    247     }
    248 
    249     /**
    250      * Action class form the next image button.
    251      *
    252      * @author Jorge
    253      *
    254      */
    255     class nextPictureAction extends AbstractAction {
    256         public nextPictureAction() {
    257             putValue(NAME, tr("Next picture"));
    258             putValue(SHORT_DESCRIPTION,
    259                     tr("Shows the next picture in the sequence"));
    260         }
    261 
     184        this.nextButton.setEnabled(false);
     185        this.previousButton.setEnabled(false);
     186        MapillaryImportedImage mapillaryImage = (MapillaryImportedImage) this.image;
     187        try {
     188          mapillaryImageDisplay.setImage(mapillaryImage.getImage());
     189        } catch (IOException e) {
     190          Main.error(e);
     191        }
     192        mapillaryImageDisplay.hyperlink.setURL(null);
     193      }
     194    }
     195  }
     196
     197  private void disableAllButtons() {
     198    nextButton.setEnabled(false);
     199    previousButton.setEnabled(false);
     200    blueButton.setEnabled(false);
     201    redButton.setEnabled(false);
     202    mapillaryImageDisplay.hyperlink.setVisible(false);
     203  }
     204
     205  /**
     206   * Sets a new MapillaryImage to be shown.
     207   *
     208   * @param image
     209   */
     210  public synchronized void setImage(MapillaryAbstractImage image) {
     211    this.image = image;
     212  }
     213
     214  /**
     215   * Updates the title of the dialog.
     216   */
     217  public synchronized void updateTitle() {
     218    if (!SwingUtilities.isEventDispatchThread()) {
     219      SwingUtilities.invokeLater(new Runnable() {
    262220        @Override
    263         public void actionPerformed(ActionEvent e) {
    264             if (MapillaryMainDialog.getInstance().getImage() != null) {
    265                 MapillaryData.getInstance().selectNext();
    266             }
    267         }
    268     }
    269 
    270     /**
    271      * Action class for the previous image button.
    272      *
    273      * @author Jorge
    274      *
    275      */
    276     class previousPictureAction extends AbstractAction {
    277         public previousPictureAction() {
    278             putValue(NAME, tr("Previous picture"));
    279             putValue(SHORT_DESCRIPTION,
    280                     tr("Shows the previous picture in the sequence"));
    281         }
    282 
     221        public void run() {
     222          updateTitle();
     223        }
     224      });
     225    } else {
     226      if (this.image != null) {
     227        MapillaryImage mapillaryImage = (MapillaryImage) this.image;
     228        String title = tr(BASE_TITLE);
     229        if (mapillaryImage.getUser() != null)
     230          title += " -- " + mapillaryImage.getUser();
     231        if (mapillaryImage.getCapturedAt() != 0)
     232          title += " -- " + mapillaryImage.getDate();
     233        setTitle(title);
     234      }
     235    }
     236  }
     237
     238  /**
     239   * Returns the MapillaryImage objects which is being shown.
     240   *
     241   * @return
     242   */
     243  public synchronized MapillaryAbstractImage getImage() {
     244    return this.image;
     245  }
     246
     247  /**
     248   * Action class form the next image button.
     249   *
     250   * @author Jorge
     251   *
     252   */
     253  class nextPictureAction extends AbstractAction {
     254    public nextPictureAction() {
     255      putValue(NAME, tr("Next picture"));
     256      putValue(SHORT_DESCRIPTION, tr("Shows the next picture in the sequence"));
     257    }
     258
     259    @Override
     260    public void actionPerformed(ActionEvent e) {
     261      if (MapillaryMainDialog.getInstance().getImage() != null) {
     262        MapillaryData.getInstance().selectNext();
     263      }
     264    }
     265  }
     266
     267  /**
     268   * Action class for the previous image button.
     269   *
     270   * @author Jorge
     271   *
     272   */
     273  class previousPictureAction extends AbstractAction {
     274    public previousPictureAction() {
     275      putValue(NAME, tr("Previous picture"));
     276      putValue(SHORT_DESCRIPTION,
     277          tr("Shows the previous picture in the sequence"));
     278    }
     279
     280    @Override
     281    public void actionPerformed(ActionEvent e) {
     282      if (MapillaryMainDialog.getInstance().getImage() != null) {
     283        MapillaryData.getInstance().selectPrevious();
     284      }
     285    }
     286  }
     287
     288  /**
     289   * Action class to jump to the image following the red line.
     290   *
     291   * @author nokutu
     292   *
     293   */
     294  class redAction extends AbstractAction {
     295    public redAction() {
     296      putValue(NAME, tr("Jump to red"));
     297      putValue(SHORT_DESCRIPTION,
     298          tr("Jumps to the picture at the other side of the red line"));
     299    }
     300
     301    @Override
     302    public void actionPerformed(ActionEvent e) {
     303      if (MapillaryMainDialog.getInstance().getImage() != null) {
     304        MapillaryData.getInstance().setSelectedImage(MapillaryLayer.RED, true);
     305      }
     306    }
     307  }
     308
     309  /**
     310   * Action class to jump to the image following the blue line.
     311   *
     312   * @author nokutu
     313   *
     314   */
     315  class blueAction extends AbstractAction {
     316    public blueAction() {
     317      putValue(NAME, tr("Jump to blue"));
     318      putValue(SHORT_DESCRIPTION,
     319          tr("Jumps to the picture at the other side of the blue line"));
     320    }
     321
     322    @Override
     323    public void actionPerformed(ActionEvent e) {
     324      if (MapillaryMainDialog.getInstance().getImage() != null) {
     325        MapillaryData.getInstance().setSelectedImage(MapillaryLayer.BLUE, true);
     326      }
     327    }
     328  }
     329
     330  /**
     331   * When the pictures are returned from the cache, they are set in the
     332   * {@link MapillaryImageDisplay} object.
     333   */
     334  @Override
     335  public void loadingFinished(final CacheEntry data,
     336      final CacheEntryAttributes attributes, final LoadResult result) {
     337    if (!SwingUtilities.isEventDispatchThread()) {
     338      SwingUtilities.invokeLater(new Runnable() {
    283339        @Override
    284         public void actionPerformed(ActionEvent e) {
    285             if (MapillaryMainDialog.getInstance().getImage() != null) {
    286                 MapillaryData.getInstance().selectPrevious();
    287             }
    288         }
    289     }
    290 
    291     /**
    292      * Action class to jump to the image following the red line.
    293      *
    294      * @author nokutu
    295      *
    296      */
    297     class redAction extends AbstractAction {
    298         public redAction() {
    299             putValue(NAME, tr("Jump to red"));
    300             putValue(
    301                     SHORT_DESCRIPTION,
    302                     tr("Jumps to the picture at the other side of the red line"));
    303         }
    304 
    305         @Override
    306         public void actionPerformed(ActionEvent e) {
    307             if (MapillaryMainDialog.getInstance().getImage() != null) {
    308                 MapillaryData.getInstance().setSelectedImage(
    309                         MapillaryLayer.RED, true);
    310             }
    311         }
    312     }
    313 
    314     /**
    315      * Action class to jump to the image following the blue line.
    316      *
    317      * @author nokutu
    318      *
    319      */
    320     class blueAction extends AbstractAction {
    321         public blueAction() {
    322             putValue(NAME, tr("Jump to blue"));
    323             putValue(
    324                     SHORT_DESCRIPTION,
    325                     tr("Jumps to the picture at the other side of the blue line"));
    326         }
    327 
    328         @Override
    329         public void actionPerformed(ActionEvent e) {
    330             if (MapillaryMainDialog.getInstance().getImage() != null) {
    331                 MapillaryData.getInstance().setSelectedImage(
    332                         MapillaryLayer.BLUE, true);
    333             }
    334         }
    335     }
    336 
    337     /**
    338      * When the pictures are returned from the cache, they are set in the
    339      * {@link MapillaryImageDisplay} object.
    340      */
    341     @Override
    342     public void loadingFinished(final CacheEntry data,
    343             final CacheEntryAttributes attributes, final LoadResult result) {
    344         if (!SwingUtilities.isEventDispatchThread()) {
    345             SwingUtilities.invokeLater(new Runnable() {
    346                 @Override
    347                 public void run() {
    348                     loadingFinished(data, attributes, result);
    349                 }
    350             });
    351         } else if (data != null && result == LoadResult.SUCCESS) {
    352             try {
    353                 BufferedImage img = ImageIO.read(new ByteArrayInputStream(data
    354                         .getContent()));
    355                 if (img == null)
    356                     return;
    357                 if (this.mapillaryImageDisplay.getImage() == null)
    358                     mapillaryImageDisplay.setImage(img);
    359                 else if (img.getHeight() > this.mapillaryImageDisplay
    360                         .getImage().getHeight()) {
    361                     mapillaryImageDisplay.setImage(img);
    362                 }
    363             } catch (IOException e) {
    364                 Main.error(e);
    365             }
    366         }
    367     }
    368 
    369     /**
    370      * Creates the layout of the dialog.
    371      *
    372      * @param data
    373      *            The content of the dialog
    374      * @param buttons
    375      *            The buttons where you can click
    376      * @param reverse
    377      *            {@code true} if the buttons should go at the top;
    378      *            {@code false} otherwise.
    379      */
    380     public void createLayout(Component data, List<SideButton> buttons,
    381             boolean reverse) {
    382         this.removeAll();
    383         JPanel panel = new JPanel();
    384         panel.setLayout(new BorderLayout());
    385         panel.add(data, BorderLayout.CENTER);
    386         if (reverse) {
    387             buttonsPanel = new JPanel(new GridLayout(1, 1));
    388             if (!buttons.isEmpty() && buttons.get(0) != null) {
    389                 final JPanel buttonRowPanel = new JPanel(Main.pref.getBoolean(
    390                         "dialog.align.left", false) ? new FlowLayout(
    391                         FlowLayout.LEFT) : new GridLayout(1, buttons.size()));
    392                 buttonsPanel.add(buttonRowPanel);
    393                 for (SideButton button : buttons)
    394                     buttonRowPanel.add(button);
    395             }
    396             panel.add(buttonsPanel, BorderLayout.NORTH);
    397             createLayout(panel, true, null);
    398         } else
    399             createLayout(panel, true, buttons);
    400         this.add(titleBar, BorderLayout.NORTH);
    401     }
    402 
    403     @Override
    404     public void selectedImageChanged(MapillaryAbstractImage oldImage,
    405             MapillaryAbstractImage newImage) {
    406         setImage(MapillaryData.getInstance().getSelectedImage());
    407         updateImage();
    408     }
    409 
    410     @Override
    411     public void imagesAdded() {
    412     }
     340        public void run() {
     341          loadingFinished(data, attributes, result);
     342        }
     343      });
     344    } else if (data != null && result == LoadResult.SUCCESS) {
     345      try {
     346        BufferedImage img = ImageIO.read(new ByteArrayInputStream(data
     347            .getContent()));
     348        if (img == null)
     349          return;
     350        if (this.mapillaryImageDisplay.getImage() == null)
     351          mapillaryImageDisplay.setImage(img);
     352        else if (img.getHeight() > this.mapillaryImageDisplay.getImage()
     353            .getHeight()) {
     354          mapillaryImageDisplay.setImage(img);
     355        }
     356      } catch (IOException e) {
     357        Main.error(e);
     358      }
     359    }
     360  }
     361
     362  /**
     363   * Creates the layout of the dialog.
     364   *
     365   * @param data
     366   *          The content of the dialog
     367   * @param buttons
     368   *          The buttons where you can click
     369   * @param reverse
     370   *          {@code true} if the buttons should go at the top; {@code false}
     371   *          otherwise.
     372   */
     373  public void createLayout(Component data, List<SideButton> buttons,
     374      boolean reverse) {
     375    this.removeAll();
     376    JPanel panel = new JPanel();
     377    panel.setLayout(new BorderLayout());
     378    panel.add(data, BorderLayout.CENTER);
     379    if (reverse) {
     380      buttonsPanel = new JPanel(new GridLayout(1, 1));
     381      if (!buttons.isEmpty() && buttons.get(0) != null) {
     382        final JPanel buttonRowPanel = new JPanel(Main.pref.getBoolean(
     383            "dialog.align.left", false) ? new FlowLayout(FlowLayout.LEFT)
     384            : new GridLayout(1, buttons.size()));
     385        buttonsPanel.add(buttonRowPanel);
     386        for (SideButton button : buttons)
     387          buttonRowPanel.add(button);
     388      }
     389      panel.add(buttonsPanel, BorderLayout.NORTH);
     390      createLayout(panel, true, null);
     391    } else
     392      createLayout(panel, true, buttons);
     393    this.add(titleBar, BorderLayout.NORTH);
     394  }
     395
     396  @Override
     397  public void selectedImageChanged(MapillaryAbstractImage oldImage,
     398      MapillaryAbstractImage newImage) {
     399    setImage(MapillaryData.getInstance().getSelectedImage());
     400    updateImage();
     401  }
     402
     403  @Override
     404  public void imagesAdded() {
     405  }
    413406}
  • applications/editors/josm/plugins/mapillary/src/org/openstreetmap/josm/plugins/mapillary/gui/MapillaryOAuthUI.java

    r31342 r31350  
    2020public class MapillaryOAuthUI extends JPanel {
    2121
    22     private static final Token EMPTY_TOKEN = null;
     22  private static final Token EMPTY_TOKEN = null;
    2323
    24     public MapillaryOAuthUI() {
    25         Scanner in = new Scanner(System.in);
    26         OAuthService service = new ServiceBuilder()
    27                 .provider(MapillaryOAuthApi.class)
    28                 .apiKey("NzNRM2otQkR2SHJzaXJmNmdQWVQ0dzo1YTA2NmNlODhlNWMwOTBm")
    29                 .apiSecret("Secret").build();
    30         String authorizationUrl = service.getAuthorizationUrl(EMPTY_TOKEN);
    31         this.add(new JLabel("Login"));
    32         System.out.println("Fetching the Authorization URL...");
    33         System.out.println("Got the Authorization URL!");
    34         System.out.println("Now go and authorize Scribe here:");
    35         System.out.println(authorizationUrl);
    36         System.out.println("And paste the authorization code here");
    37         System.out.print(">>");
    38         Verifier verifier = new Verifier(in.nextLine());
    39         System.out.println();
    40     }
     24  public MapillaryOAuthUI() {
     25    Scanner in = new Scanner(System.in);
     26    OAuthService service = new ServiceBuilder()
     27        .provider(MapillaryOAuthApi.class)
     28        .apiKey("NzNRM2otQkR2SHJzaXJmNmdQWVQ0dzo1YTA2NmNlODhlNWMwOTBm")
     29        .apiSecret("Secret").build();
     30    String authorizationUrl = service.getAuthorizationUrl(EMPTY_TOKEN);
     31    this.add(new JLabel("Login"));
     32    System.out.println("Fetching the Authorization URL...");
     33    System.out.println("Got the Authorization URL!");
     34    System.out.println("Now go and authorize Scribe here:");
     35    System.out.println(authorizationUrl);
     36    System.out.println("And paste the authorization code here");
     37    System.out.print(">>");
     38    Verifier verifier = new Verifier(in.nextLine());
     39    System.out.println();
     40  }
    4141
    4242}
  • applications/editors/josm/plugins/mapillary/src/org/openstreetmap/josm/plugins/mapillary/gui/MapillaryPreferenceSetting.java

    r31340 r31350  
    2121public class MapillaryPreferenceSetting implements SubPreferenceSetting {
    2222
    23     private JCheckBox reverseButtons = new JCheckBox(
    24             tr("Reverse buttons position when displaying images."));
    25     private JCheckBox downloadMode = new JCheckBox(
    26             tr("Download images manually"));
    27     private JCheckBox displayHour = new JCheckBox(
    28             tr("Display hour when the picture was taken"));
    29     private JCheckBox format24 = new JCheckBox(tr("Use 24 hour format"));
    30     private JCheckBox moveTo = new JCheckBox(
    31             tr("Move to picture's location with next/previous buttons"));
     23  private JCheckBox reverseButtons = new JCheckBox(
     24      tr("Reverse buttons position when displaying images."));
     25  private JCheckBox downloadMode = new JCheckBox(tr("Download images manually"));
     26  private JCheckBox displayHour = new JCheckBox(
     27      tr("Display hour when the picture was taken"));
     28  private JCheckBox format24 = new JCheckBox(tr("Use 24 hour format"));
     29  private JCheckBox moveTo = new JCheckBox(
     30      tr("Move to picture's location with next/previous buttons"));
     31
     32  @Override
     33  public TabPreferenceSetting getTabPreferenceSetting(PreferenceTabbedPane gui) {
     34    return gui.getDisplayPreference();
     35  }
     36
     37  @Override
     38  public void addGui(PreferenceTabbedPane gui) {
     39    JPanel panel = new JPanel();
     40
     41    reverseButtons.setSelected(Main.pref
     42        .getBoolean("mapillary.reverse-buttons"));
     43    downloadMode.setSelected(Main.pref
     44        .getBoolean("mapillary.download-manually"));
     45    displayHour.setSelected(Main.pref
     46        .getBoolean("mapillary.display-hour", true));
     47    format24.setSelected(Main.pref.getBoolean("mapillary.format-24"));
     48    moveTo.setSelected(Main.pref.getBoolean("mapillary.move-to-picture", true));
     49
     50    panel.setLayout(new FlowLayout(FlowLayout.LEFT));
     51    panel.add(reverseButtons);
     52    panel.add(downloadMode);
     53    panel.add(displayHour);
     54    panel.add(format24);
     55    panel.add(moveTo);
     56    JButton oauth = new JButton(new OAuthAction());
     57    oauth.setText("Login");
     58    panel.add(oauth);
     59    gui.getDisplayPreference().addSubTab(this, "Mapillary", panel);
     60  }
     61
     62  @Override
     63  public boolean ok() {
     64    boolean mod = false;
     65    Main.pref.put("mapillary.reverse-buttons", reverseButtons.isSelected());
     66    Main.pref.put("mapillary.download-manually", downloadMode.isSelected());
     67    MapillaryPlugin.setMenuEnabled(MapillaryPlugin.DOWNLOAD_VIEW_MENU,
     68        downloadMode.isSelected());
     69
     70    Main.pref.put("mapillary.display-hour", displayHour.isSelected());
     71    Main.pref.put("mapillary.format-24", format24.isSelected());
     72    Main.pref.put("mapillary.move-to-picture", moveTo.isSelected());
     73    return mod;
     74  }
     75
     76  @Override
     77  public boolean isExpert() {
     78    return false;
     79  }
     80
     81  public class OAuthAction extends AbstractAction {
    3282
    3383    @Override
    34     public TabPreferenceSetting getTabPreferenceSetting(PreferenceTabbedPane gui) {
    35         return gui.getDisplayPreference();
     84    public void actionPerformed(ActionEvent arg0) {
     85      JButton login = new JButton();
     86      JButton cancel = new JButton();
     87      JOptionPane pane = new JOptionPane(new MapillaryOAuthUI(),
     88          JOptionPane.PLAIN_MESSAGE, JOptionPane.DEFAULT_OPTION, null,
     89          new JButton[] { login, cancel });
     90      login.setAction(new LoginAction(pane));
     91      cancel.setAction(new CancelAction(pane));
     92      JDialog dlg = pane.createDialog(Main.parent, tr("Login"));
     93      dlg.setVisible(true);
     94      dlg.dispose();
     95    }
     96  }
     97
     98  private class LoginAction extends AbstractAction {
     99    private JOptionPane pane;
     100
     101    public LoginAction(JOptionPane pane) {
     102      putValue(NAME, tr("Login"));
     103      this.pane = pane;
    36104    }
    37105
    38106    @Override
    39     public void addGui(PreferenceTabbedPane gui) {
    40         JPanel panel = new JPanel();
     107    public void actionPerformed(ActionEvent e) {
     108      pane.setValue(JOptionPane.OK_OPTION);
     109    }
     110  }
    41111
    42         reverseButtons.setSelected(Main.pref
    43                 .getBoolean("mapillary.reverse-buttons"));
    44         downloadMode.setSelected(Main.pref
    45                 .getBoolean("mapillary.download-manually"));
    46         displayHour.setSelected(Main.pref.getBoolean("mapillary.display-hour",
    47                 true));
    48         format24.setSelected(Main.pref.getBoolean("mapillary.format-24"));
    49         moveTo.setSelected(Main.pref.getBoolean("mapillary.move-to-picture",
    50                 true));
     112  private class CancelAction extends AbstractAction {
     113    private JOptionPane pane;
    51114
    52         panel.setLayout(new FlowLayout(FlowLayout.LEFT));
    53         panel.add(reverseButtons);
    54         panel.add(downloadMode);
    55         panel.add(displayHour);
    56         panel.add(format24);
    57         panel.add(moveTo);
    58         JButton oauth = new JButton(new OAuthAction());
    59         oauth.setText("Login");
    60         panel.add(oauth);
    61         gui.getDisplayPreference().addSubTab(this, "Mapillary", panel);
     115    public CancelAction(JOptionPane pane) {
     116      putValue(NAME, tr("Cancel"));
     117      this.pane = pane;
    62118    }
    63119
    64120    @Override
    65     public boolean ok() {
    66         boolean mod = false;
    67         Main.pref.put("mapillary.reverse-buttons", reverseButtons.isSelected());
    68         Main.pref.put("mapillary.download-manually", downloadMode.isSelected());
    69         MapillaryPlugin.setMenuEnabled(MapillaryPlugin.DOWNLOAD_VIEW_MENU,
    70                 downloadMode.isSelected());
    71 
    72         Main.pref.put("mapillary.display-hour", displayHour.isSelected());
    73         Main.pref.put("mapillary.format-24", format24.isSelected());
    74         Main.pref.put("mapillary.move-to-picture", moveTo.isSelected());
    75         return mod;
     121    public void actionPerformed(ActionEvent e) {
     122      pane.setValue(JOptionPane.CANCEL_OPTION);
    76123    }
    77 
    78     @Override
    79     public boolean isExpert() {
    80         return false;
    81     }
    82 
    83     public class OAuthAction extends AbstractAction {
    84 
    85         @Override
    86         public void actionPerformed(ActionEvent arg0) {
    87             JButton login = new JButton();
    88             JButton cancel = new JButton();
    89             JOptionPane pane = new JOptionPane(new MapillaryOAuthUI(),
    90                     JOptionPane.PLAIN_MESSAGE, JOptionPane.DEFAULT_OPTION,
    91                     null, new JButton[] { login, cancel });
    92             login.setAction(new LoginAction(pane));
    93             cancel.setAction(new CancelAction(pane));
    94             JDialog dlg = pane.createDialog(Main.parent, tr("Login"));
    95             dlg.setVisible(true);
    96             dlg.dispose();
    97         }
    98     }
    99 
    100     private class LoginAction extends AbstractAction {
    101         private JOptionPane pane;
    102 
    103         public LoginAction(JOptionPane pane) {
    104             putValue(NAME, tr("Login"));
    105             this.pane = pane;
    106         }
    107        
    108         @Override
    109         public void actionPerformed(ActionEvent e) {
    110             pane.setValue(JOptionPane.OK_OPTION);
    111         }
    112     }
    113    
    114     private class CancelAction extends AbstractAction {
    115         private JOptionPane pane;
    116 
    117         public CancelAction(JOptionPane pane) {
    118             putValue(NAME, tr("Cancel"));
    119             this.pane = pane;
    120         }
    121        
    122         @Override
    123         public void actionPerformed(ActionEvent e) {
    124             pane.setValue(JOptionPane.CANCEL_OPTION);
    125         }
    126     }
     124  }
    127125}
  • applications/editors/josm/plugins/mapillary/src/org/openstreetmap/josm/plugins/mapillary/oauth/MapillaryOAuthApi.java

    r31342 r31350  
    1313public class MapillaryOAuthApi extends DefaultApi20 {
    1414
    15     @Override
    16     public String getAccessTokenEndpoint() {
    17         return "https://a.mapillary.com/v2/oauth/token";
    18     }
     15  @Override
     16  public String getAccessTokenEndpoint() {
     17    return "https://a.mapillary.com/v2/oauth/token";
     18  }
    1919
    20     @Override
    21     public String getAuthorizationUrl(OAuthConfig config) {
    22         return "http://www.mapillary.io/connect?client_id=MkJKbDA0bnZuZlcxeTJHTmFqN3g1dzplZTlkZjQyYjYyZTczOTdi&redirect_uri=https:%2F%2Fjosm.openstreetmap.de%2F&response_type=token&scope=upload";
    23     }
     20  @Override
     21  public String getAuthorizationUrl(OAuthConfig config) {
     22    return "http://www.mapillary.io/connect?client_id=MkJKbDA0bnZuZlcxeTJHTmFqN3g1dzplZTlkZjQyYjYyZTczOTdi&redirect_uri=https:%2F%2Fjosm.openstreetmap.de%2F&response_type=token&scope=upload";
     23  }
    2424
    25     @Override
    26     public Verb getAccessTokenVerb() {
    27         return Verb.POST;
    28     }
     25  @Override
     26  public Verb getAccessTokenVerb() {
     27    return Verb.POST;
     28  }
    2929}
Note: See TracChangeset for help on using the changeset viewer.