001// License: GPL. For details, see LICENSE file. 002package org.openstreetmap.josm.plugins.streetside; 003 004import org.openstreetmap.josm.data.coor.LatLon; 005 006/** 007 * Abstract superclass for all image objects. At the moment there are 2, 008 * {@link StreetsideImage}, {@link StreetsideCubemap}. 009 * 010 * @author nokutu 011 * @author renerr18 012 * 013 */ 014public abstract class StreetsideAbstractImage implements Comparable<StreetsideAbstractImage> { 015 /** 016 * If two values for field cd differ by less than EPSILON both values are 017 * considered equal. 018 */ 019 private static final float EPSILON = 1e-5f; 020 021 protected String id; 022 023 // Image id of next image in sequence (decimal) 024 private long ne; 025 //Image id of previous image in sequence (decimal) 026 private long pr; 027 028 029 /** Sequence of pictures containing this object. */ 030 private StreetsideSequence sequence; 031 032 /** Position of the picture. */ 033 protected LatLon latLon; 034 /** Direction of the picture in degrees from true north. */ 035 protected double he; 036 /** Temporal position of the picture until it is uploaded. */ 037 private LatLon tempLatLon; 038 /** 039 * When the object is being dragged in the map, the temporal position is stored 040 * here. 041 */ 042 private LatLon movingLatLon; 043 /** Temporal direction of the picture until it is uploaded */ 044 private double tempHe; 045 /** 046 * When the object direction is being moved in the map, the temporal direction 047 * is stored here 048 */ 049 protected double movingHe; 050 /** Whether the image must be drown in the map or not */ 051 private boolean visible; 052 053 /** 054 * Creates a new object in the given position and with the given direction. 055 * {@link LatLon} 056 * 057 * @param id - the Streetside image id 058 * 059 * @param latLon 060 * The latitude and longitude of the image. 061 * @param he 062 * The direction of the picture (0 means north im Mapillary 063 * camera direction is not yet supported in the Streetside plugin). 064 */ 065 protected StreetsideAbstractImage(final String id, final LatLon latLon, final double he) { 066 this.id = id; 067 this.latLon = latLon; 068 tempLatLon = this.latLon; 069 movingLatLon = this.latLon; 070 this.he = he; 071 tempHe = he; 072 movingHe = he; 073 visible = true; 074 } 075 076 /** 077 * Creates a new object with the given id. 078 * 079 * @param id - the image id (All images require ids in Streetside) 080 */ 081 protected StreetsideAbstractImage(final String id) { 082 this.id = id; 083 084 visible = true; 085 } 086 087 /** 088 * @return the id 089 */ 090 public String getId() { 091 return id; 092 } 093 094 /** 095 * @param id 096 * the id to set 097 */ 098 public void setId(String id) { 099 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 /** 286 * @return the ne 287 */ 288 public long getNe() { 289 return ne; 290 } 291 292 /** 293 * @param ne the ne to set 294 */ 295 public void setNe(long ne) { 296 this.ne = ne; 297 } 298 299 /** 300 * @return the pr 301 */ 302 public long getPr() { 303 return pr; 304 } 305 306 /** 307 * @param pr the pr to set 308 */ 309 public void setPr(long pr) { 310 this.pr = pr; 311 } 312 313}