Changeset 31882 in osm for applications/editors/josm/plugins/mapillary/src
- Timestamp:
- 2015-12-28T14:23:04+01:00 (9 years ago)
- Location:
- applications/editors/josm/plugins/mapillary/src/org/openstreetmap/josm/plugins/mapillary
- Files:
-
- 22 edited
Legend:
- Unmodified
- Added
- Removed
-
applications/editors/josm/plugins/mapillary/src/org/openstreetmap/josm/plugins/mapillary/MapillaryAbstractImage.java
r31812 r31882 17 17 * 18 18 */ 19 public class MapillaryAbstractImage {19 public class MapillaryAbstractImage implements Comparable<MapillaryAbstractImage>{ 20 20 /** 21 21 * If two values for field ca differ by less than EPSILON both values are considered equal. … … 120 120 final Date date = new Date(getCapturedAt()); 121 121 122 final SimpleDateFormat formatter = new SimpleDateFormat(format , Locale.UK);122 final SimpleDateFormat formatter = new SimpleDateFormat(format); 123 123 formatter.setTimeZone(Calendar.getInstance().getTimeZone()); 124 124 return formatter.format(date); … … 267 267 this.movingCa = this.tempCa + ca; 268 268 } 269 270 @Override 271 public int compareTo(MapillaryAbstractImage mapillaryAbstractImage) { 272 return hashCode() - mapillaryAbstractImage.hashCode(); 273 } 269 274 } -
applications/editors/josm/plugins/mapillary/src/org/openstreetmap/josm/plugins/mapillary/MapillaryData.java
r31833 r31882 2 2 package org.openstreetmap.josm.plugins.mapillary; 3 3 4 import java.util.ArrayList; 5 import java.util.List; 4 import java.util.*; 5 import java.util.concurrent.ConcurrentHashMap; 6 import java.util.concurrent.ConcurrentSkipListSet; 6 7 import java.util.concurrent.CopyOnWriteArrayList; 7 8 … … 17 18 * @see MapillaryAbstractImage 18 19 * @see MapillarySequence 19 *20 20 */ 21 21 public class MapillaryData { 22 22 23 private List<MapillaryAbstractImage> images; 24 /** The image currently selected, this is the one being shown. */ 23 private Set<MapillaryAbstractImage> images; 24 /** 25 * The image currently selected, this is the one being shown. 26 */ 25 27 private MapillaryAbstractImage selectedImage; 26 /** The image under the cursor. */ 28 /** 29 * The image under the cursor. 30 */ 27 31 private MapillaryAbstractImage highlightedImage; 28 /** All the images selected, can be more than one. */ 29 private final List<MapillaryAbstractImage> multiSelectedImages; 30 /** Listeners of the class. */ 32 /** 33 * All the images selected, can be more than one. 34 */ 35 private final Set<MapillaryAbstractImage> multiSelectedImages; 36 /** 37 * Listeners of the class. 38 */ 31 39 private final CopyOnWriteArrayList<MapillaryDataListener> listeners = new CopyOnWriteArrayList<>(); 32 /** The bounds of the areas for which the pictures have been downloaded. */ 40 /** 41 * The bounds of the areas for which the pictures have been downloaded. 42 */ 33 43 public List<Bounds> bounds; 34 44 … … 37 47 */ 38 48 protected MapillaryData() { 39 this.images = new Co pyOnWriteArrayList<>();40 this.multiSelectedImages = new ArrayList<>();49 this.images = new ConcurrentSkipListSet<>(); 50 this.multiSelectedImages = new ConcurrentSkipListSet<>(); 41 51 this.selectedImage = null; 42 52 … … 52 62 * Adds an MapillaryImage to the object, and then repaints mapView. 53 63 * 54 * @param image 55 * The image to be added. 64 * @param image The image to be added. 56 65 */ 57 66 public synchronized void add(MapillaryAbstractImage image) { … … 63 72 * needed for concurrency. 64 73 * 65 * @param image 66 * The image to be added. 67 * @param update 68 * Whether the map must be updated or not. 74 * @param image The image to be added. 75 * @param update Whether the map must be updated or not. 69 76 */ 70 77 public synchronized void add(MapillaryAbstractImage image, boolean update) { … … 80 87 * Adds a set of MapillaryImages to the object, and then repaints mapView. 81 88 * 82 * @param images 83 * The set of images to be added. 84 */ 85 public synchronized void add(List<MapillaryAbstractImage> images) { 89 * @param images The set of images to be added. 90 */ 91 public synchronized void add(Set<MapillaryAbstractImage> images) { 86 92 add(images, true); 87 93 } … … 90 96 * Adds a set of {link MapillaryAbstractImage} objects to this object. 91 97 * 92 * @param images 93 * The set of images to be added. 94 * @param update 95 * Whether the map must be updated or not. 96 */ 97 public synchronized void add(List<MapillaryAbstractImage> images, boolean update) { 98 * @param images The set of images to be added. 99 * @param update Whether the map must be updated or not. 100 */ 101 public synchronized void add(Set<MapillaryAbstractImage> images, boolean update) { 98 102 for (MapillaryAbstractImage image : images) { 99 103 add(image, update); … … 104 108 * Adds a new listener. 105 109 * 106 * @param lis 107 * Listener to be added. 110 * @param lis Listener to be added. 108 111 */ 109 112 public void addListener(MapillaryDataListener lis) { … … 115 118 * ctrl + click) 116 119 * 117 * @param image 118 * The {@link MapillaryImage} object to be added. 120 * @param image The {@link MapillaryImage} object to be added. 119 121 */ 120 122 public void addMultiSelectedImage(MapillaryAbstractImage image) { … … 133 135 * selected images. 134 136 * 135 * @param images 136 * A List object containing the set of images to be added. 137 */ 138 public void addMultiSelectedImage(List<MapillaryAbstractImage> images) { 137 * @param images A List object containing the set of images to be added. 138 */ 139 public void addMultiSelectedImage(Set<MapillaryAbstractImage> images) { 139 140 for (MapillaryAbstractImage image : images) 140 141 if (!this.multiSelectedImages.contains(image)) { … … 151 152 * and from its {@link MapillarySequence}. 152 153 * 153 * @param image 154 * The {@link MapillaryAbstractImage} that is going to be deleted. 154 * @param image The {@link MapillaryAbstractImage} that is going to be deleted. 155 155 */ 156 156 public synchronized void remove(MapillaryAbstractImage image) { 157 157 if (Main.main != null 158 && MapillaryMainDialog.getInstance().getImage() != null) {158 && MapillaryMainDialog.getInstance().getImage() != null) { 159 159 MapillaryMainDialog.getInstance().setImage(null); 160 160 MapillaryMainDialog.getInstance().updateImage(); … … 171 171 * Removes a set of images from the database. 172 172 * 173 * @param images 174 * A {@link List} of {@link MapillaryAbstractImage} objects that are 175 * going to be removed. 176 */ 177 public synchronized void remove(List<MapillaryAbstractImage> images) { 178 for (MapillaryAbstractImage img : images) 173 * @param images A {@link List} of {@link MapillaryAbstractImage} objects that are 174 * going to be removed. 175 */ 176 public synchronized void remove(Set<MapillaryAbstractImage> images) { 177 for (MapillaryAbstractImage img : images) { 179 178 remove(img); 179 } 180 180 } 181 181 … … 183 183 * Removes a listener. 184 184 * 185 * @param lis 186 * Listener to be removed. 185 * @param lis Listener to be removed. 187 186 */ 188 187 public void removeListener(MapillaryDataListener lis) { … … 193 192 * Highlights the image under the cursor. 194 193 * 195 * @param image 196 * The image under the cursor. 194 * @param image The image under the cursor. 197 195 */ 198 196 public void setHighlightedImage(MapillaryAbstractImage image) { … … 222 220 * @return A List object containing all images. 223 221 */ 224 public synchronized List<MapillaryAbstractImage> getImages() {222 public synchronized Set<MapillaryAbstractImage> getImages() { 225 223 return this.images; 226 224 } … … 248 246 * nothing. 249 247 * 250 * @throws IllegalStateException 251 * if the selected image is null or the selected image doesn't 252 * belong to a sequence. 248 * @throws IllegalStateException if the selected image is null or the selected image doesn't 249 * belong to a sequence. 253 250 */ 254 251 public void selectNext() { … … 261 258 * nothing. 262 259 * 263 * @param moveToPicture 264 * True if the view must me moved to the next picture. 265 * @throws IllegalStateException 266 * if the selected image is null or the selected image doesn't 267 * belong to a sequence. 260 * @param moveToPicture True if the view must me moved to the next picture. 261 * @throws IllegalStateException if the selected image is null or the selected image doesn't 262 * belong to a sequence. 268 263 */ 269 264 public void selectNext(boolean moveToPicture) { … … 287 282 * nothing. 288 283 * 289 * @throws IllegalStateException 290 * if the selected image is null or the selected image doesn't 291 * belong to a sequence. 284 * @throws IllegalStateException if the selected image is null or the selected image doesn't 285 * belong to a sequence. 292 286 */ 293 287 public void selectPrevious() { … … 301 295 * the selected image doesn't belong to a sequence. 302 296 * 303 * @param moveToPicture 304 * True if the view must me moved to the previous picture. 305 * @throws IllegalStateException 306 * if the selected image is null or the selected image doesn't 307 * belong to a sequence. 297 * @param moveToPicture True if the view must me moved to the previous picture. 298 * @throws IllegalStateException if the selected image is null or the selected image doesn't 299 * belong to a sequence. 308 300 */ 309 301 public void selectPrevious(boolean moveToPicture) { … … 325 317 * Selects a new image.If the user does ctrl + click, this isn't triggered. 326 318 * 327 * @param image 328 * The MapillaryImage which is going to be selected 329 * 319 * @param image The MapillaryImage which is going to be selected 330 320 */ 331 321 public void setSelectedImage(MapillaryAbstractImage image) { … … 337 327 * can choose whether to center the view on the new image or not. 338 328 * 339 * @param image 340 * The {@link MapillaryImage} which is going to be selected. 341 * @param zoom 342 * True if the view must be centered on the image; false otherwise. 329 * @param image The {@link MapillaryImage} which is going to be selected. 330 * @param zoom True if the view must be centered on the image; false otherwise. 343 331 */ 344 332 public void setSelectedImage(MapillaryAbstractImage image, boolean zoom) { … … 346 334 this.selectedImage = image; 347 335 this.multiSelectedImages.clear(); 348 this.multiSelectedImages.add(image); 336 if (image != null) { 337 this.multiSelectedImages.add(image); 338 } 349 339 if (image != null && Main.main != null && image instanceof MapillaryImage) { 350 340 MapillaryImage mapillaryImage = (MapillaryImage) image; … … 369 359 370 360 private void fireSelectedImageChanged(MapillaryAbstractImage oldImage, 371 MapillaryAbstractImage newImage) {361 MapillaryAbstractImage newImage) { 372 362 if (this.listeners.isEmpty()) 373 363 return; … … 383 373 * @return A List object containing all the images selected. 384 374 */ 385 public List<MapillaryAbstractImage> getMultiSelectedImages() {375 public Set<MapillaryAbstractImage> getMultiSelectedImages() { 386 376 return this.multiSelectedImages; 387 377 } … … 392 382 * @param images the new image list (previously set images are completely replaced) 393 383 */ 394 public synchronized void setImages( List<MapillaryAbstractImage> images) {395 this.images = new ArrayList<>(images);384 public synchronized void setImages(Set<MapillaryAbstractImage> images) { 385 this.images = new ConcurrentSkipListSet<>(images); 396 386 } 397 387 -
applications/editors/josm/plugins/mapillary/src/org/openstreetmap/josm/plugins/mapillary/MapillaryImage.java
r31811 r31882 120 120 121 121 @Override 122 public int compareTo(MapillaryAbstractImage image) { 123 if (image instanceof MapillaryImage) 124 return this.key.compareTo(((MapillaryImage) image).getKey()); 125 return super.compareTo(image); 126 } 127 128 @Override 122 129 public int hashCode() { 123 130 return this.key.hashCode(); -
applications/editors/josm/plugins/mapillary/src/org/openstreetmap/josm/plugins/mapillary/MapillaryImportedImage.java
r31842 r31882 100 100 101 101 @Override 102 public int compareTo(MapillaryAbstractImage image) { 103 if (image instanceof MapillaryImage) 104 return this.file.compareTo(((MapillaryImportedImage) image).getFile()); 105 return super.compareTo(image); 106 } 107 108 @Override 102 109 public int hashCode() { 103 110 return this.file.hashCode(); -
applications/editors/josm/plugins/mapillary/src/org/openstreetmap/josm/plugins/mapillary/MapillarySequence.java
r31826 r31882 10 10 * @author nokutu 11 11 * @see MapillaryAbstractImage 12 *13 12 */ 14 13 public class MapillarySequence { 15 /** The images in the sequence. */ 14 /** 15 * The images in the sequence. 16 */ 16 17 private final List<MapillaryAbstractImage> images; 17 /** Unique identifier. Used only for {@link MapillaryImage} sequences. */ 18 /** 19 * Unique identifier. Used only for {@link MapillaryImage} sequences. 20 */ 18 21 private String key; 19 /** Epoch time when the sequence was created */ 22 /** 23 * Epoch time when the sequence was created 24 */ 20 25 private long createdAt; 21 26 … … 31 36 * Creates a sequence object with the given parameters. 32 37 * 33 * @param key 34 * The unique identifier of the sequence. 35 * @param createdAt 36 * The date the sequence was created. 38 * @param key The unique identifier of the sequence. 39 * @param createdAt The date the sequence was created. 37 40 */ 38 41 public MapillarySequence(String key, long createdAt) { … … 45 48 * Adds a new {@link MapillaryAbstractImage} object to the database. 46 49 * 47 * @param image 48 * The {@link MapillaryAbstractImage} object to be added 50 * @param image The {@link MapillaryAbstractImage} object to be added 49 51 */ 50 52 public synchronized void add(MapillaryAbstractImage image) { … … 55 57 * Adds a set of {@link MapillaryAbstractImage} objects to the database. 56 58 * 57 * @param images 58 * The set of {@link MapillaryAbstractImage} objects to be added. 59 * @param images The set of {@link MapillaryAbstractImage} objects to be added. 59 60 */ 60 61 public synchronized void add(List<MapillaryAbstractImage> images) { … … 67 68 * 68 69 * @return A long containing the Epoch time when the sequence was captured. 69 *70 70 */ 71 71 public long getCreatedAt() { … … 78 78 * 79 79 * @return A {@link List} object containing all the 80 * 81 * 80 * {@link MapillaryAbstractImage} objects that are part of the 81 * sequence. 82 82 */ 83 83 public List<MapillaryAbstractImage> getImages() { … … 89 89 * 90 90 * @return A {@code String} containing the unique identifier of the sequence. 91 * 92 * 91 * null means that the sequence has been created locally for imported 92 * images. 93 93 */ 94 94 public String getKey() { … … 100 100 * {@link MapillaryAbstractImage} object. 101 101 * 102 * @param image 103 * The {@link MapillaryAbstractImage} object whose next image is 104 * going to be returned. 102 * @param image The {@link MapillaryAbstractImage} object whose next image is 103 * going to be returned. 105 104 * @return The next {@link MapillaryAbstractImage} object in the sequence. 106 * @throws IllegalArgumentException 107 * if the given {@link MapillaryAbstractImage} object doesn't belong 108 * the this sequence. 105 * @throws IllegalArgumentException if the given {@link MapillaryAbstractImage} object doesn't belong 106 * the this sequence. 109 107 */ 110 108 public MapillaryAbstractImage next(MapillaryAbstractImage image) { 111 if (!this.images.contains(image)) 109 int i = this.images.indexOf(image); 110 if (i == -1) { 112 111 throw new IllegalArgumentException(); 113 int i = this.images.indexOf(image);114 if (i == this.images.size() - 1) 112 } 113 if (i == this.images.size() - 1) { 115 114 return null; 115 } 116 116 return this.images.get(i + 1); 117 117 } … … 121 121 * given {@link MapillaryAbstractImage} object. 122 122 * 123 * @param image 124 * The {@link MapillaryAbstractImage} object whose previous image is 125 * going to be returned. 123 * @param image The {@link MapillaryAbstractImage} object whose previous image is 124 * going to be returned. 126 125 * @return The previous {@link MapillaryAbstractImage} object in the sequence. 127 * @throws IllegalArgumentException 128 * if the given {@link MapillaryAbstractImage} object doesn't belong 129 * the this sequence. 126 * @throws IllegalArgumentException if the given {@link MapillaryAbstractImage} object doesn't belong 127 * the this sequence. 130 128 */ 131 129 public MapillaryAbstractImage previous(MapillaryAbstractImage image) { 132 if (!this.images.contains(image)) 130 int i = this.images.indexOf(image); 131 if (i == -1) { 133 132 throw new IllegalArgumentException(); 134 int i = this.images.indexOf(image);135 if (i == 0) 133 } 134 if (i == 0) { 136 135 return null; 136 } 137 137 return this.images.get(i - 1); 138 138 } … … 141 141 * Removes a {@link MapillaryAbstractImage} object from the database. 142 142 * 143 * @param image 144 * The {@link MapillaryAbstractImage} object to be removed. 143 * @param image The {@link MapillaryAbstractImage} object to be removed. 145 144 */ 146 145 public void remove(MapillaryAbstractImage image) { -
applications/editors/josm/plugins/mapillary/src/org/openstreetmap/josm/plugins/mapillary/actions/MapillaryExportAction.java
r31840 r31882 11 11 import java.util.ArrayList; 12 12 import java.util.List; 13 import java.util.Set; 14 import java.util.concurrent.ConcurrentSkipListSet; 13 15 14 16 import javax.swing.JButton; … … 74 76 export(MapillaryLayer.getInstance().getData().getImages()); 75 77 } else if (this.dialog.group.isSelected(this.dialog.sequence.getModel())) { 76 ArrayList<MapillaryAbstractImage> images = new ArrayList<>();78 Set<MapillaryAbstractImage> images = new ConcurrentSkipListSet<>(); 77 79 for (MapillaryAbstractImage image : MapillaryLayer.getInstance() 78 80 .getData().getMultiSelectedImages()) … … 110 112 * The set of images to be exported. 111 113 */ 112 public void export( List<MapillaryAbstractImage> images) {114 public void export(Set<MapillaryAbstractImage> images) { 113 115 Main.worker.submit(new Thread(new MapillaryExportManager(images, 114 116 this.dialog.chooser.getSelectedFile().toString()))); -
applications/editors/josm/plugins/mapillary/src/org/openstreetmap/josm/plugins/mapillary/actions/MapillaryImportAction.java
r31843 r31882 6 6 import java.awt.event.ActionEvent; 7 7 import java.awt.event.KeyEvent; 8 import java.beans.beancontext.BeanContextChildComponentProxy; 8 9 import java.io.File; 9 10 import java.io.IOException; 10 11 import java.util.ArrayList; 11 12 import java.util.List; 13 import java.util.Set; 14 import java.util.concurrent.ConcurrentSkipListSet; 12 15 13 16 import javax.swing.JFileChooser; … … 67 70 chooser.setMultiSelectionEnabled(true); 68 71 if (chooser.showOpenDialog(Main.parent) == JFileChooser.APPROVE_OPTION) { 69 List<MapillaryAbstractImage> images = new ArrayList<>();72 Set<MapillaryAbstractImage> images = new ConcurrentSkipListSet<>(); 70 73 for (File file : chooser.getSelectedFiles()) { 71 74 Main.pref.put("mapillary.start-directory", file.getParent()); -
applications/editors/josm/plugins/mapillary/src/org/openstreetmap/josm/plugins/mapillary/actions/MapillaryImportIntoSequenceAction.java
r31837 r31882 8 8 import java.io.File; 9 9 import java.io.IOException; 10 import java.util.Collections; 11 import java.util.Comparator; 12 import java.util.LinkedList; 13 import java.util.List; 10 import java.util.*; 11 import java.util.concurrent.ConcurrentSkipListSet; 14 12 15 13 import javax.swing.JFileChooser; … … 55 53 @Override 56 54 public void actionPerformed(ActionEvent arg0) { 57 this.images = new LinkedList<>();55 this.images = new ArrayList<>(); 58 56 59 57 JFileChooser chooser = new JFileChooser(); … … 99 97 } 100 98 joinImages(); 101 MapillaryRecord.getInstance().addCommand(new CommandImport( this.images));99 MapillaryRecord.getInstance().addCommand(new CommandImport(new ConcurrentSkipListSet(images))); 102 100 } 103 101 MapillaryUtils.showAllPictures(); -
applications/editors/josm/plugins/mapillary/src/org/openstreetmap/josm/plugins/mapillary/gui/MapillaryMainDialog.java
r31843 r31882 39 39 import org.openstreetmap.josm.plugins.mapillary.actions.WalkListener; 40 40 import org.openstreetmap.josm.plugins.mapillary.actions.WalkThread; 41 import org.openstreetmap.josm.plugins.mapillary.cache.CacheUtils; 41 42 import org.openstreetmap.josm.plugins.mapillary.cache.MapillaryCache; 42 43 import org.openstreetmap.josm.tools.ImageProvider; … … 47 48 * 48 49 * @author nokutu 49 *50 50 */ 51 51 public class MapillaryMainDialog extends ToggleDialog implements 52 ICachedLoaderListener, MapillaryDataListener {52 ICachedLoaderListener, MapillaryDataListener { 53 53 54 54 private static final long serialVersionUID = 6856496736429480600L; … … 62 62 private final SideButton nextButton = new SideButton(new NextPictureAction()); 63 63 private final SideButton previousButton = new SideButton( 64 new PreviousPictureAction()); 65 /** Button used to jump to the image following the red line */ 64 new PreviousPictureAction()); 65 /** 66 * Button used to jump to the image following the red line 67 */ 66 68 public final SideButton redButton = new SideButton(new RedAction()); 67 /** Button used to jump to the image following the blue line */ 69 /** 70 * Button used to jump to the image following the blue line 71 */ 68 72 public final SideButton blueButton = new SideButton(new BlueAction()); 69 73 … … 76 80 * 77 81 * @author nokutu 78 *79 82 */ 80 83 public enum MODE { 81 /** Standard mode to view pictures. */ 84 /** 85 * Standard mode to view pictures. 86 */ 82 87 NORMAL, 83 /** Mode when in walk. */ 88 /** 89 * Mode when in walk. 90 */ 84 91 WALK; 85 92 } … … 87 94 private JPanel buttonsPanel; 88 95 89 /** Object containing the shown image and that handles zoom and drag */ 96 /** 97 * Object containing the shown image and that handles zoom and drag 98 */ 90 99 public MapillaryImageDisplay mapillaryImageDisplay; 91 100 … … 95 104 private MapillaryMainDialog() { 96 105 super(tr(BASE_TITLE), "mapillary.png", tr("Open Mapillary window"), 97 Shortcut.registerShortcut(tr("Mapillary dialog"),98 tr("Open Mapillary main dialog"), KeyEvent.VK_M, Shortcut.NONE),99 200, false, MapillaryPreferenceSetting.class);106 Shortcut.registerShortcut(tr("Mapillary dialog"), 107 tr("Open Mapillary main dialog"), KeyEvent.VK_M, Shortcut.NONE), 108 200, false, MapillaryPreferenceSetting.class); 100 109 addShortcuts(); 101 110 this.mapillaryImageDisplay = new MapillaryImageDisplay(); … … 105 114 106 115 createLayout( 107 this.mapillaryImageDisplay,108 Arrays.asList(new SideButton[]{this.blueButton, this.previousButton, this.nextButton, this.redButton}),109 Main.pref.getBoolean("mapillary.reverse-buttons"));116 this.mapillaryImageDisplay, 117 Arrays.asList(new SideButton[]{this.blueButton, this.previousButton, this.nextButton, this.redButton}), 118 Main.pref.getBoolean("mapillary.reverse-buttons")); 110 119 disableAllButtons(); 111 120 … … 117 126 private void addShortcuts() { 118 127 this.nextButton.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put( 119 KeyStroke.getKeyStroke("PAGE_DOWN"), "next");128 KeyStroke.getKeyStroke("PAGE_DOWN"), "next"); 120 129 this.nextButton.getActionMap().put("next", new NextPictureAction()); 121 130 this.previousButton.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put( 122 KeyStroke.getKeyStroke("PAGE_UP"), "previous");131 KeyStroke.getKeyStroke("PAGE_UP"), "previous"); 123 132 this.previousButton.getActionMap().put("previous", 124 new PreviousPictureAction());133 new PreviousPictureAction()); 125 134 this.blueButton.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put( 126 KeyStroke.getKeyStroke("control PAGE_UP"), "blue");135 KeyStroke.getKeyStroke("control PAGE_UP"), "blue"); 127 136 this.blueButton.getActionMap().put("blue", new BlueAction()); 128 137 this.redButton.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put( 129 KeyStroke.getKeyStroke("control PAGE_DOWN"), "red");138 KeyStroke.getKeyStroke("control PAGE_DOWN"), "red"); 130 139 this.redButton.getActionMap().put("red", new RedAction()); 131 140 } … … 145 154 * Sets a new mode for the dialog. 146 155 * 147 * @param mode 148 * The mode to be set. 156 * @param mode The mode to be set. 149 157 */ 150 158 public void setMode(MODE mode) { … … 152 160 case WALK: 153 161 createLayout( 154 this.mapillaryImageDisplay,155 Arrays.asList(new SideButton[]{playButton, pauseButton, stopButton}),156 Main.pref.getBoolean("mapillary.reverse-buttons"));162 this.mapillaryImageDisplay, 163 Arrays.asList(new SideButton[]{playButton, pauseButton, stopButton}), 164 Main.pref.getBoolean("mapillary.reverse-buttons")); 157 165 break; 158 166 case NORMAL: 159 167 default: 160 168 createLayout( 161 this.mapillaryImageDisplay,162 Arrays.asList(new SideButton[]{blueButton, previousButton, nextButton, redButton}),163 Main.pref.getBoolean("mapillary.reverse-buttons"));169 this.mapillaryImageDisplay, 170 Arrays.asList(new SideButton[]{blueButton, previousButton, nextButton, redButton}), 171 Main.pref.getBoolean("mapillary.reverse-buttons")); 164 172 break; 165 173 } … … 189 197 * MapillaryImageDisplay object. 190 198 * 191 * @param fullQuality 192 * If the full quality picture must be downloaded or just the 193 * thumbnail. 199 * @param fullQuality If the full quality picture must be downloaded or just the 200 * thumbnail. 194 201 */ 195 202 public synchronized void updateImage(boolean fullQuality) { … … 243 250 this.thumbnailCache.cancelOutstandingTasks(); 244 251 this.thumbnailCache = new MapillaryCache(mapillaryImage.getKey(), 245 MapillaryCache.Type.THUMBNAIL);252 MapillaryCache.Type.THUMBNAIL); 246 253 try { 247 254 this.thumbnailCache.submit(this, false); … … 251 258 252 259 // Downloads the full resolution image. 253 if (fullQuality) { 260 if (fullQuality || new MapillaryCache(mapillaryImage.getKey(), 261 MapillaryCache.Type.FULL_IMAGE).get() != null) { 254 262 if (this.imageCache != null) 255 263 this.imageCache.cancelOutstandingTasks(); 256 264 this.imageCache = new MapillaryCache(mapillaryImage.getKey(), 257 MapillaryCache.Type.FULL_IMAGE);265 MapillaryCache.Type.FULL_IMAGE); 258 266 try { 259 267 this.imageCache.submit(this, false); … … 277 285 } 278 286 279 /** Disables all the buttons in the dialog */ 287 /** 288 * Disables all the buttons in the dialog 289 */ 280 290 private void disableAllButtons() { 281 291 this.nextButton.setEnabled(false); … … 289 299 * Sets a new MapillaryImage to be shown. 290 300 * 291 * @param image 292 * The image to be shown. 301 * @param image The image to be shown. 293 302 */ 294 303 public synchronized void setImage(MapillaryAbstractImage image) { … … 338 347 * 339 348 * @author nokutu 340 *341 349 */ 342 350 private static class NextPictureAction extends AbstractAction { … … 362 370 * 363 371 * @author nokutu 364 *365 372 */ 366 373 private class PreviousPictureAction extends AbstractAction { … … 374 381 putValue(NAME, tr("Previous picture")); 375 382 putValue(SHORT_DESCRIPTION, 376 tr("Shows the previous picture in the sequence"));383 tr("Shows the previous picture in the sequence")); 377 384 } 378 385 … … 387 394 * 388 395 * @author nokutu 389 *390 396 */ 391 397 private class RedAction extends AbstractAction { … … 399 405 putValue(NAME, tr("Jump to red")); 400 406 putValue(SHORT_DESCRIPTION, 401 tr("Jumps to the picture at the other side of the red line"));407 tr("Jumps to the picture at the other side of the red line")); 402 408 } 403 409 … … 406 412 if (MapillaryMainDialog.getInstance().getImage() != null) { 407 413 MapillaryLayer.getInstance().getData() 408 .setSelectedImage(MapillaryLayer.getInstance().getRed(), true);414 .setSelectedImage(MapillaryLayer.getInstance().getRed(), true); 409 415 } 410 416 } … … 415 421 * 416 422 * @author nokutu 417 *418 423 */ 419 424 private class BlueAction extends AbstractAction { … … 427 432 putValue(NAME, tr("Jump to blue")); 428 433 putValue(SHORT_DESCRIPTION, 429 tr("Jumps to the picture at the other side of the blue line"));434 tr("Jumps to the picture at the other side of the blue line")); 430 435 } 431 436 … … 434 439 if (MapillaryMainDialog.getInstance().getImage() != null) { 435 440 MapillaryLayer.getInstance().getData() 436 .setSelectedImage(MapillaryLayer.getInstance().getBlue(), true);441 .setSelectedImage(MapillaryLayer.getInstance().getBlue(), true); 437 442 } 438 443 } … … 528 533 @Override 529 534 public void loadingFinished(final CacheEntry data, 530 final CacheEntryAttributes attributes, final LoadResult result) {535 final CacheEntryAttributes attributes, final LoadResult result) { 531 536 if (!SwingUtilities.isEventDispatchThread()) { 532 537 SwingUtilities.invokeLater(new Runnable() { … … 543 548 } 544 549 if ( 545 this.mapillaryImageDisplay.getImage() == null546 || img.getHeight() > this.mapillaryImageDisplay.getImage().getHeight()547 ) {550 this.mapillaryImageDisplay.getImage() == null 551 || img.getHeight() > this.mapillaryImageDisplay.getImage().getHeight() 552 ) { 548 553 this.mapillaryImageDisplay.setImage(img); 549 554 } … … 557 562 * Creates the layout of the dialog. 558 563 * 559 * @param data 560 * The content of the dialog 561 * @param buttons 562 * The buttons where you can click 563 * @param reverse 564 * {@code true} if the buttons should go at the top; {@code false} 565 * otherwise. 564 * @param data The content of the dialog 565 * @param buttons The buttons where you can click 566 * @param reverse {@code true} if the buttons should go at the top; {@code false} 567 * otherwise. 566 568 */ 567 569 public void createLayout(Component data, List<SideButton> buttons, 568 boolean reverse) {570 boolean reverse) { 569 571 this.removeAll(); 570 572 JPanel panel = new JPanel(); … … 575 577 if (!buttons.isEmpty() && buttons.get(0) != null) { 576 578 final JPanel buttonRowPanel = new JPanel(Main.pref.getBoolean( 577 "dialog.align.left", false) ? new FlowLayout(FlowLayout.LEFT)578 : new GridLayout(1, buttons.size()));579 "dialog.align.left", false) ? new FlowLayout(FlowLayout.LEFT) 580 : new GridLayout(1, buttons.size())); 579 581 this.buttonsPanel.add(buttonRowPanel); 580 582 for (SideButton button : buttons) -
applications/editors/josm/plugins/mapillary/src/org/openstreetmap/josm/plugins/mapillary/history/commands/CommandDelete.java
r31840 r31882 7 7 import java.util.List; 8 8 import java.util.Map; 9 import java.util.Set; 9 10 10 11 import org.openstreetmap.josm.plugins.mapillary.MapillaryAbstractImage; … … 27 28 * The set of images that are going to be deleted. 28 29 */ 29 public CommandDelete( List<MapillaryAbstractImage> images) {30 public CommandDelete(Set<MapillaryAbstractImage> images) { 30 31 super(images); 31 32 } … … 52 53 @Override 53 54 public void undo() { 54 for (int i = this.images.size() - 1; i >= 0; i--) { 55 MapillaryAbstractImage img = this.images.get(i); 55 for (MapillaryAbstractImage img : images) { 56 56 MapillaryLayer.getInstance().getData().add(img); 57 57 img.getSequence().getImages().add(this.changesHash.get(img), img); -
applications/editors/josm/plugins/mapillary/src/org/openstreetmap/josm/plugins/mapillary/history/commands/CommandImport.java
r31788 r31882 5 5 6 6 import java.util.List; 7 import java.util.Set; 7 8 8 9 import org.openstreetmap.josm.Main; … … 26 27 * sequence or not. 27 28 */ 28 public CommandImport( List<MapillaryAbstractImage> images) {29 public CommandImport(Set<MapillaryAbstractImage> images) { 29 30 super(images); 30 31 } -
applications/editors/josm/plugins/mapillary/src/org/openstreetmap/josm/plugins/mapillary/history/commands/CommandJoin.java
r31788 r31882 5 5 6 6 import java.util.List; 7 import java.util.concurrent.ConcurrentSkipListSet; 7 8 8 9 import org.openstreetmap.josm.plugins.mapillary.MapillaryAbstractImage; … … 17 18 public class CommandJoin extends MapillaryExecutableCommand { 18 19 20 private MapillaryAbstractImage a; 21 private MapillaryAbstractImage b; 22 19 23 /** 20 24 * Main constructor. … … 27 31 */ 28 32 public CommandJoin(List<MapillaryAbstractImage> images) { 29 super(images); 33 super(new ConcurrentSkipListSet(images)); 34 a = images.get(0); 35 b = images.get(1); 30 36 if (images.size() != 2) 31 37 throw new IllegalArgumentException(); … … 39 45 @Override 40 46 public void undo() { 41 MapillaryUtils.unjoin( this.images.get(0), this.images.get(1));47 MapillaryUtils.unjoin(a, b); 42 48 } 43 49 44 50 @Override 45 51 public void redo() { 46 MapillaryUtils.join( this.images.get(0), this.images.get(1));52 MapillaryUtils.join(a, b); 47 53 } 48 54 -
applications/editors/josm/plugins/mapillary/src/org/openstreetmap/josm/plugins/mapillary/history/commands/CommandMove.java
r31788 r31882 5 5 6 6 import java.util.List; 7 import java.util.Set; 7 8 8 9 import org.openstreetmap.josm.Main; … … 29 30 * How much the y coordinate increases. 30 31 */ 31 public CommandMove( List<MapillaryAbstractImage> images, double x,32 double y) {32 public CommandMove(Set<MapillaryAbstractImage> images, double x, 33 double y) { 33 34 super(images); 34 35 this.x = x; -
applications/editors/josm/plugins/mapillary/src/org/openstreetmap/josm/plugins/mapillary/history/commands/CommandTurn.java
r31788 r31882 5 5 6 6 import java.util.List; 7 import java.util.Set; 7 8 8 9 import org.openstreetmap.josm.Main; … … 26 27 * How much the images turn. 27 28 */ 28 public CommandTurn( List<MapillaryAbstractImage> images, double ca) {29 public CommandTurn(Set<MapillaryAbstractImage> images, double ca) { 29 30 super(images); 30 31 this.ca = ca; -
applications/editors/josm/plugins/mapillary/src/org/openstreetmap/josm/plugins/mapillary/history/commands/CommandUnjoin.java
r31788 r31882 5 5 6 6 import java.util.List; 7 import java.util.Set; 8 import java.util.concurrent.ConcurrentSkipListSet; 7 9 8 10 import org.openstreetmap.josm.plugins.mapillary.MapillaryAbstractImage; … … 17 19 public class CommandUnjoin extends MapillaryExecutableCommand { 18 20 21 private MapillaryAbstractImage a; 22 private MapillaryAbstractImage b; 23 19 24 /** 20 25 * Main constructor. … … 27 32 */ 28 33 public CommandUnjoin(List<MapillaryAbstractImage> images) { 29 super(images); 34 super(new ConcurrentSkipListSet(images)); 35 a = images.get(0); 36 b = images.get(1); 30 37 if (images.size() != 2) 31 38 throw new IllegalArgumentException(); … … 39 46 @Override 40 47 public void undo() { 41 MapillaryUtils.join( this.images.get(0), this.images.get(1));48 MapillaryUtils.join(a, b); 42 49 } 43 50 44 51 @Override 45 52 public void redo() { 46 MapillaryUtils.unjoin( this.images.get(0), this.images.get(1));53 MapillaryUtils.unjoin(a, b); 47 54 } 48 55 -
applications/editors/josm/plugins/mapillary/src/org/openstreetmap/josm/plugins/mapillary/history/commands/MapillaryCommand.java
r31840 r31882 4 4 import java.util.ArrayList; 5 5 import java.util.List; 6 import java.util.Set; 7 import java.util.concurrent.ConcurrentSkipListSet; 6 8 7 9 import org.openstreetmap.josm.plugins.mapillary.MapillaryAbstractImage; … … 15 17 public abstract class MapillaryCommand { 16 18 /** Set of {@link MapillaryAbstractImage} objects affected by the command */ 17 public List<MapillaryAbstractImage> images;19 public Set<MapillaryAbstractImage> images; 18 20 19 21 /** … … 23 25 * The images that are affected by the command. 24 26 */ 25 public MapillaryCommand( List<MapillaryAbstractImage> images) {26 this.images = new ArrayList<>(images);27 public MapillaryCommand(Set<MapillaryAbstractImage> images) { 28 this.images = new ConcurrentSkipListSet<>(images); 27 29 } 28 30 -
applications/editors/josm/plugins/mapillary/src/org/openstreetmap/josm/plugins/mapillary/history/commands/MapillaryExecutableCommand.java
r31788 r31882 3 3 4 4 import java.util.List; 5 import java.util.Set; 5 6 6 7 import org.openstreetmap.josm.plugins.mapillary.MapillaryAbstractImage; … … 20 21 * The set of images affected by the command. 21 22 */ 22 public MapillaryExecutableCommand( List<MapillaryAbstractImage> images) {23 public MapillaryExecutableCommand(Set<MapillaryAbstractImage> images) { 23 24 super(images); 24 25 } -
applications/editors/josm/plugins/mapillary/src/org/openstreetmap/josm/plugins/mapillary/io/download/MapillarySequenceDownloadThread.java
r31843 r31882 7 7 import java.util.ArrayList; 8 8 import java.util.List; 9 import java.util.concurrent.ConcurrentSkipListSet; 9 10 import java.util.concurrent.ExecutorService; 10 11 … … 38 39 * Main constructor. 39 40 * 40 * @param ex {@link ExecutorService} executing this thread.41 * @param ex {@link ExecutorService} executing this thread. 41 42 * @param bounds The bounds inside which the sequences should be downloaded 42 * @param page the pagenumber of the results that should be retrieved43 * @param page the pagenumber of the results that should be retrieved 43 44 */ 44 45 public MapillarySequenceDownloadThread(ExecutorService ex, Bounds bounds, int page) { … … 51 52 public void run() { 52 53 try ( 53 BufferedReader br = new BufferedReader(new InputStreamReader(54 MapillaryURL.searchSequenceURL(bounds, page).openStream(),55 "UTF-8"56 ));54 BufferedReader br = new BufferedReader(new InputStreamReader( 55 MapillaryURL.searchSequenceURL(bounds, page).openStream(), 56 "UTF-8" 57 )); 57 58 ) { 58 59 JsonObject jsonall = Json.createReader(br).readObject(); … … 71 72 try { 72 73 images.add(new MapillaryImage(keys.getString(j), coords 73 .getJsonArray(j).getJsonNumber(1).doubleValue(), coords74 .getJsonArray(j).getJsonNumber(0).doubleValue(), cas75 .getJsonNumber(j).doubleValue()));74 .getJsonArray(j).getJsonNumber(1).doubleValue(), coords 75 .getJsonArray(j).getJsonNumber(0).doubleValue(), cas 76 .getJsonNumber(j).doubleValue())); 76 77 } catch (IndexOutOfBoundsException e) { 77 78 Main.warn("Mapillary bug at " + MapillaryURL.searchSequenceURL(bounds, page)); … … 82 83 break; 83 84 MapillarySequence sequence = new MapillarySequence( 84 jsonobj.getString("key"), jsonobj.getJsonNumber("captured_at")85 jsonobj.getString("key"), jsonobj.getJsonNumber("captured_at") 85 86 .longValue()); 86 87 List<MapillaryImage> finalImages = new ArrayList<>(images); … … 97 98 // The image in finalImages is substituted by the one in the 98 99 // database, as they represent the same picture. 99 img = (MapillaryImage) MapillaryLayer.getInstance().getData().getImages() 100 .get(MapillaryLayer.getInstance().getData().getImages().indexOf(img)); 100 for (MapillaryAbstractImage source : MapillaryLayer.getInstance().getData().getImages()) { 101 if (source.equals(img)) { 102 img = (MapillaryImage) source; 103 } 104 } 101 105 sequence.add(img); 102 ((MapillaryImage) MapillaryLayer.getInstance().getData().getImages() 103 .get(MapillaryLayer.getInstance().getData().getImages().indexOf(img))) 104 .setSequence(sequence); 106 img.setSequence(sequence); 105 107 finalImages.set(finalImages.indexOf(img), img); 106 108 } else { … … 112 114 } 113 115 114 MapillaryLayer.getInstance().getData().add(new ArrayList<MapillaryAbstractImage>(finalImages), false);116 MapillaryLayer.getInstance().getData().add(new ConcurrentSkipListSet(finalImages), false); 115 117 } 116 118 } catch (IOException e) { -
applications/editors/josm/plugins/mapillary/src/org/openstreetmap/josm/plugins/mapillary/io/export/MapillaryExportManager.java
r31811 r31882 7 7 import java.io.IOException; 8 8 import java.util.List; 9 import java.util.Set; 9 10 import java.util.concurrent.ArrayBlockingQueue; 10 11 import java.util.concurrent.ThreadPoolExecutor; … … 38 39 39 40 private final int amount; 40 private List<MapillaryAbstractImage> images;41 private Set<MapillaryAbstractImage> images; 41 42 private String path; 42 43 … … 52 53 * Export path. 53 54 */ 54 public MapillaryExportManager( List<MapillaryAbstractImage> images, String path) {55 public MapillaryExportManager(Set<MapillaryAbstractImage> images, String path) { 55 56 super(tr("Downloading") + "...", new PleaseWaitProgressMonitor( 56 57 "Exporting Mapillary Images"), true); -
applications/editors/josm/plugins/mapillary/src/org/openstreetmap/josm/plugins/mapillary/mode/SelectMode.java
r31811 r31882 9 9 import java.awt.event.MouseEvent; 10 10 import java.util.ArrayList; 11 import java.util.concurrent.ConcurrentSkipListSet; 11 12 12 13 import org.openstreetmap.josm.Main; … … 29 30 * 30 31 * @author nokutu 31 *32 32 */ 33 33 public class SelectMode extends AbstractMode { … … 54 54 MapillaryAbstractImage closest = getClosest(e.getPoint()); 55 55 if (!(Main.map.mapView.getActiveLayer() instanceof MapillaryLayer) 56 && closest != null && Main.map.mapMode == Main.map.mapModeSelect) {56 && closest != null && Main.map.mapMode == Main.map.mapModeSelect) { 57 57 this.lastClicked = this.closest; 58 58 this.data.setSelectedImage(closest); 59 59 return; 60 60 } else if (Main.map.mapView.getActiveLayer() != MapillaryLayer 61 .getInstance())61 .getInstance()) 62 62 return; 63 63 // Double click 64 64 if (e.getClickCount() == 2 && this.data.getSelectedImage() != null 65 && closest != null) {65 && closest != null) { 66 66 for (MapillaryAbstractImage img : closest.getSequence().getImages()) { 67 67 this.data.addMultiSelectedImage(img); … … 71 71 this.lastClicked = this.closest; 72 72 this.closest = closest; 73 if ( this.data.getMultiSelectedImages().contains(closest))73 if (closest != null && this.data.getMultiSelectedImages().contains(closest)) 74 74 return; 75 75 // ctrl+click 76 76 if (e.getModifiers() == (InputEvent.BUTTON1_MASK | InputEvent.CTRL_MASK) 77 && closest != null)77 && closest != null) 78 78 this.data.addMultiSelectedImage(closest); 79 // shift + click79 // shift + click 80 80 else if (e.getModifiers() == (InputEvent.BUTTON1_MASK | InputEvent.SHIFT_MASK) 81 && this.lastClicked instanceof MapillaryImage) {81 && this.lastClicked instanceof MapillaryImage) { 82 82 if (this.closest != null && this.lastClicked != null 83 && this.closest.getSequence() == (this.lastClicked).getSequence()) {83 && this.closest.getSequence() == (this.lastClicked).getSequence()) { 84 84 int i = this.closest.getSequence().getImages().indexOf(this.closest); 85 85 int j = this.lastClicked.getSequence().getImages() 86 .indexOf(this.lastClicked);86 .indexOf(this.lastClicked); 87 87 if (i < j) 88 this.data.addMultiSelectedImage(new ArrayList<>(this.closest.getSequence()89 .getImages().subList(i, j + 1)));88 this.data.addMultiSelectedImage(new ConcurrentSkipListSet(this.closest.getSequence() 89 .getImages().subList(i, j + 1))); 90 90 else 91 this.data.addMultiSelectedImage(new ArrayList<>(this.closest.getSequence()92 .getImages().subList(j, i + 1)));91 this.data.addMultiSelectedImage(new ConcurrentSkipListSet(this.closest.getSequence() 92 .getImages().subList(j, i + 1))); 93 93 } 94 94 // click … … 99 99 @Override 100 100 public void mouseDragged(MouseEvent e) { 101 if (Main.map.mapView.getActiveLayer() != MapillaryLayer.getInstance()) 102 return; 101 if (Main.map.mapView.getActiveLayer() != MapillaryLayer.getInstance()) { 102 return; 103 } 103 104 104 105 if (!Main.pref.getBoolean("mapillary.developer")) … … 118 119 } else if (this.lastButton == MouseEvent.BUTTON1 && e.isShiftDown()) { 119 120 this.closest.turn(Math.toDegrees(Math.atan2((e.getX() - this.start.x), 120 -(e.getY() - this.start.y)))121 - this.closest.getTempCa());121 -(e.getY() - this.start.y))) 122 - this.closest.getTempCa()); 122 123 for (MapillaryAbstractImage img : this.data.getMultiSelectedImages()) { 123 124 img.turn(Math.toDegrees(Math.atan2((e.getX() - this.start.x), 124 -(e.getY() - this.start.y))) - this.closest.getTempCa());125 -(e.getY() - this.start.y))) - this.closest.getTempCa()); 125 126 } 126 127 Main.map.repaint(); … … 137 138 double to = this.data.getSelectedImage().getCa(); 138 139 this.record.addCommand(new CommandTurn(this.data.getMultiSelectedImages(), to 139 - from));140 - from)); 140 141 } else if (this.data.getSelectedImage().getTempLatLon() != this.data 141 .getSelectedImage().getLatLon()) {142 .getSelectedImage().getLatLon()) { 142 143 LatLon from = this.data.getSelectedImage().getTempLatLon(); 143 144 LatLon to = this.data.getSelectedImage().getLatLon(); 144 145 this.record.addCommand(new CommandMove(this.data.getMultiSelectedImages(), to 145 .getX() - from.getX(), to.getY() - from.getY()));146 .getX() - from.getX(), to.getY() - from.getY())); 146 147 } 147 148 for (MapillaryAbstractImage img : this.data.getMultiSelectedImages()) { … … 156 157 @Override 157 158 public void mouseMoved(MouseEvent e) { 159 if (Main.map.mapView.getActiveLayer() instanceof OsmDataLayer 160 && Main.map.mapMode != Main.map.mapModeSelect) { 161 return; 162 } 158 163 MapillaryAbstractImage closestTemp = getClosest(e.getPoint()); 159 if (Main.map.mapView.getActiveLayer() instanceof OsmDataLayer 160 && Main.map.mapMode != Main.map.mapModeSelect) 161 return; 164 162 165 if (closestTemp != null 163 && Main.map.mapView.getActiveLayer() instanceof OsmDataLayer164 && !this.imageHighlighted) {166 && Main.map.mapView.getActiveLayer() instanceof OsmDataLayer 167 && !this.imageHighlighted) { 165 168 Main.map.mapMode.putValue("active", Boolean.FALSE); 166 169 this.imageHighlighted = true; 167 170 168 171 } else if (closestTemp == null 169 && Main.map.mapView.getActiveLayer() instanceof OsmDataLayer170 && this.imageHighlighted && this.nothingHighlighted) {172 && Main.map.mapView.getActiveLayer() instanceof OsmDataLayer 173 && this.imageHighlighted && this.nothingHighlighted) { 171 174 this.nothingHighlighted = false; 172 175 Main.map.mapMode.putValue("active", Boolean.TRUE); 173 176 174 177 } else if (this.imageHighlighted && !this.nothingHighlighted 175 && Main.map.mapView.getEditLayer().data != null176 && Main.map.mapView.getActiveLayer() instanceof OsmDataLayer) {178 && Main.map.mapView.getEditLayer().data != null 179 && Main.map.mapView.getActiveLayer() instanceof OsmDataLayer) { 177 180 178 181 for (OsmPrimitive primivitive : Main.map.mapView.getEditLayer().data 179 .allPrimitives()) {182 .allPrimitives()) { 180 183 primivitive.setHighlighted(false); 181 184 } -
applications/editors/josm/plugins/mapillary/src/org/openstreetmap/josm/plugins/mapillary/oauth/UploadUtils.java
r31842 r31882 10 10 import java.util.HashMap; 11 11 import java.util.List; 12 import java.util.Set; 12 13 import java.util.UUID; 13 14 import java.util.concurrent.ArrayBlockingQueue; 15 import java.util.concurrent.ConcurrentSkipListSet; 14 16 import java.util.concurrent.ThreadPoolExecutor; 15 17 import java.util.concurrent.TimeUnit; … … 52 54 * 53 55 * @author nokutu 54 *55 56 */ 56 57 public class UploadUtils { 57 58 58 /** Required keys for POST */ 59 private static final String[] keys = { "key", "AWSAccessKeyId", "acl", 60 "policy", "signature", "Content-Type" }; 61 62 /** Mapillary upload URL */ 59 /** 60 * Required keys for POST 61 */ 62 private static final String[] keys = {"key", "AWSAccessKeyId", "acl", 63 "policy", "signature", "Content-Type"}; 64 65 /** 66 * Mapillary upload URL 67 */ 63 68 private static final String UPLOAD_URL = "https://s3-eu-west-1.amazonaws.com/mapillary.uploads.manual.images"; 64 69 65 /** Count to name temporal files. */ 70 /** 71 * Count to name temporal files. 72 */ 66 73 private static int c; 67 74 68 75 private static class SequenceUploadThread extends Thread { 69 private final List<MapillaryAbstractImage> images;76 private final Set<MapillaryAbstractImage> images; 70 77 private final UUID uuid; 71 78 private final boolean delete; 72 79 private final ThreadPoolExecutor ex; 73 80 74 private SequenceUploadThread( List<MapillaryAbstractImage> images,75 boolean delete) {81 private SequenceUploadThread(Set<MapillaryAbstractImage> images, 82 boolean delete) { 76 83 this.images = images; 77 84 this.uuid = UUID.randomUUID(); … … 104 111 if (this.delete) 105 112 MapillaryRecord.getInstance() 106 .addCommand(new CommandDelete(this.images)); 107 } 108 } 113 .addCommand(new CommandDelete(images)); 114 } 115 } 116 109 117 private static class SingleUploadThread extends Thread { 110 118 … … 129 137 * @param image 130 138 * @return A File object containing the picture and an updated version of the 131 * EXIF tags. 132 * @throws ImageReadException 133 * if there are errors reading the image from the file. 134 * @throws IOException 135 * if there are errors getting the metadata from the file or writing 136 * the output. 137 * @throws ImageWriteException 138 * if there are errors writing the image in the file. 139 * EXIF tags. 140 * @throws ImageReadException if there are errors reading the image from the file. 141 * @throws IOException if there are errors getting the metadata from the file or writing 142 * the output. 143 * @throws ImageWriteException if there are errors writing the image in the file. 139 144 */ 140 145 public static File updateFile(MapillaryImportedImage image) 141 throws ImageReadException, IOException, ImageWriteException {146 throws ImageReadException, IOException, ImageWriteException { 142 147 TiffOutputSet outputSet = null; 143 148 TiffOutputDirectory exifDirectory = null; … … 167 172 gpsDirectory.removeField(GpsTagConstants.GPS_TAG_GPS_IMG_DIRECTION_REF); 168 173 gpsDirectory.add(GpsTagConstants.GPS_TAG_GPS_IMG_DIRECTION_REF, 169 GpsTagConstants.GPS_TAG_GPS_IMG_DIRECTION_REF_VALUE_TRUE_NORTH);174 GpsTagConstants.GPS_TAG_GPS_IMG_DIRECTION_REF_VALUE_TRUE_NORTH); 170 175 171 176 gpsDirectory.removeField(GpsTagConstants.GPS_TAG_GPS_IMG_DIRECTION); 172 177 gpsDirectory.add(GpsTagConstants.GPS_TAG_GPS_IMG_DIRECTION, 173 RationalNumber.valueOf(image.getCa()));178 RationalNumber.valueOf(image.getCa())); 174 179 175 180 exifDirectory.removeField(ExifTagConstants.EXIF_TAG_DATE_TIME_ORIGINAL); 176 181 exifDirectory.add(ExifTagConstants.EXIF_TAG_DATE_TIME_ORIGINAL, 177 ((MapillaryImportedImage) image).getDate("yyyy/MM/dd HH:mm:ss"));182 ((MapillaryImportedImage) image).getDate("yyyy/MM/dd HH:mm:ss")); 178 183 179 184 // Removes the ImageDescription tag, that causes problems in the upload. … … 197 202 * 198 203 * @param image 199 *200 204 */ 201 205 public static void upload(MapillaryImportedImage image) { … … 205 209 /** 206 210 * @param image 207 * @param uuid 208 * The UUID used to create the sequence. 211 * @param uuid The UUID used to create the sequence. 209 212 */ 210 213 public static void upload(MapillaryImportedImage image, UUID uuid) { 211 214 String key = MapillaryUser.getUsername() + "/" + uuid.toString() + "/" 212 + image.getLatLon().lat() + "_" + image.getLatLon().lon() + "_"213 + image.getCa() + "_" + image.getCapturedAt() + ".jpg";215 + image.getLatLon().lat() + "_" + image.getLatLon().lon() + "_" 216 + image.getCa() + "_" + image.getCapturedAt() + ".jpg"; 214 217 215 218 String policy = null; … … 236 239 * @param hash 237 240 * @throws IOException 238 * @throws IllegalArgumentException 239 * if the hash doesn't contain all the needed keys. 241 * @throws IllegalArgumentException if the hash doesn't contain all the needed keys. 240 242 */ 241 243 public static void uploadFile(File file, HashMap<String, String> hash) 242 throws IOException {244 throws IOException { 243 245 HttpClientBuilder builder = HttpClientBuilder.create(); 244 246 HttpClient httpClient = builder.build(); … … 250 252 throw new IllegalArgumentException(); 251 253 entityBuilder.addPart(key, new StringBody(hash.get(key), 252 ContentType.TEXT_PLAIN));254 ContentType.TEXT_PLAIN)); 253 255 } 254 256 entityBuilder.addPart("file", new FileBody(file)); … … 268 270 * Uploads the given {@link MapillarySequence}. 269 271 * 270 * @param sequence 271 * The sequence to upload. It must contain only 272 * {@link MapillaryImportedImage} objects. 273 * @param delete 274 * Whether the images must be deleted after upload or not. 272 * @param sequence The sequence to upload. It must contain only 273 * {@link MapillaryImportedImage} objects. 274 * @param delete Whether the images must be deleted after upload or not. 275 275 */ 276 276 public static void uploadSequence(MapillarySequence sequence, boolean delete) { 277 Main.worker.submit(new SequenceUploadThread( sequence.getImages(), delete));277 Main.worker.submit(new SequenceUploadThread(new ConcurrentSkipListSet(sequence.getImages()), delete)); 278 278 } 279 279 } -
applications/editors/josm/plugins/mapillary/src/org/openstreetmap/josm/plugins/mapillary/utils/MapillaryUtils.java
r31842 r31882 11 11 import java.text.ParseException; 12 12 import java.text.SimpleDateFormat; 13 import java.util.ArrayList; 14 import java.util.Calendar; 15 import java.util.Date; 16 import java.util.List; 17 import java.util.Locale; 13 import java.util.*; 18 14 19 15 import javax.swing.SwingUtilities; … … 40 36 * 41 37 * @author nokutu 42 *43 38 */ 44 39 public final class MapillaryUtils { … … 97 92 * ({@link java.util.TimeZone#getDefault()}). 98 93 * 99 * @param date The string containing the date.94 * @param date The string containing the date. 100 95 * @param format The format of the date. 101 96 * @return The date in Epoch format. … … 110 105 * degrees-minutes-seconds-format 111 106 * 112 * @param degMinSec 113 * an array of length 3, the values in there are (in this order) 114 * degrees, minutes and seconds 115 * @param ref 116 * the latitude or longitude reference determining if the given value 117 * is: 118 * <ul> 119 * <li>north ( 120 * {@link GpsTagConstants#GPS_TAG_GPS_LATITUDE_REF_VALUE_NORTH}) or 121 * south ( 122 * {@link GpsTagConstants#GPS_TAG_GPS_LATITUDE_REF_VALUE_SOUTH}) of 123 * the equator</li> 124 * <li>east ( 125 * {@link GpsTagConstants#GPS_TAG_GPS_LONGITUDE_REF_VALUE_EAST}) or 126 * west ({@link GpsTagConstants#GPS_TAG_GPS_LONGITUDE_REF_VALUE_WEST} 127 * ) of the equator</li> 128 * </ul> 107 * @param degMinSec an array of length 3, the values in there are (in this order) 108 * degrees, minutes and seconds 109 * @param ref the latitude or longitude reference determining if the given value 110 * is: 111 * <ul> 112 * <li>north ( 113 * {@link GpsTagConstants#GPS_TAG_GPS_LATITUDE_REF_VALUE_NORTH}) or 114 * south ( 115 * {@link GpsTagConstants#GPS_TAG_GPS_LATITUDE_REF_VALUE_SOUTH}) of 116 * the equator</li> 117 * <li>east ( 118 * {@link GpsTagConstants#GPS_TAG_GPS_LONGITUDE_REF_VALUE_EAST}) or 119 * west ({@link GpsTagConstants#GPS_TAG_GPS_LONGITUDE_REF_VALUE_WEST} 120 * ) of the equator</li> 121 * </ul> 129 122 * @return the decimal degree-value for the given input, negative when west of 130 * 0-meridian or south of equator, positive otherwise 131 * @throws IllegalArgumentException 132 * if {@code degMinSec} doesn't have length 3 or if {@code ref} is 133 * not one of the values mentioned above 123 * 0-meridian or south of equator, positive otherwise 124 * @throws IllegalArgumentException if {@code degMinSec} doesn't have length 3 or if {@code ref} is 125 * not one of the values mentioned above 134 126 */ 135 127 public static double degMinSecToDouble(RationalNumber[] degMinSec, 136 String ref) {128 String ref) { 137 129 if (degMinSec == null || degMinSec.length != 3) { 138 130 throw new IllegalArgumentException("Array's length must be 3."); … … 157 149 158 150 if (GpsTagConstants.GPS_TAG_GPS_LATITUDE_REF_VALUE_SOUTH.equals(ref) 159 || GpsTagConstants.GPS_TAG_GPS_LONGITUDE_REF_VALUE_WEST.equals(ref)) {151 || GpsTagConstants.GPS_TAG_GPS_LONGITUDE_REF_VALUE_WEST.equals(ref)) { 160 152 result *= -1; 161 153 } … … 168 160 * Returns the extension of a {@link File} object. 169 161 * 170 * @param file 171 * The {@link File} object whose extension is going to be returned. 162 * @param file The {@link File} object whose extension is going to be returned. 172 163 * @return A {@code String} object containing the extension in lowercase. 173 164 */ … … 189 180 */ 190 181 public static synchronized void join( 191 MapillaryAbstractImage mapillaryAbstractImage,192 MapillaryAbstractImage mapillaryAbstractImage2) {182 MapillaryAbstractImage mapillaryAbstractImage, 183 MapillaryAbstractImage mapillaryAbstractImage2) { 193 184 MapillaryAbstractImage firstImage = mapillaryAbstractImage; 194 185 MapillaryAbstractImage secondImage = mapillaryAbstractImage2; … … 221 212 * direction) and creates a new icon in that position. 222 213 * 223 * @param file 224 * The file where the picture is located. 214 * @param file The file where the picture is located. 225 215 * @return The imported image. 226 * @throws ImageReadException 227 * If the file isn't an image. 228 * @throws IOException 229 * If the file doesn't have the valid metadata. 216 * @throws ImageReadException If the file isn't an image. 217 * @throws IOException If the file doesn't have the valid metadata. 230 218 */ 231 219 public static MapillaryImportedImage readJPG(File file) 232 throws IOException, ImageReadException {220 throws IOException, ImageReadException { 233 221 return readJPG(file, false); 234 222 } … … 238 226 * direction) and creates a new icon in that position. 239 227 * 240 * @param file 241 * The {@link File} where the picture is located. 242 * @param exceptionNoTags 243 * {@code true} if an exception must be thrown if the image doesn't 244 * have all the needed EXIF tags; {@code false} returns an image in 245 * the center of the screen. 228 * @param file The {@link File} where the picture is located. 229 * @param exceptionNoTags {@code true} if an exception must be thrown if the image doesn't 230 * have all the needed EXIF tags; {@code false} returns an image in 231 * the center of the screen. 246 232 * @return The imported image, whose data has been extracted from the 247 * picture's metadata. 248 * @throws ImageReadException 249 * If the {@link File} isn't an image. 250 * @throws IOException 251 * If the {@link File} doesn't have the valid metadata. 252 * @throws IllegalArgumentException 253 * if exceptionNoTags is set to {@code true} and the image doesn't 254 * have the needed EXIF tags. 233 * picture's metadata. 234 * @throws ImageReadException If the {@link File} isn't an image. 235 * @throws IOException If the {@link File} doesn't have the valid metadata. 236 * @throws IllegalArgumentException if exceptionNoTags is set to {@code true} and the image doesn't 237 * have the needed EXIF tags. 255 238 */ 256 239 public static MapillaryImportedImage readJPG(File file, 257 boolean exceptionNoTags) throws IOException, ImageReadException {240 boolean exceptionNoTags) throws IOException, ImageReadException { 258 241 final ImageMetadata metadata = Imaging.getMetadata(file); 259 242 if (metadata instanceof JpegImageMetadata) { 260 243 final JpegImageMetadata jpegMetadata = (JpegImageMetadata) metadata; 261 244 final TiffField lat_ref = jpegMetadata.findEXIFValueWithExactMatch( 262 GpsTagConstants.GPS_TAG_GPS_LATITUDE_REF);245 GpsTagConstants.GPS_TAG_GPS_LATITUDE_REF); 263 246 final TiffField lat = jpegMetadata 264 .findEXIFValueWithExactMatch(GpsTagConstants.GPS_TAG_GPS_LATITUDE);247 .findEXIFValueWithExactMatch(GpsTagConstants.GPS_TAG_GPS_LATITUDE); 265 248 final TiffField lon_ref = jpegMetadata.findEXIFValueWithExactMatch( 266 GpsTagConstants.GPS_TAG_GPS_LONGITUDE_REF);249 GpsTagConstants.GPS_TAG_GPS_LONGITUDE_REF); 267 250 final TiffField lon = jpegMetadata 268 .findEXIFValueWithExactMatch(GpsTagConstants.GPS_TAG_GPS_LONGITUDE);251 .findEXIFValueWithExactMatch(GpsTagConstants.GPS_TAG_GPS_LONGITUDE); 269 252 final TiffField ca = jpegMetadata.findEXIFValueWithExactMatch( 270 GpsTagConstants.GPS_TAG_GPS_IMG_DIRECTION);253 GpsTagConstants.GPS_TAG_GPS_IMG_DIRECTION); 271 254 final TiffField datetimeOriginal = jpegMetadata 272 .findEXIFValueWithExactMatch(273 ExifTagConstants.EXIF_TAG_DATE_TIME_ORIGINAL);255 .findEXIFValueWithExactMatch( 256 ExifTagConstants.EXIF_TAG_DATE_TIME_ORIGINAL); 274 257 if (lat_ref == null || lat == null || lon == null || lon_ref == null) { 275 258 if (exceptionNoTags) 276 259 throw new IllegalArgumentException( 277 "The image doesn't have the needed EXIF tags.");260 "The image doesn't have the needed EXIF tags."); 278 261 else 279 262 return readNoTags(file); … … 284 267 if (lat.getValue() instanceof RationalNumber[]) 285 268 latValue = MapillaryUtils.degMinSecToDouble( 286 (RationalNumber[]) lat.getValue(), lat_ref.getValue().toString());269 (RationalNumber[]) lat.getValue(), lat_ref.getValue().toString()); 287 270 if (lon.getValue() instanceof RationalNumber[]) 288 271 lonValue = MapillaryUtils.degMinSecToDouble( 289 (RationalNumber[]) lon.getValue(), lon_ref.getValue().toString());272 (RationalNumber[]) lon.getValue(), lon_ref.getValue().toString()); 290 273 if (ca != null && ca.getValue() instanceof RationalNumber) 291 274 caValue = ((RationalNumber) ca.getValue()).doubleValue(); 292 275 if (datetimeOriginal != null) 293 276 return new MapillaryImportedImage(latValue, lonValue, caValue, file, 294 datetimeOriginal.getStringValue());277 datetimeOriginal.getStringValue()); 295 278 else 296 279 return new MapillaryImportedImage(latValue, lonValue, caValue, file); … … 303 286 * creates a new icon in the middle of the map. 304 287 * 305 * @param file 306 * The file where the image is located. 288 * @param file The file where the image is located. 307 289 * @return The imported image. 308 290 */ 309 291 public static MapillaryImportedImage readNoTags(File file) { 310 292 return readNoTags(file, Main.map.mapView.getProjection() 311 .eastNorth2latlon(Main.map.mapView.getCenter()));293 .eastNorth2latlon(Main.map.mapView.getCenter())); 312 294 } 313 295 … … 316 298 * creates a new icon in the middle of the map. 317 299 * 318 * @param file 319 * The file where the image is located. 320 * @param pos 321 * A {@link LatLon} object indicating the position in the map where 322 * the image must be set. 300 * @param file The file where the image is located. 301 * @param pos A {@link LatLon} object indicating the position in the map where 302 * the image must be set. 323 303 * @return The imported image. 324 304 */ … … 335 315 final JpegImageMetadata jpegMetadata = (JpegImageMetadata) metadata; 336 316 final TiffField datetimeOriginal = jpegMetadata 337 .findEXIFValueWithExactMatch(338 ExifTagConstants.EXIF_TAG_DATE_TIME_ORIGINAL);317 .findEXIFValueWithExactMatch( 318 ExifTagConstants.EXIF_TAG_DATE_TIME_ORIGINAL); 339 319 if (datetimeOriginal == null) 340 320 return new MapillaryImportedImage(pos.lat(), pos.lon(), 0, 341 file);321 file); 342 322 else { 343 323 try { 344 324 return new MapillaryImportedImage(pos.lat(), pos.lon(), 0, 345 file, datetimeOriginal.getStringValue());325 file, datetimeOriginal.getStringValue()); 346 326 } catch (ImageReadException e) { 347 327 Main.error(e); … … 355 335 * Reads an image in PNG format. 356 336 * 357 * @param file 358 * The file where the image is located. 337 * @param file The file where the image is located. 359 338 * @return The imported image. 360 339 */ … … 374 353 * Zooms to fit all the given {@link MapillaryAbstractImage} objects. 375 354 * 376 * @param images 377 * The images your are zooming to. 378 * @param select 379 * Whether the added images must be selected or not. 380 */ 381 public static void showPictures(final List<MapillaryAbstractImage> images, final boolean select) { 355 * @param images The images your are zooming to. 356 * @param select Whether the added images must be selected or not. 357 */ 358 public static void showPictures(final Set<MapillaryAbstractImage> images, final boolean select) { 382 359 if (!SwingUtilities.isEventDispatchThread()) { 383 360 SwingUtilities.invokeLater(new Runnable() { … … 388 365 }); 389 366 } else { 390 Bounds zoomBounds ;367 Bounds zoomBounds = null; 391 368 if (images.isEmpty()) { 392 369 zoomBounds = new Bounds(new LatLon(0, 0)); 393 370 } else { 394 zoomBounds = new Bounds(images.get(0).getLatLon());395 371 for (MapillaryAbstractImage img : images) { 396 zoomBounds.extend(img.getLatLon()); 372 if (zoomBounds == null) { 373 zoomBounds = new Bounds(img.getLatLon()); 374 } else 375 zoomBounds.extend(img.getLatLon()); 397 376 } 398 377 } 378 399 379 // The zoom rectangle must have a minimum size. 400 380 double latExtent = Math.max(zoomBounds.getMaxLat() - zoomBounds.getMinLat(), MIN_ZOOM_SQUARE_SIDE); … … 409 389 MapillaryData.dataUpdated(); 410 390 } 391 411 392 } 412 393 … … 418 399 */ 419 400 public static synchronized void unjoin( 420 MapillaryAbstractImage mapillaryAbstractImage,421 MapillaryAbstractImage mapillaryAbstractImage2) {401 MapillaryAbstractImage mapillaryAbstractImage, 402 MapillaryAbstractImage mapillaryAbstractImage2) { 422 403 MapillaryAbstractImage firstImage = mapillaryAbstractImage; 423 404 MapillaryAbstractImage secondImage = mapillaryAbstractImage2; … … 429 410 430 411 ArrayList<MapillaryAbstractImage> firstHalf = new ArrayList<>( 431 firstImage.getSequence().getImages().subList(0,432 firstImage.getSequence().getImages().indexOf(secondImage)));412 firstImage.getSequence().getImages().subList(0, 413 firstImage.getSequence().getImages().indexOf(secondImage))); 433 414 ArrayList<MapillaryAbstractImage> secondHalf = new ArrayList<>( 434 firstImage.getSequence().getImages().subList(435 firstImage.getSequence().getImages().indexOf(secondImage),436 firstImage.getSequence().getImages().size()));415 firstImage.getSequence().getImages().subList( 416 firstImage.getSequence().getImages().indexOf(secondImage), 417 firstImage.getSequence().getImages().size())); 437 418 438 419 MapillarySequence seq1 = new MapillarySequence(); … … 457 438 StringBuilder ret = new StringBuilder(); 458 439 if (PluginState.isDownloading()) { 459 ret 440 ret.append(tr("Downloading Mapillary images")); 460 441 } else if (MapillaryLayer.getInstance().getData().size() > 0) { 461 442 ret.append(tr("Total Mapillary images: {0}", MapillaryLayer.getInstance().getData().size()));
Note:
See TracChangeset
for help on using the changeset viewer.