source: josm/trunk/src/org/openstreetmap/josm/gui/layer/geoimage/ImageEntry.java@ 7912

Last change on this file since 7912 was 7912, checked in by bastiK, 9 years ago

applied #10894 - Show photo direction arrow for thumbnail (patch by holgermappt)

  • Property svn:eol-style set to native
File size: 8.0 KB
Line 
1// License: GPL. See LICENSE file for details.
2package org.openstreetmap.josm.gui.layer.geoimage;
3
4import java.awt.Image;
5import java.io.File;
6import java.util.Date;
7
8import org.openstreetmap.josm.data.coor.CachedLatLon;
9import org.openstreetmap.josm.data.coor.LatLon;
10
11/**
12 * Stores info about each image
13 */
14public final class ImageEntry implements Comparable<ImageEntry>, Cloneable {
15 private File file;
16 private Integer exifOrientation;
17 private LatLon exifCoor;
18 private Double exifImgDir;
19 private Date exifTime;
20 /**
21 * Flag isNewGpsData indicates that the GPS data of the image is new or has changed.
22 * GPS data includes the position, speed, elevation, time (e.g. as extracted from the GPS track).
23 * The flag can used to decide for which image file the EXIF GPS data is (re-)written.
24 */
25 private boolean isNewGpsData = false;
26 /** Temporary source of GPS time if not correlated with GPX track. */
27 private Date exifGpsTime = null;
28 Image thumbnail;
29
30 /**
31 * The following values are computed from the correlation with the gpx track
32 * or extracted from the image EXIF data.
33 */
34 private CachedLatLon pos;
35 /** Speed in kilometer per hour */
36 private Double speed;
37 /** Elevation (altitude) in meters */
38 private Double elevation;
39 /** The time after correlation with a gpx track */
40 private Date gpsTime;
41
42 /**
43 * When the correlation dialog is open, we like to show the image position
44 * for the current time offset on the map in real time.
45 * On the other hand, when the user aborts this operation, the old values
46 * should be restored. We have a temprary copy, that overrides
47 * the normal values if it is not null. (This may be not the most elegant
48 * solution for this, but it works.)
49 */
50 ImageEntry tmp;
51
52 /**
53 * getter methods that refer to the temporary value
54 */
55 public CachedLatLon getPos() {
56 if (tmp != null)
57 return tmp.pos;
58 return pos;
59 }
60 public Double getSpeed() {
61 if (tmp != null)
62 return tmp.speed;
63 return speed;
64 }
65 public Double getElevation() {
66 if (tmp != null)
67 return tmp.elevation;
68 return elevation;
69 }
70
71 public Date getGpsTime() {
72 if (tmp != null)
73 return getDefensiveDate(tmp.gpsTime);
74 return getDefensiveDate(gpsTime);
75 }
76
77 /**
78 * Convenient way to determine if this entry has a GPS time, without the cost of building a defensive copy.
79 * @return {@code true} if this entry has a GPS time
80 * @since 6450
81 */
82 public final boolean hasGpsTime() {
83 return (tmp != null && tmp.gpsTime != null) || gpsTime != null;
84 }
85
86 /**
87 * other getter methods
88 */
89 public File getFile() {
90 return file;
91 }
92 public Integer getExifOrientation() {
93 return exifOrientation;
94 }
95 public Date getExifTime() {
96 return getDefensiveDate(exifTime);
97 }
98
99 /**
100 * Convenient way to determine if this entry has a EXIF time, without the cost of building a defensive copy.
101 * @return {@code true} if this entry has a EXIF time
102 * @since 6450
103 */
104 public final boolean hasExifTime() {
105 return exifTime != null;
106 }
107
108 /**
109 * Returns the EXIF GPS time.
110 * @return the EXIF GPS time
111 * @since 6392
112 */
113 public final Date getExifGpsTime() {
114 return getDefensiveDate(exifGpsTime);
115 }
116
117 /**
118 * Convenient way to determine if this entry has a EXIF GPS time, without the cost of building a defensive copy.
119 * @return {@code true} if this entry has a EXIF GPS time
120 * @since 6450
121 */
122 public final boolean hasExifGpsTime() {
123 return exifGpsTime != null;
124 }
125
126 private static Date getDefensiveDate(Date date) {
127 if (date == null)
128 return null;
129 return new Date(date.getTime());
130 }
131
132 public LatLon getExifCoor() {
133 return exifCoor;
134 }
135 public Double getExifImgDir() {
136 return exifImgDir;
137 }
138
139 public boolean hasThumbnail() {
140 return thumbnail != null;
141 }
142
143 /**
144 * setter methods
145 */
146 public void setPos(CachedLatLon pos) {
147 this.pos = pos;
148 }
149 public void setPos(LatLon pos) {
150 this.pos = new CachedLatLon(pos);
151 }
152 public void setSpeed(Double speed) {
153 this.speed = speed;
154 }
155 public void setElevation(Double elevation) {
156 this.elevation = elevation;
157 }
158 public void setFile(File file) {
159 this.file = file;
160 }
161 public void setExifOrientation(Integer exifOrientation) {
162 this.exifOrientation = exifOrientation;
163 }
164 public void setExifTime(Date exifTime) {
165 this.exifTime = getDefensiveDate(exifTime);
166 }
167
168 /**
169 * Sets the EXIF GPS time.
170 * @param exifGpsTime the EXIF GPS time
171 * @since 6392
172 */
173 public final void setExifGpsTime(Date exifGpsTime) {
174 this.exifGpsTime = getDefensiveDate(exifGpsTime);
175 }
176
177 public void setGpsTime(Date gpsTime) {
178 this.gpsTime = getDefensiveDate(gpsTime);
179 }
180 public void setExifCoor(LatLon exifCoor) {
181 this.exifCoor = exifCoor;
182 }
183 public void setExifImgDir(double exifDir) {
184 this.exifImgDir = exifDir;
185 }
186
187 @Override
188 public ImageEntry clone() {
189 Object c;
190 try {
191 c = super.clone();
192 } catch (CloneNotSupportedException e) {
193 throw new RuntimeException(e);
194 }
195 return (ImageEntry) c;
196 }
197
198 @Override
199 public int compareTo(ImageEntry image) {
200 if (exifTime != null && image.exifTime != null)
201 return exifTime.compareTo(image.exifTime);
202 else if (exifTime == null && image.exifTime == null)
203 return 0;
204 else if (exifTime == null)
205 return -1;
206 else
207 return 1;
208 }
209
210 /**
211 * Make a fresh copy and save it in the temporary variable.
212 */
213 public void cleanTmp() {
214 tmp = clone();
215 tmp.setPos(null);
216 tmp.tmp = null;
217 }
218
219 /**
220 * Copy the values from the temporary variable to the main instance.
221 */
222 public void applyTmp() {
223 if (tmp != null) {
224 pos = tmp.pos;
225 speed = tmp.speed;
226 elevation = tmp.elevation;
227 gpsTime = tmp.gpsTime;
228 tmp = null;
229 }
230 }
231
232 /**
233 * If it has been tagged i.e. matched to a gpx track or retrieved lat/lon from exif
234 */
235 public boolean isTagged() {
236 return pos != null;
237 }
238
239 /**
240 * String representation. (only partial info)
241 */
242 @Override
243 public String toString() {
244 return file.getName()+": "+
245 "pos = "+pos+" | "+
246 "exifCoor = "+exifCoor+" | "+
247 (tmp == null ? " tmp==null" :
248 " [tmp] pos = "+tmp.pos);
249 }
250
251 /**
252 * Indicates that the image has new GPS data.
253 * That flag is used e.g. by the photo_geotagging plugin to decide for which image
254 * file the EXIF GPS data needs to be (re-)written.
255 * @since 6392
256 */
257 public void flagNewGpsData() {
258 isNewGpsData = true;
259 // We need to set the GPS time to tell the system (mainly the photo_geotagging plug-in)
260 // that the GPS data has changed. Check for existing GPS time and take EXIF time otherwise.
261 // This can be removed once isNewGpsData is used instead of the GPS time.
262 if (gpsTime == null) {
263 Date time = getExifGpsTime();
264 if (time == null) {
265 time = getExifTime();
266 if (time == null) {
267 // Time still not set, take the current time.
268 time = new Date();
269 }
270 }
271 gpsTime = time;
272 }
273 if (tmp != null && !tmp.hasGpsTime()) {
274 // tmp.gpsTime overrides gpsTime, so we set it too.
275 tmp.gpsTime = gpsTime;
276 }
277 }
278
279 /**
280 * Queries whether the GPS data changed.
281 * @return {@code true} if GPS data changed, {@code false} otherwise
282 * @since 6392
283 */
284 public boolean hasNewGpsData() {
285 return isNewGpsData;
286 }
287}
Note: See TracBrowser for help on using the repository browser.