Changeset 36194 in osm for applications/editors/josm/plugins
- Timestamp:
- 2023-11-14T23:40:50+01:00 (12 months ago)
- Location:
- applications/editors/josm/plugins/MicrosoftStreetside
- Files:
-
- 111 edited
Legend:
- Unmodified
- Added
- Removed
-
applications/editors/josm/plugins/MicrosoftStreetside/GPL-v3.0.md
r34317 r36194 633 633 <one line to give the program's name and a brief idea of what it does.> 634 634 Copyright (C) <year> <name of author> 635 635 636 636 This program is free software: you can redistribute it and/or modify 637 637 it under the terms of the GNU General Public License as published by 638 638 the Free Software Foundation, either version 3 of the License, or 639 639 (at your option) any later version. 640 640 641 641 This program is distributed in the hope that it will be useful, 642 642 but WITHOUT ANY WARRANTY; without even the implied warranty of 643 643 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 644 644 GNU General Public License for more details. 645 645 646 646 You should have received a copy of the GNU General Public License 647 647 along with this program. If not, see <http://www.gnu.org/licenses/>. -
applications/editors/josm/plugins/MicrosoftStreetside/build.gradle
r35779 r36194 7 7 id 'jacoco' 8 8 id 'pmd' 9 id("com.github.ben-manes.versions").version("0. 39.0")10 id("net.ltgt.errorprone").version(" 2.0.2")9 id("com.github.ben-manes.versions").version("0.49.0") 10 id("net.ltgt.errorprone").version("3.1.0") 11 11 id("org.kordamp.markdown.convert").version("1.2.0") 12 12 id("org.sonarqube").version("3.3") 13 id('com.github.spotbugs').version(' 4.7.2')14 id('org.openstreetmap.josm').version("0. 7.1")15 id("com.diffplug.spotless").version(" 5.14.1")13 id('com.github.spotbugs').version('5.2.3') 14 id('org.openstreetmap.josm').version("0.8.2") 15 id("com.diffplug.spotless").version("6.22.0") 16 16 } 17 17 … … 34 34 35 35 repositories { 36 jcenter()37 36 mavenCentral() 38 37 maven { … … 42 41 43 42 def versions = [ 44 awaitility: "4.1.0", 45 jackson: "2.12.4", 43 awaitility: "4.2.0", 46 44 jmockit: "1.49.a", 47 junit: "5. 7.1",45 junit: "5.10.1", 48 46 wiremock: "2.27.2" 49 47 ] … … 53 51 errorproneJavac("com.google.errorprone:javac:9+181-r4173-1") 54 52 } 55 implementation "com.fasterxml.jackson.core:jackson-core:${versions.jackson}"56 implementation "com.fasterxml.jackson.core:jackson-databind:${versions.jackson}"57 implementation "com.fasterxml.jackson.core:jackson-annotations:${versions.jackson}"58 implementation "us.monoid.web:resty:0.3.2"59 implementation "log4j:log4j:1.2.17"60 53 testRuntimeOnly("org.junit.jupiter:junit-jupiter-engine:${versions.junit}") 61 54 testImplementation("org.junit.jupiter:junit-jupiter-params:${versions.junit}") -
applications/editors/josm/plugins/MicrosoftStreetside/build.xml
r36034 r36194 15 15 <include name="apache-commons.jar"/> 16 16 <include name="apache-http.jar"/> 17 <include name="jackson.jar"/>18 17 <include name="javafx-osx.jar" if:set="isMac"/> 19 18 <include name="javafx-unixoid.jar" if:set="isUnix"/> 20 19 <include name="javafx-windows.jar" if:set="isWindows"/> 21 <include name="log4j.jar"/>22 20 <include name="utilsplugin2.jar"/> 23 21 </fileset> -
applications/editors/josm/plugins/MicrosoftStreetside/gradle.properties
r36122 r36194 14 14 # If not, choose the next higher number that is available, or the gradle build will break. 15 15 plugin.compile.version=18724 16 plugin.requires=apache-commons;apache-http;ja ckson;javafx;log4j;utilsplugin216 plugin.requires=apache-commons;apache-http;javafx;utilsplugin2 17 17 18 18 # Character encoding of Gradle files -
applications/editors/josm/plugins/MicrosoftStreetside/gradle/wrapper/gradle-wrapper.properties
r35779 r36194 1 1 distributionBase=GRADLE_USER_HOME 2 2 distributionPath=wrapper/dists 3 distributionUrl=https\://services.gradle.org/distributions/gradle-7.1.1-bin.zip 3 distributionSha256Sum=740c2e472ee4326c33bf75a5c9f5cd1e69ecf3f9b580f6e236c86d1f3d98cfac 4 distributionUrl=https\://services.gradle.org/distributions/gradle-7.6.3-bin.zip 4 5 zipStoreBase=GRADLE_USER_HOME 5 6 zipStorePath=wrapper/dists -
applications/editors/josm/plugins/MicrosoftStreetside/gradlew
r35779 r36194 73 73 darwin=true 74 74 ;; 75 M INGW* )75 MSYS* | MINGW* ) 76 76 msys=true 77 77 ;; -
applications/editors/josm/plugins/MicrosoftStreetside/ivy.xml
r36176 r36194 7 7 </configurations> 8 8 <dependencies> 9 <dependency org="com.fasterxml.jackson.core" name="jackson-annotations" rev="2.15.3" conf="default->default"/>10 <dependency org="com.fasterxml.jackson.core" name="jackson-databind" rev="2.15.3" conf="default->default"/>11 <dependency org="us.monoid.web" name="resty" rev="0.3.2" conf="default->default"/>12 9 <dependency org="org.openjfx" name="javafx-swing" rev="19" conf="provided"> 13 10 <artifact name="javafx-swing" type="jar" m:classifier="linux"/> … … 38 35 <artifact name="javafx-graphics" type="jar" m:classifier="javadoc"/> 39 36 </dependency> 40 <!-- from jackson plugin -->41 <exclude org="com.fasterxml.jackson.core" module="jackson-core"/>42 <!-- not needed at runtime -->43 <exclude org="net.java.dev.javacc" module="javacc"/>44 37 </dependencies> 45 38 </ivy-module> -
applications/editors/josm/plugins/MicrosoftStreetside/src/org/openstreetmap/josm/plugins/streetside/StreetsideAbstractImage.java
r34577 r36194 13 13 */ 14 14 public abstract class StreetsideAbstractImage implements Comparable<StreetsideAbstractImage> { 15 /** 16 * If two values for field cd differ by less than EPSILON both values are 17 * considered equal. 18 */ 19 private static final float EPSILON = 1e-5f; 20 21 protected String id; 22 23 // Image id of next image in sequence (decimal) 24 private long ne; 25 //Image id of previous image in sequence (decimal) 26 private long pr; 27 28 29 /** Sequence of pictures containing this object. */ 30 private StreetsideSequence sequence; 31 32 /** Position of the picture. */ 33 protected LatLon latLon; 34 /** Direction of the picture in degrees from true north. */ 35 protected double he; 36 /** Temporal position of the picture until it is uploaded. */ 37 private LatLon tempLatLon; 38 /** 39 * When the object is being dragged in the map, the temporal position is stored 40 * here. 41 */ 42 private LatLon movingLatLon; 43 /** Temporal direction of the picture until it is uploaded */ 44 private double tempHe; 45 /** 46 * When the object direction is being moved in the map, the temporal direction 47 * is stored here 48 */ 49 protected double movingHe; 50 /** Whether the image must be drown in the map or not */ 51 private boolean visible; 52 53 /** 54 * Creates a new object in the given position and with the given direction. 55 * {@link LatLon} 56 * 57 * @param id - the Streetside image id 58 * 59 * @param latLon 60 * The latitude and longitude of the image. 61 * @param he 62 * The direction of the picture (0 means north im Mapillary 63 * camera direction is not yet supported in the Streetside plugin). 64 */ 65 protected StreetsideAbstractImage(final String id, final LatLon latLon, final double he) { 66 this.id = id; 67 this.latLon = latLon; 68 tempLatLon = this.latLon; 69 movingLatLon = this.latLon; 70 this.he = he; 71 tempHe = he; 72 movingHe = he; 73 visible = true; 74 } 75 76 /** 77 * Creates a new object with the given id. 78 * 79 * @param id - the image id (All images require ids in Streetside) 80 */ 81 protected StreetsideAbstractImage(final String id) { 82 this.id = id; 83 84 visible = true; 85 } 86 87 /** 88 * @return the id 89 */ 90 public String getId() { 91 return id; 92 } 93 94 /** 95 * @param id 96 * the id to set 97 */ 98 public void setId(String id) { 99 this.id = id; 100 } 101 102 /** 103 * Returns the original direction towards the image has been taken. 104 * 105 * @return The direction of the image (0 means north and goes clockwise). 106 */ 107 public double getHe() { 108 return he; 109 } 110 111 /** 112 * Returns a LatLon object containing the original coordinates of the object. 113 * 114 * @return The LatLon object with the position of the object. 115 */ 116 public LatLon getLatLon() { 117 return latLon; 118 } 119 120 /** 121 * Returns the direction towards the image has been taken. 122 * 123 * @return The direction of the image (0 means north and goes clockwise). 124 */ 125 public double getMovingHe() { 126 return movingHe; 127 } 128 129 /** 130 * Returns a LatLon object containing the current coordinates of the object. 131 * When you are dragging the image this changes. 132 * 133 * @return The LatLon object with the position of the object. 134 */ 135 public LatLon getMovingLatLon() { 136 return movingLatLon; 137 } 138 139 /** 140 * Returns the sequence which contains this image. Never null. 141 * 142 * @return The StreetsideSequence object that contains this StreetsideImage. 143 */ 144 145 public StreetsideSequence getSequence() { 146 synchronized (this) { 147 if (sequence == null) { 148 sequence = new StreetsideSequence(); 149 sequence.add(this); 150 } 151 return sequence; 152 } 153 } 154 155 /** 156 * Returns the last fixed direction of the object. 157 * 158 * @return The last fixed direction of the object. 0 means north. 159 */ 160 public double getTempHe() { 161 return tempHe; 162 } 163 164 /** 165 * Returns the last fixed coordinates of the object. 166 * 167 * @return A LatLon object containing. 168 */ 169 public LatLon getTempLatLon() { 170 return tempLatLon; 171 } 172 173 /** 174 * Returns whether the object has been modified or not. 175 * 176 * @return true if the object has been modified; false otherwise. 177 */ 178 public boolean isModified() { 179 return !getMovingLatLon().equals(latLon) || Math.abs(getMovingHe() - he) > EPSILON; 180 } 181 182 /** 183 * Returns whether the image is visible on the map or not. 184 * 185 * @return True if the image is visible; false otherwise. 186 */ 187 public boolean isVisible() { 188 return visible; 189 } 190 191 /** 192 * Moves the image temporally to another position 193 * 194 * @param x 195 * The movement of the image in longitude units. 196 * @param y 197 * The movement of the image in latitude units. 198 */ 199 public void move(final double x, final double y) { 200 movingLatLon = new LatLon(tempLatLon.getY() + y, tempLatLon.getX() + x); 201 } 202 203 /** 204 * If the StreetsideImage belongs to a StreetsideSequence, returns the next 205 * image in the sequence. 206 * 207 * @return The following StreetsideImage, or null if there is none. 208 */ 209 public StreetsideAbstractImage next() { 210 synchronized (this) { 211 return getSequence().next(this); 212 } 213 } 214 215 /** 216 * If the StreetsideImage belongs to a StreetsideSequence, returns the previous 217 * image in the sequence. 218 * 219 * @return The previous StreetsideImage, or null if there is none. 220 */ 221 public StreetsideAbstractImage previous() { 222 synchronized (this) { 223 return getSequence().previous(this); 224 } 225 } 226 227 public void setHe(final double he) { 228 this.he = he; 229 } 230 231 public void setLatLon(final LatLon latLon) { 232 if (latLon != null) { 233 this.latLon = latLon; 234 } 235 } 236 237 /** 238 * Sets the StreetsideSequence object which contains the StreetsideImage. 239 * 240 * @param sequence 241 * The StreetsideSequence that contains the StreetsideImage. 242 * @throws IllegalArgumentException 243 * if the image is not already part of the 244 * {@link StreetsideSequence}. Call 245 * {@link StreetsideSequence#add(StreetsideAbstractImage)} first. 246 */ 247 public void setSequence(final StreetsideSequence sequence) { 248 synchronized (this) { 249 if (sequence != null && !sequence.getImages().contains(this)) { 250 throw new IllegalArgumentException(); 251 } 252 this.sequence = sequence; 253 } 254 } 255 256 /** 257 * Set's whether the image should be visible on the map or not. 258 * 259 * @param visible 260 * true if the image is set to be visible; false otherwise. 261 */ 262 public void setVisible(final boolean visible) { 263 this.visible = visible; 264 } 265 266 /** 267 * Called when the mouse button is released, meaning that the picture has 268 * stopped being dragged, so the temporal values are saved. 269 */ 270 public void stopMoving() { 271 tempLatLon = movingLatLon; 272 tempHe = movingHe; 273 } 274 275 /** 276 * Turns the image direction. 277 * 278 * @param he 279 * The angle the image is moving. 280 */ 281 public void turn(final double he) { 282 movingHe = tempHe + he; 283 } 284 285 /** 15 /** 16 * If two values for field cd differ by less than EPSILON both values are 17 * considered equal. 18 */ 19 private static final float EPSILON = 1e-5f; 20 21 protected String id; 22 /** 23 * Position of the picture. 24 */ 25 protected LatLon latLon; 26 //Image id of previous image in sequence (decimal) 27 private long pr; 28 /** 29 * Direction of the picture in degrees from true north. 30 */ 31 protected double he; 32 /** 33 * When the object direction is being moved in the map, the temporal direction 34 * is stored here 35 */ 36 protected double movingHe; 37 // Image id of next image in sequence (decimal) 38 private long ne; 39 /** 40 * Sequence of pictures containing this object. 41 */ 42 private StreetsideSequence sequence; 43 /** 44 * Temporal position of the picture until it is uploaded. 45 */ 46 private LatLon tempLatLon; 47 /** 48 * When the object is being dragged in the map, the temporal position is stored 49 * here. 50 */ 51 private LatLon movingLatLon; 52 /** 53 * Temporal direction of the picture until it is uploaded 54 */ 55 private double tempHe; 56 /** 57 * Whether the image must be drown in the map or not 58 */ 59 private boolean visible; 60 61 /** 62 * Creates a new object in the given position and with the given direction. 63 * {@link LatLon} 64 * 65 * @param id - the Streetside image id 66 * @param latLon The latitude and longitude of the image. 67 * @param he The direction of the picture (0 means north im Mapillary 68 * camera direction is not yet supported in the Streetside plugin). 69 */ 70 protected StreetsideAbstractImage(final String id, final LatLon latLon, final double he) { 71 this.id = id; 72 this.latLon = latLon; 73 tempLatLon = this.latLon; 74 movingLatLon = this.latLon; 75 this.he = he; 76 tempHe = he; 77 movingHe = he; 78 visible = true; 79 } 80 81 /** 82 * Creates a new object with the given id. 83 * 84 * @param id - the image id (All images require ids in Streetside) 85 */ 86 protected StreetsideAbstractImage(final String id) { 87 this.id = id; 88 89 visible = true; 90 } 91 92 /** 93 * @return the id 94 */ 95 public String getId() { 96 return id; 97 } 98 99 /** 100 * @param id the id to set 101 */ 102 public void setId(String id) { 103 this.id = id; 104 } 105 106 /** 107 * Returns the original direction towards the image has been taken. 108 * 109 * @return The direction of the image (0 means north and goes clockwise). 110 */ 111 public double getHe() { 112 return he; 113 } 114 115 public void setHe(final double he) { 116 this.he = he; 117 } 118 119 /** 120 * Returns a LatLon object containing the original coordinates of the object. 121 * 122 * @return The LatLon object with the position of the object. 123 */ 124 public LatLon getLatLon() { 125 return latLon; 126 } 127 128 public void setLatLon(final LatLon latLon) { 129 if (latLon != null) { 130 this.latLon = latLon; 131 } 132 } 133 134 /** 135 * Returns the direction towards the image has been taken. 136 * 137 * @return The direction of the image (0 means north and goes clockwise). 138 */ 139 public double getMovingHe() { 140 return movingHe; 141 } 142 143 /** 144 * Returns a LatLon object containing the current coordinates of the object. 145 * When you are dragging the image this changes. 146 * 147 * @return The LatLon object with the position of the object. 148 */ 149 public LatLon getMovingLatLon() { 150 return movingLatLon; 151 } 152 153 /** 154 * Returns the sequence which contains this image. Never null. 155 * 156 * @return The StreetsideSequence object that contains this StreetsideImage. 157 */ 158 159 public StreetsideSequence getSequence() { 160 synchronized (this) { 161 if (sequence == null) { 162 sequence = new StreetsideSequence(); 163 sequence.add(this); 164 } 165 return sequence; 166 } 167 } 168 169 /** 170 * Sets the StreetsideSequence object which contains the StreetsideImage. 171 * 172 * @param sequence 173 * The StreetsideSequence that contains the StreetsideImage. 174 * @throws IllegalArgumentException 175 * if the image is not already part of the 176 * {@link StreetsideSequence}. Call 177 * {@link StreetsideSequence#add(StreetsideAbstractImage)} first. 178 */ 179 public void setSequence(final StreetsideSequence sequence) { 180 synchronized (this) { 181 if (sequence != null && !sequence.getImages().contains(this)) { 182 throw new IllegalArgumentException(); 183 } 184 this.sequence = sequence; 185 } 186 } 187 188 /** 189 * Returns the last fixed direction of the object. 190 * 191 * @return The last fixed direction of the object. 0 means north. 192 */ 193 public double getTempHe() { 194 return tempHe; 195 } 196 197 /** 198 * Returns the last fixed coordinates of the object. 199 * 200 * @return A LatLon object containing. 201 */ 202 public LatLon getTempLatLon() { 203 return tempLatLon; 204 } 205 206 /** 207 * Returns whether the object has been modified or not. 208 * 209 * @return true if the object has been modified; false otherwise. 210 */ 211 public boolean isModified() { 212 return !getMovingLatLon().equals(latLon) || Math.abs(getMovingHe() - he) > EPSILON; 213 } 214 215 /** 216 * Returns whether the image is visible on the map or not. 217 * 218 * @return True if the image is visible; false otherwise. 219 */ 220 public boolean isVisible() { 221 return visible; 222 } 223 224 /** 225 * Set's whether the image should be visible on the map or not. 226 * 227 * @param visible 228 * true if the image is set to be visible; false otherwise. 229 */ 230 public void setVisible(final boolean visible) { 231 this.visible = visible; 232 } 233 234 /** 235 * Moves the image temporally to another position 236 * 237 * @param x The movement of the image in longitude units. 238 * @param y The movement of the image in latitude units. 239 */ 240 public void move(final double x, final double y) { 241 movingLatLon = new LatLon(tempLatLon.getY() + y, tempLatLon.getX() + x); 242 } 243 244 /** 245 * If the StreetsideImage belongs to a StreetsideSequence, returns the next 246 * image in the sequence. 247 * 248 * @return The following StreetsideImage, or null if there is none. 249 */ 250 public StreetsideAbstractImage next() { 251 synchronized (this) { 252 return getSequence().next(this); 253 } 254 } 255 256 /** 257 * If the StreetsideImage belongs to a StreetsideSequence, returns the previous 258 * image in the sequence. 259 * 260 * @return The previous StreetsideImage, or null if there is none. 261 */ 262 public StreetsideAbstractImage previous() { 263 synchronized (this) { 264 return getSequence().previous(this); 265 } 266 } 267 268 /** 269 * Called when the mouse button is released, meaning that the picture has 270 * stopped being dragged, so the temporal values are saved. 271 */ 272 public void stopMoving() { 273 tempLatLon = movingLatLon; 274 tempHe = movingHe; 275 } 276 277 /** 278 * Turns the image direction. 279 * 280 * @param he 281 * The angle the image is moving. 282 */ 283 public void turn(final double he) { 284 movingHe = tempHe + he; 285 } 286 287 /** 286 288 * @return the ne 287 289 */ -
applications/editors/josm/plugins/MicrosoftStreetside/src/org/openstreetmap/josm/plugins/streetside/StreetsideCubemap.java
r34399 r36194 12 12 public class StreetsideCubemap extends StreetsideAbstractImage { 13 13 14 15 16 17 18 14 /** 15 * If two values for field cd differ by less than EPSILON both values are considered equal. 16 */ 17 @SuppressWarnings("unused") 18 private static final float EPSILON = 1e-5f; 19 19 20 /** 21 * Main constructor of the class StreetsideCubemap 22 * 23 * @param quadId 24 * The Streetside id of the base frontal image of the cubemap 25 * in quternary 26 * @param latLon 27 * The latitude and longitude where it is positioned. 28 * @param he 29 * The direction of the images in degrees, meaning 0 north (camera 30 * direction is not yet supported in the Streetside plugin). 31 */ 32 public StreetsideCubemap(String quadId, LatLon latLon, double he) { 33 super(quadId, latLon, he); 34 } 20 /** 21 * Main constructor of the class StreetsideCubemap 22 * 23 * @param quadId The Streetside id of the base frontal image of the cubemap 24 * in quternary 25 * @param latLon The latitude and longitude where it is positioned. 26 * @param he The direction of the images in degrees, meaning 0 north (camera 27 * direction is not yet supported in the Streetside plugin). 28 */ 29 public StreetsideCubemap(String quadId, LatLon latLon, double he) { 30 super(quadId, latLon, he); 31 } 35 32 36 37 38 39 40 *- a StreetsideAbstract image object41 42 *StreetsideCubemaps are considered equal if they are associated43 *with the same image id - only one cubemap may be displayed at a44 *time. If the image selection changes, the cubemap changes.45 46 47 48 49 50 51 52 return id.compareTo(((StreetsideImage) image).getId());53 54 55 33 /** 34 * Comparison method for the StreetsideCubemap object. 35 * 36 * @param image 37 * - a StreetsideAbstract image object 38 * 39 * StreetsideCubemaps are considered equal if they are associated 40 * with the same image id - only one cubemap may be displayed at a 41 * time. If the image selection changes, the cubemap changes. 42 * 43 * @return result of the hashcode comparison. 44 * @see org.openstreetmap.josm.plugins.streetside.StreetsideAbstractImage 45 */ 46 @Override 47 public int compareTo(StreetsideAbstractImage image) { 48 if (image instanceof StreetsideImage) { 49 return id.compareTo(image.getId()); 50 } 51 return hashCode() - image.hashCode(); 52 } 56 53 57 58 59 60 61 62 63 64 65 66 54 /** 55 * HashCode StreetsideCubemap object. 56 * 57 * @return int hashCode 58 * @see org.openstreetmap.josm.plugins.streetside.StreetsideAbstractImage 59 */ 60 @Override 61 public int hashCode() { 62 return id.hashCode(); 63 } 67 64 68 69 70 71 72 73 74 75 76 65 /** 66 * stops ImageDisplay WalkAction (not currently supported by Streetside) 67 * 68 * @see org.openstreetmap.josm.plugins.streetside.actions.StreetsideWalkAction 69 */ 70 @Override 71 public void stopMoving() { 72 super.stopMoving(); 73 } 77 74 78 79 80 81 82 83 84 85 86 87 88 75 /** 76 * turns ImageDisplay WalkAction (not currently supported by Streetside) 77 * 78 * @param he - the direction the camera is facing (heading) 79 * 80 * @see org.openstreetmap.josm.plugins.streetside.actions.StreetsideWalkAction 81 */ 82 @Override 83 public void turn(double he) { 84 super.turn(he); 85 } 89 86 90 91 92 93 94 95 96 return StreetsideProperties.SHOW_HIGH_RES_STREETSIDE_IMAGERY.get().booleanValue()?1016:510;97 87 /** 88 * @return the height of an assembled cubemap face for 16-tiled or 4-tiled imagery 89 * 90 * @see org.openstreetmap.josm.plugins.streetside.actions.StreetsideWalkAction 91 */ 92 public int getHeight() { 93 return Boolean.TRUE.equals(StreetsideProperties.SHOW_HIGH_RES_STREETSIDE_IMAGERY.get()) ? 1016 : 510; 94 } 98 95 99 96 } -
applications/editors/josm/plugins/MicrosoftStreetside/src/org/openstreetmap/josm/plugins/streetside/StreetsideData.java
r35601 r36194 37 37 private final Set<StreetsideAbstractImage> images = ConcurrentHashMap.newKeySet(); 38 38 /** 39 * All the images selected, can be more than one. 40 */ 41 private final Set<StreetsideAbstractImage> multiSelectedImages = ConcurrentHashMap.newKeySet(); 42 /** 43 * Listeners of the class. 44 */ 45 private final List<StreetsideDataListener> listeners = new CopyOnWriteArrayList<>(); 46 /** 47 * The bounds of the areas for which the pictures have been downloaded. 48 */ 49 private final List<Bounds> bounds; 50 /** 39 51 * The image currently selected, this is the one being shown. 40 52 */ … … 44 56 */ 45 57 private StreetsideAbstractImage highlightedImage; 46 /**47 * All the images selected, can be more than one.48 */49 private final Set<StreetsideAbstractImage> multiSelectedImages = ConcurrentHashMap.newKeySet();50 /**51 * Listeners of the class.52 */53 private final List<StreetsideDataListener> listeners = new CopyOnWriteArrayList<>();54 /**55 * The bounds of the areas for which the pictures have been downloaded.56 */57 private final List<Bounds> bounds;58 58 59 59 /** … … 64 64 bounds = new CopyOnWriteArrayList<>(); 65 65 66 // Adds the basic set of listeners. 67 Arrays.stream(StreetsidePlugin.getStreetsideDataListeners()).forEach(this::addListener); 68 addListener(StreetsideViewerDialog.getInstance().getStreetsideViewerPanel()); 69 addListener(StreetsideMainDialog.getInstance()); 70 addListener(ImageInfoPanel.getInstance()); 66 // Adds the basic set of listeners. 67 Arrays.stream(StreetsidePlugin.getStreetsideDataListeners()).forEach(this::addListener); 68 addListener(StreetsideViewerDialog.getInstance().getStreetsideViewerPanel()); 69 addListener(StreetsideMainDialog.getInstance()); 70 addListener(ImageInfoPanel.getInstance()); 71 } 72 73 /** 74 * Downloads surrounding images of this mapillary image in background threads 75 * 76 * @param streetsideImage the image for which the surrounding images should be downloaded 77 */ 78 private static void downloadSurroundingImages(StreetsideImage streetsideImage) { 79 MainApplication.worker.execute(() -> { 80 final int prefetchCount = StreetsideProperties.PRE_FETCH_IMAGE_COUNT.get(); 81 CacheAccess<String, BufferedImageCacheEntry> imageCache = Caches.ImageCache.getInstance().getCache(); 82 83 StreetsideAbstractImage nextImage = streetsideImage.next(); 84 StreetsideAbstractImage prevImage = streetsideImage.previous(); 85 86 for (int i = 0; i < prefetchCount; i++) { 87 if (nextImage != null) { 88 if (nextImage instanceof StreetsideImage && imageCache.get(nextImage.getId()) == null) { 89 CacheUtils.downloadPicture((StreetsideImage) nextImage); 90 } 91 nextImage = nextImage.next(); 92 } 93 if (prevImage != null) { 94 if (prevImage instanceof StreetsideImage && imageCache.get(prevImage.getId()) == null) { 95 CacheUtils.downloadPicture((StreetsideImage) prevImage); 96 } 97 prevImage = prevImage.previous(); 98 } 99 } 100 }); 101 } 102 103 /** 104 * Downloads surrounding images of this mapillary image in background threads 105 * 106 * @param streetsideImage the image for which the surrounding images should be downloaded 107 */ 108 public static void downloadSurroundingCubemaps(StreetsideImage streetsideImage) { 109 MainApplication.worker.execute(() -> { 110 final int prefetchCount = StreetsideProperties.PRE_FETCH_IMAGE_COUNT.get(); 111 CacheAccess<String, BufferedImageCacheEntry> imageCache = Caches.ImageCache.getInstance().getCache(); 112 113 StreetsideAbstractImage nextImage = streetsideImage.next(); 114 StreetsideAbstractImage prevImage = streetsideImage.previous(); 115 116 for (int i = 0; i < prefetchCount; i++) { 117 if (nextImage != null) { 118 if (nextImage instanceof StreetsideImage && imageCache.get(nextImage.getId()) == null) { 119 CacheUtils.downloadCubemap((StreetsideImage) nextImage); 120 } 121 nextImage = nextImage.next(); 122 } 123 if (prevImage != null) { 124 if (prevImage instanceof StreetsideImage && imageCache.get(prevImage.getId()) == null) { 125 CacheUtils.downloadCubemap((StreetsideImage) prevImage); 126 } 127 prevImage = prevImage.previous(); 128 } 129 } 130 }); 71 131 } 72 132 … … 86 146 * @param image The image to be added. 87 147 * @param update Whether the map must be updated or not 88 * (updates are currently unsupported by Streetside).148 * (updates are currently unsupported by Streetside). 89 149 */ 90 150 public void add(StreetsideAbstractImage image, boolean update) { 91 92 93 94 95 151 images.add(image); 152 if (update) { 153 StreetsideLayer.invalidateInstance(); 154 } 155 fireImagesAdded(); 96 156 } 97 157 … … 109 169 * 110 170 * @param newImages The set of images to be added. 111 * @param update Whether the map must be updated or not.171 * @param update Whether the map must be updated or not. 112 172 */ 113 173 public void addAll(Collection<? extends StreetsideAbstractImage> newImages, boolean update) { … … 119 179 } 120 180 121 /**181 /** 122 182 * Adds a new listener. 123 183 * … … 176 236 177 237 /** 238 * Returns the image under the mouse cursor. 239 * 240 * @return The image under the mouse cursor. 241 */ 242 public StreetsideAbstractImage getHighlightedImage() { 243 return highlightedImage; 244 } 245 246 /** 178 247 * Highlights the image under the cursor. 179 248 * … … 185 254 186 255 /** 187 * Returns the image under the mouse cursor.188 *189 * @return The image under the mouse cursor.190 */191 public StreetsideAbstractImage getHighlightedImage() {192 return highlightedImage;193 }194 195 /**196 256 * Returns a Set containing all images. 197 257 * … … 203 263 204 264 /** 265 * Sets a new {@link Collection} object as the used set of images. 266 * Any images that are already present, are removed. 267 * 268 * @param newImages the new image list (previously set images are completely replaced) 269 */ 270 public void setImages(Collection<StreetsideAbstractImage> newImages) { 271 synchronized (this) { 272 images.clear(); 273 images.addAll(newImages); 274 } 275 } 276 277 /** 205 278 * Returns a Set of all sequences, that the images are part of. 279 * 206 280 * @return all sequences that are contained in the Streetside data 207 281 */ … … 217 291 public StreetsideAbstractImage getSelectedImage() { 218 292 return selectedImage; 293 } 294 295 /** 296 * Selects a new image.If the user does ctrl + click, this isn't triggered. 297 * 298 * @param image The StreetsideImage which is going to be selected 299 */ 300 public void setSelectedImage(StreetsideAbstractImage image) { 301 setSelectedImage(image, false); 219 302 } 220 303 … … 229 312 * 230 313 * @throws IllegalStateException if the selected image is null or the selected image doesn't 231 * 314 * belong to a sequence. 232 315 */ 233 316 public void selectNext() { … … 242 325 * @param moveToPicture True if the view must me moved to the next picture. 243 326 * @throws IllegalStateException if the selected image is null or the selected image doesn't 244 * 327 * belong to a sequence. 245 328 */ 246 329 public void selectNext(boolean moveToPicture) { … … 263 346 * 264 347 * @throws IllegalStateException if the selected image is null or the selected image doesn't 265 * 348 * belong to a sequence. 266 349 */ 267 350 public void selectPrevious() { … … 277 360 * @param moveToPicture True if the view must me moved to the previous picture. 278 361 * @throws IllegalStateException if the selected image is null or the selected image doesn't 279 * 362 * belong to a sequence. 280 363 */ 281 364 public void selectPrevious(boolean moveToPicture) { … … 290 373 } 291 374 } 292 }293 294 /**295 * Selects a new image.If the user does ctrl + click, this isn't triggered.296 *297 * @param image The StreetsideImage which is going to be selected298 */299 public void setSelectedImage(StreetsideAbstractImage image) {300 setSelectedImage(image, false);301 375 } 302 376 … … 329 403 } 330 404 331 /**332 * Downloads surrounding images of this mapillary image in background threads333 * @param streetsideImage the image for which the surrounding images should be downloaded334 */335 private static void downloadSurroundingImages (StreetsideImage streetsideImage) {336 MainApplication.worker.execute(() -> {337 final int prefetchCount = StreetsideProperties.PRE_FETCH_IMAGE_COUNT.get();338 CacheAccess <String, BufferedImageCacheEntry> imageCache = Caches.ImageCache.getInstance().getCache();339 340 StreetsideAbstractImage nextImage = streetsideImage.next();341 StreetsideAbstractImage prevImage = streetsideImage.previous();342 343 for (int i = 0; i < prefetchCount; i++) {344 if (nextImage != null) {345 if (nextImage instanceof StreetsideImage &&346 imageCache.get(((StreetsideImage) nextImage).getId()) == null) {347 CacheUtils.downloadPicture((StreetsideImage) nextImage);348 }349 nextImage = nextImage.next();350 }351 if (prevImage != null) {352 if (prevImage instanceof StreetsideImage &&353 imageCache.get(((StreetsideImage) prevImage).getId()) == null) {354 CacheUtils.downloadPicture((StreetsideImage) prevImage);355 }356 prevImage = prevImage.previous();357 }358 }359 });360 }361 362 /**363 * Downloads surrounding images of this mapillary image in background threads364 * @param streetsideImage the image for which the surrounding images should be downloaded365 */366 public static void downloadSurroundingCubemaps(StreetsideImage streetsideImage) {367 MainApplication.worker.execute(() -> {368 final int prefetchCount = StreetsideProperties.PRE_FETCH_IMAGE_COUNT.get();369 CacheAccess<String, BufferedImageCacheEntry> imageCache = Caches.ImageCache.getInstance().getCache();370 371 StreetsideAbstractImage nextImage = streetsideImage.next();372 StreetsideAbstractImage prevImage = streetsideImage.previous();373 374 for (int i = 0; i < prefetchCount; i++) {375 if (nextImage != null) {376 if (nextImage instanceof StreetsideImage && imageCache.get(((StreetsideImage) nextImage).getId()) == null) {377 CacheUtils.downloadCubemap((StreetsideImage) nextImage);378 }379 nextImage = nextImage.next();380 }381 if (prevImage != null) {382 if (prevImage instanceof StreetsideImage && imageCache.get(((StreetsideImage) prevImage).getId()) == null) {383 CacheUtils.downloadCubemap((StreetsideImage) prevImage);384 }385 prevImage = prevImage.previous();386 }387 }388 });389 }390 391 405 private void fireSelectedImageChanged(StreetsideAbstractImage oldImage, StreetsideAbstractImage newImage) { 392 406 listeners.stream().filter(Objects::nonNull).forEach(lis -> lis.selectedImageChanged(oldImage, newImage)); 393 407 } 394 408 … … 403 417 } 404 418 405 /**406 * Sets a new {@link Collection} object as the used set of images.407 * Any images that are already present, are removed.408 *409 * @param newImages the new image list (previously set images are completely replaced)410 */411 public void setImages(Collection<StreetsideAbstractImage> newImages) {412 synchronized (this) {413 images.clear();414 images.addAll(newImages);415 }416 }417 418 419 @Override 419 420 public Collection<DataSource> getDataSources() { 420 421 return Collections.emptyList(); 421 422 } 422 423 } -
applications/editors/josm/plugins/MicrosoftStreetside/src/org/openstreetmap/josm/plugins/streetside/StreetsideDataListener.java
r34317 r36194 19 19 * manually clicking on the icon. 20 20 * 21 * @param oldImage 22 * Old selected {@link StreetsideAbstractImage} 23 * @param newImage 24 * New selected {@link StreetsideAbstractImage} 21 * @param oldImage Old selected {@link StreetsideAbstractImage} 22 * @param newImage New selected {@link StreetsideAbstractImage} 25 23 */ 26 void selectedImageChanged(StreetsideAbstractImage oldImage, 27 StreetsideAbstractImage newImage); 24 void selectedImageChanged(StreetsideAbstractImage oldImage, StreetsideAbstractImage newImage); 28 25 } -
applications/editors/josm/plugins/MicrosoftStreetside/src/org/openstreetmap/josm/plugins/streetside/StreetsideImage.java
r34429 r36194 18 18 */ 19 19 public class StreetsideImage extends StreetsideAbstractImage { 20 /**21 * Rn is a Bing Streetside image attribute - currently not22 * used, mapped or supported in the Streetside plugin -23 * left out initially because it's an unrequired complex object.24 */25 public static class Rn {26 // placeholder for Rn attribute (undocumented streetside complex inner type)27 }28 29 20 // latitude of the Streetside image 30 21 private double la; 31 32 22 //longitude of the Streetside image 33 23 private double lo; 34 35 24 // The bubble altitude, in meters above the WGS84 ellipsoid 36 25 private double al; 37 38 26 // Roll 39 27 private double ro; 40 41 28 // Pitch 42 29 private double pi; 43 44 30 // Blurring instructions - not currently used by the plugin 45 31 private String bl; 46 47 32 // Undocumented Attributes 48 33 private int ml; … … 55 40 * Main constructor of the class StreetsideImage 56 41 * 57 * @param id 42 * @param id The unique identifier of the image. 58 43 * @param latLon The latitude and longitude where it is positioned. 59 * @param he 44 * @param he The direction of the images in degrees, meaning 0 north. 60 45 */ 61 46 public StreetsideImage(String id, LatLon latLon, double he) { … … 64 49 65 50 public StreetsideImage(String id, double la, double lo) { 66 super(id, new LatLon(la, lo), 0.0);51 super(id, new LatLon(la, lo), 0.0); 67 52 } 68 53 69 54 public StreetsideImage(String id) { 70 55 super(id); 71 56 } 72 57 … … 82 67 */ 83 68 @Override 84 public String getId() {69 public String getId() { 85 70 return String.valueOf(id); 86 71 } 87 72 73 /** 74 * @param id the id to set 75 */ 76 @Override 77 public void setId(String id) { 78 this.id = id; 79 } 80 88 81 public UserProfile getUser() { 89 82 return getSequence().getUser(); 90 83 } 91 84 92 85 @Override 93 86 public String toString() { 94 return String.format( 95 "Image[id=%s,lat=%f,lon=%f,he=%f,user=%s]", 96 id, latLon.lat(), latLon.lon(), he, "null"//, cd 87 return String.format("Image[id=%s,lat=%f,lon=%f,he=%f,user=%s]", id, latLon.lat(), latLon.lon(), he, "null"//, cd 97 88 ); 98 89 } … … 106 97 public int compareTo(StreetsideAbstractImage image) { 107 98 if (image instanceof StreetsideImage) { 108 return id.compareTo( ((StreetsideImage) image).getId());99 return id.compareTo(image.getId()); 109 100 } 110 101 return hashCode() - image.hashCode(); … … 273 264 274 265 /** 275 * @param id the id to set276 */277 @Override278 public void setId(String id) {279 this.id = id;280 }281 282 /**283 266 * @return the rn 284 267 */ … … 293 276 this.rn = rn; 294 277 } 278 279 /** 280 * Rn is a Bing Streetside image attribute - currently not 281 * used, mapped or supported in the Streetside plugin - 282 * left out initially because it's an unrequired complex object. 283 */ 284 public static class Rn { 285 // placeholder for Rn attribute (undocumented streetside complex inner type) 286 } 295 287 } -
applications/editors/josm/plugins/MicrosoftStreetside/src/org/openstreetmap/josm/plugins/streetside/StreetsideLayer.java
r35978 r36194 17 17 import java.util.IntSummaryStatistics; 18 18 import java.util.Optional; 19 import java.util.logging.Logger; 19 20 20 21 import javax.swing.Action; 21 22 import javax.swing.Icon; 22 23 23 import org.apache.log4j.Logger;24 24 import org.openstreetmap.josm.data.Bounds; 25 25 import org.openstreetmap.josm.data.coor.ILatLon; … … 50 50 import org.openstreetmap.josm.tools.I18n; 51 51 import org.openstreetmap.josm.tools.ImageProvider.ImageSizes; 52 import org.openstreetmap.josm.tools.Logging; 52 53 53 54 /** … … 57 58 * @author nokutu 58 59 */ 59 public final class StreetsideLayer extends AbstractModifiableLayer implements 60 ActiveLayerChangeListener, StreetsideDataListener { 61 62 final static Logger logger = Logger.getLogger(StreetsideLayer.class); 63 64 /** The radius of the image marker */ 60 public final class StreetsideLayer extends AbstractModifiableLayer 61 implements ActiveLayerChangeListener, StreetsideDataListener { 62 63 private static final Logger LOGGER = Logger.getLogger(StreetsideLayer.class.getCanonicalName()); 64 65 /** 66 * The radius of the image marker 67 */ 65 68 private static final int IMG_MARKER_RADIUS = 7; 66 /** The radius of the circular sector that indicates the camera angle */ 69 /** 70 * The radius of the circular sector that indicates the camera angle 71 */ 67 72 private static final int CA_INDICATOR_RADIUS = 15; 68 /** The angle of the circular sector that indicates the camera angle */ 73 /** 74 * The angle of the circular sector that indicates the camera angle 75 */ 69 76 private static final int CA_INDICATOR_ANGLE = 40; 70 71 private static final DataSetListenerAdapter DATASET_LISTENER = 72 new DataSetListenerAdapter(e -> { 73 if (e instanceof DataChangedEvent && StreetsideDownloader.getMode() == DOWNLOAD_MODE.OSM_AREA) { 74 // When more data is downloaded, a delayed update is thrown, in order to 75 // wait for the data bounds to be set. 76 MainApplication.worker.execute(StreetsideDownloader::downloadOSMArea); 77 } 78 }); 79 80 /** Unique instance of the class. */ 81 private static StreetsideLayer instance; 82 /** The nearest images to the selected image from different sequences sorted by distance from selection. */ 83 private StreetsideImage[] nearestImages = {}; 84 /** {@link StreetsideData} object that stores the database. */ 85 private final StreetsideData data; 86 87 /** Mode of the layer. */ 88 public AbstractMode mode; 89 90 private volatile TexturePaint hatched; 91 92 private StreetsideLayer() { 93 super(I18n.tr("Microsoft Streetside Images")); 94 data = new StreetsideData(); 95 data.addListener(this); 96 } 77 /** 78 * Unique instance of the class. 79 */ 80 private static StreetsideLayer instance; 81 private static final DataSetListenerAdapter DATASET_LISTENER = new DataSetListenerAdapter(e -> { 82 if (e instanceof DataChangedEvent && StreetsideDownloader.getMode() == DOWNLOAD_MODE.OSM_AREA) { 83 // When more data is downloaded, a delayed update is thrown, in order to 84 // wait for the data bounds to be set. 85 MainApplication.worker.execute(StreetsideDownloader::downloadOSMArea); 86 } 87 }); 88 /** 89 * {@link StreetsideData} object that stores the database. 90 */ 91 private final StreetsideData data; 92 /** 93 * Mode of the layer. 94 */ 95 public AbstractMode mode; 96 /** 97 * The nearest images to the selected image from different sequences sorted by distance from selection. 98 */ 99 private StreetsideImage[] nearestImages = {}; 100 private volatile TexturePaint hatched; 101 102 private StreetsideLayer() { 103 super(I18n.tr("Microsoft Streetside Images")); 104 data = new StreetsideData(); 105 data.addListener(this); 106 } 107 108 public static void invalidateInstance() { 109 if (hasInstance()) { 110 getInstance().invalidate(); 111 } 112 } 113 114 private static synchronized void clearInstance() { 115 instance = null; 116 } 117 118 /** 119 * Returns the unique instance of this class. 120 * 121 * @return The unique instance of this class. 122 */ 123 public static synchronized StreetsideLayer getInstance() { 124 if (instance != null) { 125 return instance; 126 } 127 final StreetsideLayer layer = new StreetsideLayer(); 128 layer.init(); 129 instance = layer; // Only set instance field after initialization is complete 130 return instance; 131 } 132 133 /** 134 * @return if the unique instance of this layer is currently instantiated 135 */ 136 public static boolean hasInstance() { 137 return instance != null; 138 } 97 139 98 140 /** … … 120 162 if (StreetsidePlugin.getMapView() != null) { 121 163 StreetsideMainDialog.getInstance().streetsideImageDisplay.repaint(); 122 } 123 createHatchTexture(); 124 invalidate(); 125 } 126 127 public static void invalidateInstance() { 128 if (hasInstance()) { 129 getInstance().invalidate(); 130 } 164 } 165 createHatchTexture(); 166 invalidate(); 131 167 } 132 168 … … 153 189 } 154 190 155 private static synchronized void clearInstance() { 156 instance = null; 157 } 158 159 /** 160 * Returns the unique instance of this class. 191 /** 192 * Returns the {@link StreetsideData} object, which acts as the database of the 193 * Layer. 161 194 * 162 * @return The unique instance of this class. 163 */ 164 public static synchronized StreetsideLayer getInstance() { 165 if (instance != null) { 166 return instance; 167 } 168 final StreetsideLayer layer = new StreetsideLayer(); 169 layer.init(); 170 instance = layer; // Only set instance field after initialization is complete 171 return instance; 172 } 173 174 /** 175 * @return if the unique instance of this layer is currently instantiated 176 */ 177 public static boolean hasInstance() { 178 return instance != null; 179 } 180 181 /** 182 * Returns the {@link StreetsideData} object, which acts as the database of the 183 * Layer. 184 * 185 * @return The {@link StreetsideData} object that stores the database. 186 */ 187 @Override 188 public StreetsideData getData() { 189 return data; 190 } 195 * @return The {@link StreetsideData} object that stores the database. 196 */ 197 @Override 198 public StreetsideData getData() { 199 return data; 200 } 191 201 192 202 /** … … 194 204 * The "n-nearest image" is picked from the list of one image from every sequence that is nearest to the currently 195 205 * selected image, excluding the sequence to which the selected image belongs. 206 * 196 207 * @param n the index for picking from the list of "nearest images", beginning from 1 197 208 * @return the n-nearest image to the currently selected image … … 223 234 } 224 235 } catch (IllegalArgumentException e) { 236 Logging.trace(e); 225 237 // TODO: It would be ideal, to fix this properly. But for the moment let's catch this, for when a listener has already been removed. 226 238 } … … 228 240 } 229 241 230 231 @Override 242 @Override 232 243 public boolean isModified() { 233 244 return data.getImages().parallelStream().anyMatch(StreetsideAbstractImage::isModified); … … 289 300 for (StreetsideSequence seq : getData().getSequences()) { 290 301 if (seq.getImages().contains(selectedImage)) { 291 292 293 302 g.setColor( 303 seq.getId() == null ? StreetsideColorScheme.SEQ_IMPORTED_SELECTED : StreetsideColorScheme.SEQ_SELECTED 304 ); 294 305 } else { 295 296 297 306 g.setColor( 307 seq.getId() == null ? StreetsideColorScheme.SEQ_IMPORTED_UNSELECTED : StreetsideColorScheme.SEQ_UNSELECTED 308 ); 298 309 } 299 310 g.draw(MapViewGeometryUtil.getSequencePath(mv, seq)); … … 308 319 /** 309 320 * Draws an image marker onto the given Graphics context. 310 * @param g the Graphics context 321 * 322 * @param g the Graphics context 311 323 * @param img the image to be drawn onto the Graphics context 312 324 */ 313 325 private void drawImageMarker(final Graphics2D g, final StreetsideAbstractImage img) { 314 326 if (img == null || img.getLatLon() == null) { 315 logger.warn("An image is not painted, because it is null or has no LatLon!");327 LOGGER.warning("An image is not painted, because it is null or has no LatLon!"); 316 328 return; 317 329 } … … 325 337 markerC = StreetsideColorScheme.SEQ_HIGHLIGHTED; 326 338 directionC = StreetsideColorScheme.SEQ_HIGHLIGHTED_CA; 327 } else if (selectedImg != null && selectedImg.getSequence() != null && selectedImg.getSequence().equals(img.getSequence())) { 339 } else if (selectedImg != null && selectedImg.getSequence() != null 340 && selectedImg.getSequence().equals(img.getSequence())) { 328 341 markerC = StreetsideColorScheme.SEQ_SELECTED; 329 342 directionC = StreetsideColorScheme.SEQ_SELECTED_CA; … … 336 349 float alpha = 0.75f; 337 350 int type = AlphaComposite.SRC_OVER; 338 AlphaComposite composite = 339 AlphaComposite.getInstance(type, alpha); 351 AlphaComposite composite = AlphaComposite.getInstance(type, alpha); 340 352 g.setComposite(composite); 341 353 g.setColor(directionC); 342 g.fillArc(p.x - CA_INDICATOR_RADIUS, p.y - CA_INDICATOR_RADIUS, 2 * CA_INDICATOR_RADIUS, 2 * CA_INDICATOR_RADIUS, (int) (90 - /*img.getMovingHe()*/img.getHe() - CA_INDICATOR_ANGLE / 2d), CA_INDICATOR_ANGLE); 354 g.fillArc(p.x - CA_INDICATOR_RADIUS, p.y - CA_INDICATOR_RADIUS, 2 * CA_INDICATOR_RADIUS, 355 2 * CA_INDICATOR_RADIUS, (int) (90 - /*img.getMovingHe()*/img.getHe() - CA_INDICATOR_ANGLE / 2d), 356 CA_INDICATOR_ANGLE); 343 357 // Paint image marker 344 358 g.setColor(markerC); … … 351 365 g.drawOval(p.x - IMG_MARKER_RADIUS, p.y - IMG_MARKER_RADIUS, 2 * IMG_MARKER_RADIUS, 2 * IMG_MARKER_RADIUS); 352 366 } 353 367 } 354 368 355 369 @Override … … 365 379 @Override 366 380 public void mergeFrom(Layer from) { 367 throw new UnsupportedOperationException( 368 "This layer does not support merging yet"); 381 throw new UnsupportedOperationException("This layer does not support merging yet"); 369 382 } 370 383 371 384 @Override 372 385 public Action[] getMenuEntries() { 373 return new Action[]{ 374 LayerListDialog.getInstance().createShowHideLayerAction(), 375 LayerListDialog.getInstance().createDeleteLayerAction(), 376 new LayerListPopup.InfoAction(this) 377 }; 386 return new Action[] { LayerListDialog.getInstance().createShowHideLayerAction(), 387 LayerListDialog.getInstance().createDeleteLayerAction(), new LayerListPopup.InfoAction(this) }; 378 388 } 379 389 380 390 @Override 381 391 public Object getInfoComponent() { 382 IntSummaryStatistics seqSizeStats = getData().getSequences().stream().mapToInt(seq -> seq.getImages().size()).summaryStatistics(); 383 return new StringBuilder(I18n.tr("Streetside layer")) 384 .append('\n') 385 .append(I18n.tr( 386 "{0} sequences, each containing between {1} and {2} images (ø {3})", 387 getData().getSequences().size(), 388 seqSizeStats.getCount() <= 0 ? 0 : seqSizeStats.getMin(), 389 seqSizeStats.getCount() <= 0 ? 0 : seqSizeStats.getMax(), 390 seqSizeStats.getAverage() 391 )) 392 .append("\n\n") 393 .append("\n+ ") 394 .append(I18n.tr( 395 "{0} downloaded images", 396 getData().getImages().stream().filter(i -> i instanceof StreetsideImage).count() 397 )) 398 .append("\n= ") 399 .append(I18n.tr( 400 "{0} images in total", 401 getData().getImages().size() 402 )).toString(); 392 IntSummaryStatistics seqSizeStats = getData().getSequences().stream().mapToInt(seq -> seq.getImages().size()) 393 .summaryStatistics(); 394 return I18n.tr("Streetside layer") + '\n' 395 + I18n.tr("{0} sequences, each containing between {1} and {2} images (ø {3})", 396 getData().getSequences().size(), seqSizeStats.getCount() <= 0 ? 0 : seqSizeStats.getMin(), 397 seqSizeStats.getCount() <= 0 ? 0 : seqSizeStats.getMax(), seqSizeStats.getAverage()) 398 + "\n\n" + "\n+ " 399 + I18n.tr("{0} downloaded images", 400 getData().getImages().stream().filter(i -> i instanceof StreetsideImage).count()) 401 + "\n= " + I18n.tr("{0} images in total", getData().getImages().size()); 403 402 } 404 403 … … 449 448 * 450 449 * @param target the image for which you want to find the nearest other images 451 * @param limit the maximum length of the returned array450 * @param limit the maximum length of the returned array 452 451 * @return An array containing the closest images belonging to different sequences sorted by distance from target. 453 452 */ 454 453 private StreetsideImage[] getNearestImagesFromDifferentSequences(StreetsideAbstractImage target, int limit) { 455 454 return data.getSequences().parallelStream() 456 .filter(seq -> seq.getId() != null && !seq.getId().equals(target.getSequence().getId())) 457 .map(seq -> { // Maps sequence to image from sequence that is nearest to target 458 Optional<StreetsideAbstractImage> resImg = seq.getImages().parallelStream() 459 .filter(img -> img instanceof StreetsideImage && img.isVisible()) 460 .min(new NearestImgToTargetComparator(target)); 461 return resImg.orElse(null); 462 }) 463 .filter(img -> // Filters out images too far away from target 464 img != null && 465 img.getMovingLatLon().greatCircleDistance((ILatLon) target.getMovingLatLon()) 466 < StreetsideProperties.SEQUENCE_MAX_JUMP_DISTANCE.get() 467 ) 468 .sorted(new NearestImgToTargetComparator(target)) 469 .limit(limit) 470 .toArray(StreetsideImage[]::new); 455 .filter(seq -> seq.getId() != null && !seq.getId().equals(target.getSequence().getId())).map(seq -> { // Maps sequence to image from sequence that is nearest to target 456 Optional<StreetsideAbstractImage> resImg = seq.getImages().parallelStream() 457 .filter(img -> img instanceof StreetsideImage && img.isVisible()) 458 .min(new NearestImgToTargetComparator(target)); 459 return resImg.orElse(null); 460 }).filter(img -> // Filters out images too far away from target 461 img != null && img.getMovingLatLon().greatCircleDistance( 462 (ILatLon) target.getMovingLatLon()) < StreetsideProperties.SEQUENCE_MAX_JUMP_DISTANCE.get()) 463 .sorted(new NearestImgToTargetComparator(target)).limit(limit).toArray(StreetsideImage[]::new); 471 464 } 472 465 … … 496 489 this.target = target; 497 490 } 491 498 492 /* (non-Javadoc) 499 493 * @see java.util.Comparator#compare(java.lang.Object, java.lang.Object) … … 501 495 @Override 502 496 public int compare(StreetsideAbstractImage img1, StreetsideAbstractImage img2) { 503 return (int) Math.signum( 504 img1.getMovingLatLon().greatCircleDistance((ILatLon) target.getMovingLatLon()) - 505 img2.getMovingLatLon().greatCircleDistance((ILatLon) target.getMovingLatLon()) 506 ); 507 } 508 } 497 return (int) Math.signum(img1.getMovingLatLon().greatCircleDistance((ILatLon) target.getMovingLatLon()) 498 - img2.getMovingLatLon().greatCircleDistance((ILatLon) target.getMovingLatLon())); 499 } 500 } 501 509 502 } -
applications/editors/josm/plugins/MicrosoftStreetside/src/org/openstreetmap/josm/plugins/streetside/StreetsidePlugin.java
r36065 r36194 31 31 public static final ImageProvider LOGO = new ImageProvider("streetside-logo"); 32 32 33 /** Zoom action */ 33 /** 34 * Zoom action 35 */ 34 36 private static final StreetsideZoomAction ZOOM_ACTION = new StreetsideZoomAction(); 35 /** Walk action */ 37 /** 38 * Walk action 39 */ 36 40 private static final StreetsideWalkAction WALK_ACTION = new StreetsideWalkAction(); 37 41 … … 39 43 * Main constructor. 40 44 * 41 * @param info 42 * Required information of the plugin. Obtained from the jar file. 45 * @param info Required information of the plugin. Obtained from the jar file. 43 46 */ 44 47 public StreetsidePlugin(PluginInformation info) { … … 56 59 57 60 static StreetsideDataListener[] getStreetsideDataListeners() { 58 return new StreetsideDataListener[]{WALK_ACTION, ZOOM_ACTION, CubemapBuilder.getInstance()};61 return new StreetsideDataListener[] { WALK_ACTION, ZOOM_ACTION, CubemapBuilder.getInstance() }; 59 62 } 60 61 63 62 64 /** … … 65 67 public static StreetsideWalkAction getStreetsideWalkAction() { 66 68 return WALK_ACTION; 69 } 70 71 /** 72 * @return the current {@link MapView} without throwing a {@link NullPointerException} 73 */ 74 public static MapView getMapView() { 75 final MapFrame mf = MainApplication.getMap(); 76 if (mf != null) { 77 return mf.mapView; 78 } 79 return null; 67 80 } 68 81 … … 75 88 MainApplication.getMap().addToggleDialog(StreetsideMainDialog.getInstance(), false); 76 89 StreetsideMainDialog.getInstance().setImageInfoHelp(new ImageInfoHelpPopup( 77 MainApplication.getMap().addToggleDialog(ImageInfoPanel.getInstance(), false) 78 )); 90 MainApplication.getMap().addToggleDialog(ImageInfoPanel.getInstance(), false))); 79 91 MainApplication.getMap().addToggleDialog(StreetsideViewerDialog.getInstance(), false); 80 92 } … … 91 103 return new StreetsidePreferenceSetting(); 92 104 } 93 94 /**95 * @return the current {@link MapView} without throwing a {@link NullPointerException}96 */97 public static MapView getMapView() {98 final MapFrame mf = MainApplication.getMap();99 if (mf != null) {100 return mf.mapView;101 }102 return null;103 }104 105 } -
applications/editors/josm/plugins/MicrosoftStreetside/src/org/openstreetmap/josm/plugins/streetside/StreetsideSequence.java
r34399 r36194 17 17 public class StreetsideSequence { 18 18 19 19 /** 20 * The images in the sequence. 21 */ 22 private final List<StreetsideAbstractImage> images; 20 23 /** 21 24 * Unique identifier. Used only for {@link StreetsideImage} sequences. … … 23 26 private String id; 24 27 private UserProfile user; 25 26 28 private double la; 27 29 private double lo; 28 29 30 /** 30 31 * Epoch time when the sequence was created … … 32 33 private long cd; 33 34 34 /**35 * The images in the sequence.36 */37 private List<StreetsideAbstractImage> images;38 39 35 public StreetsideSequence(String id, Long ca) { 40 36 this.id = id; 41 37 cd = ca; 42 38 images = new CopyOnWriteArrayList<>(); … … 54 50 */ 55 51 public StreetsideSequence() { 56 52 images = new CopyOnWriteArrayList<>(); 57 53 } 58 54 59 55 public StreetsideSequence(String id, double la, double lo, long ca) { 60 61 62 63 64 65 }66 67 public StreetsideSequence(String id) {68 69 70 }56 this.id = id; 57 this.la = la; 58 this.lo = lo; 59 cd = ca; 60 images = new CopyOnWriteArrayList<>(); 61 } 62 63 public StreetsideSequence(String id) { 64 this.id = id; 65 images = new CopyOnWriteArrayList<>(); 66 } 71 67 72 68 /** … … 95 91 * 96 92 * @param image The {@link StreetsideAbstractImage} object whose next image is 97 * going to be returned. 98 * 93 * going to be returned. 99 94 * @return The next {@link StreetsideAbstractImage} object in the sequence. 100 *101 95 * @throws IllegalArgumentException if the given {@link StreetsideAbstractImage} object doesn't belong 102 * thethis sequence.96 * in this sequence. 103 97 */ 104 98 public StreetsideAbstractImage next(StreetsideAbstractImage image) { … … 118 112 * 119 113 * @param image The {@link StreetsideAbstractImage} object whose previous image is 120 * going to be returned. 121 * 114 * going to be returned. 122 115 * @return The previous {@link StreetsideAbstractImage} object in the sequence. 123 *124 116 * @throws IllegalArgumentException if the given {@link StreetsideAbstractImage} object doesn't belong 125 * the this sequence.117 * the this sequence. 126 118 */ 127 119 public StreetsideAbstractImage previous(StreetsideAbstractImage image) { … … 146 138 147 139 /** 148 * @param id the id to set149 */150 public void setId(String id) {151 this.id = id;152 }153 154 /**155 140 * @return the la 156 141 */ … … 214 199 } 215 200 201 /** 202 * @param id the id to set 203 */ 204 public void setId(String id) { 205 this.id = id; 206 } 207 216 208 public UserProfile getUser() { 217 209 return user; 218 210 } 219 211 } -
applications/editors/josm/plugins/MicrosoftStreetside/src/org/openstreetmap/josm/plugins/streetside/actions/ImageReloadAction.java
r34400 r36194 13 13 public class ImageReloadAction extends AbstractAction { 14 14 15 15 private static final long serialVersionUID = 7987479726049238315L; 16 16 17 18 19 17 public ImageReloadAction(final String name) { 18 super(name, ImageProvider.get("reload", ImageSizes.SMALLICON)); 19 } 20 20 21 22 23 if(StreetsideMainDialog.getInstance().getImage()!=null){24 25 26 21 @Override 22 public void actionPerformed(ActionEvent arg0) { 23 if (StreetsideMainDialog.getInstance().getImage() != null) { 24 CubemapBuilder.getInstance().reload(CubemapBuilder.getInstance().getCubemap().getId()); 25 } 26 } 27 27 } -
applications/editors/josm/plugins/MicrosoftStreetside/src/org/openstreetmap/josm/plugins/streetside/actions/StreetsideDownloadAction.java
r34399 r36194 6 6 import java.awt.event.ActionEvent; 7 7 import java.awt.event.KeyEvent; 8 import java.util.logging.Level; 9 import java.util.logging.Logger; 8 10 9 import org.apache.log4j.Logger;10 11 import org.openstreetmap.josm.actions.JosmAction; 11 12 import org.openstreetmap.josm.gui.MainApplication; … … 26 27 public class StreetsideDownloadAction extends JosmAction { 27 28 29 public static final Shortcut SHORTCUT = Shortcut.registerShortcut("Streetside", "Open Streetside layer", 30 KeyEvent.VK_COMMA, Shortcut.SHIFT); 28 31 private static final long serialVersionUID = 4426446157849005029L; 29 30 public static final Shortcut SHORTCUT = Shortcut.registerShortcut("Streetside", "Open Streetside layer", KeyEvent.VK_COMMA, Shortcut.SHIFT); 31 32 final static Logger logger = Logger.getLogger(StreetsideDownloadAction.class); 32 private static final Logger LOGGER = Logger.getLogger(StreetsideDownloadAction.class.getCanonicalName()); 33 33 34 34 /** … … 36 36 */ 37 37 public StreetsideDownloadAction() { 38 super( 39 tr("Streetside"), 40 new ImageProvider(StreetsidePlugin.LOGO).setSize(ImageSizes.DEFAULT), 41 tr("Open Streetside layer"), 42 SHORTCUT, 43 false, 44 "streetsideDownload", 45 false 46 ); 38 super(tr("Streetside"), new ImageProvider(StreetsidePlugin.LOGO).setSize(ImageSizes.DEFAULT), 39 tr("Open Streetside layer"), SHORTCUT, false, "streetsideDownload", false); 47 40 } 48 41 49 42 @Override 50 43 public void actionPerformed(ActionEvent ae) { 51 if (!StreetsideLayer.hasInstance() || !MainApplication.getLayerManager().containsLayer(StreetsideLayer.getInstance())) { 44 if (!StreetsideLayer.hasInstance() 45 || !MainApplication.getLayerManager().containsLayer(StreetsideLayer.getInstance())) { 52 46 MainApplication.getLayerManager().addLayer(StreetsideLayer.getInstance()); 53 47 return; … … 64 58 } catch (IllegalArgumentException e) { 65 59 // If the StreetsideLayer is not managed by LayerManager but you try to set it as active layer 66 logger.warn(e);60 LOGGER.log(Level.WARNING, e.getMessage(), e); 67 61 } 68 62 } -
applications/editors/josm/plugins/MicrosoftStreetside/src/org/openstreetmap/josm/plugins/streetside/actions/StreetsideDownloadViewAction.java
r34349 r36194 33 33 */ 34 34 public StreetsideDownloadViewAction() { 35 super( 36 I18n.tr(DESCRIPTION), 37 new ImageProvider(StreetsidePlugin.LOGO).setSize(ImageSizes.DEFAULT), 38 I18n.tr(DESCRIPTION), 39 Shortcut.registerShortcut("Streetside area", I18n.tr(DESCRIPTION), KeyEvent.VK_PERIOD, Shortcut.SHIFT), 40 false, 41 "streetsideArea", 42 true 43 ); 35 super(I18n.tr(DESCRIPTION), new ImageProvider(StreetsidePlugin.LOGO).setSize(ImageSizes.DEFAULT), 36 I18n.tr(DESCRIPTION), 37 Shortcut.registerShortcut("Streetside area", I18n.tr(DESCRIPTION), KeyEvent.VK_PERIOD, Shortcut.SHIFT), 38 false, "streetsideArea", true); 44 39 StreetsideProperties.DOWNLOAD_MODE.addListener(this); 45 40 initEnabledState(); … … 62 57 protected void updateEnabledState() { 63 58 super.updateEnabledState(); 64 setEnabled( 65 StreetsideLayer.hasInstance() && ( 66 StreetsideDownloader.getMode() == StreetsideDownloader.DOWNLOAD_MODE.OSM_AREA 67 || StreetsideDownloader.getMode() == StreetsideDownloader.DOWNLOAD_MODE.MANUAL_ONLY 68 ) 69 ); 59 setEnabled(StreetsideLayer.hasInstance() 60 && (StreetsideDownloader.getMode() == StreetsideDownloader.DOWNLOAD_MODE.OSM_AREA 61 || StreetsideDownloader.getMode() == StreetsideDownloader.DOWNLOAD_MODE.MANUAL_ONLY)); 70 62 } 71 63 -
applications/editors/josm/plugins/MicrosoftStreetside/src/org/openstreetmap/josm/plugins/streetside/actions/StreetsideExportAction.java
r34577 r36194 14 14 import javax.swing.JOptionPane; 15 15 16 import org.apache.log4j.Logger;17 16 import org.openstreetmap.josm.actions.JosmAction; 18 17 import org.openstreetmap.josm.gui.MainApplication; … … 37 36 private static final long serialVersionUID = 6131359489725632369L; 38 37 39 final static Logger logger = Logger.getLogger(StreetsideExportAction.class);40 41 38 private StreetsideExportDialog dialog; 42 39 … … 47 44 super(tr("Export Streetside images"), new ImageProvider(StreetsidePlugin.LOGO).setSize(ImageSizes.DEFAULT), 48 45 tr("Export Streetside images"), Shortcut.registerShortcut("Export Streetside", 49 tr("Export Streetside images"), KeyEvent.CHAR_UNDEFINED, 50 Shortcut.NONE),false, "streetsideExport", true);46 tr("Export Streetside images"), KeyEvent.CHAR_UNDEFINED, Shortcut.NONE), 47 false, "streetsideExport", true); 51 48 setEnabled(false); 52 49 } … … 63 60 dialog = new StreetsideExportDialog(ok); 64 61 pane.setMessage(dialog); 65 pane.setOptions(new JButton[] { ok, cancel});62 pane.setOptions(new JButton[] { ok, cancel }); 66 63 67 64 JDialog dlg = pane.createDialog(MainApplication.getMainFrame(), tr("Export Streetside images")); … … 70 67 71 68 // Checks if the inputs are correct and starts the export process. 72 if (pane.getValue() != null 73 && (int) pane.getValue() == JOptionPane.OK_OPTION 74 && dialog.chooser != null) { 69 if (pane.getValue() != null && (int) pane.getValue() == JOptionPane.OK_OPTION && dialog.chooser != null) { 75 70 if (dialog.group.isSelected(dialog.all.getModel())) { 76 71 export(StreetsideLayer.getInstance().getData().getImages()); … … 97 92 * Exports the given images from the database. 98 93 * 99 * @param images 100 * The set of images to be exported. 94 * @param images The set of images to be exported. 101 95 */ 102 96 public void export(Set<StreetsideAbstractImage> images) { 103 MainApplication.worker .execute(new StreetsideExportManager(images,104 dialog.chooser.getSelectedFile().toString()));97 MainApplication.worker 98 .execute(new StreetsideExportManager(images, dialog.chooser.getSelectedFile().toString())); 105 99 } 106 100 -
applications/editors/josm/plugins/MicrosoftStreetside/src/org/openstreetmap/josm/plugins/streetside/actions/StreetsideWalkAction.java
r34577 r36194 32 32 33 33 private static final long serialVersionUID = 3454223919402245818L; 34 34 private final List<WalkListener> listeners = new ArrayList<>(); 35 35 private WalkThread thread; 36 private final List<WalkListener> listeners = new ArrayList<>();37 36 38 37 /** … … 40 39 */ 41 40 public StreetsideWalkAction() { 42 super(tr("Walk mode"), new ImageProvider(StreetsidePlugin.LOGO).setSize(ImageSizes.DEFAULT), 43 tr("Walk mode"), null, 44 false, "streetsideWalk", true); 41 super(tr("Walk mode"), new ImageProvider(StreetsidePlugin.LOGO).setSize(ImageSizes.DEFAULT), tr("Walk mode"), 42 null, false, "streetsideWalk", true); 45 43 } 46 44 … … 48 46 public void actionPerformed(ActionEvent arg0) { 49 47 StreetsideWalkDialog dialog = new StreetsideWalkDialog(); 50 JOptionPane pane = new JOptionPane(dialog, JOptionPane.PLAIN_MESSAGE, 51 JOptionPane.OK_CANCEL_OPTION); 48 JOptionPane pane = new JOptionPane(dialog, JOptionPane.PLAIN_MESSAGE, JOptionPane.OK_CANCEL_OPTION); 52 49 JDialog dlg = pane.createDialog(MainApplication.getMainFrame(), tr("Walk mode")); 53 50 dlg.setMinimumSize(new Dimension(400, 150)); 54 51 dlg.setVisible(true); 55 if (pane.getValue() != null 56 && (int) pane.getValue() == JOptionPane.OK_OPTION) { 57 thread = new WalkThread((int) dialog.spin.getValue(), 58 dialog.waitForPicture.isSelected(), 52 if (pane.getValue() != null && (int) pane.getValue() == JOptionPane.OK_OPTION) { 53 thread = new WalkThread((int) dialog.spin.getValue(), dialog.waitForPicture.isSelected(), 59 54 dialog.followSelection.isSelected(), dialog.goForward.isSelected()); 60 55 fireWalkStarted(); … … 72 67 * Adds a listener. 73 68 * 74 * @param lis 75 * The listener to be added. 69 * @param lis The listener to be added. 76 70 */ 77 71 public void addListener(WalkListener lis) { … … 83 77 * 84 78 * @param lis 85 * 79 * The listener to be added. 86 80 */ 87 81 public void removeListener(WalkListener lis) { -
applications/editors/josm/plugins/MicrosoftStreetside/src/org/openstreetmap/josm/plugins/streetside/actions/StreetsideZoomAction.java
r34400 r36194 29 29 */ 30 30 public StreetsideZoomAction() { 31 super( 32 tr("Zoom to selected image"), 33 new ImageProvider(StreetsidePlugin.LOGO).setSize(ImageSizes.DEFAULT), 34 tr("Zoom to the currently selected Streetside image"), 35 null, 36 false, 37 "mapillaryZoom", 38 true 39 ); 31 super(tr("Zoom to selected image"), new ImageProvider(StreetsidePlugin.LOGO).setSize(ImageSizes.DEFAULT), 32 tr("Zoom to the currently selected Streetside image"), null, false, "mapillaryZoom", true); 40 33 } 41 34 … … 45 38 throw new IllegalStateException(); 46 39 } 47 MainApplication.getMap().mapView .zoomTo(StreetsideLayer.getInstance().getData()48 . getSelectedImage().getMovingLatLon());40 MainApplication.getMap().mapView 41 .zoomTo(StreetsideLayer.getInstance().getData().getSelectedImage().getMovingLatLon()); 49 42 } 50 43 … … 54 47 } 55 48 56 49 @Override 57 50 protected boolean listenToSelectionChange() { 58 51 return false; -
applications/editors/josm/plugins/MicrosoftStreetside/src/org/openstreetmap/josm/plugins/streetside/actions/WalkThread.java
r34416 r36194 4 4 import java.awt.image.BufferedImage; 5 5 import java.text.MessageFormat; 6 import java.util.logging.Logger; 6 7 7 8 import javax.swing.SwingUtilities; 8 9 9 import org.apache.log4j.Logger;10 10 import org.openstreetmap.josm.plugins.streetside.StreetsideAbstractImage; 11 11 import org.openstreetmap.josm.plugins.streetside.StreetsideData; … … 16 16 import org.openstreetmap.josm.plugins.streetside.gui.StreetsideMainDialog; 17 17 import org.openstreetmap.josm.plugins.streetside.utils.StreetsideProperties; 18 18 import org.openstreetmap.josm.tools.Logging; 19 19 20 20 /** … … 24 24 */ 25 25 public class WalkThread extends Thread implements StreetsideDataListener { 26 private static final Logger LOGGER = Logger.getLogger(WalkThread.class.getCanonicalName()); 26 27 private final int interval; 27 28 private final StreetsideData data; 28 private boolean end;29 29 private final boolean waitForFullQuality; 30 30 private final boolean followSelected; 31 31 private final boolean goForward; 32 private boolean end; 32 33 private BufferedImage lastImage; 33 34 private volatile boolean paused; 34 35 final static Logger logger = Logger.getLogger(WalkThread.class);36 35 37 36 /** 38 37 * Main constructor. 39 38 * 40 * @param interval How often the images switch.39 * @param interval How often the images switch. 41 40 * @param waitForPicture If it must wait for the full resolution picture or just the 42 * thumbnail.41 * thumbnail. 43 42 * @param followSelected Zoom to each image that is selected. 44 * @param goForward true to go forward; false to go backwards.43 * @param goForward true to go forward; false to go backwards. 45 44 */ 46 public WalkThread(int interval, boolean waitForPicture, 47 boolean followSelected, boolean goForward) { 45 public WalkThread(int interval, boolean waitForPicture, boolean followSelected, boolean goForward) { 48 46 this.interval = interval; 49 47 waitForFullQuality = waitForPicture; … … 52 50 data = StreetsideLayer.getInstance().getData(); 53 51 data.addListener(this); 52 } 53 54 /** 55 * Downloads n images into the cache beginning from the supplied start-image (including the start-image itself). 56 * 57 * @param startImage the image to start with (this and the next n-1 images in the same sequence are downloaded) 58 * @param n the number of images to download 59 * @param type the quality of the image (full or thumbnail) 60 */ 61 private static void preDownloadImages(StreetsideImage startImage, int n, CacheUtils.PICTURE type) { 62 if (n >= 1 && startImage != null) { 63 CacheUtils.downloadPicture(startImage, type); 64 if (startImage.next() instanceof StreetsideImage && n >= 2) { 65 preDownloadImages((StreetsideImage) startImage.next(), n - 1, type); 66 } 67 } 54 68 } 55 69 … … 62 76 // Predownload next 10 thumbnails. 63 77 preDownloadImages((StreetsideImage) image.next(), 10, CacheUtils.PICTURE.THUMBNAIL); 64 if (StreetsideProperties.PREDOWNLOAD_CUBEMAPS.get()) {78 if (Boolean.TRUE.equals(StreetsideProperties.PREDOWNLOAD_CUBEMAPS.get())) { 65 79 preDownloadCubemaps((StreetsideImage) image.next(), 10); 66 80 } … … 68 82 // Start downloading 3 next full images. 69 83 StreetsideAbstractImage currentImage = image.next(); 70 84 preDownloadImages((StreetsideImage) currentImage, 3, CacheUtils.PICTURE.FULL_IMAGE); 71 85 } 72 86 } 73 87 try { 74 88 // Waits for full quality picture. 75 final BufferedImage displayImage = StreetsideMainDialog.getInstance().getStreetsideImageDisplay().getImage(); 89 final BufferedImage displayImage = StreetsideMainDialog.getInstance().getStreetsideImageDisplay() 90 .getImage(); 76 91 if (waitForFullQuality && image instanceof StreetsideImage) { 77 92 while (displayImage == lastImage || displayImage == null || displayImage.getWidth() < 2048) { … … 101 116 } 102 117 } catch (NullPointerException e) { 103 if (StreetsideProperties.DEBUGING_ENABLED.get()) {104 logger.debug(MessageFormat.format("Exception thrown in WalkThread: {0}", e.getMessage()));105 e.printStackTrace();118 if (Boolean.TRUE.equals(StreetsideProperties.DEBUGING_ENABLED.get())) { 119 LOGGER.log(Logging.LEVEL_DEBUG, 120 MessageFormat.format("Exception thrown in WalkThread: {0}", e.getMessage()), e); 106 121 } 107 122 return; … … 111 126 112 127 private void preDownloadCubemaps(StreetsideImage startImage, int n) { 113 128 if (n >= 1 && startImage != null) { 114 129 115 116 117 130 for (int i = 0; i < 6; i++) { 131 for (int j = 0; j < 4; j++) { 132 for (int k = 0; k < 4; k++) { 118 133 119 CacheUtils.downloadPicture(startImage, CacheUtils.PICTURE.CUBEMAP); 120 if (startImage.next() instanceof StreetsideImage && n >= 2) { 121 preDownloadCubemaps((StreetsideImage) startImage.next(), n - 1); 122 } 123 } 124 } 125 } 126 } 127 } 128 129 /** 130 * Downloads n images into the cache beginning from the supplied start-image (including the start-image itself). 131 * 132 * @param startImage the image to start with (this and the next n-1 images in the same sequence are downloaded) 133 * @param n the number of images to download 134 * @param type the quality of the image (full or thumbnail) 135 */ 136 private static void preDownloadImages(StreetsideImage startImage, int n, CacheUtils.PICTURE type) { 137 if (n >= 1 && startImage != null) { 138 CacheUtils.downloadPicture(startImage, type); 139 if (startImage.next() instanceof StreetsideImage && n >= 2) { 140 preDownloadImages((StreetsideImage) startImage.next(), n - 1, type); 134 CacheUtils.downloadPicture(startImage, CacheUtils.PICTURE.CUBEMAP); 135 if (startImage.next() instanceof StreetsideImage && n >= 2) { 136 preDownloadCubemaps((StreetsideImage) startImage.next(), n - 1); 137 } 138 } 139 } 141 140 } 142 141 } -
applications/editors/josm/plugins/MicrosoftStreetside/src/org/openstreetmap/josm/plugins/streetside/cache/CacheUtils.java
r34399 r36194 2 2 package org.openstreetmap.josm.plugins.streetside.cache; 3 3 4 import java.io.IOException; 5 import java.util.logging.Logger; 4 6 5 import java.io.IOException;6 7 import org.apache.log4j.Logger;8 7 import org.openstreetmap.josm.data.cache.CacheEntry; 9 8 import org.openstreetmap.josm.data.cache.CacheEntryAttributes; … … 11 10 import org.openstreetmap.josm.plugins.streetside.StreetsideImage; 12 11 import org.openstreetmap.josm.plugins.streetside.cubemap.CubemapBuilder; 12 import org.openstreetmap.josm.tools.Logging; 13 13 14 14 /** … … 20 20 public final class CacheUtils { 21 21 22 final static Logger logger = Logger.getLogger(CacheUtils.class);22 private static final Logger LOGGER = Logger.getLogger(CacheUtils.class.getCanonicalName()); 23 23 24 private staticIgnoreDownload ignoreDownload = new IgnoreDownload();24 private static final IgnoreDownload ignoreDownload = new IgnoreDownload(); 25 25 26 /** Picture quality */ 27 public enum PICTURE { 28 /** Thumbnail quality picture (320 p) */ 29 THUMBNAIL, 30 /** Full quality picture (2048 p) */ 31 FULL_IMAGE, 32 /** Both of them */ 33 BOTH, 34 /** Streetside cubemap */ 35 CUBEMAP 36 } 26 private CacheUtils() { 27 // Private constructor to avoid instantiation 28 } 37 29 38 private CacheUtils() { 39 // Private constructor to avoid instantiation 40 } 30 /** 31 * Downloads the the thumbnail and the full resolution picture of the given 32 * image. Does nothing if it is already in cache. 33 * 34 * @param img The image whose picture is going to be downloaded. 35 */ 36 public static void downloadPicture(StreetsideImage img) { 37 downloadPicture(img, PICTURE.BOTH); 38 } 41 39 42 /** 43 * Downloads the the thumbnail and the full resolution picture of the given 44 * image. Does nothing if it is already in cache. 45 * 46 * @param img 47 * The image whose picture is going to be downloaded. 48 */ 49 public static void downloadPicture(StreetsideImage img) { 50 downloadPicture(img, PICTURE.BOTH); 51 } 40 /** 41 * Downloads the the thumbnail and the full resolution picture of the given 42 * image. Does nothing if it is already in cache. 43 * 44 * @param cm The image whose picture is going to be downloaded. 45 */ 46 public static void downloadCubemap(StreetsideImage cm) { 47 downloadPicture(cm, PICTURE.CUBEMAP); 48 } 52 49 53 /** 54 * Downloads the the thumbnail and the full resolution picture of the given 55 * image. Does nothing if it is already in cache. 56 * 57 * @param cm 58 * The image whose picture is going to be downloaded. 59 */ 60 public static void downloadCubemap(StreetsideImage cm) { 61 downloadPicture(cm, PICTURE.CUBEMAP); 62 } 50 /** 51 * Downloads the picture of the given image. Does nothing when it is already 52 * in cache. 53 * 54 * @param img The image to be downloaded. 55 * @param pic The picture type to be downloaded (full quality, thumbnail or 56 * both.) 57 */ 58 public static void downloadPicture(StreetsideImage img, PICTURE pic) { 59 switch (pic) { 60 case BOTH: 61 if (new StreetsideCache(img.getId(), StreetsideCache.Type.THUMBNAIL).get() == null) 62 submit(img.getId(), StreetsideCache.Type.THUMBNAIL, ignoreDownload); 63 if (new StreetsideCache(img.getId(), StreetsideCache.Type.FULL_IMAGE).get() == null) 64 submit(img.getId(), StreetsideCache.Type.FULL_IMAGE, ignoreDownload); 65 break; 66 case THUMBNAIL: 67 submit(img.getId(), StreetsideCache.Type.THUMBNAIL, ignoreDownload); 68 break; 69 case FULL_IMAGE: 70 // not used (relic from Mapillary) 71 break; 72 case CUBEMAP: 73 if (img.getId() == null) { 74 LOGGER.log(Logging.LEVEL_ERROR, "Download cancelled. Image id is null."); 75 } else { 76 CubemapBuilder.getInstance().downloadCubemapImages(img.getId()); 77 } 78 break; 79 default: 80 submit(img.getId(), StreetsideCache.Type.FULL_IMAGE, ignoreDownload); 81 break; 82 } 83 } 63 84 64 /** 65 * Downloads the picture of the given image. Does nothing when it is already 66 * in cache. 67 * 68 * @param img 69 * The image to be downloaded. 70 * @param pic 71 * The picture type to be downloaded (full quality, thumbnail or 72 * both.) 73 */ 74 public static void downloadPicture(StreetsideImage img, PICTURE pic) { 75 switch (pic) { 76 case BOTH: 77 if (new StreetsideCache(img.getId(), StreetsideCache.Type.THUMBNAIL).get() == null) 78 submit(img.getId(), StreetsideCache.Type.THUMBNAIL, ignoreDownload); 79 if (new StreetsideCache(img.getId(), StreetsideCache.Type.FULL_IMAGE).get() == null) 80 submit(img.getId(), StreetsideCache.Type.FULL_IMAGE, ignoreDownload); 81 break; 82 case THUMBNAIL: 83 submit(img.getId(), StreetsideCache.Type.THUMBNAIL, ignoreDownload); 84 break; 85 case FULL_IMAGE: 86 // not used (relic from Mapillary) 87 break; 88 case CUBEMAP: 89 if(img.getId()==null) { 90 logger.error("Download cancelled. Image id is null."); 91 } else { 92 CubemapBuilder.getInstance().downloadCubemapImages(img.getId()); 93 } 94 break; 95 default: 96 submit(img.getId(), StreetsideCache.Type.FULL_IMAGE, ignoreDownload); 97 break; 98 } 99 } 85 /** 86 * Requests the picture with the given key and quality and uses the given 87 * listener. 88 * 89 * @param key The key of the picture to be requested. 90 * @param type The quality of the picture to be requested. 91 * @param lis The listener that is going to receive the picture. 92 */ 93 public static void submit(String key, StreetsideCache.Type type, ICachedLoaderListener lis) { 94 try { 95 new StreetsideCache(key, type).submit(lis, false); 96 } catch (IOException e) { 97 LOGGER.log(Logging.LEVEL_ERROR, e.getMessage(), e); 98 } 99 } 100 100 101 /** 102 * Requests the picture with the given key and quality and uses the given 103 * listener. 104 * 105 * @param key 106 * The key of the picture to be requested. 107 * @param type 108 * The quality of the picture to be requested. 109 * @param lis 110 * The listener that is going to receive the picture. 111 */ 112 public static void submit(String key, StreetsideCache.Type type, 113 ICachedLoaderListener lis) { 114 try { 115 new StreetsideCache(key, type).submit(lis, false); 116 } catch (IOException e) { 117 logger.error(e); 118 } 119 } 101 /** 102 * Picture quality 103 */ 104 public enum PICTURE { 105 /** 106 * Thumbnail quality picture (320 p) 107 */ 108 THUMBNAIL, 109 /** 110 * Full quality picture (2048 p) 111 */ 112 FULL_IMAGE, 113 /** 114 * Both of them 115 */ 116 BOTH, 117 /** 118 * Streetside cubemap 119 */ 120 CUBEMAP 121 } 120 122 121 123 private static class IgnoreDownload implements ICachedLoaderListener { -
applications/editors/josm/plugins/MicrosoftStreetside/src/org/openstreetmap/josm/plugins/streetside/cache/Caches.java
r35466 r36194 5 5 import java.io.IOException; 6 6 import java.io.Serializable; 7 import java.util.logging.Logger; 7 8 8 9 import javax.swing.ImageIcon; … … 10 11 import org.apache.commons.jcs3.access.CacheAccess; 11 12 import org.apache.commons.jcs3.engine.behavior.IElementAttributes; 12 import org.apache.log4j.Logger;13 13 import org.openstreetmap.josm.data.Preferences; 14 14 import org.openstreetmap.josm.data.cache.BufferedImageCacheEntry; … … 19 19 public final class Caches { 20 20 21 final static Logger logger = Logger.getLogger(Caches.class);21 private static final Logger LOGGER = Logger.getLogger(Caches.class.getCanonicalName()); 22 22 23 24 25 23 private Caches() { 24 // Private constructor to avoid instantiation 25 } 26 26 27 28 29 30 31 32 33 27 public static File getCacheDirectory() { 28 final File f = new File(Preferences.main().getPluginsDirectory().getPath() + "/MicrosoftStreetside/cache"); 29 if (!f.exists()) { 30 f.mkdirs(); 31 } 32 return f; 33 } 34 34 35 36 35 public abstract static class CacheProxy<K, V extends Serializable> { 36 private final CacheAccess<K, V> cache; 37 37 38 publicCacheProxy() {39 40 41 42 43 logger.warn("Could not initialize cache for " + getClass().getName(), e);44 45 46 47 38 protected CacheProxy() { 39 CacheAccess<K, V> c; 40 try { 41 c = createNewCache(); 42 } catch (IOException e) { 43 LOGGER.log(Logging.LEVEL_WARN, e, () -> "Could not initialize cache for " + getClass().getName()); 44 c = null; 45 } 46 cache = c; 47 } 48 48 49 49 protected abstract CacheAccess<K, V> createNewCache() throws IOException; 50 50 51 52 53 51 public V get(final K key) { 52 return cache == null ? null : cache.get(key); 53 } 54 54 55 56 57 58 59 60 55 public void put(final K key, final V value) { 56 if (cache != null) { 57 cache.put(key, value); 58 } 59 } 60 } 61 61 62 63 64 62 public static class ImageCache { 63 private static ImageCache instance; 64 private final CacheAccess<String, BufferedImageCacheEntry> cache; 65 65 66 67 68 69 70 71 72 73 74 75 66 public ImageCache() { 67 CacheAccess<String, BufferedImageCacheEntry> c; 68 try { 69 c = JCSCacheManager.getCache("streetside", 10, 10000, Caches.getCacheDirectory().getPath()); 70 } catch (Exception e) { 71 Logging.log(Logging.LEVEL_WARN, "Could not initialize the Streetside image cache.", e); 72 c = null; 73 } 74 cache = c; 75 } 76 76 77 public CacheAccess<String, BufferedImageCacheEntry> getCache() { 78 return cache; 79 } 77 public static ImageCache getInstance() { 78 synchronized (ImageCache.class) { 79 if (ImageCache.instance == null) { 80 ImageCache.instance = new ImageCache(); 81 } 82 return ImageCache.instance; 83 } 84 } 80 85 81 public static ImageCache getInstance() { 82 synchronized (ImageCache.class) { 83 if (ImageCache.instance == null) { 84 ImageCache.instance = new ImageCache(); 85 } 86 return ImageCache.instance; 87 } 88 } 89 } 86 public CacheAccess<String, BufferedImageCacheEntry> getCache() { 87 return cache; 88 } 89 } 90 90 91 92 93 91 public static class CubemapCache { 92 private static CubemapCache instance; 93 private final CacheAccess<String, BufferedImageCacheEntry> cache; 94 94 95 96 97 98 99 100 logger.warn("Could not initialize the Streetside cubemap cache.", e);101 102 103 104 95 public CubemapCache() { 96 CacheAccess<String, BufferedImageCacheEntry> c; 97 try { 98 c = JCSCacheManager.getCache("streetside", 10, 10000, Caches.getCacheDirectory().getPath()); 99 } catch (Exception e) { 100 LOGGER.log(Logging.LEVEL_WARN, "Could not initialize the Streetside cubemap cache.", e); 101 c = null; 102 } 103 cache = c; 104 } 105 105 106 public CacheAccess<String, BufferedImageCacheEntry> getCache() { 107 return cache; 108 } 106 public static CubemapCache getInstance() { 107 synchronized (CubemapCache.class) { 108 if (CubemapCache.instance == null) { 109 CubemapCache.instance = new CubemapCache(); 110 } 111 return CubemapCache.instance; 112 } 113 } 109 114 110 public static CubemapCache getInstance() { 111 synchronized (CubemapCache.class) { 112 if (CubemapCache.instance == null) { 113 CubemapCache.instance = new CubemapCache(); 114 } 115 return CubemapCache.instance; 116 } 117 } 118 } 115 public CacheAccess<String, BufferedImageCacheEntry> getCache() { 116 return cache; 117 } 118 } 119 119 120 121 120 public static class MapObjectIconCache extends CacheProxy<String, ImageIcon> { 121 private static CacheProxy<String, ImageIcon> instance; 122 122 123 124 125 126 127 128 129 130 123 public static CacheProxy<String, ImageIcon> getInstance() { 124 synchronized (MapObjectIconCache.class) { 125 if (MapObjectIconCache.instance == null) { 126 MapObjectIconCache.instance = new MapObjectIconCache(); 127 } 128 return MapObjectIconCache.instance; 129 } 130 } 131 131 132 133 134 135 136 132 @Override 133 protected CacheAccess<String, ImageIcon> createNewCache() throws IOException { 134 return JCSCacheManager.getCache("streetsideObjectIcons", 100, 1000, Caches.getCacheDirectory().getPath()); 135 } 136 } 137 137 138 139 138 public static class UserProfileCache extends CacheProxy<String, UserProfile> { 139 private static CacheProxy<String, UserProfile> instance; 140 140 141 142 143 144 145 146 147 148 141 public static CacheProxy<String, UserProfile> getInstance() { 142 synchronized (UserProfileCache.class) { 143 if (UserProfileCache.instance == null) { 144 UserProfileCache.instance = new UserProfileCache(); 145 } 146 return UserProfileCache.instance; 147 } 148 } 149 149 150 151 152 CacheAccess<String, UserProfile> cache = 153 JCSCacheManager.getCache("userProfile", 100, 1000,Caches.getCacheDirectory().getPath());154 155 156 157 158 159 150 @Override 151 protected CacheAccess<String, UserProfile> createNewCache() throws IOException { 152 CacheAccess<String, UserProfile> cache = JCSCacheManager.getCache("userProfile", 100, 1000, 153 Caches.getCacheDirectory().getPath()); 154 IElementAttributes atts = cache.getDefaultElementAttributes(); 155 atts.setMaxLife(604_800_000); // Sets lifetime to 7 days (604800000=1000*60*60*24*7) 156 cache.setDefaultElementAttributes(atts); 157 return cache; 158 } 159 } 160 160 } -
applications/editors/josm/plugins/MicrosoftStreetside/src/org/openstreetmap/josm/plugins/streetside/cache/StreetsideCache.java
r34412 r36194 18 18 public class StreetsideCache extends JCSCachedTileLoaderJob<String, BufferedImageCacheEntry> { 19 19 20 21 20 private final URL url; 21 private final String id; 22 22 23 /** 24 * Types of images. 25 * 26 * @author nokutu 27 */ 28 public enum Type { 29 /** Full quality image */ 30 FULL_IMAGE, 31 /** Low quality image */ 32 THUMBNAIL 33 } 23 /** 24 * Main constructor. 25 * 26 * @param id The id of the image. 27 * @param type The type of image that must be downloaded (THUMBNAIL or 28 * FULL_IMAGE). 29 */ 30 public StreetsideCache(final String id, final Type type) { 31 super(Caches.ImageCache.getInstance().getCache(), new TileJobOptions(50000, 50000, new HashMap<>(), 50000L)); 34 32 35 /** 36 * Main constructor. 37 * 38 * @param id 39 * The id of the image. 40 * @param type 41 * The type of image that must be downloaded (THUMBNAIL or 42 * FULL_IMAGE). 43 */ 44 public StreetsideCache(final String id, final Type type) { 45 super(Caches.ImageCache.getInstance().getCache(),new TileJobOptions(50000, 50000, new HashMap<String,String>(),50000l)); 33 if (id == null || type == null) { 34 this.id = null; 35 url = null; 36 } else { 37 this.id = id; 38 url = VirtualEarth.streetsideTile(id, type == Type.THUMBNAIL); 39 } 40 } 46 41 47 if (id == null || type == null) { 48 this.id = null; 49 url = null; 50 } else { 51 this.id = id; 52 url = VirtualEarth.streetsideTile(id, type == Type.THUMBNAIL); 53 } 54 } 42 @Override 43 public String getCacheKey() { 44 return id; 45 } 55 46 56 57 public String getCacheKey() {58 return id;59 47 @Override 48 public URL getUrl() { 49 return url; 50 } 60 51 61 62 public URL getUrl() {63 return url;64 52 @Override 53 protected BufferedImageCacheEntry createCacheEntry(byte[] content) { 54 return new BufferedImageCacheEntry(content); 55 } 65 56 66 @Override 67 protected BufferedImageCacheEntry createCacheEntry(byte[] content) { 68 return new BufferedImageCacheEntry(content); 69 } 57 @Override 58 protected boolean isObjectLoadable() { 59 if (cacheData == null) { 60 return false; 61 } 62 final byte[] content = cacheData.getContent(); 63 return content != null && content.length > 0; 64 } 70 65 71 @Override 72 protected boolean isObjectLoadable() { 73 if (cacheData == null) { 74 return false; 75 } 76 final byte[] content = cacheData.getContent(); 77 return content != null && content.length > 0; 78 } 66 /** 67 * Types of images. 68 * 69 * @author nokutu 70 */ 71 public enum Type { 72 /** 73 * Full quality image 74 */ 75 FULL_IMAGE, 76 /** 77 * Low quality image 78 */ 79 THUMBNAIL 80 } 79 81 } -
applications/editors/josm/plugins/MicrosoftStreetside/src/org/openstreetmap/josm/plugins/streetside/cubemap/CameraTransformer.java
r34416 r36194 11 11 public class CameraTransformer extends Group { 12 12 13 public enum RotateOrder {14 XYZ, XZY, YXZ, YZX, ZXY, ZYX15 }16 17 13 public Translate t = new Translate(); 18 14 public Translate p = new Translate(); 19 15 public Translate ip = new Translate(); 20 16 public Rotate rx = new Rotate(); 17 public Rotate ry = new Rotate(); 18 public Rotate rz = new Rotate(); 19 public Scale s = new Scale(); 20 21 21 { 22 22 rx.setAxis(Rotate.X_AXIS); 23 23 } 24 public Rotate ry = new Rotate(); 24 25 25 { 26 26 ry.setAxis(Rotate.Y_AXIS); 27 27 } 28 public Rotate rz = new Rotate(); 28 29 29 { 30 30 rz.setAxis(Rotate.Z_AXIS); 31 31 } 32 public Scale s = new Scale();33 32 34 33 public CameraTransformer() { … … 179 178 ip.setZ(0.0); 180 179 } 180 181 public enum RotateOrder { 182 XYZ, XZY, YXZ, YZX, ZXY, ZYX 183 } 181 184 } -
applications/editors/josm/plugins/MicrosoftStreetside/src/org/openstreetmap/josm/plugins/streetside/cubemap/CubemapBox.java
r34428 r36194 1 /* 2 * To change this license header, choose License Headers in Project Properties. 3 * To change this template file, choose Tools | Templates 4 * and open the template in the editor. 5 */ 6 1 // License: GPL. For details, see LICENSE file. 7 2 package org.openstreetmap.josm.plugins.streetside.cubemap; 8 3 … … 29 24 public class CubemapBox extends Group { 30 25 31 public enum CubemapBoxImageType {32 MULTIPLE, SINGLE33 }34 35 26 private final Affine affine = new Affine(); 36 37 private final ImageView front = new ImageView(), right = new ImageView(), back = new ImageView(), 38 left = new ImageView(), up = new ImageView(), down = new ImageView(); 27 private final ImageView front = new ImageView(); 28 private final ImageView right = new ImageView(); 29 private final ImageView back = new ImageView(); 30 private final ImageView left = new ImageView(); 31 private final ImageView up = new ImageView(); 32 private final ImageView down = new ImageView(); 33 private final ImageView[] views = new ImageView[] { front, right, back, left, up, down }; 34 private final Image frontImg; 35 private final Image rightImg; 36 private final Image backImg; 37 private final Image leftImg; 38 private final Image upImg; 39 private final Image downImg; 40 private final PerspectiveCamera camera; 41 private final CubemapBoxImageType imageType; 42 private Image singleImg; 43 private AnimationTimer timer; 39 44 40 45 { … … 47 52 48 53 } 49 private final ImageView[] views = new ImageView[] { front, right, back, left, up, down }; 50 51 private Image frontImg, rightImg, backImg, leftImg, upImg, downImg, singleImg; 52 53 private final PerspectiveCamera camera; 54 private AnimationTimer timer; 55 private final CubemapBoxImageType imageType; 56 57 public CubemapBox( 58 Image frontImg, Image rightImg, Image backImg, Image leftImg, Image upImg, Image downImg, double size, 59 PerspectiveCamera camera) { 54 55 public CubemapBox(Image frontImg, Image rightImg, Image backImg, Image leftImg, Image upImg, Image downImg, 56 double size, PerspectiveCamera camera) { 60 57 61 58 super(); … … 148 145 private void loadSingleImageViewports() { 149 146 layoutViews(); 150 double width = singleImg.getWidth(), height = singleImg.getHeight(); 147 double width = singleImg.getWidth(); 148 double height = singleImg.getHeight(); 151 149 152 150 // simple check to see if cells will be square … … 158 156 recalculateSize(cellSize); 159 157 160 double topx = cellSize, topy = 0, 161 162 botx = cellSize, boty = cellSize * 2, 163 164 leftx = 0, lefty = cellSize, 165 166 rightx = cellSize * 2, righty = cellSize, 167 168 fwdx = cellSize, fwdy = cellSize, 169 170 backx = cellSize * 3, backy = cellSize; 158 double topx = cellSize; 159 double topy = 0; 160 double botx = cellSize; 161 double boty = cellSize * 2; 162 double leftx = 0; 163 double lefty = cellSize; 164 double rightx = cellSize * 2; 165 double righty = cellSize; 166 double fwdx = cellSize; 167 double fwdy = cellSize; 168 double backx = cellSize * 3; 169 double backy = cellSize; 171 170 172 171 // add top padding x+, y+, width-, height … … 231 230 } 232 231 233 /* 234 * Properties 235 */ 232 public final double getSize() { 233 return size.get(); 234 } 235 236 public final void setSize(double value) { 237 size.set(value); 238 } /* 239 * Properties 240 */ 241 236 242 private final DoubleProperty size = new SimpleDoubleProperty() { 237 243 @Override … … 248 254 }; 249 255 250 public final double getSize() {251 return size.get();252 }253 254 public final void setSize(double value) {255 size.set(value);256 }257 258 256 public DoubleProperty sizeProperty() { 259 257 return size; … … 263 261 return views; 264 262 } 263 264 public enum CubemapBoxImageType { 265 MULTIPLE, SINGLE 266 } 267 265 268 } -
applications/editors/josm/plugins/MicrosoftStreetside/src/org/openstreetmap/josm/plugins/streetside/cubemap/CubemapBuilder.java
r36065 r36194 10 10 import java.util.Map; 11 11 import java.util.concurrent.Callable; 12 import java.util.concurrent.ConcurrentHashMap; 12 13 import java.util.concurrent.ExecutionException; 13 import java.util.concurrent.ConcurrentHashMap;14 14 import java.util.concurrent.ExecutorService; 15 15 import java.util.concurrent.Executors; 16 16 import java.util.concurrent.Future; 17 18 import org.apache.log4j.Logger; 17 import java.util.logging.Logger; 18 19 19 import org.openstreetmap.josm.gui.MainApplication; 20 import java.util.concurrent.ExecutionException;21 20 import org.openstreetmap.josm.plugins.streetside.StreetsideAbstractImage; 22 21 import org.openstreetmap.josm.plugins.streetside.StreetsideCubemap; … … 27 26 import org.openstreetmap.josm.plugins.streetside.utils.GraphicsUtils; 28 27 import org.openstreetmap.josm.plugins.streetside.utils.StreetsideProperties; 28 import org.openstreetmap.josm.tools.Logging; 29 29 30 30 import javafx.scene.image.Image; … … 34 34 public class CubemapBuilder implements ITileDownloadingTaskListener, StreetsideDataListener { 35 35 36 final static Logger logger = Logger.getLogger(CubemapBuilder.class); 37 38 private static CubemapBuilder instance; 39 private StreetsideCubemap cubemap; 40 protected boolean isBuilding; 41 36 private static final Logger LOGGER = Logger.getLogger(CubemapBuilder.class.getCanonicalName()); 37 38 private static CubemapBuilder instance; 39 protected boolean isBuilding; 40 private StreetsideCubemap cubemap; 42 41 private long startTime; 43 42 44 43 private Map<String, BufferedImage> tileImages = new ConcurrentHashMap<>(); 45 44 private ExecutorService pool; 46 45 47 private int currentTileCount = 0; 46 private int currentTileCount = 0; 47 48 private CubemapBuilder() { 49 // private constructor to avoid instantiation 50 } 51 52 public static CubemapBuilder getInstance() { 53 if (instance == null) { 54 instance = new CubemapBuilder(); 55 } 56 return instance; 57 } 58 59 /** 60 * @return true, iff the singleton instance is present 61 */ 62 public static boolean hasInstance() { 63 return CubemapBuilder.instance != null; 64 } 65 66 /** 67 * Destroys the unique instance of the class. 68 */ 69 public static synchronized void destroyInstance() { 70 CubemapBuilder.instance = null; 71 } 48 72 49 73 /** … … 61 85 } 62 86 63 private CubemapBuilder() { 64 // private constructor to avoid instantiation 65 } 66 67 /** 87 /** 68 88 * Fired when any image is added to the database. 69 89 */ 70 90 @Override 71 72 73 74 75 91 public void imagesAdded() { 92 // Not implemented by the CubemapBuilder 93 } 94 95 /** 76 96 * Fired when the selected image is changed by something different from 77 97 * manually clicking on the icon. 78 98 * 79 * @param oldImage 80 * Old selected {@link StreetsideAbstractImage} 81 * @param newImage 82 * New selected {@link StreetsideAbstractImage} 83 * 99 * @param oldImage Old selected {@link StreetsideAbstractImage} 100 * @param newImage New selected {@link StreetsideAbstractImage} 84 101 * @see StreetsideDataListener 85 102 */ … … 87 104 public void selectedImageChanged(StreetsideAbstractImage oldImage, StreetsideAbstractImage newImage) { 88 105 89 90 106 startTime = System.currentTimeMillis(); 91 107 92 if (newImage != null) { 93 94 cubemap = null; 95 cubemap = new StreetsideCubemap(newImage.getId(), newImage.getLatLon(), newImage.getHe()); 96 currentTileCount = 0; 97 resetTileImages(); 98 99 // download cubemap images in different threads and then subsequently 100 // set the cubeface images in JavaFX 101 downloadCubemapImages(cubemap.getId()); 102 103 long runTime = (System.currentTimeMillis()-startTime)/1000; 104 if(StreetsideProperties.DEBUGING_ENABLED.get()) { 105 logger.debug(MessageFormat.format("Completed downloading tiles for {0} in {1} seconds.", newImage.getId() , runTime)); 106 } 107 } 108 } 109 110 public void reload(String imageId) { 111 if (cubemap != null && imageId.equals(cubemap.getId())) { 112 tileImages = new HashMap<>(); 113 downloadCubemapImages(imageId); 114 } 115 } 116 117 public void downloadCubemapImages(String imageId) { 118 ThreeSixtyDegreeViewerPanel panel360 = StreetsideViewerPanel.getThreeSixtyDegreeViewerPanel(); 119 if (panel360 != null && panel360.getScene() != panel360.getLoadingScene()) { 120 panel360.setScene(panel360.getLoadingScene()); 121 } 122 123 final int maxThreadCount = StreetsideProperties.DOWNLOAD_CUBEFACE_TILES_TOGETHER.get()?6:6 * CubemapUtils.getMaxCols() * CubemapUtils.getMaxRows(); 124 125 int fails = 0; 108 if (newImage != null) { 109 110 cubemap = null; 111 cubemap = new StreetsideCubemap(newImage.getId(), newImage.getLatLon(), newImage.getHe()); 112 currentTileCount = 0; 113 resetTileImages(); 114 115 // download cubemap images in different threads and then subsequently 116 // set the cubeface images in JavaFX 117 downloadCubemapImages(cubemap.getId()); 118 119 long runTime = (System.currentTimeMillis() - startTime) / 1000; 120 if (Boolean.TRUE.equals(StreetsideProperties.DEBUGING_ENABLED.get())) { 121 LOGGER.log(Logging.LEVEL_DEBUG, MessageFormat 122 .format("Completed downloading tiles for {0} in {1} seconds.", newImage.getId(), runTime)); 123 } 124 } 125 } 126 127 public void reload(String imageId) { 128 if (cubemap != null && imageId.equals(cubemap.getId())) { 129 tileImages = new HashMap<>(); 130 downloadCubemapImages(imageId); 131 } 132 } 133 134 public void downloadCubemapImages(String imageId) { 135 ThreeSixtyDegreeViewerPanel panel360 = StreetsideViewerPanel.getThreeSixtyDegreeViewerPanel(); 136 if (panel360 != null && panel360.getScene() != panel360.getLoadingScene()) { 137 panel360.setScene(panel360.getLoadingScene()); 138 } 139 140 final int maxThreadCount = Boolean.TRUE.equals(StreetsideProperties.DOWNLOAD_CUBEFACE_TILES_TOGETHER.get()) ? 6 141 : 6 * CubemapUtils.getMaxCols() * CubemapUtils.getMaxRows(); 142 143 int fails = 0; 126 144 127 145 // TODO: message for progress bar … … 132 150 long startTime = System.currentTimeMillis(); 133 151 134 if (CubemapBuilder.getInstance().getTileImages().keySet().size() > 0) {152 if (!CubemapBuilder.getInstance().getTileImages().keySet().isEmpty()) { 135 153 pool.shutdownNow(); 136 154 CubemapBuilder.getInstance().resetTileImages(); … … 142 160 List<Callable<List<String>>> tasks = new ArrayList<>(maxThreadCount); 143 161 144 if ( StreetsideProperties.DOWNLOAD_CUBEFACE_TILES_TOGETHER.get()) {162 if (Boolean.TRUE.equals(StreetsideProperties.DOWNLOAD_CUBEFACE_TILES_TOGETHER.get())) { 145 163 EnumSet.allOf(CubemapUtils.CubemapFaces.class).forEach(face -> { 146 String tileId = String.valueOf(imageId + face.getValue());164 String tileId = imageId + face.getValue(); 147 165 tasks.add(new TileDownloadingTask(tileId)); 148 166 }); … … 150 168 151 169 // launch 4-tiled (low-res) downloading tasks . . . 152 if ( !StreetsideProperties.SHOW_HIGH_RES_STREETSIDE_IMAGERY.get()) {170 if (Boolean.FALSE.equals(StreetsideProperties.SHOW_HIGH_RES_STREETSIDE_IMAGERY.get())) { 153 171 // download all imagery for each cubeface at once 154 172 … … 158 176 for (int k = 0; k < CubemapUtils.getMaxRows(); k++) { 159 177 160 String tileId = String 161 .valueOf(imageId + CubemapUtils.getFaceNumberForCount(i) + Integer.valueOf(tileNr++).toString()); 178 String tileId = imageId + CubemapUtils.getFaceNumberForCount(i) + tileNr++; 162 179 tasks.add(new TileDownloadingTask(tileId)); 163 180 } 164 181 } 165 182 } 166 // launch 16-tiled (high-res) downloading tasks167 } else if ( StreetsideProperties.SHOW_HIGH_RES_STREETSIDE_IMAGERY.get()) {183 // launch 16-tiled (high-res) downloading tasks 184 } else if (Boolean.TRUE.equals(StreetsideProperties.SHOW_HIGH_RES_STREETSIDE_IMAGERY.get())) { 168 185 169 186 for (int i = 0; i < CubemapUtils.NUM_SIDES; i++) { … … 171 188 for (int k = 0; k < CubemapUtils.getMaxRows(); k++) { 172 189 173 String tileId = String 174 .valueOf(imageId + CubemapUtils.getFaceNumberForCount(i) + String.valueOf(Integer.valueOf(j).toString() + Integer.valueOf(k).toString())); 190 String tileId = imageId + CubemapUtils.getFaceNumberForCount(i) + j + k; 175 191 tasks.add(new TileDownloadingTask(tileId)); 176 192 } … … 181 197 182 198 // execute tasks 183 184 199 MainApplication.worker.submit(() -> { 200 try { 185 201 List<Future<List<String>>> results = pool.invokeAll(tasks); 186 187 if (StreetsideProperties.DEBUGING_ENABLED.get() && results != null) {202 203 if (Boolean.TRUE.equals(StreetsideProperties.DEBUGING_ENABLED.get()) && results != null) { 188 204 for (Future<List<String>> ff : results) { 189 205 try { 190 logger.debug(MessageFormat.format("Completed tile downloading task {0} in {1} seconds.",ff.get().toString(), 191 (System.currentTimeMillis() - startTime)/1000)); 206 LOGGER.log(Logging.LEVEL_DEBUG, 207 MessageFormat.format("Completed tile downloading task {0} in {1} seconds.", 208 ff.get().toString(), (System.currentTimeMillis() - startTime) / 1000)); 192 209 } catch (ExecutionException e) { 193 logger.error(e);210 LOGGER.log(Logging.LEVEL_ERROR, e.getMessage(), e); 194 211 } 195 212 } 196 213 } 197 214 } catch (InterruptedException e) { 198 logger.error(e);199 } 200 215 LOGGER.log(Logging.LEVEL_ERROR, e.getMessage(), e); 216 } 217 }); 201 218 } catch (Exception ee) { 202 219 fails++; 203 logger.error("Error loading tile for image " + imageId); 204 ee.printStackTrace(); 220 LOGGER.log(Logging.LEVEL_ERROR, ee, () -> "Error loading tile for image " + imageId); 205 221 } 206 222 … … 208 224 long runTime = stopTime - startTime; 209 225 210 if (StreetsideProperties.DEBUGING_ENABLED.get()) { 211 logger.debug(MessageFormat.format("Tile imagery downloading tasks completed in {0} seconds.", runTime / 1000)); 226 if (Boolean.TRUE.equals(StreetsideProperties.DEBUGING_ENABLED.get())) { 227 LOGGER.log(Logging.LEVEL_DEBUG, 228 MessageFormat.format("Tile imagery downloading tasks completed in {0} seconds.", runTime / 1000)); 212 229 } 213 230 214 231 if (fails > 0) { 215 logger.error(Integer.valueOf(fails)+ " downloading tasks failed!");232 LOGGER.log(Logging.LEVEL_ERROR, fails + " downloading tasks failed!"); 216 233 } 217 234 } … … 222 239 * 223 240 * @param tileId 224 * 241 * the complete quadKey of the imagery tile, including cubeface and row/column in quaternary. 225 242 * @see TileDownloadingTask 226 243 */ … … 231 248 // and set the views in the cubemap box. 232 249 233 if (!tileId.startsWith(cubemap.getId())) {250 if (!tileId.startsWith(cubemap.getId())) { 234 251 return; 235 252 } … … 238 255 239 256 if (currentTileCount == (CubemapUtils.NUM_SIDES * CubemapUtils.getMaxCols() * CubemapUtils.getMaxRows())) { 240 if ( StreetsideProperties.DEBUGING_ENABLED.get()) {257 if (Boolean.TRUE.equals(StreetsideProperties.DEBUGING_ENABLED.get())) { 241 258 long endTime = System.currentTimeMillis(); 242 259 long runTime = (endTime - startTime) / 1000; 243 logger.debug( 244 MessageFormat.format( 245 "{0} tile images ready for building cumbemap faces for cubemap {1} in {2} seconds.", currentTileCount, 246 CubemapBuilder.getInstance().getCubemap().getId(), Long.toString(runTime)) 247 ); 260 LOGGER.log(Logging.LEVEL_DEBUG, MessageFormat.format( 261 "{0} tile images ready for building cumbemap faces for cubemap {1} in {2} seconds.", 262 currentTileCount, CubemapBuilder.getInstance().getCubemap().getId(), Long.toString(runTime))); 248 263 } 249 264 … … 258 273 * then the ImageViews of the cubemap are set with the new imagery. 259 274 * 260 * @see 261 */ 262 263 CubemapBox cmb = StreetsideViewerDialog.getInstance().getStreetsideViewerPanel().getCubemapBox();264 ImageView[] views = cmb.getViews();265 266 Image finalImages[] = new Image[CubemapUtils.NUM_SIDES]; 267 268 // build 4-tiled cubemap faces and crop buffers 269 if (!StreetsideProperties.SHOW_HIGH_RES_STREETSIDE_IMAGERY.get()) { 270 for (int i = 0; i < CubemapUtils.NUM_SIDES; i++) {271 272 BufferedImage[] faceTileImages = new BufferedImage[CubemapUtils.getMaxCols() * CubemapUtils.getMaxRows()]; 273 274 for (int j = 0; j < (CubemapUtils.getMaxCols() * CubemapUtils.getMaxRows()); j++) { 275 String tileId = String.valueOf(getCubemap().getId() + CubemapUtils.getFaceNumberForCount(i) 276 + Integer.valueOf(j).toString()); 277 BufferedImage currentTile = tileImages.get(tileId);278 279 faceTileImages[j] = currentTile; 280 } 281 282 BufferedImage finalImg = GraphicsUtils.buildMultiTiledCubemapFaceImage(faceTileImages); 283 284 // rotate top cubeface 180 degrees - misalignment workaround 285 if (i == 4) { 286 finalImg = GraphicsUtils.rotateImage(finalImg); 287 } 288 finalImages[i] = GraphicsUtils.convertBufferedImage2JavaFXImage(finalImg); 289 } 290 // build 16-tiled cubemap faces and crop buffers 291 } else if (StreetsideProperties.SHOW_HIGH_RES_STREETSIDE_IMAGERY.get()) { 292 for (int i = 0; i < CubemapUtils.NUM_SIDES; i++) {293 294 int tileCount = 0; 295 296 BufferedImage[] faceTileImages = new BufferedImage[StreetsideProperties.SHOW_HIGH_RES_STREETSIDE_IMAGERY 297 .get() ? 16 : 4]; 298 299 for (int j = 0; j < CubemapUtils.getMaxCols(); j++) { 300 for (int k = 0; k < CubemapUtils.getMaxRows(); k++) {301 String tileId = String.valueOf(getCubemap().getId() + CubemapUtils.getFaceNumberForCount(i) 302 + CubemapUtils.convertDoubleCountNrto16TileNr( 303 String.valueOf(Integer.valueOf(j).toString() + Integer.valueOf(k).toString())));304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 275 * @see StreetsideCubemap 276 */ 277 private void buildCubemapFaces() { 278 StreetsideViewerDialog.getInstance(); 279 CubemapBox cmb = StreetsideViewerPanel.getCubemapBox(); 280 ImageView[] views = cmb.getViews(); 281 282 Image[] finalImages = new Image[CubemapUtils.NUM_SIDES]; 283 284 // build 4-tiled cubemap faces and crop buffers 285 if (Boolean.FALSE.equals(StreetsideProperties.SHOW_HIGH_RES_STREETSIDE_IMAGERY.get())) { 286 for (int i = 0; i < CubemapUtils.NUM_SIDES; i++) { 287 288 BufferedImage[] faceTileImages = new BufferedImage[CubemapUtils.getMaxCols() 289 * CubemapUtils.getMaxRows()]; 290 291 for (int j = 0; j < (CubemapUtils.getMaxCols() * CubemapUtils.getMaxRows()); j++) { 292 String tileId = getCubemap().getId() + CubemapUtils.getFaceNumberForCount(i) + j; 293 BufferedImage currentTile = tileImages.get(tileId); 294 295 faceTileImages[j] = currentTile; 296 } 297 298 BufferedImage finalImg = GraphicsUtils.buildMultiTiledCubemapFaceImage(faceTileImages); 299 300 // rotate top cubeface 180 degrees - misalignment workaround 301 if (i == 4) { 302 finalImg = GraphicsUtils.rotateImage(finalImg); 303 } 304 finalImages[i] = GraphicsUtils.convertBufferedImage2JavaFXImage(finalImg); 305 } 306 // build 16-tiled cubemap faces and crop buffers 307 } else if (Boolean.TRUE.equals(StreetsideProperties.SHOW_HIGH_RES_STREETSIDE_IMAGERY.get())) { 308 for (int i = 0; i < CubemapUtils.NUM_SIDES; i++) { 309 310 int tileCount = 0; 311 312 BufferedImage[] faceTileImages = new BufferedImage[Boolean.TRUE 313 .equals(StreetsideProperties.SHOW_HIGH_RES_STREETSIDE_IMAGERY.get()) ? 16 : 4]; 314 315 for (int j = 0; j < CubemapUtils.getMaxCols(); j++) { 316 for (int k = 0; k < CubemapUtils.getMaxRows(); k++) { 317 String tileId = getCubemap().getId() + CubemapUtils.getFaceNumberForCount(i) 318 + CubemapUtils.convertDoubleCountNrto16TileNr(j + Integer.toString(k)); 319 BufferedImage currentTile = tileImages.get(tileId); 320 faceTileImages[tileCount++] = currentTile; 321 } 322 } 323 BufferedImage finalImg = GraphicsUtils.buildMultiTiledCubemapFaceImage(faceTileImages); 324 // rotate top cubeface 180 degrees - misalignment workaround 325 if (i == 4) { 326 finalImg = GraphicsUtils.rotateImage(finalImg); 327 } 328 finalImages[i] = GraphicsUtils.convertBufferedImage2JavaFXImage(finalImg); 329 } 330 } 331 332 for (int i = 0; i < CubemapUtils.NUM_SIDES; i++) { 333 views[i].setImage(finalImages[i]); 334 } 320 335 321 336 StreetsideViewerDialog.getInstance().getStreetsideViewerPanel().revalidate(); … … 323 338 324 339 StreetsideViewerPanel.getThreeSixtyDegreeViewerPanel() 325 340 .setScene(StreetsideViewerPanel.getThreeSixtyDegreeViewerPanel().getCubemapScene()); 326 341 327 342 StreetsideViewerPanel.getThreeSixtyDegreeViewerPanel().revalidate(); … … 331 346 long runTime = (endTime - startTime) / 1000; 332 347 333 String message = MessageFormat.format("Completed downloading, assembling and setting cubemap imagery for cubemap {0} in {1} seconds.", cubemap.getId(), 334 runTime); 335 336 if (StreetsideProperties.DEBUGING_ENABLED.get()) { 337 logger.debug(message); 348 String message = MessageFormat.format( 349 "Completed downloading, assembling and setting cubemap imagery for cubemap {0} in {1} seconds.", 350 cubemap.getId(), runTime); 351 352 if (Boolean.TRUE.equals(StreetsideProperties.DEBUGING_ENABLED.get())) { 353 LOGGER.log(Logging.LEVEL_DEBUG, message); 338 354 } 339 355 … … 342 358 currentTileCount = 0; 343 359 isBuilding = false; 344 345 346 360 } 361 362 private void resetTileImages() { 347 363 tileImages = new HashMap<>(); 348 364 } 349 365 350 366 /** 351 * @return the cubemap 352 */ 353 public synchronized StreetsideCubemap getCubemap() { 354 return cubemap; 355 } 356 357 /** 358 * @param cubemap 359 * the cubemap to set 360 */ 361 public static void setCubemap(StreetsideCubemap cubemap) { 362 CubemapBuilder.getInstance().cubemap = cubemap; 363 } 364 365 public static CubemapBuilder getInstance() { 366 if (instance == null) { 367 instance = new CubemapBuilder(); 368 } 369 return instance; 370 } 371 372 /** 373 * @return true, iff the singleton instance is present 374 */ 375 public static boolean hasInstance() { 376 return CubemapBuilder.instance != null; 377 } 378 379 /** 367 * @return the cubemap 368 */ 369 public synchronized StreetsideCubemap getCubemap() { 370 return cubemap; 371 } 372 373 /** 374 * @param cubemap 375 * the cubemap to set 376 */ 377 public static void setCubemap(StreetsideCubemap cubemap) { 378 CubemapBuilder.getInstance().cubemap = cubemap; 379 } 380 381 /** 380 382 * @return the isBuilding 381 383 */ … … 383 385 return isBuilding; 384 386 } 385 386 387 /**388 * Destroys the unique instance of the class.389 */390 public static synchronized void destroyInstance() {391 CubemapBuilder.instance = null;392 }393 387 } -
applications/editors/josm/plugins/MicrosoftStreetside/src/org/openstreetmap/josm/plugins/streetside/cubemap/CubemapUtils.java
r36065 r36194 5 5 import java.util.HashMap; 6 6 import java.util.Map; 7 import java.util.logging.Logger; 7 8 import java.util.stream.Stream; 8 9 9 import org.apache.log4j.Logger;10 10 import org.openstreetmap.josm.plugins.streetside.utils.StreetsideProperties; 11 import org.openstreetmap.josm.tools.Logging; 11 12 12 13 public class CubemapUtils { 13 14 14 final static Logger logger = Logger.getLogger(CubemapUtils.class); 15 public static final String TEST_IMAGE_ID = "00000000"; 16 public static final int NUM_SIDES = 6; 17 private static final Logger LOGGER = Logger.getLogger(CubemapUtils.class.getCanonicalName()); 18 // numerical base for decimal conversion (quaternary in the case of Streetside) 19 private static final int NUM_BASE = 4; 20 public static Map<String[], String> directionConversion = new HashMap<>(); 21 public static Map<String, String> rowCol2StreetsideCellAddressMap = null; 22 23 // Intialize utility map for storing row to Streetside cell number conversions 24 static { 25 26 CubemapUtils.rowCol2StreetsideCellAddressMap = new HashMap<>(); 27 CubemapUtils.rowCol2StreetsideCellAddressMap.put("00", "00"); 28 CubemapUtils.rowCol2StreetsideCellAddressMap.put("01", "01"); 29 CubemapUtils.rowCol2StreetsideCellAddressMap.put("02", "10"); 30 CubemapUtils.rowCol2StreetsideCellAddressMap.put("03", "11"); 31 CubemapUtils.rowCol2StreetsideCellAddressMap.put("10", "02"); 32 CubemapUtils.rowCol2StreetsideCellAddressMap.put("11", "03"); 33 CubemapUtils.rowCol2StreetsideCellAddressMap.put("12", "12"); 34 CubemapUtils.rowCol2StreetsideCellAddressMap.put("13", "13"); 35 CubemapUtils.rowCol2StreetsideCellAddressMap.put("20", "20"); 36 CubemapUtils.rowCol2StreetsideCellAddressMap.put("21", "21"); 37 CubemapUtils.rowCol2StreetsideCellAddressMap.put("22", "30"); 38 CubemapUtils.rowCol2StreetsideCellAddressMap.put("23", "31"); 39 CubemapUtils.rowCol2StreetsideCellAddressMap.put("30", "22"); 40 CubemapUtils.rowCol2StreetsideCellAddressMap.put("31", "23"); 41 CubemapUtils.rowCol2StreetsideCellAddressMap.put("32", "32"); 42 CubemapUtils.rowCol2StreetsideCellAddressMap.put("33", "33"); 43 } 15 44 16 45 private CubemapUtils() { … … 18 47 } 19 48 20 public enum CubefaceType { 21 ONE(1), 22 FOUR(4), 23 SIXTEEN(16); 24 25 private final int value; 26 private static Map<Integer, CubefaceType> map = new HashMap<>(); 27 28 private CubefaceType(int value) { 29 this.value = value; 30 } 31 32 static { 33 for (CubefaceType cubefaceType : CubefaceType.values()) { 34 map.put(cubefaceType.value, cubefaceType); 35 } 36 } 37 38 public static CubefaceType valueOf(int cubefaceType) { 39 return map.get(cubefaceType); 40 } 41 42 public int getValue() { 43 return value; 44 } 45 } 46 47 public static enum CubemapFaces { 48 FRONT("01"), 49 RIGHT("02"), 50 BACK("03"), 51 LEFT("10"), 52 UP("11"), 53 DOWN("12"); 54 55 public static Stream<CubemapFaces> stream() { 56 return Stream.of(CubemapFaces.values()); 57 } 58 59 private final String value; 60 61 CubemapFaces(String value) { 62 this.value = value; 63 } 64 65 public String getValue() { 66 return value; 67 } 68 } 69 70 public static Map<String[],String> directionConversion = new HashMap<>(); 71 72 // numerical base for decimal conversion (quaternary in the case of Streetside) 73 private static final int NUM_BASE = 4; 74 public static final String TEST_IMAGE_ID = "00000000"; 75 public static final int NUM_SIDES = 6; 76 public static Map<String,String> rowCol2StreetsideCellAddressMap = null; 77 78 // Intialize utility map for storing row to Streetside cell number conversions 79 static { 80 81 CubemapUtils.rowCol2StreetsideCellAddressMap = new HashMap<>(); 82 CubemapUtils.rowCol2StreetsideCellAddressMap.put("00","00"); 83 CubemapUtils.rowCol2StreetsideCellAddressMap.put("01","01"); 84 CubemapUtils.rowCol2StreetsideCellAddressMap.put("02","10"); 85 CubemapUtils.rowCol2StreetsideCellAddressMap.put("03","11"); 86 CubemapUtils.rowCol2StreetsideCellAddressMap.put("10","02"); 87 CubemapUtils.rowCol2StreetsideCellAddressMap.put("11","03"); 88 CubemapUtils.rowCol2StreetsideCellAddressMap.put("12","12"); 89 CubemapUtils.rowCol2StreetsideCellAddressMap.put("13","13"); 90 CubemapUtils.rowCol2StreetsideCellAddressMap.put("20","20"); 91 CubemapUtils.rowCol2StreetsideCellAddressMap.put("21","21"); 92 CubemapUtils.rowCol2StreetsideCellAddressMap.put("22","30"); 93 CubemapUtils.rowCol2StreetsideCellAddressMap.put("23","31"); 94 CubemapUtils.rowCol2StreetsideCellAddressMap.put("30","22"); 95 CubemapUtils.rowCol2StreetsideCellAddressMap.put("31","23"); 96 CubemapUtils.rowCol2StreetsideCellAddressMap.put("32","32"); 97 CubemapUtils.rowCol2StreetsideCellAddressMap.put("33","33"); 98 } 99 100 public static int getMaxCols() { 101 return StreetsideProperties.SHOW_HIGH_RES_STREETSIDE_IMAGERY.get()?4:2; 102 } 103 104 public static int getMaxRows() { 105 return getMaxCols(); 106 } 107 108 public static String convertDecimal2Quaternary(long inputNum) { 109 String res = null; 110 final StringBuilder sb = new StringBuilder(); 111 112 if (StreetsideProperties.DEBUGING_ENABLED.get()) { 113 logger.debug(MessageFormat.format("convertDecimal2Quaternary input: {0}", Long.toString(inputNum))); 114 } 115 116 while (inputNum > 0) { 117 sb.append(inputNum % CubemapUtils.NUM_BASE); 118 inputNum /= CubemapUtils.NUM_BASE; 119 } 120 121 res = sb.reverse().toString(); 122 123 if (StreetsideProperties.DEBUGING_ENABLED.get()) { 124 logger.debug(MessageFormat.format("convertDecimal2Quaternary output: {0}", res)); 125 } 126 127 return res; 128 } 129 130 public static String convertQuaternary2Decimal(String inputNum) { 131 132 final String res; 133 134 if (StreetsideProperties.DEBUGING_ENABLED.get()) { 135 logger.debug(MessageFormat.format("convertQuaternary2Decimal input: {0}", inputNum)); 136 } 137 138 int len = inputNum.length(); 49 public static int getMaxCols() { 50 return Boolean.TRUE.equals(StreetsideProperties.SHOW_HIGH_RES_STREETSIDE_IMAGERY.get()) ? 4 : 2; 51 } 52 53 public static int getMaxRows() { 54 return getMaxCols(); 55 } 56 57 public static String convertDecimal2Quaternary(long inputNum) { 58 String res = null; 59 final StringBuilder sb = new StringBuilder(); 60 61 if (Boolean.TRUE.equals(StreetsideProperties.DEBUGING_ENABLED.get())) { 62 LOGGER.log(Logging.LEVEL_DEBUG, 63 MessageFormat.format("convertDecimal2Quaternary input: {0}", Long.toString(inputNum))); 64 } 65 66 while (inputNum > 0) { 67 sb.append(inputNum % CubemapUtils.NUM_BASE); 68 inputNum /= CubemapUtils.NUM_BASE; 69 } 70 71 res = sb.reverse().toString(); 72 73 if (Boolean.TRUE.equals(StreetsideProperties.DEBUGING_ENABLED.get())) { 74 LOGGER.log(Logging.LEVEL_DEBUG, MessageFormat.format("convertDecimal2Quaternary output: {0}", res)); 75 } 76 77 return res; 78 } 79 80 public static String convertQuaternary2Decimal(String inputNum) { 81 82 final String res; 83 84 if (Boolean.TRUE.equals(StreetsideProperties.DEBUGING_ENABLED.get())) { 85 LOGGER.log(Logging.LEVEL_DEBUG, MessageFormat.format("convertQuaternary2Decimal input: {0}", inputNum)); 86 } 87 88 int len = inputNum.length(); 139 89 int power = 1; 140 90 int num = 0; 141 91 int i; 142 92 143 for (i = len - 1; i >= 0; i--) 144 { 145 if (Integer.parseInt(inputNum.substring(i,i+1)) >= CubemapUtils.NUM_BASE) 146 { 147 logger.error("Error converting quadkey " + inputNum + " to decimal."); 148 return "000000000"; 149 } 150 151 num += Integer.parseInt(inputNum.substring(i,i+1)) * power; 152 power = power * CubemapUtils.NUM_BASE; 153 } 154 155 res = Integer.toString(num); 156 157 if (StreetsideProperties.DEBUGING_ENABLED.get()) { 158 logger.debug(MessageFormat.format("convertQuaternary2Decimal output: {0}", res)); 159 } 160 161 return res; 162 } 163 164 public static String getFaceNumberForCount(int count) { 165 final String res; 166 167 switch (count) { 168 case 0: 169 res = CubemapFaces.FRONT.getValue(); 170 break; 171 case 1: 172 res = CubemapFaces.RIGHT.getValue(); 173 break; 174 case 2: 175 res = CubemapFaces.BACK.getValue(); 176 break; 177 case 3: 178 res = CubemapFaces.LEFT.getValue(); 179 break; 180 case 4: 181 res = CubemapFaces.UP.getValue(); 182 break; 183 case 5: 184 res = CubemapFaces.DOWN.getValue(); 185 break; 186 default: 187 res = null; 188 break; 189 } 190 return res; 191 } 192 193 public static int getTileWidth() { 194 // 4-tiled cubemap imagery has a 2-pixel overlap; 16-tiled has a 1-pixel 195 // overlap 196 if (!StreetsideProperties.SHOW_HIGH_RES_STREETSIDE_IMAGERY.get()) { 197 return 255; 198 } else { 199 return 254; 200 } 201 } 202 203 public static int getTileHeight() { 204 // 4-tiled cubemap imagery has a 2-pixel overlap; 16-tiled has a 1-pixel 205 // overlap 206 if(!StreetsideProperties.SHOW_HIGH_RES_STREETSIDE_IMAGERY.get()) { 207 return 255; 208 } else { 209 return 254; 210 } 211 } 212 213 public static int getCount4FaceNumber(String faceString) { 214 215 final int tileAddress; 216 217 switch (faceString) { 218 // back 219 case "03": tileAddress = 0; 220 break; 221 // down 222 case "12": tileAddress = 1; 223 break; 224 // front 225 case "01": tileAddress = 2; 226 break; 227 // left 228 case "10": tileAddress = 3; 229 break; 230 // right 231 case "02": tileAddress = 4; 232 break; 233 // up 234 case "11": tileAddress = 5; 235 break; 236 default: tileAddress = 6; 237 break; 238 } 239 240 return tileAddress; 241 } 242 243 public static String getFaceIdFromTileId(String tileId) { 244 // magic numbers - the face id is contained in the 16th and 17th positions 245 return tileId.substring(16, 18); 246 } 247 248 public static String convertDoubleCountNrto16TileNr(String countNr) { 249 String tileAddress; 250 251 switch (countNr) { 252 case "00": tileAddress = "00"; 253 break; 254 case "01": tileAddress = "01"; 255 break; 256 case "02": tileAddress = "10"; 257 break; 258 case "03": tileAddress = "11"; 259 break; 260 case "10": tileAddress = "02"; 261 break; 262 case "11": tileAddress = "03"; 263 break; 264 case "12": tileAddress = "12"; 265 break; 266 case "13": tileAddress = "13"; 267 break; 268 case "20": tileAddress = "20"; 269 break; 270 case "21": tileAddress = "21"; 271 break; 272 case "22": tileAddress = "30"; 273 break; 274 case "23": tileAddress = "31"; 275 break; 276 case "30": tileAddress = "22"; 277 break; 278 case "31": tileAddress = "23"; 279 break; 280 case "32": tileAddress = "32"; 281 break; 282 case "33": tileAddress = "33"; 283 break; 284 // shouldn't happen 285 default: tileAddress = null; 286 break; 287 } 288 289 return tileAddress; 290 } 93 for (i = len - 1; i >= 0; i--) { 94 if (Integer.parseInt(inputNum.substring(i, i + 1)) >= CubemapUtils.NUM_BASE) { 95 LOGGER.log(Logging.LEVEL_ERROR, "Error converting quadkey " + inputNum + " to decimal."); 96 return "000000000"; 97 } 98 99 num += Integer.parseInt(inputNum.substring(i, i + 1)) * power; 100 power = power * CubemapUtils.NUM_BASE; 101 } 102 103 res = Integer.toString(num); 104 105 if (Boolean.TRUE.equals(StreetsideProperties.DEBUGING_ENABLED.get())) { 106 LOGGER.log(Logging.LEVEL_DEBUG, MessageFormat.format("convertQuaternary2Decimal output: {0}", res)); 107 } 108 109 return res; 110 } 111 112 public static String getFaceNumberForCount(int count) { 113 final String res; 114 115 switch (count) { 116 case 0: 117 res = CubemapFaces.FRONT.getValue(); 118 break; 119 case 1: 120 res = CubemapFaces.RIGHT.getValue(); 121 break; 122 case 2: 123 res = CubemapFaces.BACK.getValue(); 124 break; 125 case 3: 126 res = CubemapFaces.LEFT.getValue(); 127 break; 128 case 4: 129 res = CubemapFaces.UP.getValue(); 130 break; 131 case 5: 132 res = CubemapFaces.DOWN.getValue(); 133 break; 134 default: 135 res = null; 136 break; 137 } 138 return res; 139 } 140 141 public static int getTileWidth() { 142 // 4-tiled cubemap imagery has a 2-pixel overlap; 16-tiled has a 1-pixel 143 // overlap 144 if (Boolean.FALSE.equals(StreetsideProperties.SHOW_HIGH_RES_STREETSIDE_IMAGERY.get())) { 145 return 255; 146 } else { 147 return 254; 148 } 149 } 150 151 public static int getTileHeight() { 152 // 4-tiled cubemap imagery has a 2-pixel overlap; 16-tiled has a 1-pixel 153 // overlap 154 if (Boolean.FALSE.equals(StreetsideProperties.SHOW_HIGH_RES_STREETSIDE_IMAGERY.get())) { 155 return 255; 156 } else { 157 return 254; 158 } 159 } 160 161 public static int getCount4FaceNumber(String faceString) { 162 163 final int tileAddress; 164 165 switch (faceString) { 166 // back 167 case "03": 168 tileAddress = 0; 169 break; 170 // down 171 case "12": 172 tileAddress = 1; 173 break; 174 // front 175 case "01": 176 tileAddress = 2; 177 break; 178 // left 179 case "10": 180 tileAddress = 3; 181 break; 182 // right 183 case "02": 184 tileAddress = 4; 185 break; 186 // up 187 case "11": 188 tileAddress = 5; 189 break; 190 default: 191 tileAddress = 6; 192 break; 193 } 194 195 return tileAddress; 196 } 197 198 public static String getFaceIdFromTileId(String tileId) { 199 // magic numbers - the face id is contained in the 16th and 17th positions 200 return tileId.substring(16, 18); 201 } 202 203 public static String convertDoubleCountNrto16TileNr(String countNr) { 204 String tileAddress; 205 206 switch (countNr) { 207 case "00": 208 tileAddress = "00"; 209 break; 210 case "01": 211 tileAddress = "01"; 212 break; 213 case "02": 214 tileAddress = "10"; 215 break; 216 case "03": 217 tileAddress = "11"; 218 break; 219 case "10": 220 tileAddress = "02"; 221 break; 222 case "11": 223 tileAddress = "03"; 224 break; 225 case "12": 226 tileAddress = "12"; 227 break; 228 case "13": 229 tileAddress = "13"; 230 break; 231 case "20": 232 tileAddress = "20"; 233 break; 234 case "21": 235 tileAddress = "21"; 236 break; 237 case "22": 238 tileAddress = "30"; 239 break; 240 case "23": 241 tileAddress = "31"; 242 break; 243 case "30": 244 tileAddress = "22"; 245 break; 246 case "31": 247 tileAddress = "23"; 248 break; 249 case "32": 250 tileAddress = "32"; 251 break; 252 case "33": 253 tileAddress = "33"; 254 break; 255 // shouldn't happen 256 default: 257 tileAddress = null; 258 break; 259 } 260 261 return tileAddress; 262 } 263 264 public enum CubefaceType { 265 ONE(1), FOUR(4), SIXTEEN(16); 266 267 private static final Map<Integer, CubefaceType> map = new HashMap<>(); 268 269 static { 270 for (CubefaceType cubefaceType : CubefaceType.values()) { 271 map.put(cubefaceType.value, cubefaceType); 272 } 273 } 274 275 private final int value; 276 277 CubefaceType(int value) { 278 this.value = value; 279 } 280 281 public static CubefaceType valueOf(int cubefaceType) { 282 return map.get(cubefaceType); 283 } 284 285 public int getValue() { 286 return value; 287 } 288 } 289 290 public enum CubemapFaces { 291 FRONT("01"), RIGHT("02"), BACK("03"), LEFT("10"), UP("11"), DOWN("12"); 292 293 private final String value; 294 295 CubemapFaces(String value) { 296 this.value = value; 297 } 298 299 public static Stream<CubemapFaces> stream() { 300 return Stream.of(CubemapFaces.values()); 301 } 302 303 public String getValue() { 304 return value; 305 } 306 } 291 307 } -
applications/editors/josm/plugins/MicrosoftStreetside/src/org/openstreetmap/josm/plugins/streetside/cubemap/ITileDownloadingTaskListener.java
r34428 r36194 1 // License: GPL. For details, see LICENSE file.1 // License: GPL. For details, see LICENSE file. 2 2 package org.openstreetmap.josm.plugins.streetside.cubemap; 3 3 … … 10 10 public interface ITileDownloadingTaskListener { 11 11 12 /** 13 * Fired when a cubemap tile image is downloaded by a download worker. 14 * @param imageId image id 15 */ 16 void tileAdded(String imageId); 12 /** 13 * Fired when a cubemap tile image is downloaded by a download worker. 14 * 15 * @param imageId image id 16 */ 17 void tileAdded(String imageId); 17 18 18 19 } -
applications/editors/josm/plugins/MicrosoftStreetside/src/org/openstreetmap/josm/plugins/streetside/cubemap/TileDownloadingTask.java
r34428 r36194 10 10 import java.util.concurrent.Callable; 11 11 import java.util.concurrent.CopyOnWriteArrayList; 12 import java.util.logging.Logger; 12 13 13 14 import javax.imageio.ImageIO; 14 15 15 import org.apache.log4j.Logger;16 16 import org.openstreetmap.josm.plugins.streetside.cache.StreetsideCache; 17 17 import org.openstreetmap.josm.plugins.streetside.utils.StreetsideProperties; 18 18 import org.openstreetmap.josm.plugins.streetside.utils.StreetsideURL; 19 20 import us.monoid.web.Resty; 19 import org.openstreetmap.josm.tools.Logging; 21 20 22 21 public class TileDownloadingTask implements Callable<List<String>> { 23 22 24 final static Logger logger = Logger.getLogger(TileDownloadingTask.class); 23 private static final Logger LOGGER = Logger.getLogger(TileDownloadingTask.class.getCanonicalName()); 24 /** 25 * Listeners of the class. 26 */ 27 private final List<ITileDownloadingTaskListener> listeners = new CopyOnWriteArrayList<>(); 28 protected CubemapBuilder cb; 29 boolean cancelled; 30 private String tileId; 31 private StreetsideCache cache; 25 32 26 private String tileId; 27 private StreetsideCache cache; 28 protected CubemapBuilder cb; 33 public TileDownloadingTask(String id) { 34 tileId = id; 35 cb = CubemapBuilder.getInstance(); 36 addListener(CubemapBuilder.getInstance()); 37 } 29 38 30 /** 31 * Listeners of the class. 32 */ 33 private final List<ITileDownloadingTaskListener> listeners = new CopyOnWriteArrayList<>(); 39 /** 40 * Adds a new listener. 41 * 42 * @param lis Listener to be added. 43 */ 44 public final void addListener(final ITileDownloadingTaskListener lis) { 45 listeners.add(lis); 46 } 34 47 35 boolean cancelled = false; 48 /** 49 * @return the tileId 50 */ 51 public String getId() { 52 return tileId; 53 } 36 54 37 public TileDownloadingTask(String id) { 38 tileId = id; 39 cb = CubemapBuilder.getInstance(); 40 addListener(CubemapBuilder.getInstance()); 41 } 55 /** 56 * @param id the tileId to set 57 */ 58 public void setId(String id) { 59 tileId = id; 60 } 42 61 43 /** 44 * Adds a new listener. 45 * 46 * @param lis Listener to be added. 47 */ 48 public final void addListener(final ITileDownloadingTaskListener lis) { 49 listeners.add(lis); 50 } 62 /** 63 * @return the cache 64 */ 65 public StreetsideCache getCache() { 66 return cache; 67 } 51 68 52 53 * @return the tileId 54 55 public String getId() {56 return tileId;57 69 /** 70 * @param cache the cache to set 71 */ 72 public void setCache(StreetsideCache cache) { 73 this.cache = cache; 74 } 58 75 59 60 * @param id the tileId to set 61 62 public void setId(String id) {63 tileId = id;64 76 /** 77 * @return the cb 78 */ 79 public CubemapBuilder getCb() { 80 return cb; 81 } 65 82 66 67 * @return the cache 68 69 public StreetsideCache getCache() {70 return cache;71 83 /** 84 * @param cb the cb to set 85 */ 86 public void setCb(CubemapBuilder cb) { 87 this.cb = cb; 88 } 72 89 73 /** 74 * @param cache the cache to set 75 */ 76 public void setCache(StreetsideCache cache) { 77 this.cache = cache; 78 } 79 80 /** 81 * @return the cb 82 */ 83 public CubemapBuilder getCb() { 84 return cb; 85 } 86 87 /** 88 * @param cb the cb to set 89 */ 90 public void setCb(CubemapBuilder cb) { 91 this.cb = cb; 92 } 93 94 /** 95 * @param cancelled the cancelled to set 96 */ 97 public void setCancelled(boolean cancelled) { 98 this.cancelled = cancelled; 99 } 90 /** 91 * @param cancelled the cancelled to set 92 */ 93 public void setCancelled(boolean cancelled) { 94 this.cancelled = cancelled; 95 } 100 96 101 97 @Override … … 104 100 List<String> res = new ArrayList<>(); 105 101 106 if ( StreetsideProperties.DOWNLOAD_CUBEFACE_TILES_TOGETHER.get()) {102 if (Boolean.TRUE.equals(StreetsideProperties.DOWNLOAD_CUBEFACE_TILES_TOGETHER.get())) { 107 103 // download all imagery for each cubeface at once 108 if ( !StreetsideProperties.SHOW_HIGH_RES_STREETSIDE_IMAGERY.get()) {104 if (Boolean.FALSE.equals(StreetsideProperties.SHOW_HIGH_RES_STREETSIDE_IMAGERY.get())) { 109 105 // download low-res imagery 110 106 int tileNr = 0; 111 107 for (int j = 0; j < CubemapUtils.getMaxCols(); j++) { 112 108 for (int k = 0; k < CubemapUtils.getMaxRows(); k++) { 113 String quadKey = String.valueOf(tileId + Integer.valueOf(tileNr++).toString());109 String quadKey = tileId + tileNr++; 114 110 res.add(downloadTile(quadKey)); 115 111 } … … 119 115 for (int j = 0; j < CubemapUtils.getMaxCols(); j++) { 120 116 for (int k = 0; k < CubemapUtils.getMaxRows(); k++) { 121 String quadKey = String 122 .valueOf(tileId + String.valueOf(Integer.valueOf(j).toString() + Integer.valueOf(k).toString())); 117 String quadKey = tileId + j + k; 123 118 res.add(downloadTile(quadKey)); 124 119 } 125 120 } 126 121 } 127 // task downloads just one tile122 // task downloads just one tile 128 123 } else { 129 124 res.add(downloadTile(tileId)); … … 138 133 139 134 try { 140 img = ImageIO 141 .read(new Resty().bytes(StreetsideURL.VirtualEarth.streetsideTile(tileId, false).toExternalForm()).stream()); 135 img = ImageIO.read(StreetsideURL.VirtualEarth.streetsideTile(tileId, false)); 142 136 143 137 if (img == null) { 144 logger.error("Download of BufferedImage " + tileId + " is null!");138 LOGGER.log(Logging.LEVEL_ERROR, "Download of BufferedImage " + tileId + " is null!"); 145 139 } 146 140 … … 149 143 fireTileAdded(tileId); 150 144 151 if ( StreetsideProperties.DEBUGING_ENABLED.get()) {145 if (Boolean.TRUE.equals(StreetsideProperties.DEBUGING_ENABLED.get())) { 152 146 long endTime = System.currentTimeMillis(); 153 147 long runTime = (endTime - startTime) / 1000; 154 logger.debug(MessageFormat.format("Loaded image for {0} in {1} seconds.", tileId, runTime)); 148 LOGGER.log(Logging.LEVEL_DEBUG, 149 MessageFormat.format("Loaded image for {0} in {1} seconds.", tileId, runTime)); 155 150 } 156 151 } catch (IOException e) { 157 logger.error(MessageFormat.format("Error downloading image for tileId {0}", tileId));152 LOGGER.log(Logging.LEVEL_ERROR, MessageFormat.format("Error downloading image for tileId {0}", tileId), e); 158 153 return null; 159 154 } … … 161 156 } 162 157 163 164 165 158 private void fireTileAdded(String id) { 159 listeners.stream().filter(Objects::nonNull).forEach(lis -> lis.tileAdded(id)); 160 } 166 161 } -
applications/editors/josm/plugins/MicrosoftStreetside/src/org/openstreetmap/josm/plugins/streetside/gui/StreetsideExportDialog.java
r34429 r36194 20 20 import org.openstreetmap.josm.plugins.streetside.StreetsideLayer; 21 21 22 23 22 /** 24 23 * GUI for exporting images. … … 30 29 31 30 private static final long serialVersionUID = -2746815082016025516L; 32 /** Button to export all downloaded images. */ 31 /** 32 * Button to export all downloaded images. 33 */ 33 34 public final JRadioButton all; 34 35 /** … … 41 42 */ 42 43 public final JRadioButton selected; 43 /** Group of button containing all the options. */ 44 /** 45 * Group of button containing all the options. 46 */ 44 47 public final ButtonGroup group; 45 48 private final JButton choose; 46 49 private final JLabel path; 47 /** File chooser. */ 50 private final JButton ok; 51 /** 52 * File chooser. 53 */ 48 54 public JFileChooser chooser; 49 private final JButton ok;50 55 51 56 /** 52 57 * Main constructor. 53 58 * 54 * @param ok 55 * The button for to OK option. 59 * @param ok The button for to OK option. 56 60 */ 57 61 public StreetsideExportDialog(JButton ok) { … … 75 79 sequence.setEnabled(StreetsideLayer.getInstance().getData().getSelectedImage() instanceof StreetsideImage); 76 80 if (StreetsideLayer.getInstance().getData().getMultiSelectedImages().isEmpty()) { 77 selected.setEnabled(false);81 selected.setEnabled(false); 78 82 } 79 83 … … 103 107 public void actionPerformed(ActionEvent e) { 104 108 chooser = new JFileChooser(); 105 chooser.setCurrentDirectory(new java.io.File(System 106 .getProperty("user.home"))); 109 chooser.setCurrentDirectory(new java.io.File(System.getProperty("user.home"))); 107 110 chooser.setDialogTitle(tr("Select a directory")); 108 111 chooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY); … … 121 124 * 122 125 * @author nokutu 123 *124 126 */ 125 127 public class RewriteButtonAction extends AbstractAction { 126 128 127 129 private static final long serialVersionUID = 1035332841101190301L; 128 129 private String lastPath;130 130 private final StreetsideExportDialog dlg; 131 private String lastPath; 131 132 132 133 /** 133 134 * Main constructor. 134 135 * 135 * @param dlg 136 * Parent dialog. 136 * @param dlg Parent dialog. 137 137 */ 138 138 public RewriteButtonAction(StreetsideExportDialog dlg) { … … 143 143 @Override 144 144 public void actionPerformed(ActionEvent arg0) { 145 choose 146 .setEnabled(true); 145 choose.setEnabled(true); 147 146 if (lastPath != null) { 148 147 dlg.path.setText(lastPath); -
applications/editors/josm/plugins/MicrosoftStreetside/src/org/openstreetmap/josm/plugins/streetside/gui/StreetsideImageDisplay.java
r34349 r36194 33 33 import org.openstreetmap.josm.plugins.streetside.utils.StreetsideProperties; 34 34 35 36 35 /** 37 36 * This object is a responsible JComponent which lets you zoom and drag. It is … … 48 47 private final Collection<ImageDetection> detections = new ArrayList<>(); 49 48 50 /** The image currently displayed */ 49 /** 50 * The image currently displayed 51 */ 51 52 private volatile BufferedImage image; 52 53 … … 62 63 */ 63 64 private Rectangle selectedRect; 65 66 /** 67 * Main constructor. 68 */ 69 public StreetsideImageDisplay() { 70 ImgDisplayMouseListener mouseListener = new ImgDisplayMouseListener(); 71 addMouseListener(mouseListener); 72 addMouseWheelListener(mouseListener); 73 addMouseMotionListener(mouseListener); 74 75 StreetsideProperties.SHOW_DETECTED_SIGNS.addListener(valChanged -> repaint()); 76 } 77 78 private static Point getCenterImgCoord(Rectangle visibleRect) { 79 return new Point(visibleRect.x + visibleRect.width / 2, visibleRect.y + visibleRect.height / 2); 80 } 81 82 /** 83 * calculateDrawImageRectangle 84 * 85 * @param imgRect the part of the image that should be drawn (in image coordinates) 86 * @param compRect the part of the component where the image should be drawn (in 87 * component coordinates) 88 * @return the part of compRect with the same width/height ratio as the image 89 */ 90 private static Rectangle calculateDrawImageRectangle(Rectangle imgRect, Rectangle compRect) { 91 int x = 0; 92 int y = 0; 93 int w = compRect.width; 94 int h = compRect.height; 95 int wFact = w * imgRect.height; 96 int hFact = h * imgRect.width; 97 if (wFact != hFact) { 98 if (wFact > hFact) { 99 w = hFact / imgRect.height; 100 x = (compRect.width - w) / 2; 101 } else { 102 h = wFact / imgRect.width; 103 y = (compRect.height - h) / 2; 104 } 105 } 106 return new Rectangle(x + compRect.x, y + compRect.y, w, h); 107 } 108 109 private static void checkVisibleRectPos(Image image, Rectangle visibleRect) { 110 if (visibleRect.x < 0) { 111 visibleRect.x = 0; 112 } 113 if (visibleRect.y < 0) { 114 visibleRect.y = 0; 115 } 116 if (visibleRect.x + visibleRect.width > image.getWidth(null)) { 117 visibleRect.x = image.getWidth(null) - visibleRect.width; 118 } 119 if (visibleRect.y + visibleRect.height > image.getHeight(null)) { 120 visibleRect.y = image.getHeight(null) - visibleRect.height; 121 } 122 } 123 124 private static void checkVisibleRectSize(Image image, Rectangle visibleRect) { 125 if (visibleRect.width > image.getWidth(null)) { 126 visibleRect.width = image.getWidth(null); 127 } 128 if (visibleRect.height > image.getHeight(null)) { 129 visibleRect.height = image.getHeight(null); 130 } 131 } 132 133 /** 134 * Sets a new picture to be displayed. 135 * 136 * @param image The picture to be displayed. 137 * @param detections image detections 138 */ 139 public void setImage(BufferedImage image, Collection<ImageDetection> detections) { 140 synchronized (this) { 141 this.image = image; 142 this.detections.clear(); 143 if (detections != null) { 144 this.detections.addAll(detections); 145 } 146 selectedRect = null; 147 if (image != null) 148 visibleRect = new Rectangle(0, 0, image.getWidth(null), image.getHeight(null)); 149 } 150 repaint(); 151 } 152 153 /** 154 * Returns the picture that is being displayed 155 * 156 * @return The picture that is being displayed. 157 */ 158 public BufferedImage getImage() { 159 return image; 160 } 161 162 /** 163 * Paints the visible part of the picture. 164 */ 165 @Override 166 public void paintComponent(Graphics g) { 167 Image image; 168 Rectangle visibleRect; 169 synchronized (this) { 170 image = this.image; 171 visibleRect = this.visibleRect; 172 } 173 if (image == null) { 174 g.setColor(Color.black); 175 String noImageStr = StreetsideLayer.hasInstance() ? tr("No image selected") 176 : tr("Press \"{0}\" to download images", StreetsideDownloadAction.SHORTCUT.getKeyText()); 177 Rectangle2D noImageSize = g.getFontMetrics(g.getFont()).getStringBounds(noImageStr, g); 178 Dimension size = getSize(); 179 g.drawString(noImageStr, (int) ((size.width - noImageSize.getWidth()) / 2), 180 (int) ((size.height - noImageSize.getHeight()) / 2)); 181 } else { 182 Rectangle target = calculateDrawImageRectangle(visibleRect); 183 g.drawImage(image, target.x, target.y, target.x + target.width, target.y + target.height, visibleRect.x, 184 visibleRect.y, visibleRect.x + visibleRect.width, visibleRect.y + visibleRect.height, null); 185 if (selectedRect != null) { 186 Point topLeft = img2compCoord(visibleRect, selectedRect.x, selectedRect.y); 187 Point bottomRight = img2compCoord(visibleRect, selectedRect.x + selectedRect.width, 188 selectedRect.y + selectedRect.height); 189 g.setColor(new Color(128, 128, 128, 180)); 190 g.fillRect(target.x, target.y, target.width, topLeft.y - target.y); 191 g.fillRect(target.x, target.y, topLeft.x - target.x, target.height); 192 g.fillRect(bottomRight.x, target.y, target.x + target.width - bottomRight.x, target.height); 193 g.fillRect(target.x, bottomRight.y, target.width, target.y + target.height - bottomRight.y); 194 g.setColor(Color.black); 195 g.drawRect(topLeft.x, topLeft.y, bottomRight.x - topLeft.x, bottomRight.y - topLeft.y); 196 } 197 198 if (Boolean.TRUE.equals(StreetsideProperties.SHOW_DETECTED_SIGNS.get())) { 199 Point upperLeft = img2compCoord(visibleRect, 0, 0); 200 Point lowerRight = img2compCoord(visibleRect, getImage().getWidth(), getImage().getHeight()); 201 202 // Transformation, which can convert you a Shape relative to the unit square to a Shape relative to the Component 203 AffineTransform unit2compTransform = AffineTransform.getTranslateInstance(upperLeft.getX(), 204 upperLeft.getY()); 205 unit2compTransform.concatenate(AffineTransform.getScaleInstance(lowerRight.getX() - upperLeft.getX(), 206 lowerRight.getY() - upperLeft.getY())); 207 208 final Graphics2D g2d = (Graphics2D) g; 209 g2d.setStroke(new BasicStroke(2)); 210 for (ImageDetection d : detections) { 211 final Shape shape = d.getShape().createTransformedShape(unit2compTransform); 212 g2d.setColor(d.isTrafficSign() ? StreetsideColorScheme.IMAGEDETECTION_TRAFFICSIGN 213 : StreetsideColorScheme.IMAGEDETECTION_UNKNOWN); 214 g2d.draw(shape); 215 if (d.isTrafficSign()) { 216 g2d.drawImage(MapObject.getIcon(d.getValue()).getImage(), shape.getBounds().x, 217 shape.getBounds().y, shape.getBounds().width, shape.getBounds().height, null); 218 } 219 } 220 } 221 } 222 } 223 224 private Point img2compCoord(Rectangle visibleRect, int xImg, int yImg) { 225 Rectangle drawRect = calculateDrawImageRectangle(visibleRect); 226 return new Point(drawRect.x + ((xImg - visibleRect.x) * drawRect.width) / visibleRect.width, 227 drawRect.y + ((yImg - visibleRect.y) * drawRect.height) / visibleRect.height); 228 } 229 230 private Point comp2imgCoord(Rectangle visibleRect, int xComp, int yComp) { 231 Rectangle drawRect = calculateDrawImageRectangle(visibleRect); 232 return new Point(visibleRect.x + ((xComp - drawRect.x) * visibleRect.width) / drawRect.width, 233 visibleRect.y + ((yComp - drawRect.y) * visibleRect.height) / drawRect.height); 234 } 235 236 private Rectangle calculateDrawImageRectangle(Rectangle visibleRect) { 237 return calculateDrawImageRectangle(visibleRect, new Rectangle(0, 0, getSize().width, getSize().height)); 238 } 239 240 /** 241 * Zooms to 1:1 and, if it is already in 1:1, to best fit. 242 */ 243 public void zoomBestFitOrOne() { 244 Image image; 245 Rectangle visibleRect; 246 synchronized (this) { 247 image = this.image; 248 visibleRect = this.visibleRect; 249 } 250 if (image == null) 251 return; 252 if (visibleRect.width != image.getWidth(null) || visibleRect.height != image.getHeight(null)) { 253 // The display is not at best fit. => Zoom to best fit 254 visibleRect = new Rectangle(0, 0, image.getWidth(null), image.getHeight(null)); 255 } else { 256 // The display is at best fit => zoom to 1:1 257 Point center = getCenterImgCoord(visibleRect); 258 visibleRect = new Rectangle(center.x - getWidth() / 2, center.y - getHeight() / 2, getWidth(), getHeight()); 259 checkVisibleRectPos(image, visibleRect); 260 } 261 synchronized (this) { 262 this.visibleRect = visibleRect; 263 } 264 repaint(); 265 } 64 266 65 267 private class ImgDisplayMouseListener implements MouseListener, MouseWheelListener, MouseMotionListener { … … 121 323 // cursor doesn't move on the image. 122 324 Rectangle drawRect = calculateDrawImageRectangle(visibleRect); 123 visibleRect.x = mousePointInImg.x 124 + ((drawRect.x - e.getX()) * visibleRect.width) / drawRect.width; 125 visibleRect.y = mousePointInImg.y 126 + ((drawRect.y - e.getY()) * visibleRect.height) / drawRect.height; 325 visibleRect.x = mousePointInImg.x + ((drawRect.x - e.getX()) * visibleRect.width) / drawRect.width; 326 visibleRect.y = mousePointInImg.y + ((drawRect.y - e.getY()) * visibleRect.height) / drawRect.height; 127 327 // The position is also limited by the image size 128 328 checkVisibleRectPos(image, visibleRect); … … 134 334 } 135 335 136 /** Center the display on the point that has been clicked */ 336 /** 337 * Center the display on the point that has been clicked 338 */ 137 339 @Override 138 340 public void mouseClicked(MouseEvent e) { … … 146 348 if (image != null && Math.min(getSize().getWidth(), getSize().getHeight()) > 0) { 147 349 if (e.getButton() == StreetsideProperties.PICTURE_OPTION_BUTTON.get()) { 148 if (!StreetsideImageDisplay.this.visibleRect.equals(new Rectangle(0, 0, image.getWidth(null), image.getHeight(null)))) { 350 if (!StreetsideImageDisplay.this.visibleRect 351 .equals(new Rectangle(0, 0, image.getWidth(null), image.getHeight(null)))) { 149 352 // Zooms to 1:1 150 StreetsideImageDisplay.this.visibleRect = new Rectangle(0, 0, 151 image.get Width(null), image.getHeight(null));353 StreetsideImageDisplay.this.visibleRect = new Rectangle(0, 0, image.getWidth(null), 354 image.getHeight(null)); 152 355 } else { 153 356 // Zooms to best fit. 154 StreetsideImageDisplay.this.visibleRect = new Rectangle( 155 0, 357 StreetsideImageDisplay.this.visibleRect = new Rectangle(0, 156 358 (image.getHeight(null) - (image.getWidth(null) * getHeight()) / getWidth()) / 2, 157 image.getWidth(null), 158 (image.getWidth(null) * getHeight()) / getWidth() 159 ); 359 image.getWidth(null), (image.getWidth(null) * getHeight()) / getWidth()); 160 360 } 161 361 StreetsideImageDisplay.this.repaint(); … … 240 440 Point p = comp2imgCoord(visibleRect, e.getX(), e.getY()); 241 441 checkPointInVisibleRect(p, visibleRect); 242 Rectangle rect = new Rectangle(p.x < mousePointInImg.x ? p.x 243 : mousePointInImg.x, p.y < mousePointInImg.y ? p.y 244 : mousePointInImg.y, p.x < mousePointInImg.x ? mousePointInImg.x 245 - p.x : p.x - mousePointInImg.x, 246 p.y < mousePointInImg.y ? mousePointInImg.y - p.y : p.y 247 - mousePointInImg.y); 442 Rectangle rect = new Rectangle(p.x < mousePointInImg.x ? p.x : mousePointInImg.x, 443 p.y < mousePointInImg.y ? p.y : mousePointInImg.y, 444 p.x < mousePointInImg.x ? mousePointInImg.x - p.x : p.x - mousePointInImg.x, 445 p.y < mousePointInImg.y ? mousePointInImg.y - p.y : p.y - mousePointInImg.y); 248 446 checkVisibleRectSize(image, rect); 249 447 checkVisibleRectPos(image, rect); … … 273 471 // Check that the zoom doesn't exceed 2:1 274 472 if (selectedRect.width < getSize().width / 2) { 275 473 selectedRect.width = getSize().width / 2; 276 474 } 277 475 if (selectedRect.height < getSize().height / 2) { 278 476 selectedRect.height = getSize().height / 2; 279 477 } 280 478 // Set the same ratio for the visible rectangle and the display … … 289 487 // Keep the center of the selection 290 488 if (selectedRect.width != oldWidth) { 291 489 selectedRect.x -= (selectedRect.width - oldWidth) / 2; 292 490 } 293 491 if (selectedRect.height != oldHeight) { 294 492 selectedRect.y -= (selectedRect.height - oldHeight) / 2; 295 493 } 296 494 checkVisibleRectSize(image, selectedRect); … … 334 532 } 335 533 } 336 337 /**338 * Main constructor.339 */340 public StreetsideImageDisplay() {341 ImgDisplayMouseListener mouseListener = new ImgDisplayMouseListener();342 addMouseListener(mouseListener);343 addMouseWheelListener(mouseListener);344 addMouseMotionListener(mouseListener);345 346 StreetsideProperties.SHOW_DETECTED_SIGNS.addListener(valChanged -> repaint());347 }348 349 /**350 * Sets a new picture to be displayed.351 *352 * @param image The picture to be displayed.353 * @param detections image detections354 */355 public void setImage(BufferedImage image, Collection<ImageDetection> detections) {356 synchronized (this) {357 this.image = image;358 this.detections.clear();359 if (detections != null) {360 this.detections.addAll(detections);361 }362 selectedRect = null;363 if (image != null)364 visibleRect = new Rectangle(0, 0, image.getWidth(null),365 image.getHeight(null));366 }367 repaint();368 }369 370 /**371 * Returns the picture that is being displayed372 *373 * @return The picture that is being displayed.374 */375 public BufferedImage getImage() {376 return image;377 }378 379 /**380 * Paints the visible part of the picture.381 */382 @Override383 public void paintComponent(Graphics g) {384 Image image;385 Rectangle visibleRect;386 synchronized (this) {387 image = this.image;388 visibleRect = this.visibleRect;389 }390 if (image == null) {391 g.setColor(Color.black);392 String noImageStr = StreetsideLayer.hasInstance() ? tr("No image selected") : tr("Press \"{0}\" to download images", StreetsideDownloadAction.SHORTCUT.getKeyText());393 Rectangle2D noImageSize = g.getFontMetrics(g.getFont()).getStringBounds(394 noImageStr, g);395 Dimension size = getSize();396 g.drawString(noImageStr,397 (int) ((size.width - noImageSize.getWidth()) / 2),398 (int) ((size.height - noImageSize.getHeight()) / 2));399 } else {400 Rectangle target = calculateDrawImageRectangle(visibleRect);401 g.drawImage(image, target.x, target.y, target.x + target.width, target.y402 + target.height, visibleRect.x, visibleRect.y, visibleRect.x403 + visibleRect.width, visibleRect.y + visibleRect.height, null);404 if (selectedRect != null) {405 Point topLeft = img2compCoord(visibleRect, selectedRect.x,406 selectedRect.y);407 Point bottomRight = img2compCoord(visibleRect, selectedRect.x408 + selectedRect.width, selectedRect.y + selectedRect.height);409 g.setColor(new Color(128, 128, 128, 180));410 g.fillRect(target.x, target.y, target.width, topLeft.y - target.y);411 g.fillRect(target.x, target.y, topLeft.x - target.x, target.height);412 g.fillRect(bottomRight.x, target.y, target.x + target.width413 - bottomRight.x, target.height);414 g.fillRect(target.x, bottomRight.y, target.width, target.y415 + target.height - bottomRight.y);416 g.setColor(Color.black);417 g.drawRect(topLeft.x, topLeft.y, bottomRight.x - topLeft.x,418 bottomRight.y - topLeft.y);419 }420 421 if (StreetsideProperties.SHOW_DETECTED_SIGNS.get()) {422 Point upperLeft = img2compCoord(visibleRect, 0, 0);423 Point lowerRight = img2compCoord(visibleRect, getImage().getWidth(), getImage().getHeight());424 425 // Transformation, which can convert you a Shape relative to the unit square to a Shape relative to the Component426 AffineTransform unit2compTransform = AffineTransform.getTranslateInstance(upperLeft.getX(), upperLeft.getY());427 unit2compTransform.concatenate(AffineTransform.getScaleInstance(lowerRight.getX() - upperLeft.getX(), lowerRight.getY() - upperLeft.getY()));428 429 final Graphics2D g2d = (Graphics2D) g;430 g2d.setStroke(new BasicStroke(2));431 for (ImageDetection d : detections) {432 final Shape shape = d.getShape().createTransformedShape(unit2compTransform);433 g2d.setColor(d.isTrafficSign() ? StreetsideColorScheme.IMAGEDETECTION_TRAFFICSIGN : StreetsideColorScheme.IMAGEDETECTION_UNKNOWN);434 g2d.draw(shape);435 if (d.isTrafficSign()) {436 g2d.drawImage(437 MapObject.getIcon(d.getValue()).getImage(),438 shape.getBounds().x, shape.getBounds().y,439 shape.getBounds().width, shape.getBounds().height,440 null441 );442 }443 }444 }445 }446 }447 448 private Point img2compCoord(Rectangle visibleRect, int xImg, int yImg) {449 Rectangle drawRect = calculateDrawImageRectangle(visibleRect);450 return new Point(drawRect.x + ((xImg - visibleRect.x) * drawRect.width)451 / visibleRect.width, drawRect.y452 + ((yImg - visibleRect.y) * drawRect.height) / visibleRect.height);453 }454 455 private Point comp2imgCoord(Rectangle visibleRect, int xComp, int yComp) {456 Rectangle drawRect = calculateDrawImageRectangle(visibleRect);457 return new Point(458 visibleRect.x + ((xComp - drawRect.x) * visibleRect.width) / drawRect.width,459 visibleRect.y + ((yComp - drawRect.y) * visibleRect.height) / drawRect.height460 );461 }462 463 private static Point getCenterImgCoord(Rectangle visibleRect) {464 return new Point(visibleRect.x + visibleRect.width / 2, visibleRect.y + visibleRect.height / 2);465 }466 467 private Rectangle calculateDrawImageRectangle(Rectangle visibleRect) {468 return calculateDrawImageRectangle(visibleRect, new Rectangle(0, 0, getSize().width, getSize().height));469 }470 471 /**472 * calculateDrawImageRectangle473 *474 * @param imgRect475 * the part of the image that should be drawn (in image coordinates)476 * @param compRect477 * the part of the component where the image should be drawn (in478 * component coordinates)479 * @return the part of compRect with the same width/height ratio as the image480 */481 private static Rectangle calculateDrawImageRectangle(Rectangle imgRect, Rectangle compRect) {482 int x = 0;483 int y = 0;484 int w = compRect.width;485 int h = compRect.height;486 int wFact = w * imgRect.height;487 int hFact = h * imgRect.width;488 if (wFact != hFact) {489 if (wFact > hFact) {490 w = hFact / imgRect.height;491 x = (compRect.width - w) / 2;492 } else {493 h = wFact / imgRect.width;494 y = (compRect.height - h) / 2;495 }496 }497 return new Rectangle(x + compRect.x, y + compRect.y, w, h);498 }499 500 /**501 * Zooms to 1:1 and, if it is already in 1:1, to best fit.502 */503 public void zoomBestFitOrOne() {504 Image image;505 Rectangle visibleRect;506 synchronized (this) {507 image = this.image;508 visibleRect = this.visibleRect;509 }510 if (image == null)511 return;512 if (visibleRect.width != image.getWidth(null)513 || visibleRect.height != image.getHeight(null)) {514 // The display is not at best fit. => Zoom to best fit515 visibleRect = new Rectangle(0, 0, image.getWidth(null),516 image.getHeight(null));517 } else {518 // The display is at best fit => zoom to 1:1519 Point center = getCenterImgCoord(visibleRect);520 visibleRect = new Rectangle(center.x - getWidth() / 2, center.y521 - getHeight() / 2, getWidth(), getHeight());522 checkVisibleRectPos(image, visibleRect);523 }524 synchronized (this) {525 this.visibleRect = visibleRect;526 }527 repaint();528 }529 530 private static void checkVisibleRectPos(Image image, Rectangle visibleRect) {531 if (visibleRect.x < 0) {532 visibleRect.x = 0;533 }534 if (visibleRect.y < 0) {535 visibleRect.y = 0;536 }537 if (visibleRect.x + visibleRect.width > image.getWidth(null)) {538 visibleRect.x = image.getWidth(null) - visibleRect.width;539 }540 if (visibleRect.y + visibleRect.height > image.getHeight(null)) {541 visibleRect.y = image.getHeight(null) - visibleRect.height;542 }543 }544 545 private static void checkVisibleRectSize(Image image, Rectangle visibleRect) {546 if (visibleRect.width > image.getWidth(null)) {547 visibleRect.width = image.getWidth(null);548 }549 if (visibleRect.height > image.getHeight(null)) {550 visibleRect.height = image.getHeight(null);551 }552 }553 534 } -
applications/editors/josm/plugins/MicrosoftStreetside/src/org/openstreetmap/josm/plugins/streetside/gui/StreetsideImageTreeCellRenderer.java
r34317 r36194 20 20 21 21 @Override 22 public Component getTreeCellRendererComponent( 23 JTree tree, Object value, boolean sel, boolean expanded, boolean leaf, int row, boolean hasFocus 24 ) { 22 public Component getTreeCellRendererComponent(JTree tree, Object value, boolean sel, boolean expanded, boolean leaf, 23 int row, boolean hasFocus) { 25 24 super.getTreeCellRendererComponent(tree, value.toString(), sel, expanded, leaf, row, hasFocus); 26 25 setIcon(ICON); -
applications/editors/josm/plugins/MicrosoftStreetside/src/org/openstreetmap/josm/plugins/streetside/gui/StreetsideMainDialog.java
r35202 r36194 12 12 import java.util.Arrays; 13 13 import java.util.List; 14 import java.util.logging.Logger; 14 15 15 16 import javax.imageio.ImageIO; … … 20 21 import javax.swing.SwingUtilities; 21 22 22 import org.apache.log4j.Logger;23 23 import org.openstreetmap.josm.data.cache.CacheEntry; 24 24 import org.openstreetmap.josm.data.cache.CacheEntryAttributes; … … 38 38 import org.openstreetmap.josm.tools.I18n; 39 39 import org.openstreetmap.josm.tools.ImageProvider; 40 import org.openstreetmap.josm.tools.Logging; 40 41 41 42 /** … … 45 46 * @author renerr18 46 47 */ 47 public final class StreetsideMainDialog extends ToggleDialog implements 48 ICachedLoaderListener, StreetsideDataListener { 49 50 private static final long serialVersionUID = 2645654786827812861L; 51 52 final static Logger logger = Logger.getLogger(StreetsideMainDialog.class); 48 public final class StreetsideMainDialog extends ToggleDialog implements ICachedLoaderListener, StreetsideDataListener { 53 49 54 50 public static final String BASE_TITLE = I18n.marktr("Microsoft Streetside image"); 55 56 private static final String MESSAGE_SEPARATOR = " — "; 57 58 private static StreetsideMainDialog instance; 59 60 private volatile StreetsideAbstractImage image; 61 62 private final SideButton nextButton = new SideButton(new NextPictureAction()); 51 private static final long serialVersionUID = 2645654786827812861L; 52 private static final Logger LOGGER = Logger.getLogger(StreetsideMainDialog.class.getCanonicalName()); 53 private static final String MESSAGE_SEPARATOR = " — "; 54 55 private static StreetsideMainDialog instance; 56 /** 57 * Button used to jump to the image following the red line 58 */ 59 public final SideButton redButton = new SideButton(new RedAction()); 60 /** 61 * Button used to jump to the image following the blue line 62 */ 63 public final SideButton blueButton = new SideButton(new BlueAction()); 64 private final SideButton nextButton = new SideButton(new NextPictureAction()); 63 65 private final SideButton previousButton = new SideButton(new PreviousPictureAction()); 64 /**65 * Button used to jump to the image following the red line66 */67 public final SideButton redButton = new SideButton(new RedAction());68 /**69 * Button used to jump to the image following the blue line70 */71 public final SideButton blueButton = new SideButton(new BlueAction());72 73 66 private final SideButton playButton = new SideButton(new PlayAction()); 74 67 private final SideButton pauseButton = new SideButton(new PauseAction()); 75 68 private final SideButton stopButton = new SideButton(new StopAction()); 76 69 /** 70 * Object containing the shown image and that handles zoom and drag 71 */ 72 public StreetsideImageDisplay streetsideImageDisplay; 73 public StreetsideCache thumbnailCache; 74 private volatile StreetsideAbstractImage image; 77 75 private ImageInfoHelpPopup imageInfoHelp; 78 79 /** 80 * Buttons mode. 81 * 82 * @author nokutu 83 */ 84 public enum MODE { 85 /** 86 * Standard mode to view pictures. 87 */ 88 NORMAL, 89 /** 90 * Mode when in walk. 91 */ 92 WALK 93 } 94 95 /** 96 * Object containing the shown image and that handles zoom and drag 97 */ 98 public StreetsideImageDisplay streetsideImageDisplay; 99 100 private StreetsideCache imageCache; 101 public StreetsideCache thumbnailCache; 102 103 private StreetsideMainDialog() { 104 super(I18n.tr(StreetsideMainDialog.BASE_TITLE), "streetside-main", I18n.tr("Open Streetside window"), null, 200, 105 true, StreetsidePreferenceSetting.class); 106 addShortcuts(); 107 108 streetsideImageDisplay = new StreetsideImageDisplay(); 109 110 blueButton.setForeground(Color.BLUE); 76 private StreetsideCache imageCache; 77 78 private StreetsideMainDialog() { 79 super(I18n.tr(StreetsideMainDialog.BASE_TITLE), "streetside-main", I18n.tr("Open Streetside window"), null, 200, 80 true, StreetsidePreferenceSetting.class); 81 addShortcuts(); 82 83 streetsideImageDisplay = new StreetsideImageDisplay(); 84 85 blueButton.setForeground(Color.BLUE); 111 86 redButton.setForeground(Color.RED); 112 87 113 setMode(MODE.NORMAL); 114 } 115 116 /** 117 * Adds the shortcuts to the buttons. 118 */ 88 setMode(MODE.NORMAL); 89 } 90 91 /** 92 * Returns the unique instance of the class. 93 * 94 * @return The unique instance of the class. 95 */ 96 public static synchronized StreetsideMainDialog getInstance() { 97 if (StreetsideMainDialog.instance == null) { 98 StreetsideMainDialog.instance = new StreetsideMainDialog(); 99 } 100 return StreetsideMainDialog.instance; 101 } 102 103 /** 104 * @return true, iff the singleton instance is present 105 */ 106 public static boolean hasInstance() { 107 return StreetsideMainDialog.instance != null; 108 } 109 110 /** 111 * Destroys the unique instance of the class. 112 */ 113 public static synchronized void destroyInstance() { 114 StreetsideMainDialog.instance = null; 115 } 116 117 /** 118 * Adds the shortcuts to the buttons. 119 */ 119 120 private void addShortcuts() { 120 121 nextButton.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke("PAGE_DOWN"), "next"); 121 122 nextButton.getActionMap().put("next", new NextPictureAction()); 122 previousButton.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke("PAGE_UP"), "previous"); 123 previousButton.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke("PAGE_UP"), 124 "previous"); 123 125 previousButton.getActionMap().put("previous", new PreviousPictureAction()); 124 blueButton.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke("control PAGE_UP"), "blue"); 126 blueButton.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke("control PAGE_UP"), 127 "blue"); 125 128 blueButton.getActionMap().put("blue", new BlueAction()); 126 redButton.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke("control PAGE_DOWN"), "red"); 129 redButton.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke("control PAGE_DOWN"), 130 "red"); 127 131 redButton.getActionMap().put("red", new RedAction()); 128 132 } 129 133 130 /** 131 * Returns the unique instance of the class. 132 * 133 * @return The unique instance of the class. 134 */ 135 public static synchronized StreetsideMainDialog getInstance() { 136 if (StreetsideMainDialog.instance == null) { 137 StreetsideMainDialog.instance = new StreetsideMainDialog(); 138 } 139 return StreetsideMainDialog.instance; 140 } 141 142 /** 143 * @return true, iff the singleton instance is present 144 */ 145 public static boolean hasInstance() { 146 return StreetsideMainDialog.instance != null; 147 } 148 149 public synchronized void setImageInfoHelp(ImageInfoHelpPopup popup) { 150 imageInfoHelp = popup; 151 } 152 153 /** 154 * Sets a new mode for the dialog. 155 * 156 * @param mode The mode to be set. Must not be {@code null}. 157 */ 158 public void setMode(MODE mode) { 159 switch (mode) { 160 case WALK: 161 createLayout( 162 streetsideImageDisplay, 163 Arrays.asList(playButton, pauseButton, stopButton) 164 ); 134 public synchronized void setImageInfoHelp(ImageInfoHelpPopup popup) { 135 imageInfoHelp = popup; 136 } 137 138 /** 139 * Sets a new mode for the dialog. 140 * 141 * @param mode The mode to be set. Must not be {@code null}. 142 */ 143 public void setMode(MODE mode) { 144 switch (mode) { 145 case WALK: 146 createLayout(streetsideImageDisplay, Arrays.asList(playButton, pauseButton, stopButton)); 165 147 break; 166 148 case NORMAL: 167 149 default: 168 createLayout( 169 streetsideImageDisplay, 170 Arrays.asList(blueButton, previousButton, nextButton, redButton) 171 ); 150 createLayout(streetsideImageDisplay, Arrays.asList(blueButton, previousButton, nextButton, redButton)); 172 151 break; 173 174 175 if (MODE.NORMAL .equals(mode)) {152 } 153 disableAllButtons(); 154 if (MODE.NORMAL == mode) { 176 155 updateImage(); 177 156 } 178 157 revalidate(); 179 158 repaint(); 180 } 181 182 /** 183 * Destroys the unique instance of the class. 184 */ 185 public static synchronized void destroyInstance() { 186 StreetsideMainDialog.instance = null; 187 } 188 189 /** 190 * Downloads the full quality picture of the selected StreetsideImage and sets 191 * in the StreetsideImageDisplay object. 192 */ 193 public synchronized void updateImage() { 194 updateImage(true); 195 } 196 197 /** 198 * Downloads the picture of the selected StreetsideImage and sets in the 199 * StreetsideImageDisplay object. 200 * 201 * @param fullQuality If the full quality picture must be downloaded or just the 202 * thumbnail. 203 */ 204 public synchronized void updateImage(boolean fullQuality) { 205 if (!SwingUtilities.isEventDispatchThread()) { 206 SwingUtilities.invokeLater(this::updateImage); 207 } else { 208 if (!StreetsideLayer.hasInstance()) { 209 return; 210 } 211 if (image == null) { 212 streetsideImageDisplay.setImage(null, null); 213 setTitle(I18n.tr(StreetsideMainDialog.BASE_TITLE)); 214 return; 215 } 216 217 if (imageInfoHelp != null && StreetsideProperties.IMAGEINFO_HELP_COUNTDOWN.get() > 0 && imageInfoHelp.showPopup()) { 218 // Count down the number of times the popup will be displayed 219 StreetsideProperties.IMAGEINFO_HELP_COUNTDOWN.put(StreetsideProperties.IMAGEINFO_HELP_COUNTDOWN.get() - 1); 220 } 221 222 if (image instanceof StreetsideImage) { 223 final StreetsideImage streetsideImage = (StreetsideImage) image; 224 // Downloads the thumbnail. 225 streetsideImageDisplay.setImage(null, null); 226 if (thumbnailCache != null) { 227 thumbnailCache.cancelOutstandingTasks(); 228 } 229 thumbnailCache = new StreetsideCache(streetsideImage.getId(), 230 StreetsideCache.Type.THUMBNAIL); 231 try { 232 thumbnailCache.submit(this, false); 233 } catch (final IOException e) { 234 logger.error(e); 235 } 236 237 // Downloads the full resolution image. 238 if (fullQuality || new StreetsideCache(streetsideImage.getId(), 239 StreetsideCache.Type.FULL_IMAGE).get() != null) { 240 if (imageCache != null) { 241 imageCache.cancelOutstandingTasks(); 242 } 243 imageCache = new StreetsideCache(streetsideImage.getId(), 244 StreetsideCache.Type.FULL_IMAGE); 245 try { 246 imageCache.submit(this, false); 247 } catch (final IOException e) { 248 logger.error(e); 249 } 250 } 251 } 252 updateTitle(); 253 } 254 } 255 256 /** 159 } 160 161 /** 162 * Downloads the full quality picture of the selected StreetsideImage and sets 163 * in the StreetsideImageDisplay object. 164 */ 165 public synchronized void updateImage() { 166 updateImage(true); 167 } 168 169 /** 170 * Downloads the picture of the selected StreetsideImage and sets in the 171 * StreetsideImageDisplay object. 172 * 173 * @param fullQuality If the full quality picture must be downloaded or just the 174 * thumbnail. 175 */ 176 public synchronized void updateImage(boolean fullQuality) { 177 if (!SwingUtilities.isEventDispatchThread()) { 178 SwingUtilities.invokeLater(this::updateImage); 179 } else { 180 if (!StreetsideLayer.hasInstance()) { 181 return; 182 } 183 if (image == null) { 184 streetsideImageDisplay.setImage(null, null); 185 setTitle(I18n.tr(StreetsideMainDialog.BASE_TITLE)); 186 return; 187 } 188 189 if (imageInfoHelp != null && StreetsideProperties.IMAGEINFO_HELP_COUNTDOWN.get() > 0 190 && imageInfoHelp.showPopup()) { 191 // Count down the number of times the popup will be displayed 192 StreetsideProperties.IMAGEINFO_HELP_COUNTDOWN 193 .put(StreetsideProperties.IMAGEINFO_HELP_COUNTDOWN.get() - 1); 194 } 195 196 if (image instanceof StreetsideImage) { 197 final StreetsideImage streetsideImage = (StreetsideImage) image; 198 // Downloads the thumbnail. 199 streetsideImageDisplay.setImage(null, null); 200 if (thumbnailCache != null) { 201 thumbnailCache.cancelOutstandingTasks(); 202 } 203 thumbnailCache = new StreetsideCache(streetsideImage.getId(), StreetsideCache.Type.THUMBNAIL); 204 try { 205 thumbnailCache.submit(this, false); 206 } catch (final IOException e) { 207 LOGGER.log(Logging.LEVEL_ERROR, e.getMessage(), e); 208 } 209 210 // Downloads the full resolution image. 211 if (fullQuality || new StreetsideCache(streetsideImage.getId(), StreetsideCache.Type.FULL_IMAGE) 212 .get() != null) { 213 if (imageCache != null) { 214 imageCache.cancelOutstandingTasks(); 215 } 216 imageCache = new StreetsideCache(streetsideImage.getId(), StreetsideCache.Type.FULL_IMAGE); 217 try { 218 imageCache.submit(this, false); 219 } catch (final IOException e) { 220 LOGGER.log(Logging.LEVEL_ERROR, e.getMessage(), e); 221 } 222 } 223 } 224 updateTitle(); 225 } 226 } 227 228 /** 257 229 * Disables all the buttons in the dialog 258 230 */ … … 264 236 } 265 237 266 /** 267 * Sets a new StreetsideImage to be shown. 268 * 269 * @param image The image to be shown. 270 */ 271 public synchronized void setImage(StreetsideAbstractImage image) { 272 this.image = image; 273 } 274 275 /** 276 * Updates the title of the dialog. 277 */ 278 public synchronized void updateTitle() { 279 if (!SwingUtilities.isEventDispatchThread()) { 280 SwingUtilities.invokeLater(this::updateTitle); 281 } else if (image != null) { 282 final StringBuilder title = new StringBuilder(I18n.tr(StreetsideMainDialog.BASE_TITLE)); 283 if (image instanceof StreetsideImage) { 284 title.append(StreetsideMainDialog.MESSAGE_SEPARATOR).append(MessageFormat.format("(heading {0}°)",Double.toString(image.getHe()))); 238 /** 239 * Updates the title of the dialog. 240 */ 241 public synchronized void updateTitle() { 242 if (!SwingUtilities.isEventDispatchThread()) { 243 SwingUtilities.invokeLater(this::updateTitle); 244 } else if (image != null) { 245 final StringBuilder title = new StringBuilder(I18n.tr(StreetsideMainDialog.BASE_TITLE)); 246 if (image instanceof StreetsideImage) { 247 title.append(StreetsideMainDialog.MESSAGE_SEPARATOR) 248 .append(MessageFormat.format("(heading {0}°)", Double.toString(image.getHe()))); 285 249 setTitle(title.toString()); 286 } 287 } 288 } 289 290 /** 291 * Returns the {@link StreetsideAbstractImage} object which is being shown. 292 * 293 * @return The {@link StreetsideAbstractImage} object which is being shown. 294 */ 295 public synchronized StreetsideAbstractImage getImage() { 296 return image; 297 } 298 299 /** 300 * Action class form the next image button. 301 * 302 * @author nokutu 303 */ 304 private static class NextPictureAction extends AbstractAction { 305 306 private static final long serialVersionUID = 6333692154558730392L; 307 308 /** 309 * Constructs a normal NextPictureAction 310 */ 311 NextPictureAction() { 312 super(I18n.tr("Next picture")); 313 putValue(Action.SHORT_DESCRIPTION, I18n.tr("Shows the next picture in the sequence")); 314 new ImageProvider("help", "next").getResource().attachImageIcon(this, true); 315 } 316 317 @Override 318 public void actionPerformed(ActionEvent e) { 319 StreetsideLayer.getInstance().getData().selectNext(); 320 } 321 } 322 323 /** 324 * Action class for the previous image button. 325 * 326 * @author nokutu 327 */ 328 private static class PreviousPictureAction extends AbstractAction { 329 330 private static final long serialVersionUID = 4390593660514657107L; 331 332 /** 333 * Constructs a normal PreviousPictureAction 334 */ 335 PreviousPictureAction() { 336 super(I18n.tr("Previous picture")); 337 putValue(Action.SHORT_DESCRIPTION, I18n.tr("Shows the previous picture in the sequence")); 338 new ImageProvider("help", "previous").getResource().attachImageIcon(this, true); 339 } 340 341 @Override 342 public void actionPerformed(ActionEvent e) { 343 StreetsideLayer.getInstance().getData().selectPrevious(); 344 } 345 } 346 347 /** 348 * Action class to jump to the image following the red line. 349 * 350 * @author nokutu 351 */ 352 private static class RedAction extends AbstractAction { 353 354 private static final long serialVersionUID = -1244456062285831231L; 355 356 /** 357 * Constructs a normal RedAction 358 */ 359 RedAction() { 360 putValue(Action.NAME, I18n.tr("Jump to red")); 361 putValue(Action.SHORT_DESCRIPTION, 362 I18n.tr("Jumps to the picture at the other side of the red line")); 363 new ImageProvider("dialogs", "red").getResource().attachImageIcon(this, true); 364 } 365 366 @Override 367 public void actionPerformed(ActionEvent e) { 368 if (StreetsideMainDialog.getInstance().getImage() != null) { 369 StreetsideLayer.getInstance().getData() 370 .setSelectedImage(StreetsideLayer.getInstance().getNNearestImage(1), true); 371 } 372 } 373 } 374 375 /** 376 * Action class to jump to the image following the blue line. 377 * 378 * @author nokutu 379 */ 380 private static class BlueAction extends AbstractAction { 381 382 private static final long serialVersionUID = 5951233534212838780L; 383 384 /** 385 * Constructs a normal BlueAction 386 */ 387 BlueAction() { 388 putValue(Action.NAME, I18n.tr("Jump to blue")); 389 putValue(Action.SHORT_DESCRIPTION, 390 I18n.tr("Jumps to the picture at the other side of the blue line")); 391 new ImageProvider("dialogs", "blue").getResource().attachImageIcon(this, true); 392 } 393 394 @Override 395 public void actionPerformed(ActionEvent e) { 396 if (StreetsideMainDialog.getInstance().getImage() != null) { 397 StreetsideLayer.getInstance().getData() 398 .setSelectedImage(StreetsideLayer.getInstance().getNNearestImage(2), true); 399 } 400 } 401 } 402 403 private static class StopAction extends AbstractAction implements WalkListener { 404 405 private static final long serialVersionUID = 8789972456611625341L; 406 407 private WalkThread thread; 408 409 /** 410 * Constructs a normal StopAction 411 */ 412 StopAction() { 413 putValue(Action.NAME, I18n.tr("Stop")); 414 putValue(Action.SHORT_DESCRIPTION, I18n.tr("Stops the walk.")); 415 new ImageProvider("dialogs/streetsideStop.png").getResource().attachImageIcon(this, true); 416 StreetsidePlugin.getStreetsideWalkAction().addListener(this); 417 } 418 419 @Override 420 public void actionPerformed(ActionEvent e) { 421 if (thread != null) { 422 thread.stopWalk(); 423 } 424 } 425 426 @Override 427 public void walkStarted(WalkThread thread) { 428 this.thread = thread; 429 } 430 } 431 432 private static class PlayAction extends AbstractAction implements WalkListener { 433 434 private static final long serialVersionUID = -1572747020946842769L; 435 436 private transient WalkThread thread; 437 438 /** 439 * Constructs a normal PlayAction 440 */ 441 PlayAction() { 442 putValue(Action.NAME, I18n.tr("Play")); 443 putValue(Action.SHORT_DESCRIPTION, I18n.tr("Continues with the paused walk.")); 444 new ImageProvider("dialogs/streetsidePlay.png").getResource().attachImageIcon(this, true); 445 StreetsidePlugin.getStreetsideWalkAction().addListener(this); 446 } 447 448 @Override 449 public void actionPerformed(ActionEvent e) { 450 if (thread != null) { 451 thread.play(); 452 } 453 } 454 455 @Override 456 public void walkStarted(WalkThread thread) { 457 if (thread != null) { 458 this.thread = thread; 459 } 460 } 461 } 462 463 private static class PauseAction extends AbstractAction implements WalkListener { 464 465 /** 466 * 467 */ 468 private static final long serialVersionUID = -8758326399460817222L; 469 private WalkThread thread; 470 471 /** 472 * Constructs a normal PauseAction 473 */ 474 PauseAction() { 475 putValue(Action.NAME, I18n.tr("Pause")); 476 putValue(Action.SHORT_DESCRIPTION, I18n.tr("Pauses the walk.")); 477 new ImageProvider("dialogs/streetsidePause.png").getResource().attachImageIcon(this, true); 478 StreetsidePlugin.getStreetsideWalkAction().addListener(this); 479 } 480 481 @Override 482 public void actionPerformed(ActionEvent e) { 483 thread.pause(); 484 } 485 486 @Override 487 public void walkStarted(WalkThread thread) { 488 this.thread = thread; 489 } 490 } 491 492 /** 493 * When the pictures are returned from the cache, they are set in the 494 * {@link StreetsideImageDisplay} object. 495 */ 496 @Override 497 public void loadingFinished(final CacheEntry data, final CacheEntryAttributes attributes, final LoadResult result) { 498 if (!SwingUtilities.isEventDispatchThread()) { 499 SwingUtilities.invokeLater(() -> loadingFinished(data, attributes, result)); 500 501 } else if (data != null && result == LoadResult.SUCCESS) { 502 try { 503 final BufferedImage img = ImageIO.read(new ByteArrayInputStream(data.getContent())); 504 if (img == null) { 505 return; 506 } 507 if ( 508 streetsideImageDisplay.getImage() == null 509 || img.getHeight() > streetsideImageDisplay.getImage().getHeight() 510 ) { 511 streetsideImageDisplay.setImage( 512 img, 513 null); 514 } 515 } catch (final IOException e) { 516 logger.error(e); 517 } 518 } 519 } 520 521 522 /** 523 * Creates the layout of the dialog. 524 * 525 * @param data The content of the dialog 526 * @param buttons The buttons where you can click 527 */ 528 public void createLayout(Component data, List<SideButton> buttons) { 529 removeAll(); 530 createLayout(data, true, buttons); 531 add(titleBar, BorderLayout.NORTH); 532 } 533 534 @Override 535 public void selectedImageChanged(StreetsideAbstractImage oldImage, StreetsideAbstractImage newImage) { 536 setImage(newImage); 537 if (newImage != null && newImage.getSequence() != null) { 538 if (newImage.next() != null) { 539 nextButton.setEnabled(true); 540 } 541 if (newImage.previous() != null) { 542 previousButton.setEnabled(true); 543 } 250 } 251 } 252 } 253 254 /** 255 * Returns the {@link StreetsideAbstractImage} object which is being shown. 256 * 257 * @return The {@link StreetsideAbstractImage} object which is being shown. 258 */ 259 public synchronized StreetsideAbstractImage getImage() { 260 return image; 261 } 262 263 /** 264 * Sets a new StreetsideImage to be shown. 265 * 266 * @param image The image to be shown. 267 */ 268 public synchronized void setImage(StreetsideAbstractImage image) { 269 this.image = image; 270 } 271 272 /** 273 * When the pictures are returned from the cache, they are set in the 274 * {@link StreetsideImageDisplay} object. 275 */ 276 @Override 277 public void loadingFinished(final CacheEntry data, final CacheEntryAttributes attributes, final LoadResult result) { 278 if (!SwingUtilities.isEventDispatchThread()) { 279 SwingUtilities.invokeLater(() -> loadingFinished(data, attributes, result)); 280 281 } else if (data != null && result == LoadResult.SUCCESS) { 282 try { 283 final BufferedImage img = ImageIO.read(new ByteArrayInputStream(data.getContent())); 284 if (img == null) { 285 return; 544 286 } 545 updateImage(); 546 } 547 548 @Override 549 public void imagesAdded() { 550 // This method is enforced by StreetsideDataListener, but only selectedImageChanged() is needed 551 } 552 553 /** 554 * @return the streetsideImageDisplay 555 */ 556 public StreetsideImageDisplay getStreetsideImageDisplay() { 557 return streetsideImageDisplay; 558 } 559 560 /** 561 * @param streetsideImageDisplay the streetsideImageDisplay to set 562 */ 563 public void setStreetsideImageDisplay(StreetsideImageDisplay streetsideImageDisplay) { 564 this.streetsideImageDisplay = streetsideImageDisplay; 565 } 287 if (streetsideImageDisplay.getImage() == null 288 || img.getHeight() > streetsideImageDisplay.getImage().getHeight()) { 289 streetsideImageDisplay.setImage(img, null); 290 } 291 } catch (final IOException e) { 292 LOGGER.log(Logging.LEVEL_ERROR, e.getMessage(), e); 293 } 294 } 295 } 296 297 /** 298 * Creates the layout of the dialog. 299 * 300 * @param data The content of the dialog 301 * @param buttons The buttons where you can click 302 */ 303 public void createLayout(Component data, List<SideButton> buttons) { 304 removeAll(); 305 createLayout(data, true, buttons); 306 add(titleBar, BorderLayout.NORTH); 307 } 308 309 @Override 310 public void selectedImageChanged(StreetsideAbstractImage oldImage, StreetsideAbstractImage newImage) { 311 setImage(newImage); 312 if (newImage != null && newImage.getSequence() != null) { 313 if (newImage.next() != null) { 314 nextButton.setEnabled(true); 315 } 316 if (newImage.previous() != null) { 317 previousButton.setEnabled(true); 318 } 319 } 320 updateImage(); 321 } 322 323 @Override 324 public void imagesAdded() { 325 // This method is enforced by StreetsideDataListener, but only selectedImageChanged() is needed 326 } 327 328 /** 329 * @return the streetsideImageDisplay 330 */ 331 public StreetsideImageDisplay getStreetsideImageDisplay() { 332 return streetsideImageDisplay; 333 } 334 335 /** 336 * @param streetsideImageDisplay the streetsideImageDisplay to set 337 */ 338 public void setStreetsideImageDisplay(StreetsideImageDisplay streetsideImageDisplay) { 339 this.streetsideImageDisplay = streetsideImageDisplay; 340 } 341 342 /** 343 * Buttons mode. 344 * 345 * @author nokutu 346 */ 347 public enum MODE { 348 /** 349 * Standard mode to view pictures. 350 */ 351 NORMAL, 352 /** 353 * Mode when in walk. 354 */ 355 WALK 356 } 357 358 /** 359 * Action class form the next image button. 360 * 361 * @author nokutu 362 */ 363 private static class NextPictureAction extends AbstractAction { 364 365 private static final long serialVersionUID = 6333692154558730392L; 366 367 /** 368 * Constructs a normal NextPictureAction 369 */ 370 NextPictureAction() { 371 super(I18n.tr("Next picture")); 372 putValue(Action.SHORT_DESCRIPTION, I18n.tr("Shows the next picture in the sequence")); 373 new ImageProvider("help", "next").getResource().attachImageIcon(this, true); 374 } 375 376 @Override 377 public void actionPerformed(ActionEvent e) { 378 StreetsideLayer.getInstance().getData().selectNext(); 379 } 380 } 381 382 /** 383 * Action class for the previous image button. 384 * 385 * @author nokutu 386 */ 387 private static class PreviousPictureAction extends AbstractAction { 388 389 private static final long serialVersionUID = 4390593660514657107L; 390 391 /** 392 * Constructs a normal PreviousPictureAction 393 */ 394 PreviousPictureAction() { 395 super(I18n.tr("Previous picture")); 396 putValue(Action.SHORT_DESCRIPTION, I18n.tr("Shows the previous picture in the sequence")); 397 new ImageProvider("help", "previous").getResource().attachImageIcon(this, true); 398 } 399 400 @Override 401 public void actionPerformed(ActionEvent e) { 402 StreetsideLayer.getInstance().getData().selectPrevious(); 403 } 404 } 405 406 /** 407 * Action class to jump to the image following the red line. 408 * 409 * @author nokutu 410 */ 411 private static class RedAction extends AbstractAction { 412 413 private static final long serialVersionUID = -1244456062285831231L; 414 415 /** 416 * Constructs a normal RedAction 417 */ 418 RedAction() { 419 putValue(Action.NAME, I18n.tr("Jump to red")); 420 putValue(Action.SHORT_DESCRIPTION, I18n.tr("Jumps to the picture at the other side of the red line")); 421 new ImageProvider("dialogs", "red").getResource().attachImageIcon(this, true); 422 } 423 424 @Override 425 public void actionPerformed(ActionEvent e) { 426 if (StreetsideMainDialog.getInstance().getImage() != null) { 427 StreetsideLayer.getInstance().getData() 428 .setSelectedImage(StreetsideLayer.getInstance().getNNearestImage(1), true); 429 } 430 } 431 } 432 433 /** 434 * Action class to jump to the image following the blue line. 435 * 436 * @author nokutu 437 */ 438 private static class BlueAction extends AbstractAction { 439 440 private static final long serialVersionUID = 5951233534212838780L; 441 442 /** 443 * Constructs a normal BlueAction 444 */ 445 BlueAction() { 446 putValue(Action.NAME, I18n.tr("Jump to blue")); 447 putValue(Action.SHORT_DESCRIPTION, I18n.tr("Jumps to the picture at the other side of the blue line")); 448 new ImageProvider("dialogs", "blue").getResource().attachImageIcon(this, true); 449 } 450 451 @Override 452 public void actionPerformed(ActionEvent e) { 453 if (StreetsideMainDialog.getInstance().getImage() != null) { 454 StreetsideLayer.getInstance().getData() 455 .setSelectedImage(StreetsideLayer.getInstance().getNNearestImage(2), true); 456 } 457 } 458 } 459 460 private static class StopAction extends AbstractAction implements WalkListener { 461 462 private static final long serialVersionUID = 8789972456611625341L; 463 464 private WalkThread thread; 465 466 /** 467 * Constructs a normal StopAction 468 */ 469 StopAction() { 470 putValue(Action.NAME, I18n.tr("Stop")); 471 putValue(Action.SHORT_DESCRIPTION, I18n.tr("Stops the walk.")); 472 new ImageProvider("dialogs/streetsideStop.png").getResource().attachImageIcon(this, true); 473 StreetsidePlugin.getStreetsideWalkAction().addListener(this); 474 } 475 476 @Override 477 public void actionPerformed(ActionEvent e) { 478 if (thread != null) { 479 thread.stopWalk(); 480 } 481 } 482 483 @Override 484 public void walkStarted(WalkThread thread) { 485 this.thread = thread; 486 } 487 } 488 489 private static class PlayAction extends AbstractAction implements WalkListener { 490 491 private static final long serialVersionUID = -1572747020946842769L; 492 493 private transient WalkThread thread; 494 495 /** 496 * Constructs a normal PlayAction 497 */ 498 PlayAction() { 499 putValue(Action.NAME, I18n.tr("Play")); 500 putValue(Action.SHORT_DESCRIPTION, I18n.tr("Continues with the paused walk.")); 501 new ImageProvider("dialogs/streetsidePlay.png").getResource().attachImageIcon(this, true); 502 StreetsidePlugin.getStreetsideWalkAction().addListener(this); 503 } 504 505 @Override 506 public void actionPerformed(ActionEvent e) { 507 if (thread != null) { 508 thread.play(); 509 } 510 } 511 512 @Override 513 public void walkStarted(WalkThread thread) { 514 if (thread != null) { 515 this.thread = thread; 516 } 517 } 518 } 519 520 private static class PauseAction extends AbstractAction implements WalkListener { 521 522 /** 523 * 524 */ 525 private static final long serialVersionUID = -8758326399460817222L; 526 private WalkThread thread; 527 528 /** 529 * Constructs a normal PauseAction 530 */ 531 PauseAction() { 532 putValue(Action.NAME, I18n.tr("Pause")); 533 putValue(Action.SHORT_DESCRIPTION, I18n.tr("Pauses the walk.")); 534 new ImageProvider("dialogs/streetsidePause.png").getResource().attachImageIcon(this, true); 535 StreetsidePlugin.getStreetsideWalkAction().addListener(this); 536 } 537 538 @Override 539 public void actionPerformed(ActionEvent e) { 540 thread.pause(); 541 } 542 543 @Override 544 public void walkStarted(WalkThread thread) { 545 this.thread = thread; 546 } 547 } 566 548 } -
applications/editors/josm/plugins/MicrosoftStreetside/src/org/openstreetmap/josm/plugins/streetside/gui/StreetsidePreferenceSetting.java
r34433 r36194 9 9 import java.io.IOException; 10 10 import java.io.InputStream; 11 import java.util.logging.Logger; 11 12 12 13 import javax.imageio.ImageIO; … … 26 27 import javax.swing.SwingUtilities; 27 28 28 import org.apache.log4j.Logger;29 29 import org.openstreetmap.josm.actions.ExpertToggleAction; 30 30 import org.openstreetmap.josm.gui.preferences.PreferenceTabbedPane; … … 41 41 import org.openstreetmap.josm.tools.GBC; 42 42 import org.openstreetmap.josm.tools.I18n; 43 import org.openstreetmap.josm.tools.Logging; 43 44 44 45 /** … … 50 51 public class StreetsidePreferenceSetting implements SubPreferenceSetting, StreetsideLoginListener { 51 52 52 final static Logger logger = Logger.getLogger(StreetsidePreferenceSetting.class); 53 54 private final JComboBox<String> downloadModeComboBox = new JComboBox<>(new String[]{ 55 DOWNLOAD_MODE.VISIBLE_AREA.getLabel(), 56 DOWNLOAD_MODE.OSM_AREA.getLabel(), 57 DOWNLOAD_MODE.MANUAL_ONLY.getLabel() 58 }); 59 60 private final JCheckBox displayHour = 61 new JCheckBox(I18n.tr("Display hour when the picture was taken"), StreetsideProperties.DISPLAY_HOUR.get()); 62 private final JCheckBox format24 = 63 new JCheckBox(I18n.tr("Use 24 hour format"), StreetsideProperties.TIME_FORMAT_24.get()); 64 private final JCheckBox moveTo = 65 new JCheckBox(I18n.tr("Move to picture''s location with next/previous buttons"), StreetsideProperties.MOVE_TO_IMG.get()); 66 private final JCheckBox hoverEnabled = 67 new JCheckBox(I18n.tr("Preview images when hovering its icon"), StreetsideProperties.HOVER_ENABLED.get()); 68 private final JCheckBox cutOffSeq = 69 new JCheckBox(I18n.tr("Cut off sequences at download bounds"), StreetsideProperties.CUT_OFF_SEQUENCES_AT_BOUNDS.get()); 70 private final JCheckBox imageLinkToBlurEditor = 71 new JCheckBox( 53 private static final Logger logger = Logger.getLogger(StreetsidePreferenceSetting.class.getCanonicalName()); 54 55 private final JComboBox<String> downloadModeComboBox = new JComboBox<>( 56 new String[] { DOWNLOAD_MODE.VISIBLE_AREA.getLabel(), DOWNLOAD_MODE.OSM_AREA.getLabel(), 57 DOWNLOAD_MODE.MANUAL_ONLY.getLabel() }); 58 59 private final JCheckBox displayHour = new JCheckBox(I18n.tr("Display hour when the picture was taken"), 60 StreetsideProperties.DISPLAY_HOUR.get()); 61 private final JCheckBox format24 = new JCheckBox(I18n.tr("Use 24 hour format"), 62 StreetsideProperties.TIME_FORMAT_24.get()); 63 private final JCheckBox moveTo = new JCheckBox(I18n.tr("Move to picture''s location with next/previous buttons"), 64 StreetsideProperties.MOVE_TO_IMG.get()); 65 private final JCheckBox hoverEnabled = new JCheckBox(I18n.tr("Preview images when hovering its icon"), 66 StreetsideProperties.HOVER_ENABLED.get()); 67 private final JCheckBox cutOffSeq = new JCheckBox(I18n.tr("Cut off sequences at download bounds"), 68 StreetsideProperties.CUT_OFF_SEQUENCES_AT_BOUNDS.get()); 69 private final JCheckBox imageLinkToBlurEditor = new JCheckBox( 72 70 I18n.tr("When opening Streetside image in web browser, show the blur editor instead of the image viewer"), 73 StreetsideProperties.IMAGE_LINK_TO_BLUR_EDITOR.get() 74 ); 75 private final JCheckBox developer = 76 new JCheckBox(I18n.tr("Enable experimental beta-features (might be unstable)"), StreetsideProperties.DEVELOPER.get()); 71 StreetsideProperties.IMAGE_LINK_TO_BLUR_EDITOR.get()); 72 private final JCheckBox developer = new JCheckBox(I18n.tr("Enable experimental beta-features (might be unstable)"), 73 StreetsideProperties.DEVELOPER.get()); 77 74 private final SpinnerNumberModel preFetchSize = new SpinnerNumberModel( 78 StreetsideProperties.PRE_FETCH_IMAGE_COUNT.get().intValue(), 79 0, 80 Integer.MAX_VALUE, 81 1 82 ); 75 StreetsideProperties.PRE_FETCH_IMAGE_COUNT.get().intValue(), 0, Integer.MAX_VALUE, 1); 83 76 private final JButton loginButton = new StreetsideButton(new LoginAction(this)); 84 77 private final JButton logoutButton = new StreetsideButton(new LogoutAction()); … … 99 92 loginPanel.setBackground(StreetsideColorScheme.TOOLBAR_DARK_GREY); 100 93 JLabel brandImage = new JLabel(); 101 try (InputStream is = StreetsidePreferenceSetting.class.getResourceAsStream("/images/streetside-logo-white.png")) { 94 try (InputStream is = StreetsidePreferenceSetting.class 95 .getResourceAsStream("/images/streetside-logo-white.png")) { 102 96 if (is != null) { 103 97 brandImage.setIcon(new ImageIcon(ImageIO.read(is))); 104 98 } else { 105 logger. warn("Could not load Streetside brand image!");99 logger.log(Logging.LEVEL_WARN, "Could not load Streetside brand image!"); 106 100 } 107 101 } catch (IOException e) { 108 logger. warn("While reading Streetside brand image, an IO-exception occured!");102 logger.log(Logging.LEVEL_WARN, "While reading Streetside brand image, an IO-exception occured!", e); 109 103 } 110 104 loginPanel.add(brandImage, 0); … … 121 115 mainPanel.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5)); 122 116 123 downloadModeComboBox.setSelectedItem(DOWNLOAD_MODE.fromPrefId(StreetsideProperties.DOWNLOAD_MODE.get()).getLabel()); 117 downloadModeComboBox 118 .setSelectedItem(DOWNLOAD_MODE.fromPrefId(StreetsideProperties.DOWNLOAD_MODE.get()).getLabel()); 124 119 125 120 JPanel downloadModePanel = new JPanel(); … … 147 142 mainPanel.add(developer, GBC.eol()); 148 143 } 149 StreetsideColorScheme.styleAsDefaultPanel( 150 mainPanel, downloadModePanel, displayHour, format24, moveTo, hoverEnabled, cutOffSeq, imageLinkToBlurEditor, developer, preFetchPanel 151 ); 144 StreetsideColorScheme.styleAsDefaultPanel(mainPanel, downloadModePanel, displayHour, format24, moveTo, 145 hoverEnabled, cutOffSeq, imageLinkToBlurEditor, developer, preFetchPanel); 152 146 mainPanel.add(Box.createVerticalGlue(), GBC.eol().fill(GridBagConstraints.BOTH)); 153 147 … … 156 150 synchronized (gui.getDisplayPreference().getTabPane()) { 157 151 gui.getDisplayPreference().addSubTab(this, "Streetside", new JScrollPane(container)); 158 gui.getDisplayPreference().getTabPane().setIconAt(gui.getDisplayPreference().getTabPane().getTabCount()-1, StreetsidePlugin.LOGO.setSize(12, 12).get()); 152 gui.getDisplayPreference().getTabPane().setIconAt(gui.getDisplayPreference().getTabPane().getTabCount() - 1, 153 StreetsidePlugin.LOGO.setSize(12, 12).get()); 159 154 } 160 155 … … 188 183 @Override 189 184 public boolean ok() { 190 StreetsideProperties.DOWNLOAD_MODE.put(DOWNLOAD_MODE.fromLabel(downloadModeComboBox.getSelectedItem().toString()).getPrefId()); 185 StreetsideProperties.DOWNLOAD_MODE 186 .put(DOWNLOAD_MODE.fromLabel(downloadModeComboBox.getSelectedItem().toString()).getPrefId()); 191 187 StreetsideProperties.DISPLAY_HOUR.put(displayHour.isSelected()); 192 188 StreetsideProperties.TIME_FORMAT_24.put(format24.isSelected()); … … 211 207 * 212 208 * @author nokutu 213 *214 209 */ 215 210 private static class LoginAction extends AbstractAction { … … 217 212 private static final long serialVersionUID = 8743119160917296506L; 218 213 219 214 private final transient StreetsideLoginListener callback; 220 215 221 216 LoginAction(StreetsideLoginListener loginCallback) { … … 242 237 private static final long serialVersionUID = -4146587895393766981L; 243 238 244 239 private LogoutAction() { 245 240 super(I18n.tr("Logout")); 246 241 } -
applications/editors/josm/plugins/MicrosoftStreetside/src/org/openstreetmap/josm/plugins/streetside/gui/StreetsideViewerDialog.java
r34433 r36194 16 16 */ 17 17 18 public final class StreetsideViewerDialog extends ToggleDialog 19 { 18 public final class StreetsideViewerDialog extends ToggleDialog { 20 19 21 20 private static final long serialVersionUID = -8983900297628236197L; 22 21 23 22 private static final String BASE_TITLE = "360° Streetside Viewer"; 24 23 25 24 private static StreetsideViewerDialog instance; 26 25 27 28 29 30 privateStreetsideViewerPanel streetsideViewerPanel;26 /** 27 * Object containing the shown image and that handles zoom and drag 28 */ 29 private final StreetsideViewerPanel streetsideViewerPanel; 31 30 32 33 super(StreetsideViewerDialog.BASE_TITLE, "streetside-viewer", "Open Streetside Viewer window",34 null, 200, true,StreetsidePreferenceSetting.class);35 36 37 31 private StreetsideViewerDialog() { 32 super(StreetsideViewerDialog.BASE_TITLE, "streetside-viewer", "Open Streetside Viewer window", null, 200, true, 33 StreetsidePreferenceSetting.class); 34 streetsideViewerPanel = new StreetsideViewerPanel(); 35 createLayout(streetsideViewerPanel, true, null); 36 } 38 37 39 40 41 42 43 44 45 46 47 48 49 38 /** 39 * Returns the unique instance of the class. 40 * 41 * @return The unique instance of the class. 42 */ 43 public static synchronized StreetsideViewerDialog getInstance() { 44 if (StreetsideViewerDialog.instance == null) { 45 StreetsideViewerDialog.instance = new StreetsideViewerDialog(); 46 } 47 return StreetsideViewerDialog.instance; 48 } 50 49 51 52 53 54 55 56 50 /** 51 * @return true, iff the singleton instance is present 52 */ 53 public static boolean hasInstance() { 54 return StreetsideViewerDialog.instance != null; 55 } 57 56 58 59 60 61 62 63 57 /** 58 * Destroys the unique instance of the class. 59 */ 60 public static synchronized void destroyInstance() { 61 StreetsideViewerDialog.instance = null; 62 } 64 63 65 /** 66 * Creates the layout of the dialog. 67 * 68 * @param data 69 * The content of the dialog 70 * @param buttons 71 * The buttons where you can click 72 */ 73 public void createLayout(Component data, List<SideButton> buttons) { 74 removeAll(); 75 createLayout(data, true, buttons); 76 add(titleBar, BorderLayout.NORTH); 77 } 64 /** 65 * Creates the layout of the dialog. 66 * 67 * @param data The content of the dialog 68 * @param buttons The buttons where you can click 69 */ 70 public void createLayout(Component data, List<SideButton> buttons) { 71 removeAll(); 72 createLayout(data, true, buttons); 73 add(titleBar, BorderLayout.NORTH); 74 } 78 75 79 80 81 76 public StreetsideViewerPanel getStreetsideViewerPanel() { 77 return streetsideViewerPanel; 78 } 82 79 } -
applications/editors/josm/plugins/MicrosoftStreetside/src/org/openstreetmap/josm/plugins/streetside/gui/StreetsideWalkDialog.java
r34317 r36194 21 21 private static final long serialVersionUID = 7974881240732957573L; 22 22 23 /** Spin containing the interval value. */ 23 /** 24 * Spin containing the interval value. 25 */ 24 26 public SpinnerModel spin; 25 /** Whether it must wait for the picture to be downloaded */ 27 /** 28 * Whether it must wait for the picture to be downloaded 29 */ 26 30 public JCheckBox waitForPicture; 27 /** Whether the view must follow the selected image. */ 31 /** 32 * Whether the view must follow the selected image. 33 */ 28 34 public JCheckBox followSelection; 29 /** Go forward or backwards */ 35 /** 36 * Go forward or backwards 37 */ 30 38 public JCheckBox goForward; 31 39 -
applications/editors/josm/plugins/MicrosoftStreetside/src/org/openstreetmap/josm/plugins/streetside/gui/boilerplate/SelectableLabel.java
r34317 r36194 10 10 public class SelectableLabel extends JTextPane { 11 11 12 private static final long serialVersionUID = 5432480892000739831L;13 14 12 public static final Font DEFAULT_FONT = UIManager.getFont("Label.font").deriveFont(Font.PLAIN); 15 13 public static final Color DEFAULT_BACKGROUND = UIManager.getColor("Panel.background"); 14 private static final long serialVersionUID = 5432480892000739831L; 16 15 17 16 public SelectableLabel() { -
applications/editors/josm/plugins/MicrosoftStreetside/src/org/openstreetmap/josm/plugins/streetside/gui/boilerplate/StreetsideButton.java
r34317 r36194 12 12 13 13 import org.openstreetmap.josm.plugins.streetside.utils.StreetsideColorScheme; 14 15 14 16 15 public class StreetsideButton extends JButton { -
applications/editors/josm/plugins/MicrosoftStreetside/src/org/openstreetmap/josm/plugins/streetside/gui/dialog/ChooseGeoImageLayersDialog.java
r34399 r36194 27 27 public class ChooseGeoImageLayersDialog extends JDialog { 28 28 private static final long serialVersionUID = -1793622345412435234L; 29 private static final String QUESTION = I18n.marktr("Which image layers do you want to import into the Streetside layer?"); 29 private static final String QUESTION = I18n 30 .marktr("Which image layers do you want to import into the Streetside layer?"); 30 31 31 32 public ChooseGeoImageLayersDialog(final Component parent, final List<GeoImageLayer> layers) { 32 33 super(GuiHelper.getFrameForComponent(parent), I18n.tr(QUESTION)); 33 34 final Container c = getContentPane(); 34 35 c.setLayout(new BorderLayout(10, 10)); … … 64 65 protected static class GeoImageLayerListCellRenderer implements ListCellRenderer<GeoImageLayer> { 65 66 @Override 66 public Component getListCellRendererComponent( 67 JList<? extends GeoImageLayer> list, GeoImageLayer value, int index, boolean isSelected, boolean cellHasFocus 68 ) { 69 final JLabel result = value == null 70 ? null 67 public Component getListCellRendererComponent(JList<? extends GeoImageLayer> list, GeoImageLayer value, 68 int index, boolean isSelected, boolean cellHasFocus) { 69 final JLabel result = value == null ? null 71 70 /* i18n: {0} is the layer name, {1} the number of images in it */ 72 : new JLabel(I18n.tr("{0} ({1} images)", value.getName(), value.getImages().size()), value.getIcon(), SwingConstants.LEADING); 71 : new JLabel(I18n.tr("{0} ({1} images)", value.getName(), value.getImages().size()), 72 value.getIcon(), SwingConstants.LEADING); 73 73 if (result != null) { 74 74 result.setOpaque(true); 75 result.setBackground(isSelected ? UIManager.getColor("List.selectionBackground") : UIManager.getColor("List.background")); 75 result.setBackground(isSelected ? UIManager.getColor("List.selectionBackground") 76 : UIManager.getColor("List.background")); 76 77 } 77 78 return result; -
applications/editors/josm/plugins/MicrosoftStreetside/src/org/openstreetmap/josm/plugins/streetside/gui/imageinfo/AddTagToPrimitiveAction.java
r34577 r36194 44 44 int conflictResolution = JOptionPane.YES_OPTION; 45 45 if (target.hasKey(tag.getKey()) && !target.hasTag(tag.getKey(), tag.getValue())) { 46 conflictResolution = JOptionPane.showConfirmDialog( 47 MainApplication.getMainFrame(), 48 "<html>" + 49 I18n.tr("A tag with key <i>{0}</i> is already present on the selected OSM object.", tag.getKey()) + "<br>" + 50 I18n.tr( 51 "Do you really want to replace the current value <i>{0}</i> with the new value <i>{1}</i>?", 52 target.get(tag.getKey()), 53 tag.getValue() 54 ) + "</html>", 55 I18n.tr("Tag conflict"), 56 JOptionPane.YES_NO_OPTION, 57 JOptionPane.WARNING_MESSAGE 58 ); 46 conflictResolution = JOptionPane.showConfirmDialog(MainApplication.getMainFrame(), "<html>" + I18n 47 .tr("A tag with key <i>{0}</i> is already present on the selected OSM object.", tag.getKey()) 48 + "<br>" 49 + I18n.tr( 50 "Do you really want to replace the current value <i>{0}</i> with the new value <i>{1}</i>?", 51 target.get(tag.getKey()), tag.getValue()) 52 + "</html>", I18n.tr("Tag conflict"), JOptionPane.YES_NO_OPTION, JOptionPane.WARNING_MESSAGE); 59 53 } 60 54 if (JOptionPane.YES_OPTION == conflictResolution) { -
applications/editors/josm/plugins/MicrosoftStreetside/src/org/openstreetmap/josm/plugins/streetside/gui/imageinfo/ClipboardAction.java
r34433 r36194 67 67 /** 68 68 * Sets the component, under which the popup will be shown, which indicates that the key was copied to the clipboard. 69 * 69 70 * @param popupParent the component to set as parent of the popup 70 71 */ -
applications/editors/josm/plugins/MicrosoftStreetside/src/org/openstreetmap/josm/plugins/streetside/gui/imageinfo/ImageInfoHelpPopup.java
r34412 r36194 7 7 import java.awt.IllegalComponentStateException; 8 8 import java.awt.event.ActionEvent; 9 import java.util.logging.Logger; 9 10 10 11 import javax.swing.AbstractAction; … … 14 15 import javax.swing.JTextPane; 15 16 16 import org.apache.log4j.Logger;17 17 import org.openstreetmap.josm.plugins.streetside.gui.boilerplate.SelectableLabel; 18 18 import org.openstreetmap.josm.plugins.streetside.gui.boilerplate.StreetsideButton; … … 21 21 import org.openstreetmap.josm.tools.I18n; 22 22 import org.openstreetmap.josm.tools.ImageProvider; 23 import org.openstreetmap.josm.tools.Logging; 23 24 24 25 public class ImageInfoHelpPopup extends JPopupMenu { … … 26 27 private static final long serialVersionUID = -1721594904273820586L; 27 28 28 final static Logger logger = Logger.getLogger(ImageInfoHelpPopup.class);29 private static final Logger LOGGER = Logger.getLogger(ImageInfoHelpPopup.class.getCanonicalName()); 29 30 30 31 private final Component invokerComp; … … 44 45 mainText.setContentType("text/html"); 45 46 mainText.setFont(SelectableLabel.DEFAULT_FONT); 46 mainText.setText("<html><div style='width:250px'>" +47 "Welcome to the Microsoft Streetside JOSM Plugin. To view the vector bubbles for the 360 degree imagery, select Imagery->Streetside from the JOSM menu."48 + "<br><br>"49 + "Once the blue bubbles appear on the map, click on a vector bubble and undock/maximize the 360 viewer to view the imagery."50 + "</div></html>");47 mainText.setText("<html><div style='width:250px'>" 48 + "Welcome to the Microsoft Streetside JOSM Plugin. To view the vector bubbles for the 360 degree imagery, select Imagery->Streetside from the JOSM menu." 49 + "<br><br>" 50 + "Once the blue bubbles appear on the map, click on a vector bubble and undock/maximize the 360 viewer to view the imagery." 51 + "</div></html>"); 51 52 add(mainText, BorderLayout.CENTER); 52 53 … … 56 57 infoButton.addActionListener(e -> setVisible(false)); 57 58 bottomBar.add(infoButton); 58 59 StreetsideButton closeBtn = new StreetsideButton(new AbstractAction() { 59 60 60 61 private static final long serialVersionUID = 2853315308169651854L; 61 62 62 63 64 65 66 67 63 @Override 64 public void actionPerformed(ActionEvent e) { 65 setVisible(false); 66 StreetsideProperties.IMAGEINFO_HELP_COUNTDOWN.put(0); 67 } 68 }); 68 69 69 70 71 70 closeBtn.setText(I18n.tr("I got it, close this.")); 71 bottomBar.add(closeBtn); 72 add(bottomBar, BorderLayout.SOUTH); 72 73 73 74 74 setBackground(Color.WHITE); 75 } 75 76 76 77 /** … … 84 85 return true; 85 86 } catch (IllegalComponentStateException e) { 86 logger.warn(I18n.tr("Could not show ImageInfoHelpPopup, because probably the invoker component has disappeared from screen.", e)); 87 LOGGER.log(Logging.LEVEL_WARN, I18n.tr( 88 "Could not show ImageInfoHelpPopup, because probably the invoker component has disappeared from screen.", 89 e)); 87 90 } 88 91 } -
applications/editors/josm/plugins/MicrosoftStreetside/src/org/openstreetmap/josm/plugins/streetside/gui/imageinfo/ImageInfoPanel.java
r34416 r36194 7 7 import java.awt.datatransfer.StringSelection; 8 8 import java.util.Collection; 9 import java.util.logging.Logger; 9 10 10 11 import javax.swing.JLabel; … … 12 13 import javax.swing.JTextPane; 13 14 14 import org.apache.log4j.Logger;15 15 import org.openstreetmap.josm.data.osm.DataSelectionListener; 16 16 import org.openstreetmap.josm.data.osm.OsmPrimitive; … … 27 27 import org.openstreetmap.josm.plugins.streetside.utils.StreetsideURL; 28 28 import org.openstreetmap.josm.tools.I18n; 29 import org.openstreetmap.josm.tools.Logging; 29 30 30 31 public final class ImageInfoPanel extends ToggleDialog implements StreetsideDataListener, DataSelectionListener { 31 32 private static final long serialVersionUID = 4141847503072417190L; 32 33 33 final static Logger logger = Logger.getLogger(ImageInfoPanel.class);34 private static final Logger LOGGER = Logger.getLogger(ImageInfoPanel.class.getCanonicalName()); 34 35 35 36 private static ImageInfoPanel instance; … … 44 45 45 46 private ImageInfoPanel() { 46 super( 47 I18n.tr("Streetside 360° image info"), 48 "streetside-info", 49 I18n.tr("Displays detail information on the currently selected Streetside image"), 50 null, 51 150 52 ); 47 super(I18n.tr("Streetside 360° image info"), "streetside-info", 48 I18n.tr("Displays detail information on the currently selected Streetside image"), null, 150); 53 49 SelectionEventManager.getInstance().addSelectionListener(this); 54 50 … … 153 149 */ 154 150 @Override 155 public synchronized void selectedImageChanged(final StreetsideAbstractImage oldImage, final StreetsideAbstractImage newImage) { 156 logger.info(String.format( 157 "Selected Streetside image changed from %s to %s.", 158 oldImage instanceof StreetsideImage ? ((StreetsideImage) oldImage).getId() : "‹none›", 159 newImage instanceof StreetsideImage ? ((StreetsideImage) newImage).getId() : "‹none›" 160 )); 151 public synchronized void selectedImageChanged(final StreetsideAbstractImage oldImage, 152 final StreetsideAbstractImage newImage) { 153 LOGGER.info(String.format("Selected Streetside image changed from %s to %s.", 154 oldImage instanceof StreetsideImage ? oldImage.getId() : "‹none›", 155 newImage instanceof StreetsideImage ? newImage.getId() : "‹none›")); 161 156 162 157 imgKeyValue.setEnabled(newImage instanceof StreetsideImage); 163 final String newImageKey = newImage instanceof StreetsideImage ? ((StreetsideImage) newImage).getId(): null;158 final String newImageKey = newImage instanceof StreetsideImage ? newImage.getId() : null; 164 159 if (newImageKey != null) { 165 imageLinkChangeListener = b -> imgLinkAction.setURL( 166 StreetsideURL.MainWebsite.browseImage(newImageKey) 167 ); 160 imageLinkChangeListener = b -> imgLinkAction.setURL(StreetsideURL.MainWebsite.browseImage(newImageKey)); 168 161 imageLinkChangeListener.valueChanged(null); 169 162 StreetsideProperties.IMAGE_LINK_TO_BLUR_EDITOR.addListener(imageLinkChangeListener); … … 184 177 } 185 178 186 final boolean partOfSequence = newImage != null && newImage.getSequence() != null && newImage.getSequence().getId() != null; 179 final boolean partOfSequence = newImage != null && newImage.getSequence() != null 180 && newImage.getSequence().getId() != null; 187 181 seqKeyValue.setEnabled(partOfSequence); 188 182 if (partOfSequence) { … … 199 193 public synchronized void selectionChanged(final SelectionChangeEvent event) { 200 194 final Collection<? extends OsmPrimitive> sel = event.getSelection(); 201 if (StreetsideProperties.DEBUGING_ENABLED.get()) { 202 logger.debug(String.format("Selection changed. %d primitives are selected.", sel == null ? 0 : sel.size())); 195 if (Boolean.TRUE.equals(StreetsideProperties.DEBUGING_ENABLED.get())) { 196 LOGGER.log(Logging.LEVEL_DEBUG, 197 String.format("Selection changed. %d primitives are selected.", sel == null ? 0 : sel.size())); 203 198 } 204 199 addStreetsideTagAction.setTarget(sel != null && sel.size() == 1 ? sel.iterator().next() : null); -
applications/editors/josm/plugins/MicrosoftStreetside/src/org/openstreetmap/josm/plugins/streetside/gui/imageinfo/StreetsideViewerHelpPopup.java
r34412 r36194 8 8 import java.awt.event.ActionEvent; 9 9 import java.text.MessageFormat; 10 import java.util.logging.Logger; 10 11 11 12 import javax.swing.AbstractAction; … … 15 16 import javax.swing.JTextPane; 16 17 17 import org.apache.log4j.Logger;18 18 import org.openstreetmap.josm.plugins.streetside.gui.boilerplate.SelectableLabel; 19 19 import org.openstreetmap.josm.plugins.streetside.gui.boilerplate.StreetsideButton; … … 22 22 import org.openstreetmap.josm.tools.I18n; 23 23 import org.openstreetmap.josm.tools.ImageProvider; 24 24 import org.openstreetmap.josm.tools.Logging; 25 25 26 26 public class StreetsideViewerHelpPopup extends JPopupMenu { 27 27 28 28 private static final long serialVersionUID = -7840242522398163839L; 29 29 30 final static Logger logger = Logger.getLogger(StreetsideViewerHelpPopup.class);30 private static final Logger LOGGER = Logger.getLogger(StreetsideViewerHelpPopup.class.getCanonicalName()); 31 31 32 33 32 private final Component invokerComp; 33 private boolean alreadyDisplayed; 34 34 35 35 public StreetsideViewerHelpPopup(Component invoker) { 36 36 37 38 39 37 invokerComp = invoker; 38 removeAll(); 39 setLayout(new BorderLayout()); 40 40 41 42 43 44 41 JPanel topBar = new JPanel(); 42 topBar.add(new JLabel(ImageProvider.get("streetside-logo-white"))); 43 topBar.setBackground(StreetsideColorScheme.TOOLBAR_DARK_GREY); 44 add(topBar, BorderLayout.NORTH); 45 45 46 JTextPane mainText = new JTextPane(); 47 mainText.setContentType("text/html"); 48 mainText.setFont(SelectableLabel.DEFAULT_FONT); 49 mainText.setText("<html><div style='width:250px'>" + 50 "Welcome to the Microsoft Streetside JOSM Plugin. To view the vector bubbles for the 360 degree imagery, select Imagery->Streetside from the JOSM menu." 51 + "<br><br>" 52 + 53 "Once the blue bubbles appear on the map, click on a vector bubble and undock/maximize the 360 viewer to view the imagery." 54 + "</div></html>"); 55 add(mainText, BorderLayout.CENTER); 46 JTextPane mainText = new JTextPane(); 47 mainText.setContentType("text/html"); 48 mainText.setFont(SelectableLabel.DEFAULT_FONT); 49 mainText.setText("<html><div style='width:250px'>" 50 + "Welcome to the Microsoft Streetside JOSM Plugin. To view the vector bubbles for the 360 degree imagery, select Imagery->Streetside from the JOSM menu." 51 + "<br><br>" 52 + "Once the blue bubbles appear on the map, click on a vector bubble and undock/maximize the 360 viewer to view the imagery." 53 + "</div></html>"); 54 add(mainText, BorderLayout.CENTER); 56 55 57 58 59 60 61 62 63 56 JPanel bottomBar = new JPanel(); 57 bottomBar.setBackground(new Color(0x00FFFFFF, true)); 58 StreetsideButton infoButton = new StreetsideButton(ImageInfoPanel.getInstance().getToggleAction()); 59 infoButton.addActionListener(e -> setVisible(false)); 60 bottomBar.add(infoButton); 61 StreetsideButton closeBtn = new StreetsideButton(new AbstractAction() { 62 private static final long serialVersionUID = -6193886964751195196L; 64 63 65 66 67 68 69 70 64 @Override 65 public void actionPerformed(ActionEvent e) { 66 setVisible(false); 67 StreetsideProperties.IMAGEINFO_HELP_COUNTDOWN.put(0); 68 } 69 }); 71 70 72 73 bottomBar.add(closeBtn);74 add(bottomBar, BorderLayout.SOUTH);71 closeBtn.setText(I18n.tr("I got it, close this.")); 72 bottomBar.add(closeBtn); 73 add(bottomBar, BorderLayout.SOUTH); 75 74 76 setBackground(Color.WHITE); 75 setBackground(Color.WHITE); 76 } 77 78 /** 79 * @return <code>true</code> if the popup is displayed 80 */ 81 public boolean showPopup() { 82 if (!alreadyDisplayed && invokerComp.isShowing()) { 83 try { 84 show(invokerComp, invokerComp.getWidth(), 0); 85 alreadyDisplayed = true; 86 return true; 87 } catch (IllegalComponentStateException e) { 88 LOGGER.log(Logging.LEVEL_ERROR, MessageFormat.format( 89 "Could not show ImageInfoHelpPopup, because probably the invoker component has disappeared from screen. {0}", 90 e.getMessage()), e); 91 } 92 } 93 return false; 94 } 77 95 } 78 79 /**80 * @return <code>true</code> if the popup is displayed81 */82 public boolean showPopup() {83 if (!alreadyDisplayed && invokerComp.isShowing()) {84 try {85 show(invokerComp, invokerComp.getWidth(), 0);86 alreadyDisplayed = true;87 return true;88 } catch (IllegalComponentStateException e) {89 logger.error(MessageFormat.format("Could not show ImageInfoHelpPopup, because probably the invoker component has disappeared from screen. {0}", e.getMessage()));90 }91 }92 return false;93 }94 } -
applications/editors/josm/plugins/MicrosoftStreetside/src/org/openstreetmap/josm/plugins/streetside/gui/imageinfo/StreetsideViewerPanel.java
r36065 r36194 1 // License: GPL. For details, see LICENSE file.1 // License: GPL. For details, see LICENSE file. 2 2 package org.openstreetmap.josm.plugins.streetside.gui.imageinfo; 3 3 … … 5 5 import java.awt.GraphicsEnvironment; 6 6 import java.text.MessageFormat; 7 import java.util.logging.Logger; 7 8 8 9 import javax.swing.JCheckBox; … … 10 11 import javax.swing.SwingUtilities; 11 12 12 import org.apache.log4j.Logger;13 13 import org.openstreetmap.josm.data.preferences.AbstractProperty.ValueChangeListener; 14 14 import org.openstreetmap.josm.plugins.streetside.StreetsideAbstractImage; … … 24 24 import org.openstreetmap.josm.plugins.streetside.utils.StreetsideURL; 25 25 import org.openstreetmap.josm.tools.I18n; 26 import org.openstreetmap.josm.tools.Logging; 26 27 27 public final class StreetsideViewerPanel extends JPanel 28 implements StreetsideDataListener { 28 public final class StreetsideViewerPanel extends JPanel implements StreetsideDataListener { 29 29 30 30 private static final long serialVersionUID = 4141847503072417190L; 31 31 32 final static Logger logger = Logger.getLogger(StreetsideViewerPanel.class); 33 34 private JCheckBox highResImageryCheck; 35 private WebLinkAction imgLinkAction; 36 private ImageReloadAction imgReloadAction; 37 private ValueChangeListener<Boolean> imageLinkChangeListener; 38 39 private static ThreeSixtyDegreeViewerPanel threeSixtyDegreeViewerPanel; 40 32 private static final Logger LOGGER = Logger.getLogger(StreetsideViewerPanel.class.getCanonicalName()); 33 private static ThreeSixtyDegreeViewerPanel threeSixtyDegreeViewerPanel; 34 private JCheckBox highResImageryCheck; 35 private WebLinkAction imgLinkAction; 36 private ImageReloadAction imgReloadAction; 37 private ValueChangeListener<Boolean> imageLinkChangeListener; 41 38 private StreetsideViewerHelpPopup streetsideViewerHelp; 42 39 43 40 public StreetsideViewerPanel() { 44 41 45 42 super(new BorderLayout()); 46 43 47 SwingUtilities.invokeLater(() -> initializeAndStartGUI());44 SwingUtilities.invokeLater(this::initializeAndStartGUI); 48 45 49 46 selectedImageChanged(null, null); 50 47 51 setToolTipText(I18n.tr("Select Microsoft Streetside from the Imagery menu, then click on a blue vector bubble..")); 52 } 48 setToolTipText( 49 I18n.tr("Select Microsoft Streetside from the Imagery menu, then click on a blue vector bubble..")); 50 } 53 51 54 private void initializeAndStartGUI() { 52 public static CubemapBox getCubemapBox() { 53 return threeSixtyDegreeViewerPanel.getCubemapBox(); 54 } 55 55 56 threeSixtyDegreeViewerPanel = new ThreeSixtyDegreeViewerPanel(); 56 /** 57 * @return the threeSixtyDegreeViewerPanel 58 */ 59 public static ThreeSixtyDegreeViewerPanel getThreeSixtyDegreeViewerPanel() { 60 return threeSixtyDegreeViewerPanel; 61 } 62 63 private void initializeAndStartGUI() { 64 65 threeSixtyDegreeViewerPanel = new ThreeSixtyDegreeViewerPanel(); 57 66 58 67 if (!GraphicsEnvironment.isHeadless()) { … … 60 69 } 61 70 62 63 64 65 71 add(threeSixtyDegreeViewerPanel, BorderLayout.CENTER); 72 revalidate(); 73 repaint(); 74 JPanel checkPanel = new JPanel(); 66 75 67 76 imgReloadAction = new ImageReloadAction("Reload"); 68 77 69 78 StreetsideButton imgReloadButton = new StreetsideButton(imgReloadAction); 70 79 71 highResImageryCheck = new JCheckBox("High resolution"); 72 highResImageryCheck.setSelected(StreetsideProperties.SHOW_HIGH_RES_STREETSIDE_IMAGERY.get()); 73 highResImageryCheck.addActionListener( 74 action -> StreetsideProperties.SHOW_HIGH_RES_STREETSIDE_IMAGERY.put(highResImageryCheck.isSelected()) 75 ); 76 StreetsideProperties.SHOW_HIGH_RES_STREETSIDE_IMAGERY.addListener( 77 valueChange -> highResImageryCheck.setSelected(StreetsideProperties.SHOW_HIGH_RES_STREETSIDE_IMAGERY.get()) 78 ); 79 checkPanel.add(highResImageryCheck, BorderLayout.WEST); 80 checkPanel.add(imgReloadButton, BorderLayout.EAST); 80 highResImageryCheck = new JCheckBox("High resolution"); 81 highResImageryCheck.setSelected(StreetsideProperties.SHOW_HIGH_RES_STREETSIDE_IMAGERY.get()); 82 highResImageryCheck.addActionListener( 83 action -> StreetsideProperties.SHOW_HIGH_RES_STREETSIDE_IMAGERY.put(highResImageryCheck.isSelected())); 84 StreetsideProperties.SHOW_HIGH_RES_STREETSIDE_IMAGERY.addListener(valueChange -> highResImageryCheck 85 .setSelected(StreetsideProperties.SHOW_HIGH_RES_STREETSIDE_IMAGERY.get())); 86 checkPanel.add(highResImageryCheck, BorderLayout.WEST); 87 checkPanel.add(imgReloadButton, BorderLayout.EAST); 81 88 82 89 JPanel privacyLink = new JPanel(); 83 90 84 85 86 91 imgLinkAction = new WebLinkAction("Report a privacy concern with this image", null); 92 privacyLink.add(new StreetsideButton(imgLinkAction, true)); 93 checkPanel.add(privacyLink, BorderLayout.PAGE_END); 87 94 88 95 add(threeSixtyDegreeViewerPanel, BorderLayout.CENTER); 89 96 90 91 92 97 JPanel bottomPanel = new JPanel(); 98 bottomPanel.add(checkPanel, BorderLayout.NORTH); 99 bottomPanel.add(privacyLink, BorderLayout.SOUTH); 93 100 94 95 101 add(bottomPanel, BorderLayout.PAGE_END); 102 } 96 103 97 98 99 100 101 102 103 104 105 106 107 104 /* 105 * (non-Javadoc) 106 * 107 * @see 108 * org.openstreetmap.josm.plugins.streetside.StreetsideDataListener#imagesAdded( 109 * ) 110 */ 111 @Override 112 public void imagesAdded() { 113 // Method is not needed, but enforcesd by the interface StreetsideDataListener 114 } 108 115 109 110 111 112 113 114 115 116 117 118 119 116 /* 117 * (non-Javadoc) 118 * 119 * @see org.openstreetmap.josm.plugins.streetside.StreetsideDataListener# 120 * selectedImageChanged(org.openstreetmap.josm.plugins.streetside. 121 * StreetsideAbstractImage, 122 * org.openstreetmap.josm.plugins.streetside.StreetsideAbstractImage) 123 */ 124 @Override 125 public synchronized void selectedImageChanged(final StreetsideAbstractImage oldImage, 126 final StreetsideAbstractImage newImage) { 120 127 121 122 if(newImage!=null) {128 // method is invoked with null initially by framework 129 if (newImage != null) { 123 130 124 logger.info(String.format( 125 "Selected Streetside image changed from %s to %s.", 126 oldImage instanceof StreetsideImage ? ((StreetsideImage) oldImage).getId() : "‹none›", 127 newImage instanceof StreetsideImage ? ((StreetsideImage) newImage).getId() : "‹none›" 128 )); 131 LOGGER.info(String.format("Selected Streetside image changed from %s to %s.", 132 oldImage instanceof StreetsideImage ? oldImage.getId() : "‹none›", 133 newImage instanceof StreetsideImage ? newImage.getId() : "‹none›")); 129 134 130 final String newImageId = CubemapBuilder.getInstance().getCubemap() !=null ? CubemapBuilder.getInstance().getCubemap().getId() : newImage instanceof StreetsideImage ? ((StreetsideImage) newImage).getId(): null; 131 if (newImageId != null) { 132 final String bubbleId = CubemapUtils.convertQuaternary2Decimal(newImageId); 133 imageLinkChangeListener = b -> imgLinkAction.setURL( 134 StreetsideURL.MainWebsite.streetsidePrivacyLink(bubbleId) 135 ); 135 final String newImageId = CubemapBuilder.getInstance().getCubemap() != null 136 ? CubemapBuilder.getInstance().getCubemap().getId() 137 : newImage instanceof StreetsideImage ? ((StreetsideImage) newImage).getId() : null; 138 if (newImageId != null) { 139 final String bubbleId = CubemapUtils.convertQuaternary2Decimal(newImageId); 140 imageLinkChangeListener = b -> imgLinkAction 141 .setURL(StreetsideURL.MainWebsite.streetsidePrivacyLink(bubbleId)); 136 142 137 if(StreetsideProperties.DEBUGING_ENABLED.get()) { 138 logger.debug(MessageFormat.format("Privacy link set for Streetside image {0} quadKey {1}", bubbleId, newImageId)); 139 } 143 if (Boolean.TRUE.equals(StreetsideProperties.DEBUGING_ENABLED.get())) { 144 LOGGER.log(Logging.LEVEL_DEBUG, MessageFormat 145 .format("Privacy link set for Streetside image {0} quadKey {1}", bubbleId, newImageId)); 146 } 140 147 141 imageLinkChangeListener.valueChanged(null); 142 StreetsideProperties.CUBEMAP_LINK_TO_BLUR_EDITOR.addListener(imageLinkChangeListener); 143 } else { 144 if (imageLinkChangeListener != null) { 145 StreetsideProperties.CUBEMAP_LINK_TO_BLUR_EDITOR.removeListener(imageLinkChangeListener); 146 imageLinkChangeListener = null; 147 } 148 imgLinkAction.setURL(null); 149 } 150 } 151 } 152 153 public static CubemapBox getCubemapBox() { 154 return threeSixtyDegreeViewerPanel.getCubemapBox(); 155 } 156 157 /** 158 * @return the threeSixtyDegreeViewerPanel 159 */ 160 public static ThreeSixtyDegreeViewerPanel getThreeSixtyDegreeViewerPanel() { 161 return threeSixtyDegreeViewerPanel; 162 } 148 imageLinkChangeListener.valueChanged(null); 149 StreetsideProperties.CUBEMAP_LINK_TO_BLUR_EDITOR.addListener(imageLinkChangeListener); 150 } else { 151 if (imageLinkChangeListener != null) { 152 StreetsideProperties.CUBEMAP_LINK_TO_BLUR_EDITOR.removeListener(imageLinkChangeListener); 153 imageLinkChangeListener = null; 154 } 155 imgLinkAction.setURL(null); 156 } 157 } 158 } 163 159 } -
applications/editors/josm/plugins/MicrosoftStreetside/src/org/openstreetmap/josm/plugins/streetside/gui/imageinfo/ThreeSixtyDegreeViewerPanel.java
r34774 r36194 1 // License: GPL. For details, see LICENSE file.1 // License: GPL. For details, see LICENSE file. 2 2 package org.openstreetmap.josm.plugins.streetside.gui.imageinfo; 3 3 … … 11 11 import javafx.scene.PointLight; 12 12 import javafx.scene.Scene; 13 import javafx.scene.SceneAntialiasing; 13 14 import javafx.scene.control.Label; 14 import javafx.scene.SceneAntialiasing;15 15 import javafx.scene.control.TextArea; 16 16 import javafx.scene.image.Image; … … 26 26 27 27 private static final long serialVersionUID = -4940350009018422000L; 28 28 private static final CameraTransformer cameraTransform = new CameraTransformer(); 29 private static final double cameraDistance = 5000; 29 30 private static Scene cubemapScene; 30 31 31 private static Scene defaultScene; 32 32 private static Scene loadingScene; 33 34 33 private static Group root; 35 34 private static Group subGroup; 36 35 private static CubemapBox cubemapBox; 37 36 private static PerspectiveCamera camera; 38 private static CameraTransformer cameraTransform = new CameraTransformer();39 40 37 private static double mousePosX; 41 38 private static double mousePosY; … … 44 41 private static double mouseDeltaX; 45 42 private static double mouseDeltaY; 46 private static double cameraDistance = 5000;47 48 43 private static Image front; 49 44 private static Image right; … … 55 50 public ThreeSixtyDegreeViewerPanel() { 56 51 57 }58 59 public void initialize() {60 61 root = new Group();62 63 camera = new PerspectiveCamera(true);64 cameraTransform.setTranslate(0, 0, 0);65 cameraTransform.getChildren().addAll(camera);66 camera.setNearClip(0.1);67 camera.setFarClip(1000000.0);68 camera.setFieldOfView(42);69 camera.setTranslateZ(-cameraDistance);70 final PointLight light = new PointLight(Color.WHITE);71 72 cameraTransform.getChildren().add(light);73 light.setTranslateX(camera.getTranslateX());74 light.setTranslateY(camera.getTranslateY());75 light.setTranslateZ(camera.getTranslateZ());76 77 root.getChildren().add(cameraTransform);78 79 final double size = 100000D;80 81 cubemapBox = new CubemapBox(front, right, back, left, up, down, size, camera);82 83 subGroup = new Group();84 subGroup.getChildren().add(cameraTransform);85 86 createLoadingScene();87 88 Platform.runLater(new Runnable() {89 @Override90 public void run() {91 setScene(createDefaultScene());92 }93 });94 52 } 95 53 … … 177 135 if (me.isPrimaryButtonDown()) { 178 136 cameraTransform.ry.setAngle( 179 ((cameraTransform.ry.getAngle() + mouseDeltaX * modifierFactor * modifier * 2.0) % 360 + 540) % 360 - 180180 ); // +137 ((cameraTransform.ry.getAngle() + mouseDeltaX * modifierFactor * modifier * 2.0) % 360 + 540) 138 % 360 - 180); // + 181 139 cameraTransform.rx.setAngle( 182 ((cameraTransform.rx.getAngle() - mouseDeltaY * modifierFactor * modifier * 2.0) % 360 + 540) % 360 - 180183 ); // -140 ((cameraTransform.rx.getAngle() - mouseDeltaY * modifierFactor * modifier * 2.0) % 360 + 540) 141 % 360 - 180); // - 184 142 185 143 } else if (me.isSecondaryButtonDown()) { … … 212 170 } 213 171 172 public void initialize() { 173 174 root = new Group(); 175 176 camera = new PerspectiveCamera(true); 177 cameraTransform.setTranslate(0, 0, 0); 178 cameraTransform.getChildren().addAll(camera); 179 camera.setNearClip(0.1); 180 camera.setFarClip(1000000.0); 181 camera.setFieldOfView(42); 182 camera.setTranslateZ(-cameraDistance); 183 final PointLight light = new PointLight(Color.WHITE); 184 185 cameraTransform.getChildren().add(light); 186 light.setTranslateX(camera.getTranslateX()); 187 light.setTranslateY(camera.getTranslateY()); 188 light.setTranslateZ(camera.getTranslateZ()); 189 190 root.getChildren().add(cameraTransform); 191 192 final double size = 100000D; 193 194 cubemapBox = new CubemapBox(front, right, back, left, up, down, size, camera); 195 196 subGroup = new Group(); 197 subGroup.getChildren().add(cameraTransform); 198 199 createLoadingScene(); 200 201 Platform.runLater(() -> setScene(createDefaultScene())); 202 } 203 214 204 public CubemapBox getCubemapBox() { 215 205 if (cubemapBox == null) { -
applications/editors/josm/plugins/MicrosoftStreetside/src/org/openstreetmap/josm/plugins/streetside/gui/imageinfo/WebLinkAction.java
r34416 r36194 5 5 import java.io.IOException; 6 6 import java.net.URL; 7 import java.util.logging.Logger; 7 8 8 9 import javax.swing.AbstractAction; 9 10 import javax.swing.JOptionPane; 10 11 11 import org.apache.log4j.Logger;12 12 import org.openstreetmap.josm.gui.Notification; 13 13 import org.openstreetmap.josm.plugins.streetside.utils.StreetsideUtils; 14 14 import org.openstreetmap.josm.tools.ImageProvider; 15 15 import org.openstreetmap.josm.tools.ImageProvider.ImageSizes; 16 import org.openstreetmap.josm.tools.Logging; 16 17 17 18 public class WebLinkAction extends AbstractAction { … … 19 20 private static final long serialVersionUID = -8168227661356480455L; 20 21 21 final static Logger logger = Logger.getLogger(WebLinkAction.class);22 private static final Logger LOGGER = Logger.getLogger(WebLinkAction.class.getCanonicalName()); 22 23 23 24 private URL url; … … 45 46 } catch (IOException e1) { 46 47 String msg = "Could not open the URL " + url == null ? "‹null›" : url + " in a browser"; 47 logger.warn(msg, e1);48 LOGGER.log(Logging.LEVEL_WARN, msg, e1); 48 49 new Notification(msg).setIcon(JOptionPane.WARNING_MESSAGE).show(); 49 50 } -
applications/editors/josm/plugins/MicrosoftStreetside/src/org/openstreetmap/josm/plugins/streetside/history/StreetsideRecord.java
r34400 r36194 17 17 */ 18 18 public class StreetsideRecord { 19 /** The unique instance of the class. */ 20 private static StreetsideRecord instance; 19 /** 20 * The unique instance of the class. 21 */ 22 private static StreetsideRecord instance; 21 23 22 private final List<StreetsideRecordListener> listeners = new ArrayList<>();24 private final List<StreetsideRecordListener> listeners = new ArrayList<>(); 23 25 24 /** The set of commands that have taken place or that have been undone. */ 25 public List<StreetsideCommand> commandList; 26 /** Last written command. */ 27 public int position; 26 /** 27 * The set of commands that have taken place or that have been undone. 28 */ 29 public List<StreetsideCommand> commandList; 30 /** 31 * Last written command. 32 */ 33 public int position; 28 34 29 /** 30 * Main constructor. 31 */ 32 public StreetsideRecord() { 33 this.commandList = new ArrayList<>(); 34 this.position = -1; 35 /** 36 * Main constructor. 37 */ 38 public StreetsideRecord() { 39 this.commandList = new ArrayList<>(); 40 this.position = -1; 41 } 42 43 /** 44 * Returns the unique instance of the class. 45 * 46 * @return The unique instance of the class. 47 */ 48 public static synchronized StreetsideRecord getInstance() { 49 if (StreetsideRecord.instance == null) 50 StreetsideRecord.instance = new StreetsideRecord(); 51 return StreetsideRecord.instance; 52 } 53 54 /** 55 * Adds a listener. 56 * 57 * @param lis The listener to be added. 58 */ 59 public void addListener(StreetsideRecordListener lis) { 60 this.listeners.add(lis); 61 } 62 63 /** 64 * Removes the given listener. 65 * 66 * @param lis The listener to be removed. 67 */ 68 public void removeListener(StreetsideRecordListener lis) { 69 this.listeners.remove(lis); 70 } 71 72 /** 73 * Adds a new command to the list. 74 * 75 * @param command The command to be added. 76 */ 77 public void addCommand(final StreetsideCommand command) { 78 79 if (command instanceof StreetsideExecutableCommand) 80 ((StreetsideExecutableCommand) command).execute(); 81 // Checks if it is a continuation of last command 82 if (this.position != -1) { 83 boolean equalSets = true; 84 for (StreetsideAbstractImage img : this.commandList.get(this.position).images) { 85 equalSets = command.images.contains(img) && equalSets; 86 } 87 for (StreetsideAbstractImage img : command.images) { 88 equalSets = this.commandList.get(this.position).images.contains(img) && equalSets; 89 } 90 if (equalSets && this.commandList.get(this.position).getClass() == command.getClass()) { 91 this.commandList.get(this.position).sum(command); 92 fireRecordChanged(); 93 return; 94 } 95 } 96 // Adds the command to the last position of the list. 97 this.commandList.add(this.position + 1, command); 98 this.position++; 99 while (this.commandList.size() > this.position + 1) { 100 this.commandList.remove(this.position + 1); 101 } 102 fireRecordChanged(); 103 } 104 105 /** 106 * Undo latest command. 107 */ 108 public void undo() { 109 if (this.position <= -1) { 110 return; 111 } 112 this.commandList.get(this.position).undo(); 113 this.position--; 114 fireRecordChanged(); 115 } 116 117 /** 118 * Redoes latest undone action. 119 */ 120 public void redo() { 121 if (position + 1 >= commandList.size()) { 122 return; 123 } 124 this.position++; 125 this.commandList.get(this.position).redo(); 126 fireRecordChanged(); 127 } 128 129 private void fireRecordChanged() { 130 this.listeners.stream().filter(Objects::nonNull).forEach(StreetsideRecordListener::recordChanged); 131 } 132 133 /** 134 * Resets the object to its start state. 135 */ 136 public void reset() { 137 this.commandList.clear(); 138 this.position = -1; 139 } 35 140 } 36 37 /**38 * Returns the unique instance of the class.39 *40 * @return The unique instance of the class.41 */42 public static synchronized StreetsideRecord getInstance() {43 if (StreetsideRecord.instance == null)44 StreetsideRecord.instance = new StreetsideRecord();45 return StreetsideRecord.instance;46 }47 48 /**49 * Adds a listener.50 *51 * @param lis52 * The listener to be added.53 */54 public void addListener(StreetsideRecordListener lis) {55 this.listeners.add(lis);56 }57 58 /**59 * Removes the given listener.60 *61 * @param lis62 * The listener to be removed.63 */64 public void removeListener(StreetsideRecordListener lis) {65 this.listeners.remove(lis);66 }67 68 /**69 * Adds a new command to the list.70 *71 * @param command72 * The command to be added.73 */74 public void addCommand(final StreetsideCommand command) {75 76 if (command instanceof StreetsideExecutableCommand)77 ((StreetsideExecutableCommand) command).execute();78 // Checks if it is a continuation of last command79 if (this.position != -1) {80 boolean equalSets = true;81 for (StreetsideAbstractImage img : this.commandList.get(this.position).images) {82 equalSets = command.images.contains(img) && equalSets;83 }84 for (StreetsideAbstractImage img : command.images) {85 equalSets = this.commandList.get(this.position).images.contains(img) && equalSets;86 }87 if (equalSets && this.commandList.get(this.position).getClass() == command.getClass()) {88 this.commandList.get(this.position).sum(command);89 fireRecordChanged();90 return;91 }92 }93 // Adds the command to the last position of the list.94 this.commandList.add(this.position + 1, command);95 this.position++;96 while (this.commandList.size() > this.position + 1) {97 this.commandList.remove(this.position + 1);98 }99 fireRecordChanged();100 }101 102 /**103 * Undo latest command.104 */105 public void undo() {106 if (this.position <= -1) {107 return;108 }109 this.commandList.get(this.position).undo();110 this.position--;111 fireRecordChanged();112 }113 114 /**115 * Redoes latest undone action.116 */117 public void redo() {118 if (position + 1 >= commandList.size()) {119 return;120 }121 this.position++;122 this.commandList.get(this.position).redo();123 fireRecordChanged();124 }125 126 private void fireRecordChanged() {127 this.listeners.stream().filter(Objects::nonNull).forEach(StreetsideRecordListener::recordChanged);128 }129 130 /**131 * Resets the object to its start state.132 */133 public void reset() {134 this.commandList.clear();135 this.position = -1;136 }137 } -
applications/editors/josm/plugins/MicrosoftStreetside/src/org/openstreetmap/josm/plugins/streetside/history/StreetsideRecordListener.java
r34317 r36194 11 11 public interface StreetsideRecordListener { 12 12 13 /**14 * Fired when any command is undone or redone.15 */16 void recordChanged();13 /** 14 * Fired when any command is undone or redone. 15 */ 16 void recordChanged(); 17 17 } -
applications/editors/josm/plugins/MicrosoftStreetside/src/org/openstreetmap/josm/plugins/streetside/history/commands/CommandJoin.java
r34317 r36194 27 27 * @param b the second image, that is joined with the first one 28 28 * @throws IllegalArgumentException if the images are already in the same sequence 29 * @throws NullPointerException if {@code a} or {@code b} is null29 * @throws NullPointerException if {@code a} or {@code b} is null 30 30 */ 31 31 public CommandJoin(final StreetsideAbstractImage a, final StreetsideAbstractImage b) { -
applications/editors/josm/plugins/MicrosoftStreetside/src/org/openstreetmap/josm/plugins/streetside/history/commands/CommandMove.java
r34416 r36194 22 22 * Main constructor. 23 23 * 24 * @param images 25 * Set of images that are going to be moved. 26 * @param x 27 * How much the x coordinate increases. 28 * @param y 29 * How much the y coordinate increases. 24 * @param images Set of images that are going to be moved. 25 * @param x How much the x coordinate increases. 26 * @param y How much the y coordinate increases. 30 27 */ 31 public CommandMove(Set<StreetsideAbstractImage> images, double x, 32 double y) { 28 public CommandMove(Set<StreetsideAbstractImage> images, double x, double y) { 33 29 super(images); 34 30 this.x = x; … … 56 52 @Override 57 53 public String toString() { 58 return trn("Moved {0} image", "Moved {0} images", images.size(), 59 images.size()); 54 return trn("Moved {0} image", "Moved {0} images", images.size(), images.size()); 60 55 } 61 56 -
applications/editors/josm/plugins/MicrosoftStreetside/src/org/openstreetmap/josm/plugins/streetside/history/commands/CommandTurn.java
r34432 r36194 21 21 * Main constructor. 22 22 * 23 * @param images 24 * Set of images that is turned. 25 * @param ca 26 * How much the images turn. 23 * @param images Set of images that is turned. 24 * @param ca How much the images turn. 27 25 */ 28 26 public CommandTurn(Set<StreetsideAbstractImage> images, double ca) { … … 51 49 @Override 52 50 public String toString() { 53 return trn("Turned {0} image", "Turned {0} images", images.size(), 54 images.size()); 51 return trn("Turned {0} image", "Turned {0} images", images.size(), images.size()); 55 52 } 56 53 -
applications/editors/josm/plugins/MicrosoftStreetside/src/org/openstreetmap/josm/plugins/streetside/history/commands/CommandUnjoin.java
r34416 r36194 24 24 * Main constructor. 25 25 * 26 * @param images 27 * The two images that are going to be unjoined. Must be of exactly 28 * size 2. 29 * @throws IllegalArgumentException 30 * if the List size is different from 2. 26 * @param images The two images that are going to be unjoined. Must be of exactly 27 * size 2. 28 * @throws IllegalArgumentException if the List size is different from 2. 31 29 */ 32 30 public CommandUnjoin(List<StreetsideAbstractImage> images) { -
applications/editors/josm/plugins/MicrosoftStreetside/src/org/openstreetmap/josm/plugins/streetside/history/commands/StreetsideCommand.java
r34317 r36194 14 14 */ 15 15 public abstract class StreetsideCommand { 16 /** Set of {@link StreetsideAbstractImage} objects affected by the command */ 17 public Set<StreetsideAbstractImage> images; 16 /** 17 * Set of {@link StreetsideAbstractImage} objects affected by the command 18 */ 19 public Set<StreetsideAbstractImage> images; 18 20 19 /** 20 * Main constructor. 21 * 22 * @param images 23 * The images that are affected by the command. 24 */ 25 public StreetsideCommand(Set<StreetsideAbstractImage> images) { 26 this.images = new ConcurrentSkipListSet<>(images); 21 /** 22 * Main constructor. 23 * 24 * @param images The images that are affected by the command. 25 */ 26 protected StreetsideCommand(Set<StreetsideAbstractImage> images) { 27 this.images = new ConcurrentSkipListSet<>(images); 28 } 29 30 /** 31 * Undoes the action. 32 */ 33 public abstract void undo(); 34 35 /** 36 * Redoes the action. 37 */ 38 public abstract void redo(); 39 40 /** 41 * If two equal commands are applied consecutively to the same set of images, 42 * they are summed in order to reduce them to just one command. 43 * 44 * @param command The command to be summed to last command. 45 */ 46 public abstract void sum(StreetsideCommand command); 47 48 @Override 49 public abstract String toString(); 27 50 } 28 29 /**30 * Undoes the action.31 */32 public abstract void undo();33 34 /**35 * Redoes the action.36 */37 public abstract void redo();38 39 /**40 * If two equal commands are applied consecutively to the same set of images,41 * they are summed in order to reduce them to just one command.42 *43 * @param command44 * The command to be summed to last command.45 */46 public abstract void sum(StreetsideCommand command);47 48 @Override49 public abstract String toString();50 } -
applications/editors/josm/plugins/MicrosoftStreetside/src/org/openstreetmap/josm/plugins/streetside/history/commands/StreetsideExecutableCommand.java
r34317 r36194 14 14 public abstract class StreetsideExecutableCommand extends StreetsideCommand { 15 15 16 /** 17 * Main constructor. 18 * 19 * @param images 20 * The set of images affected by the command. 21 */ 22 public StreetsideExecutableCommand(Set<StreetsideAbstractImage> images) { 23 super(images); 16 /** 17 * Main constructor. 18 * 19 * @param images The set of images affected by the command. 20 */ 21 protected StreetsideExecutableCommand(Set<StreetsideAbstractImage> images) { 22 super(images); 23 } 24 25 /** 26 * Executes the command. It is run when the command is added to the history 27 * record. 28 */ 29 public abstract void execute(); 24 30 } 25 26 /**27 * Executes the command. It is run when the command is added to the history28 * record.29 */30 public abstract void execute();31 } -
applications/editors/josm/plugins/MicrosoftStreetside/src/org/openstreetmap/josm/plugins/streetside/io/download/BoundsDownloadRunnable.java
r34432 r36194 7 7 import java.net.URL; 8 8 import java.net.URLConnection; 9 import java.text.MessageFormat;10 9 import java.util.function.Function; 10 import java.util.logging.Logger; 11 11 12 import org.apache.log4j.Logger;13 12 import org.openstreetmap.josm.data.Bounds; 14 13 import org.openstreetmap.josm.gui.Notification; … … 17 16 import org.openstreetmap.josm.plugins.streetside.utils.StreetsideURL.APIv3; 18 17 import org.openstreetmap.josm.tools.ImageProvider.ImageSizes; 18 import org.openstreetmap.josm.tools.Logging; 19 19 20 20 public abstract class BoundsDownloadRunnable implements Runnable { 21 21 22 final static Logger logger = Logger.getLogger(BoundsDownloadRunnable.class);22 private static final Logger LOGGER = Logger.getLogger(BoundsDownloadRunnable.class.getCanonicalName()); 23 23 24 24 protected Bounds bounds; 25 protected abstract Function<Bounds, URL> getUrlGenerator();26 25 27 p ublicBoundsDownloadRunnable(final Bounds bounds) {26 protected BoundsDownloadRunnable(final Bounds bounds) { 28 27 this.bounds = bounds; 29 28 } 29 30 /** 31 * Logs information about the given connection via {@link Logger}. 32 * If it's a {@link HttpURLConnection}, the request method, the response code and the URL itself are logged. 33 * Otherwise only the URL is logged. 34 * 35 * @param con the {@link URLConnection} for which information is logged 36 * @param info an additional info text, which is appended to the output in braces 37 * @throws IOException if {@link HttpURLConnection#getResponseCode()} throws an {@link IOException} 38 */ 39 public static void logConnectionInfo(final URLConnection con, final String info) throws IOException { 40 final StringBuilder message; 41 if (con instanceof HttpURLConnection) { 42 message = new StringBuilder(((HttpURLConnection) con).getRequestMethod()).append(' ').append(con.getURL()) 43 .append(" → ").append(((HttpURLConnection) con).getResponseCode()); 44 } else { 45 message = new StringBuilder("Download from ").append(con.getURL()); 46 } 47 if (info != null && info.length() >= 1) { 48 message.append(" (").append(info).append(')'); 49 } 50 LOGGER.info(message::toString); 51 } 52 53 protected abstract Function<Bounds, URL> getUrlGenerator(); 30 54 31 55 @Override 32 56 public void run() { 33 57 URL nextURL = getUrlGenerator().apply(bounds); 34 if (StreetsideProperties.DEBUGING_ENABLED.get()) {35 logger.debug(MessageFormat.format("Downloading bounds: URL: {0}", nextURL.toString()));58 if (Boolean.TRUE.equals(StreetsideProperties.DEBUGING_ENABLED.get())) { 59 LOGGER.log(Logging.LEVEL_DEBUG, "Downloading bounds: URL: {0}", nextURL); 36 60 } 37 61 try { 38 62 while (nextURL != null) { 39 63 if (Thread.interrupted()) { 40 logger.error(getClass().getSimpleName() + " for " + bounds.toString() + " interrupted!"); 64 LOGGER.log(Logging.LEVEL_ERROR, "{0} for {1} interrupted!", 65 new Object[] { getClass().getSimpleName(), bounds }); 41 66 return; 42 67 } … … 46 71 } 47 72 } catch (IOException e) { 48 String message = "Could not read from URL " + nextURL.toString()+ "!";49 logger.warn(message, e);73 String message = "Could not read from URL " + nextURL + "!"; 74 LOGGER.log(Logging.LEVEL_WARN, message, e); 50 75 if (!GraphicsEnvironment.isHeadless()) { 51 new Notification(message) 52 .setIcon(StreetsidePlugin.LOGO.setSize(ImageSizes.LARGEICON).get()) 53 .setDuration(Notification.TIME_LONG) 54 .show(); 76 new Notification(message).setIcon(StreetsidePlugin.LOGO.setSize(ImageSizes.LARGEICON).get()) 77 .setDuration(Notification.TIME_LONG).show(); 55 78 } 56 e.printStackTrace();57 79 } 58 }59 60 /**61 * Logs information about the given connection via {@link Logger}.62 * If it's a {@link HttpURLConnection}, the request method, the response code and the URL itself are logged.63 * Otherwise only the URL is logged.64 * @param con the {@link URLConnection} for which information is logged65 * @param info an additional info text, which is appended to the output in braces66 * @throws IOException if {@link HttpURLConnection#getResponseCode()} throws an {@link IOException}67 */68 public static void logConnectionInfo(final URLConnection con, final String info) throws IOException {69 final StringBuilder message;70 if (con instanceof HttpURLConnection) {71 message = new StringBuilder(((HttpURLConnection) con).getRequestMethod())72 .append(' ').append(con.getURL())73 .append(" → ").append(((HttpURLConnection) con).getResponseCode());74 } else {75 message = new StringBuilder("Download from ").append(con.getURL());76 }77 if (info != null && info.length() >= 1) {78 message.append(" (").append(info).append(')');79 }80 logger.info(message.toString());81 80 } 82 81 -
applications/editors/josm/plugins/MicrosoftStreetside/src/org/openstreetmap/josm/plugins/streetside/io/download/SequenceDownloadRunnable.java
r34433 r36194 2 2 package org.openstreetmap.josm.plugins.streetside.io.download; 3 3 4 import java.io.BufferedInputStream;5 4 import java.io.IOException; 6 5 import java.net.URL; … … 11 10 import java.util.List; 12 11 import java.util.function.Function; 12 import java.util.logging.Logger; 13 13 14 14 import org.openstreetmap.josm.data.Bounds; … … 22 22 import org.openstreetmap.josm.plugins.streetside.utils.StreetsideSequenceIdGenerator; 23 23 import org.openstreetmap.josm.plugins.streetside.utils.StreetsideURL.APIv3; 24 import org.openstreetmap.josm.tools.Logging; 24 25 25 import com.fasterxml.jackson.core.JsonParseException; 26 import com.fasterxml.jackson.core.JsonParser; 27 import com.fasterxml.jackson.core.JsonToken; 28 import com.fasterxml.jackson.databind.DeserializationFeature; 29 import com.fasterxml.jackson.databind.JsonMappingException; 30 import com.fasterxml.jackson.databind.ObjectMapper; 31 import com.fasterxml.jackson.databind.node.ObjectNode; 26 import jakarta.json.Json; 27 import jakarta.json.JsonException; 28 import jakarta.json.JsonObject; 29 import jakarta.json.JsonValue; 30 import jakarta.json.stream.JsonParser; 32 31 33 32 public final class SequenceDownloadRunnable extends BoundsDownloadRunnable { 34 35 private final StreetsideData data; 36 33 private static final Logger LOG = Logger.getLogger(BoundsDownloadRunnable.class.getCanonicalName()); 37 34 private static final Function<Bounds, URL> URL_GEN = APIv3::searchStreetsideImages; 35 private final StreetsideData data; 38 36 39 37 public SequenceDownloadRunnable(final StreetsideData data, final Bounds bounds) { … … 54 52 final long startTime = System.currentTimeMillis(); 55 53 56 ObjectMapper mapper = new ObjectMapper();57 // Creation of Jackson Object Mapper necessary for Silverlight 2.0 JSON Syntax parsing:58 // (no double quotes in JSON on attribute names)59 mapper.configure(JsonParser.Feature.ALLOW_UNQUOTED_FIELD_NAMES, true);54 try (JsonParser parser = Json.createParser(con.getInputStream())) { 55 if (!parser.hasNext() || parser.next() != JsonParser.Event.START_ARRAY) { 56 throw new IllegalStateException("Expected an array"); 57 } 60 58 61 // Allow unrecognized properties - won't break with addition of new attributes 62 mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, true); 59 StreetsideImage previous = null; 63 60 64 try { 65 JsonParser parser = mapper.getFactory().createParser(new BufferedInputStream(con.getInputStream())); 66 if(parser.nextToken() != JsonToken.START_ARRAY) { 67 parser.close(); 68 throw new IllegalStateException("Expected an array"); 69 } 70 71 StreetsideImage previous = null; 72 73 while (parser.nextToken() == JsonToken.START_OBJECT) { 61 while (parser.hasNext() && parser.next() == JsonParser.Event.START_OBJECT) { 74 62 // read everything from this START_OBJECT to the matching END_OBJECT 75 63 // and return it as a tree model ObjectNode 76 ObjectNode node = mapper.readTree(parser);64 JsonObject node = parser.getObject(); 77 65 // Discard the first sequence ('enabled') - it does not contain bubble data 78 66 if (node.get("id") != null && node.get("la") != null && node.get("lo") != null) { 79 StreetsideImage image = new StreetsideImage(CubemapUtils.convertDecimal2Quaternary(node.path("id").asLong()), new LatLon(node.path("la").asDouble(), node.get("lo").asDouble()), node.get("he").asDouble()); 80 if(previous!=null) { 67 StreetsideImage image = new StreetsideImage( 68 CubemapUtils.convertDecimal2Quaternary(node.getJsonNumber("id").longValue()), 69 new LatLon(node.getJsonNumber("la").doubleValue(), node.getJsonNumber("lo").doubleValue()), 70 node.getJsonNumber("he").doubleValue()); 71 if (previous != null) { 81 72 image.setPr(Long.parseLong(previous.getId())); 82 73 previous.setNe(Long.parseLong(image.getId())); … … 84 75 } 85 76 previous = image; 86 image.setAd(node.path("ad").asInt()); 87 image.setAl(node.path("al").asDouble()); 88 image.setBl(node.path("bl").asText()); 89 image.setMl(node.path("ml").asInt()); 90 image.setNbn(node.findValuesAsText("nbn")); 91 image.setNe(node.path("ne").asLong()); 92 image.setPbn(node.findValuesAsText("pbn")); 93 image.setPi(node.path("pi").asDouble()); 94 image.setPr(node.path("pr").asLong()); 95 image.setRo(node.path("ro").asDouble()); 77 if (node.containsKey("ad")) 78 image.setAd(node.getJsonNumber("ad").intValue()); 79 if (node.containsKey("al")) 80 image.setAl(node.getJsonNumber("al").doubleValue()); 81 if (node.containsKey("bl")) 82 image.setBl(node.getString("bl")); 83 if (node.containsKey("ml")) 84 image.setMl(node.getJsonNumber("ml").intValue()); 85 if (node.containsKey("ne")) 86 image.setNe(node.getJsonNumber("ne").longValue()); 87 if (node.containsKey("pi")) 88 image.setPi(node.getJsonNumber("pi").doubleValue()); 89 if (node.containsKey("pr")) 90 image.setPr(node.getJsonNumber("pr").longValue()); 91 if (node.containsKey("ro")) 92 image.setRo(node.getJsonNumber("ro").doubleValue()); 93 if (node.containsKey("nbn")) 94 image.setNbn(node.getJsonArray("nbn").getValuesAs(JsonValue::toString)); 95 if (node.containsKey("pbn")) 96 image.setPbn(node.getJsonArray("pbn").getValuesAs(JsonValue::toString)); 96 97 97 98 // Add list of cubemap tile images to images … … 103 104 // Initialize four-tiled cubemap faces (four images per cube side with 18-length 104 105 // Quadkey) 105 if ( !StreetsideProperties.SHOW_HIGH_RES_STREETSIDE_IMAGERY.get()) {106 StreetsideImage tile = new StreetsideImage( String.valueOf(image.getId() + Integer.valueOf(i)));106 if (Boolean.FALSE.equals(StreetsideProperties.SHOW_HIGH_RES_STREETSIDE_IMAGERY.get())) { 107 StreetsideImage tile = new StreetsideImage(image.getId() + i); 107 108 tiles.add(tile); 108 109 } 109 110 // Initialize four-tiled cubemap faces (four images per cub eside with 20-length 110 111 // Quadkey) 111 if ( StreetsideProperties.SHOW_HIGH_RES_STREETSIDE_IMAGERY.get()) {112 if (Boolean.TRUE.equals(StreetsideProperties.SHOW_HIGH_RES_STREETSIDE_IMAGERY.get())) { 112 113 for (int j = 0; j < 4; j++) { 113 StreetsideImage tile = new StreetsideImage( 114 String.valueOf( 115 image.getId() + face.getValue() + CubemapUtils.rowCol2StreetsideCellAddressMap 116 .get(String.valueOf(Integer.valueOf(i).toString() + Integer.valueOf(j).toString())) 117 )); 114 StreetsideImage tile = new StreetsideImage(image.getId() + face.getValue() 115 + CubemapUtils.rowCol2StreetsideCellAddressMap 116 .get(i + Integer.toString(j))); 118 117 tiles.add(tile); 119 118 } … … 122 121 }); 123 122 124 125 logger.info("Added image with id <" + image.getId() + ">");126 if ( StreetsideProperties.PREDOWNLOAD_CUBEMAPS.get()) {123 bubbleImages.add(image); 124 LOG.info("Added image with id <" + image.getId() + ">"); 125 if (Boolean.TRUE.equals(StreetsideProperties.PREDOWNLOAD_CUBEMAPS.get())) { 127 126 StreetsideData.downloadSurroundingCubemaps(image); 128 127 } 129 128 } else { 130 logger.info(MessageFormat.format("Unparsable JSON node object: {0}",node.toString()));129 LOG.info(MessageFormat.format("Unparsable JSON node object: {0}", node)); 131 130 } 132 131 } 133 134 parser.close(); 135 136 } catch (JsonParseException e) { 137 logger.error(MessageFormat.format("JSON parsing error occured during Streetside sequence download {0}",e.getMessage())); 138 } catch (JsonMappingException e) { 139 logger.error(MessageFormat.format("JSON mapping error occured during Streetside sequence download {0}",e.getMessage())); 132 } catch (ClassCastException | JsonException e) { 133 LOG.log(Logging.LEVEL_ERROR, e, () -> MessageFormat 134 .format("JSON parsing error occurred during Streetside sequence download {0}", e.getMessage())); 140 135 } catch (IOException e) { 141 logger.error(MessageFormat.format("Input/output error occured during Streetside sequence download {0}",e.getMessage())); 136 LOG.log(Logging.LEVEL_ERROR, e, () -> MessageFormat 137 .format("Input/output error occurred during Streetside sequence download {0}", e.getMessage())); 142 138 } 143 139 144 /** Top Level Bubble Metadata in Streetside are bubble (aka images) not Sequences 140 /* 141 * Top Level Bubble Metadata in Streetside are bubble (aka images) not Sequences 145 142 * so a sequence needs to be created and have images added to it. If the distribution 146 143 * of Streetside images is non-sequential, the Mapillary "Walking Action" may behave 147 144 * unpredictably. 148 * */145 */ 149 146 seq.add(bubbleImages); 150 147 151 if ( StreetsideProperties.CUT_OFF_SEQUENCES_AT_BOUNDS.get()) {148 if (Boolean.TRUE.equals(StreetsideProperties.CUT_OFF_SEQUENCES_AT_BOUNDS.get())) { 152 149 for (StreetsideAbstractImage img : seq.getImages()) { 153 150 if (bounds.contains(img.getLatLon())) { … … 168 165 169 166 final long endTime = System.currentTimeMillis(); 170 logger.info(MessageFormat.format("Sucessfully loaded {0} Microsoft Streetside images in {1} seconds.", seq.getImages().size(),(endTime-startTime)/1000)); 167 LOG.info(MessageFormat.format("Successfully loaded {0} Microsoft Streetside images in {1} seconds.", 168 seq.getImages().size(), (endTime - startTime) / 1000)); 171 169 } 172 170 -
applications/editors/josm/plugins/MicrosoftStreetside/src/org/openstreetmap/josm/plugins/streetside/io/download/StreetsideDownloader.java
r34399 r36194 5 5 import java.util.concurrent.ThreadPoolExecutor; 6 6 import java.util.concurrent.TimeUnit; 7 8 import org.apache.log4j.Logger; 7 import java.util.logging.Logger; 8 9 9 import org.openstreetmap.josm.data.Bounds; 10 10 import org.openstreetmap.josm.data.coor.LatLon; … … 15 15 import org.openstreetmap.josm.plugins.streetside.utils.StreetsideProperties; 16 16 import org.openstreetmap.josm.tools.I18n; 17 import org.openstreetmap.josm.tools.Logging; 17 18 18 19 /** … … 24 25 public final class StreetsideDownloader { 25 26 26 final static Logger logger = Logger.getLogger(StreetsideDownloader.class); 27 28 /** Possible download modes. */ 27 private static final Logger LOGGER = Logger.getLogger(StreetsideDownloader.class.getCanonicalName()); 28 /** 29 * Max area to be downloaded 30 */ 31 private static final double MAX_AREA = StreetsideProperties.MAX_DOWNLOAD_AREA.get(); 32 /** 33 * Executor that will run the petitions. 34 */ 35 private static ThreadPoolExecutor executor = new ThreadPoolExecutor(3, 5, 100, TimeUnit.SECONDS, 36 new ArrayBlockingQueue<>(100), new ThreadPoolExecutor.DiscardPolicy()); 37 /** 38 * Indicates whether the last download request has been rejected because it requested an area that was too big. 39 * Iff true, the last download has been rejected, if false, it was executed. 40 */ 41 private static boolean stoppedDownload; 42 43 private StreetsideDownloader() { 44 // Private constructor to avoid instantiation 45 } 46 47 /** 48 * Downloads all images of the area covered by the OSM data. 49 */ 50 public static void downloadOSMArea() { 51 if (MainApplication.getLayerManager().getEditLayer() == null) { 52 return; 53 } 54 if (isAreaTooBig(MainApplication.getLayerManager().getEditLayer().data.getDataSourceBounds().stream() 55 .map(Bounds::getArea).reduce(0.0, Double::sum))) { 56 return; 57 } 58 MainApplication.getLayerManager().getEditLayer().data.getDataSourceBounds().stream() 59 .filter(bounds -> !StreetsideLayer.getInstance().getData().getBounds().contains(bounds)) 60 .forEach(bounds -> { 61 StreetsideLayer.getInstance().getData().getBounds().add(bounds); 62 StreetsideDownloader.getImages(bounds.getMin(), bounds.getMax()); 63 }); 64 } 65 66 /** 67 * Gets all the images in a square. It downloads all the images of all the 68 * sequences that pass through the given rectangle. 69 * 70 * @param minLatLon The minimum latitude and longitude of the rectangle. 71 * @param maxLatLon The maximum latitude and longitude of the rectangle 72 */ 73 public static void getImages(LatLon minLatLon, LatLon maxLatLon) { 74 if (minLatLon == null || maxLatLon == null) { 75 throw new IllegalArgumentException(); 76 } 77 getImages(new Bounds(minLatLon, maxLatLon)); 78 } 79 80 /** 81 * Gets the images within the given bounds. 82 * 83 * @param bounds A {@link Bounds} object containing the area to be downloaded. 84 */ 85 public static void getImages(Bounds bounds) { 86 run(new StreetsideSquareDownloadRunnable(bounds)); 87 } 88 89 /** 90 * Returns the current download mode. 91 * 92 * @return the currently enabled {@link DOWNLOAD_MODE} 93 */ 94 public static DOWNLOAD_MODE getMode() { 95 return DOWNLOAD_MODE.fromPrefId(StreetsideProperties.DOWNLOAD_MODE.get()); 96 } 97 98 private static void run(Runnable t) { 99 executor.execute(t); 100 } 101 102 /** 103 * If some part of the current view has not been downloaded, it is downloaded. 104 */ 105 public static void downloadVisibleArea() { 106 Bounds view = MainApplication.getMap().mapView.getRealBounds(); 107 if (isAreaTooBig(view.getArea())) { 108 return; 109 } 110 if (isViewDownloaded(view)) { 111 return; 112 } 113 StreetsideLayer.getInstance().getData().getBounds().add(view); 114 getImages(view); 115 } 116 117 private static boolean isViewDownloaded(Bounds view) { 118 int n = 15; 119 boolean[][] inside = new boolean[n][n]; 120 for (int i = 0; i < n; i++) { 121 for (int j = 0; j < n; j++) { 122 if (isInBounds(new LatLon(view.getMinLat() + (view.getMaxLat() - view.getMinLat()) * ((double) i / n), 123 view.getMinLon() + (view.getMaxLon() - view.getMinLon()) * ((double) j / n)))) { 124 inside[i][j] = true; 125 } 126 } 127 } 128 for (int i = 0; i < n; i++) { 129 for (int j = 0; j < n; j++) { 130 if (!inside[i][j]) 131 return false; 132 } 133 } 134 return true; 135 } 136 137 /** 138 * Checks if the given {@link LatLon} object lies inside the bounds of the 139 * image. 140 * 141 * @param latlon The coordinates to check. 142 * @return true if it lies inside the bounds; false otherwise; 143 */ 144 private static boolean isInBounds(LatLon latlon) { 145 return StreetsideLayer.getInstance().getData().getBounds().parallelStream().anyMatch(b -> b.contains(latlon)); 146 } 147 148 /** 149 * Checks if the area for which Streetside images should be downloaded is too big. This means that probably 150 * lots of Streetside images are going to be downloaded, slowing down the 151 * program too much. A notification is shown when the download has stopped or continued. 152 * 153 * @param area area to check 154 * @return {@code true} if the area is too big 155 */ 156 private static boolean isAreaTooBig(final double area) { 157 final boolean tooBig = area > MAX_AREA; 158 if (!stoppedDownload && tooBig) { 159 new Notification(I18n 160 .tr("The Streetside layer has stopped downloading images, because the requested area is too big!") 161 + (getMode() == DOWNLOAD_MODE.VISIBLE_AREA 162 ? "\n" + I18n 163 .tr("To solve this problem, you could zoom in and load a smaller area of the map.") 164 : (getMode() == DOWNLOAD_MODE.OSM_AREA ? "\n" + I18n.tr( 165 "To solve this problem, you could switch to download mode ''{0}'' and load Streetside images for a smaller portion of the map.", 166 DOWNLOAD_MODE.MANUAL_ONLY) : ""))).setIcon(StreetsidePlugin.LOGO.get()) 167 .setDuration(Notification.TIME_LONG).show(); 168 } 169 if (stoppedDownload && !tooBig) { 170 new Notification("The Streetside layer now continues to download images…") 171 .setIcon(StreetsidePlugin.LOGO.get()).show(); 172 } 173 stoppedDownload = tooBig; 174 return tooBig; 175 } 176 177 /** 178 * Stops all running threads. 179 */ 180 public static void stopAll() { 181 executor.shutdownNow(); 182 try { 183 executor.awaitTermination(30, TimeUnit.SECONDS); 184 } catch (InterruptedException e) { 185 LOGGER.log(Logging.LEVEL_ERROR, e.getMessage(), e); 186 } 187 executor = new ThreadPoolExecutor(3, 5, 100, TimeUnit.SECONDS, new ArrayBlockingQueue<>(100), 188 new ThreadPoolExecutor.DiscardPolicy()); 189 } 190 191 /** 192 * Possible download modes. 193 */ 29 194 public enum DOWNLOAD_MODE { 30 195 VISIBLE_AREA("visibleArea", I18n.tr("everything in the visible area")), … … 34 199 MANUAL_ONLY("manualOnly", I18n.tr("only when manually requested")); 35 200 36 public final staticDOWNLOAD_MODE DEFAULT = OSM_AREA;201 public static final DOWNLOAD_MODE DEFAULT = OSM_AREA; 37 202 38 203 private final String prefId; … … 42 207 this.prefId = prefId; 43 208 this.label = label; 209 } 210 211 public static DOWNLOAD_MODE fromPrefId(String prefId) { 212 for (DOWNLOAD_MODE mode : DOWNLOAD_MODE.values()) { 213 if (mode.getPrefId().equals(prefId)) { 214 return mode; 215 } 216 } 217 return DEFAULT; 218 } 219 220 public static DOWNLOAD_MODE fromLabel(String label) { 221 for (DOWNLOAD_MODE mode : DOWNLOAD_MODE.values()) { 222 if (mode.getLabel().equals(label)) { 223 return mode; 224 } 225 } 226 return DEFAULT; 44 227 } 45 228 … … 57 240 return label; 58 241 } 59 60 public static DOWNLOAD_MODE fromPrefId(String prefId) {61 for (DOWNLOAD_MODE mode : DOWNLOAD_MODE.values()) {62 if (mode.getPrefId().equals(prefId)) {63 return mode;64 }65 }66 return DEFAULT;67 }68 69 public static DOWNLOAD_MODE fromLabel(String label) {70 for (DOWNLOAD_MODE mode : DOWNLOAD_MODE.values()) {71 if (mode.getLabel().equals(label)) {72 return mode;73 }74 }75 return DEFAULT;76 }77 }78 79 /** Max area to be downloaded */80 private static final double MAX_AREA = StreetsideProperties.MAX_DOWNLOAD_AREA.get();81 82 /** Executor that will run the petitions. */83 private static ThreadPoolExecutor executor = new ThreadPoolExecutor(84 3, 5, 100, TimeUnit.SECONDS, new ArrayBlockingQueue<>(100), new ThreadPoolExecutor.DiscardPolicy());85 86 /**87 * Indicates whether the last download request has been rejected because it requested an area that was too big.88 * Iff true, the last download has been rejected, if false, it was executed.89 */90 private static boolean stoppedDownload;91 92 private StreetsideDownloader() {93 // Private constructor to avoid instantiation94 }95 96 /**97 * Gets all the images in a square. It downloads all the images of all the98 * sequences that pass through the given rectangle.99 *100 * @param minLatLon The minimum latitude and longitude of the rectangle.101 * @param maxLatLon The maximum latitude and longitude of the rectangle102 */103 public static void getImages(LatLon minLatLon, LatLon maxLatLon) {104 if (minLatLon == null || maxLatLon == null) {105 throw new IllegalArgumentException();106 }107 getImages(new Bounds(minLatLon, maxLatLon));108 }109 110 /**111 * Gets the images within the given bounds.112 *113 * @param bounds A {@link Bounds} object containing the area to be downloaded.114 */115 public static void getImages(Bounds bounds) {116 run(new StreetsideSquareDownloadRunnable(bounds));117 }118 119 /**120 * Returns the current download mode.121 *122 * @return the currently enabled {@link DOWNLOAD_MODE}123 */124 public static DOWNLOAD_MODE getMode() {125 return DOWNLOAD_MODE.fromPrefId(StreetsideProperties.DOWNLOAD_MODE.get());126 }127 128 private static void run(Runnable t) {129 executor.execute(t);130 }131 132 /**133 * If some part of the current view has not been downloaded, it is downloaded.134 */135 public static void downloadVisibleArea() {136 Bounds view = MainApplication.getMap().mapView.getRealBounds();137 if (isAreaTooBig(view.getArea())) {138 return;139 }140 if (isViewDownloaded(view)) {141 return;142 }143 StreetsideLayer.getInstance().getData().getBounds().add(view);144 getImages(view);145 }146 147 private static boolean isViewDownloaded(Bounds view) {148 int n = 15;149 boolean[][] inside = new boolean[n][n];150 for (int i = 0; i < n; i++) {151 for (int j = 0; j < n; j++) {152 if (isInBounds(new LatLon(view.getMinLat()153 + (view.getMaxLat() - view.getMinLat()) * ((double) i / n),154 view.getMinLon() + (view.getMaxLon() - view.getMinLon())155 * ((double) j / n)))) {156 inside[i][j] = true;157 }158 }159 }160 for (int i = 0; i < n; i++) {161 for (int j = 0; j < n; j++) {162 if (!inside[i][j])163 return false;164 }165 }166 return true;167 }168 169 /**170 * Checks if the given {@link LatLon} object lies inside the bounds of the171 * image.172 *173 * @param latlon The coordinates to check.174 *175 * @return true if it lies inside the bounds; false otherwise;176 */177 private static boolean isInBounds(LatLon latlon) {178 return StreetsideLayer.getInstance().getData().getBounds().parallelStream().anyMatch(b -> b.contains(latlon));179 }180 181 /**182 * Downloads all images of the area covered by the OSM data.183 */184 public static void downloadOSMArea() {185 if (MainApplication.getLayerManager().getEditLayer() == null) {186 return;187 }188 if (isAreaTooBig(MainApplication.getLayerManager().getEditLayer().data.getDataSourceBounds().parallelStream().map(Bounds::getArea).reduce(0.0, Double::sum))) {189 return;190 }191 MainApplication.getLayerManager().getEditLayer().data.getDataSourceBounds().stream().filter(bounds -> !StreetsideLayer.getInstance().getData().getBounds().contains(bounds)).forEach(bounds -> {192 StreetsideLayer.getInstance().getData().getBounds().add(bounds);193 StreetsideDownloader.getImages(bounds.getMin(), bounds.getMax());194 });195 }196 197 /**198 * Checks if the area for which Streetside images should be downloaded is too big. This means that probably199 * lots of Streetside images are going to be downloaded, slowing down the200 * program too much. A notification is shown when the download has stopped or continued.201 * @param area area to check202 * @return {@code true} if the area is too big203 */204 private static boolean isAreaTooBig(final double area) {205 final boolean tooBig = area > MAX_AREA;206 if (!stoppedDownload && tooBig) {207 new Notification(208 I18n.tr("The Streetside layer has stopped downloading images, because the requested area is too big!") + (209 getMode() == DOWNLOAD_MODE.VISIBLE_AREA210 ? "\n"+I18n.tr("To solve this problem, you could zoom in and load a smaller area of the map.")211 : (getMode() == DOWNLOAD_MODE.OSM_AREA ? "\n"+I18n.tr("To solve this problem, you could switch to download mode ''{0}'' and load Streetside images for a smaller portion of the map.", DOWNLOAD_MODE.MANUAL_ONLY): "")212 )213 ).setIcon(StreetsidePlugin.LOGO.get()).setDuration(Notification.TIME_LONG).show();214 }215 if (stoppedDownload && !tooBig) {216 new Notification("The Streetside layer now continues to download images…").setIcon(StreetsidePlugin.LOGO.get()).show();217 }218 stoppedDownload = tooBig;219 return tooBig;220 }221 222 /**223 * Stops all running threads.224 */225 public static void stopAll() {226 executor.shutdownNow();227 try {228 executor.awaitTermination(30, TimeUnit.SECONDS);229 } catch (InterruptedException e) {230 logger.error(e);231 }232 executor = new ThreadPoolExecutor(3, 5, 100, TimeUnit.SECONDS,233 new ArrayBlockingQueue<>(100), new ThreadPoolExecutor.DiscardPolicy());234 242 } 235 243 } -
applications/editors/josm/plugins/MicrosoftStreetside/src/org/openstreetmap/josm/plugins/streetside/io/download/StreetsideSquareDownloadRunnable.java
r34412 r36194 2 2 package org.openstreetmap.josm.plugins.streetside.io.download; 3 3 4 import org.apache.log4j.Logger;5 4 import org.openstreetmap.josm.data.Bounds; 6 5 import org.openstreetmap.josm.plugins.streetside.StreetsideLayer; … … 11 10 public class StreetsideSquareDownloadRunnable implements Runnable { 12 11 13 final static Logger logger = Logger.getLogger(StreetsideSquareDownloadRunnable.class);14 15 12 private final Bounds bounds; 16 13 … … 19 16 * 20 17 * @param bounds the bounds of the area that should be downloaded 21 *22 18 */ 23 19 public StreetsideSquareDownloadRunnable(Bounds bounds) { -
applications/editors/josm/plugins/MicrosoftStreetside/src/org/openstreetmap/josm/plugins/streetside/io/export/StreetsideExportDownloadThread.java
r34416 r36194 6 6 import java.io.IOException; 7 7 import java.util.concurrent.ArrayBlockingQueue; 8 import java.util.logging.Logger; 8 9 9 10 import javax.imageio.ImageIO; 10 11 11 import org.apache.log4j.Logger;12 12 import org.openstreetmap.josm.data.cache.CacheEntry; 13 13 import org.openstreetmap.josm.data.cache.CacheEntryAttributes; … … 17 17 import org.openstreetmap.josm.plugins.streetside.cache.CacheUtils; 18 18 import org.openstreetmap.josm.plugins.streetside.cache.StreetsideCache; 19 import org.openstreetmap.josm.tools.Logging; 19 20 20 21 /** … … 26 27 * @see StreetsideExportWriterThread 27 28 */ 28 public class StreetsideExportDownloadThread extends Thread implements 29 ICachedLoaderListener { 29 public class StreetsideExportDownloadThread extends Thread implements ICachedLoaderListener { 30 30 31 final static Logger logger = Logger.getLogger(StreetsideExportDownloadThread.class);31 private static final Logger LOGGER = Logger.getLogger(StreetsideExportDownloadThread.class.getCanonicalName()); 32 32 33 33 private final ArrayBlockingQueue<BufferedImage> queue; … … 39 39 * Main constructor. 40 40 * 41 * @param image 42 * Image to be downloaded. 43 * @param queue 44 * Queue of {@link BufferedImage} objects for the 41 * @param image Image to be downloaded. 42 * @param queue Queue of {@link BufferedImage} objects for the 45 43 * {@link StreetsideExportWriterThread}. 46 * @param queueImages 47 * Queue of {@link StreetsideAbstractImage} objects for the 44 * @param queueImages Queue of {@link StreetsideAbstractImage} objects for the 48 45 * {@link StreetsideExportWriterThread}. 49 46 */ 50 public StreetsideExportDownloadThread(StreetsideImage image, 51 ArrayBlockingQueue<BufferedImage> queue, 47 public StreetsideExportDownloadThread(StreetsideImage image, ArrayBlockingQueue<BufferedImage> queue, 52 48 ArrayBlockingQueue<StreetsideAbstractImage> queueImages) { 53 49 this.queue = queue; … … 63 59 64 60 @Override 65 public synchronized void loadingFinished(CacheEntry data, 66 CacheEntryAttributes attributes, LoadResult result) { 61 public synchronized void loadingFinished(CacheEntry data, CacheEntryAttributes attributes, LoadResult result) { 67 62 try { 68 63 synchronized (StreetsideExportDownloadThread.class) { 69 queue 70 .put(ImageIO.read(new ByteArrayInputStream(data.getContent()))); 64 queue.put(ImageIO.read(new ByteArrayInputStream(data.getContent()))); 71 65 queueImages.put(image); 72 66 } 73 67 } catch (InterruptedException | IOException e) { 74 logger.error(e);68 LOGGER.log(Logging.LEVEL_ERROR, e.getMessage(), e); 75 69 } 76 70 } -
applications/editors/josm/plugins/MicrosoftStreetside/src/org/openstreetmap/josm/plugins/streetside/io/export/StreetsideExportManager.java
r34429 r36194 11 11 import java.util.concurrent.ThreadPoolExecutor; 12 12 import java.util.concurrent.TimeUnit; 13 import java.util.logging.Logger; 13 14 14 import org.apache.log4j.Logger;15 15 import org.openstreetmap.josm.gui.PleaseWaitRunnable; 16 16 import org.openstreetmap.josm.gui.progress.swing.PleaseWaitProgressMonitor; 17 17 import org.openstreetmap.josm.plugins.streetside.StreetsideAbstractImage; 18 18 import org.openstreetmap.josm.plugins.streetside.StreetsideImage; 19 import org.openstreetmap.josm.tools.Logging; 19 20 20 21 /** … … 32 33 public class StreetsideExportManager extends PleaseWaitRunnable { 33 34 34 final static Logger logger = Logger.getLogger(StreetsideExportManager.class);35 private static final Logger LOGGER = Logger.getLogger(StreetsideExportManager.class.getCanonicalName()); 35 36 36 37 private final ArrayBlockingQueue<BufferedImage> queue = new ArrayBlockingQueue<>(10); 37 38 private final ArrayBlockingQueue<StreetsideAbstractImage> queueImages = new ArrayBlockingQueue<>(10); 38 39 39 private int amount;40 private Set<StreetsideAbstractImage> images;41 private String path;40 private final int amount; 41 private final Set<StreetsideAbstractImage> images; 42 private final String path; 42 43 43 44 private Thread writer; … … 48 49 * 49 50 * @param images Set of {@link StreetsideAbstractImage} objects to be exported. 50 * @param path Export path.51 * @param path Export path. 51 52 */ 52 53 public StreetsideExportManager(Set<StreetsideAbstractImage> images, String path) { 53 super( 54 tr("Downloading") + "…", 55 new PleaseWaitProgressMonitor(tr("Exporting Streetside Images")), 56 true 57 ); 54 super(tr("Downloading") + "…", new PleaseWaitProgressMonitor(tr("Exporting Streetside Images")), true); 58 55 this.images = images == null ? new HashSet<>() : images; 59 56 this.path = path; … … 70 67 protected void realRun() throws IOException { 71 68 // Starts a writer thread in order to write the pictures on the disk. 72 writer = new StreetsideExportWriterThread(path, queue, 73 queueImages, amount, getProgressMonitor()); 69 writer = new StreetsideExportWriterThread(path, queue, queueImages, amount, getProgressMonitor()); 74 70 writer.start(); 75 71 if (path == null) { … … 77 73 writer.join(); 78 74 } catch (InterruptedException e) { 79 logger.error(e);75 LOGGER.log(Logging.LEVEL_ERROR, e.getMessage(), e); 80 76 } 81 77 return; 82 78 } 83 ex = new ThreadPoolExecutor(20, 35, 25, TimeUnit.SECONDS, 84 new ArrayBlockingQueue<>(10)); 79 ex = new ThreadPoolExecutor(20, 35, 25, TimeUnit.SECONDS, new ArrayBlockingQueue<>(10)); 85 80 for (StreetsideAbstractImage image : images) { 86 81 if (image instanceof StreetsideImage) { 87 82 try { 88 ex.execute(new StreetsideExportDownloadThread( 89 (StreetsideImage) image, queue, queueImages)); 83 ex.execute(new StreetsideExportDownloadThread((StreetsideImage) image, queue, queueImages)); 90 84 } catch (Exception e) { 91 logger.error(e);85 LOGGER.log(Logging.LEVEL_ERROR, e.getMessage(), e); 92 86 } 93 87 } … … 99 93 } 100 94 } catch (Exception e) { 101 logger.error(e);95 LOGGER.log(Logging.LEVEL_ERROR, e.getMessage(), e); 102 96 } 103 97 } … … 105 99 writer.join(); 106 100 } catch (InterruptedException e) { 107 logger.error(e);101 LOGGER.log(Logging.LEVEL_ERROR, e.getMessage(), e); 108 102 } 109 103 } -
applications/editors/josm/plugins/MicrosoftStreetside/src/org/openstreetmap/josm/plugins/streetside/io/export/StreetsideExportWriterThread.java
r34429 r36194 9 9 import java.io.OutputStream; 10 10 import java.util.concurrent.ArrayBlockingQueue; 11 import java.util.logging.Logger; 11 12 12 13 import javax.imageio.ImageIO; … … 20 21 import org.apache.commons.imaging.formats.tiff.write.TiffOutputDirectory; 21 22 import org.apache.commons.imaging.formats.tiff.write.TiffOutputSet; 22 import org.apache.log4j.Logger;23 23 import org.openstreetmap.josm.gui.progress.ProgressMonitor; 24 24 import org.openstreetmap.josm.gui.progress.swing.PleaseWaitProgressMonitor; 25 25 import org.openstreetmap.josm.plugins.streetside.StreetsideAbstractImage; 26 import org.openstreetmap.josm.tools.Logging; 26 27 27 28 /** … … 33 34 public class StreetsideExportWriterThread extends Thread { 34 35 35 final static Logger logger = Logger.getLogger(StreetsideExportWriterThread.class);36 private static final Logger LOGGER = Logger.getLogger(StreetsideExportWriterThread.class.getCanonicalName()); 36 37 37 38 private final String path; … … 44 45 * Main constructor. 45 46 * 46 * @param path 47 * Path to write the pictures. 48 * @param queue 49 * Queue of {@link StreetsideAbstractImage} objects. 50 * @param queueImages 51 * Queue of {@link BufferedImage} objects. 52 * @param amount 53 * Amount of images that are going to be exported. 54 * @param monitor 55 * Progress monitor. 47 * @param path Path to write the pictures. 48 * @param queue Queue of {@link StreetsideAbstractImage} objects. 49 * @param queueImages Queue of {@link BufferedImage} objects. 50 * @param amount Amount of images that are going to be exported. 51 * @param monitor Progress monitor. 56 52 */ 57 public StreetsideExportWriterThread(String path, 58 ArrayBlockingQueue<BufferedImage> queue, 59 ArrayBlockingQueue<StreetsideAbstractImage> queueImages, int amount, 60 ProgressMonitor monitor) { 53 public StreetsideExportWriterThread(String path, ArrayBlockingQueue<BufferedImage> queue, 54 ArrayBlockingQueue<StreetsideAbstractImage> queueImages, int amount, ProgressMonitor monitor) { 61 55 this.path = path; 62 56 this.queue = queue; … … 76 70 img = queue.take(); 77 71 mimg = queueImages.take(); 78 79 72 80 73 // Transforms the image into a byte array. … … 100 93 101 94 gpsDirectory.removeField(GpsTagConstants.GPS_TAG_GPS_IMG_DIRECTION); 102 gpsDirectory.add(GpsTagConstants.GPS_TAG_GPS_IMG_DIRECTION, 103 RationalNumber.valueOf(mimg.getMovingHe())); 95 gpsDirectory.add(GpsTagConstants.GPS_TAG_GPS_IMG_DIRECTION, RationalNumber.valueOf(mimg.getMovingHe())); 104 96 105 97 exifDirectory.removeField(ExifTagConstants.EXIF_TAG_DATE_TIME_ORIGINAL); … … 111 103 os.close(); 112 104 } catch (InterruptedException e) { 113 logger.info("Streetside export cancelled");105 LOGGER.info("Streetside export cancelled"); 114 106 return; 115 107 } catch (IOException | ImageReadException | ImageWriteException e) { 116 logger.error(e);108 LOGGER.log(Logging.LEVEL_ERROR, e.getMessage(), e); 117 109 } 118 110 -
applications/editors/josm/plugins/MicrosoftStreetside/src/org/openstreetmap/josm/plugins/streetside/mode/AbstractMode.java
r34400 r36194 22 22 * @see StreetsideLayer 23 23 */ 24 public abstract class AbstractMode extends MouseAdapter implements 25 ZoomChangeListener { 24 public abstract class AbstractMode extends MouseAdapter implements ZoomChangeListener { 26 25 27 26 private static final int DOWNLOAD_COOLDOWN = 2000; … … 33 32 public int cursor = Cursor.DEFAULT_CURSOR; 34 33 34 /** 35 * Resets the semiautomatic mode thread. 36 */ 37 public static void resetThread() { 38 semiautomaticThread.interrupt(); 39 semiautomaticThread = new SemiautomaticThread(); 40 } 41 35 42 protected StreetsideAbstractImage getClosest(Point clickPoint) { 36 43 double snapDistance = 10; … … 41 48 imagePoint.setLocation(imagePoint.getX(), imagePoint.getY()); 42 49 double dist = clickPoint.distanceSq(imagePoint); 43 if (minDistance > dist && clickPoint.distance(imagePoint) < snapDistance 44 && image.isVisible()) { 50 if (minDistance > dist && clickPoint.distance(imagePoint) < snapDistance && image.isVisible()) { 45 51 minDistance = dist; 46 52 closest = image; … … 53 59 * Paint the dataset using the engine set. 54 60 * 55 * @param g {@link Graphics2D} used for painting56 * @param mv The object that can translate GeoPoints to screen coordinates.61 * @param g {@link Graphics2D} used for painting 62 * @param mv The object that can translate GeoPoints to screen coordinates. 57 63 * @param box Area where painting is going to be performed 58 64 */ … … 68 74 } 69 75 70 /**71 * Resets the semiautomatic mode thread.72 */73 public static void resetThread() {74 semiautomaticThread.interrupt();75 semiautomaticThread = new SemiautomaticThread();76 }77 78 76 private static class SemiautomaticThread extends Thread { 79 77 80 /** If in semiautomatic mode, the last Epoch time when there was a download */ 78 /** 79 * If in semiautomatic mode, the last Epoch time when there was a download 80 */ 81 81 private long lastDownload; 82 82 -
applications/editors/josm/plugins/MicrosoftStreetside/src/org/openstreetmap/josm/plugins/streetside/mode/SelectMode.java
r34627 r36194 35 35 */ 36 36 public class SelectMode extends AbstractMode { 37 private final StreetsideRecord record; 37 38 private StreetsideAbstractImage closest; 38 39 private StreetsideAbstractImage lastClicked; 39 private final StreetsideRecord record;40 40 private boolean nothingHighlighted; 41 41 private boolean imageHighlighted; … … 54 54 } 55 55 StreetsideAbstractImage closest = getClosest(e.getPoint()); 56 if (!(MainApplication.getLayerManager().getActiveLayer() instanceof StreetsideLayer) 57 && closest != null&& MainApplication.getMap().mapMode == MainApplication.getMap().mapModeSelect) {56 if (!(MainApplication.getLayerManager().getActiveLayer() instanceof StreetsideLayer) && closest != null 57 && MainApplication.getMap().mapMode == MainApplication.getMap().mapModeSelect) { 58 58 lastClicked = this.closest; 59 59 StreetsideLayer.getInstance().getData().setSelectedImage(closest); … … 63 63 } 64 64 // Double click 65 if (e.getClickCount() == 2 && StreetsideLayer.getInstance().getData().getSelectedImage() != null && closest != null) { 65 if (e.getClickCount() == 2 && StreetsideLayer.getInstance().getData().getSelectedImage() != null 66 && closest != null) { 66 67 closest.getSequence().getImages().forEach(StreetsideLayer.getInstance().getData()::addMultiSelectedImage); 67 68 } … … 75 76 StreetsideLayer.getInstance().getData().addMultiSelectedImage(closest); 76 77 // shift + click 77 } else if ( 78 e.getModifiers() == (InputEvent.BUTTON1_MASK | InputEvent.SHIFT_MASK) 79 && lastClicked instanceof StreetsideImage 80 ) { 81 if (this.closest != null 82 && this.closest.getSequence() == lastClicked.getSequence()) { 78 } else if (e.getModifiers() == (InputEvent.BUTTON1_MASK | InputEvent.SHIFT_MASK) 79 && lastClicked instanceof StreetsideImage) { 80 if (this.closest != null && this.closest.getSequence() == lastClicked.getSequence()) { 83 81 int i = this.closest.getSequence().getImages().indexOf(this.closest); 84 82 int j = lastClicked.getSequence().getImages().indexOf(lastClicked); 85 StreetsideLayer.getInstance().getData().addMultiSelectedImage( 86 i < j 87 ? new ConcurrentSkipListSet<>(this.closest.getSequence().getImages().subList(i, j + 1)) 88 : new ConcurrentSkipListSet<>(this.closest.getSequence().getImages().subList(j, i + 1)) 89 ); 83 StreetsideLayer.getInstance().getData().addMultiSelectedImage(i < j 84 ? new ConcurrentSkipListSet<>(this.closest.getSequence().getImages().subList(i, j + 1)) 85 : new ConcurrentSkipListSet<>(this.closest.getSequence().getImages().subList(j, i + 1))); 90 86 } 91 87 // click … … 98 94 public void mouseDragged(MouseEvent e) { 99 95 StreetsideAbstractImage highlightImg = StreetsideLayer.getInstance().getData().getHighlightedImage(); 100 if ( 101 MainApplication.getLayerManager().getActiveLayer() == StreetsideLayer.getInstance() 102 && SwingUtilities.isLeftMouseButton(e) 103 && highlightImg != null && highlightImg.getLatLon() != null 104 ) { 96 if (MainApplication.getLayerManager().getActiveLayer() == StreetsideLayer.getInstance() 97 && SwingUtilities.isLeftMouseButton(e) && highlightImg != null && highlightImg.getLatLon() != null) { 105 98 Point highlightImgPoint = MainApplication.getMap().mapView.getPoint(highlightImg.getTempLatLon()); 106 99 if (e.isShiftDown()) { // turn 107 StreetsideLayer.getInstance().getData().getMultiSelectedImages().parallelStream().filter(img -> !(img instanceof StreetsideImage) || StreetsideProperties.DEVELOPER.get()) 108 .forEach(img -> img.turn(Math.toDegrees(Math.atan2(e.getX() - highlightImgPoint.getX(), -e.getY() + highlightImgPoint.getY())) - highlightImg.getTempHe())); 100 StreetsideLayer.getInstance().getData().getMultiSelectedImages().parallelStream() 101 .filter(img -> !(img instanceof StreetsideImage) || StreetsideProperties.DEVELOPER.get()) 102 .forEach(img -> img.turn(Math.toDegrees( 103 Math.atan2(e.getX() - highlightImgPoint.getX(), -e.getY() + highlightImgPoint.getY())) 104 - highlightImg.getTempHe())); 109 105 } else { // move 110 106 LatLon eventLatLon = MainApplication.getMap().mapView.getLatLon(e.getX(), e.getY()); 111 LatLon imgLatLon = MainApplication.getMap().mapView.getLatLon(highlightImgPoint.getX(), highlightImgPoint.getY()); 112 StreetsideLayer.getInstance().getData().getMultiSelectedImages().parallelStream().filter(img -> !(img instanceof StreetsideImage) || StreetsideProperties.DEVELOPER.get()) 113 .forEach(img -> img.move(eventLatLon.getX() - imgLatLon.getX(), eventLatLon.getY() - imgLatLon.getY())); 107 LatLon imgLatLon = MainApplication.getMap().mapView.getLatLon(highlightImgPoint.getX(), 108 highlightImgPoint.getY()); 109 StreetsideLayer.getInstance().getData().getMultiSelectedImages().parallelStream() 110 .filter(img -> !(img instanceof StreetsideImage) || StreetsideProperties.DEVELOPER.get()) 111 .forEach(img -> img.move(eventLatLon.getX() - imgLatLon.getX(), 112 eventLatLon.getY() - imgLatLon.getY())); 114 113 } 115 114 StreetsideLayer.invalidateInstance(); … … 127 126 double to = data.getSelectedImage().getMovingHe(); 128 127 record.addCommand(new CommandTurn(data.getMultiSelectedImages(), to - from)); 129 } else if (!Objects.equals(data.getSelectedImage().getTempLatLon(), data.getSelectedImage().getMovingLatLon())) { 128 } else if (!Objects.equals(data.getSelectedImage().getTempLatLon(), 129 data.getSelectedImage().getMovingLatLon())) { 130 130 LatLon from = data.getSelectedImage().getTempLatLon(); 131 131 LatLon to = data.getSelectedImage().getMovingLatLon(); 132 record.addCommand(new CommandMove(data.getMultiSelectedImages(), to.getX() - from.getX(), to.getY() - from.getY())); 132 record.addCommand( 133 new CommandMove(data.getMultiSelectedImages(), to.getX() - from.getX(), to.getY() - from.getY())); 133 134 } 134 data.getMultiSelectedImages().parallelStream().filter(Objects::nonNull).forEach(StreetsideAbstractImage::stopMoving); 135 data.getMultiSelectedImages().parallelStream().filter(Objects::nonNull) 136 .forEach(StreetsideAbstractImage::stopMoving); 135 137 StreetsideLayer.invalidateInstance(); 136 138 } … … 142 144 public void mouseMoved(MouseEvent e) { 143 145 if (MainApplication.getLayerManager().getActiveLayer() instanceof OsmDataLayer 144 146 && MainApplication.getMap().mapMode != MainApplication.getMap().mapModeSelect) { 145 147 return; 146 148 } 147 if ( !StreetsideProperties.HOVER_ENABLED.get()) {149 if (Boolean.FALSE.equals(StreetsideProperties.HOVER_ENABLED.get())) { 148 150 return; 149 151 } … … 177 179 StreetsideMainDialog.getInstance().updateImage(false); 178 180 179 } else if (StreetsideLayer.getInstance().getData().getHighlightedImage() != closestTemp && closestTemp == null) { 181 } else if (StreetsideLayer.getInstance().getData().getHighlightedImage() != closestTemp 182 && closestTemp == null) { 180 183 StreetsideLayer.getInstance().getData().setHighlightedImage(null); 181 184 StreetsideMainDialog.getInstance().setImage(StreetsideLayer.getInstance().getData().getSelectedImage()); -
applications/editors/josm/plugins/MicrosoftStreetside/src/org/openstreetmap/josm/plugins/streetside/model/ImageDetection.java
r34317 r36194 11 11 private final String value; 12 12 13 public ImageDetection(final Path2D shape, final String imageKey, final String key, final double score, final String packag, final String value) { 13 public ImageDetection(final Path2D shape, final String imageKey, final String key, final double score, 14 final String packag, final String value) { 14 15 super(shape, imageKey, key); 15 16 this.packag = packag; -
applications/editors/josm/plugins/MicrosoftStreetside/src/org/openstreetmap/josm/plugins/streetside/model/KeyIndexedObject.java
r34317 r36194 46 46 } 47 47 KeyIndexedObject other = (KeyIndexedObject) obj; 48 if (!key.equals(other.key)) { 49 return false; 50 } 51 return true; 48 return key.equals(other.key); 52 49 } 53 50 -
applications/editors/josm/plugins/MicrosoftStreetside/src/org/openstreetmap/josm/plugins/streetside/model/MapObject.java
r34416 r36194 18 18 private final long updatedTime; 19 19 20 public MapObject( 21 final LatLon coordinate, final String key, final String objPackage, final String value, 22 long firstSeenTime, long lastSeenTime, long updatedTime 23 ) { 20 public MapObject(final LatLon coordinate, final String key, final String objPackage, final String value, 21 long firstSeenTime, long lastSeenTime, long updatedTime) { 24 22 super(key); 25 23 if (objPackage == null || value == null || coordinate == null) { … … 34 32 } 35 33 36 public LatLon getCoordinate() {37 return coordinate;38 }39 40 34 /** 41 35 * @param objectTypeID the {@link String} representing the type of map object. This ID can be retrieved via 42 * {@link #getValue()} for any given {@link MapObject}.36 * {@link #getValue()} for any given {@link MapObject}. 43 37 * @return the icon, which represents the given objectTypeID 44 38 */ … … 51 45 } 52 46 return cachedIcon; 47 } 48 49 public LatLon getCoordinate() { 50 return coordinate; 53 51 } 54 52 -
applications/editors/josm/plugins/MicrosoftStreetside/src/org/openstreetmap/josm/plugins/streetside/oauth/OAuthPortListener.java
r34577 r36194 1 1 // License: GPL. For details, see LICENSE file. 2 2 package org.openstreetmap.josm.plugins.streetside.oauth; 3 4 3 5 4 import java.io.IOException; … … 10 9 import java.net.ServerSocket; 11 10 import java.net.Socket; 11 import java.nio.charset.StandardCharsets; 12 12 import java.util.Scanner; 13 import java.util.logging.Logger; 13 14 import java.util.regex.Matcher; 14 15 import java.util.regex.Pattern; 15 16 16 import org.apache.log4j.Logger;17 17 import org.openstreetmap.josm.plugins.streetside.utils.StreetsideProperties; 18 18 import org.openstreetmap.josm.tools.I18n; 19 import org.openstreetmap.josm.tools.Logging; 19 20 20 21 /** … … 26 27 */ 27 28 public class OAuthPortListener extends Thread { 28 public static final int PORT = 8763; 29 public static final int PORT = 8763; 30 protected static final String RESPONSE = String.format( 31 "<!DOCTYPE html><html><head><meta charset=\"utf8\"><title>%s</title></head><body>%s</body></html>", 32 I18n.tr("Streetside login"), I18n.tr("Login successful, return to JOSM.")); 33 private static final Logger LOGGER = Logger.getLogger(OAuthPortListener.class.getCanonicalName()); 34 private final StreetsideLoginListener callback; 29 35 30 final static Logger logger = Logger.getLogger(OAuthPortListener.class); 36 public OAuthPortListener(StreetsideLoginListener loginCallback) { 37 callback = loginCallback; 38 } 31 39 32 protected static final String RESPONSE = String.format( 33 "<!DOCTYPE html><html><head><meta charset=\"utf8\"><title>%s</title></head><body>%s</body></html>",34 I18n.tr("Streetside login"),35 I18n.tr("Login successful, return to JOSM.")36 );37 private final StreetsideLoginListener callback; 40 private static void writeContent(PrintWriter out) { 41 out.println("HTTP/1.1 200 OK"); 42 out.println("Content-Length: " + RESPONSE.length()); 43 out.println("Content-Type: text/html" + "\r\n\r\n"); 44 out.println(RESPONSE); 45 } 38 46 39 public OAuthPortListener(StreetsideLoginListener loginCallback) { 40 callback = loginCallback; 47 @Override 48 public void run() { 49 try (ServerSocket serverSocket = new ServerSocket(PORT); 50 Socket clientSocket = serverSocket.accept(); 51 PrintWriter out = new PrintWriter( 52 new OutputStreamWriter(clientSocket.getOutputStream(), StandardCharsets.UTF_8), true); 53 Scanner in = new Scanner( 54 new InputStreamReader(clientSocket.getInputStream(), StandardCharsets.UTF_8))) { 55 String s; 56 String accessToken = null; 57 while (in.hasNextLine()) { 58 s = in.nextLine(); 59 Matcher tokenMatcher = Pattern.compile("^.*&access_token=([^&]+)&.*$").matcher('&' + s + '&'); 60 if (tokenMatcher.matches()) { 61 accessToken = tokenMatcher.group(1); 62 break; 63 } else if (s.contains("keep-alive")) { 64 break; 65 } 66 } 67 68 writeContent(out); 69 out.flush(); 70 71 StreetsideUser.reset(); 72 73 LOGGER.info(I18n.tr("Successful login with Streetside, the access token is: {0}", accessToken)); 74 // Saves the access token in preferences. 75 StreetsideUser.setTokenValid(true); 76 StreetsideProperties.ACCESS_TOKEN.put(accessToken); 77 String username = StreetsideUser.getUsername(); 78 LOGGER.info(I18n.tr("The username is: {0}", username)); 79 if (callback != null) { 80 callback.onLogin(username); 81 } 82 } catch (BindException e) { 83 LOGGER.log(Logging.LEVEL_WARN, e.getMessage(), e); 84 } catch (IOException e) { 85 LOGGER.log(Logging.LEVEL_ERROR, e.getMessage(), e); 86 } 87 } 41 88 } 42 43 @Override44 public void run() {45 try (46 ServerSocket serverSocket = new ServerSocket(PORT);47 Socket clientSocket = serverSocket.accept();48 PrintWriter out = new PrintWriter(new OutputStreamWriter(clientSocket.getOutputStream(), "UTF-8"), true);49 Scanner in = new Scanner(new InputStreamReader(clientSocket.getInputStream(), "UTF-8"))50 ) {51 String s;52 String accessToken = null;53 while (in.hasNextLine()) {54 s = in.nextLine();55 Matcher tokenMatcher = Pattern.compile("^.*&access_token=([^&]+)&.*$").matcher('&'+s+'&');56 if (tokenMatcher.matches()) {57 accessToken = tokenMatcher.group(1);58 break;59 } else if (s.contains("keep-alive")) {60 break;61 }62 }63 64 writeContent(out);65 out.flush();66 67 StreetsideUser.reset();68 69 logger.info(I18n.tr("Successful login with Streetside, the access token is: {0}", accessToken));70 // Saves the access token in preferences.71 StreetsideUser.setTokenValid(true);72 StreetsideProperties.ACCESS_TOKEN.put(accessToken);73 String username = StreetsideUser.getUsername();74 logger.info(I18n.tr("The username is: {0}", username));75 if (callback != null) {76 callback.onLogin(username);77 }78 } catch (BindException e) {79 logger.warn(e);80 } catch (IOException e) {81 logger.error(e);82 }83 }84 85 private static void writeContent(PrintWriter out) {86 out.println("HTTP/1.1 200 OK");87 out.println("Content-Length: " + RESPONSE.length());88 out.println("Content-Type: text/html" + "\r\n\r\n");89 out.println(RESPONSE);90 }91 } -
applications/editors/josm/plugins/MicrosoftStreetside/src/org/openstreetmap/josm/plugins/streetside/oauth/OAuthUtils.java
r36122 r36194 7 7 import java.net.HttpURLConnection; 8 8 import java.net.URL; 9 import java.nio.charset.StandardCharsets; 10 11 import org.openstreetmap.josm.plugins.streetside.utils.StreetsideProperties; 9 12 10 13 import jakarta.json.Json; … … 12 15 import jakarta.json.JsonObject; 13 16 import jakarta.json.JsonReader; 14 15 import org.openstreetmap.josm.plugins.streetside.utils.StreetsideProperties;16 17 17 18 /** … … 23 24 public final class OAuthUtils { 24 25 25 private OAuthUtils() { 26 // Private constructor to avoid instantiation 26 private OAuthUtils() { 27 // Private constructor to avoid instantiation 28 } 29 30 /** 31 * Returns a JsonObject containing the result of making a GET request with the 32 * authorization header. 33 * 34 * @param url The {@link URL} where the request must be made. 35 * @return A JsonObject containing the result of the GET request. 36 * @throws IOException Errors relating to the connection. 37 */ 38 public static JsonObject getWithHeader(URL url) throws IOException { 39 HttpURLConnection con = (HttpURLConnection) url.openConnection(); 40 con.setRequestMethod("GET"); 41 con.setRequestProperty("Authorization", "Bearer " + StreetsideProperties.ACCESS_TOKEN.get()); 42 43 try (JsonReader reader = Json.createReader( 44 new BufferedReader(new InputStreamReader(con.getInputStream(), StandardCharsets.UTF_8)))) { 45 return reader.readObject(); 46 } catch (JsonException e) { 47 throw new IOException(e); 48 } 49 } 27 50 } 28 29 /**30 * Returns a JsonObject containing the result of making a GET request with the31 * authorization header.32 *33 * @param url34 * The {@link URL} where the request must be made.35 * @return A JsonObject containing the result of the GET request.36 * @throws IOException37 * Errors relating to the connection.38 */39 public static JsonObject getWithHeader(URL url) throws IOException {40 HttpURLConnection con = (HttpURLConnection) url.openConnection();41 con.setRequestMethod("GET");42 con.setRequestProperty("Authorization", "Bearer " + StreetsideProperties.ACCESS_TOKEN.get());43 44 try (45 JsonReader reader = Json.createReader(new BufferedReader(new InputStreamReader(con.getInputStream(), "UTF-8")))46 ) {47 return reader.readObject();48 } catch (JsonException e) {49 throw new IOException(e);50 }51 }52 } -
applications/editors/josm/plugins/MicrosoftStreetside/src/org/openstreetmap/josm/plugins/streetside/oauth/StreetsideLoginListener.java
r34317 r36194 11 11 * Should be called whenever the user logs into a mapillary account. 12 12 * E.g. for updating the GUI to reflect the login status. 13 * 13 14 * @param username the username that the user is now logged in with 14 15 */ 15 16 void onLogin(final String username); 17 16 18 /** 17 19 * Should be called whenever the user logs out of a mapillary account. -
applications/editors/josm/plugins/MicrosoftStreetside/src/org/openstreetmap/josm/plugins/streetside/oauth/StreetsideUser.java
r34400 r36194 1 1 // License: GPL. For details, see LICENSE file. 2 2 package org.openstreetmap.josm.plugins.streetside.oauth; 3 4 3 5 4 import java.util.Map; … … 15 14 public final class StreetsideUser { 16 15 17 private static String username; 18 private static String imagesPolicy; 19 private static String imagesHash; 20 /** If the stored token is valid or not. */ 21 private static boolean isTokenValid = true; 16 private static String username; 17 private static String imagesPolicy; 18 private static String imagesHash; 19 /** 20 * If the stored token is valid or not. 21 */ 22 private static boolean isTokenValid = true; 22 23 23 private StreetsideUser() { 24 // Private constructor to avoid instantiation 24 private StreetsideUser() { 25 // Private constructor to avoid instantiation 26 } 27 28 /** 29 * @return The username of the logged in user. 30 */ 31 public static synchronized String getUsername() { 32 // users are not currently supported in Streetside 33 return null; 34 } 35 36 /** 37 * @return A HashMap object containing the images_policy and images_hash 38 * strings. 39 */ 40 public static synchronized Map<String, String> getSecrets() { 41 // secrets are not currently supported in Streetside 42 return null; 43 } 44 45 /** 46 * Resets the MapillaryUser to null values. 47 */ 48 public static synchronized void reset() { 49 username = null; 50 imagesPolicy = null; 51 imagesHash = null; 52 isTokenValid = false; 53 StreetsideProperties.ACCESS_TOKEN.put(StreetsideProperties.ACCESS_TOKEN.getDefaultValue()); 54 } 55 56 public static synchronized void setTokenValid(boolean value) { 57 isTokenValid = value; 58 } 25 59 } 26 27 /**28 * @return The username of the logged in user.29 */30 public static synchronized String getUsername() {31 // users are not currently supported in Streetside32 return null;33 }34 35 /**36 * @return A HashMap object containing the images_policy and images_hash37 * strings.38 */39 public static synchronized Map<String, String> getSecrets() {40 // secrets are not currently supported in Streetside41 return null;42 }43 44 /**45 * Resets the MapillaryUser to null values.46 */47 public static synchronized void reset() {48 username = null;49 imagesPolicy = null;50 imagesHash = null;51 isTokenValid = false;52 StreetsideProperties.ACCESS_TOKEN.put(StreetsideProperties.ACCESS_TOKEN.getDefaultValue());53 }54 55 public static synchronized void setTokenValid(boolean value) {56 isTokenValid = value;57 }58 } -
applications/editors/josm/plugins/MicrosoftStreetside/src/org/openstreetmap/josm/plugins/streetside/utils/GraphicsUtils.java
r34577 r36194 6 6 import java.awt.image.BufferedImage; 7 7 import java.text.MessageFormat; 8 import java.util.logging.Logger; 8 9 9 import org. apache.log4j.Logger;10 import org.openstreetmap.josm.tools.Logging; 10 11 11 12 import javafx.application.Platform; 12 13 import javafx.scene.image.PixelWriter; 13 //import javafx.embed.swing.SwingFXUtils;14 //import javafx.scene.image.Image;15 14 import javafx.scene.image.WritableImage; 16 15 17 @SuppressWarnings({ "restriction"})18 16 public class GraphicsUtils { 19 17 20 final static Logger logger = Logger.getLogger(GraphicsUtils.class);18 private static final Logger LOGGER = Logger.getLogger(GraphicsUtils.class.getCanonicalName()); 21 19 22 20 private GraphicsUtils() { … … 24 22 } 25 23 26 27 28 29 30 31 32 33 34 35 36 37 38 24 public static javafx.scene.image.Image convertBufferedImage2JavaFXImage(BufferedImage bf) { 25 WritableImage res = null; 26 if (bf != null) { 27 res = new WritableImage(bf.getWidth(), bf.getHeight()); 28 PixelWriter pw = res.getPixelWriter(); 29 for (int x = 0; x < bf.getWidth(); x++) { 30 for (int y = 0; y < bf.getHeight(); y++) { 31 pw.setArgb(x, y, bf.getRGB(x, y)); 32 } 33 } 34 } 35 return res; 36 } 39 37 40 public static class PlatformHelper{38 public static BufferedImage buildMultiTiledCubemapFaceImage(final BufferedImage[] tiles) { 41 39 42 private PlatformHelper() { 43 // Private constructor to avoid instantiation 44 } 40 long start = System.currentTimeMillis(); 45 41 46 public static void run(Runnable treatment) { 47 if(treatment == null) throw new IllegalArgumentException("The treatment to perform can not be null"); 42 BufferedImage res = null; 48 43 49 if(Platform.isFxApplicationThread()) treatment.run(); 50 else Platform.runLater(treatment); 51 } 52 } 44 int pixelBuffer = Boolean.TRUE.equals(StreetsideProperties.SHOW_HIGH_RES_STREETSIDE_IMAGERY.get()) ? 2 : 1; 53 45 54 public static BufferedImage buildMultiTiledCubemapFaceImage(final BufferedImage[] tiles) { 46 BufferedImage[] croppedTiles = cropMultiTiledImages(tiles, pixelBuffer); 55 47 56 long start = System.currentTimeMillis(); 48 // we assume the no. of rows and cols are known and each chunk has equal width and height 49 int rows = Boolean.TRUE.equals(StreetsideProperties.SHOW_HIGH_RES_STREETSIDE_IMAGERY.get()) ? 4 : 2; 50 int cols = Boolean.TRUE.equals(StreetsideProperties.SHOW_HIGH_RES_STREETSIDE_IMAGERY.get()) ? 4 : 2; 57 51 58 BufferedImage res = null; 52 int chunkWidth; 53 int chunkHeight; 59 54 60 int pixelBuffer = StreetsideProperties.SHOW_HIGH_RES_STREETSIDE_IMAGERY.get()?2:1; 55 chunkWidth = croppedTiles[0].getWidth(); 56 chunkHeight = croppedTiles[0].getHeight(); 61 57 62 BufferedImage[] croppedTiles = cropMultiTiledImages(tiles, pixelBuffer); 58 //Initializing the final image 59 BufferedImage img = new BufferedImage(chunkWidth * cols, chunkHeight * rows, BufferedImage.TYPE_INT_ARGB); 63 60 64 int rows = StreetsideProperties.SHOW_HIGH_RES_STREETSIDE_IMAGERY.get()?4:2; //we assume the no. of rows and cols are known and each chunk has equal width and height 65 int cols = StreetsideProperties.SHOW_HIGH_RES_STREETSIDE_IMAGERY.get()?4:2; 66 67 int chunkWidth, chunkHeight; 68 69 chunkWidth = croppedTiles[0].getWidth(); 70 chunkHeight = croppedTiles[0].getHeight(); 71 72 //Initializing the final image 73 BufferedImage img = new BufferedImage(chunkWidth*cols, chunkHeight*rows, BufferedImage.TYPE_INT_ARGB); 74 75 int num = 0; 76 for (int i = 0; i < rows; i++) { 77 for (int j = 0; j < cols; j++) { 61 int num = 0; 62 for (int i = 0; i < rows; i++) { 63 for (int j = 0; j < cols; j++) { 78 64 // TODO: unintended mirror image created with draw call - requires 79 65 // extra reversal step - fix! 80 66 img.createGraphics().drawImage(croppedTiles[num], chunkWidth * j, (chunkHeight * i), null); 81 67 82 int width = StreetsideProperties.SHOW_HIGH_RES_STREETSIDE_IMAGERY.get() ? 1014 : 510; 68 int width = Boolean.TRUE.equals(StreetsideProperties.SHOW_HIGH_RES_STREETSIDE_IMAGERY.get()) ? 1014 69 : 510; 83 70 int height = width; 84 71 85 72 // BufferedImage for mirror image 86 res = new BufferedImage( 87 width, 88 height, BufferedImage.TYPE_INT_ARGB); 73 res = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB); 89 74 90 75 // Create mirror image pixel by pixel … … 106 91 } 107 92 108 if ( StreetsideProperties.DEBUGING_ENABLED.get()) {109 logger110 .debug(MessageFormat.format("Image concatenated in {0} millisecs.", (System.currentTimeMillis() - start)));93 if (Boolean.TRUE.equals(StreetsideProperties.DEBUGING_ENABLED.get())) { 94 LOGGER.log(Logging.LEVEL_DEBUG, 95 MessageFormat.format("Image concatenated in {0} millisecs.", (System.currentTimeMillis() - start))); 111 96 } 112 97 return res; 113 98 } 114 99 115 public static BufferedImage rotateImage(BufferedImage bufImg) { 116 AffineTransform tx = AffineTransform.getScaleInstance(-1, -1); 117 tx.translate(-bufImg.getWidth(null), -bufImg.getHeight(null)); 118 AffineTransformOp op = new AffineTransformOp(tx, 119 AffineTransformOp.TYPE_NEAREST_NEIGHBOR); 120 bufImg = op.filter(bufImg, null); 121 return bufImg; 122 } 100 public static BufferedImage rotateImage(BufferedImage bufImg) { 101 AffineTransform tx = AffineTransform.getScaleInstance(-1, -1); 102 tx.translate(-bufImg.getWidth(null), -bufImg.getHeight(null)); 103 AffineTransformOp op = new AffineTransformOp(tx, AffineTransformOp.TYPE_NEAREST_NEIGHBOR); 104 bufImg = op.filter(bufImg, null); 105 return bufImg; 106 } 123 107 124 108 private static BufferedImage[] cropMultiTiledImages(BufferedImage[] tiles, int pixelBuffer) { 125 109 126 110 long start = System.currentTimeMillis(); 127 111 128 112 BufferedImage[] res = new BufferedImage[tiles.length]; 129 113 130 for(int i=0; i<tiles.length;i++) {131 if(StreetsideProperties.SHOW_HIGH_RES_STREETSIDE_IMAGERY.get()) {132 res[i] = tiles[i].getSubimage(pixelBuffer, pixelBuffer, 256-pixelBuffer, 256-pixelBuffer);133 134 res[i] = tiles[i].getSubimage(pixelBuffer, pixelBuffer, 256-pixelBuffer, 256-pixelBuffer);135 136 114 for (int i = 0; i < tiles.length; i++) { 115 if (Boolean.TRUE.equals(StreetsideProperties.SHOW_HIGH_RES_STREETSIDE_IMAGERY.get())) { 116 res[i] = tiles[i].getSubimage(pixelBuffer, pixelBuffer, 256 - pixelBuffer, 256 - pixelBuffer); 117 } else { 118 res[i] = tiles[i].getSubimage(pixelBuffer, pixelBuffer, 256 - pixelBuffer, 256 - pixelBuffer); 119 } 120 } 137 121 138 if(StreetsideProperties.DEBUGING_ENABLED.get()) { 139 logger.debug(MessageFormat.format("Images cropped in {0} millisecs.", (System.currentTimeMillis()-start))); 140 } 122 if (Boolean.TRUE.equals(StreetsideProperties.DEBUGING_ENABLED.get())) { 123 LOGGER.log(Logging.LEVEL_DEBUG, 124 MessageFormat.format("Images cropped in {0} millisecs.", (System.currentTimeMillis() - start))); 125 } 141 126 142 return res; 143 } 127 return res; 128 } 129 130 public static class PlatformHelper { 131 132 private PlatformHelper() { 133 // Private constructor to avoid instantiation 134 } 135 136 public static void run(Runnable treatment) { 137 if (treatment == null) 138 throw new IllegalArgumentException("The treatment to perform can not be null"); 139 140 if (Platform.isFxApplicationThread()) 141 treatment.run(); 142 else 143 Platform.runLater(treatment); 144 } 145 } 144 146 } -
applications/editors/josm/plugins/MicrosoftStreetside/src/org/openstreetmap/josm/plugins/streetside/utils/ImageUtil.java
r34365 r36194 3 3 4 4 import java.awt.Image; 5 import java.util.logging.Logger; 5 6 6 7 import javax.swing.ImageIcon; 7 8 8 import org.apache.log4j.Logger;9 9 import org.openstreetmap.josm.tools.I18n; 10 import org.openstreetmap.josm.tools.Logging; 10 11 11 12 public final class ImageUtil { 12 13 13 final static Logger logger = Logger.getLogger(ImageUtil.class);14 private static final Logger LOGGER = Logger.getLogger(ImageUtil.class.getCanonicalName()); 14 15 15 16 private ImageUtil() { … … 19 20 /** 20 21 * Scales an {@link ImageIcon} to the desired size 22 * 21 23 * @param icon the icon, which should be resized 22 24 * @param size the desired length of the longest edge of the icon 23 25 * @return the resized {@link ImageIcon}. It is the same object that you put in, 24 * 26 * only the contained {@link Image} is exchanged. 25 27 */ 26 28 public static ImageIcon scaleImageIcon(final ImageIcon icon, int size) { 27 if (StreetsideProperties.DEBUGING_ENABLED.get()) {28 logger.debug(I18n.tr("Scale icon {0} → {1}", icon.getIconWidth(), size));29 if (Boolean.TRUE.equals(StreetsideProperties.DEBUGING_ENABLED.get())) { 30 LOGGER.log(Logging.LEVEL_DEBUG, I18n.tr("Scale icon {0} → {1}", icon.getIconWidth(), size)); 29 31 } 30 return new ImageIcon(icon.getImage().getScaledInstance( 31 icon.getIconWidth() >= icon.getIconHeight() ? size : Math.max(1, Math.round(icon.getIconWidth() / (float) icon.getIconHeight() * size)), 32 icon.getIconHeight() >= icon.getIconWidth() ? size : Math.max(1, Math.round(icon.getIconHeight() / (float) icon.getIconWidth() * size)), 33 Image.SCALE_SMOOTH 34 )); 32 return new ImageIcon( 33 icon.getImage() 34 .getScaledInstance( 35 icon.getIconWidth() >= icon.getIconHeight() ? size 36 : Math.max(1, 37 Math.round(icon.getIconWidth() / (float) icon.getIconHeight() * size)), 38 icon.getIconHeight() >= icon.getIconWidth() ? size 39 : Math.max(1, 40 Math.round(icon.getIconHeight() / (float) icon.getIconWidth() * size)), 41 Image.SCALE_SMOOTH)); 35 42 } 36 43 } -
applications/editors/josm/plugins/MicrosoftStreetside/src/org/openstreetmap/josm/plugins/streetside/utils/MapViewGeometryUtil.java
r34317 r36194 19 19 * can then easily be drawn on a {@link MapView}s {@link Graphics2D}-context. 20 20 */ 21 public final 21 public final class MapViewGeometryUtil { 22 22 private MapViewGeometryUtil() { 23 23 // Private constructor to avoid instantiation … … 26 26 /** 27 27 * Subtracts the download bounds from the rectangular bounds of the map view. 28 * @param mv the MapView that is used for the LatLon-to-Point-conversion and that determines 29 * the Bounds from which the downloaded Bounds are subtracted 28 * 29 * @param mv the MapView that is used for the LatLon-to-Point-conversion and that determines 30 * the Bounds from which the downloaded Bounds are subtracted 30 31 * @param downloadBounds multiple {@link Bounds} objects that represent the downloaded area 31 32 * @return the difference between the {@link MapView}s bounds and the downloaded area … … 41 42 Point p1 = mv.getPoint(bounds.getMin()); 42 43 Point p2 = mv.getPoint(bounds.getMax()); 43 Rectangle r = new Rectangle(Math.min(p1.x, p2.x), Math.min(p1.y, p2.y), 44 Math.abs(p2. x - p1.x), Math.abs(p2.y - p1.y));44 Rectangle r = new Rectangle(Math.min(p1.x, p2.x), Math.min(p1.y, p2.y), Math.abs(p2.x - p1.x), 45 Math.abs(p2.y - p1.y)); 45 46 a.subtract(new Area(r)); 46 47 } … … 51 52 * Converts a {@link StreetsideSequence} into a {@link Path2D} that can be drawn 52 53 * on the specified {@link NavigatableComponent}'s {@link Graphics2D}-context. 53 * @param nc the {@link NavigatableComponent} for which this conversion should be performed, typically a {@link MapView} 54 * 55 * @param nc the {@link NavigatableComponent} for which this conversion should be performed, typically a {@link MapView} 54 56 * @param seq the sequence to convert 55 57 * @return the {@link Path2D} object to which the {@link StreetsideSequence} has been converted -
applications/editors/josm/plugins/MicrosoftStreetside/src/org/openstreetmap/josm/plugins/streetside/utils/PluginState.java
r34577 r36194 4 4 import static org.openstreetmap.josm.tools.I18n.tr; 5 5 6 import java.util.logging.Logger; 7 6 8 import javax.swing.JOptionPane; 7 9 8 import org.apache.log4j.Logger;9 10 import org.openstreetmap.josm.gui.MainApplication; 10 11 import org.openstreetmap.josm.tools.I18n; 12 import org.openstreetmap.josm.tools.Logging; 11 13 12 14 /** … … 16 18 public final class PluginState { 17 19 18 final static Logger logger = Logger.getLogger(PluginState.class);20 private static final Logger LOGGER = Logger.getLogger(PluginState.class.getCanonicalName()); 19 21 20 22 private static boolean submittingChangeset; 21 23 22 24 private static int runningDownloads; 23 /** Images that have to be uploaded. */ 25 /** 26 * Images that have to be uploaded. 27 */ 24 28 private static int imagesToUpload; 25 /** Images that have been uploaded. */ 29 /** 30 * Images that have been uploaded. 31 */ 26 32 private static int imagesUploaded; 27 33 … … 42 48 public static void finishDownload() { 43 49 if (runningDownloads == 0) { 44 logger.warn(I18n.tr("The amount of running downloads is equal to 0"));50 LOGGER.log(Logging.LEVEL_WARN, I18n.tr("The amount of running downloads is equal to 0")); 45 51 return; 46 52 } … … 65 71 return submittingChangeset; 66 72 } 67 /** 73 74 public static void setSubmittingChangeset(boolean isSubmitting) { 75 submittingChangeset = isSubmitting; 76 } 77 78 /** 68 79 * Checks if there is any running upload. 69 80 * … … 77 88 * Sets the amount of images that are going to be uploaded. 78 89 * 79 * @param amount 80 * The amount of images that are going to be uploaded. 90 * @param amount The amount of images that are going to be uploaded. 81 91 */ 82 92 public static void addImagesToUpload(int amount) { … … 102 112 imagesUploaded++; 103 113 if (imagesToUpload == imagesUploaded) { 104 114 finishedUploadDialog(imagesUploaded); 105 115 } 106 116 } 107 117 108 118 private static void finishedUploadDialog(int numImages) { 109 JOptionPane.showMessageDialog( 110 MainApplication.getMainFrame(), 111 tr("You have successfully uploaded {0} images to Bing.com", numImages), 112 tr("Finished upload"), 113 JOptionPane.INFORMATION_MESSAGE 114 ); 119 JOptionPane.showMessageDialog(MainApplication.getMainFrame(), 120 tr("You have successfully uploaded {0} images to Bing.com", numImages), tr("Finished upload"), 121 JOptionPane.INFORMATION_MESSAGE); 115 122 } 116 123 117 124 public static void notLoggedInToMapillaryDialog() { 118 JOptionPane.showMessageDialog( 119 MainApplication.getMainFrame(), 125 JOptionPane.showMessageDialog(MainApplication.getMainFrame(), 120 126 tr("You are not logged in, please log in to Streetside in the preferences"), 121 tr("Not Logged in to Streetside"), 122 JOptionPane.WARNING_MESSAGE 123 ); 127 tr("Not Logged in to Streetside"), JOptionPane.WARNING_MESSAGE); 124 128 } 125 129 … … 132 136 return tr("Uploading: {0}", "(" + imagesUploaded + "/" + imagesToUpload + ")"); 133 137 } 134 135 public static void setSubmittingChangeset(boolean isSubmitting) {136 submittingChangeset = isSubmitting;137 }138 138 } -
applications/editors/josm/plugins/MicrosoftStreetside/src/org/openstreetmap/josm/plugins/streetside/utils/StreetsideColorScheme.java
r34317 r36194 51 51 /** 52 52 * Styles the given components as default panels (currently only the background is set to white) 53 * 53 54 * @param components the components to style as default panels (e.g. checkboxes also, that's why 54 * not only JPanels are accepted)55 * not only JPanels are accepted) 55 56 */ 56 57 public static void styleAsDefaultPanel(JComponent... components) { -
applications/editors/josm/plugins/MicrosoftStreetside/src/org/openstreetmap/josm/plugins/streetside/utils/StreetsideProperties.java
r34433 r36194 14 14 15 15 public final class StreetsideProperties { 16 public static final BooleanProperty DELETE_AFTER_UPLOAD = new BooleanProperty("streetside.delete-after-upload", true); 16 public static final BooleanProperty DELETE_AFTER_UPLOAD = new BooleanProperty("streetside.delete-after-upload", 17 true); 17 18 public static final BooleanProperty DEVELOPER = new BooleanProperty("streetside.developer", false); 18 19 public static final BooleanProperty DISPLAY_HOUR = new BooleanProperty("streetside.display-hour", true); … … 20 21 public static final BooleanProperty MOVE_TO_IMG = new BooleanProperty("streetside.move-to-picture", true); 21 22 public static final BooleanProperty TIME_FORMAT_24 = new BooleanProperty("streetside.format-24", false); 22 public static final BooleanProperty IMAGE_LINK_TO_BLUR_EDITOR = new BooleanProperty("streetside.image-link-to-blur-editor", true); 23 public static final BooleanProperty CUBEMAP_LINK_TO_BLUR_EDITOR = new BooleanProperty("streetside.cubemap-link-to-blur-editor", true); 24 public static final IntegerProperty TILE_DOWNLOAD_THREAD_PAUSE_LEN_SEC = new IntegerProperty("streetside.tile-download-thread-pause-len-sec", 60); 25 public static final BooleanProperty PREDOWNLOAD_CUBEMAPS = new BooleanProperty("streetside.predownload-cubemaps", false); 23 public static final BooleanProperty IMAGE_LINK_TO_BLUR_EDITOR = new BooleanProperty( 24 "streetside.image-link-to-blur-editor", true); 25 public static final BooleanProperty CUBEMAP_LINK_TO_BLUR_EDITOR = new BooleanProperty( 26 "streetside.cubemap-link-to-blur-editor", true); 27 public static final IntegerProperty TILE_DOWNLOAD_THREAD_PAUSE_LEN_SEC = new IntegerProperty( 28 "streetside.tile-download-thread-pause-len-sec", 60); 29 public static final BooleanProperty PREDOWNLOAD_CUBEMAPS = new BooleanProperty("streetside.predownload-cubemaps", 30 false); 26 31 public static final BooleanProperty DEBUGING_ENABLED = new BooleanProperty("streetside.debugging-enabled", false); 27 public static final BooleanProperty DOWNLOAD_CUBEFACE_TILES_TOGETHER = new BooleanProperty("streetside.download-cubeface-tiles-together", false); 32 public static final BooleanProperty DOWNLOAD_CUBEFACE_TILES_TOGETHER = new BooleanProperty( 33 "streetside.download-cubeface-tiles-together", false); 28 34 29 35 /** … … 31 37 * Otherwise only all images (!) inside the download bounds are added, the others are discarded. 32 38 */ 33 public static final BooleanProperty CUT_OFF_SEQUENCES_AT_BOUNDS = 34 new BooleanProperty("streetside.cut-off-sequences-at-bounds", false);39 public static final BooleanProperty CUT_OFF_SEQUENCES_AT_BOUNDS = new BooleanProperty( 40 "streetside.cut-off-sequences-at-bounds", false); 35 41 public static final IntegerProperty MAPOBJECT_ICON_SIZE = new IntegerProperty("streetside.mapobjects.iconsize", 32); 36 public static final IntegerProperty MAX_MAPOBJECTS = new IntegerProperty("streetside.mapobjects.maximum-number", 200); 37 public static final BooleanProperty SHOW_DETECTED_SIGNS = new BooleanProperty("streetside.show-detected-signs", true); 38 public static final BooleanProperty SHOW_HIGH_RES_STREETSIDE_IMAGERY = new BooleanProperty("streetside.show-high-res-streetside-imagery", true); 42 public static final IntegerProperty MAX_MAPOBJECTS = new IntegerProperty("streetside.mapobjects.maximum-number", 43 200); 44 public static final BooleanProperty SHOW_DETECTED_SIGNS = new BooleanProperty("streetside.show-detected-signs", 45 true); 46 public static final BooleanProperty SHOW_HIGH_RES_STREETSIDE_IMAGERY = new BooleanProperty( 47 "streetside.show-high-res-streetside-imagery", true); 39 48 40 49 /** … … 45 54 * See {@code OsmDataLayer#PROPERTY_OUTSIDE_COLOR} 46 55 */ 47 public static final NamedColorProperty OUTSIDE_DOWNLOADED_AREA = new NamedColorProperty("outside downloaded area", Color.YELLOW); 56 public static final NamedColorProperty OUTSIDE_DOWNLOADED_AREA = new NamedColorProperty("outside downloaded area", 57 Color.YELLOW); 48 58 49 59 public static final DoubleProperty MAX_DOWNLOAD_AREA = new DoubleProperty("streetside.max-download-area", 0.015); 50 60 51 61 public static final IntegerProperty PICTURE_DRAG_BUTTON = new IntegerProperty("streetside.picture-drag-button", 3); 52 public static final IntegerProperty PICTURE_OPTION_BUTTON = new IntegerProperty("streetside.picture-option-button", 2); 62 public static final IntegerProperty PICTURE_OPTION_BUTTON = new IntegerProperty("streetside.picture-option-button", 63 2); 53 64 public static final IntegerProperty PICTURE_ZOOM_BUTTON = new IntegerProperty("streetside.picture-zoom-button", 1); 54 public static final IntegerProperty SEQUENCE_MAX_JUMP_DISTANCE = 55 new IntegerProperty("streetside.sequence-max-jump-distance", 100);65 public static final IntegerProperty SEQUENCE_MAX_JUMP_DISTANCE = new IntegerProperty( 66 "streetside.sequence-max-jump-distance", 100); 56 67 57 68 public static final StringProperty ACCESS_TOKEN = new StringProperty("streetside.access-token", null); 58 public static final StringProperty DOWNLOAD_MODE = 59 new StringProperty("streetside.download-mode",StreetsideDownloader.DOWNLOAD_MODE.DEFAULT.getPrefId());60 public static final StringProperty START_DIR = 61 new StringProperty("streetside.start-directory",System.getProperty("user.home"));62 public static final StringProperty URL_CLIENT_ID = 63 new StringProperty("streetside.url-clientid", System.getProperty("T1Fzd20xZjdtR0s1VDk5OFNIOXpYdzoxNDYyOGRkYzUyYTFiMzgz"));64 public static final StringProperty BING_MAPS_KEY = 65 new StringProperty("streetside.bing-maps-key", System.getProperty("AuftgJsO0Xs8Ts4M1xZUQJQXJNsvmh3IV8DkNieCiy3tCwCUMq76-WpkrBtNAuEm"));66 public static final StringProperty TEST_BUBBLE_ID = 67 new StringProperty("streetside.test-bubble-id", System.getProperty("80848005"));69 public static final StringProperty DOWNLOAD_MODE = new StringProperty("streetside.download-mode", 70 StreetsideDownloader.DOWNLOAD_MODE.DEFAULT.getPrefId()); 71 public static final StringProperty START_DIR = new StringProperty("streetside.start-directory", 72 System.getProperty("user.home")); 73 public static final StringProperty URL_CLIENT_ID = new StringProperty("streetside.url-clientid", 74 System.getProperty("streetside.url-clientid", "T1Fzd20xZjdtR0s1VDk5OFNIOXpYdzoxNDYyOGRkYzUyYTFiMzgz")); 75 public static final StringProperty BING_MAPS_KEY = new StringProperty("streetside.bing-maps-key", 76 System.getProperty("streetside.bing-maps-key", "AuftgJsO0Xs8Ts4M1xZUQJQXJNsvmh3IV8DkNieCiy3tCwCUMq76-WpkrBtNAuEm")); 77 public static final StringProperty TEST_BUBBLE_ID = new StringProperty("streetside.test-bubble-id", 78 System.getProperty("streetside.test-bubble-id", "80848005")); 68 79 69 80 /** … … 72 83 * Or opening the {@link ImageInfoPanel} immediately brings this number down to zero. 73 84 */ 74 public static final IntegerProperty IMAGEINFO_HELP_COUNTDOWN = 75 new IntegerProperty("streetside.imageInfo.helpDisplayedCountdown", 4);85 public static final IntegerProperty IMAGEINFO_HELP_COUNTDOWN = new IntegerProperty( 86 "streetside.imageInfo.helpDisplayedCountdown", 4); 76 87 77 88 /** … … 80 91 * Or opening the {@link StreetsideViewerPanel} immediately brings this number down to zero. 81 92 */ 82 public static final IntegerProperty STREETSIDE_VIEWER_HELP_COUNTDOWN = 83 new IntegerProperty("streetside.streetsideViewer.helpDisplayedCountdown", 4);93 public static final IntegerProperty STREETSIDE_VIEWER_HELP_COUNTDOWN = new IntegerProperty( 94 "streetside.streetsideViewer.helpDisplayedCountdown", 4); 84 95 85 96 /** 86 97 * The number of images to be prefetched when a streetside image is selected 87 98 */ 88 public static final IntegerProperty PRE_FETCH_IMAGE_COUNT = new IntegerProperty("streetside.prefetch-image-count", 2); 99 public static final IntegerProperty PRE_FETCH_IMAGE_COUNT = new IntegerProperty("streetside.prefetch-image-count", 100 2); 89 101 90 102 /** 91 103 * The number of images to be prefetched when a streetside image is selected 92 104 */ 93 public static final IntegerProperty PRE_FETCH_CUBEMAP_COUNT = new IntegerProperty("streetside.prefetch-image-count", 2);94 105 public static final IntegerProperty PRE_FETCH_CUBEMAP_COUNT = new IntegerProperty("streetside.prefetch-image-count", 106 2); 95 107 96 108 private StreetsideProperties() { -
applications/editors/josm/plugins/MicrosoftStreetside/src/org/openstreetmap/josm/plugins/streetside/utils/StreetsideSequenceIdGenerator.java
r34577 r36194 9 9 * handle sequences of contiguous imagery, but Streetside only has implicit 10 10 * sequences defined by the "pre" and "ne" attributes. 11 * 12 * See {@link org.openstreetmap.josm.plugins.streetside.StreetsideSequence}11 * 12 * @see org.openstreetmap.josm.plugins.streetside.StreetsideSequence 13 13 */ 14 14 public class StreetsideSequenceIdGenerator { -
applications/editors/josm/plugins/MicrosoftStreetside/src/org/openstreetmap/josm/plugins/streetside/utils/StreetsideURL.java
r34431 r36194 15 15 import java.util.Map; 16 16 import java.util.Map.Entry; 17 18 import org.apache.log4j.Logger; 17 import java.util.logging.Logger; 18 19 19 import org.openstreetmap.josm.data.Bounds; 20 20 import org.openstreetmap.josm.plugins.streetside.cubemap.CubemapUtils; … … 24 24 public final class StreetsideURL { 25 25 26 final static Logger logger = Logger.getLogger(StreetsideURL.class); 27 28 /** Base URL of the Bing Bubble API. */ 29 private static final String STREETSIDE_BASE_URL = "https://dev.virtualearth.net/mapcontrol/HumanScaleServices/GetBubbles.ashx"; 30 /** Base URL for Streetside privacy concerns. */ 26 private static final Logger LOGGER = Logger.getLogger(StreetsideURL.class.getCanonicalName()); 27 28 /** 29 * Base URL of the Bing Bubble API. 30 */ 31 private static final String STREETSIDE_BASE_URL = "https://dev.virtualearth.net/mapcontrol/HumanScaleServices/GetBubbles.ashx"; 32 /** 33 * Base URL for Streetside privacy concerns. 34 */ 31 35 private static final String STREETSIDE_PRIVACY_URL = "https://www.bing.com/maps/privacyreport/streetsideprivacyreport?bubbleid="; 32 36 33 private static final int OSM_BBOX_NORTH = 3; 34 private static final int OSM_BBOX_SOUTH = 1; 35 private static final int OSM_BBOXEAST = 2; 36 private static final int OSM_BBOX_WEST = 0; 37 38 public static final class APIv3 { 39 40 private APIv3() { 41 // Private constructor to avoid instantiation 42 } 43 44 public static URL searchStreetsideImages(Bounds bounds) { 45 return StreetsideURL.string2URL(StreetsideURL.STREETSIDE_BASE_URL, APIv3.queryStreetsideString(bounds)); 46 } 47 48 /** 49 * The APIv3 returns a Link header for each request. It contains a URL for requesting more results. 50 * If you supply the value of the Link header, this method returns the next URL, 51 * if such a URL is defined in the header. 52 * @param value the value of the HTTP-header with key "Link" 53 * @return the {@link URL} for the next result page, or <code>null</code> if no such URL could be found 54 */ 55 public static URL parseNextFromLinkHeaderValue(String value) { 56 if (value != null) { 57 // Iterate over the different entries of the Link header 58 for (final String link : value.split(",", Integer.MAX_VALUE)) { 59 boolean isNext = false; 60 URL url = null; 61 // Iterate over the parts of each entry (typically it's one `rel="‹linkType›"` and one like `<https://URL>`) 62 for (String linkPart : link.split(";", Integer.MAX_VALUE)) { 63 linkPart = linkPart.trim(); 64 isNext |= linkPart.matches("rel\\s*=\\s*\"next\""); 65 if (linkPart.length() >= 1 && linkPart.charAt(0) == '<' && linkPart.endsWith(">")) { 66 try { 67 url = new URL(linkPart.substring(1, linkPart.length() - 1)); 68 } catch (final MalformedURLException e) { 69 Logging.log(Logging.LEVEL_WARN, "Mapillary API v3 returns a malformed URL in the Link header.", e); 70 } 71 } 72 } 73 // If both a URL and the rel=next attribute are present, return the URL. Otherwise null is returned 74 if (url != null && isNext) { 75 return url; 76 } 77 } 78 } 79 return null; 80 } 81 82 public static String queryString(final Bounds bounds) { 83 if (bounds != null) { 84 final Map<String, String> parts = new HashMap<>(); 85 parts.put("bbox", bounds.toBBox().toStringCSV(",")); 86 return StreetsideURL.queryString(parts); 87 } 88 return StreetsideURL.queryString(null); 89 } 90 91 public static String queryStreetsideString(final Bounds bounds) { 92 if (bounds != null) { 93 final Map<String, String> parts = new HashMap<>(); 94 parts.put("bbox", bounds.toBBox().toStringCSV(",")); 95 return StreetsideURL.queryStreetsideBoundsString(parts); 96 } 97 return StreetsideURL.queryStreetsideBoundsString(null); 98 } 99 100 } 101 102 public static final class VirtualEarth { 103 private static final String BASE_URL_PREFIX = "https://t.ssl.ak.tiles.virtualearth.net/tiles/hs"; 104 private static final String BASE_URL_SUFFIX = ".jpg?g=6528&n=z"; 105 106 private VirtualEarth() { 107 // Private constructor to avoid instantiation 108 } 109 110 public static URL streetsideTile(final String id, boolean thumbnail) { 111 StringBuilder modifiedId = new StringBuilder(); 112 113 if (thumbnail) { 37 private static final int OSM_BBOX_NORTH = 3; 38 private static final int OSM_BBOX_SOUTH = 1; 39 private static final int OSM_BBOXEAST = 2; 40 private static final int OSM_BBOX_WEST = 0; 41 42 private StreetsideURL() { 43 // Private constructor to avoid instantiation 44 } 45 46 public static URL[] string2URLs(String baseUrlPrefix, String cubemapImageId, String baseUrlSuffix) { 47 List<URL> res = new ArrayList<>(); 48 49 switch (Boolean.TRUE.equals(StreetsideProperties.SHOW_HIGH_RES_STREETSIDE_IMAGERY.get()) ? 16 : 4) { 50 51 case 16: 52 53 EnumSet.allOf(CubemapUtils.CubemapFaces.class).forEach(face -> { 54 for (int i = 0; i < 4; i++) { 55 for (int j = 0; j < 4; j++) { 56 try { 57 final String urlStr = baseUrlPrefix + cubemapImageId 58 + CubemapUtils.rowCol2StreetsideCellAddressMap.get(String.valueOf(i) + j) 59 + baseUrlSuffix; 60 res.add(new URL(urlStr)); 61 } catch (final MalformedURLException e) { 62 LOGGER.log(Logging.LEVEL_ERROR, "Error creating URL String for cubemap " + cubemapImageId); 63 e.printStackTrace(); 64 } 65 66 } 67 } 68 }); 69 break; 70 71 case 4: 72 EnumSet.allOf(CubemapUtils.CubemapFaces.class).forEach(face -> { 73 for (int i = 0; i < 4; i++) { 74 75 try { 76 final String urlStr = baseUrlPrefix + cubemapImageId 77 + CubemapUtils.rowCol2StreetsideCellAddressMap.get(String.valueOf(i)) + baseUrlSuffix; 78 res.add(new URL(urlStr)); 79 } catch (final MalformedURLException e) { 80 LOGGER.log(Logging.LEVEL_WARN, "Error creating URL String for cubemap " + cubemapImageId); 81 e.printStackTrace(); 82 } 83 84 } 85 }); 86 break; // break is optional 87 default: 88 // Statements 89 } 90 return res.toArray(new URL[0]); 91 } 92 93 /** 94 * Builds a query string from it's parts that are supplied as a {@link Map} 95 * 96 * @param parts the parts of the query string 97 * @return the constructed query string (including a leading ?) 98 */ 99 static String queryString(Map<String, String> parts) { 100 final StringBuilder ret = new StringBuilder("?client_id=").append(StreetsideProperties.URL_CLIENT_ID.get()); 101 if (parts != null) { 102 for (final Entry<String, String> entry : parts.entrySet()) { 103 try { 104 ret.append('&').append(URLEncoder.encode(entry.getKey(), StandardCharsets.UTF_8.name())).append('=') 105 .append(URLEncoder.encode(entry.getValue(), StandardCharsets.UTF_8.name())); 106 } catch (final UnsupportedEncodingException e) { 107 LOGGER.log(Logging.LEVEL_WARN, e.getMessage(), e); // This should not happen, as the encoding is hard-coded 108 } 109 } 110 } 111 112 if (Boolean.TRUE.equals(StreetsideProperties.DEBUGING_ENABLED.get())) { 113 LOGGER.log(Logging.LEVEL_DEBUG, MessageFormat.format("queryString result: {0}", ret)); 114 } 115 116 return ret.toString(); 117 } 118 119 static String queryStreetsideBoundsString(Map<String, String> parts) { 120 final StringBuilder ret = new StringBuilder("?n="); 121 if (parts != null) { 122 final List<String> bbox = new ArrayList<>(Arrays.asList(parts.get("bbox").split(","))); 123 try { 124 ret.append(URLEncoder.encode(bbox.get(StreetsideURL.OSM_BBOX_NORTH), StandardCharsets.UTF_8.name())) 125 .append("&s=") 126 .append(URLEncoder.encode(bbox.get(StreetsideURL.OSM_BBOX_SOUTH), 127 StandardCharsets.UTF_8.name())) 128 .append("&e=") 129 .append(URLEncoder.encode(bbox.get(StreetsideURL.OSM_BBOXEAST), StandardCharsets.UTF_8.name())) 130 .append("&w=") 131 .append(URLEncoder.encode(bbox.get(StreetsideURL.OSM_BBOX_WEST), StandardCharsets.UTF_8.name())) 132 .append("&c=1000").append("&appkey=").append(StreetsideProperties.BING_MAPS_KEY.get()); 133 } catch (final UnsupportedEncodingException e) { 134 LOGGER.log(Logging.LEVEL_ERROR, e.getMessage(), e); // This should not happen, as the encoding is hard-coded 135 } 136 } 137 138 return ret.toString(); 139 } 140 141 static String queryByIdString(Map<String, String> parts) { 142 final StringBuilder ret = new StringBuilder("?id="); 143 try { 144 ret.append(URLEncoder.encode(StreetsideProperties.TEST_BUBBLE_ID.get(), StandardCharsets.UTF_8.name())); 145 ret.append('&').append(URLEncoder.encode("appkey=", StandardCharsets.UTF_8.name())).append('=') 146 .append(URLEncoder.encode(StreetsideProperties.BING_MAPS_KEY.get(), StandardCharsets.UTF_8.name())); 147 } catch (final UnsupportedEncodingException e) { 148 LOGGER.log(Logging.LEVEL_ERROR, e.getMessage(), e); // This should not happen, as the encoding is hard-coded 149 } 150 151 if (Boolean.TRUE.equals(StreetsideProperties.DEBUGING_ENABLED.get())) { 152 LOGGER.info("queryById result: " + ret); 153 } 154 return ret.toString(); 155 } 156 157 /** 158 * Converts a {@link String} into a {@link URL} without throwing a {@link MalformedURLException}. 159 * Instead such an exception will lead to an {@link Logger}. 160 * So you should be very confident that your URL is well-formed when calling this method. 161 * 162 * @param strings the Strings describing the URL 163 * @return the URL that is constructed from the given string 164 */ 165 static URL string2URL(String... strings) { 166 final StringBuilder builder = new StringBuilder(); 167 for (int i = 0; strings != null && i < strings.length; i++) { 168 builder.append(strings[i]); 169 } 170 try { 171 return new URL(builder.toString()); 172 } catch (final MalformedURLException e) { 173 LOGGER.log(Logging.LEVEL_ERROR, I18n.tr(String.format("The class '%s' produces malformed URLs like '%s'!", 174 StreetsideURL.class.getName(), builder), e)); 175 return null; 176 } 177 } 178 179 public static final class APIv3 { 180 181 private APIv3() { 182 // Private constructor to avoid instantiation 183 } 184 185 public static URL searchStreetsideImages(Bounds bounds) { 186 return StreetsideURL.string2URL(StreetsideURL.STREETSIDE_BASE_URL, APIv3.queryStreetsideString(bounds)); 187 } 188 189 /** 190 * The APIv3 returns a Link header for each request. It contains a URL for requesting more results. 191 * If you supply the value of the Link header, this method returns the next URL, 192 * if such a URL is defined in the header. 193 * 194 * @param value the value of the HTTP-header with key "Link" 195 * @return the {@link URL} for the next result page, or <code>null</code> if no such URL could be found 196 */ 197 public static URL parseNextFromLinkHeaderValue(String value) { 198 if (value != null) { 199 // Iterate over the different entries of the Link header 200 for (final String link : value.split(",", Integer.MAX_VALUE)) { 201 boolean isNext = false; 202 URL url = null; 203 // Iterate over the parts of each entry (typically it's one `rel="‹linkType›"` and one like `<https://URL>`) 204 for (String linkPart : link.split(";", Integer.MAX_VALUE)) { 205 linkPart = linkPart.trim(); 206 isNext |= linkPart.matches("rel\\s*=\\s*\"next\""); 207 if (linkPart.length() >= 1 && linkPart.charAt(0) == '<' && linkPart.endsWith(">")) { 208 try { 209 url = new URL(linkPart.substring(1, linkPart.length() - 1)); 210 } catch (final MalformedURLException e) { 211 Logging.log(Logging.LEVEL_WARN, 212 "Mapillary API v3 returns a malformed URL in the Link header.", e); 213 } 214 } 215 } 216 // If both a URL and the rel=next attribute are present, return the URL. Otherwise null is returned 217 if (url != null && isNext) { 218 return url; 219 } 220 } 221 } 222 return null; 223 } 224 225 public static String queryString(final Bounds bounds) { 226 if (bounds != null) { 227 final Map<String, String> parts = new HashMap<>(); 228 parts.put("bbox", bounds.toBBox().toStringCSV(",")); 229 return StreetsideURL.queryString(parts); 230 } 231 return StreetsideURL.queryString(null); 232 } 233 234 public static String queryStreetsideString(final Bounds bounds) { 235 if (bounds != null) { 236 final Map<String, String> parts = new HashMap<>(); 237 parts.put("bbox", bounds.toBBox().toStringCSV(",")); 238 return StreetsideURL.queryStreetsideBoundsString(parts); 239 } 240 return StreetsideURL.queryStreetsideBoundsString(null); 241 } 242 243 } 244 245 public static final class VirtualEarth { 246 private static final String BASE_URL_PREFIX = "https://t.ssl.ak.tiles.virtualearth.net/tiles/hs"; 247 private static final String BASE_URL_SUFFIX = ".jpg?g=6528&n=z"; 248 249 private VirtualEarth() { 250 // Private constructor to avoid instantiation 251 } 252 253 public static URL streetsideTile(final String id, boolean thumbnail) { 254 StringBuilder modifiedId = new StringBuilder(); 255 256 if (thumbnail) { 114 257 // pad thumbnail imagery with leading zeros 115 258 if (id.length() < 16) { … … 119 262 } 120 263 modifiedId.append(id).append("01"); 121 } else if(StreetsideProperties.SHOW_HIGH_RES_STREETSIDE_IMAGERY.get()){ 122 // pad 16-tiled imagery with leading zeros 123 if (id.length() < 20) { 124 for (int i = 0; i < 20 - id.length(); i++) { 125 modifiedId.append("0"); 264 } else { 265 if (Boolean.TRUE.equals(StreetsideProperties.SHOW_HIGH_RES_STREETSIDE_IMAGERY.get())) { 266 // pad 16-tiled imagery with leading zeros 267 if (id.length() < 20) { 268 for (int i = 0; i < 20 - id.length(); i++) { 269 modifiedId.append("0"); 270 } 271 } 272 } else { 273 // pad 4-tiled imagery with leading zeros 274 if (id.length() < 19) { 275 for (int i = 0; i < 19 - id.length(); i++) { 276 modifiedId.append("0"); 277 } 278 } 126 279 } 127 280 modifiedId.append(id); 128 } 129 } else if(!StreetsideProperties.SHOW_HIGH_RES_STREETSIDE_IMAGERY.get()) { 130 // pad 4-tiled imagery with leading zeros 131 if (id.length() < 19) { 132 for (int i = 0; i < 19 - id.length(); i++) { 133 modifiedId.append("0"); 134 } 135 modifiedId.append(id); 136 } 137 } 138 URL url = StreetsideURL.string2URL(VirtualEarth.BASE_URL_PREFIX + modifiedId.toString() + VirtualEarth.BASE_URL_SUFFIX); 139 if(StreetsideProperties.DEBUGING_ENABLED.get()) { 140 logger.debug(MessageFormat.format("Tile task URL {0} invoked.", url.toString())); 141 } 142 return url; 143 } 144 } 145 146 public static final class MainWebsite { 147 148 private MainWebsite() { 149 // Private constructor to avoid instantiation 150 } 151 152 /** 153 * Gives you the URL for the online viewer of a specific Streetside image. 154 * @param id the id of the image to which you want to link 155 * @return the URL of the online viewer for the image with the given image key 156 * @throws IllegalArgumentException if the image key is <code>null</code> 157 */ 158 public static URL browseImage(String id) { 159 if (id == null) { 160 throw new IllegalArgumentException("The image id may not be null!"); 161 } 162 163 StringBuilder modifiedId = new StringBuilder(); 281 } 282 URL url = StreetsideURL 283 .string2URL(VirtualEarth.BASE_URL_PREFIX + modifiedId + VirtualEarth.BASE_URL_SUFFIX); 284 if (Boolean.TRUE.equals(StreetsideProperties.DEBUGING_ENABLED.get())) { 285 LOGGER.log(Logging.LEVEL_DEBUG, MessageFormat.format("Tile task URL {0} invoked.", url)); 286 } 287 return url; 288 } 289 } 290 291 public static final class MainWebsite { 292 293 private MainWebsite() { 294 // Private constructor to avoid instantiation 295 } 296 297 /** 298 * Gives you the URL for the online viewer of a specific Streetside image. 299 * 300 * @param id the id of the image to which you want to link 301 * @return the URL of the online viewer for the image with the given image key 302 * @throws IllegalArgumentException if the image key is <code>null</code> 303 */ 304 public static URL browseImage(String id) { 305 if (id == null) { 306 throw new IllegalArgumentException("The image id may not be null!"); 307 } 308 309 StringBuilder modifiedId = new StringBuilder(); 164 310 165 311 // pad thumbnail imagery with leading zeros … … 171 317 modifiedId.append(id).append("01"); 172 318 173 return StreetsideURL.string2URL(MessageFormat.format("{0}{1}{2}",VirtualEarth.BASE_URL_PREFIX, modifiedId.toString(), VirtualEarth.BASE_URL_SUFFIX)); 174 } 175 176 /** 177 * Gives you the URL for the blur editor of the image with the given key. 178 * @param id the key of the image for which you want to open the blur editor 179 * @return the URL of the blur editor 180 * @throws IllegalArgumentException if the image key is <code>null</code> 181 */ 182 public static URL streetsidePrivacyLink(final String id) { 183 if (id == null) { 184 throw new IllegalArgumentException("The image id must not be null!"); 185 } 186 String urlEncodedId; 187 try { 188 urlEncodedId = URLEncoder.encode(id, StandardCharsets.UTF_8.name()); 189 } catch (final UnsupportedEncodingException e) { 190 logger.error(I18n.tr("Unsupported encoding when URL encoding", e)); 191 urlEncodedId = id; 192 } 193 return StreetsideURL.string2URL(StreetsideURL.STREETSIDE_PRIVACY_URL, urlEncodedId); 194 } 195 196 } 197 198 private StreetsideURL() { 199 // Private constructor to avoid instantiation 200 } 201 202 public static URL[] string2URLs(String baseUrlPrefix, String cubemapImageId, String baseUrlSuffix) { 203 List<URL> res = new ArrayList<>(); 204 205 switch (StreetsideProperties.SHOW_HIGH_RES_STREETSIDE_IMAGERY.get() ? 16 : 4) { 206 207 case 16: 208 209 EnumSet.allOf(CubemapUtils.CubemapFaces.class).forEach(face -> { 210 for (int i = 0; i < 4; i++) { 211 for (int j = 0; j < 4; j++) { 212 try { 213 final String urlStr = baseUrlPrefix + cubemapImageId 214 + CubemapUtils.rowCol2StreetsideCellAddressMap 215 .get(String.valueOf(i) + String.valueOf(j)) 216 + baseUrlSuffix; 217 res.add(new URL(urlStr)); 218 } catch (final MalformedURLException e) { 219 logger.error("Error creating URL String for cubemap " + cubemapImageId); 220 e.printStackTrace(); 221 } 222 223 } 224 } 225 }); 226 break; 227 228 case 4: 229 EnumSet.allOf(CubemapUtils.CubemapFaces.class).forEach(face -> { 230 for (int i = 0; i < 4; i++) { 231 232 try { 233 final String urlStr = baseUrlPrefix + cubemapImageId 234 + CubemapUtils.rowCol2StreetsideCellAddressMap.get(String.valueOf(i)) + baseUrlSuffix; 235 res.add(new URL(urlStr)); 236 } catch (final MalformedURLException e) { 237 logger.error("Error creating URL String for cubemap " + cubemapImageId); 238 e.printStackTrace(); 239 } 240 241 } 242 }); 243 break; // break is optional 244 default: 245 // Statements 246 } 247 return res.stream().toArray(URL[]::new); 248 } 249 250 /** 251 * Builds a query string from it's parts that are supplied as a {@link Map} 252 * @param parts the parts of the query string 253 * @return the constructed query string (including a leading ?) 254 */ 255 static String queryString(Map<String, String> parts) { 256 final StringBuilder ret = new StringBuilder("?client_id=").append(StreetsideProperties.URL_CLIENT_ID.get()); 257 if (parts != null) { 258 for (final Entry<String, String> entry : parts.entrySet()) { 259 try { 260 ret.append('&') 261 .append(URLEncoder.encode(entry.getKey(), StandardCharsets.UTF_8.name())) 262 .append('=') 263 .append(URLEncoder.encode(entry.getValue(), StandardCharsets.UTF_8.name())); 264 } catch (final UnsupportedEncodingException e) { 265 logger.error(e); // This should not happen, as the encoding is hard-coded 266 } 267 } 268 } 269 270 if(StreetsideProperties.DEBUGING_ENABLED.get()) { 271 logger.debug(MessageFormat.format("queryString result: {0}", ret.toString())); 272 } 273 274 return ret.toString(); 275 } 276 277 static String queryStreetsideBoundsString(Map<String, String> parts) { 278 final StringBuilder ret = new StringBuilder("?n="); 279 if (parts != null) { 280 final List<String> bbox = new ArrayList<>(Arrays.asList(parts.get("bbox").split(","))); 281 try { 282 ret.append(URLEncoder.encode(bbox.get(StreetsideURL.OSM_BBOX_NORTH), StandardCharsets.UTF_8.name())) 283 .append("&s=") 284 .append(URLEncoder.encode(bbox.get(StreetsideURL.OSM_BBOX_SOUTH), StandardCharsets.UTF_8.name())) 285 .append("&e=") 286 .append(URLEncoder.encode(bbox.get(StreetsideURL.OSM_BBOXEAST), StandardCharsets.UTF_8.name())) 287 .append("&w=") 288 .append(URLEncoder.encode(bbox.get(StreetsideURL.OSM_BBOX_WEST), StandardCharsets.UTF_8.name())) 289 .append("&c=1000") 290 .append("&appkey=") 291 .append(StreetsideProperties.BING_MAPS_KEY.get()); 292 } catch (final UnsupportedEncodingException e) { 293 logger.error(e); // This should not happen, as the encoding is hard-coded 294 } 295 } 296 297 return ret.toString(); 298 } 299 300 static String queryByIdString(Map<String, String> parts) { 301 final StringBuilder ret = new StringBuilder("?id="); 302 try { 303 ret.append(URLEncoder.encode(StreetsideProperties.TEST_BUBBLE_ID.get(), StandardCharsets.UTF_8.name())); 304 ret.append('&').append(URLEncoder.encode("appkey=", StandardCharsets.UTF_8.name())).append('=') 305 .append(URLEncoder.encode(StreetsideProperties.BING_MAPS_KEY.get(), StandardCharsets.UTF_8.name())); 306 } catch (final UnsupportedEncodingException e) { 307 logger.error(e); // This should not happen, as the encoding is hard-coded 308 } 309 310 if(StreetsideProperties.DEBUGING_ENABLED.get()) { 311 logger.info("queryById result: " + ret.toString()); 312 } 313 return ret.toString(); 314 } 315 316 /** 317 * Converts a {@link String} into a {@link URL} without throwing a {@link MalformedURLException}. 318 * Instead such an exception will lead to an {@link Logger}. 319 * So you should be very confident that your URL is well-formed when calling this method. 320 * @param strings the Strings describing the URL 321 * @return the URL that is constructed from the given string 322 */ 323 static URL string2URL(String... strings) { 324 final StringBuilder builder = new StringBuilder(); 325 for (int i = 0; strings != null && i < strings.length; i++) { 326 builder.append(strings[i]); 327 } 328 try { 329 return new URL(builder.toString()); 330 } catch (final MalformedURLException e) { 331 logger.error(I18n.tr(String.format( 332 "The class '%s' produces malformed URLs like '%s'!", 333 StreetsideURL.class.getName(), 334 builder 335 ), e)); 336 return null; 337 } 338 } 319 return StreetsideURL.string2URL(MessageFormat.format("{0}{1}{2}", VirtualEarth.BASE_URL_PREFIX, modifiedId, 320 VirtualEarth.BASE_URL_SUFFIX)); 321 } 322 323 /** 324 * Gives you the URL for the blur editor of the image with the given key. 325 * 326 * @param id the key of the image for which you want to open the blur editor 327 * @return the URL of the blur editor 328 * @throws IllegalArgumentException if the image key is <code>null</code> 329 */ 330 public static URL streetsidePrivacyLink(final String id) { 331 if (id == null) { 332 throw new IllegalArgumentException("The image id must not be null!"); 333 } 334 String urlEncodedId; 335 try { 336 urlEncodedId = URLEncoder.encode(id, StandardCharsets.UTF_8.name()); 337 } catch (final UnsupportedEncodingException e) { 338 LOGGER.log(Logging.LEVEL_ERROR, I18n.tr("Unsupported encoding when URL encoding", e), e); 339 urlEncodedId = id; 340 } 341 return StreetsideURL.string2URL(StreetsideURL.STREETSIDE_PRIVACY_URL, urlEncodedId); 342 } 343 344 } 339 345 } -
applications/editors/josm/plugins/MicrosoftStreetside/src/org/openstreetmap/josm/plugins/streetside/utils/StreetsideUtils.java
r34431 r36194 16 16 import org.apache.commons.imaging.common.RationalNumber; 17 17 import org.apache.commons.imaging.formats.tiff.constants.GpsTagConstants; 18 import org.apache.log4j.Logger;19 18 import org.openstreetmap.josm.data.Bounds; 20 19 import org.openstreetmap.josm.data.coor.LatLon; … … 32 31 public final class StreetsideUtils { 33 32 34 final static Logger logger = Logger.getLogger(StreetsideUtils.class);35 36 33 private static final double MIN_ZOOM_SQUARE_SIDE = 0.002; 37 34 … … 101 98 * 102 99 * @param degMinSec an array of length 3, the values in there are (in this order) 103 * 104 * @param ref 105 * 106 * 107 * 108 * 109 * 110 * 111 * 112 * 113 * 114 * 115 * 116 * 100 * degrees, minutes and seconds 101 * @param ref the latitude or longitude reference determining if the given value 102 * is: 103 * <ul> 104 * <li>north ( 105 * {@link GpsTagConstants#GPS_TAG_GPS_LATITUDE_REF_VALUE_NORTH}) or 106 * south ( 107 * {@link GpsTagConstants#GPS_TAG_GPS_LATITUDE_REF_VALUE_SOUTH}) of 108 * the equator</li> 109 * <li>east ( 110 * {@link GpsTagConstants#GPS_TAG_GPS_LONGITUDE_REF_VALUE_EAST}) or 111 * west ({@link GpsTagConstants#GPS_TAG_GPS_LONGITUDE_REF_VALUE_WEST} 112 * ) of the equator</li> 113 * </ul> 117 114 * @return the decimal degree-value for the given input, negative when west of 118 115 * 0-meridian or south of equator, positive otherwise 119 116 * @throws IllegalArgumentException if {@code degMinSec} doesn't have length 3 or if {@code ref} is 120 * 117 * not one of the values mentioned above 121 118 */ 122 119 public static double degMinSecToDouble(RationalNumber[] degMinSec, String ref) { … … 130 127 131 128 switch (ref) { 132 133 134 135 136 137 138 129 case GpsTagConstants.GPS_TAG_GPS_LATITUDE_REF_VALUE_NORTH: 130 case GpsTagConstants.GPS_TAG_GPS_LATITUDE_REF_VALUE_SOUTH: 131 case GpsTagConstants.GPS_TAG_GPS_LONGITUDE_REF_VALUE_EAST: 132 case GpsTagConstants.GPS_TAG_GPS_LONGITUDE_REF_VALUE_WEST: 133 break; 134 default: 135 throw new IllegalArgumentException("Invalid ref."); 139 136 } 140 137 … … 144 141 145 142 if (GpsTagConstants.GPS_TAG_GPS_LATITUDE_REF_VALUE_SOUTH.equals(ref) 146 143 || GpsTagConstants.GPS_TAG_GPS_LONGITUDE_REF_VALUE_WEST.equals(ref)) { 147 144 result *= -1; 148 145 } … … 166 163 } 167 164 if ((imgA.next() != null || imgB.previous() != null) && (imgB.next() != null || imgA.previous() != null)) { 168 throw new IllegalArgumentException("You can only join an image at the end of a sequence with one at the beginning of another sequence."); 165 throw new IllegalArgumentException( 166 "You can only join an image at the end of a sequence with one at the beginning of another sequence."); 169 167 } 170 168 if (imgA.next() != null || imgB.previous() != null) { … … 223 221 /** 224 222 * Separates two images belonging to the same sequence. The two images have to be consecutive in the same sequence. 225 * Two new sequences are created and all images up to (and including) either {@code imgA} or {@code imgB} (whichever appears first in the sequence) are put into the first of the two sequences. 223 * Two new sequences are created and all images up to (and including) either {@code imgA} or {@code imgB} 224 * (whichever appears first in the sequence) are put into the first of the two sequences. 226 225 * All others are put into the second new sequence. 227 226 * … … 237 236 } 238 237 if (imgB.equals(imgA.next()) && imgA.equals(imgB.next())) { 239 throw new IllegalArgumentException("When unjoining with two images these must be consecutive in one sequence."); 238 throw new IllegalArgumentException( 239 "When unjoining with two images these must be consecutive in one sequence."); 240 240 } 241 241 … … 273 273 ret.append(I18n.tr("Total Streetside images: {0}", StreetsideLayer.getInstance().getToolTipText())); 274 274 } else if (PluginState.isSubmittingChangeset()) { 275 275 ret.append(I18n.tr("Submitting Streetside Changeset")); 276 276 } else { 277 277 ret.append(I18n.tr("No images found")); -
applications/editors/josm/plugins/MicrosoftStreetside/src/org/openstreetmap/josm/plugins/streetside/utils/api/JsonDecoder.java
r36122 r36194 9 9 import java.util.function.Function; 10 10 11 import org.openstreetmap.josm.data.coor.LatLon; 12 import org.openstreetmap.josm.tools.I18n; 13 import org.openstreetmap.josm.tools.Logging; 14 11 15 import jakarta.json.JsonArray; 12 16 import jakarta.json.JsonNumber; 13 17 import jakarta.json.JsonObject; 14 18 import jakarta.json.JsonValue; 15 16 import org.openstreetmap.josm.data.coor.LatLon;17 import org.openstreetmap.josm.tools.I18n;18 import org.openstreetmap.josm.tools.Logging;19 19 20 20 public final class JsonDecoder { … … 29 29 * of the desired Java objects. The method, which converts the GeoJSON features into Java objects 30 30 * is given as a parameter to this method. 31 * @param <T> feature type 32 * @param json the {@link JsonObject} to be parsed 31 * 32 * @param <T> feature type 33 * @param json the {@link JsonObject} to be parsed 33 34 * @param featureDecoder feature decoder which transforms JSON objects to Java objects 34 35 * @return a {@link Collection} which is parsed from the given {@link JsonObject}, which contains GeoJSON. 35 * 36 * 36 * Currently a {@link HashSet} is used, but please don't rely on it, this could change at any time without 37 * prior notice. The return value will not be <code>null</code>. 37 38 */ 38 public static <T> Collection<T> decodeFeatureCollection(final JsonObject json, Function<JsonObject, T> featureDecoder) { 39 public static <T> Collection<T> decodeFeatureCollection(final JsonObject json, 40 Function<JsonObject, T> featureDecoder) { 39 41 final Collection<T> result = new HashSet<>(); 40 if ( 41 json != null && "FeatureCollection".equals(json.getString("type", null)) && json.containsKey("features") 42 ) { 42 if (json != null && "FeatureCollection".equals(json.getString("type", null)) && json.containsKey("features")) { 43 43 final JsonValue features = json.get("features"); 44 44 for (int i = 0; features instanceof JsonArray && i < ((JsonArray) features).size(); i++) { … … 58 58 * Decodes a {@link JsonArray} of exactly size 2 to a {@link LatLon} instance. 59 59 * The first value in the {@link JsonArray} is treated as longitude, the second one as latitude. 60 * 60 61 * @param json the {@link JsonArray} containing the two numbers 61 62 * @return the decoded {@link LatLon} instance, or <code>null</code> if the parameter is 62 * 63 * not a {@link JsonArray} of exactly size 2 containing two {@link JsonNumber}s. 63 64 */ 64 65 static LatLon decodeLatLon(final JsonArray json) { … … 72 73 /** 73 74 * Decodes a pair of double values, which are stored in a {@link JsonArray} of exactly size 2. 75 * 74 76 * @param json the {@link JsonArray} containing the two values 75 77 * @return a double array which contains the two values in the same order, or <code>null</code> 76 * 78 * if the parameter was not a {@link JsonArray} of exactly size 2 containing two {@link JsonNumber}s 77 79 */ 78 80 static double[] decodeDoublePair(final JsonArray json) { 79 if ( 80 json != null && 81 json.size() == 2 && 82 json.get(0) instanceof JsonNumber && 83 json.get(1) instanceof JsonNumber 84 ) { 85 return new double[]{json.getJsonNumber(0).doubleValue(), json.getJsonNumber(1).doubleValue()}; 81 if (json != null && json.size() == 2 && json.get(0) instanceof JsonNumber 82 && json.get(1) instanceof JsonNumber) { 83 return new double[] { json.getJsonNumber(0).doubleValue(), json.getJsonNumber(1).doubleValue() }; 86 84 } 87 85 return EMPTY_DOUBLE; … … 91 89 * Decodes a timestamp formatted as a {@link String} to the equivalent UNIX epoch timestamp 92 90 * (number of milliseconds since 1970-01-01T00:00:00.000+0000). 91 * 93 92 * @param timestamp the timestamp formatted according to the format <code>yyyy-MM-dd'T'HH:mm:ss.SSSX</code> 94 93 * @return the point in time as a {@link Long} value representing the UNIX epoch time, or <code>null</code> if the 95 * 96 * 94 * parameter does not match the required format (this also triggers a warning via 95 * {@link Logging}, or the parameter is <code>null</code>). 97 96 */ 98 97 static Long decodeTimestamp(final String timestamp) { … … 102 101 } catch (ParseException e) { 103 102 StackTraceElement calledBy = e.getStackTrace()[Math.min(e.getStackTrace().length - 1, 2)]; 104 Logging.warn(I18n.tr(String.format( 105 "Could not decode time from the timestamp `%s` (called by %s.%s:%d)", 106 timestamp, calledBy.getClassName(), calledBy.getMethodName(), calledBy.getLineNumber() 107 ), e)); 103 Logging.warn(I18n.tr(String.format("Could not decode time from the timestamp `%s` (called by %s.%s:%d)", 104 timestamp, calledBy.getClassName(), calledBy.getMethodName(), calledBy.getLineNumber()), e)); 108 105 } 109 106 } -
applications/editors/josm/plugins/MicrosoftStreetside/src/org/openstreetmap/josm/plugins/streetside/utils/api/JsonImageDetectionDecoder.java
r36122 r36194 5 5 import java.awt.geom.Path2D; 6 6 7 import org.openstreetmap.josm.plugins.streetside.model.ImageDetection; 8 import org.openstreetmap.josm.plugins.streetside.utils.StreetsideURL.APIv3; 9 import org.openstreetmap.josm.tools.Logging; 10 7 11 import jakarta.json.JsonArray; 8 12 import jakarta.json.JsonNumber; 9 13 import jakarta.json.JsonObject; 10 14 import jakarta.json.JsonValue; 11 12 import org.openstreetmap.josm.plugins.streetside.model.ImageDetection;13 import org.openstreetmap.josm.plugins.streetside.utils.StreetsideURL.APIv3;14 import org.openstreetmap.josm.tools.Logging;15 15 16 16 /** … … 38 38 final Double score = scoreVal instanceof JsonNumber ? ((JsonNumber) scoreVal).doubleValue() : null; 39 39 final Shape shape = decodeShape(((JsonObject) properties).get("shape")); 40 if (shape instanceof Path2D && imageKey != null && key != null && score != null && packag != null && value != null) { 40 if (shape instanceof Path2D && imageKey != null && key != null && score != null && packag != null 41 && value != null) { 41 42 return new ImageDetection((Path2D) shape, imageKey, key, score, packag, value); 42 43 } … … 48 49 if (json instanceof JsonObject) { 49 50 if (!"Polygon".equals(((JsonObject) json).getString("type", null))) { 50 Logging.warn( 51 String.format("Image detections using shapes with type=%s are currently not supported!", 52 ((JsonObject) json).getString("type", "‹no type set›")) 53 ); 51 Logging.warn(String.format("Image detections using shapes with type=%s are currently not supported!", 52 ((JsonObject) json).getString("type", "‹no type set›"))); 54 53 } else { 55 54 final JsonValue coordinates = ((JsonObject) json).get("coordinates"); … … 64 63 /** 65 64 * Decodes a polygon (may be a multipolygon) from JSON 65 * 66 66 * @param json the json array to decode, must not be <code>null</code> 67 67 * @return the decoded polygon as {@link Path2D.Double} … … 83 83 /** 84 84 * Decodes a simple polygon (consisting of only one continuous path) from JSON 85 * 85 86 * @param json the json array to decode, must not be <code>null</code> 86 87 * @return the decoded polygon as {@link Path2D.Double} -
applications/editors/josm/plugins/MicrosoftStreetside/src/org/openstreetmap/josm/plugins/streetside/utils/api/JsonSequencesDecoder.java
r36122 r36194 5 5 import java.util.function.Function; 6 6 7 import org.openstreetmap.josm.data.coor.LatLon; 8 import org.openstreetmap.josm.plugins.streetside.StreetsideImage; 9 import org.openstreetmap.josm.plugins.streetside.StreetsideSequence; 10 import org.openstreetmap.josm.plugins.streetside.utils.StreetsideURL.APIv3; 11 7 12 import jakarta.json.JsonArray; 8 13 import jakarta.json.JsonNumber; … … 10 15 import jakarta.json.JsonString; 11 16 import jakarta.json.JsonValue; 12 13 import org.openstreetmap.josm.data.coor.LatLon;14 import org.openstreetmap.josm.plugins.streetside.StreetsideImage;15 import org.openstreetmap.josm.plugins.streetside.StreetsideSequence;16 import org.openstreetmap.josm.plugins.streetside.utils.StreetsideURL.APIv3;17 17 18 18 /** … … 27 27 /** 28 28 * Parses a given {@link JsonObject} as a GeoJSON Feature into a {@link StreetsideSequence}. 29 * 29 30 * @param json the {@link JsonObject} to be parsed 30 31 * @return a {@link StreetsideSequence} that is parsed from the given {@link JsonObject}. If mandatory information is 31 * 32 * 32 * missing from the JSON or it's not meeting the expecting format in another way, <code>null</code> will be 33 * returned. 33 34 */ 34 35 public static StreetsideSequence decodeSequence(final JsonObject json) { … … 39 40 final JsonObject properties = json.getJsonObject("properties"); 40 41 final Long ca = properties == null ? null : JsonDecoder.decodeTimestamp(properties.getString("cd", null)); 41 if (properties != null && properties.getString("id", null) != null && properties.getString("user_key", null) != null && ca != null) { 42 if (properties != null && properties.getString("id", null) != null 43 && properties.getString("user_key", null) != null && ca != null) { 42 44 result = new StreetsideSequence(properties.getString("id", null), ca); 43 45 44 final Double[] hes = decodeCoordinateProperty( 45 properties, 46 "hes", 47 val -> val instanceof JsonNumber ? ((JsonNumber) val).doubleValue() : null, 48 Double.class 49 ); 50 final String[] imageIds = decodeCoordinateProperty( 51 properties, 52 "image_ids", 53 val -> val instanceof JsonString ? ((JsonString) val).getString() : null, 54 String.class 55 ); 46 final Double[] hes = decodeCoordinateProperty(properties, "hes", 47 val -> val instanceof JsonNumber ? ((JsonNumber) val).doubleValue() : null, Double.class); 48 final String[] imageIds = decodeCoordinateProperty(properties, "image_ids", 49 val -> val instanceof JsonString ? ((JsonString) val).getString() : null, String.class); 56 50 final LatLon[] geometry = decodeLatLons(json.getJsonObject("geometry")); 57 51 final int sequenceLength = Math.min(Math.min(hes.length, imageIds.length), geometry.length); … … 77 71 * @param clazz the desired type that the elements of the resulting array should have 78 72 * @return the supplied array converted from {@link JsonArray} to a java array of the supplied type, converted using 79 * 73 * the supplied function. Never <code>null</code>, in case of array==null, an array of length 0 is returned. 80 74 */ 81 75 @SuppressWarnings("unchecked") 82 private static <T> T[] decodeJsonArray(final JsonArray array, final Function<JsonValue, T> decodeValueFunction, final Class<T> clazz) { 76 private static <T> T[] decodeJsonArray(final JsonArray array, final Function<JsonValue, T> decodeValueFunction, 77 final Class<T> clazz) { 83 78 final T[] result; 84 79 if (array == null) { 85 result = 80 result = (T[]) Array.newInstance(clazz, 0); 86 81 } else { 87 82 result = (T[]) Array.newInstance(clazz, array.size()); … … 103 98 * @param key the key, which identifies the desired array inside the `coordinateProperties` object to be converted 104 99 * @param decodeValueFunction a function that converts the {@link JsonValue}s in the JSON array to java objects of the 105 * 100 * desired type 106 101 * @param clazz the {@link Class} object of the desired type, that the entries of the resulting array should have 107 102 * @return the resulting array, when converting the desired entry of the `coordinateProperties`. 108 * 109 * 103 * Never <code>null</code>. If no `coordinateProperties` are set, or if the desired key is not set or is not 104 * an array, then an empty array of the desired type is returned. 110 105 */ 111 106 @SuppressWarnings("unchecked") 112 private static <T> T[] decodeCoordinateProperty( 113 final JsonObject json, final String key, final Function<JsonValue, T> decodeValueFunction, final Class<T> clazz 114 ) { 107 private static <T> T[] decodeCoordinateProperty(final JsonObject json, final String key, 108 final Function<JsonValue, T> decodeValueFunction, final Class<T> clazz) { 115 109 final JsonValue coordinateProperties = json == null ? null : json.get("coordinateProperties"); 116 110 if (coordinateProperties instanceof JsonObject) { -
applications/editors/josm/plugins/MicrosoftStreetside/src/org/openstreetmap/josm/plugins/streetside/utils/api/JsonStreetsideDecoder.java
r36122 r36194 23 23 * of the desired Java objects. The method, which converts the GeoJSON features into Java objects 24 24 * is given as a parameter to this method. 25 * @param <T> feature type 26 * @param json the {@link JsonObject} to be parsed 25 * 26 * @param <T> feature type 27 * @param json the {@link JsonObject} to be parsed 27 28 * @param featureDecoder feature decoder which transforms JSON objects to Java objects 28 29 * @return a {@link Collection} which is parsed from the given {@link JsonObject}, which contains GeoJSON. 29 * 30 * 30 * Currently a {@link HashSet} is used, but please don't rely on it, this could change at any time without 31 * prior notice. The return value will not be <code>null</code>. 31 32 */ 32 public static <T> Collection<T> decodeFeatureCollection(final JsonObject json, Function<JsonObject, T> featureDecoder) { 33 public static <T> Collection<T> decodeFeatureCollection(final JsonObject json, 34 Function<JsonObject, T> featureDecoder) { 33 35 return JsonDecoder.decodeFeatureCollection(json, featureDecoder); 34 36 } … … 37 39 * Decodes a {@link JsonArray} of exactly size 2 to a {@link LatLon} instance. 38 40 * The first value in the {@link JsonArray} is treated as longitude, the second one as latitude. 41 * 39 42 * @param json the {@link JsonArray} containing the two numbers 40 43 * @return the decoded {@link LatLon} instance, or <code>null</code> if the parameter is 41 * 44 * not a {@link JsonArray} of exactly size 2 containing two {@link JsonNumber}s. 42 45 */ 43 46 static LatLon decodeLatLon(final JsonArray json) { … … 48 51 * Decodes a timestamp formatted as a {@link String} to the equivalent UNIX epoch timestamp 49 52 * (number of milliseconds since 1970-01-01T00:00:00.000+0000). 53 * 50 54 * @param timestamp the timestamp formatted according to the format <code>yyyy-MM-dd'T'HH:mm:ss.SSSX</code> 51 55 * @return the point in time as a {@link Long} value representing the UNIX epoch time, or <code>null</code> if the 52 * 53 * 56 * parameter does not match the required format (this also triggers a warning via 57 * {@link Logging}, or the parameter is <code>null</code>). 54 58 */ 55 59 static Long decodeTimestamp(final String timestamp) { -
applications/editors/josm/plugins/MicrosoftStreetside/src/org/openstreetmap/josm/plugins/streetside/utils/api/JsonStreetsideSequencesDecoder.java
r36122 r36194 5 5 import java.util.function.Function; 6 6 7 import org.openstreetmap.josm.data.coor.LatLon; 8 import org.openstreetmap.josm.plugins.streetside.StreetsideImage; 9 import org.openstreetmap.josm.plugins.streetside.StreetsideSequence; 10 import org.openstreetmap.josm.plugins.streetside.utils.StreetsideURL.APIv3; 11 7 12 import jakarta.json.JsonArray; 8 13 import jakarta.json.JsonNumber; … … 10 15 import jakarta.json.JsonString; 11 16 import jakarta.json.JsonValue; 12 13 import org.openstreetmap.josm.data.coor.LatLon;14 import org.openstreetmap.josm.plugins.streetside.StreetsideImage;15 import org.openstreetmap.josm.plugins.streetside.StreetsideSequence;16 import org.openstreetmap.josm.plugins.streetside.utils.StreetsideURL.APIv3;17 17 18 18 /** … … 27 27 /** 28 28 * Parses a given {@link JsonObject} as a GeoJSON Feature into a {@link StreetsideSequence}. 29 * 29 30 * @param json the {@link JsonObject} to be parsed 30 31 * @return a {@link StreetsideSequence} that is parsed from the given {@link JsonObject}. If mandatory information is 31 * 32 * 32 * missing from the JSON or it's not meeting the expecting format in another way, <code>null</code> will be 33 * returned. 33 34 */ 34 35 public static StreetsideSequence decodeSequence(final JsonObject json) { … … 42 43 result = new StreetsideSequence(properties.getString("id", null), ca); 43 44 44 final Double[] cas = decodeCoordinateProperty( 45 properties, 46 "hes", 47 val -> val instanceof JsonNumber ? ((JsonNumber) val).doubleValue() : null, 48 Double.class 49 ); 50 final String[] imageIds = decodeCoordinateProperty( 51 properties, 52 "image_ids", 53 val -> val instanceof JsonString ? ((JsonString) val).getString() : null, 54 String.class 55 ); 45 final Double[] cas = decodeCoordinateProperty(properties, "hes", 46 val -> val instanceof JsonNumber ? ((JsonNumber) val).doubleValue() : null, Double.class); 47 final String[] imageIds = decodeCoordinateProperty(properties, "image_ids", 48 val -> val instanceof JsonString ? ((JsonString) val).getString() : null, String.class); 56 49 final LatLon[] geometry = decodeLatLons(json.getJsonObject("geometry")); 57 50 final int sequenceLength = Math.min(Math.min(cas.length, imageIds.length), geometry.length); … … 73 66 * @param image the {@link StreetsideImage} to be parsed 74 67 * @return a {@link StreetsideSequence} that is parsed from the given {@link JsonObject}. If mandatory information is 75 * 76 * 68 * missing from the JSON or it's not meeting the expecting format in another way, <code>null</code> will be 69 * returned. 77 70 */ 78 71 public static StreetsideImage decodeBubbleData(final StreetsideImage image) { … … 82 75 // Declare and instantiate new Streetside object to ensure proper setting of superclass attributes 83 76 StreetsideImage result = null; 84 if (image.getId() != null) {77 if (image.getId() != null) { 85 78 result = new StreetsideImage(image.getId(), new LatLon(image.getLa(), image.getLo()), 0.0); 86 79 result.setAl(image.getAl()); … … 103 96 * @param json the {@link JsonObject} to be parsed 104 97 * @return a {@link StreetsideSequence} that is parsed from the given {@link JsonObject}. If mandatory information is 105 * 106 * 98 * missing from the JSON or it's not meeting the expecting format in another way, <code>null</code> will be 99 * returned. 107 100 */ 108 101 public static StreetsideSequence decodeStreetsideSequence(final JsonObject json) { … … 112 105 StreetsideSequence result = null; 113 106 114 if (json.getString("id", null) != null && json.getString("la", null) != null && json.getString("lo", null) != null) { 115 result = new StreetsideSequence(json.getString("id", null), 116 json.getJsonNumber("la").doubleValue(), json.getJsonNumber("lo").doubleValue(), json.getJsonNumber("cd").longValue()); 107 if (json.getString("id", null) != null && json.getString("la", null) != null 108 && json.getString("lo", null) != null) { 109 result = new StreetsideSequence(json.getString("id", null), json.getJsonNumber("la").doubleValue(), 110 json.getJsonNumber("lo").doubleValue(), json.getJsonNumber("cd").longValue()); 117 111 } 118 112 … … 128 122 * @param clazz the desired type that the elements of the resulting array should have 129 123 * @return the supplied array converted from {@link JsonArray} to a java array of the supplied type, converted using 130 * 124 * the supplied function. Never <code>null</code>, in case of array==null, an array of length 0 is returned. 131 125 */ 132 126 @SuppressWarnings("unchecked") 133 private static <T> T[] decodeJsonArray(final JsonArray array, final Function<JsonValue, T> decodeValueFunction, final Class<T> clazz) { 127 private static <T> T[] decodeJsonArray(final JsonArray array, final Function<JsonValue, T> decodeValueFunction, 128 final Class<T> clazz) { 134 129 final T[] result; 135 130 if (array == null) { 136 result = 131 result = (T[]) Array.newInstance(clazz, 0); 137 132 } else { 138 133 result = (T[]) Array.newInstance(clazz, array.size()); … … 154 149 * @param key the key, which identifies the desired array inside the `coordinateProperties` object to be converted 155 150 * @param decodeValueFunction a function that converts the {@link JsonValue}s in the JSON array to java objects of the 156 * 151 * desired type 157 152 * @param clazz the {@link Class} object of the desired type, that the entries of the resulting array should have 158 153 * @return the resulting array, when converting the desired entry of the `coordinateProperties`. 159 * 160 * 154 * Never <code>null</code>. If no `coordinateProperties` are set, or if the desired key is not set or is not 155 * an array, then an empty array of the desired type is returned. 161 156 */ 162 157 @SuppressWarnings("unchecked") 163 private static <T> T[] decodeCoordinateProperty( 164 final JsonObject json, final String key, final Function<JsonValue, T> decodeValueFunction, final Class<T> clazz 165 ) { 158 private static <T> T[] decodeCoordinateProperty(final JsonObject json, final String key, 159 final Function<JsonValue, T> decodeValueFunction, final Class<T> clazz) { 166 160 final JsonValue coordinateProperties = json == null ? null : json.get("coordinateProperties"); 167 161 if (coordinateProperties instanceof JsonObject) { -
applications/editors/josm/plugins/MicrosoftStreetside/test/unit/org/openstreetmap/josm/plugins/streetside/StreetsideAbstractImageTest.java
r36064 r36194 9 9 10 10 class StreetsideAbstractImageTest { 11 @Test12 void testIsModified() {13 StreetsideImage img = new StreetsideImage("key___________________", new LatLon(0, 0), 0);14 assertFalse(img.isModified());15 img.turn(1e-4);16 img.stopMoving();17 assertTrue(img.isModified());18 img.turn(-1e-4);19 img.stopMoving();20 assertFalse(img.isModified());21 img.move(1e-4, 1e-4);22 img.stopMoving();23 assertTrue(img.isModified());24 img.move(-1e-4, -1e-4);25 img.stopMoving();26 assertFalse(img.isModified());27 }11 @Test 12 void testIsModified() { 13 StreetsideImage img = new StreetsideImage("key___________________", new LatLon(0, 0), 0); 14 assertFalse(img.isModified()); 15 img.turn(1e-4); 16 img.stopMoving(); 17 assertTrue(img.isModified()); 18 img.turn(-1e-4); 19 img.stopMoving(); 20 assertFalse(img.isModified()); 21 img.move(1e-4, 1e-4); 22 img.stopMoving(); 23 assertTrue(img.isModified()); 24 img.move(-1e-4, -1e-4); 25 img.stopMoving(); 26 assertFalse(img.isModified()); 27 } 28 28 } -
applications/editors/josm/plugins/MicrosoftStreetside/test/unit/org/openstreetmap/josm/plugins/streetside/StreetsideDataTest.java
r36193 r36194 1 1 // License: GPL. For details, see LICENSE file. 2 2 package org.openstreetmap.josm.plugins.streetside; 3 4 3 5 4 import static org.junit.jupiter.api.Assertions.assertEquals; … … 13 12 import org.junit.jupiter.api.Disabled; 14 13 import org.junit.jupiter.api.Test; 15 import org.junit.jupiter.api.condition.DisabledIf;16 14 import org.openstreetmap.josm.data.coor.LatLon; 17 15 import org.openstreetmap.josm.testutils.annotations.Main; … … 26 24 class StreetsideDataTest { 27 25 28 private StreetsideData data;29 private StreetsideImage img1;30 private StreetsideImage img2;31 private StreetsideImage img3;32 private StreetsideImage img4;26 private StreetsideData data; 27 private StreetsideImage img1; 28 private StreetsideImage img2; 29 private StreetsideImage img3; 30 private StreetsideImage img4; 33 31 34 /**35 * Creates a sample {@link StreetsideData} objects, 4 {@link StreetsideImage}36 * objects and a {@link StreetsideSequence} object.37 */38 @BeforeEach39 public void setUp() {40 img1 = new StreetsideImage("id1__________________", new LatLon(0.1, 0.1), 90);41 img2 = new StreetsideImage("id2__________________", new LatLon(0.2, 0.2), 90);42 img3 = new StreetsideImage("id3__________________", new LatLon(0.3, 0.3), 90);43 img4 = new StreetsideImage("id4__________________", new LatLon(0.4, 0.4), 90);44 final StreetsideSequence seq = new StreetsideSequence();32 /** 33 * Creates a sample {@link StreetsideData} objects, 4 {@link StreetsideImage} 34 * objects and a {@link StreetsideSequence} object. 35 */ 36 @BeforeEach 37 public void setUp() { 38 img1 = new StreetsideImage("id1__________________", new LatLon(0.1, 0.1), 90); 39 img2 = new StreetsideImage("id2__________________", new LatLon(0.2, 0.2), 90); 40 img3 = new StreetsideImage("id3__________________", new LatLon(0.3, 0.3), 90); 41 img4 = new StreetsideImage("id4__________________", new LatLon(0.4, 0.4), 90); 42 final StreetsideSequence seq = new StreetsideSequence(); 45 43 46 seq.add(Arrays.asList(img1, img2, img3, img4));44 seq.add(Arrays.asList(img1, img2, img3, img4)); 47 45 48 data = new StreetsideData();49 data.addAll(new ConcurrentSkipListSet<>(seq.getImages()));50 }46 data = new StreetsideData(); 47 data.addAll(new ConcurrentSkipListSet<>(seq.getImages())); 48 } 51 49 52 /**53 * Tests the addition of new images. If a second image with the same key as54 * another one in the database, the one that is being added should be ignored.55 */56 @Test57 void testAdd() {58 data = new StreetsideData();59 assertEquals(0, data.getImages().size());60 data.add(img1);61 assertEquals(1, data.getImages().size());62 data.add(img1);63 assertEquals(1, data.getImages().size());64 data.addAll(new ConcurrentSkipListSet<>(Arrays.asList(img2, img3)));65 assertEquals(3, data.getImages().size());66 data.addAll(new ConcurrentSkipListSet<>(Arrays.asList(img3, img4)));67 assertEquals(4, data.getImages().size());68 }50 /** 51 * Tests the addition of new images. If a second image with the same key as 52 * another one in the database, the one that is being added should be ignored. 53 */ 54 @Test 55 void testAdd() { 56 data = new StreetsideData(); 57 assertEquals(0, data.getImages().size()); 58 data.add(img1); 59 assertEquals(1, data.getImages().size()); 60 data.add(img1); 61 assertEquals(1, data.getImages().size()); 62 data.addAll(new ConcurrentSkipListSet<>(Arrays.asList(img2, img3))); 63 assertEquals(3, data.getImages().size()); 64 data.addAll(new ConcurrentSkipListSet<>(Arrays.asList(img3, img4))); 65 assertEquals(4, data.getImages().size()); 66 } 69 67 70 /**71 * Test that the size is properly calculated.72 */73 @Test74 void testSize() {75 assertEquals(4, data.getImages().size());76 data.add(new StreetsideImage("id5__________________", new LatLon(0.1, 0.1), 90));77 assertEquals(5, data.getImages().size());78 }68 /** 69 * Test that the size is properly calculated. 70 */ 71 @Test 72 void testSize() { 73 assertEquals(4, data.getImages().size()); 74 data.add(new StreetsideImage("id5__________________", new LatLon(0.1, 0.1), 90)); 75 assertEquals(5, data.getImages().size()); 76 } 79 77 80 /**81 * Test the {@link StreetsideData#setHighlightedImage(StreetsideAbstractImage)}82 * and {@link StreetsideData#getHighlightedImage()} methods.83 */84 @Test85 void testHighlight() {86 data.setHighlightedImage(img1);87 assertEquals(img1, data.getHighlightedImage());78 /** 79 * Test the {@link StreetsideData#setHighlightedImage(StreetsideAbstractImage)} 80 * and {@link StreetsideData#getHighlightedImage()} methods. 81 */ 82 @Test 83 void testHighlight() { 84 data.setHighlightedImage(img1); 85 assertEquals(img1, data.getHighlightedImage()); 88 86 89 data.setHighlightedImage(null);90 assertNull(data.getHighlightedImage());91 }87 data.setHighlightedImage(null); 88 assertNull(data.getHighlightedImage()); 89 } 92 90 93 /**94 * Tests the selection of images.95 */96 @Disabled("The imgs have non-int identifiers while the code expects the identifiers to be int in string form")97 @Test98 void testSelect() {99 data.setSelectedImage(img1);100 assertEquals(img1, data.getSelectedImage());91 /** 92 * Tests the selection of images. 93 */ 94 @Disabled("The imgs have non-int identifiers while the code expects the identifiers to be int in string form") 95 @Test 96 void testSelect() { 97 data.setSelectedImage(img1); 98 assertEquals(img1, data.getSelectedImage()); 101 99 102 data.setSelectedImage(img4);103 assertEquals(img4, data.getSelectedImage());100 data.setSelectedImage(img4); 101 assertEquals(img4, data.getSelectedImage()); 104 102 105 data.setSelectedImage(null);106 assertNull(data.getSelectedImage());107 }103 data.setSelectedImage(null); 104 assertNull(data.getSelectedImage()); 105 } 108 106 109 /**110 * Tests the {@link StreetsideData#selectNext()} and111 * {@link StreetsideData#selectPrevious()} methods.112 */113 @Test114 @Disabled("The imgs have non-int identifiers while the code expects the identifiers to be int in string form")115 void testNextAndPrevious() {116 data.setSelectedImage(img1);107 /** 108 * Tests the {@link StreetsideData#selectNext()} and 109 * {@link StreetsideData#selectPrevious()} methods. 110 */ 111 @Test 112 @Disabled("The imgs have non-int identifiers while the code expects the identifiers to be int in string form") 113 void testNextAndPrevious() { 114 data.setSelectedImage(img1); 117 115 118 data.selectNext();119 assertEquals(img2, data.getSelectedImage());120 data.selectNext();121 assertEquals(img3, data.getSelectedImage());122 data.selectPrevious();123 assertEquals(img2, data.getSelectedImage());116 data.selectNext(); 117 assertEquals(img2, data.getSelectedImage()); 118 data.selectNext(); 119 assertEquals(img3, data.getSelectedImage()); 120 data.selectPrevious(); 121 assertEquals(img2, data.getSelectedImage()); 124 122 125 data.setSelectedImage(null);126 }123 data.setSelectedImage(null); 124 } 127 125 128 @Disabled("Someone decided to not throw an IllegalStateException. No clue why.")129 @Test130 void testNextOfNullImg() {131 data.setSelectedImage(null);132 assertThrows(IllegalStateException.class, data::selectNext);133 }126 @Disabled("Someone decided to not throw an IllegalStateException. No clue why.") 127 @Test 128 void testNextOfNullImg() { 129 data.setSelectedImage(null); 130 assertThrows(IllegalStateException.class, data::selectNext); 131 } 134 132 135 @Disabled("Someone decided to not throw an IllegalStateException. No clue why.")136 @Test137 void testPreviousOfNullImg() {138 data.setSelectedImage(null);139 assertThrows(IllegalStateException.class, data::selectPrevious);140 }133 @Disabled("Someone decided to not throw an IllegalStateException. No clue why.") 134 @Test 135 void testPreviousOfNullImg() { 136 data.setSelectedImage(null); 137 assertThrows(IllegalStateException.class, data::selectPrevious); 138 } 141 139 142 /**143 * Test the multiselection of images. When a new image is selected, the144 * multiselected List should reset.145 */146 @Disabled("The imgs have non-int identifiers while the code expects the identifiers to be int in string form")147 @Test148 void testMultiSelect() {149 assertEquals(0, data.getMultiSelectedImages().size());150 data.setSelectedImage(img1);151 assertEquals(1, data.getMultiSelectedImages().size());152 data.addMultiSelectedImage(img2);153 assertEquals(2, data.getMultiSelectedImages().size());154 data.setSelectedImage(img1);155 assertEquals(1, data.getMultiSelectedImages().size());156 }140 /** 141 * Test the multiselection of images. When a new image is selected, the 142 * multiselected List should reset. 143 */ 144 @Disabled("The imgs have non-int identifiers while the code expects the identifiers to be int in string form") 145 @Test 146 void testMultiSelect() { 147 assertEquals(0, data.getMultiSelectedImages().size()); 148 data.setSelectedImage(img1); 149 assertEquals(1, data.getMultiSelectedImages().size()); 150 data.addMultiSelectedImage(img2); 151 assertEquals(2, data.getMultiSelectedImages().size()); 152 data.setSelectedImage(img1); 153 assertEquals(1, data.getMultiSelectedImages().size()); 154 } 157 155 } -
applications/editors/josm/plugins/MicrosoftStreetside/test/unit/org/openstreetmap/josm/plugins/streetside/StreetsideLayerTest.java
r36193 r36194 24 24 @Projection 25 25 class StreetsideLayerTest { 26 private static Layer getDummyLayer() { 27 return ImageryLayer.create(new ImageryInfo("dummy", "https://example.org")); 28 } 29 30 @Test 31 void testGetIcon() { 32 assertNotNull(StreetsideLayer.getInstance().getIcon()); 33 } 34 35 @Test 36 void testIsMergable() { 37 assertFalse(StreetsideLayer.getInstance().isMergable(getDummyLayer())); 38 } 39 40 @Test 41 void testMergeFrom() { 42 StreetsideLayer layer = StreetsideLayer.getInstance(); 43 Layer dummyLayer = getDummyLayer(); 44 assertThrows(UnsupportedOperationException.class, () -> layer.mergeFrom(dummyLayer)); 45 } 46 47 @Test 48 void testSetVisible() { 49 StreetsideLayer.getInstance().getData().add(new StreetsideImage(CubemapUtils.TEST_IMAGE_ID, new LatLon(0.0, 0.0), 0.0)); 50 StreetsideLayer.getInstance().getData().add(new StreetsideImage(CubemapUtils.TEST_IMAGE_ID, new LatLon(0.0, 0.0), 0.0)); 51 StreetsideImage invisibleImage = new StreetsideImage(CubemapUtils.TEST_IMAGE_ID, new LatLon(0.0, 0.0), 0.0); 52 invisibleImage.setVisible(false); 53 StreetsideLayer.getInstance().getData().add(invisibleImage); 54 55 StreetsideLayer.getInstance().setVisible(false); 56 for (StreetsideAbstractImage img : StreetsideLayer.getInstance().getData().getImages()) { 57 assertFalse(img.isVisible()); 26 private static Layer getDummyLayer() { 27 return ImageryLayer.create(new ImageryInfo("dummy", "https://example.org")); 58 28 } 59 29 30 @Test 31 void testGetIcon() { 32 assertNotNull(StreetsideLayer.getInstance().getIcon()); 33 } 60 34 61 StreetsideLayer.getInstance().setVisible(true);62 for (StreetsideAbstractImage img : StreetsideLayer.getInstance().getData().getImages()) {63 assertTrue(img.isVisible());35 @Test 36 void testIsMergable() { 37 assertFalse(StreetsideLayer.getInstance().isMergable(getDummyLayer())); 64 38 } 65 }66 39 67 @Test68 void testGetInfoComponent() {69 Object comp = StreetsideLayer.getInstance().getInfoComponent();70 assertInstanceOf(String.class, comp);71 assertTrue(((String) comp).length() >= 9);72 }40 @Test 41 void testMergeFrom() { 42 StreetsideLayer layer = StreetsideLayer.getInstance(); 43 Layer dummyLayer = getDummyLayer(); 44 assertThrows(UnsupportedOperationException.class, () -> layer.mergeFrom(dummyLayer)); 45 } 73 46 74 @DisabledIf(value = "java.awt.GraphicsEnvironment#isHeadless", disabledReason = "Listener for destruction is only registered in non-headless environments") 75 @Test 76 void testClearInstance() { 77 StreetsideLayer.getInstance(); 78 assertTrue(StreetsideLayer.hasInstance()); 79 JOSMTestRules.cleanLayerEnvironment(); 80 assertFalse(StreetsideLayer.hasInstance()); 81 StreetsideLayer.getInstance(); 82 assertTrue(StreetsideLayer.hasInstance()); 83 } 47 @Test 48 void testSetVisible() { 49 StreetsideLayer.getInstance().getData() 50 .add(new StreetsideImage(CubemapUtils.TEST_IMAGE_ID, new LatLon(0.0, 0.0), 0.0)); 51 StreetsideLayer.getInstance().getData() 52 .add(new StreetsideImage(CubemapUtils.TEST_IMAGE_ID, new LatLon(0.0, 0.0), 0.0)); 53 StreetsideImage invisibleImage = new StreetsideImage(CubemapUtils.TEST_IMAGE_ID, new LatLon(0.0, 0.0), 0.0); 54 invisibleImage.setVisible(false); 55 StreetsideLayer.getInstance().getData().add(invisibleImage); 56 57 StreetsideLayer.getInstance().setVisible(false); 58 for (StreetsideAbstractImage img : StreetsideLayer.getInstance().getData().getImages()) { 59 assertFalse(img.isVisible()); 60 } 61 62 StreetsideLayer.getInstance().setVisible(true); 63 for (StreetsideAbstractImage img : StreetsideLayer.getInstance().getData().getImages()) { 64 assertTrue(img.isVisible()); 65 } 66 } 67 68 @Test 69 void testGetInfoComponent() { 70 Object comp = StreetsideLayer.getInstance().getInfoComponent(); 71 assertInstanceOf(String.class, comp); 72 assertTrue(((String) comp).length() >= 9); 73 } 74 75 @DisabledIf(value = "java.awt.GraphicsEnvironment#isHeadless", disabledReason = "Listener for destruction is only registered in non-headless environments") 76 @Test 77 void testClearInstance() { 78 StreetsideLayer.getInstance(); 79 assertTrue(StreetsideLayer.hasInstance()); 80 JOSMTestRules.cleanLayerEnvironment(); 81 assertFalse(StreetsideLayer.hasInstance()); 82 StreetsideLayer.getInstance(); 83 assertTrue(StreetsideLayer.hasInstance()); 84 } 84 85 } -
applications/editors/josm/plugins/MicrosoftStreetside/test/unit/org/openstreetmap/josm/plugins/streetside/StreetsideSequenceTest.java
r36064 r36194 20 20 class StreetsideSequenceTest { 21 21 22 private final StreetsideImage img1 = new StreetsideImage("key1", new LatLon(0.1, 0.1), 90);23 private final StreetsideImage img2 = new StreetsideImage("key2", new LatLon(0.2, 0.2), 90);24 private final StreetsideImage img3 = new StreetsideImage("key3", new LatLon(0.3, 0.3), 90);25 private final StreetsideImage img4 = new StreetsideImage("key4", new LatLon(0.4, 0.4), 90);26 private final StreetsideImage imgWithoutSeq = new StreetsideImage("key5", new LatLon(0.5, 0.5), 90);27 private final StreetsideSequence seq = new StreetsideSequence();22 private final StreetsideImage img1 = new StreetsideImage("key1", new LatLon(0.1, 0.1), 90); 23 private final StreetsideImage img2 = new StreetsideImage("key2", new LatLon(0.2, 0.2), 90); 24 private final StreetsideImage img3 = new StreetsideImage("key3", new LatLon(0.3, 0.3), 90); 25 private final StreetsideImage img4 = new StreetsideImage("key4", new LatLon(0.4, 0.4), 90); 26 private final StreetsideImage imgWithoutSeq = new StreetsideImage("key5", new LatLon(0.5, 0.5), 90); 27 private final StreetsideSequence seq = new StreetsideSequence(); 28 28 29 /**30 * Creates 4 {@link StreetsideImage} objects and puts them in a31 * {@link StreetsideSequence} object.32 */33 @BeforeEach34 public void setUp() {35 seq.add(Arrays.asList(img1, img2, img3, img4));36 }29 /** 30 * Creates 4 {@link StreetsideImage} objects and puts them in a 31 * {@link StreetsideSequence} object. 32 */ 33 @BeforeEach 34 public void setUp() { 35 seq.add(Arrays.asList(img1, img2, img3, img4)); 36 } 37 37 38 /**39 * Tests the {@link StreetsideSequence#next(StreetsideAbstractImage)} and40 * {@link StreetsideSequence#previous(StreetsideAbstractImage)}.41 */42 @Test43 void testNextAndPrevious() {44 assertEquals(img2, img1.next());45 assertEquals(img1, img2.previous());46 assertEquals(img3, img2.next());47 assertEquals(img2, img3.previous());48 assertEquals(img4, img3.next());49 assertEquals(img3, img4.previous());38 /** 39 * Tests the {@link StreetsideSequence#next(StreetsideAbstractImage)} and 40 * {@link StreetsideSequence#previous(StreetsideAbstractImage)}. 41 */ 42 @Test 43 void testNextAndPrevious() { 44 assertEquals(img2, img1.next()); 45 assertEquals(img1, img2.previous()); 46 assertEquals(img3, img2.next()); 47 assertEquals(img2, img3.previous()); 48 assertEquals(img4, img3.next()); 49 assertEquals(img3, img4.previous()); 50 50 51 assertNull(img4.next()); 52 assertNull(img1.previous()); 51 53 52 assertNull(img4.next());53 assertNull(img1.previous());54 assertNull(imgWithoutSeq.next()); 55 assertNull(imgWithoutSeq.previous()); 54 56 55 assertNull(imgWithoutSeq.next()); 56 assertNull(imgWithoutSeq.previous()); 57 // Test IllegalArgumentException when asking for the next image of an image 58 // that is not in the sequence. 59 assertThrows(IllegalArgumentException.class, () -> seq.next(imgWithoutSeq)); 57 60 58 // Test IllegalArgumentException when asking for the next image of an image 59 // that is not in the sequence. 60 assertThrows(IllegalArgumentException.class, () -> seq.next(imgWithoutSeq)); 61 62 // Test IllegalArgumentException when asking for the previous image of an 63 // image that is not in the sequence. 64 assertThrows(IllegalArgumentException.class, () -> seq.previous(imgWithoutSeq)); 65 } 61 // Test IllegalArgumentException when asking for the previous image of an 62 // image that is not in the sequence. 63 assertThrows(IllegalArgumentException.class, () -> seq.previous(imgWithoutSeq)); 64 } 66 65 } -
applications/editors/josm/plugins/MicrosoftStreetside/test/unit/org/openstreetmap/josm/plugins/streetside/cache/CachesTest.java
r36064 r36194 1 1 // License: GPL. For details, see LICENSE file. 2 2 package org.openstreetmap.josm.plugins.streetside.cache; 3 4 3 5 4 import org.junit.jupiter.api.Test; … … 8 7 class CachesTest { 9 8 10 @Test11 void testUtilityClass() {12 TestUtil.testUtilityClass(Caches.class);13 }9 @Test 10 void testUtilityClass() { 11 TestUtil.testUtilityClass(Caches.class); 12 } 14 13 } -
applications/editors/josm/plugins/MicrosoftStreetside/test/unit/org/openstreetmap/josm/plugins/streetside/cache/StreetsideCacheTest.java
r36064 r36194 13 13 class StreetsideCacheTest { 14 14 15 @Test16 void testCache() {17 StreetsideCache cache = new StreetsideCache("00000", Type.FULL_IMAGE);18 assertNotNull(cache.getUrl());19 assertNotNull(cache.getCacheKey());15 @Test 16 void testCache() { 17 StreetsideCache cache = new StreetsideCache("00000", Type.FULL_IMAGE); 18 assertNotNull(cache.getUrl()); 19 assertNotNull(cache.getCacheKey()); 20 20 21 assertFalse(cache.isObjectLoadable());21 assertFalse(cache.isObjectLoadable()); 22 22 23 cache = new StreetsideCache("00000", Type.THUMBNAIL);24 assertNotNull(cache.getCacheKey());25 assertNotNull(cache.getUrl());23 cache = new StreetsideCache("00000", Type.THUMBNAIL); 24 assertNotNull(cache.getCacheKey()); 25 assertNotNull(cache.getUrl()); 26 26 27 cache = new StreetsideCache(null, null);28 assertNull(cache.getCacheKey());29 assertNull(cache.getUrl());30 }27 cache = new StreetsideCache(null, null); 28 assertNull(cache.getCacheKey()); 29 assertNull(cache.getUrl()); 30 } 31 31 } -
applications/editors/josm/plugins/MicrosoftStreetside/test/unit/org/openstreetmap/josm/plugins/streetside/cubemap/CubemapUtilsTest.java
r36064 r36194 1 // License: GPL. For details, see LICENSE file. 1 2 package org.openstreetmap.josm.plugins.streetside.cubemap; 2 3 3 4 4 import static org.junit.jupiter.api.Assertions.assertEquals; … … 9 9 class CubemapUtilsTest { 10 10 11 @Test12 void testConvertDecimal2Quaternary() {13 final long decimal0 = 680730040L;14 final long decimal1 = 680931568L;15 String res = CubemapUtils.convertDecimal2Quaternary(decimal0);16 assertEquals("220210301312320", res);17 res = CubemapUtils.convertDecimal2Quaternary(decimal1);18 assertEquals("220211203003300", res);19 }11 @Test 12 void testConvertDecimal2Quaternary() { 13 final long decimal0 = 680730040L; 14 final long decimal1 = 680931568L; 15 String res = CubemapUtils.convertDecimal2Quaternary(decimal0); 16 assertEquals("220210301312320", res); 17 res = CubemapUtils.convertDecimal2Quaternary(decimal1); 18 assertEquals("220211203003300", res); 19 } 20 20 21 @Test22 void testConvertQuaternary2Decimal() {23 final String quadKey0 = "220210301312320";24 final String quadKey1 = "220211203003300";25 String res = CubemapUtils.convertQuaternary2Decimal(quadKey0);26 assertEquals("680730040", res);27 res = CubemapUtils.convertQuaternary2Decimal(quadKey1);28 assertEquals("680931568", res);29 }21 @Test 22 void testConvertQuaternary2Decimal() { 23 final String quadKey0 = "220210301312320"; 24 final String quadKey1 = "220211203003300"; 25 String res = CubemapUtils.convertQuaternary2Decimal(quadKey0); 26 assertEquals("680730040", res); 27 res = CubemapUtils.convertQuaternary2Decimal(quadKey1); 28 assertEquals("680931568", res); 29 } 30 30 31 @Disabled32 @Test33 void testGetFaceNumberForCount() {34 String faceNrFront = CubemapUtils.getFaceNumberForCount(0);35 String faceNrRight = CubemapUtils.getFaceNumberForCount(1);36 String faceNrBack = CubemapUtils.getFaceNumberForCount(2);37 String faceNrLeft = CubemapUtils.getFaceNumberForCount(3);38 String faceNrUp = CubemapUtils.getFaceNumberForCount(4);39 String faceNrDown = CubemapUtils.getFaceNumberForCount(5);40 assertEquals(faceNrFront, "01");41 assertEquals(faceNrRight, "02");42 assertEquals(faceNrBack, "03");43 assertEquals(faceNrLeft, "10");44 assertEquals(faceNrUp, "11");45 assertEquals(faceNrDown, "12");46 }31 @Disabled 32 @Test 33 void testGetFaceNumberForCount() { 34 String faceNrFront = CubemapUtils.getFaceNumberForCount(0); 35 String faceNrRight = CubemapUtils.getFaceNumberForCount(1); 36 String faceNrBack = CubemapUtils.getFaceNumberForCount(2); 37 String faceNrLeft = CubemapUtils.getFaceNumberForCount(3); 38 String faceNrUp = CubemapUtils.getFaceNumberForCount(4); 39 String faceNrDown = CubemapUtils.getFaceNumberForCount(5); 40 assertEquals(faceNrFront, "01"); 41 assertEquals(faceNrRight, "02"); 42 assertEquals(faceNrBack, "03"); 43 assertEquals(faceNrLeft, "10"); 44 assertEquals(faceNrUp, "11"); 45 assertEquals(faceNrDown, "12"); 46 } 47 47 48 @Disabled49 @Test50 void testGetCount4FaceNumber() {51 int count4Front = CubemapUtils.getCount4FaceNumber("01");52 int count4Right = CubemapUtils.getCount4FaceNumber("02");53 int count4Back = CubemapUtils.getCount4FaceNumber("03");54 int count4Left = CubemapUtils.getCount4FaceNumber("10");55 int count4Up = CubemapUtils.getCount4FaceNumber("11");56 int count4Down = CubemapUtils.getCount4FaceNumber("12");57 assertEquals(count4Front, 0);58 assertEquals(count4Right, 1);59 assertEquals(count4Back, 2);60 assertEquals(count4Left, 3);61 assertEquals(count4Up, 4);62 assertEquals(count4Down, 5);63 }48 @Disabled 49 @Test 50 void testGetCount4FaceNumber() { 51 int count4Front = CubemapUtils.getCount4FaceNumber("01"); 52 int count4Right = CubemapUtils.getCount4FaceNumber("02"); 53 int count4Back = CubemapUtils.getCount4FaceNumber("03"); 54 int count4Left = CubemapUtils.getCount4FaceNumber("10"); 55 int count4Up = CubemapUtils.getCount4FaceNumber("11"); 56 int count4Down = CubemapUtils.getCount4FaceNumber("12"); 57 assertEquals(count4Front, 0); 58 assertEquals(count4Right, 1); 59 assertEquals(count4Back, 2); 60 assertEquals(count4Left, 3); 61 assertEquals(count4Up, 4); 62 assertEquals(count4Down, 5); 63 } 64 64 65 @Test66 void testConvertDoubleCountNrto16TileNr() {67 String x0y0 = CubemapUtils.convertDoubleCountNrto16TileNr("00");68 String x0y1 = CubemapUtils.convertDoubleCountNrto16TileNr("01");69 String x0y2 = CubemapUtils.convertDoubleCountNrto16TileNr("02");70 String x0y3 = CubemapUtils.convertDoubleCountNrto16TileNr("03");71 String x1y0 = CubemapUtils.convertDoubleCountNrto16TileNr("10");72 String x1y1 = CubemapUtils.convertDoubleCountNrto16TileNr("11");73 String x1y2 = CubemapUtils.convertDoubleCountNrto16TileNr("12");74 String x1y3 = CubemapUtils.convertDoubleCountNrto16TileNr("13");75 String x2y0 = CubemapUtils.convertDoubleCountNrto16TileNr("20");76 String x2y1 = CubemapUtils.convertDoubleCountNrto16TileNr("21");77 String x2y2 = CubemapUtils.convertDoubleCountNrto16TileNr("22");78 String x2y3 = CubemapUtils.convertDoubleCountNrto16TileNr("23");79 String x3y0 = CubemapUtils.convertDoubleCountNrto16TileNr("30");80 String x3y1 = CubemapUtils.convertDoubleCountNrto16TileNr("31");81 String x3y2 = CubemapUtils.convertDoubleCountNrto16TileNr("32");82 String x3y3 = CubemapUtils.convertDoubleCountNrto16TileNr("33");65 @Test 66 void testConvertDoubleCountNrto16TileNr() { 67 String x0y0 = CubemapUtils.convertDoubleCountNrto16TileNr("00"); 68 String x0y1 = CubemapUtils.convertDoubleCountNrto16TileNr("01"); 69 String x0y2 = CubemapUtils.convertDoubleCountNrto16TileNr("02"); 70 String x0y3 = CubemapUtils.convertDoubleCountNrto16TileNr("03"); 71 String x1y0 = CubemapUtils.convertDoubleCountNrto16TileNr("10"); 72 String x1y1 = CubemapUtils.convertDoubleCountNrto16TileNr("11"); 73 String x1y2 = CubemapUtils.convertDoubleCountNrto16TileNr("12"); 74 String x1y3 = CubemapUtils.convertDoubleCountNrto16TileNr("13"); 75 String x2y0 = CubemapUtils.convertDoubleCountNrto16TileNr("20"); 76 String x2y1 = CubemapUtils.convertDoubleCountNrto16TileNr("21"); 77 String x2y2 = CubemapUtils.convertDoubleCountNrto16TileNr("22"); 78 String x2y3 = CubemapUtils.convertDoubleCountNrto16TileNr("23"); 79 String x3y0 = CubemapUtils.convertDoubleCountNrto16TileNr("30"); 80 String x3y1 = CubemapUtils.convertDoubleCountNrto16TileNr("31"); 81 String x3y2 = CubemapUtils.convertDoubleCountNrto16TileNr("32"); 82 String x3y3 = CubemapUtils.convertDoubleCountNrto16TileNr("33"); 83 83 84 assertEquals(x0y0, "00");85 assertEquals(x0y1, "01");86 assertEquals(x0y2, "10");87 assertEquals(x0y3, "11");88 assertEquals(x1y0, "02");89 assertEquals(x1y1, "03");90 assertEquals(x1y2, "12");91 assertEquals(x1y3, "13");92 assertEquals(x2y0, "20");93 assertEquals(x2y1, "21");94 assertEquals(x2y2, "30");95 assertEquals(x2y3, "31");96 assertEquals(x3y0, "22");97 assertEquals(x3y1, "23");98 assertEquals(x3y2, "32");99 assertEquals(x3y3, "33");100 }84 assertEquals(x0y0, "00"); 85 assertEquals(x0y1, "01"); 86 assertEquals(x0y2, "10"); 87 assertEquals(x0y3, "11"); 88 assertEquals(x1y0, "02"); 89 assertEquals(x1y1, "03"); 90 assertEquals(x1y2, "12"); 91 assertEquals(x1y3, "13"); 92 assertEquals(x2y0, "20"); 93 assertEquals(x2y1, "21"); 94 assertEquals(x2y2, "30"); 95 assertEquals(x2y3, "31"); 96 assertEquals(x3y0, "22"); 97 assertEquals(x3y1, "23"); 98 assertEquals(x3y2, "32"); 99 assertEquals(x3y3, "33"); 100 } 101 101 } -
applications/editors/josm/plugins/MicrosoftStreetside/test/unit/org/openstreetmap/josm/plugins/streetside/cubemap/TileDownloadingTaskTest.java
r36064 r36194 1 // License: GPL. For details, see LICENSE file. 1 2 package org.openstreetmap.josm.plugins.streetside.cubemap; 2 3 3 4 4 import static org.junit.jupiter.api.Assertions.assertEquals; … … 17 17 class TileDownloadingTaskTest { 18 18 19 @Test20 final void testCall() throws InterruptedException {21 ExecutorService pool = Executors.newFixedThreadPool(1);22 List<Callable<List<String>>> tasks = new ArrayList<>(1);23 tasks.add(new TileDownloadingTask("2202112030033001233"));24 List<Future<List<String>>> results = pool.invokeAll(tasks);25 assertEquals(results.get(0), "2202112030033001233");26 }19 @Test 20 final void testCall() throws InterruptedException { 21 ExecutorService pool = Executors.newFixedThreadPool(1); 22 List<Callable<List<String>>> tasks = new ArrayList<>(1); 23 tasks.add(new TileDownloadingTask("2202112030033001233")); 24 List<Future<List<String>>> results = pool.invokeAll(tasks); 25 assertEquals(results.get(0), "2202112030033001233"); 26 } 27 27 } -
applications/editors/josm/plugins/MicrosoftStreetside/test/unit/org/openstreetmap/josm/plugins/streetside/gui/ImageDisplayTest.java
r36064 r36194 20 20 class ImageDisplayTest { 21 21 22 private static final BufferedImage DUMMY_IMAGE = new BufferedImage(1, 1, BufferedImage.TYPE_INT_RGB);22 private static final BufferedImage DUMMY_IMAGE = new BufferedImage(1, 1, BufferedImage.TYPE_INT_RGB); 23 23 24 @Test25 void testImagePersistence() {26 StreetsideImageDisplay display = new StreetsideImageDisplay();27 display.setImage(DUMMY_IMAGE, null);28 assertEquals(DUMMY_IMAGE, display.getImage());29 }24 @Test 25 void testImagePersistence() { 26 StreetsideImageDisplay display = new StreetsideImageDisplay(); 27 display.setImage(DUMMY_IMAGE, null); 28 assertEquals(DUMMY_IMAGE, display.getImage()); 29 } 30 30 31 /**32 * This test does not check if the scroll events result in the correct changes in the {@link StreetsideImageDisplay},33 * it only checks if the tested method runs through.34 */31 /** 32 * This test does not check if the scroll events result in the correct changes in the {@link StreetsideImageDisplay}, 33 * it only checks if the tested method runs through. 34 */ 35 35 36 @Test 37 void testMouseWheelMoved() { 38 if (GraphicsEnvironment.isHeadless()) { 39 return; 36 @Test 37 void testMouseWheelMoved() { 38 if (GraphicsEnvironment.isHeadless()) { 39 return; 40 } 41 StreetsideImageDisplay display = new StreetsideImageDisplay(); 42 final MouseWheelEvent dummyScroll = new MouseWheelEvent(display, 42, System.currentTimeMillis(), 0, 0, 0, 0, 43 false, MouseWheelEvent.WHEEL_UNIT_SCROLL, 1, 3); 44 display.getMouseWheelListeners()[0].mouseWheelMoved(dummyScroll); 45 46 display.setImage(DUMMY_IMAGE, null); 47 48 display.getMouseWheelListeners()[0].mouseWheelMoved(dummyScroll); 49 50 // This is necessary to make the size of the component > 0. If you know a more elegant solution, feel free to change it. 51 JFrame frame = new JFrame(); 52 frame.setSize(42, 42); 53 frame.getContentPane().add(display); 54 frame.pack(); 55 56 display.getMouseWheelListeners()[0].mouseWheelMoved(dummyScroll); 40 57 } 41 StreetsideImageDisplay display = new StreetsideImageDisplay();42 final MouseWheelEvent dummyScroll = new MouseWheelEvent(display, 42, System.currentTimeMillis(), 0, 0, 0, 0, false, MouseWheelEvent.WHEEL_UNIT_SCROLL, 1, 3);43 display.getMouseWheelListeners()[0].mouseWheelMoved(dummyScroll);44 58 45 display.setImage(DUMMY_IMAGE, null); 59 /** 60 * This test does not check if the scroll events result in the correct changes in the {@link StreetsideImageDisplay}, 61 * it only checks if the tested method runs through. 62 */ 63 @Test 64 void testMouseClicked() { 65 if (GraphicsEnvironment.isHeadless()) { 66 return; 67 } 68 for (int button = 1; button <= 3; button++) { 69 StreetsideImageDisplay display = new StreetsideImageDisplay(); 70 final MouseEvent dummyClick = new MouseEvent(display, 42, System.currentTimeMillis(), 0, 0, 0, 1, false, 71 button); 72 display.getMouseListeners()[0].mouseClicked(dummyClick); 46 73 47 display.getMouseWheelListeners()[0].mouseWheelMoved(dummyScroll);74 display.setImage(DUMMY_IMAGE, null); 48 75 49 // This is necessary to make the size of the component > 0. If you know a more elegant solution, feel free to change it. 50 JFrame frame = new JFrame(); 51 frame.setSize(42, 42); 52 frame.getContentPane().add(display); 53 frame.pack(); 76 display.getMouseListeners()[0].mouseClicked(dummyClick); 54 77 55 display.getMouseWheelListeners()[0].mouseWheelMoved(dummyScroll); 56 } 78 // This is necessary to make the size of the component > 0. If you know a more elegant solution, feel free to change it. 79 JFrame frame = new JFrame(); 80 frame.setSize(42, 42); 81 frame.getContentPane().add(display); 82 frame.pack(); 57 83 58 /** 59 * This test does not check if the scroll events result in the correct changes in the {@link StreetsideImageDisplay}, 60 * it only checks if the tested method runs through. 61 */ 62 @Test 63 void testMouseClicked() { 64 if (GraphicsEnvironment.isHeadless()) { 65 return; 84 display.getMouseListeners()[0].mouseClicked(dummyClick); 85 } 66 86 } 67 for (int button = 1; button <= 3; button++) {68 StreetsideImageDisplay display = new StreetsideImageDisplay();69 final MouseEvent dummyClick = new MouseEvent(display, 42, System.currentTimeMillis(), 0, 0, 0, 1, false, button);70 display.getMouseListeners()[0].mouseClicked(dummyClick);71 72 display.setImage(DUMMY_IMAGE, null);73 74 display.getMouseListeners()[0].mouseClicked(dummyClick);75 76 // This is necessary to make the size of the component > 0. If you know a more elegant solution, feel free to change it.77 JFrame frame = new JFrame();78 frame.setSize(42, 42);79 frame.getContentPane().add(display);80 frame.pack();81 82 display.getMouseListeners()[0].mouseClicked(dummyClick);83 }84 }85 87 } -
applications/editors/josm/plugins/MicrosoftStreetside/test/unit/org/openstreetmap/josm/plugins/streetside/gui/StreetsidePreferenceSettingTest.java
r36064 r36194 1 // License: GPL. For details, see LICENSE file. 1 2 package org.openstreetmap.josm.plugins.streetside.gui; 2 3 … … 22 23 @Disabled 23 24 class StreetsidePreferenceSettingTest { 24 // TODO: repair broken unit test from Mapillary 25 @Test 26 void testAddGui() { 27 if (GraphicsEnvironment.isHeadless()) { 28 return; 25 // TODO: repair broken unit test from Mapillary 26 @Test 27 void testAddGui() { 28 if (GraphicsEnvironment.isHeadless()) { 29 return; 30 } 31 PreferenceTabbedPane tabs = new PreferenceTabbedPane(); 32 tabs.buildGui(); 33 int displayTabs = tabs.getDisplayPreference().getTabPane().getTabCount(); 34 StreetsidePreferenceSetting setting = new StreetsidePreferenceSetting(); 35 setting.addGui(tabs); 36 assertEquals(displayTabs + 1, tabs.getDisplayPreference().getTabPane().getTabCount()); 37 assertEquals(tabs.getDisplayPreference(), setting.getTabPreferenceSetting(tabs)); 29 38 } 30 PreferenceTabbedPane tabs = new PreferenceTabbedPane();31 tabs.buildGui();32 int displayTabs = tabs.getDisplayPreference().getTabPane().getTabCount();33 StreetsidePreferenceSetting setting = new StreetsidePreferenceSetting();34 setting.addGui(tabs);35 assertEquals(displayTabs + 1, tabs.getDisplayPreference().getTabPane().getTabCount());36 assertEquals(tabs.getDisplayPreference(), setting.getTabPreferenceSetting(tabs));37 }38 39 39 @Test40 void testIsExpert() {41 Assertions.assertFalse(new StreetsidePreferenceSetting().isExpert());42 }40 @Test 41 void testIsExpert() { 42 Assertions.assertFalse(new StreetsidePreferenceSetting().isExpert()); 43 } 43 44 44 @SuppressWarnings("unchecked")45 @Test46 void testOk() {47 StreetsidePreferenceSetting settings = new StreetsidePreferenceSetting();45 @SuppressWarnings("unchecked") 46 @Test 47 void testOk() { 48 StreetsidePreferenceSetting settings = new StreetsidePreferenceSetting(); 48 49 49 // Initialize the properties with some arbitrary value to make sure they are not unset50 new StringProperty("streetside.display-hour", "default").put("arbitrary");51 new StringProperty("streetside.format-24", "default").put("arbitrary");52 new StringProperty("streetside.move-to-picture", "default").put("arbitrary");53 new StringProperty("streetside.hover-enabled", "default").put("arbitrary");54 new StringProperty("streetside.download-mode", "default").put("arbitrary");55 new StringProperty("streetside.prefetch-image-count", "default").put("arbitrary");50 // Initialize the properties with some arbitrary value to make sure they are not unset 51 new StringProperty("streetside.display-hour", "default").put("arbitrary"); 52 new StringProperty("streetside.format-24", "default").put("arbitrary"); 53 new StringProperty("streetside.move-to-picture", "default").put("arbitrary"); 54 new StringProperty("streetside.hover-enabled", "default").put("arbitrary"); 55 new StringProperty("streetside.download-mode", "default").put("arbitrary"); 56 new StringProperty("streetside.prefetch-image-count", "default").put("arbitrary"); 56 57 57 // Test checkboxes 58 settings.ok(); 59 assertPropertyMatchesCheckboxSelection((JCheckBox) getPrivateFieldValue(settings, "displayHour"), "streetside.display-hour"); 60 assertPropertyMatchesCheckboxSelection((JCheckBox) getPrivateFieldValue(settings, "format24"), "streetside.format-24"); 61 assertPropertyMatchesCheckboxSelection((JCheckBox) getPrivateFieldValue(settings, "moveTo"), "streetside.move-to-picture"); 62 assertPropertyMatchesCheckboxSelection((JCheckBox) getPrivateFieldValue(settings, "hoverEnabled"), "streetside.hover-enabled"); 63 assertEquals(String.valueOf(((SpinnerNumberModel) getPrivateFieldValue(settings, "preFetchSize")).getNumber().intValue()), new StringProperty("streetside.prefetch-image-count", "default").get()); 58 // Test checkboxes 59 settings.ok(); 60 assertPropertyMatchesCheckboxSelection((JCheckBox) getPrivateFieldValue(settings, "displayHour"), 61 "streetside.display-hour"); 62 assertPropertyMatchesCheckboxSelection((JCheckBox) getPrivateFieldValue(settings, "format24"), 63 "streetside.format-24"); 64 assertPropertyMatchesCheckboxSelection((JCheckBox) getPrivateFieldValue(settings, "moveTo"), 65 "streetside.move-to-picture"); 66 assertPropertyMatchesCheckboxSelection((JCheckBox) getPrivateFieldValue(settings, "hoverEnabled"), 67 "streetside.hover-enabled"); 68 assertEquals( 69 String.valueOf( 70 ((SpinnerNumberModel) getPrivateFieldValue(settings, "preFetchSize")).getNumber().intValue()), 71 new StringProperty("streetside.prefetch-image-count", "default").get()); 64 72 65 // Toggle state of the checkboxes66 toggleCheckbox((JCheckBox) getPrivateFieldValue(settings, "displayHour"));67 toggleCheckbox((JCheckBox) getPrivateFieldValue(settings, "format24"));68 toggleCheckbox((JCheckBox) getPrivateFieldValue(settings, "moveTo"));69 toggleCheckbox((JCheckBox) getPrivateFieldValue(settings, "hoverEnabled"));70 ((SpinnerNumberModel) getPrivateFieldValue(settings, "preFetchSize")).setValue(73);73 // Toggle state of the checkboxes 74 toggleCheckbox((JCheckBox) getPrivateFieldValue(settings, "displayHour")); 75 toggleCheckbox((JCheckBox) getPrivateFieldValue(settings, "format24")); 76 toggleCheckbox((JCheckBox) getPrivateFieldValue(settings, "moveTo")); 77 toggleCheckbox((JCheckBox) getPrivateFieldValue(settings, "hoverEnabled")); 78 ((SpinnerNumberModel) getPrivateFieldValue(settings, "preFetchSize")).setValue(73); 71 79 72 // Test the second state of the checkboxes 73 settings.ok(); 74 assertPropertyMatchesCheckboxSelection((JCheckBox) getPrivateFieldValue(settings, "displayHour"), "streetside.display-hour"); 75 assertPropertyMatchesCheckboxSelection((JCheckBox) getPrivateFieldValue(settings, "format24"), "streetside.format-24"); 76 assertPropertyMatchesCheckboxSelection((JCheckBox) getPrivateFieldValue(settings, "moveTo"), "streetside.move-to-picture"); 77 assertPropertyMatchesCheckboxSelection((JCheckBox) getPrivateFieldValue(settings, "hoverEnabled"), "streetside.hover-enabled"); 78 assertEquals(String.valueOf(((SpinnerNumberModel) getPrivateFieldValue(settings, "preFetchSize")).getNumber().intValue()), new StringProperty("streetside.prefetch-image-count", "default").get()); 80 // Test the second state of the checkboxes 81 settings.ok(); 82 assertPropertyMatchesCheckboxSelection((JCheckBox) getPrivateFieldValue(settings, "displayHour"), 83 "streetside.display-hour"); 84 assertPropertyMatchesCheckboxSelection((JCheckBox) getPrivateFieldValue(settings, "format24"), 85 "streetside.format-24"); 86 assertPropertyMatchesCheckboxSelection((JCheckBox) getPrivateFieldValue(settings, "moveTo"), 87 "streetside.move-to-picture"); 88 assertPropertyMatchesCheckboxSelection((JCheckBox) getPrivateFieldValue(settings, "hoverEnabled"), 89 "streetside.hover-enabled"); 90 assertEquals( 91 String.valueOf( 92 ((SpinnerNumberModel) getPrivateFieldValue(settings, "preFetchSize")).getNumber().intValue()), 93 new StringProperty("streetside.prefetch-image-count", "default").get()); 79 94 80 // Test combobox 81 for (int i = 0; i < ((JComboBox<String>) getPrivateFieldValue(settings, "downloadModeComboBox")).getItemCount(); i++) { 82 ((JComboBox<String>) getPrivateFieldValue(settings, "downloadModeComboBox")).setSelectedIndex(i); 83 settings.ok(); 84 assertEquals( 85 new StringProperty("streetside.download-mode", "default").get(), 86 DOWNLOAD_MODE.fromLabel( 87 ((JComboBox<String>) getPrivateFieldValue(settings, "downloadModeComboBox")).getSelectedItem().toString() 88 ).getPrefId() 89 ); 95 // Test combobox 96 for (int i = 0; i < ((JComboBox<String>) getPrivateFieldValue(settings, "downloadModeComboBox")) 97 .getItemCount(); i++) { 98 ((JComboBox<String>) getPrivateFieldValue(settings, "downloadModeComboBox")).setSelectedIndex(i); 99 settings.ok(); 100 assertEquals(new StringProperty("streetside.download-mode", "default").get(), 101 DOWNLOAD_MODE.fromLabel(((JComboBox<String>) getPrivateFieldValue(settings, "downloadModeComboBox")) 102 .getSelectedItem().toString()).getPrefId()); 103 } 90 104 } 91 }92 105 93 /**94 * Checks, if a certain {@link BooleanProperty} (identified by the {@code propName} attribute) matches the selected-state of the given {@link JCheckBox}95 * @param cb the {@link JCheckBox}, which should be checked against the {@link BooleanProperty}96 * @param propName the name of the property against which the selected-state of the given {@link JCheckBox} should be checked97 */98 private static void assertPropertyMatchesCheckboxSelection(JCheckBox cb, String propName) {99 assertEquals(cb.isSelected(), new BooleanProperty(propName, !cb.isSelected()).get());100 }106 /** 107 * Checks, if a certain {@link BooleanProperty} (identified by the {@code propName} attribute) matches the selected-state of the given {@link JCheckBox} 108 * @param cb the {@link JCheckBox}, which should be checked against the {@link BooleanProperty} 109 * @param propName the name of the property against which the selected-state of the given {@link JCheckBox} should be checked 110 */ 111 private static void assertPropertyMatchesCheckboxSelection(JCheckBox cb, String propName) { 112 assertEquals(cb.isSelected(), new BooleanProperty(propName, !cb.isSelected()).get()); 113 } 101 114 102 private static void toggleCheckbox(JCheckBox jcb) {103 jcb.setSelected(!jcb.isSelected());104 }115 private static void toggleCheckbox(JCheckBox jcb) { 116 jcb.setSelected(!jcb.isSelected()); 117 } 105 118 106 119 } -
applications/editors/josm/plugins/MicrosoftStreetside/test/unit/org/openstreetmap/josm/plugins/streetside/gui/boilerplate/SelectableLabelTest.java
r36064 r36194 7 7 import org.junit.jupiter.api.Test; 8 8 9 10 9 class SelectableLabelTest { 11 @Test12 void testSelectableLabel() {13 SelectableLabel l1 = new SelectableLabel();14 assertFalse(l1.isEditable());15 SelectableLabel l2 = new SelectableLabel("some text");16 assertTrue(l2.getText().contains("some text"));17 assertFalse(l2.isEditable());18 }10 @Test 11 void testSelectableLabel() { 12 SelectableLabel l1 = new SelectableLabel(); 13 assertFalse(l1.isEditable()); 14 SelectableLabel l2 = new SelectableLabel("some text"); 15 assertTrue(l2.getText().contains("some text")); 16 assertFalse(l2.isEditable()); 17 } 19 18 } -
applications/editors/josm/plugins/MicrosoftStreetside/test/unit/org/openstreetmap/josm/plugins/streetside/history/StreetsideRecordTest.java
r36064 r36194 1 1 // License: GPL. For details, see LICENSE file. 2 2 package org.openstreetmap.josm.plugins.streetside.history; 3 4 3 5 4 import static org.junit.jupiter.api.Assertions.assertEquals; … … 35 34 class StreetsideRecordTest { 36 35 37 private StreetsideRecord record; 38 private StreetsideImage img1; 39 private StreetsideImage img2; 40 private StreetsideImage img3; 41 42 /** 43 * Creates a new {@link StreetsideRecord} object and 3 {@link StreetsideImage} 44 * objects. 45 */ 46 @BeforeEach 47 public void setUp() { 48 record = new StreetsideRecord(); 49 img1 = new StreetsideImage("key1__________________", new LatLon(0.1, 0.1), 0.1); 50 img2 = new StreetsideImage("key2__________________", new LatLon(0.2, 0.2), 0.2); 51 img3 = new StreetsideImage("key3__________________", new LatLon(0.3, 0.3), 0.3); 52 if (StreetsideLayer.hasInstance() && StreetsideLayer.getInstance().getData().getImages().size() >= 1) { 53 StreetsideLayer.getInstance().getData().getImages().clear(); 54 } 55 } 56 57 /** 58 * Test commands in general. 59 */ 60 @Test 61 void testCommand() { 62 StreetsideCommand cmd12 = new CommandMove( 63 new ConcurrentSkipListSet<>(Arrays.asList(img1, img2)), 64 0.1, 0.1); 65 StreetsideCommand cmd23 = new CommandMove( 66 new ConcurrentSkipListSet<>(Arrays.asList(img2, img3)), 67 0.1, 0.1); 68 StreetsideCommand cmd13 = new CommandMove( 69 new ConcurrentSkipListSet<>(Arrays.asList(img1, img3)), 70 0.1, 0.1); 71 StreetsideCommand cmd1 = new CommandMove( 72 new ConcurrentSkipListSet<>(Collections.singletonList(img1)), 0.1, 0.1); 73 StreetsideCommand cmd31 = new CommandMove( 74 new ConcurrentSkipListSet<>(Arrays.asList(img3, img1)), 75 0.2, 0.2); 76 record.addCommand(cmd12); 77 record.addCommand(cmd23); 78 79 assertEquals(1, record.position); 80 assertEquals(2, record.commandList.size()); 81 82 record.undo(); 83 84 assertEquals(0, record.position); 85 assertEquals(2, record.commandList.size()); 86 87 record.addCommand(cmd1); 88 89 assertEquals(1, record.position); 90 91 record.addCommand(cmd13); 92 93 assertEquals(2, record.position); 94 assertEquals(3, record.commandList.size()); 95 96 record.undo(); 97 record.redo(); 98 99 assertEquals(2, record.position); 100 assertEquals(3, record.commandList.size()); 101 102 record.addCommand(cmd31); 103 104 assertEquals(2, record.position); 105 assertEquals(3, record.commandList.size()); 106 107 record.addCommand(cmd1); 108 109 assertEquals(3, record.position); 110 assertEquals(4, record.commandList.size()); 111 } 112 113 /** 114 * Tests {@link CommandMove} class. 115 */ 116 @Test 117 void testCommandMove() { 118 CommandMove cmd1 = new CommandMove( 119 new ConcurrentSkipListSet<>(Arrays.asList(img1, img2)), 120 0.1, 0.1); 121 CommandMove cmd2 = new CommandMove( 122 new ConcurrentSkipListSet<>(Arrays.asList(img1, img2)), 123 0.1, 0.1); 124 125 record.addCommand(cmd1); 126 127 assertEquals(0.1, img1.getMovingLatLon().lat(), 0.01); 128 129 record.undo(); 130 131 assertEquals(0.0, img1.getMovingLatLon().lat(), 0.01); 132 133 record.redo(); 134 135 assertEquals(0.1, img1.getMovingLatLon().lat(), 0.01); 136 137 record.addCommand(cmd2); 138 record.undo(); 139 140 assertEquals(-0.1, img1.getMovingLatLon().lat(), 0.01); 141 142 record.redo(); 143 144 assertEquals(0.1, img1.getMovingLatLon().lat(), 0.01); 145 } 146 147 /** 148 * Tests {@link CommandTurn} class. 149 */ 150 @Test 151 void testCommandTurn() { 152 CommandTurn cmd1 = new CommandTurn( 153 new ConcurrentSkipListSet<>(Arrays.asList(img1, img2)), 154 0.2); 155 CommandTurn cmd2 = new CommandTurn( 156 new ConcurrentSkipListSet<>(Arrays.asList(img1, img2)), 157 0.1); 158 159 record.addCommand(cmd1); 160 record.undo(); 161 162 assertEquals(-0.1, img1.getMovingHe(), 0.01); 163 164 record.redo(); 165 166 assertEquals(0.1, img1.getMovingHe(), 0.01); 167 168 record.addCommand(cmd2); 169 record.undo(); 170 171 assertEquals(-0.2, img1.getMovingHe(), 0.01); 172 173 record.redo(); 174 175 assertEquals(0.1, img1.getMovingHe(), 0.01); 176 } 177 178 /** 179 * Tests {@link CommandJoin} class. 180 */ 181 @Test 182 void testCommandJoinClass() { 183 CommandJoin cmd1 = new CommandJoin(img1, img2); 184 CommandJoin cmd2 = new CommandJoin(img2, img3); 185 186 record.addCommand(cmd1); 187 assertEquals(2, img1.getSequence().getImages().size()); 188 assertEquals(img2, img1.next()); 189 record.undo(); 190 assertEquals(1, img1.getSequence().getImages().size()); 191 record.redo(); 192 record.addCommand(cmd2); 193 assertEquals(3, img1.getSequence().getImages().size()); 194 assertEquals(img3, img1.next().next()); 195 } 196 197 @Test 198 void testCommandJoinNull1() { 199 assertThrows(NullPointerException.class, () -> new CommandJoin(img1, null)); 200 } 201 202 @Test 203 void commandJoinNull2() { 204 assertThrows(NullPointerException.class, () -> new CommandJoin(null, img1)); 205 } 206 207 /** 208 * Tests {@link CommandUnjoin} class. 209 */ 210 @Test 211 void testCommandUnjoinClass() { 212 CommandJoin join1 = new CommandJoin(img1, img2); 213 CommandJoin join2 = new CommandJoin(img2, img3); 214 215 CommandUnjoin cmd1 = new CommandUnjoin( 216 Arrays.asList(new StreetsideAbstractImage[]{img1, img2})); 217 CommandUnjoin cmd2 = new CommandUnjoin( 218 Arrays.asList(new StreetsideAbstractImage[]{img2, img3})); 219 220 record.addCommand(join1); 221 record.addCommand(join2); 222 223 record.addCommand(cmd1); 224 assertEquals(1, img1.getSequence().getImages().size()); 225 record.undo(); 226 assertEquals(3, img1.getSequence().getImages().size()); 227 record.redo(); 228 record.addCommand(cmd2); 229 assertEquals(1, img1.getSequence().getImages().size()); 230 assertEquals(1, img2.getSequence().getImages().size()); 231 232 CommandUnjoin command = new CommandUnjoin(Arrays.asList(new StreetsideAbstractImage[]{img1, img2, img3})); 233 assertThrows(IllegalArgumentException.class, () -> record.addCommand(command)); 234 } 36 private StreetsideRecord record; 37 private StreetsideImage img1; 38 private StreetsideImage img2; 39 private StreetsideImage img3; 40 41 /** 42 * Creates a new {@link StreetsideRecord} object and 3 {@link StreetsideImage} 43 * objects. 44 */ 45 @BeforeEach 46 public void setUp() { 47 record = new StreetsideRecord(); 48 img1 = new StreetsideImage("key1__________________", new LatLon(0.1, 0.1), 0.1); 49 img2 = new StreetsideImage("key2__________________", new LatLon(0.2, 0.2), 0.2); 50 img3 = new StreetsideImage("key3__________________", new LatLon(0.3, 0.3), 0.3); 51 if (StreetsideLayer.hasInstance() && StreetsideLayer.getInstance().getData().getImages().size() >= 1) { 52 StreetsideLayer.getInstance().getData().getImages().clear(); 53 } 54 } 55 56 /** 57 * Test commands in general. 58 */ 59 @Test 60 void testCommand() { 61 StreetsideCommand cmd12 = new CommandMove(new ConcurrentSkipListSet<>(Arrays.asList(img1, img2)), 0.1, 0.1); 62 StreetsideCommand cmd23 = new CommandMove(new ConcurrentSkipListSet<>(Arrays.asList(img2, img3)), 0.1, 0.1); 63 StreetsideCommand cmd13 = new CommandMove(new ConcurrentSkipListSet<>(Arrays.asList(img1, img3)), 0.1, 0.1); 64 StreetsideCommand cmd1 = new CommandMove(new ConcurrentSkipListSet<>(Collections.singletonList(img1)), 0.1, 65 0.1); 66 StreetsideCommand cmd31 = new CommandMove(new ConcurrentSkipListSet<>(Arrays.asList(img3, img1)), 0.2, 0.2); 67 record.addCommand(cmd12); 68 record.addCommand(cmd23); 69 70 assertEquals(1, record.position); 71 assertEquals(2, record.commandList.size()); 72 73 record.undo(); 74 75 assertEquals(0, record.position); 76 assertEquals(2, record.commandList.size()); 77 78 record.addCommand(cmd1); 79 80 assertEquals(1, record.position); 81 82 record.addCommand(cmd13); 83 84 assertEquals(2, record.position); 85 assertEquals(3, record.commandList.size()); 86 87 record.undo(); 88 record.redo(); 89 90 assertEquals(2, record.position); 91 assertEquals(3, record.commandList.size()); 92 93 record.addCommand(cmd31); 94 95 assertEquals(2, record.position); 96 assertEquals(3, record.commandList.size()); 97 98 record.addCommand(cmd1); 99 100 assertEquals(3, record.position); 101 assertEquals(4, record.commandList.size()); 102 } 103 104 /** 105 * Tests {@link CommandMove} class. 106 */ 107 @Test 108 void testCommandMove() { 109 CommandMove cmd1 = new CommandMove(new ConcurrentSkipListSet<>(Arrays.asList(img1, img2)), 0.1, 0.1); 110 CommandMove cmd2 = new CommandMove(new ConcurrentSkipListSet<>(Arrays.asList(img1, img2)), 0.1, 0.1); 111 112 record.addCommand(cmd1); 113 114 assertEquals(0.1, img1.getMovingLatLon().lat(), 0.01); 115 116 record.undo(); 117 118 assertEquals(0.0, img1.getMovingLatLon().lat(), 0.01); 119 120 record.redo(); 121 122 assertEquals(0.1, img1.getMovingLatLon().lat(), 0.01); 123 124 record.addCommand(cmd2); 125 record.undo(); 126 127 assertEquals(-0.1, img1.getMovingLatLon().lat(), 0.01); 128 129 record.redo(); 130 131 assertEquals(0.1, img1.getMovingLatLon().lat(), 0.01); 132 } 133 134 /** 135 * Tests {@link CommandTurn} class. 136 */ 137 @Test 138 void testCommandTurn() { 139 CommandTurn cmd1 = new CommandTurn(new ConcurrentSkipListSet<>(Arrays.asList(img1, img2)), 0.2); 140 CommandTurn cmd2 = new CommandTurn(new ConcurrentSkipListSet<>(Arrays.asList(img1, img2)), 0.1); 141 142 record.addCommand(cmd1); 143 record.undo(); 144 145 assertEquals(-0.1, img1.getMovingHe(), 0.01); 146 147 record.redo(); 148 149 assertEquals(0.1, img1.getMovingHe(), 0.01); 150 151 record.addCommand(cmd2); 152 record.undo(); 153 154 assertEquals(-0.2, img1.getMovingHe(), 0.01); 155 156 record.redo(); 157 158 assertEquals(0.1, img1.getMovingHe(), 0.01); 159 } 160 161 /** 162 * Tests {@link CommandJoin} class. 163 */ 164 @Test 165 void testCommandJoinClass() { 166 CommandJoin cmd1 = new CommandJoin(img1, img2); 167 CommandJoin cmd2 = new CommandJoin(img2, img3); 168 169 record.addCommand(cmd1); 170 assertEquals(2, img1.getSequence().getImages().size()); 171 assertEquals(img2, img1.next()); 172 record.undo(); 173 assertEquals(1, img1.getSequence().getImages().size()); 174 record.redo(); 175 record.addCommand(cmd2); 176 assertEquals(3, img1.getSequence().getImages().size()); 177 assertEquals(img3, img1.next().next()); 178 } 179 180 @Test 181 void testCommandJoinNull1() { 182 assertThrows(NullPointerException.class, () -> new CommandJoin(img1, null)); 183 } 184 185 @Test 186 void commandJoinNull2() { 187 assertThrows(NullPointerException.class, () -> new CommandJoin(null, img1)); 188 } 189 190 /** 191 * Tests {@link CommandUnjoin} class. 192 */ 193 @Test 194 void testCommandUnjoinClass() { 195 CommandJoin join1 = new CommandJoin(img1, img2); 196 CommandJoin join2 = new CommandJoin(img2, img3); 197 198 CommandUnjoin cmd1 = new CommandUnjoin(Arrays.asList(new StreetsideAbstractImage[] { img1, img2 })); 199 CommandUnjoin cmd2 = new CommandUnjoin(Arrays.asList(new StreetsideAbstractImage[] { img2, img3 })); 200 201 record.addCommand(join1); 202 record.addCommand(join2); 203 204 record.addCommand(cmd1); 205 assertEquals(1, img1.getSequence().getImages().size()); 206 record.undo(); 207 assertEquals(3, img1.getSequence().getImages().size()); 208 record.redo(); 209 record.addCommand(cmd2); 210 assertEquals(1, img1.getSequence().getImages().size()); 211 assertEquals(1, img2.getSequence().getImages().size()); 212 213 CommandUnjoin command = new CommandUnjoin(Arrays.asList(new StreetsideAbstractImage[] { img1, img2, img3 })); 214 assertThrows(IllegalArgumentException.class, () -> record.addCommand(command)); 215 } 235 216 } -
applications/editors/josm/plugins/MicrosoftStreetside/test/unit/org/openstreetmap/josm/plugins/streetside/io/download/SequenceDownloadRunnableTest.java
r36064 r36194 1 1 // License: GPL. For details, see LICENSE file. 2 2 package org.openstreetmap.josm.plugins.streetside.io.download; 3 4 3 5 4 import static org.junit.jupiter.api.Assertions.assertEquals; … … 21 20 class SequenceDownloadRunnableTest { 22 21 23 private static final Function<Bounds, URL> SEARCH_SEQUENCES_URL_GEN = b -> {24 return SequenceDownloadRunnableTest.class.getResource("/api/v3/responses/searchSequences.json");25 };26 private Field urlGenField;22 private static final Function<Bounds, URL> SEARCH_SEQUENCES_URL_GEN = b -> { 23 return SequenceDownloadRunnableTest.class.getResource("/api/v3/responses/searchSequences.json"); 24 }; 25 private Field urlGenField; 27 26 27 @Test 28 void testRun1() throws IllegalArgumentException, IllegalAccessException { 29 testNumberOfDecodedImages(4, SEARCH_SEQUENCES_URL_GEN, new Bounds(7.246497, 16.432955, 7.249027, 16.432976)); 30 } 28 31 29 @Test30 void testRun1() throws IllegalArgumentException, IllegalAccessException {31 testNumberOfDecodedImages(4, SEARCH_SEQUENCES_URL_GEN, new Bounds(7.246497, 16.432955, 7.249027, 16.432976));32 }32 @Test 33 void testRun2() throws IllegalArgumentException, IllegalAccessException { 34 testNumberOfDecodedImages(0, SEARCH_SEQUENCES_URL_GEN, new Bounds(0, 0, 0, 0)); 35 } 33 36 34 @Test 35 void testRun2() throws IllegalArgumentException, IllegalAccessException { 36 testNumberOfDecodedImages(0, SEARCH_SEQUENCES_URL_GEN, new Bounds(0, 0, 0, 0)); 37 } 37 @Test 38 void testRun3() throws IllegalArgumentException, IllegalAccessException { 39 testNumberOfDecodedImages(0, b -> { 40 try { 41 return new URL("https://streetside/nonexistentURL"); 42 } catch (MalformedURLException e) { 43 return null; 44 } 45 }, new Bounds(0, 0, 0, 0)); 46 } 38 47 39 @Test 40 void testRun3() throws IllegalArgumentException, IllegalAccessException { 41 testNumberOfDecodedImages(0, b -> { 42 try { return new URL("https://streetside/nonexistentURL"); } catch (MalformedURLException e) { return null; } 43 }, new Bounds(0, 0, 0, 0)); 44 } 48 @Test 49 void testRun4() throws IllegalArgumentException, IllegalAccessException { 50 StreetsideProperties.CUT_OFF_SEQUENCES_AT_BOUNDS.put(true); 51 testNumberOfDecodedImages(4, SEARCH_SEQUENCES_URL_GEN, new Bounds(7.246497, 16.432955, 7.249027, 16.432976)); 52 } 45 53 46 @Test47 void testRun4() throws IllegalArgumentException, IllegalAccessException {48 StreetsideProperties.CUT_OFF_SEQUENCES_AT_BOUNDS.put(true);49 testNumberOfDecodedImages(4, SEARCH_SEQUENCES_URL_GEN, new Bounds(7.246497, 16.432955, 7.249027, 16.432976));50 }54 @Test 55 void testRun5() throws IllegalArgumentException, IllegalAccessException { 56 StreetsideProperties.CUT_OFF_SEQUENCES_AT_BOUNDS.put(true); 57 testNumberOfDecodedImages(0, SEARCH_SEQUENCES_URL_GEN, new Bounds(0, 0, 0, 0)); 58 } 51 59 52 @Test 53 void testRun5() throws IllegalArgumentException, IllegalAccessException { 54 StreetsideProperties.CUT_OFF_SEQUENCES_AT_BOUNDS.put(true); 55 testNumberOfDecodedImages(0, SEARCH_SEQUENCES_URL_GEN, new Bounds(0, 0, 0, 0)); 56 } 57 58 private void testNumberOfDecodedImages(int expectedNumImgs, Function<Bounds, URL> urlGen, Bounds bounds) 59 throws IllegalArgumentException, IllegalAccessException { 60 SequenceDownloadRunnable r = new SequenceDownloadRunnable(StreetsideLayer.getInstance().getData(), bounds); 61 urlGenField.set(null, urlGen); 62 r.run(); 63 assertEquals(expectedNumImgs, StreetsideLayer.getInstance().getData().getImages().size()); 64 } 60 private void testNumberOfDecodedImages(int expectedNumImgs, Function<Bounds, URL> urlGen, Bounds bounds) 61 throws IllegalArgumentException, IllegalAccessException { 62 SequenceDownloadRunnable r = new SequenceDownloadRunnable(StreetsideLayer.getInstance().getData(), bounds); 63 urlGenField.set(null, urlGen); 64 r.run(); 65 assertEquals(expectedNumImgs, StreetsideLayer.getInstance().getData().getImages().size()); 66 } 65 67 } -
applications/editors/josm/plugins/MicrosoftStreetside/test/unit/org/openstreetmap/josm/plugins/streetside/utils/ImageUtilTest.java
r36064 r36194 1 1 // License: GPL. For details, see LICENSE file. 2 2 package org.openstreetmap.josm.plugins.streetside.utils; 3 4 3 5 4 import static org.junit.jupiter.api.Assertions.assertEquals; … … 11 10 import org.junit.jupiter.api.Test; 12 11 13 14 12 class ImageUtilTest { 15 13 16 @Test17 void testUtilityClass() {18 TestUtil.testUtilityClass(ImageUtil.class);19 }14 @Test 15 void testUtilityClass() { 16 TestUtil.testUtilityClass(ImageUtil.class); 17 } 20 18 21 @Test22 void testScaleImageIcon() {23 ImageIcon largeLandscape = new ImageIcon(new BufferedImage(72, 60, BufferedImage.TYPE_4BYTE_ABGR));24 ImageIcon largePortrait = new ImageIcon(new BufferedImage(56, 88, BufferedImage.TYPE_4BYTE_ABGR));25 ImageIcon smallLandscape = ImageUtil.scaleImageIcon(largeLandscape, 24);26 ImageIcon smallPortrait = ImageUtil.scaleImageIcon(largePortrait, 22);19 @Test 20 void testScaleImageIcon() { 21 ImageIcon largeLandscape = new ImageIcon(new BufferedImage(72, 60, BufferedImage.TYPE_4BYTE_ABGR)); 22 ImageIcon largePortrait = new ImageIcon(new BufferedImage(56, 88, BufferedImage.TYPE_4BYTE_ABGR)); 23 ImageIcon smallLandscape = ImageUtil.scaleImageIcon(largeLandscape, 24); 24 ImageIcon smallPortrait = ImageUtil.scaleImageIcon(largePortrait, 22); 27 25 28 assertEquals(24, smallLandscape.getIconWidth());29 assertEquals(20, smallLandscape.getIconHeight());26 assertEquals(24, smallLandscape.getIconWidth()); 27 assertEquals(20, smallLandscape.getIconHeight()); 30 28 31 assertEquals(22, smallPortrait.getIconHeight());32 assertEquals(14, smallPortrait.getIconWidth());33 }29 assertEquals(22, smallPortrait.getIconHeight()); 30 assertEquals(14, smallPortrait.getIconWidth()); 31 } 34 32 } -
applications/editors/josm/plugins/MicrosoftStreetside/test/unit/org/openstreetmap/josm/plugins/streetside/utils/JsonUtil.java
r36122 r36194 9 9 10 10 public final class JsonUtil { 11 private JsonUtil() {12 // Private constructor to avoid instantiation13 }11 private JsonUtil() { 12 // Private constructor to avoid instantiation 13 } 14 14 15 public static JsonObject string2jsonObject(String s) {16 return Json.createReader(new ByteArrayInputStream(s.getBytes(StandardCharsets.UTF_8))).readObject();17 }15 public static JsonObject string2jsonObject(String s) { 16 return Json.createReader(new ByteArrayInputStream(s.getBytes(StandardCharsets.UTF_8))).readObject(); 17 } 18 18 } -
applications/editors/josm/plugins/MicrosoftStreetside/test/unit/org/openstreetmap/josm/plugins/streetside/utils/PluginStateTest.java
r36064 r36194 1 1 // License: GPL. For details, see LICENSE file. 2 2 package org.openstreetmap.josm.plugins.streetside.utils; 3 4 3 5 4 import static org.junit.jupiter.api.Assertions.assertEquals; … … 21 20 class PluginStateTest { 22 21 23 /**24 * Test the methods related to the download.25 */26 @Test27 void testDownload() {28 assertFalse(PluginState.isDownloading());29 PluginState.startDownload();30 assertTrue(PluginState.isDownloading());31 PluginState.startDownload();32 assertTrue(PluginState.isDownloading());33 PluginState.finishDownload();34 assertTrue(PluginState.isDownloading());35 PluginState.finishDownload();36 assertFalse(PluginState.isDownloading());37 }22 /** 23 * Test the methods related to the download. 24 */ 25 @Test 26 void testDownload() { 27 assertFalse(PluginState.isDownloading()); 28 PluginState.startDownload(); 29 assertTrue(PluginState.isDownloading()); 30 PluginState.startDownload(); 31 assertTrue(PluginState.isDownloading()); 32 PluginState.finishDownload(); 33 assertTrue(PluginState.isDownloading()); 34 PluginState.finishDownload(); 35 assertFalse(PluginState.isDownloading()); 36 } 38 37 39 /** 40 * Tests the methods related to the upload. 41 */ 42 @Test 43 void testUpload() { 44 TestUtils.assumeWorkingJMockit(); 45 JOptionPaneSimpleMocker jopsMocker = new JOptionPaneSimpleMocker(); 46 jopsMocker.getMockResultMap().put( 47 "You have successfully uploaded 2 images to Bing.com", 48 JOptionPane.OK_OPTION 49 ); 50 assertFalse(PluginState.isUploading()); 51 PluginState.addImagesToUpload(2); 52 assertEquals(2, PluginState.getImagesToUpload()); 53 assertEquals(0, PluginState.getImagesUploaded()); 54 assertTrue(PluginState.isUploading()); 55 PluginState.imageUploaded(); 56 assertEquals(1, PluginState.getImagesUploaded()); 57 assertTrue(PluginState.isUploading()); 58 PluginState.imageUploaded(); 59 assertFalse(PluginState.isUploading()); 60 assertEquals(2, PluginState.getImagesToUpload()); 61 assertEquals(2, PluginState.getImagesUploaded()); 62 } 38 /** 39 * Tests the methods related to the upload. 40 */ 41 @Test 42 void testUpload() { 43 TestUtils.assumeWorkingJMockit(); 44 JOptionPaneSimpleMocker jopsMocker = new JOptionPaneSimpleMocker(); 45 jopsMocker.getMockResultMap().put("You have successfully uploaded 2 images to Bing.com", JOptionPane.OK_OPTION); 46 assertFalse(PluginState.isUploading()); 47 PluginState.addImagesToUpload(2); 48 assertEquals(2, PluginState.getImagesToUpload()); 49 assertEquals(0, PluginState.getImagesUploaded()); 50 assertTrue(PluginState.isUploading()); 51 PluginState.imageUploaded(); 52 assertEquals(1, PluginState.getImagesUploaded()); 53 assertTrue(PluginState.isUploading()); 54 PluginState.imageUploaded(); 55 assertFalse(PluginState.isUploading()); 56 assertEquals(2, PluginState.getImagesToUpload()); 57 assertEquals(2, PluginState.getImagesUploaded()); 58 } 63 59 } -
applications/editors/josm/plugins/MicrosoftStreetside/test/unit/org/openstreetmap/josm/plugins/streetside/utils/StreetsideColorSchemeTest.java
r36064 r36194 10 10 class StreetsideColorSchemeTest { 11 11 12 @Test13 void testUtilityClass() {14 TestUtil.testUtilityClass(StreetsideColorScheme.class);15 }12 @Test 13 void testUtilityClass() { 14 TestUtil.testUtilityClass(StreetsideColorScheme.class); 15 } 16 16 17 @Test18 void testStyleAsDefaultPanel() {19 assertDoesNotThrow(() -> StreetsideColorScheme.styleAsDefaultPanel());20 assertDoesNotThrow(() -> StreetsideColorScheme.styleAsDefaultPanel((JComponent[]) null));21 }17 @Test 18 void testStyleAsDefaultPanel() { 19 assertDoesNotThrow(() -> StreetsideColorScheme.styleAsDefaultPanel()); 20 assertDoesNotThrow(() -> StreetsideColorScheme.styleAsDefaultPanel((JComponent[]) null)); 21 } 22 22 } -
applications/editors/josm/plugins/MicrosoftStreetside/test/unit/org/openstreetmap/josm/plugins/streetside/utils/StreetsidePropertiesTest.java
r36064 r36194 5 5 6 6 public class StreetsidePropertiesTest { 7 @Test8 public void testUtilityClass() {9 TestUtil.testUtilityClass(StreetsideProperties.class);10 }7 @Test 8 public void testUtilityClass() { 9 TestUtil.testUtilityClass(StreetsideProperties.class); 10 } 11 11 12 12 } -
applications/editors/josm/plugins/MicrosoftStreetside/test/unit/org/openstreetmap/josm/plugins/streetside/utils/StreetsideURLTest.java
r36064 r36194 16 16 17 17 class StreetsideURLTest { 18 // TODO: replace with Streetside URL @rrh19 private static final String CLIENT_ID_QUERY_PART = "client_id=T1Fzd20xZjdtR0s1VDk5OFNIOXpYdzoxNDYyOGRkYzUyYTFiMzgz";18 // TODO: replace with Streetside URL @rrh 19 private static final String CLIENT_ID_QUERY_PART = "client_id=T1Fzd20xZjdtR0s1VDk5OFNIOXpYdzoxNDYyOGRkYzUyYTFiMzgz"; 20 20 21 public static class APIv3 {21 public static class APIv3 { 22 22 23 /*@Ignore 24 @Test 25 public void testSearchDetections() { 26 assertUrlEquals(StreetsideURL.APIv3.searchDetections(null), "https://a.streetside.com/v3/detections", CLIENT_ID_QUERY_PART); 23 /*@Ignore 24 @Test 25 public void testSearchDetections() { 26 assertUrlEquals(StreetsideURL.APIv3.searchDetections(null), "https://a.streetside.com/v3/detections", CLIENT_ID_QUERY_PART); 27 } 28 29 @Ignore 30 @Test 31 public void testSearchImages() { 32 assertUrlEquals(StreetsideURL.APIv3.searchImages(null), "https://a.streetside.com/v3/images", CLIENT_ID_QUERY_PART); 33 } 34 35 @Ignore 36 @Test 37 public void testSubmitChangeset() throws MalformedURLException { 38 assertEquals( 39 new URL("https://a.streetside.com/v3/changesets?" + CLIENT_ID_QUERY_PART), 40 StreetsideURL.APIv3.submitChangeset() 41 ); 42 }*/ 27 43 } 28 44 29 @Ignore30 45 @Test 31 public void testSearchImages() {32 assertUrlEquals(StreetsideURL.APIv3.searchImages(null), "https://a.streetside.com/v3/images", CLIENT_ID_QUERY_PART);33 }34 35 @Ignore36 @Test37 public void testSubmitChangeset() throws MalformedURLException {38 assertEquals(39 new URL("https://a.streetside.com/v3/changesets?" + CLIENT_ID_QUERY_PART),40 StreetsideURL.APIv3.submitChangeset()41 );42 }*/43 }44 45 46 @Test47 46 void testParseNextFromHeaderValue() throws MalformedURLException { 48 String headerVal = 49 "<https://a.streetside.com/v3/sequences?page=1&per_page=200&client_id=TG1sUUxGQlBiYWx2V05NM0pQNUVMQTo2NTU3NTBiNTk1NzM1Y2U2>; rel=\"first\", " + 50 "<https://a.streetside.com/v3/sequences?page=2&per_page=200&client_id=TG1sUUxGQlBiYWx2V05NM0pQNUVMQTo2NTU3NTBiNTk1NzM1Y2U2>; rel=\"prev\", " + 51 "<https://a.streetside.com/v3/sequences?page=4&per_page=200&client_id=TG1sUUxGQlBiYWx2V05NM0pQNUVMQTo2NTU3NTBiNTk1NzM1Y2U2>; rel=\"next\""; 52 assertEquals(new URL("https://a.streetside.com/v3/sequences?page=4&per_page=200&client_id=TG1sUUxGQlBiYWx2V05NM0pQNUVMQTo2NTU3NTBiNTk1NzM1Y2U2"), StreetsideURL.APIv3.parseNextFromLinkHeaderValue(headerVal)); 47 String headerVal = "<https://a.streetside.com/v3/sequences?page=1&per_page=200&client_id=TG1sUUxGQlBiYWx2V05NM0pQNUVMQTo2NTU3NTBiNTk1NzM1Y2U2>; rel=\"first\", " 48 + "<https://a.streetside.com/v3/sequences?page=2&per_page=200&client_id=TG1sUUxGQlBiYWx2V05NM0pQNUVMQTo2NTU3NTBiNTk1NzM1Y2U2>; rel=\"prev\", " 49 + "<https://a.streetside.com/v3/sequences?page=4&per_page=200&client_id=TG1sUUxGQlBiYWx2V05NM0pQNUVMQTo2NTU3NTBiNTk1NzM1Y2U2>; rel=\"next\""; 50 assertEquals(new URL( 51 "https://a.streetside.com/v3/sequences?page=4&per_page=200&client_id=TG1sUUxGQlBiYWx2V05NM0pQNUVMQTo2NTU3NTBiNTk1NzM1Y2U2"), 52 StreetsideURL.APIv3.parseNextFromLinkHeaderValue(headerVal)); 53 53 } 54 54 55 55 @Test 56 56 void testParseNextFromHeaderValue2() throws MalformedURLException { 57 String headerVal = 58 "<https://urlFirst>; rel=\"first\", " + 59 "rel = \"next\" ; < ; , " + 60 "rel = \"next\" ; <https://urlNext> , " + 61 "<https://urlPrev>; rel=\"prev\""; 62 assertEquals(new URL("https://urlNext"), StreetsideURL.APIv3.parseNextFromLinkHeaderValue(headerVal)); 57 String headerVal = "<https://urlFirst>; rel=\"first\", " + "rel = \"next\" ; < ; , " 58 + "rel = \"next\" ; <https://urlNext> , " + "<https://urlPrev>; rel=\"prev\""; 59 assertEquals(new URL("https://urlNext"), StreetsideURL.APIv3.parseNextFromLinkHeaderValue(headerVal)); 63 60 } 64 61 65 62 @Test 66 63 void testParseNextFromHeaderValueNull() { 67 assertNull(StreetsideURL.APIv3.parseNextFromLinkHeaderValue(null));64 assertNull(StreetsideURL.APIv3.parseNextFromLinkHeaderValue(null)); 68 65 } 69 66 70 67 @Test 71 68 void testParseNextFromHeaderValueMalformed() { 72 assertNull(StreetsideURL.APIv3.parseNextFromLinkHeaderValue("<###>; rel=\"next\", blub"));69 assertNull(StreetsideURL.APIv3.parseNextFromLinkHeaderValue("<###>; rel=\"next\", blub")); 73 70 } 74 71 75 76 /*public static class Cloudfront { 72 /*public static class Cloudfront { 77 73 @Ignore 78 74 @Test 79 75 public void testThumbnail() { 80 76 assertUrlEquals(StreetsideURL.VirtualEarth.streetsideTile("arbitrary_key", true), "https://d1cuyjsrcm0gby.cloudfront.net/arbitrary_key/thumb-2048.jpg"); 81 77 assertUrlEquals(StreetsideURL.VirtualEarth.streetsideTile("arbitrary_key2", false), "https://d1cuyjsrcm0gby.cloudfront.net/arbitrary_key2/thumb-320.jpg"); 82 78 } 83 }*/79 }*/ 84 80 85 @Disabled 86 @Test 87 void testBrowseImageURL() throws MalformedURLException { 88 assertEquals(new URL("https://www.streetside.com/map/im/1234567890123456789012"), StreetsideURL.MainWebsite.browseImage("1234567890123456789012")); 89 } 81 @Disabled 82 @Test 83 void testBrowseImageURL() throws MalformedURLException { 84 assertEquals(new URL("https://www.streetside.com/map/im/1234567890123456789012"), 85 StreetsideURL.MainWebsite.browseImage("1234567890123456789012")); 86 } 90 87 91 @Test92 void testIllegalBrowseImageURL() {93 assertThrows(IllegalArgumentException.class, () -> StreetsideURL.MainWebsite.browseImage(null));94 }88 @Test 89 void testIllegalBrowseImageURL() { 90 assertThrows(IllegalArgumentException.class, () -> StreetsideURL.MainWebsite.browseImage(null)); 91 } 95 92 96 @Disabled97 @Test98 void testConnectURL() {99 /*assertUrlEquals(93 @Disabled 94 @Test 95 void testConnectURL() { 96 /*assertUrlEquals( 100 97 StreetsideURL.MainWebsite.connect("http://redirect-host/ä"), 101 98 "https://www.streetside.com/connect", … … 104 101 "response_type=token", 105 102 "redirect_uri=http%3A%2F%2Fredirect-host%2F%C3%A4" 106 );103 ); 107 104 108 assertUrlEquals(105 assertUrlEquals( 109 106 StreetsideURL.MainWebsite.connect(null), 110 107 "https://www.streetside.com/connect", … … 112 109 "scope=user%3Aread+public%3Aupload+public%3Awrite", 113 110 "response_type=token" 114 );111 ); 115 112 116 assertUrlEquals(113 assertUrlEquals( 117 114 StreetsideURL.MainWebsite.connect(""), 118 115 "https://www.streetside.com/connect", … … 120 117 "scope=user%3Aread+public%3Aupload+public%3Awrite", 121 118 "response_type=token" 122 );*/123 }119 );*/ 120 } 124 121 125 @Disabled126 @Test127 void testUploadSecretsURL() throws MalformedURLException {128 /*assertEquals(122 @Disabled 123 @Test 124 void testUploadSecretsURL() throws MalformedURLException { 125 /*assertEquals( 129 126 new URL("https://a.streetside.com/v2/me/uploads/secrets?"+CLIENT_ID_QUERY_PART), 130 127 StreetsideURL.uploadSecretsURL() 131 );*/132 }128 );*/ 129 } 133 130 134 @Disabled135 @Test136 void testUserURL() throws MalformedURLException {137 /*assertEquals(131 @Disabled 132 @Test 133 void testUserURL() throws MalformedURLException { 134 /*assertEquals( 138 135 new URL("https://a.streetside.com/v3/me?"+CLIENT_ID_QUERY_PART), 139 136 StreetsideURL.APIv3.userURL() 140 );*/141 }137 );*/ 138 } 142 139 143 @Test144 void testString2MalformedURL()145 throws IllegalAccessException, IllegalArgumentException, InvocationTargetException,NoSuchMethodException, SecurityException {146 Method method = StreetsideURL.class.getDeclaredMethod("string2URL", String[].class);147 method.setAccessible(true);148 Assertions.assertNull(method.invoke(null, new Object[]{new String[]{"malformed URL"}})); // this simply invokes string2URL("malformed URL")149 Assertions.assertNull(method.invoke(null, new Object[]{null})); // invokes string2URL(null)150 }140 @Test 141 void testString2MalformedURL() throws IllegalAccessException, IllegalArgumentException, InvocationTargetException, 142 NoSuchMethodException, SecurityException { 143 Method method = StreetsideURL.class.getDeclaredMethod("string2URL", String[].class); 144 method.setAccessible(true); 145 Assertions.assertNull(method.invoke(null, new Object[] { new String[] { "malformed URL" } })); // this simply invokes string2URL("malformed URL") 146 Assertions.assertNull(method.invoke(null, new Object[] { null })); // invokes string2URL(null) 147 } 151 148 152 @Test153 void testUtilityClass() {154 TestUtil.testUtilityClass(StreetsideURL.class);155 TestUtil.testUtilityClass(StreetsideURL.APIv3.class);156 TestUtil.testUtilityClass(StreetsideURL.VirtualEarth.class);157 TestUtil.testUtilityClass(StreetsideURL.MainWebsite.class);158 }149 @Test 150 void testUtilityClass() { 151 TestUtil.testUtilityClass(StreetsideURL.class); 152 TestUtil.testUtilityClass(StreetsideURL.APIv3.class); 153 TestUtil.testUtilityClass(StreetsideURL.VirtualEarth.class); 154 TestUtil.testUtilityClass(StreetsideURL.MainWebsite.class); 155 } 159 156 160 private static void assertUrlEquals(URL actualUrl, String expectedBaseUrl, String... expectedParams) { 161 final String actualUrlString = actualUrl.toString(); 162 assertEquals(expectedBaseUrl, actualUrlString.contains("?") ? actualUrlString.substring(0, actualUrlString.indexOf('?')) : actualUrlString); 163 String[] actualParams = actualUrl.getQuery() == null ? new String[0] : actualUrl.getQuery().split("&"); 164 assertEquals(expectedParams.length, actualParams.length); 165 for (int exIndex = 0; exIndex < expectedParams.length; exIndex++) { 166 boolean parameterIsPresent = false; 167 for (int acIndex = 0; !parameterIsPresent && acIndex < actualParams.length; acIndex++) { 168 parameterIsPresent |= actualParams[acIndex].equals(expectedParams[exIndex]); 169 } 170 Assertions.assertTrue(parameterIsPresent, expectedParams[exIndex] + " was expected in the query string of " + actualUrl.toString() + " but wasn't there."); 157 private static void assertUrlEquals(URL actualUrl, String expectedBaseUrl, String... expectedParams) { 158 final String actualUrlString = actualUrl.toString(); 159 assertEquals(expectedBaseUrl, 160 actualUrlString.contains("?") ? actualUrlString.substring(0, actualUrlString.indexOf('?')) 161 : actualUrlString); 162 String[] actualParams = actualUrl.getQuery() == null ? new String[0] : actualUrl.getQuery().split("&"); 163 assertEquals(expectedParams.length, actualParams.length); 164 for (int exIndex = 0; exIndex < expectedParams.length; exIndex++) { 165 boolean parameterIsPresent = false; 166 for (int acIndex = 0; !parameterIsPresent && acIndex < actualParams.length; acIndex++) { 167 parameterIsPresent |= actualParams[acIndex].equals(expectedParams[exIndex]); 168 } 169 Assertions.assertTrue(parameterIsPresent, expectedParams[exIndex] + " was expected in the query string of " 170 + actualUrl + " but wasn't there."); 171 } 171 172 } 172 }173 173 } -
applications/editors/josm/plugins/MicrosoftStreetside/test/unit/org/openstreetmap/josm/plugins/streetside/utils/StreetsideUtilsTest.java
r36064 r36194 11 11 * Tests the static methods of the class {@link StreetsideUtils} 12 12 * 13 * @author nokutu 13 14 * @see StreetsideUtils 14 * @author nokutu15 *16 15 */ 17 16 class StreetsideUtilsTest { 18 17 19 @Test20 void testUtilityClass() {21 TestUtil.testUtilityClass(StreetsideUtils.class);22 }18 @Test 19 void testUtilityClass() { 20 TestUtil.testUtilityClass(StreetsideUtils.class); 21 } 23 22 24 /**25 * Test {@link StreetsideUtils#degMinSecToDouble(RationalNumber[], String)}26 * method.27 */28 @Test29 void testDegMinSecToDouble() {30 RationalNumber[] num = new RationalNumber[3];31 num[0] = new RationalNumber(1, 1);32 num[1] = new RationalNumber(0, 1);33 num[2] = new RationalNumber(0, 1);34 String ref = GpsTagConstants.GPS_TAG_GPS_LATITUDE_REF_VALUE_NORTH;35 assertEquals(1, StreetsideUtils.degMinSecToDouble(num, ref), 0.01);36 ref = GpsTagConstants.GPS_TAG_GPS_LATITUDE_REF_VALUE_SOUTH;37 assertEquals(-1, StreetsideUtils.degMinSecToDouble(num, ref), 0.01);38 num[0] = new RationalNumber(180, 1);39 assertEquals(-180, StreetsideUtils.degMinSecToDouble(num, ref), 0.01);40 num[0] = new RationalNumber(190, 1);41 assertEquals(170, StreetsideUtils.degMinSecToDouble(num, ref), 0.01);42 }23 /** 24 * Test {@link StreetsideUtils#degMinSecToDouble(RationalNumber[], String)} 25 * method. 26 */ 27 @Test 28 void testDegMinSecToDouble() { 29 RationalNumber[] num = new RationalNumber[3]; 30 num[0] = new RationalNumber(1, 1); 31 num[1] = new RationalNumber(0, 1); 32 num[2] = new RationalNumber(0, 1); 33 String ref = GpsTagConstants.GPS_TAG_GPS_LATITUDE_REF_VALUE_NORTH; 34 assertEquals(1, StreetsideUtils.degMinSecToDouble(num, ref), 0.01); 35 ref = GpsTagConstants.GPS_TAG_GPS_LATITUDE_REF_VALUE_SOUTH; 36 assertEquals(-1, StreetsideUtils.degMinSecToDouble(num, ref), 0.01); 37 num[0] = new RationalNumber(180, 1); 38 assertEquals(-180, StreetsideUtils.degMinSecToDouble(num, ref), 0.01); 39 num[0] = new RationalNumber(190, 1); 40 assertEquals(170, StreetsideUtils.degMinSecToDouble(num, ref), 0.01); 41 } 43 42 } -
applications/editors/josm/plugins/MicrosoftStreetside/test/unit/org/openstreetmap/josm/plugins/streetside/utils/TestUtil.java
r36193 r36194 18 18 public final class TestUtil { 19 19 20 private TestUtil() {21 // Prevent instantiation22 }20 private TestUtil() { 21 // Prevent instantiation 22 } 23 23 24 public static Field getAccessibleField(Class<?> clazz, String fieldName) { 25 try { 26 Field result = clazz.getDeclaredField(fieldName); 27 result.setAccessible(true); 28 Field modifiers = Field.class.getDeclaredField("modifiers"); 29 modifiers.setAccessible(true); 30 modifiers.setInt(result, modifiers.getInt(result) & ~Modifier.FINAL); 31 return result; 32 } catch (NoSuchFieldException | SecurityException | IllegalArgumentException | IllegalAccessException e) { 33 throw new JosmRuntimeException(e); 24 public static Field getAccessibleField(Class<?> clazz, String fieldName) { 25 try { 26 Field result = clazz.getDeclaredField(fieldName); 27 result.setAccessible(true); 28 Field modifiers = Field.class.getDeclaredField("modifiers"); 29 modifiers.setAccessible(true); 30 modifiers.setInt(result, modifiers.getInt(result) & ~Modifier.FINAL); 31 return result; 32 } catch (NoSuchFieldException | SecurityException | IllegalArgumentException | IllegalAccessException e) { 33 throw new JosmRuntimeException(e); 34 } 34 35 } 35 }36 36 37 /** 38 * Helper method for obtaining the value of a private field 39 * @param object the object of which you want the private field 40 * @param name the name of the private field 41 * @return the current value that field has 42 */ 43 public static Object getPrivateFieldValue(Object object, String name) { 44 try { 45 return getAccessibleField(object.getClass(), name).get(object); 46 } catch (IllegalAccessException | SecurityException e) { 47 throw new JosmRuntimeException(e); 37 /** 38 * Helper method for obtaining the value of a private field 39 * @param object the object of which you want the private field 40 * @param name the name of the private field 41 * @return the current value that field has 42 */ 43 public static Object getPrivateFieldValue(Object object, String name) { 44 try { 45 return getAccessibleField(object.getClass(), name).get(object); 46 } catch (IllegalAccessException | SecurityException e) { 47 throw new JosmRuntimeException(e); 48 } 48 49 } 49 }50 50 51 /** 52 * This method tests utility classes for common coding standards (exactly one constructor that's private, 53 * only static methods, …) and fails the current test if one of those standards is not met. 54 * This is inspired by <a href="https://stackoverflow.com/a/10872497">an answer on StackOverflow.com</a> . 55 * @param c the class under test 56 */ 57 public static void testUtilityClass(final Class<?> c) { 58 try { 59 // class must be final 60 assertTrue(Modifier.isFinal(c.getModifiers())); 61 // with exactly one constructor 62 assertEquals(1, c.getDeclaredConstructors().length); 63 final Constructor<?> constructor = c.getDeclaredConstructors()[0]; 64 // constructor has to be private 65 assertTrue(!constructor.isAccessible() && Modifier.isPrivate(constructor.getModifiers())); 66 constructor.setAccessible(true); 67 // Call private constructor for code coverage 68 constructor.newInstance(); 69 for (Method m : c.getMethods()) { 70 // Check if all methods are static 71 assertTrue(m.getDeclaringClass() != c || Modifier.isStatic(m.getModifiers())); 72 } 73 } catch (InstantiationException | IllegalAccessException | IllegalArgumentException | InvocationTargetException e) { 74 throw new JosmRuntimeException(e); 51 /** 52 * This method tests utility classes for common coding standards (exactly one constructor that's private, 53 * only static methods, …) and fails the current test if one of those standards is not met. 54 * This is inspired by <a href="https://stackoverflow.com/a/10872497">an answer on StackOverflow.com</a> . 55 * @param c the class under test 56 */ 57 public static void testUtilityClass(final Class<?> c) { 58 try { 59 // class must be final 60 assertTrue(Modifier.isFinal(c.getModifiers())); 61 // with exactly one constructor 62 assertEquals(1, c.getDeclaredConstructors().length); 63 final Constructor<?> constructor = c.getDeclaredConstructors()[0]; 64 // constructor has to be private 65 assertTrue(!constructor.isAccessible() && Modifier.isPrivate(constructor.getModifiers())); 66 constructor.setAccessible(true); 67 // Call private constructor for code coverage 68 constructor.newInstance(); 69 for (Method m : c.getMethods()) { 70 // Check if all methods are static 71 assertTrue(m.getDeclaringClass() != c || Modifier.isStatic(m.getModifiers())); 72 } 73 } catch (InstantiationException | IllegalAccessException | IllegalArgumentException 74 | InvocationTargetException e) { 75 throw new JosmRuntimeException(e); 76 } 75 77 } 76 }77 78 } -
applications/editors/josm/plugins/MicrosoftStreetside/test/unit/org/openstreetmap/josm/plugins/streetside/utils/api/JsonDecoderTest.java
r36122 r36194 1 1 // License: GPL. For details, see LICENSE file. 2 2 package org.openstreetmap.josm.plugins.streetside.utils.api; 3 4 3 5 4 import static org.junit.jupiter.api.Assertions.assertArrayEquals; … … 18 17 class JsonDecoderTest { 19 18 20 @Test21 void testUtilityClass() {22 TestUtil.testUtilityClass(JsonDecoder.class);23 }19 @Test 20 void testUtilityClass() { 21 TestUtil.testUtilityClass(JsonDecoder.class); 22 } 24 23 25 @Test26 void testDecodeDoublePair() {27 assertArrayEquals(new double[0], JsonDecoder.decodeDoublePair(null));28 }24 @Test 25 void testDecodeDoublePair() { 26 assertArrayEquals(new double[0], JsonDecoder.decodeDoublePair(null)); 27 } 29 28 30 static void assertDecodesToNull(Function<JsonObject, ?> function, String...parts) {31 assertNull(function.apply(32 Json.createReader(new ByteArrayInputStream(String.join(" ", parts).getBytes(StandardCharsets.UTF_8))).readObject()33 ));34 }29 static void assertDecodesToNull(Function<JsonObject, ?> function, String... parts) { 30 assertNull(function.apply( 31 Json.createReader(new ByteArrayInputStream(String.join(" ", parts).getBytes(StandardCharsets.UTF_8))) 32 .readObject())); 33 } 35 34 36 35 } -
applications/editors/josm/plugins/MicrosoftStreetside/test/unit/org/openstreetmap/josm/plugins/streetside/utils/api/JsonSequencesDecoderTest.java
r36122 r36194 29 29 class JsonSequencesDecoderTest { 30 30 31 @Disabled 32 @Test 33 void testDecodeSequences() { 34 Collection<StreetsideSequence> exampleSequences = JsonDecoder.decodeFeatureCollection( 35 Json.createReader(this.getClass().getResourceAsStream("test/data/api/v3/responses/searchSequences.json")).readObject(), 36 JsonSequencesDecoder::decodeSequence 37 ); 38 assertNotNull(exampleSequences); 39 assertEquals(1, exampleSequences.size()); 40 StreetsideSequence seq = exampleSequences.iterator().next(); 41 assertEquals(4, seq.getImages().size()); 31 @Disabled 32 @Test 33 void testDecodeSequences() { 34 Collection<StreetsideSequence> exampleSequences = JsonDecoder.decodeFeatureCollection(Json 35 .createReader(this.getClass().getResourceAsStream("test/data/api/v3/responses/searchSequences.json")) 36 .readObject(), JsonSequencesDecoder::decodeSequence); 37 assertNotNull(exampleSequences); 38 assertEquals(1, exampleSequences.size()); 39 StreetsideSequence seq = exampleSequences.iterator().next(); 40 assertEquals(4, seq.getImages().size()); 42 41 43 assertEquals("LwrHXqFRN_pszCopTKHF_Q", ((StreetsideImage) seq.getImages().get(0)).getId());44 assertEquals("Aufjv2hdCKwg9LySWWVSwg", ((StreetsideImage) seq.getImages().get(1)).getId());45 assertEquals("QEVZ1tp-PmrwtqhSwdW9fQ", ((StreetsideImage) seq.getImages().get(2)).getId());46 assertEquals("G_SIwxNcioYeutZuA8Rurw", ((StreetsideImage) seq.getImages().get(3)).getId());42 assertEquals("LwrHXqFRN_pszCopTKHF_Q", seq.getImages().get(0).getId()); 43 assertEquals("Aufjv2hdCKwg9LySWWVSwg", seq.getImages().get(1).getId()); 44 assertEquals("QEVZ1tp-PmrwtqhSwdW9fQ", seq.getImages().get(2).getId()); 45 assertEquals("G_SIwxNcioYeutZuA8Rurw", seq.getImages().get(3).getId()); 47 46 48 assertEquals(323.0319999999999, seq.getImages().get(0).getHe(), 1e-10);49 assertEquals(320.8918, seq.getImages().get(1).getHe(), 1e-10);50 assertEquals(333.62239999999997, seq.getImages().get(2).getHe(), 1e-10);51 assertEquals(329.94820000000004, seq.getImages().get(3).getHe(), 1e-10);47 assertEquals(323.0319999999999, seq.getImages().get(0).getHe(), 1e-10); 48 assertEquals(320.8918, seq.getImages().get(1).getHe(), 1e-10); 49 assertEquals(333.62239999999997, seq.getImages().get(2).getHe(), 1e-10); 50 assertEquals(329.94820000000004, seq.getImages().get(3).getHe(), 1e-10); 52 51 53 assertEquals(new LatLon(7.246497, 16.432958), seq.getImages().get(0).getLatLon());54 assertEquals(new LatLon(7.246567, 16.432955), seq.getImages().get(1).getLatLon());55 assertEquals(new LatLon(7.248372, 16.432971), seq.getImages().get(2).getLatLon());56 assertEquals(new LatLon(7.249027, 16.432976), seq.getImages().get(3).getLatLon());52 assertEquals(new LatLon(7.246497, 16.432958), seq.getImages().get(0).getLatLon()); 53 assertEquals(new LatLon(7.246567, 16.432955), seq.getImages().get(1).getLatLon()); 54 assertEquals(new LatLon(7.248372, 16.432971), seq.getImages().get(2).getLatLon()); 55 assertEquals(new LatLon(7.249027, 16.432976), seq.getImages().get(3).getLatLon()); 57 56 58 assertEquals(1_457_963_093_860L, seq.getCd()); // 2016-03-14T13:44:53.860 UTC59 }57 assertEquals(1_457_963_093_860L, seq.getCd()); // 2016-03-14T13:44:53.860 UTC 58 } 60 59 61 @Test62 void testDecodeSequencesInvalid() {63 // null input64 assertEquals(0, JsonDecoder.decodeFeatureCollection(null, JsonSequencesDecoder::decodeSequence).size());65 // empty object66 assertNumberOfDecodedSequences(0, "{}");67 // object without type=FeatureCollection68 assertNumberOfDecodedSequences(0, "{\"features\": []}");69 // object with wrong value for the type attribute70 assertNumberOfDecodedSequences(0, "{\"type\": \"SomethingArbitrary\", \"features\": []}");71 // object without features-array72 assertNumberOfDecodedSequences(0, "{\"type\": \"FeatureCollection\"}");73 // object with a value for the features-key, but wrong type (in this case string instead of Array)74 assertNumberOfDecodedSequences(0, "{\"type\": \"FeatureCollection\", \"features\": \"notAnArray\"}");75 }60 @Test 61 void testDecodeSequencesInvalid() { 62 // null input 63 assertEquals(0, JsonDecoder.decodeFeatureCollection(null, JsonSequencesDecoder::decodeSequence).size()); 64 // empty object 65 assertNumberOfDecodedSequences(0, "{}"); 66 // object without type=FeatureCollection 67 assertNumberOfDecodedSequences(0, "{\"features\": []}"); 68 // object with wrong value for the type attribute 69 assertNumberOfDecodedSequences(0, "{\"type\": \"SomethingArbitrary\", \"features\": []}"); 70 // object without features-array 71 assertNumberOfDecodedSequences(0, "{\"type\": \"FeatureCollection\"}"); 72 // object with a value for the features-key, but wrong type (in this case string instead of Array) 73 assertNumberOfDecodedSequences(0, "{\"type\": \"FeatureCollection\", \"features\": \"notAnArray\"}"); 74 } 76 75 77 @Test78 void testDecodeSequencesWithArbitraryObjectAsFeature() {79 assertNumberOfDecodedSequences(0, "{\"type\": \"FeatureCollection\", \"features\": [{}]}");80 }76 @Test 77 void testDecodeSequencesWithArbitraryObjectAsFeature() { 78 assertNumberOfDecodedSequences(0, "{\"type\": \"FeatureCollection\", \"features\": [{}]}"); 79 } 81 80 82 private static void assertNumberOfDecodedSequences(int expectedNumberOfSequences, String jsonString) { 83 assertEquals(expectedNumberOfSequences, JsonDecoder.decodeFeatureCollection( 84 Json.createReader(new ByteArrayInputStream(jsonString.getBytes(StandardCharsets.UTF_8))).readObject(), 85 JsonSequencesDecoder::decodeSequence 86 ).size()); 87 } 81 private static void assertNumberOfDecodedSequences(int expectedNumberOfSequences, String jsonString) { 82 assertEquals(expectedNumberOfSequences, JsonDecoder.decodeFeatureCollection( 83 Json.createReader(new ByteArrayInputStream(jsonString.getBytes(StandardCharsets.UTF_8))).readObject(), 84 JsonSequencesDecoder::decodeSequence).size()); 85 } 88 86 89 @Disabled 90 @Test 91 void testDecodeSequence() { 92 StreetsideSequence exampleSequence = JsonSequencesDecoder.decodeSequence( 93 Json.createReader(this.getClass().getResourceAsStream("/api/v3/responses/sequence.json")).readObject() 94 ); 95 assertEquals("cHBf9e8n0pG8O0ZVQHGFBQ", exampleSequence.getId()); 96 assertEquals(1_457_963_077_206L, exampleSequence.getCd()); // 2016-03-14T13:44:37.206 UTC 97 assertEquals(2, exampleSequence.getImages().size()); 87 @Disabled 88 @Test 89 void testDecodeSequence() { 90 StreetsideSequence exampleSequence = JsonSequencesDecoder.decodeSequence( 91 Json.createReader(this.getClass().getResourceAsStream("/api/v3/responses/sequence.json")).readObject()); 92 assertEquals("cHBf9e8n0pG8O0ZVQHGFBQ", exampleSequence.getId()); 93 assertEquals(1_457_963_077_206L, exampleSequence.getCd()); // 2016-03-14T13:44:37.206 UTC 94 assertEquals(2, exampleSequence.getImages().size()); 98 95 99 assertEquals(new StreetsideImage("76P0YUrlDD_lF6J7Od3yoA", new LatLon(16.43279, 7.246085), 96.71454), exampleSequence.getImages().get(0)); 100 assertEquals(new StreetsideImage("Ap_8E0BwoAqqewhJaEbFyQ", new LatLon(16.432799, 7.246082), 96.47705000000002), exampleSequence.getImages().get(1)); 101 } 96 assertEquals(new StreetsideImage("76P0YUrlDD_lF6J7Od3yoA", new LatLon(16.43279, 7.246085), 96.71454), 97 exampleSequence.getImages().get(0)); 98 assertEquals(new StreetsideImage("Ap_8E0BwoAqqewhJaEbFyQ", new LatLon(16.432799, 7.246082), 96.47705000000002), 99 exampleSequence.getImages().get(1)); 100 } 102 101 103 @Test 104 void testDecodeSequenceInvalid() { 105 // null input 106 Assertions.assertNull(JsonSequencesDecoder.decodeSequence(null)); 107 // `properties` key is not set 108 assertDecodesToNull(JsonSequencesDecoder::decodeSequence, "{\"type\": \"Feature\"}"); 109 // value for the key `key` in the properties is missing 110 assertDecodesToNull(JsonSequencesDecoder::decodeSequence, 111 "{\"type\": \"Feature\", \"properties\": {}}" 112 ); 113 // value for the key `user_key` in the properties is missing 114 assertDecodesToNull( 115 JsonSequencesDecoder::decodeSequence, 116 "{\"type\": \"Feature\", \"properties\": {\"key\": \"someKey\"}}" 117 ); 118 // value for the key `captured_at` in the properties is missing 119 assertDecodesToNull( 120 JsonSequencesDecoder::decodeSequence, 121 "{\"type\": \"Feature\", \"properties\": {\"key\": \"someKey\", \"user_key\": \"arbitraryUserKey\"}}" 122 ); 123 // the date in `captured_at` has an unrecognized format 124 assertDecodesToNull( 125 JsonSequencesDecoder::decodeSequence, 126 "{\"type\": \"Feature\", \"properties\": {\"key\": \"someKey\", \"captured_at\": \"unrecognizedDateFormat\"}}" 127 ); 128 // the `image_key` array and the `cas` array contain unexpected values (in this case `null`) 129 assertDecodesToNull( 130 JsonSequencesDecoder::decodeSequence, 131 "{\"type\": \"Feature\", \"properties\": {\"key\": \"someKey\", \"user_key\": \"arbitraryUserKey\",", 132 "\"captured_at\": \"1970-01-01T00:00:00.000Z\",", 133 "\"coordinateProperties\": {\"cas\": [null, null, null, null, 1.0, 1.0, 1.0],", 134 "\"image_keys\": [null, null, \"key\", \"key\", null, null, \"key\"]}},", 135 "\"geometry\": {\"type\": \"LineString\", \"coordinates\": [null, [1,1], null, [1,1], null, [1,1], null]}}" 136 ); 137 } 102 @Test 103 void testDecodeSequenceInvalid() { 104 // null input 105 Assertions.assertNull(JsonSequencesDecoder.decodeSequence(null)); 106 // `properties` key is not set 107 assertDecodesToNull(JsonSequencesDecoder::decodeSequence, "{\"type\": \"Feature\"}"); 108 // value for the key `key` in the properties is missing 109 assertDecodesToNull(JsonSequencesDecoder::decodeSequence, "{\"type\": \"Feature\", \"properties\": {}}"); 110 // value for the key `user_key` in the properties is missing 111 assertDecodesToNull(JsonSequencesDecoder::decodeSequence, 112 "{\"type\": \"Feature\", \"properties\": {\"key\": \"someKey\"}}"); 113 // value for the key `captured_at` in the properties is missing 114 assertDecodesToNull(JsonSequencesDecoder::decodeSequence, 115 "{\"type\": \"Feature\", \"properties\": {\"key\": \"someKey\", \"user_key\": \"arbitraryUserKey\"}}"); 116 // the date in `captured_at` has an unrecognized format 117 assertDecodesToNull(JsonSequencesDecoder::decodeSequence, 118 "{\"type\": \"Feature\", \"properties\": {\"key\": \"someKey\", \"captured_at\": \"unrecognizedDateFormat\"}}"); 119 // the `image_key` array and the `cas` array contain unexpected values (in this case `null`) 120 assertDecodesToNull(JsonSequencesDecoder::decodeSequence, 121 "{\"type\": \"Feature\", \"properties\": {\"key\": \"someKey\", \"user_key\": \"arbitraryUserKey\",", 122 "\"captured_at\": \"1970-01-01T00:00:00.000Z\",", 123 "\"coordinateProperties\": {\"cas\": [null, null, null, null, 1.0, 1.0, 1.0],", 124 "\"image_keys\": [null, null, \"key\", \"key\", null, null, \"key\"]}},", 125 "\"geometry\": {\"type\": \"LineString\", \"coordinates\": [null, [1,1], null, [1,1], null, [1,1], null]}}"); 126 } 138 127 139 /** 140 * Checks if an empty array is returned, if <code>null</code> is supplied to the method as the array. 141 */ 142 @Test 143 void testDecodeJsonArray() 144 throws NoSuchMethodException, SecurityException, IllegalAccessException, 145 IllegalArgumentException, InvocationTargetException { 146 Method method = JsonSequencesDecoder.class.getDeclaredMethod("decodeJsonArray", JsonArray.class, Function.class, Class.class); 147 method.setAccessible(true); 148 assertEquals(0, ((String[]) method.invoke(null, null, (Function<JsonValue, String>) val -> null, String.class)).length); 149 } 128 /** 129 * Checks if an empty array is returned, if <code>null</code> is supplied to the method as the array. 130 */ 131 @Test 132 void testDecodeJsonArray() throws NoSuchMethodException, SecurityException, IllegalAccessException, 133 IllegalArgumentException, InvocationTargetException { 134 Method method = JsonSequencesDecoder.class.getDeclaredMethod("decodeJsonArray", JsonArray.class, Function.class, 135 Class.class); 136 method.setAccessible(true); 137 assertEquals(0, 138 ((String[]) method.invoke(null, null, (Function<JsonValue, String>) val -> null, String.class)).length); 139 } 150 140 151 @Test 152 void testDecodeCoordinateProperty() throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException { 153 Method decodeCoordinateProperty = JsonSequencesDecoder.class.getDeclaredMethod( 154 "decodeCoordinateProperty", 155 JsonObject.class, 156 String.class, 157 Function.class, 158 Class.class 159 ); 160 decodeCoordinateProperty.setAccessible(true); 141 @Test 142 void testDecodeCoordinateProperty() throws NoSuchMethodException, SecurityException, IllegalAccessException, 143 IllegalArgumentException, InvocationTargetException { 144 Method decodeCoordinateProperty = JsonSequencesDecoder.class.getDeclaredMethod("decodeCoordinateProperty", 145 JsonObject.class, String.class, Function.class, Class.class); 146 decodeCoordinateProperty.setAccessible(true); 161 147 162 assertEquals(0, ((String[]) decodeCoordinateProperty.invoke( 163 null, null, "key", (Function<JsonValue, String>) val -> "string", String.class 164 )).length); 148 assertEquals(0, ((String[]) decodeCoordinateProperty.invoke(null, null, "key", 149 (Function<JsonValue, String>) val -> "string", String.class)).length); 165 150 166 assertEquals(0, ((String[]) decodeCoordinateProperty.invoke( 167 null, JsonUtil.string2jsonObject("{\"coordinateProperties\":{\"key\":0}}"), "key", (Function<JsonValue, String>) val -> "string", String.class 168 )).length); 169 } 151 assertEquals(0, 152 ((String[]) decodeCoordinateProperty.invoke(null, 153 JsonUtil.string2jsonObject("{\"coordinateProperties\":{\"key\":0}}"), "key", 154 (Function<JsonValue, String>) val -> "string", String.class)).length); 155 } 170 156 171 @Test 172 void testDecodeLatLons() 173 throws NoSuchMethodException, SecurityException, IllegalAccessException, 174 IllegalArgumentException, InvocationTargetException { 175 Method decodeLatLons = JsonSequencesDecoder.class.getDeclaredMethod("decodeLatLons", JsonObject.class); 176 decodeLatLons.setAccessible(true); 157 @Test 158 void testDecodeLatLons() throws NoSuchMethodException, SecurityException, IllegalAccessException, 159 IllegalArgumentException, InvocationTargetException { 160 Method decodeLatLons = JsonSequencesDecoder.class.getDeclaredMethod("decodeLatLons", JsonObject.class); 161 decodeLatLons.setAccessible(true); 177 162 178 assertEquals(0, ((LatLon[]) decodeLatLons.invoke(null, (JsonObject) null)).length); 179 assertEquals(0, ((LatLon[]) decodeLatLons.invoke(null, JsonUtil.string2jsonObject("{\"coordinates\":0}"))).length); 180 assertEquals(0, ((LatLon[]) decodeLatLons.invoke(null, JsonUtil.string2jsonObject("{\"coordinates\":[]}"))).length); 163 assertEquals(0, ((LatLon[]) decodeLatLons.invoke(null, (JsonObject) null)).length); 164 assertEquals(0, 165 ((LatLon[]) decodeLatLons.invoke(null, JsonUtil.string2jsonObject("{\"coordinates\":0}"))).length); 166 assertEquals(0, 167 ((LatLon[]) decodeLatLons.invoke(null, JsonUtil.string2jsonObject("{\"coordinates\":[]}"))).length); 181 168 182 assertEquals(0, ((LatLon[]) decodeLatLons.invoke(null, Json.createReader(new ByteArrayInputStream( 183 "{\"type\": \"Feature\", \"coordinates\": []}".getBytes(StandardCharsets.UTF_8) 184 )).readObject())).length); 169 assertEquals(0, 170 ((LatLon[]) decodeLatLons.invoke(null, 171 Json.createReader(new ByteArrayInputStream( 172 "{\"type\": \"Feature\", \"coordinates\": []}".getBytes(StandardCharsets.UTF_8))) 173 .readObject())).length); 185 174 186 LatLon[] example = (LatLon[]) decodeLatLons.invoke(null, Json.createReader(new ByteArrayInputStream( 187 "{\"type\": \"LineString\", \"coordinates\": [ [1,2,3], [\"a\", 2], [1, \"b\"] ]}".getBytes(StandardCharsets.UTF_8) 188 )).readObject()); 189 assertEquals(3, example.length); 190 Assertions.assertNull(example[0]); 191 Assertions.assertNull(example[1]); 192 Assertions.assertNull(example[2]); 193 } 175 LatLon[] example = (LatLon[]) decodeLatLons.invoke(null, 176 Json.createReader(new ByteArrayInputStream( 177 "{\"type\": \"LineString\", \"coordinates\": [ [1,2,3], [\"a\", 2], [1, \"b\"] ]}" 178 .getBytes(StandardCharsets.UTF_8))) 179 .readObject()); 180 assertEquals(3, example.length); 181 Assertions.assertNull(example[0]); 182 Assertions.assertNull(example[1]); 183 Assertions.assertNull(example[2]); 184 } 194 185 195 @Test196 void testUtilityClass() {197 TestUtil.testUtilityClass(JsonSequencesDecoder.class);198 }186 @Test 187 void testUtilityClass() { 188 TestUtil.testUtilityClass(JsonSequencesDecoder.class); 189 } 199 190 200 191 }
Note:
See TracChangeset
for help on using the changeset viewer.