Changeset 36194 in osm for applications


Ignore:
Timestamp:
2023-11-14T23:40:50+01:00 (12 months ago)
Author:
taylor.smock
Message:

Fix loading for newer images

  • Remove jackson dependency
  • Remove log4j dependency
  • Remove bundled resty dependency
  • Fix formatting (2 spaces as per CONTRIBUTING.md, not 4 as the rest of JOSM)
  • Update gradle build
  • Fix some lint issues
Location:
applications/editors/josm/plugins/MicrosoftStreetside
Files:
111 edited

Legend:

Unmodified
Added
Removed
  • applications/editors/josm/plugins/MicrosoftStreetside/GPL-v3.0.md

    r34317 r36194  
    633633        <one line to give the program's name and a brief idea of what it does.>
    634634        Copyright (C) <year>  <name of author>
    635        
     635
    636636        This program is free software: you can redistribute it and/or modify
    637637        it under the terms of the GNU General Public License as published by
    638638        the Free Software Foundation, either version 3 of the License, or
    639639        (at your option) any later version.
    640        
     640
    641641        This program is distributed in the hope that it will be useful,
    642642        but WITHOUT ANY WARRANTY; without even the implied warranty of
    643643        MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    644644        GNU General Public License for more details.
    645        
     645
    646646        You should have received a copy of the GNU General Public License
    647647        along with this program.  If not, see <http://www.gnu.org/licenses/>.
  • applications/editors/josm/plugins/MicrosoftStreetside/build.gradle

    r35779 r36194  
    77  id 'jacoco'
    88  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")
    1111  id("org.kordamp.markdown.convert").version("1.2.0")
    1212  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")
    1616}
    1717
     
    3434
    3535repositories {
    36   jcenter()
    3736  mavenCentral()
    3837  maven {
     
    4241
    4342def versions = [
    44   awaitility: "4.1.0",
    45   jackson: "2.12.4",
     43  awaitility: "4.2.0",
    4644  jmockit: "1.49.a",
    47   junit: "5.7.1",
     45  junit: "5.10.1",
    4846  wiremock: "2.27.2"
    4947]
     
    5351    errorproneJavac("com.google.errorprone:javac:9+181-r4173-1")
    5452  }
    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"
    6053  testRuntimeOnly("org.junit.jupiter:junit-jupiter-engine:${versions.junit}")
    6154  testImplementation("org.junit.jupiter:junit-jupiter-params:${versions.junit}")
  • applications/editors/josm/plugins/MicrosoftStreetside/build.xml

    r36034 r36194  
    1515    <include name="apache-commons.jar"/>
    1616    <include name="apache-http.jar"/>
    17     <include name="jackson.jar"/>
    1817    <include name="javafx-osx.jar" if:set="isMac"/>
    1918    <include name="javafx-unixoid.jar" if:set="isUnix"/>
    2019    <include name="javafx-windows.jar" if:set="isWindows"/>
    21     <include name="log4j.jar"/>
    2220    <include name="utilsplugin2.jar"/>
    2321  </fileset>
  • applications/editors/josm/plugins/MicrosoftStreetside/gradle.properties

    r36122 r36194  
    1414# If not, choose the next higher number that is available, or the gradle build will break.
    1515plugin.compile.version=18724
    16 plugin.requires=apache-commons;apache-http;jackson;javafx;log4j;utilsplugin2
     16plugin.requires=apache-commons;apache-http;javafx;utilsplugin2
    1717
    1818# Character encoding of Gradle files
  • applications/editors/josm/plugins/MicrosoftStreetside/gradle/wrapper/gradle-wrapper.properties

    r35779 r36194  
    11distributionBase=GRADLE_USER_HOME
    22distributionPath=wrapper/dists
    3 distributionUrl=https\://services.gradle.org/distributions/gradle-7.1.1-bin.zip
     3distributionSha256Sum=740c2e472ee4326c33bf75a5c9f5cd1e69ecf3f9b580f6e236c86d1f3d98cfac
     4distributionUrl=https\://services.gradle.org/distributions/gradle-7.6.3-bin.zip
    45zipStoreBase=GRADLE_USER_HOME
    56zipStorePath=wrapper/dists
  • applications/editors/josm/plugins/MicrosoftStreetside/gradlew

    r35779 r36194  
    7373    darwin=true
    7474    ;;
    75   MINGW* )
     75  MSYS* | MINGW* )
    7676    msys=true
    7777    ;;
  • applications/editors/josm/plugins/MicrosoftStreetside/ivy.xml

    r36176 r36194  
    77  </configurations>
    88  <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"/>
    129    <dependency org="org.openjfx" name="javafx-swing" rev="19" conf="provided">
    1310      <artifact name="javafx-swing" type="jar" m:classifier="linux"/>
     
    3835      <artifact name="javafx-graphics" type="jar" m:classifier="javadoc"/>
    3936    </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"/>
    4437  </dependencies>
    4538</ivy-module>
  • applications/editors/josm/plugins/MicrosoftStreetside/src/org/openstreetmap/josm/plugins/streetside/StreetsideAbstractImage.java

    r34577 r36194  
    1313 */
    1414public 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  /**
    286288   * @return the ne
    287289   */
  • applications/editors/josm/plugins/MicrosoftStreetside/src/org/openstreetmap/josm/plugins/streetside/StreetsideCubemap.java

    r34399 r36194  
    1212public class StreetsideCubemap extends StreetsideAbstractImage {
    1313
    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;
     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;
    1919
    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  }
    3532
    36         /**
    37         * Comparison method for the StreetsideCubemap object.
    38         *
    39         * @param image
    40          *            - a StreetsideAbstract image object
    41         *
    42          *            StreetsideCubemaps are considered equal if they are associated
    43          *            with the same image id - only one cubemap may be displayed at a
    44          *            time. If the image selection changes, the cubemap changes.
    45         *
    46         * @return result of the hashcode comparison.
    47         * @see org.openstreetmap.josm.plugins.streetside.StreetsideAbstractImage
    48         */
    49         @Override
    50         public int compareTo(StreetsideAbstractImage image) {
    51                 if (image instanceof StreetsideImage) {
    52                         return id.compareTo(((StreetsideImage) image).getId());
    53                 }
    54                 return hashCode() - image.hashCode();
    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  }
    5653
    57         /**
    58         * HashCode StreetsideCubemap object.
    59         *
    60         * @return int hashCode
    61         * @see org.openstreetmap.josm.plugins.streetside.StreetsideAbstractImage
    62         */
    63     @Override
    64         public int hashCode() {
    65                 return id.hashCode();
    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  }
    6764
    68         /**
    69         * stops ImageDisplay WalkAction (not currently supported by Streetside)
    70         *
    71         * @see org.openstreetmap.josm.plugins.streetside.actions.StreetsideWalkAction
    72         */
    73         @Override
    74         public void stopMoving() {
    75                 super.stopMoving();
    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  }
    7774
    78         /**
    79         * turns ImageDisplay WalkAction (not currently supported by Streetside)
    80         *
    81         * @param he - the direction the camera is facing (heading)
    82         *
    83         * @see org.openstreetmap.josm.plugins.streetside.actions.StreetsideWalkAction
    84         */
    85         @Override
    86         public void turn(double he) {
    87                 super.turn(he);
    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  }
    8986
    90         /**
    91         * @return the height of an assembled cubemap face for 16-tiled or 4-tiled imagery
    92         *
    93         * @see org.openstreetmap.josm.plugins.streetside.actions.StreetsideWalkAction
    94         */
    95         public int getHeight() {
    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  }
    9895
    9996}
  • applications/editors/josm/plugins/MicrosoftStreetside/src/org/openstreetmap/josm/plugins/streetside/StreetsideData.java

    r35601 r36194  
    3737  private final Set<StreetsideAbstractImage> images = ConcurrentHashMap.newKeySet();
    3838  /**
     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  /**
    3951   * The image currently selected, this is the one being shown.
    4052   */
     
    4456   */
    4557  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;
    5858
    5959  /**
     
    6464    bounds = new CopyOnWriteArrayList<>();
    6565
    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    });
    71131  }
    72132
     
    86146   * @param image  The image to be added.
    87147   * @param update Whether the map must be updated or not
    88    *        (updates are currently unsupported by Streetside).
     148   *         (updates are currently unsupported by Streetside).
    89149   */
    90150  public void add(StreetsideAbstractImage image, boolean update) {
    91         images.add(image);
    92         if (update) {
    93                 StreetsideLayer.invalidateInstance();
    94         }
    95         fireImagesAdded();
     151    images.add(image);
     152    if (update) {
     153      StreetsideLayer.invalidateInstance();
     154    }
     155    fireImagesAdded();
    96156  }
    97157
     
    109169   *
    110170   * @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.
    112172   */
    113173  public void addAll(Collection<? extends StreetsideAbstractImage> newImages, boolean update) {
     
    119179  }
    120180
    121  /**
     181  /**
    122182   * Adds a new listener.
    123183   *
     
    176236
    177237  /**
     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  /**
    178247   * Highlights the image under the cursor.
    179248   *
     
    185254
    186255  /**
    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   /**
    196256   * Returns a Set containing all images.
    197257   *
     
    203263
    204264  /**
     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  /**
    205278   * Returns a Set of all sequences, that the images are part of.
     279   *
    206280   * @return all sequences that are contained in the Streetside data
    207281   */
     
    217291  public StreetsideAbstractImage getSelectedImage() {
    218292    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);
    219302  }
    220303
     
    229312   *
    230313   * @throws IllegalStateException if the selected image is null or the selected image doesn't
    231    *                               belong to a sequence.
     314   *                 belong to a sequence.
    232315   */
    233316  public void selectNext() {
     
    242325   * @param moveToPicture True if the view must me moved to the next picture.
    243326   * @throws IllegalStateException if the selected image is null or the selected image doesn't
    244    *                               belong to a sequence.
     327   *                 belong to a sequence.
    245328   */
    246329  public void selectNext(boolean moveToPicture) {
     
    263346   *
    264347   * @throws IllegalStateException if the selected image is null or the selected image doesn't
    265    *                               belong to a sequence.
     348   *                 belong to a sequence.
    266349   */
    267350  public void selectPrevious() {
     
    277360   * @param moveToPicture True if the view must me moved to the previous picture.
    278361   * @throws IllegalStateException if the selected image is null or the selected image doesn't
    279    *                               belong to a sequence.
     362   *                 belong to a sequence.
    280363   */
    281364  public void selectPrevious(boolean moveToPicture) {
     
    290373      }
    291374    }
    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 selected
    298    */
    299   public void setSelectedImage(StreetsideAbstractImage image) {
    300     setSelectedImage(image, false);
    301375  }
    302376
     
    329403  }
    330404
    331   /**
    332    * Downloads surrounding images of this mapillary image in background threads
    333    * @param streetsideImage the image for which the surrounding images should be downloaded
    334    */
    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 threads
    364    * @param streetsideImage the image for which the surrounding images should be downloaded
    365    */
    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 
    391405  private void fireSelectedImageChanged(StreetsideAbstractImage oldImage, StreetsideAbstractImage newImage) {
    392         listeners.stream().filter(Objects::nonNull).forEach(lis -> lis.selectedImageChanged(oldImage, newImage));
     406    listeners.stream().filter(Objects::nonNull).forEach(lis -> lis.selectedImageChanged(oldImage, newImage));
    393407  }
    394408
     
    403417  }
    404418
    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 
    418419  @Override
    419420  public Collection<DataSource> getDataSources() {
    420         return Collections.emptyList();
     421    return Collections.emptyList();
    421422  }
    422423}
  • applications/editors/josm/plugins/MicrosoftStreetside/src/org/openstreetmap/josm/plugins/streetside/StreetsideDataListener.java

    r34317 r36194  
    1919   * manually clicking on the icon.
    2020   *
    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}
    2523   */
    26   void selectedImageChanged(StreetsideAbstractImage oldImage,
    27       StreetsideAbstractImage newImage);
     24  void selectedImageChanged(StreetsideAbstractImage oldImage, StreetsideAbstractImage newImage);
    2825}
  • applications/editors/josm/plugins/MicrosoftStreetside/src/org/openstreetmap/josm/plugins/streetside/StreetsideImage.java

    r34429 r36194  
    1818 */
    1919public class StreetsideImage extends StreetsideAbstractImage {
    20   /**
    21    * Rn is a Bing Streetside image attribute - currently not
    22    * 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 
    2920  // latitude of the Streetside image
    3021  private double la;
    31 
    3222  //longitude of the Streetside image
    3323  private double lo;
    34 
    3524  // The bubble altitude, in meters above the WGS84 ellipsoid
    3625  private double al;
    37 
    3826  // Roll
    3927  private double ro;
    40 
    4128  // Pitch
    4229  private double pi;
    43 
    4430  // Blurring instructions - not currently used by the plugin
    4531  private String bl;
    46 
    4732  // Undocumented Attributes
    4833  private int ml;
     
    5540   * Main constructor of the class StreetsideImage
    5641   *
    57    * @param id     The unique identifier of the image.
     42   * @param id   The unique identifier of the image.
    5843   * @param latLon The latitude and longitude where it is positioned.
    59    * @param he     The direction of the images in degrees, meaning 0 north.
     44   * @param he   The direction of the images in degrees, meaning 0 north.
    6045   */
    6146  public StreetsideImage(String id, LatLon latLon, double he) {
     
    6449
    6550  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);
    6752  }
    6853
    6954  public StreetsideImage(String id) {
    70             super(id);
     55    super(id);
    7156  }
    7257
     
    8267   */
    8368  @Override
    84 public String getId() {
     69  public String getId() {
    8570    return String.valueOf(id);
    8671  }
    8772
     73  /**
     74   * @param id the id to set
     75   */
     76  @Override
     77  public void setId(String id) {
     78    this.id = id;
     79  }
     80
    8881  public UserProfile getUser() {
    89             return getSequence().getUser();
     82    return getSequence().getUser();
    9083  }
    9184
    9285  @Override
    9386  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
    9788    );
    9889  }
     
    10697  public int compareTo(StreetsideAbstractImage image) {
    10798    if (image instanceof StreetsideImage) {
    108       return id.compareTo(((StreetsideImage) image).getId());
     99      return id.compareTo(image.getId());
    109100    }
    110101    return hashCode() - image.hashCode();
     
    273264
    274265  /**
    275    * @param id the id to set
    276    */
    277   @Override
    278 public void setId(String id) {
    279     this.id = id;
    280   }
    281 
    282   /**
    283266   * @return the rn
    284267   */
     
    293276    this.rn = rn;
    294277  }
     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  }
    295287}
  • applications/editors/josm/plugins/MicrosoftStreetside/src/org/openstreetmap/josm/plugins/streetside/StreetsideLayer.java

    r35978 r36194  
    1717import java.util.IntSummaryStatistics;
    1818import java.util.Optional;
     19import java.util.logging.Logger;
    1920
    2021import javax.swing.Action;
    2122import javax.swing.Icon;
    2223
    23 import org.apache.log4j.Logger;
    2424import org.openstreetmap.josm.data.Bounds;
    2525import org.openstreetmap.josm.data.coor.ILatLon;
     
    5050import org.openstreetmap.josm.tools.I18n;
    5151import org.openstreetmap.josm.tools.ImageProvider.ImageSizes;
     52import org.openstreetmap.josm.tools.Logging;
    5253
    5354/**
     
    5758 * @author nokutu
    5859 */
    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 */
     60public 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   */
    6568  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   */
    6772  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   */
    6976  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  }
    97139
    98140  /**
     
    120162    if (StreetsidePlugin.getMapView() != null) {
    121163      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();
    131167  }
    132168
     
    153189  }
    154190
    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.
    161194   *
    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  }
    191201
    192202  /**
     
    194204   * The "n-nearest image" is picked from the list of one image from every sequence that is nearest to the currently
    195205   * selected image, excluding the sequence to which the selected image belongs.
     206   *
    196207   * @param n the index for picking from the list of "nearest images", beginning from 1
    197208   * @return the n-nearest image to the currently selected image
     
    223234      }
    224235    } catch (IllegalArgumentException e) {
     236      Logging.trace(e);
    225237      // 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.
    226238    }
     
    228240  }
    229241
    230 
    231         @Override
     242  @Override
    232243  public boolean isModified() {
    233244    return data.getImages().parallelStream().anyMatch(StreetsideAbstractImage::isModified);
     
    289300    for (StreetsideSequence seq : getData().getSequences()) {
    290301      if (seq.getImages().contains(selectedImage)) {
    291         g.setColor(
    292           seq.getId() == null ? StreetsideColorScheme.SEQ_IMPORTED_SELECTED : StreetsideColorScheme.SEQ_SELECTED
    293         );
     302    g.setColor(
     303      seq.getId() == null ? StreetsideColorScheme.SEQ_IMPORTED_SELECTED : StreetsideColorScheme.SEQ_SELECTED
     304    );
    294305      } else {
    295         g.setColor(
    296           seq.getId() == null ? StreetsideColorScheme.SEQ_IMPORTED_UNSELECTED : StreetsideColorScheme.SEQ_UNSELECTED
    297         );
     306    g.setColor(
     307      seq.getId() == null ? StreetsideColorScheme.SEQ_IMPORTED_UNSELECTED : StreetsideColorScheme.SEQ_UNSELECTED
     308    );
    298309      }
    299310      g.draw(MapViewGeometryUtil.getSequencePath(mv, seq));
     
    308319  /**
    309320   * Draws an image marker onto the given Graphics context.
    310    * @param g the Graphics context
     321   *
     322   * @param g   the Graphics context
    311323   * @param img the image to be drawn onto the Graphics context
    312324   */
    313325  private void drawImageMarker(final Graphics2D g, final StreetsideAbstractImage img) {
    314326    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!");
    316328      return;
    317329    }
     
    325337      markerC = StreetsideColorScheme.SEQ_HIGHLIGHTED;
    326338      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())) {
    328341      markerC = StreetsideColorScheme.SEQ_SELECTED;
    329342      directionC = StreetsideColorScheme.SEQ_SELECTED_CA;
     
    336349    float alpha = 0.75f;
    337350    int type = AlphaComposite.SRC_OVER;
    338     AlphaComposite composite =
    339       AlphaComposite.getInstance(type, alpha);
     351    AlphaComposite composite = AlphaComposite.getInstance(type, alpha);
    340352    g.setComposite(composite);
    341353    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);
    343357    // Paint image marker
    344358    g.setColor(markerC);
     
    351365      g.drawOval(p.x - IMG_MARKER_RADIUS, p.y - IMG_MARKER_RADIUS, 2 * IMG_MARKER_RADIUS, 2 * IMG_MARKER_RADIUS);
    352366    }
    353         }
     367  }
    354368
    355369  @Override
     
    365379  @Override
    366380  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");
    369382  }
    370383
    371384  @Override
    372385  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) };
    378388  }
    379389
    380390  @Override
    381391  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());
    403402  }
    404403
     
    449448   *
    450449   * @param target the image for which you want to find the nearest other images
    451    * @param limit the maximum length of the returned array
     450   * @param limit  the maximum length of the returned array
    452451   * @return An array containing the closest images belonging to different sequences sorted by distance from target.
    453452   */
    454453  private StreetsideImage[] getNearestImagesFromDifferentSequences(StreetsideAbstractImage target, int limit) {
    455454    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);
    471464  }
    472465
     
    496489      this.target = target;
    497490    }
     491
    498492    /* (non-Javadoc)
    499493     * @see java.util.Comparator#compare(java.lang.Object, java.lang.Object)
     
    501495    @Override
    502496    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
    509502}
  • applications/editors/josm/plugins/MicrosoftStreetside/src/org/openstreetmap/josm/plugins/streetside/StreetsidePlugin.java

    r36065 r36194  
    3131  public static final ImageProvider LOGO = new ImageProvider("streetside-logo");
    3232
    33   /** Zoom action */
     33  /**
     34   * Zoom action
     35   */
    3436  private static final StreetsideZoomAction ZOOM_ACTION = new StreetsideZoomAction();
    35   /** Walk action */
     37  /**
     38   * Walk action
     39   */
    3640  private static final StreetsideWalkAction WALK_ACTION = new StreetsideWalkAction();
    3741
     
    3943   * Main constructor.
    4044   *
    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.
    4346   */
    4447  public StreetsidePlugin(PluginInformation info) {
     
    5659
    5760  static StreetsideDataListener[] getStreetsideDataListeners() {
    58         return new StreetsideDataListener[]{WALK_ACTION, ZOOM_ACTION, CubemapBuilder.getInstance()};
     61    return new StreetsideDataListener[] { WALK_ACTION, ZOOM_ACTION, CubemapBuilder.getInstance() };
    5962  }
    60 
    6163
    6264  /**
     
    6567  public static StreetsideWalkAction getStreetsideWalkAction() {
    6668    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;
    6780  }
    6881
     
    7588      MainApplication.getMap().addToggleDialog(StreetsideMainDialog.getInstance(), false);
    7689      StreetsideMainDialog.getInstance().setImageInfoHelp(new ImageInfoHelpPopup(
    77           MainApplication.getMap().addToggleDialog(ImageInfoPanel.getInstance(), false)
    78       ));
     90          MainApplication.getMap().addToggleDialog(ImageInfoPanel.getInstance(), false)));
    7991      MainApplication.getMap().addToggleDialog(StreetsideViewerDialog.getInstance(), false);
    8092    }
     
    91103    return new StreetsidePreferenceSetting();
    92104  }
    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   }
    104105}
  • applications/editors/josm/plugins/MicrosoftStreetside/src/org/openstreetmap/josm/plugins/streetside/StreetsideSequence.java

    r34399 r36194  
    1717public class StreetsideSequence {
    1818
    19 
     19  /**
     20   * The images in the sequence.
     21   */
     22  private final List<StreetsideAbstractImage> images;
    2023  /**
    2124   * Unique identifier. Used only for {@link StreetsideImage} sequences.
     
    2326  private String id;
    2427  private UserProfile user;
    25 
    2628  private double la;
    2729  private double lo;
    28 
    2930  /**
    3031   * Epoch time when the sequence was created
     
    3233  private long cd;
    3334
    34   /**
    35    * The images in the sequence.
    36    */
    37   private List<StreetsideAbstractImage> images;
    38 
    3935  public StreetsideSequence(String id, Long ca) {
    40         this.id = id;
     36    this.id = id;
    4137    cd = ca;
    4238    images = new CopyOnWriteArrayList<>();
     
    5450   */
    5551  public StreetsideSequence() {
    56           images = new CopyOnWriteArrayList<>();
     52    images = new CopyOnWriteArrayList<>();
    5753  }
    5854
    5955  public StreetsideSequence(String id, double la, double lo, long ca) {
    60         this.id = id;
    61         this.la = la;
    62         this.lo = lo;
    63         cd = ca;
    64         images = new CopyOnWriteArrayList<>();
    65 }
    66 
    67 public StreetsideSequence(String id) {
    68         this.id = id;
    69         images = new CopyOnWriteArrayList<>();
    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  }
    7167
    7268  /**
     
    9591   *
    9692   * @param image The {@link StreetsideAbstractImage} object whose next image is
    97    * going to be returned.
    98    *
     93   *        going to be returned.
    9994   * @return The next {@link StreetsideAbstractImage} object in the sequence.
    100    *
    10195   * @throws IllegalArgumentException if the given {@link StreetsideAbstractImage} object doesn't belong
    102    * the this sequence.
     96   *                  in this sequence.
    10397   */
    10498  public StreetsideAbstractImage next(StreetsideAbstractImage image) {
     
    118112   *
    119113   * @param image The {@link StreetsideAbstractImage} object whose previous image is
    120    * going to be returned.
    121    *
     114   *        going to be returned.
    122115   * @return The previous {@link StreetsideAbstractImage} object in the sequence.
    123    *
    124116   * @throws IllegalArgumentException if the given {@link StreetsideAbstractImage} object doesn't belong
    125    * the this sequence.
     117   *                  the this sequence.
    126118   */
    127119  public StreetsideAbstractImage previous(StreetsideAbstractImage image) {
     
    146138
    147139  /**
    148    * @param id the id to set
    149    */
    150   public void setId(String id) {
    151     this.id = id;
    152   }
    153 
    154   /**
    155140   * @return the la
    156141   */
     
    214199  }
    215200
     201  /**
     202   * @param id the id to set
     203   */
     204  public void setId(String id) {
     205    this.id = id;
     206  }
     207
    216208  public UserProfile getUser() {
    217         return user;
     209    return user;
    218210  }
    219211}
  • applications/editors/josm/plugins/MicrosoftStreetside/src/org/openstreetmap/josm/plugins/streetside/actions/ImageReloadAction.java

    r34400 r36194  
    1313public class ImageReloadAction extends AbstractAction {
    1414
    15         private static final long serialVersionUID = 7987479726049238315L;
     15  private static final long serialVersionUID = 7987479726049238315L;
    1616
    17         public ImageReloadAction(final String name) {
    18                 super(name, ImageProvider.get("reload", ImageSizes.SMALLICON));
    19         }
     17  public ImageReloadAction(final String name) {
     18    super(name, ImageProvider.get("reload", ImageSizes.SMALLICON));
     19  }
    2020
    21         @Override
    22         public void actionPerformed(ActionEvent arg0) {
    23                 if(StreetsideMainDialog.getInstance().getImage()!=null){
    24                         CubemapBuilder.getInstance().reload(CubemapBuilder.getInstance().getCubemap().getId());
    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  }
    2727}
  • applications/editors/josm/plugins/MicrosoftStreetside/src/org/openstreetmap/josm/plugins/streetside/actions/StreetsideDownloadAction.java

    r34399 r36194  
    66import java.awt.event.ActionEvent;
    77import java.awt.event.KeyEvent;
     8import java.util.logging.Level;
     9import java.util.logging.Logger;
    810
    9 import org.apache.log4j.Logger;
    1011import org.openstreetmap.josm.actions.JosmAction;
    1112import org.openstreetmap.josm.gui.MainApplication;
     
    2627public class StreetsideDownloadAction extends JosmAction {
    2728
     29  public static final Shortcut SHORTCUT = Shortcut.registerShortcut("Streetside", "Open Streetside layer",
     30      KeyEvent.VK_COMMA, Shortcut.SHIFT);
    2831  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());
    3333
    3434  /**
     
    3636   */
    3737  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);
    4740  }
    4841
    4942  @Override
    5043  public void actionPerformed(ActionEvent ae) {
    51     if (!StreetsideLayer.hasInstance() || !MainApplication.getLayerManager().containsLayer(StreetsideLayer.getInstance())) {
     44    if (!StreetsideLayer.hasInstance()
     45        || !MainApplication.getLayerManager().containsLayer(StreetsideLayer.getInstance())) {
    5246      MainApplication.getLayerManager().addLayer(StreetsideLayer.getInstance());
    5347      return;
     
    6458    } catch (IllegalArgumentException e) {
    6559      // 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);
    6761    }
    6862  }
  • applications/editors/josm/plugins/MicrosoftStreetside/src/org/openstreetmap/josm/plugins/streetside/actions/StreetsideDownloadViewAction.java

    r34349 r36194  
    3333   */
    3434  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);
    4439    StreetsideProperties.DOWNLOAD_MODE.addListener(this);
    4540    initEnabledState();
     
    6257  protected void updateEnabledState() {
    6358    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));
    7062  }
    7163
  • applications/editors/josm/plugins/MicrosoftStreetside/src/org/openstreetmap/josm/plugins/streetside/actions/StreetsideExportAction.java

    r34577 r36194  
    1414import javax.swing.JOptionPane;
    1515
    16 import org.apache.log4j.Logger;
    1716import org.openstreetmap.josm.actions.JosmAction;
    1817import org.openstreetmap.josm.gui.MainApplication;
     
    3736  private static final long serialVersionUID = 6131359489725632369L;
    3837
    39   final static Logger logger = Logger.getLogger(StreetsideExportAction.class);
    40 
    4138  private StreetsideExportDialog dialog;
    4239
     
    4744    super(tr("Export Streetside images"), new ImageProvider(StreetsidePlugin.LOGO).setSize(ImageSizes.DEFAULT),
    4845        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);
    5148    setEnabled(false);
    5249  }
     
    6360    dialog = new StreetsideExportDialog(ok);
    6461    pane.setMessage(dialog);
    65     pane.setOptions(new JButton[] {ok, cancel});
     62    pane.setOptions(new JButton[] { ok, cancel });
    6663
    6764    JDialog dlg = pane.createDialog(MainApplication.getMainFrame(), tr("Export Streetside images"));
     
    7067
    7168    // 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) {
    7570      if (dialog.group.isSelected(dialog.all.getModel())) {
    7671        export(StreetsideLayer.getInstance().getData().getImages());
     
    9792   * Exports the given images from the database.
    9893   *
    99    * @param images
    100    *          The set of images to be exported.
     94   * @param images The set of images to be exported.
    10195   */
    10296  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()));
    10599  }
    106100
  • applications/editors/josm/plugins/MicrosoftStreetside/src/org/openstreetmap/josm/plugins/streetside/actions/StreetsideWalkAction.java

    r34577 r36194  
    3232
    3333  private static final long serialVersionUID = 3454223919402245818L;
    34 
     34  private final List<WalkListener> listeners = new ArrayList<>();
    3535  private WalkThread thread;
    36   private final List<WalkListener> listeners = new ArrayList<>();
    3736
    3837  /**
     
    4039   */
    4140  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);
    4543  }
    4644
     
    4846  public void actionPerformed(ActionEvent arg0) {
    4947    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);
    5249    JDialog dlg = pane.createDialog(MainApplication.getMainFrame(), tr("Walk mode"));
    5350    dlg.setMinimumSize(new Dimension(400, 150));
    5451    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(),
    5954          dialog.followSelection.isSelected(), dialog.goForward.isSelected());
    6055      fireWalkStarted();
     
    7267   * Adds a listener.
    7368   *
    74    * @param lis
    75    *          The listener to be added.
     69   * @param lis The listener to be added.
    7670   */
    7771  public void addListener(WalkListener lis) {
     
    8377   *
    8478   * @param lis
    85    *          The listener to be added.
     79   *      The listener to be added.
    8680   */
    8781  public void removeListener(WalkListener lis) {
  • applications/editors/josm/plugins/MicrosoftStreetside/src/org/openstreetmap/josm/plugins/streetside/actions/StreetsideZoomAction.java

    r34400 r36194  
    2929   */
    3030  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);
    4033  }
    4134
     
    4538      throw new IllegalStateException();
    4639    }
    47     MainApplication.getMap().mapView.zoomTo(StreetsideLayer.getInstance().getData()
    48         .getSelectedImage().getMovingLatLon());
     40    MainApplication.getMap().mapView
     41        .zoomTo(StreetsideLayer.getInstance().getData().getSelectedImage().getMovingLatLon());
    4942  }
    5043
     
    5447  }
    5548
    56     @Override
     49  @Override
    5750  protected boolean listenToSelectionChange() {
    5851    return false;
  • applications/editors/josm/plugins/MicrosoftStreetside/src/org/openstreetmap/josm/plugins/streetside/actions/WalkThread.java

    r34416 r36194  
    44import java.awt.image.BufferedImage;
    55import java.text.MessageFormat;
     6import java.util.logging.Logger;
    67
    78import javax.swing.SwingUtilities;
    89
    9 import org.apache.log4j.Logger;
    1010import org.openstreetmap.josm.plugins.streetside.StreetsideAbstractImage;
    1111import org.openstreetmap.josm.plugins.streetside.StreetsideData;
     
    1616import org.openstreetmap.josm.plugins.streetside.gui.StreetsideMainDialog;
    1717import org.openstreetmap.josm.plugins.streetside.utils.StreetsideProperties;
    18 
     18import org.openstreetmap.josm.tools.Logging;
    1919
    2020/**
     
    2424 */
    2525public class WalkThread extends Thread implements StreetsideDataListener {
     26  private static final Logger LOGGER = Logger.getLogger(WalkThread.class.getCanonicalName());
    2627  private final int interval;
    2728  private final StreetsideData data;
    28   private boolean end;
    2929  private final boolean waitForFullQuality;
    3030  private final boolean followSelected;
    3131  private final boolean goForward;
     32  private boolean end;
    3233  private BufferedImage lastImage;
    3334  private volatile boolean paused;
    34 
    35   final static Logger logger = Logger.getLogger(WalkThread.class);
    3635
    3736  /**
    3837   * Main constructor.
    3938   *
    40    * @param interval How often the images switch.
     39   * @param interval     How often the images switch.
    4140   * @param waitForPicture If it must wait for the full resolution picture or just the
    42    * thumbnail.
     41   *             thumbnail.
    4342   * @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.
    4544   */
    46   public WalkThread(int interval, boolean waitForPicture,
    47                     boolean followSelected, boolean goForward) {
     45  public WalkThread(int interval, boolean waitForPicture, boolean followSelected, boolean goForward) {
    4846    this.interval = interval;
    4947    waitForFullQuality = waitForPicture;
     
    5250    data = StreetsideLayer.getInstance().getData();
    5351    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    }
    5468  }
    5569
     
    6276          // Predownload next 10 thumbnails.
    6377          preDownloadImages((StreetsideImage) image.next(), 10, CacheUtils.PICTURE.THUMBNAIL);
    64           if(StreetsideProperties.PREDOWNLOAD_CUBEMAPS.get()) {
     78          if (Boolean.TRUE.equals(StreetsideProperties.PREDOWNLOAD_CUBEMAPS.get())) {
    6579            preDownloadCubemaps((StreetsideImage) image.next(), 10);
    6680          }
     
    6882            // Start downloading 3 next full images.
    6983            StreetsideAbstractImage currentImage = image.next();
    70                   preDownloadImages((StreetsideImage) currentImage, 3, CacheUtils.PICTURE.FULL_IMAGE);
     84            preDownloadImages((StreetsideImage) currentImage, 3, CacheUtils.PICTURE.FULL_IMAGE);
    7185          }
    7286        }
    7387        try {
    7488          // Waits for full quality picture.
    75           final BufferedImage displayImage = StreetsideMainDialog.getInstance().getStreetsideImageDisplay().getImage();
     89          final BufferedImage displayImage = StreetsideMainDialog.getInstance().getStreetsideImageDisplay()
     90              .getImage();
    7691          if (waitForFullQuality && image instanceof StreetsideImage) {
    7792            while (displayImage == lastImage || displayImage == null || displayImage.getWidth() < 2048) {
     
    101116      }
    102117    } 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);
    106121      }
    107122      return;
     
    111126
    112127  private void preDownloadCubemaps(StreetsideImage startImage, int n) {
    113           if (n >= 1 && startImage != null) {
     128    if (n >= 1 && startImage != null) {
    114129
    115                   for (int i = 0; i < 6; i++) {
    116                                 for (int j = 0; j < 4; j++) {
    117                                         for (int k = 0; k < 4; k++) {
     130      for (int i = 0; i < 6; i++) {
     131        for (int j = 0; j < 4; j++) {
     132          for (int k = 0; k < 4; k++) {
    118133
    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        }
    141140      }
    142141    }
  • applications/editors/josm/plugins/MicrosoftStreetside/src/org/openstreetmap/josm/plugins/streetside/cache/CacheUtils.java

    r34399 r36194  
    22package org.openstreetmap.josm.plugins.streetside.cache;
    33
     4import java.io.IOException;
     5import java.util.logging.Logger;
    46
    5 import java.io.IOException;
    6 
    7 import org.apache.log4j.Logger;
    87import org.openstreetmap.josm.data.cache.CacheEntry;
    98import org.openstreetmap.josm.data.cache.CacheEntryAttributes;
     
    1110import org.openstreetmap.josm.plugins.streetside.StreetsideImage;
    1211import org.openstreetmap.josm.plugins.streetside.cubemap.CubemapBuilder;
     12import org.openstreetmap.josm.tools.Logging;
    1313
    1414/**
     
    2020public final class CacheUtils {
    2121
    22 final static Logger logger = Logger.getLogger(CacheUtils.class);
     22  private static final Logger LOGGER = Logger.getLogger(CacheUtils.class.getCanonicalName());
    2323
    24 private static IgnoreDownload ignoreDownload = new IgnoreDownload();
     24  private static final IgnoreDownload ignoreDownload = new IgnoreDownload();
    2525
    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  }
    3729
    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  }
    4139
    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  }
    5249
    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  }
    6384
    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  }
    100100
    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  }
    120122
    121123  private static class IgnoreDownload implements ICachedLoaderListener {
  • applications/editors/josm/plugins/MicrosoftStreetside/src/org/openstreetmap/josm/plugins/streetside/cache/Caches.java

    r35466 r36194  
    55import java.io.IOException;
    66import java.io.Serializable;
     7import java.util.logging.Logger;
    78
    89import javax.swing.ImageIcon;
     
    1011import org.apache.commons.jcs3.access.CacheAccess;
    1112import org.apache.commons.jcs3.engine.behavior.IElementAttributes;
    12 import org.apache.log4j.Logger;
    1313import org.openstreetmap.josm.data.Preferences;
    1414import org.openstreetmap.josm.data.cache.BufferedImageCacheEntry;
     
    1919public final class Caches {
    2020
    21   final static Logger logger = Logger.getLogger(Caches.class);
     21  private static final Logger LOGGER = Logger.getLogger(Caches.class.getCanonicalName());
    2222
    23         private Caches() {
    24                 // Private constructor to avoid instantiation
    25         }
     23  private Caches() {
     24    // Private constructor to avoid instantiation
     25  }
    2626
    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         }
     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  }
    3434
    35         public abstract static class CacheProxy<K, V extends Serializable> {
    36                 private final CacheAccess<K, V> cache;
     35  public abstract static class CacheProxy<K, V extends Serializable> {
     36    private final CacheAccess<K, V> cache;
    3737
    38                 public CacheProxy() {
    39                         CacheAccess<K, V> c;
    40                         try {
    41                                 c = createNewCache();
    42                         } catch (IOException e) {
    43                                 logger.warn("Could not initialize cache for " + getClass().getName(), e);
    44                                 c = null;
    45                         }
    46                         cache = c;
    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    }
    4848
    49                 protected abstract CacheAccess<K, V> createNewCache() throws IOException;
     49    protected abstract CacheAccess<K, V> createNewCache() throws IOException;
    5050
    51                 public V get(final K key) {
    52                         return cache == null ? null : cache.get(key);
    53                 }
     51    public V get(final K key) {
     52      return cache == null ? null : cache.get(key);
     53    }
    5454
    55                 public void put(final K key, final V value) {
    56                         if (cache != null) {
    57                                 cache.put(key, value);
    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  }
    6161
    62         public static class ImageCache {
    63                 private static ImageCache instance;
    64                 private final CacheAccess<String, BufferedImageCacheEntry> cache;
     62  public static class ImageCache {
     63    private static ImageCache instance;
     64    private final CacheAccess<String, BufferedImageCacheEntry> cache;
    6565
    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                 }
     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    }
    7676
    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    }
    8085
    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  }
    9090
    91         public static class CubemapCache {
    92                 private static CubemapCache instance;
    93                 private final CacheAccess<String, BufferedImageCacheEntry> cache;
     91  public static class CubemapCache {
     92    private static CubemapCache instance;
     93    private final CacheAccess<String, BufferedImageCacheEntry> cache;
    9494
    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.warn("Could not initialize the Streetside cubemap cache.", e);
    101                                 c = null;
    102                         }
    103                         cache = c;
    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    }
    105105
    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    }
    109114
    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  }
    119119
    120         public static class MapObjectIconCache extends CacheProxy<String, ImageIcon> {
    121                 private static CacheProxy<String, ImageIcon> instance;
     120  public static class MapObjectIconCache extends CacheProxy<String, ImageIcon> {
     121    private static CacheProxy<String, ImageIcon> instance;
    122122
    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                 }
     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    }
    131131
    132                 @Override
    133                 protected CacheAccess<String, ImageIcon> createNewCache() throws IOException {
    134                         return JCSCacheManager.getCache("streetsideObjectIcons", 100, 1000, Caches.getCacheDirectory().getPath());
    135                 }
    136         }
     132    @Override
     133    protected CacheAccess<String, ImageIcon> createNewCache() throws IOException {
     134      return JCSCacheManager.getCache("streetsideObjectIcons", 100, 1000, Caches.getCacheDirectory().getPath());
     135    }
     136  }
    137137
    138         public static class UserProfileCache extends CacheProxy<String, UserProfile> {
    139                 private static CacheProxy<String, UserProfile> instance;
     138  public static class UserProfileCache extends CacheProxy<String, UserProfile> {
     139    private static CacheProxy<String, UserProfile> instance;
    140140
    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                 }
     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    }
    149149
    150                 @Override
    151                 protected CacheAccess<String, UserProfile> createNewCache() throws IOException {
    152                         CacheAccess<String, UserProfile> cache =
    153                                         JCSCacheManager.getCache("userProfile", 100, 1000, 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         }
     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  }
    160160}
  • applications/editors/josm/plugins/MicrosoftStreetside/src/org/openstreetmap/josm/plugins/streetside/cache/StreetsideCache.java

    r34412 r36194  
    1818public class StreetsideCache extends JCSCachedTileLoaderJob<String, BufferedImageCacheEntry> {
    1919
    20         private final URL url;
    21         private final String id;
     20  private final URL url;
     21  private final String id;
    2222
    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));
    3432
    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  }
    4641
    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  }
    5546
    56         @Override
    57         public String getCacheKey() {
    58                 return id;
    59         }
     47  @Override
     48  public URL getUrl() {
     49    return url;
     50  }
    6051
    61         @Override
    62         public URL getUrl() {
    63                 return url;
    64         }
     52  @Override
     53  protected BufferedImageCacheEntry createCacheEntry(byte[] content) {
     54    return new BufferedImageCacheEntry(content);
     55  }
    6556
    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  }
    7065
    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  }
    7981}
  • applications/editors/josm/plugins/MicrosoftStreetside/src/org/openstreetmap/josm/plugins/streetside/cubemap/CameraTransformer.java

    r34416 r36194  
    1111public class CameraTransformer extends Group {
    1212
    13   public enum RotateOrder {
    14     XYZ, XZY, YXZ, YZX, ZXY, ZYX
    15   }
    16 
    1713  public Translate t = new Translate();
    1814  public Translate p = new Translate();
    1915  public Translate ip = new Translate();
    2016  public Rotate rx = new Rotate();
     17  public Rotate ry = new Rotate();
     18  public Rotate rz = new Rotate();
     19  public Scale s = new Scale();
     20
    2121  {
    2222    rx.setAxis(Rotate.X_AXIS);
    2323  }
    24   public Rotate ry = new Rotate();
     24
    2525  {
    2626    ry.setAxis(Rotate.Y_AXIS);
    2727  }
    28   public Rotate rz = new Rotate();
     28
    2929  {
    3030    rz.setAxis(Rotate.Z_AXIS);
    3131  }
    32   public Scale s = new Scale();
    3332
    3433  public CameraTransformer() {
     
    179178    ip.setZ(0.0);
    180179  }
     180
     181  public enum RotateOrder {
     182    XYZ, XZY, YXZ, YZX, ZXY, ZYX
     183  }
    181184}
  • 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.
    72package org.openstreetmap.josm.plugins.streetside.cubemap;
    83
     
    2924public class CubemapBox extends Group {
    3025
    31   public enum CubemapBoxImageType {
    32     MULTIPLE, SINGLE
    33   }
    34 
    3526  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;
    3944
    4045  {
     
    4752
    4853  }
    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) {
    6057
    6158    super();
     
    148145  private void loadSingleImageViewports() {
    149146    layoutViews();
    150     double width = singleImg.getWidth(), height = singleImg.getHeight();
     147    double width = singleImg.getWidth();
     148    double height = singleImg.getHeight();
    151149
    152150    // simple check to see if cells will be square
     
    158156    recalculateSize(cellSize);
    159157
    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;
    171170
    172171    // add top padding x+, y+, width-, height
     
    231230  }
    232231
    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
    236242  private final DoubleProperty size = new SimpleDoubleProperty() {
    237243    @Override
     
    248254  };
    249255
    250   public final double getSize() {
    251     return size.get();
    252   }
    253 
    254   public final void setSize(double value) {
    255     size.set(value);
    256   }
    257 
    258256  public DoubleProperty sizeProperty() {
    259257    return size;
     
    263261    return views;
    264262  }
     263
     264  public enum CubemapBoxImageType {
     265    MULTIPLE, SINGLE
     266  }
     267
    265268}
  • applications/editors/josm/plugins/MicrosoftStreetside/src/org/openstreetmap/josm/plugins/streetside/cubemap/CubemapBuilder.java

    r36065 r36194  
    1010import java.util.Map;
    1111import java.util.concurrent.Callable;
     12import java.util.concurrent.ConcurrentHashMap;
    1213import java.util.concurrent.ExecutionException;
    13 import java.util.concurrent.ConcurrentHashMap;
    1414import java.util.concurrent.ExecutorService;
    1515import java.util.concurrent.Executors;
    1616import java.util.concurrent.Future;
    17 
    18 import org.apache.log4j.Logger;
     17import java.util.logging.Logger;
     18
    1919import org.openstreetmap.josm.gui.MainApplication;
    20 import java.util.concurrent.ExecutionException;
    2120import org.openstreetmap.josm.plugins.streetside.StreetsideAbstractImage;
    2221import org.openstreetmap.josm.plugins.streetside.StreetsideCubemap;
     
    2726import org.openstreetmap.josm.plugins.streetside.utils.GraphicsUtils;
    2827import org.openstreetmap.josm.plugins.streetside.utils.StreetsideProperties;
     28import org.openstreetmap.josm.tools.Logging;
    2929
    3030import javafx.scene.image.Image;
     
    3434public class CubemapBuilder implements ITileDownloadingTaskListener, StreetsideDataListener {
    3535
    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;
    4241  private long startTime;
    4342
    44         private Map<String, BufferedImage> tileImages = new ConcurrentHashMap<>();
     43  private Map<String, BufferedImage> tileImages = new ConcurrentHashMap<>();
    4544  private ExecutorService pool;
    4645
    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  }
    4872
    4973  /**
     
    6185  }
    6286
    63   private CubemapBuilder() {
    64                 // private constructor to avoid instantiation
    65         }
    66 
    67         /**
     87  /**
    6888   * Fired when any image is added to the database.
    6989   */
    7090  @Override
    71         public void imagesAdded() {
    72                 // Not implemented by the CubemapBuilder
    73         }
    74 
    75         /**
     91  public void imagesAdded() {
     92    // Not implemented by the CubemapBuilder
     93  }
     94
     95  /**
    7696   * Fired when the selected image is changed by something different from
    7797   * manually clicking on the icon.
    7898   *
    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}
    84101   * @see StreetsideDataListener
    85102   */
     
    87104  public void selectedImageChanged(StreetsideAbstractImage oldImage, StreetsideAbstractImage newImage) {
    88105
    89 
    90106    startTime = System.currentTimeMillis();
    91107
    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;
    126144
    127145    // TODO: message for progress bar
     
    132150    long startTime = System.currentTimeMillis();
    133151
    134     if(CubemapBuilder.getInstance().getTileImages().keySet().size() > 0) {
     152    if (!CubemapBuilder.getInstance().getTileImages().keySet().isEmpty()) {
    135153      pool.shutdownNow();
    136154      CubemapBuilder.getInstance().resetTileImages();
     
    142160      List<Callable<List<String>>> tasks = new ArrayList<>(maxThreadCount);
    143161
    144       if (StreetsideProperties.DOWNLOAD_CUBEFACE_TILES_TOGETHER.get()) {
     162      if (Boolean.TRUE.equals(StreetsideProperties.DOWNLOAD_CUBEFACE_TILES_TOGETHER.get())) {
    145163        EnumSet.allOf(CubemapUtils.CubemapFaces.class).forEach(face -> {
    146           String tileId = String.valueOf(imageId + face.getValue());
     164          String tileId = imageId + face.getValue();
    147165          tasks.add(new TileDownloadingTask(tileId));
    148166        });
     
    150168
    151169        // 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())) {
    153171          // download all imagery for each cubeface at once
    154172
     
    158176              for (int k = 0; k < CubemapUtils.getMaxRows(); k++) {
    159177
    160                 String tileId = String
    161                   .valueOf(imageId + CubemapUtils.getFaceNumberForCount(i) + Integer.valueOf(tileNr++).toString());
     178                String tileId = imageId + CubemapUtils.getFaceNumberForCount(i) + tileNr++;
    162179                tasks.add(new TileDownloadingTask(tileId));
    163180              }
    164181            }
    165182          }
    166         // launch 16-tiled (high-res) downloading tasks
    167         } 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())) {
    168185
    169186          for (int i = 0; i < CubemapUtils.NUM_SIDES; i++) {
     
    171188              for (int k = 0; k < CubemapUtils.getMaxRows(); k++) {
    172189
    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;
    175191                tasks.add(new TileDownloadingTask(tileId));
    176192              }
     
    181197
    182198      // execute tasks
    183                         MainApplication.worker.submit(() -> {
    184                           try {
     199      MainApplication.worker.submit(() -> {
     200        try {
    185201          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) {
    188204            for (Future<List<String>> ff : results) {
    189205              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));
    192209              } catch (ExecutionException e) {
    193                 logger.error(e);
     210                LOGGER.log(Logging.LEVEL_ERROR, e.getMessage(), e);
    194211              }
    195212            }
    196213          }
    197214        } catch (InterruptedException e) {
    198          logger.error(e);
    199         }
    200                         });
     215          LOGGER.log(Logging.LEVEL_ERROR, e.getMessage(), e);
     216        }
     217      });
    201218    } catch (Exception ee) {
    202219      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);
    205221    }
    206222
     
    208224    long runTime = stopTime - startTime;
    209225
    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));
    212229    }
    213230
    214231    if (fails > 0) {
    215       logger.error(Integer.valueOf(fails) + " downloading tasks failed!");
     232      LOGGER.log(Logging.LEVEL_ERROR, fails + " downloading tasks failed!");
    216233    }
    217234  }
     
    222239   *
    223240   * @param tileId
    224    *          the complete quadKey of the imagery tile, including cubeface and row/column in quaternary.
     241   *      the complete quadKey of the imagery tile, including cubeface and row/column in quaternary.
    225242   * @see TileDownloadingTask
    226243   */
     
    231248    // and set the views in the cubemap box.
    232249
    233     if(!tileId.startsWith(cubemap.getId())) {
     250    if (!tileId.startsWith(cubemap.getId())) {
    234251      return;
    235252    }
     
    238255
    239256    if (currentTileCount == (CubemapUtils.NUM_SIDES * CubemapUtils.getMaxCols() * CubemapUtils.getMaxRows())) {
    240       if (StreetsideProperties.DEBUGING_ENABLED.get()) {
     257      if (Boolean.TRUE.equals(StreetsideProperties.DEBUGING_ENABLED.get())) {
    241258        long endTime = System.currentTimeMillis();
    242259        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)));
    248263      }
    249264
     
    258273   * then the ImageViews of the cubemap are set with the new imagery.
    259274   *
    260    * @see         StreetsideCubemap
    261    */
    262    private void buildCubemapFaces() {
    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                                                 BufferedImage currentTile = tileImages.get(tileId);
    305                                                 faceTileImages[tileCount++] = currentTile;
    306                                         }
    307                                 }
    308                                 BufferedImage finalImg = GraphicsUtils.buildMultiTiledCubemapFaceImage(faceTileImages);
    309                                 // rotate top cubeface 180 degrees - misalignment workaround
    310                                 if (i == 4) {
    311                                         finalImg = GraphicsUtils.rotateImage(finalImg);
    312                                 }
    313                                 finalImages[i] = GraphicsUtils.convertBufferedImage2JavaFXImage(finalImg);
    314                         }
    315                 }
    316 
    317                 for (int i = 0; i < CubemapUtils.NUM_SIDES; i++) {
    318                         views[i].setImage(finalImages[i]);
    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    }
    320335
    321336    StreetsideViewerDialog.getInstance().getStreetsideViewerPanel().revalidate();
     
    323338
    324339    StreetsideViewerPanel.getThreeSixtyDegreeViewerPanel()
    325                 .setScene(StreetsideViewerPanel.getThreeSixtyDegreeViewerPanel().getCubemapScene());
     340        .setScene(StreetsideViewerPanel.getThreeSixtyDegreeViewerPanel().getCubemapScene());
    326341
    327342    StreetsideViewerPanel.getThreeSixtyDegreeViewerPanel().revalidate();
     
    331346    long runTime = (endTime - startTime) / 1000;
    332347
    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);
    338354    }
    339355
     
    342358    currentTileCount = 0;
    343359    isBuilding = false;
    344         }
    345 
    346         private void resetTileImages() {
     360  }
     361
     362  private void resetTileImages() {
    347363    tileImages = new HashMap<>();
    348364  }
    349365
    350366  /**
    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  /**
    380382   * @return the isBuilding
    381383   */
     
    383385    return isBuilding;
    384386  }
    385 
    386 
    387         /**
    388          * Destroys the unique instance of the class.
    389          */
    390         public static synchronized void destroyInstance() {
    391                 CubemapBuilder.instance = null;
    392         }
    393387}
  • applications/editors/josm/plugins/MicrosoftStreetside/src/org/openstreetmap/josm/plugins/streetside/cubemap/CubemapUtils.java

    r36065 r36194  
    55import java.util.HashMap;
    66import java.util.Map;
     7import java.util.logging.Logger;
    78import java.util.stream.Stream;
    89
    9 import org.apache.log4j.Logger;
    1010import org.openstreetmap.josm.plugins.streetside.utils.StreetsideProperties;
     11import org.openstreetmap.josm.tools.Logging;
    1112
    1213public class CubemapUtils {
    1314
    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  }
    1544
    1645  private CubemapUtils() {
     
    1847  }
    1948
    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();
    13989    int power = 1;
    14090    int num = 0;
    14191    int i;
    14292
    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  }
    291307}
  • 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.
    22package org.openstreetmap.josm.plugins.streetside.cubemap;
    33
     
    1010public interface ITileDownloadingTaskListener {
    1111
    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);
    1718
    1819}
  • applications/editors/josm/plugins/MicrosoftStreetside/src/org/openstreetmap/josm/plugins/streetside/cubemap/TileDownloadingTask.java

    r34428 r36194  
    1010import java.util.concurrent.Callable;
    1111import java.util.concurrent.CopyOnWriteArrayList;
     12import java.util.logging.Logger;
    1213
    1314import javax.imageio.ImageIO;
    1415
    15 import org.apache.log4j.Logger;
    1616import org.openstreetmap.josm.plugins.streetside.cache.StreetsideCache;
    1717import org.openstreetmap.josm.plugins.streetside.utils.StreetsideProperties;
    1818import org.openstreetmap.josm.plugins.streetside.utils.StreetsideURL;
    19 
    20 import us.monoid.web.Resty;
     19import org.openstreetmap.josm.tools.Logging;
    2120
    2221public class TileDownloadingTask implements Callable<List<String>> {
    2322
    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;
    2532
    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  }
    2938
    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  }
    3447
    35         boolean cancelled = false;
     48  /**
     49   * @return the tileId
     50   */
     51  public String getId() {
     52    return tileId;
     53  }
    3654
    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  }
    4261
    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  }
    5168
    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  }
    5875
    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  }
    6582
    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  }
    7289
    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  }
    10096
    10197  @Override
     
    104100    List<String> res = new ArrayList<>();
    105101
    106     if (StreetsideProperties.DOWNLOAD_CUBEFACE_TILES_TOGETHER.get()) {
     102    if (Boolean.TRUE.equals(StreetsideProperties.DOWNLOAD_CUBEFACE_TILES_TOGETHER.get())) {
    107103      // 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())) {
    109105        // download low-res imagery
    110106        int tileNr = 0;
    111107        for (int j = 0; j < CubemapUtils.getMaxCols(); j++) {
    112108          for (int k = 0; k < CubemapUtils.getMaxRows(); k++) {
    113             String quadKey = String.valueOf(tileId + Integer.valueOf(tileNr++).toString());
     109            String quadKey = tileId + tileNr++;
    114110            res.add(downloadTile(quadKey));
    115111          }
     
    119115        for (int j = 0; j < CubemapUtils.getMaxCols(); j++) {
    120116          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;
    123118            res.add(downloadTile(quadKey));
    124119          }
    125120        }
    126121      }
    127     // task downloads just one tile
     122      // task downloads just one tile
    128123    } else {
    129124      res.add(downloadTile(tileId));
     
    138133
    139134    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));
    142136
    143137      if (img == null) {
    144         logger.error("Download of BufferedImage " + tileId + " is null!");
     138        LOGGER.log(Logging.LEVEL_ERROR, "Download of BufferedImage " + tileId + " is null!");
    145139      }
    146140
     
    149143      fireTileAdded(tileId);
    150144
    151       if (StreetsideProperties.DEBUGING_ENABLED.get()) {
     145      if (Boolean.TRUE.equals(StreetsideProperties.DEBUGING_ENABLED.get())) {
    152146        long endTime = System.currentTimeMillis();
    153147        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));
    155150      }
    156151    } 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);
    158153      return null;
    159154    }
     
    161156  }
    162157
    163         private void fireTileAdded(String id) {
    164             listeners.stream().filter(Objects::nonNull).forEach(lis -> lis.tileAdded(id));
    165         }
     158  private void fireTileAdded(String id) {
     159    listeners.stream().filter(Objects::nonNull).forEach(lis -> lis.tileAdded(id));
     160  }
    166161}
  • applications/editors/josm/plugins/MicrosoftStreetside/src/org/openstreetmap/josm/plugins/streetside/gui/StreetsideExportDialog.java

    r34429 r36194  
    2020import org.openstreetmap.josm.plugins.streetside.StreetsideLayer;
    2121
    22 
    2322/**
    2423 * GUI for exporting images.
     
    3029
    3130  private static final long serialVersionUID = -2746815082016025516L;
    32   /** Button to export all downloaded images. */
     31  /**
     32   * Button to export all downloaded images.
     33   */
    3334  public final JRadioButton all;
    3435  /**
     
    4142   */
    4243  public final JRadioButton selected;
    43   /** Group of button containing all the options. */
     44  /**
     45   * Group of button containing all the options.
     46   */
    4447  public final ButtonGroup group;
    4548  private final JButton choose;
    4649  private final JLabel path;
    47   /** File chooser. */
     50  private final JButton ok;
     51  /**
     52   * File chooser.
     53   */
    4854  public JFileChooser chooser;
    49   private final JButton ok;
    5055
    5156  /**
    5257   * Main constructor.
    5358   *
    54    * @param ok
    55    *          The button for to OK option.
     59   * @param ok The button for to OK option.
    5660   */
    5761  public StreetsideExportDialog(JButton ok) {
     
    7579    sequence.setEnabled(StreetsideLayer.getInstance().getData().getSelectedImage() instanceof StreetsideImage);
    7680    if (StreetsideLayer.getInstance().getData().getMultiSelectedImages().isEmpty()) {
    77      selected.setEnabled(false);
     81      selected.setEnabled(false);
    7882    }
    7983
     
    103107  public void actionPerformed(ActionEvent e) {
    104108    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")));
    107110    chooser.setDialogTitle(tr("Select a directory"));
    108111    chooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
     
    121124   *
    122125   * @author nokutu
    123    *
    124126   */
    125127  public class RewriteButtonAction extends AbstractAction {
    126128
    127129    private static final long serialVersionUID = 1035332841101190301L;
    128 
    129         private String lastPath;
    130130    private final StreetsideExportDialog dlg;
     131    private String lastPath;
    131132
    132133    /**
    133134     * Main constructor.
    134135     *
    135      * @param dlg
    136      *          Parent dialog.
     136     * @param dlg Parent dialog.
    137137     */
    138138    public RewriteButtonAction(StreetsideExportDialog dlg) {
     
    143143    @Override
    144144    public void actionPerformed(ActionEvent arg0) {
    145       choose
    146           .setEnabled(true);
     145      choose.setEnabled(true);
    147146      if (lastPath != null) {
    148147        dlg.path.setText(lastPath);
  • applications/editors/josm/plugins/MicrosoftStreetside/src/org/openstreetmap/josm/plugins/streetside/gui/StreetsideImageDisplay.java

    r34349 r36194  
    3333import org.openstreetmap.josm.plugins.streetside.utils.StreetsideProperties;
    3434
    35 
    3635/**
    3736 * This object is a responsible JComponent which lets you zoom and drag. It is
     
    4847  private final Collection<ImageDetection> detections = new ArrayList<>();
    4948
    50   /** The image currently displayed */
     49  /**
     50   * The image currently displayed
     51   */
    5152  private volatile BufferedImage image;
    5253
     
    6263   */
    6364  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  }
    64266
    65267  private class ImgDisplayMouseListener implements MouseListener, MouseWheelListener, MouseMotionListener {
     
    121323        // cursor doesn't move on the image.
    122324        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;
    127327        // The position is also limited by the image size
    128328        checkVisibleRectPos(image, visibleRect);
     
    134334    }
    135335
    136     /** Center the display on the point that has been clicked */
     336    /**
     337     * Center the display on the point that has been clicked
     338     */
    137339    @Override
    138340    public void mouseClicked(MouseEvent e) {
     
    146348      if (image != null && Math.min(getSize().getWidth(), getSize().getHeight()) > 0) {
    147349        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)))) {
    149352            // Zooms to 1:1
    150             StreetsideImageDisplay.this.visibleRect = new Rectangle(0, 0,
    151                 image.getWidth(null), image.getHeight(null));
     353            StreetsideImageDisplay.this.visibleRect = new Rectangle(0, 0, image.getWidth(null),
     354                image.getHeight(null));
    152355          } else {
    153356            // Zooms to best fit.
    154             StreetsideImageDisplay.this.visibleRect = new Rectangle(
    155                 0,
     357            StreetsideImageDisplay.this.visibleRect = new Rectangle(0,
    156358                (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());
    160360          }
    161361          StreetsideImageDisplay.this.repaint();
     
    240440        Point p = comp2imgCoord(visibleRect, e.getX(), e.getY());
    241441        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);
    248446        checkVisibleRectSize(image, rect);
    249447        checkVisibleRectPos(image, rect);
     
    273471        // Check that the zoom doesn't exceed 2:1
    274472        if (selectedRect.width < getSize().width / 2) {
    275                 selectedRect.width = getSize().width / 2;
     473          selectedRect.width = getSize().width / 2;
    276474        }
    277475        if (selectedRect.height < getSize().height / 2) {
    278                 selectedRect.height = getSize().height / 2;
     476          selectedRect.height = getSize().height / 2;
    279477        }
    280478        // Set the same ratio for the visible rectangle and the display
     
    289487        // Keep the center of the selection
    290488        if (selectedRect.width != oldWidth) {
    291                 selectedRect.x -= (selectedRect.width - oldWidth) / 2;
     489          selectedRect.x -= (selectedRect.width - oldWidth) / 2;
    292490        }
    293491        if (selectedRect.height != oldHeight) {
    294                 selectedRect.y -= (selectedRect.height - oldHeight) / 2;
     492          selectedRect.y -= (selectedRect.height - oldHeight) / 2;
    295493        }
    296494        checkVisibleRectSize(image, selectedRect);
     
    334532    }
    335533  }
    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 detections
    354    */
    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 displayed
    372    *
    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   @Override
    383   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.y
    402           + target.height, visibleRect.x, visibleRect.y, visibleRect.x
    403           + 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.x
    408             + 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.width
    413             - bottomRight.x, target.height);
    414         g.fillRect(target.x, bottomRight.y, target.width, target.y
    415             + 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 Component
    426         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               null
    441             );
    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.y
    452         + ((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.height
    460     );
    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    * calculateDrawImageRectangle
    473    *
    474    * @param imgRect
    475    *          the part of the image that should be drawn (in image coordinates)
    476    * @param compRect
    477    *          the part of the component where the image should be drawn (in
    478    *          component coordinates)
    479    * @return the part of compRect with the same width/height ratio as the image
    480    */
    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 fit
    515       visibleRect = new Rectangle(0, 0, image.getWidth(null),
    516           image.getHeight(null));
    517     } else {
    518       // The display is at best fit => zoom to 1:1
    519       Point center = getCenterImgCoord(visibleRect);
    520       visibleRect = new Rectangle(center.x - getWidth() / 2, center.y
    521           - 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   }
    553534}
  • applications/editors/josm/plugins/MicrosoftStreetside/src/org/openstreetmap/josm/plugins/streetside/gui/StreetsideImageTreeCellRenderer.java

    r34317 r36194  
    2020
    2121  @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) {
    2524    super.getTreeCellRendererComponent(tree, value.toString(), sel, expanded, leaf, row, hasFocus);
    2625    setIcon(ICON);
  • applications/editors/josm/plugins/MicrosoftStreetside/src/org/openstreetmap/josm/plugins/streetside/gui/StreetsideMainDialog.java

    r35202 r36194  
    1212import java.util.Arrays;
    1313import java.util.List;
     14import java.util.logging.Logger;
    1415
    1516import javax.imageio.ImageIO;
     
    2021import javax.swing.SwingUtilities;
    2122
    22 import org.apache.log4j.Logger;
    2323import org.openstreetmap.josm.data.cache.CacheEntry;
    2424import org.openstreetmap.josm.data.cache.CacheEntryAttributes;
     
    3838import org.openstreetmap.josm.tools.I18n;
    3939import org.openstreetmap.josm.tools.ImageProvider;
     40import org.openstreetmap.josm.tools.Logging;
    4041
    4142/**
     
    4546 * @author renerr18
    4647 */
    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);
     48public final class StreetsideMainDialog extends ToggleDialog implements ICachedLoaderListener, StreetsideDataListener {
    5349
    5450  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());
    6365  private final SideButton previousButton = new SideButton(new PreviousPictureAction());
    64   /**
    65    * Button used to jump to the image following the red line
    66    */
    67   public final SideButton redButton = new SideButton(new RedAction());
    68   /**
    69    * Button used to jump to the image following the blue line
    70    */
    71   public final SideButton blueButton = new SideButton(new BlueAction());
    72 
    7366  private final SideButton playButton = new SideButton(new PlayAction());
    7467  private final SideButton pauseButton = new SideButton(new PauseAction());
    7568  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;
    7775  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);
    11186    redButton.setForeground(Color.RED);
    11287
    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   */
    119120  private void addShortcuts() {
    120121    nextButton.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke("PAGE_DOWN"), "next");
    121122    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");
    123125    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");
    125128    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");
    127131    redButton.getActionMap().put("red", new RedAction());
    128132  }
    129133
    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));
    165147      break;
    166148    case NORMAL:
    167149    default:
    168       createLayout(
    169         streetsideImageDisplay,
    170         Arrays.asList(blueButton, previousButton, nextButton, redButton)
    171       );
     150      createLayout(streetsideImageDisplay, Arrays.asList(blueButton, previousButton, nextButton, redButton));
    172151      break;
    173                 }
    174                 disableAllButtons();
    175     if (MODE.NORMAL.equals(mode)) {
     152    }
     153    disableAllButtons();
     154    if (MODE.NORMAL == mode) {
    176155      updateImage();
    177156    }
    178157    revalidate();
    179158    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  /**
    257229   * Disables all the buttons in the dialog
    258230   */
     
    264236  }
    265237
    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())));
    285249        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;
    544286        }
    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  }
    566548}
  • applications/editors/josm/plugins/MicrosoftStreetside/src/org/openstreetmap/josm/plugins/streetside/gui/StreetsidePreferenceSetting.java

    r34433 r36194  
    99import java.io.IOException;
    1010import java.io.InputStream;
     11import java.util.logging.Logger;
    1112
    1213import javax.imageio.ImageIO;
     
    2627import javax.swing.SwingUtilities;
    2728
    28 import org.apache.log4j.Logger;
    2929import org.openstreetmap.josm.actions.ExpertToggleAction;
    3030import org.openstreetmap.josm.gui.preferences.PreferenceTabbedPane;
     
    4141import org.openstreetmap.josm.tools.GBC;
    4242import org.openstreetmap.josm.tools.I18n;
     43import org.openstreetmap.josm.tools.Logging;
    4344
    4445/**
     
    5051public class StreetsidePreferenceSetting implements SubPreferenceSetting, StreetsideLoginListener {
    5152
    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(
    7270      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());
    7774  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);
    8376  private final JButton loginButton = new StreetsideButton(new LoginAction(this));
    8477  private final JButton logoutButton = new StreetsideButton(new LogoutAction());
     
    9992    loginPanel.setBackground(StreetsideColorScheme.TOOLBAR_DARK_GREY);
    10093    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")) {
    10296      if (is != null) {
    10397        brandImage.setIcon(new ImageIcon(ImageIO.read(is)));
    10498      } else {
    105         logger.warn("Could not load Streetside brand image!");
     99        logger.log(Logging.LEVEL_WARN, "Could not load Streetside brand image!");
    106100      }
    107101    } 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);
    109103    }
    110104    loginPanel.add(brandImage, 0);
     
    121115    mainPanel.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
    122116
    123     downloadModeComboBox.setSelectedItem(DOWNLOAD_MODE.fromPrefId(StreetsideProperties.DOWNLOAD_MODE.get()).getLabel());
     117    downloadModeComboBox
     118        .setSelectedItem(DOWNLOAD_MODE.fromPrefId(StreetsideProperties.DOWNLOAD_MODE.get()).getLabel());
    124119
    125120    JPanel downloadModePanel = new JPanel();
     
    147142      mainPanel.add(developer, GBC.eol());
    148143    }
    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);
    152146    mainPanel.add(Box.createVerticalGlue(), GBC.eol().fill(GridBagConstraints.BOTH));
    153147
     
    156150    synchronized (gui.getDisplayPreference().getTabPane()) {
    157151      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());
    159154    }
    160155
     
    188183  @Override
    189184  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());
    191187    StreetsideProperties.DISPLAY_HOUR.put(displayHour.isSelected());
    192188    StreetsideProperties.TIME_FORMAT_24.put(format24.isSelected());
     
    211207   *
    212208   * @author nokutu
    213    *
    214209   */
    215210  private static class LoginAction extends AbstractAction {
     
    217212    private static final long serialVersionUID = 8743119160917296506L;
    218213
    219         private final transient StreetsideLoginListener callback;
     214    private final transient StreetsideLoginListener callback;
    220215
    221216    LoginAction(StreetsideLoginListener loginCallback) {
     
    242237    private static final long serialVersionUID = -4146587895393766981L;
    243238
    244         private LogoutAction() {
     239    private LogoutAction() {
    245240      super(I18n.tr("Logout"));
    246241    }
  • applications/editors/josm/plugins/MicrosoftStreetside/src/org/openstreetmap/josm/plugins/streetside/gui/StreetsideViewerDialog.java

    r34433 r36194  
    1616 */
    1717
    18 public final class StreetsideViewerDialog extends ToggleDialog
    19                  {
     18public final class StreetsideViewerDialog extends ToggleDialog {
    2019
    21         private static final long serialVersionUID = -8983900297628236197L;
     20  private static final long serialVersionUID = -8983900297628236197L;
    2221
    23         private static final String BASE_TITLE = "360° Streetside Viewer";
     22  private static final String BASE_TITLE = "360° Streetside Viewer";
    2423
    25         private static StreetsideViewerDialog instance;
     24  private static StreetsideViewerDialog instance;
    2625
    27         /**
    28         * Object containing the shown image and that handles zoom and drag
    29         */
    30         private StreetsideViewerPanel streetsideViewerPanel;
     26  /**
     27  * Object containing the shown image and that handles zoom and drag
     28  */
     29  private final StreetsideViewerPanel streetsideViewerPanel;
    3130
    32         private StreetsideViewerDialog() {
    33           super(StreetsideViewerDialog.BASE_TITLE, "streetside-viewer", "Open Streetside Viewer window",
    34                                 null, 200, true, StreetsidePreferenceSetting.class);
    35                 streetsideViewerPanel = new StreetsideViewerPanel();
    36                 createLayout(streetsideViewerPanel, true, null);
    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  }
    3837
    39         /**
    40         * Returns the unique instance of the class.
    41         *
    42         * @return The unique instance of the class.
    43         */
    44         public static synchronized StreetsideViewerDialog getInstance() {
    45                 if (StreetsideViewerDialog.instance == null) {
    46                         StreetsideViewerDialog.instance = new StreetsideViewerDialog();
    47                 }
    48                 return StreetsideViewerDialog.instance;
    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  }
    5049
    51         /**
    52         * @return true, iff the singleton instance is present
    53         */
    54         public static boolean hasInstance() {
    55                 return StreetsideViewerDialog.instance != null;
    56         }
     50  /**
     51  * @return true, iff the singleton instance is present
     52  */
     53  public static boolean hasInstance() {
     54    return StreetsideViewerDialog.instance != null;
     55  }
    5756
    58         /**
    59         * Destroys the unique instance of the class.
    60         */
    61         public static synchronized void destroyInstance() {
    62                 StreetsideViewerDialog.instance = null;
    63         }
     57  /**
     58  * Destroys the unique instance of the class.
     59  */
     60  public static synchronized void destroyInstance() {
     61    StreetsideViewerDialog.instance = null;
     62  }
    6463
    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  }
    7875
    79         public StreetsideViewerPanel getStreetsideViewerPanel() {
    80                 return streetsideViewerPanel;
    81         }
     76  public StreetsideViewerPanel getStreetsideViewerPanel() {
     77    return streetsideViewerPanel;
     78  }
    8279}
  • applications/editors/josm/plugins/MicrosoftStreetside/src/org/openstreetmap/josm/plugins/streetside/gui/StreetsideWalkDialog.java

    r34317 r36194  
    2121  private static final long serialVersionUID = 7974881240732957573L;
    2222
    23   /** Spin containing the interval value. */
     23  /**
     24   * Spin containing the interval value.
     25   */
    2426  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   */
    2630  public JCheckBox waitForPicture;
    27   /** Whether the view must follow the selected image. */
     31  /**
     32   * Whether the view must follow the selected image.
     33   */
    2834  public JCheckBox followSelection;
    29   /** Go forward or backwards */
     35  /**
     36   * Go forward or backwards
     37   */
    3038  public JCheckBox goForward;
    3139
  • applications/editors/josm/plugins/MicrosoftStreetside/src/org/openstreetmap/josm/plugins/streetside/gui/boilerplate/SelectableLabel.java

    r34317 r36194  
    1010public class SelectableLabel extends JTextPane {
    1111
    12   private static final long serialVersionUID = 5432480892000739831L;
    13 
    1412  public static final Font DEFAULT_FONT = UIManager.getFont("Label.font").deriveFont(Font.PLAIN);
    1513  public static final Color DEFAULT_BACKGROUND = UIManager.getColor("Panel.background");
     14  private static final long serialVersionUID = 5432480892000739831L;
    1615
    1716  public SelectableLabel() {
  • applications/editors/josm/plugins/MicrosoftStreetside/src/org/openstreetmap/josm/plugins/streetside/gui/boilerplate/StreetsideButton.java

    r34317 r36194  
    1212
    1313import org.openstreetmap.josm.plugins.streetside.utils.StreetsideColorScheme;
    14 
    1514
    1615public class StreetsideButton extends JButton {
  • applications/editors/josm/plugins/MicrosoftStreetside/src/org/openstreetmap/josm/plugins/streetside/gui/dialog/ChooseGeoImageLayersDialog.java

    r34399 r36194  
    2727public class ChooseGeoImageLayersDialog extends JDialog {
    2828  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?");
    3031
    3132  public ChooseGeoImageLayersDialog(final Component parent, final List<GeoImageLayer> layers) {
    32       super(GuiHelper.getFrameForComponent(parent), I18n.tr(QUESTION));
     33    super(GuiHelper.getFrameForComponent(parent), I18n.tr(QUESTION));
    3334    final Container c = getContentPane();
    3435    c.setLayout(new BorderLayout(10, 10));
     
    6465  protected static class GeoImageLayerListCellRenderer implements ListCellRenderer<GeoImageLayer> {
    6566    @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
    7170          /* 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);
    7373      if (result != null) {
    7474        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"));
    7677      }
    7778      return result;
  • applications/editors/josm/plugins/MicrosoftStreetside/src/org/openstreetmap/josm/plugins/streetside/gui/imageinfo/AddTagToPrimitiveAction.java

    r34577 r36194  
    4444      int conflictResolution = JOptionPane.YES_OPTION;
    4545      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);
    5953      }
    6054      if (JOptionPane.YES_OPTION == conflictResolution) {
  • applications/editors/josm/plugins/MicrosoftStreetside/src/org/openstreetmap/josm/plugins/streetside/gui/imageinfo/ClipboardAction.java

    r34433 r36194  
    6767  /**
    6868   * Sets the component, under which the popup will be shown, which indicates that the key was copied to the clipboard.
     69   *
    6970   * @param popupParent the component to set as parent of the popup
    7071   */
  • applications/editors/josm/plugins/MicrosoftStreetside/src/org/openstreetmap/josm/plugins/streetside/gui/imageinfo/ImageInfoHelpPopup.java

    r34412 r36194  
    77import java.awt.IllegalComponentStateException;
    88import java.awt.event.ActionEvent;
     9import java.util.logging.Logger;
    910
    1011import javax.swing.AbstractAction;
     
    1415import javax.swing.JTextPane;
    1516
    16 import org.apache.log4j.Logger;
    1717import org.openstreetmap.josm.plugins.streetside.gui.boilerplate.SelectableLabel;
    1818import org.openstreetmap.josm.plugins.streetside.gui.boilerplate.StreetsideButton;
     
    2121import org.openstreetmap.josm.tools.I18n;
    2222import org.openstreetmap.josm.tools.ImageProvider;
     23import org.openstreetmap.josm.tools.Logging;
    2324
    2425public class ImageInfoHelpPopup extends JPopupMenu {
     
    2627  private static final long serialVersionUID = -1721594904273820586L;
    2728
    28   final static Logger logger = Logger.getLogger(ImageInfoHelpPopup.class);
     29  private static final Logger LOGGER = Logger.getLogger(ImageInfoHelpPopup.class.getCanonicalName());
    2930
    3031  private final Component invokerComp;
     
    4445    mainText.setContentType("text/html");
    4546    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>");
    5152    add(mainText, BorderLayout.CENTER);
    5253
     
    5657    infoButton.addActionListener(e -> setVisible(false));
    5758    bottomBar.add(infoButton);
    58                 StreetsideButton closeBtn = new StreetsideButton(new AbstractAction() {
     59    StreetsideButton closeBtn = new StreetsideButton(new AbstractAction() {
    5960
    60                         private static final long serialVersionUID = 2853315308169651854L;
     61      private static final long serialVersionUID = 2853315308169651854L;
    6162
    62                         @Override
    63                         public void actionPerformed(ActionEvent e) {
    64                                 setVisible(false);
    65                                 StreetsideProperties.IMAGEINFO_HELP_COUNTDOWN.put(0);
    66                         }
    67                 });
     63      @Override
     64      public void actionPerformed(ActionEvent e) {
     65        setVisible(false);
     66        StreetsideProperties.IMAGEINFO_HELP_COUNTDOWN.put(0);
     67      }
     68    });
    6869
    69                 closeBtn.setText(I18n.tr("I got it, close this."));
    70                 bottomBar.add(closeBtn);
    71                 add(bottomBar, BorderLayout.SOUTH);
     70    closeBtn.setText(I18n.tr("I got it, close this."));
     71    bottomBar.add(closeBtn);
     72    add(bottomBar, BorderLayout.SOUTH);
    7273
    73                 setBackground(Color.WHITE);
    74         }
     74    setBackground(Color.WHITE);
     75  }
    7576
    7677  /**
     
    8485        return true;
    8586      } 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));
    8790      }
    8891    }
  • applications/editors/josm/plugins/MicrosoftStreetside/src/org/openstreetmap/josm/plugins/streetside/gui/imageinfo/ImageInfoPanel.java

    r34416 r36194  
    77import java.awt.datatransfer.StringSelection;
    88import java.util.Collection;
     9import java.util.logging.Logger;
    910
    1011import javax.swing.JLabel;
     
    1213import javax.swing.JTextPane;
    1314
    14 import org.apache.log4j.Logger;
    1515import org.openstreetmap.josm.data.osm.DataSelectionListener;
    1616import org.openstreetmap.josm.data.osm.OsmPrimitive;
     
    2727import org.openstreetmap.josm.plugins.streetside.utils.StreetsideURL;
    2828import org.openstreetmap.josm.tools.I18n;
     29import org.openstreetmap.josm.tools.Logging;
    2930
    3031public final class ImageInfoPanel extends ToggleDialog implements StreetsideDataListener, DataSelectionListener {
    3132  private static final long serialVersionUID = 4141847503072417190L;
    3233
    33   final static Logger logger = Logger.getLogger(ImageInfoPanel.class);
     34  private static final Logger LOGGER = Logger.getLogger(ImageInfoPanel.class.getCanonicalName());
    3435
    3536  private static ImageInfoPanel instance;
     
    4445
    4546  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);
    5349    SelectionEventManager.getInstance().addSelectionListener(this);
    5450
     
    153149   */
    154150  @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›"));
    161156
    162157    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;
    164159    if (newImageKey != null) {
    165       imageLinkChangeListener = b -> imgLinkAction.setURL(
    166         StreetsideURL.MainWebsite.browseImage(newImageKey)
    167       );
     160      imageLinkChangeListener = b -> imgLinkAction.setURL(StreetsideURL.MainWebsite.browseImage(newImageKey));
    168161      imageLinkChangeListener.valueChanged(null);
    169162      StreetsideProperties.IMAGE_LINK_TO_BLUR_EDITOR.addListener(imageLinkChangeListener);
     
    184177    }
    185178
    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;
    187181    seqKeyValue.setEnabled(partOfSequence);
    188182    if (partOfSequence) {
     
    199193  public synchronized void selectionChanged(final SelectionChangeEvent event) {
    200194    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()));
    203198    }
    204199    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  
    88import java.awt.event.ActionEvent;
    99import java.text.MessageFormat;
     10import java.util.logging.Logger;
    1011
    1112import javax.swing.AbstractAction;
     
    1516import javax.swing.JTextPane;
    1617
    17 import org.apache.log4j.Logger;
    1818import org.openstreetmap.josm.plugins.streetside.gui.boilerplate.SelectableLabel;
    1919import org.openstreetmap.josm.plugins.streetside.gui.boilerplate.StreetsideButton;
     
    2222import org.openstreetmap.josm.tools.I18n;
    2323import org.openstreetmap.josm.tools.ImageProvider;
    24 
     24import org.openstreetmap.josm.tools.Logging;
    2525
    2626public class StreetsideViewerHelpPopup extends JPopupMenu {
    2727
    28         private static final long serialVersionUID = -7840242522398163839L;
     28  private static final long serialVersionUID = -7840242522398163839L;
    2929
    30         final static Logger logger = Logger.getLogger(StreetsideViewerHelpPopup.class);
     30  private static final Logger LOGGER = Logger.getLogger(StreetsideViewerHelpPopup.class.getCanonicalName());
    3131
    32         private final Component invokerComp;
    33         private boolean alreadyDisplayed;
     32  private final Component invokerComp;
     33  private boolean alreadyDisplayed;
    3434
    35         public StreetsideViewerHelpPopup(Component invoker) {
     35  public StreetsideViewerHelpPopup(Component invoker) {
    3636
    37                 invokerComp = invoker;
    38                 removeAll();
    39                 setLayout(new BorderLayout());
     37    invokerComp = invoker;
     38    removeAll();
     39    setLayout(new BorderLayout());
    4040
    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);
     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);
    4545
    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);
    5655
    57                 JPanel bottomBar = new JPanel();
    58                 bottomBar.setBackground(new Color(0x00FFFFFF, true));
    59                 StreetsideButton infoButton = new StreetsideButton(ImageInfoPanel.getInstance().getToggleAction());
    60                 infoButton.addActionListener(e -> setVisible(false));
    61                 bottomBar.add(infoButton);
    62                 StreetsideButton closeBtn = new StreetsideButton(new AbstractAction() {
    63                         private static final long serialVersionUID = -6193886964751195196L;
     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;
    6463
    65                         @Override
    66                         public void actionPerformed(ActionEvent e) {
    67                                 setVisible(false);
    68                                 StreetsideProperties.IMAGEINFO_HELP_COUNTDOWN.put(0);
    69                         }
    70                 });
     64      @Override
     65      public void actionPerformed(ActionEvent e) {
     66        setVisible(false);
     67        StreetsideProperties.IMAGEINFO_HELP_COUNTDOWN.put(0);
     68      }
     69    });
    7170
    72                 closeBtn.setText(I18n.tr("I got it, close this."));
    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);
    7574
    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  }
    7795}
    78 
    79 /**
    80 * @return <code>true</code> if the popup is displayed
    81 */
    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.
    22package org.openstreetmap.josm.plugins.streetside.gui.imageinfo;
    33
     
    55import java.awt.GraphicsEnvironment;
    66import java.text.MessageFormat;
     7import java.util.logging.Logger;
    78
    89import javax.swing.JCheckBox;
     
    1011import javax.swing.SwingUtilities;
    1112
    12 import org.apache.log4j.Logger;
    1313import org.openstreetmap.josm.data.preferences.AbstractProperty.ValueChangeListener;
    1414import org.openstreetmap.josm.plugins.streetside.StreetsideAbstractImage;
     
    2424import org.openstreetmap.josm.plugins.streetside.utils.StreetsideURL;
    2525import org.openstreetmap.josm.tools.I18n;
     26import org.openstreetmap.josm.tools.Logging;
    2627
    27 public final class StreetsideViewerPanel extends JPanel
    28                 implements StreetsideDataListener {
     28public final class StreetsideViewerPanel extends JPanel implements StreetsideDataListener {
    2929
    30         private static final long serialVersionUID = 4141847503072417190L;
     30  private static final long serialVersionUID = 4141847503072417190L;
    3131
    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;
    4138  private StreetsideViewerHelpPopup streetsideViewerHelp;
    4239
    43         public StreetsideViewerPanel() {
     40  public StreetsideViewerPanel() {
    4441
    45                 super(new BorderLayout());
     42    super(new BorderLayout());
    4643
    47                 SwingUtilities.invokeLater(() -> initializeAndStartGUI());
     44    SwingUtilities.invokeLater(this::initializeAndStartGUI);
    4845
    49                 selectedImageChanged(null, null);
     46    selectedImageChanged(null, null);
    5047
    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  }
    5351
    54         private void initializeAndStartGUI() {
     52  public static CubemapBox getCubemapBox() {
     53    return threeSixtyDegreeViewerPanel.getCubemapBox();
     54  }
    5555
    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();
    5766
    5867    if (!GraphicsEnvironment.isHeadless()) {
     
    6069    }
    6170
    62                 add(threeSixtyDegreeViewerPanel, BorderLayout.CENTER);
    63                 revalidate();
    64                 repaint();
    65             JPanel checkPanel = new JPanel();
     71    add(threeSixtyDegreeViewerPanel, BorderLayout.CENTER);
     72    revalidate();
     73    repaint();
     74    JPanel checkPanel = new JPanel();
    6675
    67             imgReloadAction = new ImageReloadAction("Reload");
     76    imgReloadAction = new ImageReloadAction("Reload");
    6877
    69             StreetsideButton imgReloadButton = new StreetsideButton(imgReloadAction);
     78    StreetsideButton imgReloadButton = new StreetsideButton(imgReloadAction);
    7079
    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);
    8188
    82             JPanel privacyLink = new JPanel();
     89    JPanel privacyLink = new JPanel();
    8390
    84             imgLinkAction = new WebLinkAction("Report a privacy concern with this image", null);
    85             privacyLink.add(new StreetsideButton(imgLinkAction, true));
    86             checkPanel.add(privacyLink, BorderLayout.PAGE_END);
     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);
    8794
    88             add(threeSixtyDegreeViewerPanel, BorderLayout.CENTER);
     95    add(threeSixtyDegreeViewerPanel, BorderLayout.CENTER);
    8996
    90             JPanel bottomPanel = new JPanel();
    91             bottomPanel.add(checkPanel, BorderLayout.NORTH);
    92             bottomPanel.add(privacyLink, BorderLayout.SOUTH);
     97    JPanel bottomPanel = new JPanel();
     98    bottomPanel.add(checkPanel, BorderLayout.NORTH);
     99    bottomPanel.add(privacyLink, BorderLayout.SOUTH);
    93100
    94             add(bottomPanel, BorderLayout.PAGE_END);
    95         }
     101    add(bottomPanel, BorderLayout.PAGE_END);
     102  }
    96103
    97         /*
    98         * (non-Javadoc)
    99         *
    100         * @see
    101         * org.openstreetmap.josm.plugins.streetside.StreetsideDataListener#imagesAdded(
    102         * )
    103         */
    104         @Override
    105         public void imagesAdded() {
    106                 // Method is not needed, but enforcesd by the interface StreetsideDataListener
    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  }
    108115
    109         /*
    110         * (non-Javadoc)
    111         *
    112         * @see org.openstreetmap.josm.plugins.streetside.StreetsideDataListener#
    113         * selectedImageChanged(org.openstreetmap.josm.plugins.streetside.
    114         * StreetsideAbstractImage,
    115         * org.openstreetmap.josm.plugins.streetside.StreetsideAbstractImage)
    116         */
    117         @Override
    118         public synchronized void selectedImageChanged(final StreetsideAbstractImage oldImage,
    119                         final StreetsideAbstractImage newImage) {
     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) {
    120127
    121                 // method is invoked with null initially by framework
    122                 if(newImage!=null) {
     128    // method is invoked with null initially by framework
     129    if (newImage != null) {
    123130
    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›"));
    129134
    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));
    136142
    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        }
    140147
    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  }
    163159}
  • 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.
    22package org.openstreetmap.josm.plugins.streetside.gui.imageinfo;
    33
     
    1111import javafx.scene.PointLight;
    1212import javafx.scene.Scene;
     13import javafx.scene.SceneAntialiasing;
    1314import javafx.scene.control.Label;
    14 import javafx.scene.SceneAntialiasing;
    1515import javafx.scene.control.TextArea;
    1616import javafx.scene.image.Image;
     
    2626
    2727  private static final long serialVersionUID = -4940350009018422000L;
    28 
     28  private static final CameraTransformer cameraTransform = new CameraTransformer();
     29  private static final double cameraDistance = 5000;
    2930  private static Scene cubemapScene;
    30 
    3131  private static Scene defaultScene;
    3232  private static Scene loadingScene;
    33 
    3433  private static Group root;
    3534  private static Group subGroup;
    3635  private static CubemapBox cubemapBox;
    3736  private static PerspectiveCamera camera;
    38   private static CameraTransformer cameraTransform = new CameraTransformer();
    39 
    4037  private static double mousePosX;
    4138  private static double mousePosY;
     
    4441  private static double mouseDeltaX;
    4542  private static double mouseDeltaY;
    46   private static double cameraDistance = 5000;
    47 
    4843  private static Image front;
    4944  private static Image right;
     
    5550  public ThreeSixtyDegreeViewerPanel() {
    5651
    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       @Override
    90       public void run() {
    91         setScene(createDefaultScene());
    92       }
    93     });
    9452  }
    9553
     
    177135      if (me.isPrimaryButtonDown()) {
    178136        cameraTransform.ry.setAngle(
    179           ((cameraTransform.ry.getAngle() + mouseDeltaX * modifierFactor * modifier * 2.0) % 360 + 540) % 360 - 180
    180         ); // +
     137            ((cameraTransform.ry.getAngle() + mouseDeltaX * modifierFactor * modifier * 2.0) % 360 + 540)
     138                % 360 - 180); // +
    181139        cameraTransform.rx.setAngle(
    182           ((cameraTransform.rx.getAngle() - mouseDeltaY * modifierFactor * modifier * 2.0) % 360 + 540) % 360 - 180
    183         ); // -
     140            ((cameraTransform.rx.getAngle() - mouseDeltaY * modifierFactor * modifier * 2.0) % 360 + 540)
     141                % 360 - 180); // -
    184142
    185143      } else if (me.isSecondaryButtonDown()) {
     
    212170  }
    213171
     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
    214204  public CubemapBox getCubemapBox() {
    215205    if (cubemapBox == null) {
  • applications/editors/josm/plugins/MicrosoftStreetside/src/org/openstreetmap/josm/plugins/streetside/gui/imageinfo/WebLinkAction.java

    r34416 r36194  
    55import java.io.IOException;
    66import java.net.URL;
     7import java.util.logging.Logger;
    78
    89import javax.swing.AbstractAction;
    910import javax.swing.JOptionPane;
    1011
    11 import org.apache.log4j.Logger;
    1212import org.openstreetmap.josm.gui.Notification;
    1313import org.openstreetmap.josm.plugins.streetside.utils.StreetsideUtils;
    1414import org.openstreetmap.josm.tools.ImageProvider;
    1515import org.openstreetmap.josm.tools.ImageProvider.ImageSizes;
     16import org.openstreetmap.josm.tools.Logging;
    1617
    1718public class WebLinkAction extends AbstractAction {
     
    1920  private static final long serialVersionUID = -8168227661356480455L;
    2021
    21   final static Logger logger = Logger.getLogger(WebLinkAction.class);
     22  private static final Logger LOGGER = Logger.getLogger(WebLinkAction.class.getCanonicalName());
    2223
    2324  private URL url;
     
    4546    } catch (IOException e1) {
    4647      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);
    4849      new Notification(msg).setIcon(JOptionPane.WARNING_MESSAGE).show();
    4950    }
  • applications/editors/josm/plugins/MicrosoftStreetside/src/org/openstreetmap/josm/plugins/streetside/history/StreetsideRecord.java

    r34400 r36194  
    1717*/
    1818public 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;
    2123
    22 private final List<StreetsideRecordListener> listeners = new ArrayList<>();
     24  private final List<StreetsideRecordListener> listeners = new ArrayList<>();
    2325
    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;
    2834
    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  }
    35140}
    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 lis
    52 *          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 lis
    62 *          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 command
    72 *          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 command
    79  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  
    1111public interface StreetsideRecordListener {
    1212
    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();
    1717}
  • applications/editors/josm/plugins/MicrosoftStreetside/src/org/openstreetmap/josm/plugins/streetside/history/commands/CommandJoin.java

    r34317 r36194  
    2727   * @param b the second image, that is joined with the first one
    2828   * @throws IllegalArgumentException if the images are already in the same sequence
    29    * @throws NullPointerException if {@code a} or {@code b} is null
     29   * @throws NullPointerException   if {@code a} or {@code b} is null
    3030   */
    3131  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  
    2222   * Main constructor.
    2323   *
    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.
    3027   */
    31   public CommandMove(Set<StreetsideAbstractImage> images, double x,
    32                      double y) {
     28  public CommandMove(Set<StreetsideAbstractImage> images, double x, double y) {
    3329    super(images);
    3430    this.x = x;
     
    5652  @Override
    5753  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());
    6055  }
    6156
  • applications/editors/josm/plugins/MicrosoftStreetside/src/org/openstreetmap/josm/plugins/streetside/history/commands/CommandTurn.java

    r34432 r36194  
    2121   * Main constructor.
    2222   *
    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.
    2725   */
    2826  public CommandTurn(Set<StreetsideAbstractImage> images, double ca) {
     
    5149  @Override
    5250  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());
    5552  }
    5653
  • applications/editors/josm/plugins/MicrosoftStreetside/src/org/openstreetmap/josm/plugins/streetside/history/commands/CommandUnjoin.java

    r34416 r36194  
    2424   * Main constructor.
    2525   *
    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.
    3129   */
    3230  public CommandUnjoin(List<StreetsideAbstractImage> images) {
  • applications/editors/josm/plugins/MicrosoftStreetside/src/org/openstreetmap/josm/plugins/streetside/history/commands/StreetsideCommand.java

    r34317 r36194  
    1414*/
    1515public 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;
    1820
    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();
    2750}
    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 command
    44 *          The command to be summed to last command.
    45 */
    46 public abstract void sum(StreetsideCommand command);
    47 
    48 @Override
    49 public abstract String toString();
    50 }
  • applications/editors/josm/plugins/MicrosoftStreetside/src/org/openstreetmap/josm/plugins/streetside/history/commands/StreetsideExecutableCommand.java

    r34317 r36194  
    1414public abstract class StreetsideExecutableCommand extends StreetsideCommand {
    1515
    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();
    2430}
    25 
    26 /**
    27 * Executes the command. It is run when the command is added to the history
    28 * 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  
    77import java.net.URL;
    88import java.net.URLConnection;
    9 import java.text.MessageFormat;
    109import java.util.function.Function;
     10import java.util.logging.Logger;
    1111
    12 import org.apache.log4j.Logger;
    1312import org.openstreetmap.josm.data.Bounds;
    1413import org.openstreetmap.josm.gui.Notification;
     
    1716import org.openstreetmap.josm.plugins.streetside.utils.StreetsideURL.APIv3;
    1817import org.openstreetmap.josm.tools.ImageProvider.ImageSizes;
     18import org.openstreetmap.josm.tools.Logging;
    1919
    2020public abstract class BoundsDownloadRunnable implements Runnable {
    2121
    22   final static Logger logger = Logger.getLogger(BoundsDownloadRunnable.class);
     22  private static final Logger LOGGER = Logger.getLogger(BoundsDownloadRunnable.class.getCanonicalName());
    2323
    2424  protected Bounds bounds;
    25   protected abstract Function<Bounds, URL> getUrlGenerator();
    2625
    27   public BoundsDownloadRunnable(final Bounds bounds) {
     26  protected BoundsDownloadRunnable(final Bounds bounds) {
    2827    this.bounds = bounds;
    2928  }
     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();
    3054
    3155  @Override
    3256  public void run() {
    3357    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);
    3660    }
    3761    try {
    3862      while (nextURL != null) {
    3963        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 });
    4166          return;
    4267        }
     
    4671      }
    4772    } 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);
    5075      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();
    5578      }
    56       e.printStackTrace();
    5779    }
    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 logged
    65    * @param info an additional info text, which is appended to the output in braces
    66    * @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());
    8180  }
    8281
  • applications/editors/josm/plugins/MicrosoftStreetside/src/org/openstreetmap/josm/plugins/streetside/io/download/SequenceDownloadRunnable.java

    r34433 r36194  
    22package org.openstreetmap.josm.plugins.streetside.io.download;
    33
    4 import java.io.BufferedInputStream;
    54import java.io.IOException;
    65import java.net.URL;
     
    1110import java.util.List;
    1211import java.util.function.Function;
     12import java.util.logging.Logger;
    1313
    1414import org.openstreetmap.josm.data.Bounds;
     
    2222import org.openstreetmap.josm.plugins.streetside.utils.StreetsideSequenceIdGenerator;
    2323import org.openstreetmap.josm.plugins.streetside.utils.StreetsideURL.APIv3;
     24import org.openstreetmap.josm.tools.Logging;
    2425
    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;
     26import jakarta.json.Json;
     27import jakarta.json.JsonException;
     28import jakarta.json.JsonObject;
     29import jakarta.json.JsonValue;
     30import jakarta.json.stream.JsonParser;
    3231
    3332public final class SequenceDownloadRunnable extends BoundsDownloadRunnable {
    34 
    35         private final StreetsideData data;
    36 
     33  private static final Logger LOG = Logger.getLogger(BoundsDownloadRunnable.class.getCanonicalName());
    3734  private static final Function<Bounds, URL> URL_GEN = APIv3::searchStreetsideImages;
     35  private final StreetsideData data;
    3836
    3937  public SequenceDownloadRunnable(final StreetsideData data, final Bounds bounds) {
     
    5452    final long startTime = System.currentTimeMillis();
    5553
    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      }
    6058
    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;
    6360
    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) {
    7462        // read everything from this START_OBJECT to the matching END_OBJECT
    7563        // and return it as a tree model ObjectNode
    76         ObjectNode node = mapper.readTree(parser);
     64        JsonObject node = parser.getObject();
    7765        // Discard the first sequence ('enabled') - it does not contain bubble data
    7866        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) {
    8172            image.setPr(Long.parseLong(previous.getId()));
    8273            previous.setNe(Long.parseLong(image.getId()));
     
    8475          }
    8576          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));
    9697
    9798          // Add list of cubemap tile images to images
     
    103104              // Initialize four-tiled cubemap faces (four images per cube side with 18-length
    104105              // 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);
    107108                tiles.add(tile);
    108109              }
    109110              // Initialize four-tiled cubemap faces (four images per cub eside with 20-length
    110111              // Quadkey)
    111               if (StreetsideProperties.SHOW_HIGH_RES_STREETSIDE_IMAGERY.get()) {
     112              if (Boolean.TRUE.equals(StreetsideProperties.SHOW_HIGH_RES_STREETSIDE_IMAGERY.get())) {
    112113                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)));
    118117                  tiles.add(tile);
    119118                }
     
    122121          });
    123122
    124           bubbleImages.add(image);
    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())) {
    127126            StreetsideData.downloadSurroundingCubemaps(image);
    128127          }
    129128        } else {
    130           logger.info(MessageFormat.format("Unparsable JSON node object: {0}",node.toString()));
     129          LOG.info(MessageFormat.format("Unparsable JSON node object: {0}", node));
    131130        }
    132131      }
    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()));
    140135    } 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()));
    142138    }
    143139
    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
    145142     *  so a sequence needs to be created and have images added to it. If the distribution
    146143     *  of Streetside images is non-sequential, the Mapillary "Walking Action" may behave
    147144     *  unpredictably.
    148      **/
     145     */
    149146    seq.add(bubbleImages);
    150147
    151     if (StreetsideProperties.CUT_OFF_SEQUENCES_AT_BOUNDS.get()) {
     148    if (Boolean.TRUE.equals(StreetsideProperties.CUT_OFF_SEQUENCES_AT_BOUNDS.get())) {
    152149      for (StreetsideAbstractImage img : seq.getImages()) {
    153150        if (bounds.contains(img.getLatLon())) {
     
    168165
    169166    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));
    171169  }
    172170
  • applications/editors/josm/plugins/MicrosoftStreetside/src/org/openstreetmap/josm/plugins/streetside/io/download/StreetsideDownloader.java

    r34399 r36194  
    55import java.util.concurrent.ThreadPoolExecutor;
    66import java.util.concurrent.TimeUnit;
    7 
    8 import org.apache.log4j.Logger;
     7import java.util.logging.Logger;
     8
    99import org.openstreetmap.josm.data.Bounds;
    1010import org.openstreetmap.josm.data.coor.LatLon;
     
    1515import org.openstreetmap.josm.plugins.streetside.utils.StreetsideProperties;
    1616import org.openstreetmap.josm.tools.I18n;
     17import org.openstreetmap.josm.tools.Logging;
    1718
    1819/**
     
    2425public final class StreetsideDownloader {
    2526
    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   */
    29194  public enum DOWNLOAD_MODE {
    30195    VISIBLE_AREA("visibleArea", I18n.tr("everything in the visible area")),
     
    34199    MANUAL_ONLY("manualOnly", I18n.tr("only when manually requested"));
    35200
    36     public final static DOWNLOAD_MODE DEFAULT = OSM_AREA;
     201    public static final DOWNLOAD_MODE DEFAULT = OSM_AREA;
    37202
    38203    private final String prefId;
     
    42207      this.prefId = prefId;
    43208      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;
    44227    }
    45228
     
    57240      return label;
    58241    }
    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 instantiation
    94   }
    95 
    96   /**
    97    * Gets all the images in a square. It downloads all the images of all the
    98    * 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 rectangle
    102    */
    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 the
    171    * 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 probably
    199    * lots of Streetside images are going to be downloaded, slowing down the
    200    * program too much. A notification is shown when the download has stopped or continued.
    201    * @param area area to check
    202    * @return {@code true} if the area is too big
    203    */
    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_AREA
    210           ? "\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());
    234242  }
    235243}
  • applications/editors/josm/plugins/MicrosoftStreetside/src/org/openstreetmap/josm/plugins/streetside/io/download/StreetsideSquareDownloadRunnable.java

    r34412 r36194  
    22package org.openstreetmap.josm.plugins.streetside.io.download;
    33
    4 import org.apache.log4j.Logger;
    54import org.openstreetmap.josm.data.Bounds;
    65import org.openstreetmap.josm.plugins.streetside.StreetsideLayer;
     
    1110public class StreetsideSquareDownloadRunnable implements Runnable {
    1211
    13   final static Logger logger = Logger.getLogger(StreetsideSquareDownloadRunnable.class);
    14 
    1512  private final Bounds bounds;
    1613
     
    1916   *
    2017   * @param bounds the bounds of the area that should be downloaded
    21    *
    2218   */
    2319  public StreetsideSquareDownloadRunnable(Bounds bounds) {
  • applications/editors/josm/plugins/MicrosoftStreetside/src/org/openstreetmap/josm/plugins/streetside/io/export/StreetsideExportDownloadThread.java

    r34416 r36194  
    66import java.io.IOException;
    77import java.util.concurrent.ArrayBlockingQueue;
     8import java.util.logging.Logger;
    89
    910import javax.imageio.ImageIO;
    1011
    11 import org.apache.log4j.Logger;
    1212import org.openstreetmap.josm.data.cache.CacheEntry;
    1313import org.openstreetmap.josm.data.cache.CacheEntryAttributes;
     
    1717import org.openstreetmap.josm.plugins.streetside.cache.CacheUtils;
    1818import org.openstreetmap.josm.plugins.streetside.cache.StreetsideCache;
     19import org.openstreetmap.josm.tools.Logging;
    1920
    2021/**
     
    2627 * @see StreetsideExportWriterThread
    2728 */
    28 public class StreetsideExportDownloadThread extends Thread implements
    29     ICachedLoaderListener {
     29public class StreetsideExportDownloadThread extends Thread implements ICachedLoaderListener {
    3030
    31   final static Logger logger = Logger.getLogger(StreetsideExportDownloadThread.class);
     31  private static final Logger LOGGER = Logger.getLogger(StreetsideExportDownloadThread.class.getCanonicalName());
    3232
    3333  private final ArrayBlockingQueue<BufferedImage> queue;
     
    3939   * Main constructor.
    4040   *
    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
    4543   *          {@link StreetsideExportWriterThread}.
    46    * @param queueImages
    47    *          Queue of {@link StreetsideAbstractImage} objects for the
     44   * @param queueImages Queue of {@link StreetsideAbstractImage} objects for the
    4845   *          {@link StreetsideExportWriterThread}.
    4946   */
    50   public StreetsideExportDownloadThread(StreetsideImage image,
    51       ArrayBlockingQueue<BufferedImage> queue,
     47  public StreetsideExportDownloadThread(StreetsideImage image, ArrayBlockingQueue<BufferedImage> queue,
    5248      ArrayBlockingQueue<StreetsideAbstractImage> queueImages) {
    5349    this.queue = queue;
     
    6359
    6460  @Override
    65   public synchronized void loadingFinished(CacheEntry data,
    66       CacheEntryAttributes attributes, LoadResult result) {
     61  public synchronized void loadingFinished(CacheEntry data, CacheEntryAttributes attributes, LoadResult result) {
    6762    try {
    6863      synchronized (StreetsideExportDownloadThread.class) {
    69         queue
    70             .put(ImageIO.read(new ByteArrayInputStream(data.getContent())));
     64        queue.put(ImageIO.read(new ByteArrayInputStream(data.getContent())));
    7165        queueImages.put(image);
    7266      }
    7367    } catch (InterruptedException | IOException e) {
    74       logger.error(e);
     68      LOGGER.log(Logging.LEVEL_ERROR, e.getMessage(), e);
    7569    }
    7670  }
  • applications/editors/josm/plugins/MicrosoftStreetside/src/org/openstreetmap/josm/plugins/streetside/io/export/StreetsideExportManager.java

    r34429 r36194  
    1111import java.util.concurrent.ThreadPoolExecutor;
    1212import java.util.concurrent.TimeUnit;
     13import java.util.logging.Logger;
    1314
    14 import org.apache.log4j.Logger;
    1515import org.openstreetmap.josm.gui.PleaseWaitRunnable;
    1616import org.openstreetmap.josm.gui.progress.swing.PleaseWaitProgressMonitor;
    1717import org.openstreetmap.josm.plugins.streetside.StreetsideAbstractImage;
    1818import org.openstreetmap.josm.plugins.streetside.StreetsideImage;
     19import org.openstreetmap.josm.tools.Logging;
    1920
    2021/**
     
    3233public class StreetsideExportManager extends PleaseWaitRunnable {
    3334
    34   final static Logger logger = Logger.getLogger(StreetsideExportManager.class);
     35  private static final Logger LOGGER = Logger.getLogger(StreetsideExportManager.class.getCanonicalName());
    3536
    3637  private final ArrayBlockingQueue<BufferedImage> queue = new ArrayBlockingQueue<>(10);
    3738  private final ArrayBlockingQueue<StreetsideAbstractImage> queueImages = new ArrayBlockingQueue<>(10);
    3839
    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;
    4243
    4344  private Thread writer;
     
    4849   *
    4950   * @param images Set of {@link StreetsideAbstractImage} objects to be exported.
    50    * @param path Export path.
     51   * @param path   Export path.
    5152   */
    5253  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);
    5855    this.images = images == null ? new HashSet<>() : images;
    5956    this.path = path;
     
    7067  protected void realRun() throws IOException {
    7168    // 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());
    7470    writer.start();
    7571    if (path == null) {
     
    7773        writer.join();
    7874      } catch (InterruptedException e) {
    79         logger.error(e);
     75        LOGGER.log(Logging.LEVEL_ERROR, e.getMessage(), e);
    8076      }
    8177      return;
    8278    }
    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));
    8580    for (StreetsideAbstractImage image : images) {
    8681      if (image instanceof StreetsideImage) {
    8782        try {
    88           ex.execute(new StreetsideExportDownloadThread(
    89               (StreetsideImage) image, queue, queueImages));
     83          ex.execute(new StreetsideExportDownloadThread((StreetsideImage) image, queue, queueImages));
    9084        } catch (Exception e) {
    91           logger.error(e);
     85          LOGGER.log(Logging.LEVEL_ERROR, e.getMessage(), e);
    9286        }
    9387      }
     
    9993        }
    10094      } catch (Exception e) {
    101         logger.error(e);
     95        LOGGER.log(Logging.LEVEL_ERROR, e.getMessage(), e);
    10296      }
    10397    }
     
    10599      writer.join();
    106100    } catch (InterruptedException e) {
    107       logger.error(e);
     101      LOGGER.log(Logging.LEVEL_ERROR, e.getMessage(), e);
    108102    }
    109103  }
  • applications/editors/josm/plugins/MicrosoftStreetside/src/org/openstreetmap/josm/plugins/streetside/io/export/StreetsideExportWriterThread.java

    r34429 r36194  
    99import java.io.OutputStream;
    1010import java.util.concurrent.ArrayBlockingQueue;
     11import java.util.logging.Logger;
    1112
    1213import javax.imageio.ImageIO;
     
    2021import org.apache.commons.imaging.formats.tiff.write.TiffOutputDirectory;
    2122import org.apache.commons.imaging.formats.tiff.write.TiffOutputSet;
    22 import org.apache.log4j.Logger;
    2323import org.openstreetmap.josm.gui.progress.ProgressMonitor;
    2424import org.openstreetmap.josm.gui.progress.swing.PleaseWaitProgressMonitor;
    2525import org.openstreetmap.josm.plugins.streetside.StreetsideAbstractImage;
     26import org.openstreetmap.josm.tools.Logging;
    2627
    2728/**
     
    3334public class StreetsideExportWriterThread extends Thread {
    3435
    35   final static Logger logger = Logger.getLogger(StreetsideExportWriterThread.class);
     36  private static final Logger LOGGER = Logger.getLogger(StreetsideExportWriterThread.class.getCanonicalName());
    3637
    3738  private final String path;
     
    4445   * Main constructor.
    4546   *
    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.
    5652   */
    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) {
    6155    this.path = path;
    6256    this.queue = queue;
     
    7670        img = queue.take();
    7771        mimg = queueImages.take();
    78 
    7972
    8073        // Transforms the image into a byte array.
     
    10093
    10194        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()));
    10496
    10597        exifDirectory.removeField(ExifTagConstants.EXIF_TAG_DATE_TIME_ORIGINAL);
     
    111103        os.close();
    112104      } catch (InterruptedException e) {
    113         logger.info("Streetside export cancelled");
     105        LOGGER.info("Streetside export cancelled");
    114106        return;
    115107      } catch (IOException | ImageReadException | ImageWriteException e) {
    116         logger.error(e);
     108        LOGGER.log(Logging.LEVEL_ERROR, e.getMessage(), e);
    117109      }
    118110
  • applications/editors/josm/plugins/MicrosoftStreetside/src/org/openstreetmap/josm/plugins/streetside/mode/AbstractMode.java

    r34400 r36194  
    2222 * @see StreetsideLayer
    2323 */
    24 public abstract class AbstractMode extends MouseAdapter implements
    25   ZoomChangeListener {
     24public abstract class AbstractMode extends MouseAdapter implements ZoomChangeListener {
    2625
    2726  private static final int DOWNLOAD_COOLDOWN = 2000;
     
    3332  public int cursor = Cursor.DEFAULT_CURSOR;
    3433
     34  /**
     35   * Resets the semiautomatic mode thread.
     36   */
     37  public static void resetThread() {
     38    semiautomaticThread.interrupt();
     39    semiautomaticThread = new SemiautomaticThread();
     40  }
     41
    3542  protected StreetsideAbstractImage getClosest(Point clickPoint) {
    3643    double snapDistance = 10;
     
    4148      imagePoint.setLocation(imagePoint.getX(), imagePoint.getY());
    4249      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()) {
    4551        minDistance = dist;
    4652        closest = image;
     
    5359   * Paint the dataset using the engine set.
    5460   *
    55    * @param g {@link Graphics2D} used for painting
    56    * @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.
    5763   * @param box Area where painting is going to be performed
    5864   */
     
    6874  }
    6975
    70   /**
    71    * Resets the semiautomatic mode thread.
    72    */
    73   public static void resetThread() {
    74     semiautomaticThread.interrupt();
    75     semiautomaticThread = new SemiautomaticThread();
    76   }
    77 
    7876  private static class SemiautomaticThread extends Thread {
    7977
    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     */
    8181    private long lastDownload;
    8282
  • applications/editors/josm/plugins/MicrosoftStreetside/src/org/openstreetmap/josm/plugins/streetside/mode/SelectMode.java

    r34627 r36194  
    3535 */
    3636public class SelectMode extends AbstractMode {
     37  private final StreetsideRecord record;
    3738  private StreetsideAbstractImage closest;
    3839  private StreetsideAbstractImage lastClicked;
    39   private final StreetsideRecord record;
    4040  private boolean nothingHighlighted;
    4141  private boolean imageHighlighted;
     
    5454    }
    5555    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) {
    5858      lastClicked = this.closest;
    5959      StreetsideLayer.getInstance().getData().setSelectedImage(closest);
     
    6363    }
    6464    // 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) {
    6667      closest.getSequence().getImages().forEach(StreetsideLayer.getInstance().getData()::addMultiSelectedImage);
    6768    }
     
    7576      StreetsideLayer.getInstance().getData().addMultiSelectedImage(closest);
    7677      // 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()) {
    8381        int i = this.closest.getSequence().getImages().indexOf(this.closest);
    8482        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)));
    9086      }
    9187      // click
     
    9894  public void mouseDragged(MouseEvent e) {
    9995    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) {
    10598      Point highlightImgPoint = MainApplication.getMap().mapView.getPoint(highlightImg.getTempLatLon());
    10699      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()));
    109105      } else { // move
    110106        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()));
    114113      }
    115114      StreetsideLayer.invalidateInstance();
     
    127126      double to = data.getSelectedImage().getMovingHe();
    128127      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())) {
    130130      LatLon from = data.getSelectedImage().getTempLatLon();
    131131      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()));
    133134    }
    134     data.getMultiSelectedImages().parallelStream().filter(Objects::nonNull).forEach(StreetsideAbstractImage::stopMoving);
     135    data.getMultiSelectedImages().parallelStream().filter(Objects::nonNull)
     136        .forEach(StreetsideAbstractImage::stopMoving);
    135137    StreetsideLayer.invalidateInstance();
    136138  }
     
    142144  public void mouseMoved(MouseEvent e) {
    143145    if (MainApplication.getLayerManager().getActiveLayer() instanceof OsmDataLayer
    144             && MainApplication.getMap().mapMode != MainApplication.getMap().mapModeSelect) {
     146        && MainApplication.getMap().mapMode != MainApplication.getMap().mapModeSelect) {
    145147      return;
    146148    }
    147     if (!StreetsideProperties.HOVER_ENABLED.get()) {
     149    if (Boolean.FALSE.equals(StreetsideProperties.HOVER_ENABLED.get())) {
    148150      return;
    149151    }
     
    177179      StreetsideMainDialog.getInstance().updateImage(false);
    178180
    179     } else if (StreetsideLayer.getInstance().getData().getHighlightedImage() != closestTemp && closestTemp == null) {
     181    } else if (StreetsideLayer.getInstance().getData().getHighlightedImage() != closestTemp
     182        && closestTemp == null) {
    180183      StreetsideLayer.getInstance().getData().setHighlightedImage(null);
    181184      StreetsideMainDialog.getInstance().setImage(StreetsideLayer.getInstance().getData().getSelectedImage());
  • applications/editors/josm/plugins/MicrosoftStreetside/src/org/openstreetmap/josm/plugins/streetside/model/ImageDetection.java

    r34317 r36194  
    1111  private final String value;
    1212
    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) {
    1415    super(shape, imageKey, key);
    1516    this.packag = packag;
  • applications/editors/josm/plugins/MicrosoftStreetside/src/org/openstreetmap/josm/plugins/streetside/model/KeyIndexedObject.java

    r34317 r36194  
    4646    }
    4747    KeyIndexedObject other = (KeyIndexedObject) obj;
    48     if (!key.equals(other.key)) {
    49       return false;
    50     }
    51     return true;
     48    return key.equals(other.key);
    5249  }
    5350
  • applications/editors/josm/plugins/MicrosoftStreetside/src/org/openstreetmap/josm/plugins/streetside/model/MapObject.java

    r34416 r36194  
    1818  private final long updatedTime;
    1919
    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) {
    2422    super(key);
    2523    if (objPackage == null || value == null || coordinate == null) {
     
    3432  }
    3533
    36   public LatLon getCoordinate() {
    37     return coordinate;
    38   }
    39 
    4034  /**
    4135   * @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}.
    4337   * @return the icon, which represents the given objectTypeID
    4438   */
     
    5145    }
    5246    return cachedIcon;
     47  }
     48
     49  public LatLon getCoordinate() {
     50    return coordinate;
    5351  }
    5452
  • applications/editors/josm/plugins/MicrosoftStreetside/src/org/openstreetmap/josm/plugins/streetside/oauth/OAuthPortListener.java

    r34577 r36194  
    11// License: GPL. For details, see LICENSE file.
    22package org.openstreetmap.josm.plugins.streetside.oauth;
    3 
    43
    54import java.io.IOException;
     
    109import java.net.ServerSocket;
    1110import java.net.Socket;
     11import java.nio.charset.StandardCharsets;
    1212import java.util.Scanner;
     13import java.util.logging.Logger;
    1314import java.util.regex.Matcher;
    1415import java.util.regex.Pattern;
    1516
    16 import org.apache.log4j.Logger;
    1717import org.openstreetmap.josm.plugins.streetside.utils.StreetsideProperties;
    1818import org.openstreetmap.josm.tools.I18n;
     19import org.openstreetmap.josm.tools.Logging;
    1920
    2021/**
     
    2627*/
    2728public 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;
    2935
    30 final static Logger logger = Logger.getLogger(OAuthPortListener.class);
     36  public OAuthPortListener(StreetsideLoginListener loginCallback) {
     37    callback = loginCallback;
     38  }
    3139
    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  }
    3846
    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  }
    4188}
    42 
    43 @Override
    44 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  
    77import java.net.HttpURLConnection;
    88import java.net.URL;
     9import java.nio.charset.StandardCharsets;
     10
     11import org.openstreetmap.josm.plugins.streetside.utils.StreetsideProperties;
    912
    1013import jakarta.json.Json;
     
    1215import jakarta.json.JsonObject;
    1316import jakarta.json.JsonReader;
    14 
    15 import org.openstreetmap.josm.plugins.streetside.utils.StreetsideProperties;
    1617
    1718/**
     
    2324public final class OAuthUtils {
    2425
    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  }
    2750}
    28 
    29 /**
    30 * Returns a JsonObject containing the result of making a GET request with the
    31 * authorization header.
    32 *
    33 * @param url
    34 *          The {@link URL} where the request must be made.
    35 * @return A JsonObject containing the result of the GET request.
    36 * @throws IOException
    37 *           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  
    1111   * Should be called whenever the user logs into a mapillary account.
    1212   * E.g. for updating the GUI to reflect the login status.
     13   *
    1314   * @param username the username that the user is now logged in with
    1415   */
    1516  void onLogin(final String username);
     17
    1618  /**
    1719   * 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  
    11// License: GPL. For details, see LICENSE file.
    22package org.openstreetmap.josm.plugins.streetside.oauth;
    3 
    43
    54import java.util.Map;
     
    1514public final class StreetsideUser {
    1615
    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;
    2223
    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  }
    2559}
    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 Streetside
    32    return null;
    33 }
    34 
    35 /**
    36 * @return A HashMap object containing the images_policy and images_hash
    37 *         strings.
    38 */
    39 public static synchronized Map<String, String> getSecrets() {
    40   // secrets are not currently supported in Streetside
    41   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  
    66import java.awt.image.BufferedImage;
    77import java.text.MessageFormat;
     8import java.util.logging.Logger;
    89
    9 import org.apache.log4j.Logger;
     10import org.openstreetmap.josm.tools.Logging;
    1011
    1112import javafx.application.Platform;
    1213import javafx.scene.image.PixelWriter;
    13 //import javafx.embed.swing.SwingFXUtils;
    14 //import javafx.scene.image.Image;
    1514import javafx.scene.image.WritableImage;
    1615
    17 @SuppressWarnings({ "restriction"})
    1816public class GraphicsUtils {
    1917
    20   final static Logger logger = Logger.getLogger(GraphicsUtils.class);
     18  private static final Logger LOGGER = Logger.getLogger(GraphicsUtils.class.getCanonicalName());
    2119
    2220  private GraphicsUtils() {
     
    2422  }
    2523
    26         public static javafx.scene.image.Image convertBufferedImage2JavaFXImage(BufferedImage bf) {
    27                 WritableImage res = null;
    28                 if (bf != null) {
    29                         res = new WritableImage(bf.getWidth(), bf.getHeight());
    30                         PixelWriter pw = res.getPixelWriter();
    31                         for (int x = 0; x < bf.getWidth(); x++) {
    32                                 for (int y = 0; y < bf.getHeight(); y++) {
    33                                         pw.setArgb(x, y, bf.getRGB(x, y));
    34                                 }
    35                         }
    36                 }
    37                 return res;
    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  }
    3937
    40         public static class PlatformHelper {
     38  public static BufferedImage buildMultiTiledCubemapFaceImage(final BufferedImage[] tiles) {
    4139
    42           private PlatformHelper() {
    43             // Private constructor to avoid instantiation
    44           }
     40    long start = System.currentTimeMillis();
    4541
    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;
    4843
    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;
    5345
    54         public static BufferedImage buildMultiTiledCubemapFaceImage(final BufferedImage[] tiles) {
     46    BufferedImage[] croppedTiles = cropMultiTiledImages(tiles, pixelBuffer);
    5547
    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;
    5751
    58           BufferedImage res = null;
     52    int chunkWidth;
     53    int chunkHeight;
    5954
    60                 int pixelBuffer = StreetsideProperties.SHOW_HIGH_RES_STREETSIDE_IMAGERY.get()?2:1;
     55    chunkWidth = croppedTiles[0].getWidth();
     56    chunkHeight = croppedTiles[0].getHeight();
    6157
    62                 BufferedImage[] croppedTiles = cropMultiTiledImages(tiles, pixelBuffer);
     58    //Initializing the final image
     59    BufferedImage img = new BufferedImage(chunkWidth * cols, chunkHeight * rows, BufferedImage.TYPE_INT_ARGB);
    6360
    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++) {
    7864        // TODO: unintended mirror image created with draw call - requires
    7965        // extra reversal step - fix!
    8066        img.createGraphics().drawImage(croppedTiles[num], chunkWidth * j, (chunkHeight * i), null);
    8167
    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;
    8370        int height = width;
    8471
    8572        // 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);
    8974
    9075        // Create mirror image pixel by pixel
     
    10691    }
    10792
    108     if (StreetsideProperties.DEBUGING_ENABLED.get()) {
    109       logger
    110         .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)));
    11196    }
    11297    return res;
    113         }
     98  }
    11499
    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  }
    123107
    124         private static BufferedImage[] cropMultiTiledImages(BufferedImage[] tiles, int pixelBuffer) {
     108  private static BufferedImage[] cropMultiTiledImages(BufferedImage[] tiles, int pixelBuffer) {
    125109
    126                 long start = System.currentTimeMillis();
     110    long start = System.currentTimeMillis();
    127111
    128           BufferedImage[] res = new BufferedImage[tiles.length];
     112    BufferedImage[] res = new BufferedImage[tiles.length];
    129113
    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                                 } else {
    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    }
    137121
    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    }
    141126
    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  }
    144146}
  • applications/editors/josm/plugins/MicrosoftStreetside/src/org/openstreetmap/josm/plugins/streetside/utils/ImageUtil.java

    r34365 r36194  
    33
    44import java.awt.Image;
     5import java.util.logging.Logger;
    56
    67import javax.swing.ImageIcon;
    78
    8 import org.apache.log4j.Logger;
    99import org.openstreetmap.josm.tools.I18n;
     10import org.openstreetmap.josm.tools.Logging;
    1011
    1112public final class ImageUtil {
    1213
    13   final static Logger logger = Logger.getLogger(ImageUtil.class);
     14  private static final Logger LOGGER = Logger.getLogger(ImageUtil.class.getCanonicalName());
    1415
    1516  private ImageUtil() {
     
    1920  /**
    2021   * Scales an {@link ImageIcon} to the desired size
     22   *
    2123   * @param icon the icon, which should be resized
    2224   * @param size the desired length of the longest edge of the icon
    2325   * @return the resized {@link ImageIcon}. It is the same object that you put in,
    24    *         only the contained {@link Image} is exchanged.
     26   * only the contained {@link Image} is exchanged.
    2527   */
    2628  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));
    2931    }
    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));
    3542  }
    3643}
  • applications/editors/josm/plugins/MicrosoftStreetside/src/org/openstreetmap/josm/plugins/streetside/utils/MapViewGeometryUtil.java

    r34317 r36194  
    1919 * can then easily be drawn on a {@link MapView}s {@link Graphics2D}-context.
    2020 */
    21 public final  class MapViewGeometryUtil {
     21public final class MapViewGeometryUtil {
    2222  private MapViewGeometryUtil() {
    2323    // Private constructor to avoid instantiation
     
    2626  /**
    2727   * 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
    3031   * @param downloadBounds multiple {@link Bounds} objects that represent the downloaded area
    3132   * @return the difference between the {@link MapView}s bounds and the downloaded area
     
    4142      Point p1 = mv.getPoint(bounds.getMin());
    4243      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));
    4546      a.subtract(new Area(r));
    4647    }
     
    5152   * Converts a {@link StreetsideSequence} into a {@link Path2D} that can be drawn
    5253   * 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}
    5456   * @param seq the sequence to convert
    5557   * @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  
    44import static org.openstreetmap.josm.tools.I18n.tr;
    55
     6import java.util.logging.Logger;
     7
    68import javax.swing.JOptionPane;
    79
    8 import org.apache.log4j.Logger;
    910import org.openstreetmap.josm.gui.MainApplication;
    1011import org.openstreetmap.josm.tools.I18n;
     12import org.openstreetmap.josm.tools.Logging;
    1113
    1214/**
     
    1618public final class PluginState {
    1719
    18   final static Logger logger = Logger.getLogger(PluginState.class);
     20  private static final Logger LOGGER = Logger.getLogger(PluginState.class.getCanonicalName());
    1921
    2022  private static boolean submittingChangeset;
    2123
    2224  private static int runningDownloads;
    23   /** Images that have to be uploaded. */
     25  /**
     26   * Images that have to be uploaded.
     27   */
    2428  private static int imagesToUpload;
    25   /** Images that have been uploaded. */
     29  /**
     30   * Images that have been uploaded.
     31   */
    2632  private static int imagesUploaded;
    2733
     
    4248  public static void finishDownload() {
    4349    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"));
    4551      return;
    4652    }
     
    6571    return submittingChangeset;
    6672  }
    67    /**
     73
     74  public static void setSubmittingChangeset(boolean isSubmitting) {
     75    submittingChangeset = isSubmitting;
     76  }
     77
     78  /**
    6879   * Checks if there is any running upload.
    6980   *
     
    7788   * Sets the amount of images that are going to be uploaded.
    7889   *
    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.
    8191   */
    8292  public static void addImagesToUpload(int amount) {
     
    102112    imagesUploaded++;
    103113    if (imagesToUpload == imagesUploaded) {
    104         finishedUploadDialog(imagesUploaded);
     114      finishedUploadDialog(imagesUploaded);
    105115    }
    106116  }
    107117
    108118  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);
    115122  }
    116123
    117124  public static void notLoggedInToMapillaryDialog() {
    118     JOptionPane.showMessageDialog(
    119         MainApplication.getMainFrame(),
     125    JOptionPane.showMessageDialog(MainApplication.getMainFrame(),
    120126        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);
    124128  }
    125129
     
    132136    return tr("Uploading: {0}", "(" + imagesUploaded + "/" + imagesToUpload + ")");
    133137  }
    134 
    135   public static void setSubmittingChangeset(boolean isSubmitting) {
    136       submittingChangeset = isSubmitting;
    137   }
    138138}
  • applications/editors/josm/plugins/MicrosoftStreetside/src/org/openstreetmap/josm/plugins/streetside/utils/StreetsideColorScheme.java

    r34317 r36194  
    5151  /**
    5252   * Styles the given components as default panels (currently only the background is set to white)
     53   *
    5354   * @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)
    5556   */
    5657  public static void styleAsDefaultPanel(JComponent... components) {
  • applications/editors/josm/plugins/MicrosoftStreetside/src/org/openstreetmap/josm/plugins/streetside/utils/StreetsideProperties.java

    r34433 r36194  
    1414
    1515public 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);
    1718  public static final BooleanProperty DEVELOPER = new BooleanProperty("streetside.developer", false);
    1819  public static final BooleanProperty DISPLAY_HOUR = new BooleanProperty("streetside.display-hour", true);
     
    2021  public static final BooleanProperty MOVE_TO_IMG = new BooleanProperty("streetside.move-to-picture", true);
    2122  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);
    2631  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);
    2834
    2935  /**
     
    3137   * Otherwise only all images (!) inside the download bounds are added, the others are discarded.
    3238   */
    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);
    3541  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);
    3948
    4049  /**
     
    4554   * See {@code OsmDataLayer#PROPERTY_OUTSIDE_COLOR}
    4655   */
    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);
    4858
    4959  public static final DoubleProperty MAX_DOWNLOAD_AREA = new DoubleProperty("streetside.max-download-area", 0.015);
    5060
    5161  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);
    5364  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);
    5667
    5768  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"));
    6879
    6980  /**
     
    7283   * Or opening the {@link ImageInfoPanel} immediately brings this number down to zero.
    7384   */
    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);
    7687
    7788  /**
     
    8091   * Or opening the {@link StreetsideViewerPanel} immediately brings this number down to zero.
    8192   */
    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);
    8495
    8596  /**
    8697   * The number of images to be prefetched when a streetside image is selected
    8798   */
    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);
    89101
    90102  /**
    91103   * The number of images to be prefetched when a streetside image is selected
    92104   */
    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);
    95107
    96108  private StreetsideProperties() {
  • applications/editors/josm/plugins/MicrosoftStreetside/src/org/openstreetmap/josm/plugins/streetside/utils/StreetsideSequenceIdGenerator.java

    r34577 r36194  
    99 * handle sequences of contiguous imagery, but Streetside only has implicit
    1010 * 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
    1313 */
    1414public class StreetsideSequenceIdGenerator {
  • applications/editors/josm/plugins/MicrosoftStreetside/src/org/openstreetmap/josm/plugins/streetside/utils/StreetsideURL.java

    r34431 r36194  
    1515import java.util.Map;
    1616import java.util.Map.Entry;
    17 
    18 import org.apache.log4j.Logger;
     17import java.util.logging.Logger;
     18
    1919import org.openstreetmap.josm.data.Bounds;
    2020import org.openstreetmap.josm.plugins.streetside.cubemap.CubemapUtils;
     
    2424public final class StreetsideURL {
    2525
    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   */
    3135  private static final String STREETSIDE_PRIVACY_URL = "https://www.bing.com/maps/privacyreport/streetsideprivacyreport?bubbleid=";
    3236
    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) {
    114257        // pad thumbnail imagery with leading zeros
    115258        if (id.length() < 16) {
     
    119262        }
    120263        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              }
    126279          }
    127280          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();
    164310
    165311      // pad thumbnail imagery with leading zeros
     
    171317      modifiedId.append(id).append("01");
    172318
    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  }
    339345}
  • applications/editors/josm/plugins/MicrosoftStreetside/src/org/openstreetmap/josm/plugins/streetside/utils/StreetsideUtils.java

    r34431 r36194  
    1616import org.apache.commons.imaging.common.RationalNumber;
    1717import org.apache.commons.imaging.formats.tiff.constants.GpsTagConstants;
    18 import org.apache.log4j.Logger;
    1918import org.openstreetmap.josm.data.Bounds;
    2019import org.openstreetmap.josm.data.coor.LatLon;
     
    3231public final class StreetsideUtils {
    3332
    34   final static Logger logger = Logger.getLogger(StreetsideUtils.class);
    35 
    3633  private static final double MIN_ZOOM_SQUARE_SIDE = 0.002;
    3734
     
    10198   *
    10299   * @param degMinSec an array of length 3, the values in there are (in this order)
    103    *                  degrees, minutes and seconds
    104    * @param ref       the latitude or longitude reference determining if the given value
    105    *                  is:
    106    *                  <ul>
    107    *                  <li>north (
    108    *                  {@link GpsTagConstants#GPS_TAG_GPS_LATITUDE_REF_VALUE_NORTH}) or
    109    *                  south (
    110    *                  {@link GpsTagConstants#GPS_TAG_GPS_LATITUDE_REF_VALUE_SOUTH}) of
    111    *                  the equator</li>
    112    *                  <li>east (
    113    *                  {@link GpsTagConstants#GPS_TAG_GPS_LONGITUDE_REF_VALUE_EAST}) or
    114    *                  west ({@link GpsTagConstants#GPS_TAG_GPS_LONGITUDE_REF_VALUE_WEST}
    115    *                  ) of the equator</li>
    116    *                  </ul>
     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>
    117114   * @return the decimal degree-value for the given input, negative when west of
    118115   * 0-meridian or south of equator, positive otherwise
    119116   * @throws IllegalArgumentException if {@code degMinSec} doesn't have length 3 or if {@code ref} is
    120    *                                  not one of the values mentioned above
     117   *                  not one of the values mentioned above
    121118   */
    122119  public static double degMinSecToDouble(RationalNumber[] degMinSec, String ref) {
     
    130127
    131128    switch (ref) {
    132       case GpsTagConstants.GPS_TAG_GPS_LATITUDE_REF_VALUE_NORTH:
    133       case GpsTagConstants.GPS_TAG_GPS_LATITUDE_REF_VALUE_SOUTH:
    134       case GpsTagConstants.GPS_TAG_GPS_LONGITUDE_REF_VALUE_EAST:
    135       case GpsTagConstants.GPS_TAG_GPS_LONGITUDE_REF_VALUE_WEST:
    136         break;
    137       default:
    138         throw new IllegalArgumentException("Invalid ref.");
     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.");
    139136    }
    140137
     
    144141
    145142    if (GpsTagConstants.GPS_TAG_GPS_LATITUDE_REF_VALUE_SOUTH.equals(ref)
    146             || GpsTagConstants.GPS_TAG_GPS_LONGITUDE_REF_VALUE_WEST.equals(ref)) {
     143        || GpsTagConstants.GPS_TAG_GPS_LONGITUDE_REF_VALUE_WEST.equals(ref)) {
    147144      result *= -1;
    148145    }
     
    166163    }
    167164    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.");
    169167    }
    170168    if (imgA.next() != null || imgB.previous() != null) {
     
    223221  /**
    224222   * 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.
    226225   * All others are put into the second new sequence.
    227226   *
     
    237236    }
    238237    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.");
    240240    }
    241241
     
    273273      ret.append(I18n.tr("Total Streetside images: {0}", StreetsideLayer.getInstance().getToolTipText()));
    274274    } else if (PluginState.isSubmittingChangeset()) {
    275         ret.append(I18n.tr("Submitting Streetside Changeset"));
     275      ret.append(I18n.tr("Submitting Streetside Changeset"));
    276276    } else {
    277277      ret.append(I18n.tr("No images found"));
  • applications/editors/josm/plugins/MicrosoftStreetside/src/org/openstreetmap/josm/plugins/streetside/utils/api/JsonDecoder.java

    r36122 r36194  
    99import java.util.function.Function;
    1010
     11import org.openstreetmap.josm.data.coor.LatLon;
     12import org.openstreetmap.josm.tools.I18n;
     13import org.openstreetmap.josm.tools.Logging;
     14
    1115import jakarta.json.JsonArray;
    1216import jakarta.json.JsonNumber;
    1317import jakarta.json.JsonObject;
    1418import 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;
    1919
    2020public final class JsonDecoder {
     
    2929   * of the desired Java objects. The method, which converts the GeoJSON features into Java objects
    3030   * 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
    3334   * @param featureDecoder feature decoder which transforms JSON objects to Java objects
    3435   * @return a {@link Collection} which is parsed from the given {@link JsonObject}, which contains GeoJSON.
    35    *         Currently a {@link HashSet} is used, but please don't rely on it, this could change at any time without
    36    *         prior notice. The return value will not be <code>null</code>.
     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>.
    3738   */
    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) {
    3941    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")) {
    4343      final JsonValue features = json.get("features");
    4444      for (int i = 0; features instanceof JsonArray && i < ((JsonArray) features).size(); i++) {
     
    5858   * Decodes a {@link JsonArray} of exactly size 2 to a {@link LatLon} instance.
    5959   * The first value in the {@link JsonArray} is treated as longitude, the second one as latitude.
     60   *
    6061   * @param json the {@link JsonArray} containing the two numbers
    6162   * @return the decoded {@link LatLon} instance, or <code>null</code> if the parameter is
    62    *         not a {@link JsonArray} of exactly size 2 containing two {@link JsonNumber}s.
     63   * not a {@link JsonArray} of exactly size 2 containing two {@link JsonNumber}s.
    6364   */
    6465  static LatLon decodeLatLon(final JsonArray json) {
     
    7273  /**
    7374   * Decodes a pair of double values, which are stored in a {@link JsonArray} of exactly size 2.
     75   *
    7476   * @param json the {@link JsonArray} containing the two values
    7577   * @return a double array which contains the two values in the same order, or <code>null</code>
    76    *         if the parameter was not a {@link JsonArray} of exactly size 2 containing two {@link JsonNumber}s
     78   * if the parameter was not a {@link JsonArray} of exactly size 2 containing two {@link JsonNumber}s
    7779   */
    7880  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() };
    8684    }
    8785    return EMPTY_DOUBLE;
     
    9189   * Decodes a timestamp formatted as a {@link String} to the equivalent UNIX epoch timestamp
    9290   * (number of milliseconds since 1970-01-01T00:00:00.000+0000).
     91   *
    9392   * @param timestamp the timestamp formatted according to the format <code>yyyy-MM-dd'T'HH:mm:ss.SSSX</code>
    9493   * @return the point in time as a {@link Long} value representing the UNIX epoch time, or <code>null</code> if the
    95    *   parameter does not match the required format (this also triggers a warning via
    96    *   {@link Logging}, or the parameter is <code>null</code>).
     94   * parameter does not match the required format (this also triggers a warning via
     95   * {@link Logging}, or the parameter is <code>null</code>).
    9796   */
    9897  static Long decodeTimestamp(final String timestamp) {
     
    102101      } catch (ParseException e) {
    103102        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));
    108105      }
    109106    }
  • applications/editors/josm/plugins/MicrosoftStreetside/src/org/openstreetmap/josm/plugins/streetside/utils/api/JsonImageDetectionDecoder.java

    r36122 r36194  
    55import java.awt.geom.Path2D;
    66
     7import org.openstreetmap.josm.plugins.streetside.model.ImageDetection;
     8import org.openstreetmap.josm.plugins.streetside.utils.StreetsideURL.APIv3;
     9import org.openstreetmap.josm.tools.Logging;
     10
    711import jakarta.json.JsonArray;
    812import jakarta.json.JsonNumber;
    913import jakarta.json.JsonObject;
    1014import 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;
    1515
    1616/**
     
    3838      final Double score = scoreVal instanceof JsonNumber ? ((JsonNumber) scoreVal).doubleValue() : null;
    3939      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) {
    4142        return new ImageDetection((Path2D) shape, imageKey, key, score, packag, value);
    4243      }
     
    4849    if (json instanceof JsonObject) {
    4950      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›")));
    5453      } else {
    5554        final JsonValue coordinates = ((JsonObject) json).get("coordinates");
     
    6463  /**
    6564   * Decodes a polygon (may be a multipolygon) from JSON
     65   *
    6666   * @param json the json array to decode, must not be <code>null</code>
    6767   * @return the decoded polygon as {@link Path2D.Double}
     
    8383  /**
    8484   * Decodes a simple polygon (consisting of only one continuous path) from JSON
     85   *
    8586   * @param json the json array to decode, must not be <code>null</code>
    8687   * @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  
    55import java.util.function.Function;
    66
     7import org.openstreetmap.josm.data.coor.LatLon;
     8import org.openstreetmap.josm.plugins.streetside.StreetsideImage;
     9import org.openstreetmap.josm.plugins.streetside.StreetsideSequence;
     10import org.openstreetmap.josm.plugins.streetside.utils.StreetsideURL.APIv3;
     11
    712import jakarta.json.JsonArray;
    813import jakarta.json.JsonNumber;
     
    1015import jakarta.json.JsonString;
    1116import 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;
    1717
    1818/**
     
    2727  /**
    2828   * Parses a given {@link JsonObject} as a GeoJSON Feature into a {@link StreetsideSequence}.
     29   *
    2930   * @param json the {@link JsonObject} to be parsed
    3031   * @return a {@link StreetsideSequence} that is parsed from the given {@link JsonObject}. If mandatory information is
    31    *         missing from the JSON or it's not meeting the expecting format in another way, <code>null</code> will be
    32    *         returned.
     32   * missing from the JSON or it's not meeting the expecting format in another way, <code>null</code> will be
     33   * returned.
    3334   */
    3435  public static StreetsideSequence decodeSequence(final JsonObject json) {
     
    3940    final JsonObject properties = json.getJsonObject("properties");
    4041    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) {
    4244      result = new StreetsideSequence(properties.getString("id", null), ca);
    4345
    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);
    5650      final LatLon[] geometry = decodeLatLons(json.getJsonObject("geometry"));
    5751      final int sequenceLength = Math.min(Math.min(hes.length, imageIds.length), geometry.length);
     
    7771   * @param clazz the desired type that the elements of the resulting array should have
    7872   * @return the supplied array converted from {@link JsonArray} to a java array of the supplied type, converted using
    79    *         the supplied function. Never <code>null</code>, in case of array==null, an array of length 0 is returned.
     73   *     the supplied function. Never <code>null</code>, in case of array==null, an array of length 0 is returned.
    8074   */
    8175  @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) {
    8378    final T[] result;
    8479    if (array == null) {
    85       result =  (T[]) Array.newInstance(clazz, 0);
     80      result = (T[]) Array.newInstance(clazz, 0);
    8681    } else {
    8782      result = (T[]) Array.newInstance(clazz, array.size());
     
    10398   * @param key the key, which identifies the desired array inside the `coordinateProperties` object to be converted
    10499   * @param decodeValueFunction a function that converts the {@link JsonValue}s in the JSON array to java objects of the
    105    *        desired type
     100   *    desired type
    106101   * @param clazz the {@link Class} object of the desired type, that the entries of the resulting array should have
    107102   * @return the resulting array, when converting the desired entry of the `coordinateProperties`.
    108    *         Never <code>null</code>. If no `coordinateProperties` are set, or if the desired key is not set or is not
    109    *         an array, then an empty array of the desired type is returned.
     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.
    110105   */
    111106  @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) {
    115109    final JsonValue coordinateProperties = json == null ? null : json.get("coordinateProperties");
    116110    if (coordinateProperties instanceof JsonObject) {
  • applications/editors/josm/plugins/MicrosoftStreetside/src/org/openstreetmap/josm/plugins/streetside/utils/api/JsonStreetsideDecoder.java

    r36122 r36194  
    2323   * of the desired Java objects. The method, which converts the GeoJSON features into Java objects
    2424   * 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
    2728   * @param featureDecoder feature decoder which transforms JSON objects to Java objects
    2829   * @return a {@link Collection} which is parsed from the given {@link JsonObject}, which contains GeoJSON.
    29    *         Currently a {@link HashSet} is used, but please don't rely on it, this could change at any time without
    30    *         prior notice. The return value will not be <code>null</code>.
     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>.
    3132   */
    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) {
    3335    return JsonDecoder.decodeFeatureCollection(json, featureDecoder);
    3436  }
     
    3739   * Decodes a {@link JsonArray} of exactly size 2 to a {@link LatLon} instance.
    3840   * The first value in the {@link JsonArray} is treated as longitude, the second one as latitude.
     41   *
    3942   * @param json the {@link JsonArray} containing the two numbers
    4043   * @return the decoded {@link LatLon} instance, or <code>null</code> if the parameter is
    41    *         not a {@link JsonArray} of exactly size 2 containing two {@link JsonNumber}s.
     44   * not a {@link JsonArray} of exactly size 2 containing two {@link JsonNumber}s.
    4245   */
    4346  static LatLon decodeLatLon(final JsonArray json) {
     
    4851   * Decodes a timestamp formatted as a {@link String} to the equivalent UNIX epoch timestamp
    4952   * (number of milliseconds since 1970-01-01T00:00:00.000+0000).
     53   *
    5054   * @param timestamp the timestamp formatted according to the format <code>yyyy-MM-dd'T'HH:mm:ss.SSSX</code>
    5155   * @return the point in time as a {@link Long} value representing the UNIX epoch time, or <code>null</code> if the
    52    *   parameter does not match the required format (this also triggers a warning via
    53    *   {@link Logging}, or the parameter is <code>null</code>).
     56   * parameter does not match the required format (this also triggers a warning via
     57   * {@link Logging}, or the parameter is <code>null</code>).
    5458   */
    5559  static Long decodeTimestamp(final String timestamp) {
  • applications/editors/josm/plugins/MicrosoftStreetside/src/org/openstreetmap/josm/plugins/streetside/utils/api/JsonStreetsideSequencesDecoder.java

    r36122 r36194  
    55import java.util.function.Function;
    66
     7import org.openstreetmap.josm.data.coor.LatLon;
     8import org.openstreetmap.josm.plugins.streetside.StreetsideImage;
     9import org.openstreetmap.josm.plugins.streetside.StreetsideSequence;
     10import org.openstreetmap.josm.plugins.streetside.utils.StreetsideURL.APIv3;
     11
    712import jakarta.json.JsonArray;
    813import jakarta.json.JsonNumber;
     
    1015import jakarta.json.JsonString;
    1116import 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;
    1717
    1818/**
     
    2727  /**
    2828   * Parses a given {@link JsonObject} as a GeoJSON Feature into a {@link StreetsideSequence}.
     29   *
    2930   * @param json the {@link JsonObject} to be parsed
    3031   * @return a {@link StreetsideSequence} that is parsed from the given {@link JsonObject}. If mandatory information is
    31    *         missing from the JSON or it's not meeting the expecting format in another way, <code>null</code> will be
    32    *         returned.
     32   * missing from the JSON or it's not meeting the expecting format in another way, <code>null</code> will be
     33   * returned.
    3334   */
    3435  public static StreetsideSequence decodeSequence(final JsonObject json) {
     
    4243      result = new StreetsideSequence(properties.getString("id", null), ca);
    4344
    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);
    5649      final LatLon[] geometry = decodeLatLons(json.getJsonObject("geometry"));
    5750      final int sequenceLength = Math.min(Math.min(cas.length, imageIds.length), geometry.length);
     
    7366   * @param image the {@link StreetsideImage} to be parsed
    7467   * @return a {@link StreetsideSequence} that is parsed from the given {@link JsonObject}. If mandatory information is
    75    *         missing from the JSON or it's not meeting the expecting format in another way, <code>null</code> will be
    76    *         returned.
     68   *     missing from the JSON or it's not meeting the expecting format in another way, <code>null</code> will be
     69   *     returned.
    7770   */
    7871  public static StreetsideImage decodeBubbleData(final StreetsideImage image) {
     
    8275    // Declare and instantiate new Streetside object to ensure proper setting of superclass attributes
    8376    StreetsideImage result = null;
    84     if(image.getId() != null ) {
     77    if (image.getId() != null) {
    8578      result = new StreetsideImage(image.getId(), new LatLon(image.getLa(), image.getLo()), 0.0);
    8679      result.setAl(image.getAl());
     
    10396   * @param json the {@link JsonObject} to be parsed
    10497   * @return a {@link StreetsideSequence} that is parsed from the given {@link JsonObject}. If mandatory information is
    105    *         missing from the JSON or it's not meeting the expecting format in another way, <code>null</code> will be
    106    *         returned.
     98   *     missing from the JSON or it's not meeting the expecting format in another way, <code>null</code> will be
     99   *     returned.
    107100   */
    108101  public static StreetsideSequence decodeStreetsideSequence(final JsonObject json) {
     
    112105    StreetsideSequence result = null;
    113106
    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());
    117111    }
    118112
     
    128122   * @param clazz the desired type that the elements of the resulting array should have
    129123   * @return the supplied array converted from {@link JsonArray} to a java array of the supplied type, converted using
    130    *         the supplied function. Never <code>null</code>, in case of array==null, an array of length 0 is returned.
     124   *     the supplied function. Never <code>null</code>, in case of array==null, an array of length 0 is returned.
    131125   */
    132126  @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) {
    134129    final T[] result;
    135130    if (array == null) {
    136       result =  (T[]) Array.newInstance(clazz, 0);
     131      result = (T[]) Array.newInstance(clazz, 0);
    137132    } else {
    138133      result = (T[]) Array.newInstance(clazz, array.size());
     
    154149   * @param key the key, which identifies the desired array inside the `coordinateProperties` object to be converted
    155150   * @param decodeValueFunction a function that converts the {@link JsonValue}s in the JSON array to java objects of the
    156    *        desired type
     151   *    desired type
    157152   * @param clazz the {@link Class} object of the desired type, that the entries of the resulting array should have
    158153   * @return the resulting array, when converting the desired entry of the `coordinateProperties`.
    159    *         Never <code>null</code>. If no `coordinateProperties` are set, or if the desired key is not set or is not
    160    *         an array, then an empty array of the desired type is returned.
     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.
    161156   */
    162157  @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) {
    166160    final JsonValue coordinateProperties = json == null ? null : json.get("coordinateProperties");
    167161    if (coordinateProperties instanceof JsonObject) {
  • applications/editors/josm/plugins/MicrosoftStreetside/test/unit/org/openstreetmap/josm/plugins/streetside/StreetsideAbstractImageTest.java

    r36064 r36194  
    99
    1010class StreetsideAbstractImageTest {
    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   }
     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    }
    2828}
  • applications/editors/josm/plugins/MicrosoftStreetside/test/unit/org/openstreetmap/josm/plugins/streetside/StreetsideDataTest.java

    r36193 r36194  
    11// License: GPL. For details, see LICENSE file.
    22package org.openstreetmap.josm.plugins.streetside;
    3 
    43
    54import static org.junit.jupiter.api.Assertions.assertEquals;
     
    1312import org.junit.jupiter.api.Disabled;
    1413import org.junit.jupiter.api.Test;
    15 import org.junit.jupiter.api.condition.DisabledIf;
    1614import org.openstreetmap.josm.data.coor.LatLon;
    1715import org.openstreetmap.josm.testutils.annotations.Main;
     
    2624class StreetsideDataTest {
    2725
    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;
    3331
    34   /**
    35    * Creates a sample {@link StreetsideData} objects, 4 {@link StreetsideImage}
    36    * objects and a {@link StreetsideSequence} object.
    37    */
    38   @BeforeEach
    39   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();
    4543
    46     seq.add(Arrays.asList(img1, img2, img3, img4));
     44        seq.add(Arrays.asList(img1, img2, img3, img4));
    4745
    48     data = new StreetsideData();
    49     data.addAll(new ConcurrentSkipListSet<>(seq.getImages()));
    50   }
     46        data = new StreetsideData();
     47        data.addAll(new ConcurrentSkipListSet<>(seq.getImages()));
     48    }
    5149
    52   /**
    53    * Tests the addition of new images. If a second image with the same key as
    54    * another one in the database, the one that is being added should be ignored.
    55    */
    56   @Test
    57   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    }
    6967
    70   /**
    71    * Test that the size is properly calculated.
    72    */
    73   @Test
    74   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    }
    7977
    80   /**
    81    * Test the {@link StreetsideData#setHighlightedImage(StreetsideAbstractImage)}
    82    * and {@link StreetsideData#getHighlightedImage()} methods.
    83    */
    84   @Test
    85   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());
    8886
    89     data.setHighlightedImage(null);
    90     assertNull(data.getHighlightedImage());
    91   }
     87        data.setHighlightedImage(null);
     88        assertNull(data.getHighlightedImage());
     89    }
    9290
    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   @Test
    98   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());
    10199
    102     data.setSelectedImage(img4);
    103     assertEquals(img4, data.getSelectedImage());
     100        data.setSelectedImage(img4);
     101        assertEquals(img4, data.getSelectedImage());
    104102
    105     data.setSelectedImage(null);
    106     assertNull(data.getSelectedImage());
    107   }
     103        data.setSelectedImage(null);
     104        assertNull(data.getSelectedImage());
     105    }
    108106
    109   /**
    110    * Tests the {@link StreetsideData#selectNext()} and
    111    * {@link StreetsideData#selectPrevious()} methods.
    112    */
    113   @Test
    114   @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);
    117115
    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());
    124122
    125     data.setSelectedImage(null);
    126   }
     123        data.setSelectedImage(null);
     124    }
    127125
    128   @Disabled("Someone decided to not throw an IllegalStateException. No clue why.")
    129   @Test
    130   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    }
    134132
    135   @Disabled("Someone decided to not throw an IllegalStateException. No clue why.")
    136   @Test
    137   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    }
    141139
    142   /**
    143    * Test the multiselection of images. When a new image is selected, the
    144    * 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   @Test
    148   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    }
    157155}
  • applications/editors/josm/plugins/MicrosoftStreetside/test/unit/org/openstreetmap/josm/plugins/streetside/StreetsideLayerTest.java

    r36193 r36194  
    2424@Projection
    2525class 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"));
    5828    }
    5929
     30    @Test
     31    void testGetIcon() {
     32        assertNotNull(StreetsideLayer.getInstance().getIcon());
     33    }
    6034
    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()));
    6438    }
    65   }
    6639
    67   @Test
    68   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    }
    7346
    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    }
    8485}
  • applications/editors/josm/plugins/MicrosoftStreetside/test/unit/org/openstreetmap/josm/plugins/streetside/StreetsideSequenceTest.java

    r36064 r36194  
    2020class StreetsideSequenceTest {
    2121
    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();
    2828
    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   }
     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    }
    3737
    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());
     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());
    5050
     51        assertNull(img4.next());
     52        assertNull(img1.previous());
    5153
    52     assertNull(img4.next());
    53     assertNull(img1.previous());
     54        assertNull(imgWithoutSeq.next());
     55        assertNull(imgWithoutSeq.previous());
    5456
    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));
    5760
    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    }
    6665}
  • applications/editors/josm/plugins/MicrosoftStreetside/test/unit/org/openstreetmap/josm/plugins/streetside/cache/CachesTest.java

    r36064 r36194  
    11// License: GPL. For details, see LICENSE file.
    22package org.openstreetmap.josm.plugins.streetside.cache;
    3 
    43
    54import org.junit.jupiter.api.Test;
     
    87class CachesTest {
    98
    10   @Test
    11   void testUtilityClass() {
    12     TestUtil.testUtilityClass(Caches.class);
    13   }
     9    @Test
     10    void testUtilityClass() {
     11        TestUtil.testUtilityClass(Caches.class);
     12    }
    1413}
  • applications/editors/josm/plugins/MicrosoftStreetside/test/unit/org/openstreetmap/josm/plugins/streetside/cache/StreetsideCacheTest.java

    r36064 r36194  
    1313class StreetsideCacheTest {
    1414
    15   @Test
    16   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());
    2020
    21     assertFalse(cache.isObjectLoadable());
     21        assertFalse(cache.isObjectLoadable());
    2222
    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());
    2626
    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    }
    3131}
  • 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.
    12package org.openstreetmap.josm.plugins.streetside.cubemap;
    2 
    33
    44import static org.junit.jupiter.api.Assertions.assertEquals;
     
    99class CubemapUtilsTest {
    1010
    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   }
     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    }
    2020
    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   }
     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    }
    3030
    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   }
     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    }
    4747
    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   }
     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    }
    6464
    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");
     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");
    8383
    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    }
    101101}
  • 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.
    12package org.openstreetmap.josm.plugins.streetside.cubemap;
    2 
    33
    44import static org.junit.jupiter.api.Assertions.assertEquals;
     
    1717class TileDownloadingTaskTest {
    1818
    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   }
     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    }
    2727}
  • applications/editors/josm/plugins/MicrosoftStreetside/test/unit/org/openstreetmap/josm/plugins/streetside/gui/ImageDisplayTest.java

    r36064 r36194  
    2020class ImageDisplayTest {
    2121
    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);
    2323
    24   @Test
    25   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    }
    3030
    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     */
    3535
    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);
    4057    }
    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);
    4458
    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);
    4673
    47     display.getMouseWheelListeners()[0].mouseWheelMoved(dummyScroll);
     74            display.setImage(DUMMY_IMAGE, null);
    4875
    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);
    5477
    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();
    5783
    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        }
    6686    }
    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   }
    8587}
  • 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.
    12package org.openstreetmap.josm.plugins.streetside.gui;
    23
     
    2223@Disabled
    2324class 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));
    2938    }
    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   }
    3839
    39   @Test
    40   void testIsExpert() {
    41     Assertions.assertFalse(new StreetsidePreferenceSetting().isExpert());
    42   }
     40    @Test
     41    void testIsExpert() {
     42        Assertions.assertFalse(new StreetsidePreferenceSetting().isExpert());
     43    }
    4344
    44   @SuppressWarnings("unchecked")
    45   @Test
    46   void testOk() {
    47     StreetsidePreferenceSetting settings = new StreetsidePreferenceSetting();
     45    @SuppressWarnings("unchecked")
     46    @Test
     47    void testOk() {
     48        StreetsidePreferenceSetting settings = new StreetsidePreferenceSetting();
    4849
    49     // Initialize the properties with some arbitrary value to make sure they are not unset
    50     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");
    5657
    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());
    6472
    65     // Toggle state of the checkboxes
    66     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);
    7179
    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());
    7994
    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        }
    90104    }
    91   }
    92105
    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 checked
    97    */
    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    }
    101114
    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    }
    105118
    106119}
  • applications/editors/josm/plugins/MicrosoftStreetside/test/unit/org/openstreetmap/josm/plugins/streetside/gui/boilerplate/SelectableLabelTest.java

    r36064 r36194  
    77import org.junit.jupiter.api.Test;
    88
    9 
    109class SelectableLabelTest {
    11   @Test
    12   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    }
    1918}
  • applications/editors/josm/plugins/MicrosoftStreetside/test/unit/org/openstreetmap/josm/plugins/streetside/history/StreetsideRecordTest.java

    r36064 r36194  
    11// License: GPL. For details, see LICENSE file.
    22package org.openstreetmap.josm.plugins.streetside.history;
    3 
    43
    54import static org.junit.jupiter.api.Assertions.assertEquals;
     
    3534class StreetsideRecordTest {
    3635
    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    }
    235216}
  • applications/editors/josm/plugins/MicrosoftStreetside/test/unit/org/openstreetmap/josm/plugins/streetside/io/download/SequenceDownloadRunnableTest.java

    r36064 r36194  
    11// License: GPL. For details, see LICENSE file.
    22package org.openstreetmap.josm.plugins.streetside.io.download;
    3 
    43
    54import static org.junit.jupiter.api.Assertions.assertEquals;
     
    2120class SequenceDownloadRunnableTest {
    2221
    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;
    2726
     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    }
    2831
    29   @Test
    30   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    }
    3336
    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    }
    3847
    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    }
    4553
    46   @Test
    47   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    }
    5159
    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    }
    6567}
  • applications/editors/josm/plugins/MicrosoftStreetside/test/unit/org/openstreetmap/josm/plugins/streetside/utils/ImageUtilTest.java

    r36064 r36194  
    11// License: GPL. For details, see LICENSE file.
    22package org.openstreetmap.josm.plugins.streetside.utils;
    3 
    43
    54import static org.junit.jupiter.api.Assertions.assertEquals;
     
    1110import org.junit.jupiter.api.Test;
    1211
    13 
    1412class ImageUtilTest {
    1513
    16   @Test
    17   void testUtilityClass() {
    18     TestUtil.testUtilityClass(ImageUtil.class);
    19   }
     14    @Test
     15    void testUtilityClass() {
     16        TestUtil.testUtilityClass(ImageUtil.class);
     17    }
    2018
    21   @Test
    22   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);
    2725
    28     assertEquals(24, smallLandscape.getIconWidth());
    29     assertEquals(20, smallLandscape.getIconHeight());
     26        assertEquals(24, smallLandscape.getIconWidth());
     27        assertEquals(20, smallLandscape.getIconHeight());
    3028
    31     assertEquals(22, smallPortrait.getIconHeight());
    32     assertEquals(14, smallPortrait.getIconWidth());
    33   }
     29        assertEquals(22, smallPortrait.getIconHeight());
     30        assertEquals(14, smallPortrait.getIconWidth());
     31    }
    3432}
  • applications/editors/josm/plugins/MicrosoftStreetside/test/unit/org/openstreetmap/josm/plugins/streetside/utils/JsonUtil.java

    r36122 r36194  
    99
    1010public final class JsonUtil {
    11   private JsonUtil() {
    12     // Private constructor to avoid instantiation
    13   }
     11    private JsonUtil() {
     12        // Private constructor to avoid instantiation
     13    }
    1414
    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    }
    1818}
  • applications/editors/josm/plugins/MicrosoftStreetside/test/unit/org/openstreetmap/josm/plugins/streetside/utils/PluginStateTest.java

    r36064 r36194  
    11// License: GPL. For details, see LICENSE file.
    22package org.openstreetmap.josm.plugins.streetside.utils;
    3 
    43
    54import static org.junit.jupiter.api.Assertions.assertEquals;
     
    2120class PluginStateTest {
    2221
    23   /**
    24    * Test the methods related to the download.
    25    */
    26   @Test
    27   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    }
    3837
    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    }
    6359}
  • applications/editors/josm/plugins/MicrosoftStreetside/test/unit/org/openstreetmap/josm/plugins/streetside/utils/StreetsideColorSchemeTest.java

    r36064 r36194  
    1010class StreetsideColorSchemeTest {
    1111
    12   @Test
    13   void testUtilityClass() {
    14     TestUtil.testUtilityClass(StreetsideColorScheme.class);
    15   }
     12    @Test
     13    void testUtilityClass() {
     14        TestUtil.testUtilityClass(StreetsideColorScheme.class);
     15    }
    1616
    17   @Test
    18   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    }
    2222}
  • applications/editors/josm/plugins/MicrosoftStreetside/test/unit/org/openstreetmap/josm/plugins/streetside/utils/StreetsidePropertiesTest.java

    r36064 r36194  
    55
    66public class StreetsidePropertiesTest {
    7   @Test
    8   public void testUtilityClass() {
    9     TestUtil.testUtilityClass(StreetsideProperties.class);
    10   }
     7    @Test
     8    public void testUtilityClass() {
     9        TestUtil.testUtilityClass(StreetsideProperties.class);
     10    }
    1111
    1212}
  • applications/editors/josm/plugins/MicrosoftStreetside/test/unit/org/openstreetmap/josm/plugins/streetside/utils/StreetsideURLTest.java

    r36064 r36194  
    1616
    1717class StreetsideURLTest {
    18   // TODO: replace with Streetside URL @rrh
    19   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";
    2020
    21   public static class APIv3 {
     21    public static class APIv3 {
    2222
    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        }*/
    2743    }
    2844
    29     @Ignore
    3045    @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     }*/
    43   }
    44 
    45 
    46         @Test
    4746    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));
    5353    }
    5454
    5555    @Test
    5656    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));
    6360    }
    6461
    6562    @Test
    6663    void testParseNextFromHeaderValueNull() {
    67       assertNull(StreetsideURL.APIv3.parseNextFromLinkHeaderValue(null));
     64        assertNull(StreetsideURL.APIv3.parseNextFromLinkHeaderValue(null));
    6865    }
    6966
    7067    @Test
    7168    void testParseNextFromHeaderValueMalformed() {
    72       assertNull(StreetsideURL.APIv3.parseNextFromLinkHeaderValue("<###>; rel=\"next\", blub"));
     69        assertNull(StreetsideURL.APIv3.parseNextFromLinkHeaderValue("<###>; rel=\"next\", blub"));
    7370    }
    7471
    75 
    76   /*public static class Cloudfront {
     72    /*public static class Cloudfront {
    7773    @Ignore
    78         @Test
     74    @Test
    7975    public void testThumbnail() {
    8076      assertUrlEquals(StreetsideURL.VirtualEarth.streetsideTile("arbitrary_key", true), "https://d1cuyjsrcm0gby.cloudfront.net/arbitrary_key/thumb-2048.jpg");
    8177      assertUrlEquals(StreetsideURL.VirtualEarth.streetsideTile("arbitrary_key2", false), "https://d1cuyjsrcm0gby.cloudfront.net/arbitrary_key2/thumb-320.jpg");
    8278    }
    83   }*/
     79    }*/
    8480
    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    }
    9087
    91   @Test
    92   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    }
    9592
    96   @Disabled
    97   @Test
    98   void testConnectURL() {
    99     /*assertUrlEquals(
     93    @Disabled
     94    @Test
     95    void testConnectURL() {
     96        /*assertUrlEquals(
    10097        StreetsideURL.MainWebsite.connect("http://redirect-host/ä"),
    10198        "https://www.streetside.com/connect",
     
    104101        "response_type=token",
    105102        "redirect_uri=http%3A%2F%2Fredirect-host%2F%C3%A4"
    106     );
     103        );
    107104
    108     assertUrlEquals(
     105        assertUrlEquals(
    109106        StreetsideURL.MainWebsite.connect(null),
    110107        "https://www.streetside.com/connect",
     
    112109        "scope=user%3Aread+public%3Aupload+public%3Awrite",
    113110        "response_type=token"
    114     );
     111        );
    115112
    116     assertUrlEquals(
     113        assertUrlEquals(
    117114        StreetsideURL.MainWebsite.connect(""),
    118115        "https://www.streetside.com/connect",
     
    120117        "scope=user%3Aread+public%3Aupload+public%3Awrite",
    121118        "response_type=token"
    122     );*/
    123   }
     119        );*/
     120    }
    124121
    125   @Disabled
    126   @Test
    127   void testUploadSecretsURL() throws MalformedURLException {
    128     /*assertEquals(
     122    @Disabled
     123    @Test
     124    void testUploadSecretsURL() throws MalformedURLException {
     125        /*assertEquals(
    129126        new URL("https://a.streetside.com/v2/me/uploads/secrets?"+CLIENT_ID_QUERY_PART),
    130127        StreetsideURL.uploadSecretsURL()
    131     );*/
    132   }
     128        );*/
     129    }
    133130
    134   @Disabled
    135   @Test
    136   void testUserURL() throws MalformedURLException {
    137     /*assertEquals(
     131    @Disabled
     132    @Test
     133    void testUserURL() throws MalformedURLException {
     134        /*assertEquals(
    138135        new URL("https://a.streetside.com/v3/me?"+CLIENT_ID_QUERY_PART),
    139136        StreetsideURL.APIv3.userURL()
    140     );*/
    141   }
     137        );*/
     138    }
    142139
    143   @Test
    144   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    }
    151148
    152   @Test
    153   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    }
    159156
    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        }
    171172    }
    172   }
    173173}
  • applications/editors/josm/plugins/MicrosoftStreetside/test/unit/org/openstreetmap/josm/plugins/streetside/utils/StreetsideUtilsTest.java

    r36064 r36194  
    1111 * Tests the static methods of the class {@link StreetsideUtils}
    1212 *
     13 * @author nokutu
    1314 * @see StreetsideUtils
    14  * @author nokutu
    15  *
    1615 */
    1716class StreetsideUtilsTest {
    1817
    19   @Test
    20   void testUtilityClass() {
    21     TestUtil.testUtilityClass(StreetsideUtils.class);
    22   }
     18    @Test
     19    void testUtilityClass() {
     20        TestUtil.testUtilityClass(StreetsideUtils.class);
     21    }
    2322
    24   /**
    25    * Test {@link StreetsideUtils#degMinSecToDouble(RationalNumber[], String)}
    26    * method.
    27    */
    28   @Test
    29   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    }
    4342}
  • applications/editors/josm/plugins/MicrosoftStreetside/test/unit/org/openstreetmap/josm/plugins/streetside/utils/TestUtil.java

    r36193 r36194  
    1818public final class TestUtil {
    1919
    20   private TestUtil() {
    21     // Prevent instantiation
    22   }
     20    private TestUtil() {
     21        // Prevent instantiation
     22    }
    2323
    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        }
    3435    }
    35   }
    3636
    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        }
    4849    }
    49   }
    5050
    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        }
    7577    }
    76   }
    7778}
  • applications/editors/josm/plugins/MicrosoftStreetside/test/unit/org/openstreetmap/josm/plugins/streetside/utils/api/JsonDecoderTest.java

    r36122 r36194  
    11// License: GPL. For details, see LICENSE file.
    22package org.openstreetmap.josm.plugins.streetside.utils.api;
    3 
    43
    54import static org.junit.jupiter.api.Assertions.assertArrayEquals;
     
    1817class JsonDecoderTest {
    1918
    20   @Test
    21   void testUtilityClass() {
    22     TestUtil.testUtilityClass(JsonDecoder.class);
    23   }
     19    @Test
     20    void testUtilityClass() {
     21        TestUtil.testUtilityClass(JsonDecoder.class);
     22    }
    2423
    25   @Test
    26   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    }
    2928
    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    }
    3534
    3635}
  • applications/editors/josm/plugins/MicrosoftStreetside/test/unit/org/openstreetmap/josm/plugins/streetside/utils/api/JsonSequencesDecoderTest.java

    r36122 r36194  
    2929class JsonSequencesDecoderTest {
    3030
    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());
    4241
    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());
    4746
    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);
    5251
    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());
    5756
    58     assertEquals(1_457_963_093_860L, seq.getCd()); // 2016-03-14T13:44:53.860 UTC
    59   }
     57        assertEquals(1_457_963_093_860L, seq.getCd()); // 2016-03-14T13:44:53.860 UTC
     58    }
    6059
    61   @Test
    62   void testDecodeSequencesInvalid() {
    63     // null input
    64     assertEquals(0, JsonDecoder.decodeFeatureCollection(null, JsonSequencesDecoder::decodeSequence).size());
    65     // empty object
    66     assertNumberOfDecodedSequences(0, "{}");
    67     // object without type=FeatureCollection
    68     assertNumberOfDecodedSequences(0, "{\"features\": []}");
    69     // object with wrong value for the type attribute
    70     assertNumberOfDecodedSequences(0, "{\"type\": \"SomethingArbitrary\", \"features\": []}");
    71     // object without features-array
    72     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    }
    7675
    77   @Test
    78   void testDecodeSequencesWithArbitraryObjectAsFeature() {
    79     assertNumberOfDecodedSequences(0, "{\"type\": \"FeatureCollection\", \"features\": [{}]}");
    80   }
     76    @Test
     77    void testDecodeSequencesWithArbitraryObjectAsFeature() {
     78        assertNumberOfDecodedSequences(0, "{\"type\": \"FeatureCollection\", \"features\": [{}]}");
     79    }
    8180
    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    }
    8886
    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());
    9895
    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    }
    102101
    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    }
    138127
    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    }
    150140
    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);
    161147
    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);
    165150
    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    }
    170156
    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);
    177162
    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);
    181168
    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);
    185174
    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    }
    194185
    195   @Test
    196   void testUtilityClass() {
    197     TestUtil.testUtilityClass(JsonSequencesDecoder.class);
    198   }
     186    @Test
     187    void testUtilityClass() {
     188        TestUtil.testUtilityClass(JsonSequencesDecoder.class);
     189    }
    199190
    200191}
Note: See TracChangeset for help on using the changeset viewer.