source: josm/trunk/src/org/openstreetmap/josm/data/gpx/GpxImageEntry.java@ 19391

Last change on this file since 19391 was 19391, checked in by stoecker, 12 days ago

fix typo in Javadoc

  • Property svn:eol-style set to native
File size: 25.0 KB
Line 
1// License: GPL. For details, see LICENSE file.
2package org.openstreetmap.josm.data.gpx;
3
4import java.awt.Dimension;
5import java.awt.image.BufferedImage;
6import java.io.File;
7import java.io.IOException;
8import java.io.InputStream;
9import java.net.URI;
10import java.nio.file.Files;
11import java.time.Instant;
12import java.util.Date;
13import java.util.List;
14import java.util.Objects;
15
16import javax.imageio.IIOParam;
17
18import org.openstreetmap.josm.data.IQuadBucketType;
19import org.openstreetmap.josm.data.coor.CachedLatLon;
20import org.openstreetmap.josm.data.coor.ILatLon;
21import org.openstreetmap.josm.data.coor.LatLon;
22import org.openstreetmap.josm.data.imagery.street_level.Projections;
23import org.openstreetmap.josm.data.osm.BBox;
24import org.openstreetmap.josm.gui.layer.geoimage.ImageMetadata;
25
26/**
27 * Stores info about each image
28 * @since 14205 (extracted from gui.layer.geoimage.ImageEntry)
29 */
30public class GpxImageEntry implements Comparable<GpxImageEntry>, IQuadBucketType, ImageMetadata {
31 private File file;
32 private Integer exifOrientation;
33 private LatLon exifCoor;
34 private Double exifImgDir;
35 private Double exifGpsTrack;
36 private Double exifHPosErr;
37 private Double exifGpsDop;
38 private Instant exifTime;
39 private Projections cameraProjection = Projections.UNKNOWN;
40 /**
41 * Flag isNewGpsData indicates that the GPS data of the image is new or has changed.
42 * GPS data includes the position, speed, elevation, time (e.g. as extracted from the GPS track).
43 * The flag can used to decide for which image file the EXIF GPS data is (re-)written.
44 */
45 private boolean isNewGpsData;
46 /** Temporary source of GPS time if not correlated with GPX track. */
47 private Instant exifGpsTime;
48
49 private String iptcCaption;
50 private String iptcHeadline;
51 private List<String> iptcKeywords;
52 private String iptcObjectName;
53
54 /**
55 * The following values are computed from the correlation with the gpx track
56 * or extracted from the image EXIF data.
57 */
58 private CachedLatLon pos;
59 /** Speed in kilometer per hour */
60 private Double speed;
61 /** Elevation (altitude) in meters */
62 private Double elevation;
63 /** GPS Differential mode */
64 private Integer gpsDiffMode;
65 /** GPS Measure mode */
66 private Integer gps2d3dMode;
67 /** GPS Datum */
68 private String exifGpsDatum;
69 /** GPS processing method */
70 private String exifGpsProcMethod;
71 /** The time after correlation with a gpx track */
72 private Instant gpsTime;
73
74 private int width;
75 private int height;
76
77 /**
78 * When the correlation dialog is open, we like to show the image position
79 * for the current time offset on the map in real time.
80 * On the other hand, when the user aborts this operation, the old values
81 * should be restored. We have a temporary copy, that overrides
82 * the normal values if it is not null. (This may be not the most elegant
83 * solution for this, but it works.)
84 */
85 private GpxImageEntry tmp;
86
87 /**
88 * Constructs a new {@code GpxImageEntry}.
89 */
90 public GpxImageEntry() {}
91
92 /**
93 * Constructs a new {@code GpxImageEntry} from an existing instance.
94 * @param other existing instance
95 * @since 14624
96 */
97 public GpxImageEntry(GpxImageEntry other) {
98 file = other.file;
99 exifOrientation = other.exifOrientation;
100 exifCoor = other.exifCoor;
101 exifImgDir = other.exifImgDir;
102 exifGpsTrack = other.exifGpsTrack;
103 exifHPosErr = other.exifHPosErr;
104 gpsDiffMode = other.gpsDiffMode;
105 gps2d3dMode = other.gps2d3dMode;
106 exifGpsDop = other.exifGpsDop;
107 exifGpsDatum = other.exifGpsDatum;
108 exifGpsProcMethod = other.exifGpsProcMethod;
109 exifTime = other.exifTime;
110 isNewGpsData = other.isNewGpsData;
111 exifGpsTime = other.exifGpsTime;
112 pos = other.pos;
113 speed = other.speed;
114 elevation = other.elevation;
115 gpsTime = other.gpsTime;
116 width = other.width;
117 height = other.height;
118 tmp = other.tmp;
119 }
120
121 /**
122 * Constructs a new {@code GpxImageEntry}.
123 * @param file Path to image file on disk
124 */
125 public GpxImageEntry(File file) {
126 setFile(file);
127 }
128
129 @Override
130 public URI getImageURI() {
131 return this.getFile().toURI();
132 }
133
134 /**
135 * Returns width of the image this GpxImageEntry represents.
136 * @return width of the image this GpxImageEntry represents
137 * @since 13220
138 */
139 @Override
140 public int getWidth() {
141 return width;
142 }
143
144 /**
145 * Returns height of the image this GpxImageEntry represents.
146 * @return height of the image this GpxImageEntry represents
147 * @since 13220
148 */
149 @Override
150 public int getHeight() {
151 return height;
152 }
153
154 /**
155 * Returns the position value. The position value from the temporary copy
156 * is returned if that copy exists.
157 * @return the position value
158 */
159 @Override
160 public CachedLatLon getPos() {
161 if (tmp != null)
162 return tmp.pos;
163 return pos;
164 }
165
166 /**
167 * Returns the speed value. The speed value from the temporary copy is
168 * returned if that copy exists.
169 * @return the speed value
170 */
171 @Override
172 public Double getSpeed() {
173 if (tmp != null)
174 return tmp.speed;
175 return speed;
176 }
177
178 /**
179 * Returns the elevation value. The elevation value from the temporary
180 * copy is returned if that copy exists.
181 * @return the elevation value
182 */
183 @Override
184 public Double getElevation() {
185 if (tmp != null)
186 return tmp.elevation;
187 return elevation;
188 }
189
190 /**
191 * Return the GPS Differential mode value. The GPS Differential mode value from the temporary
192 * copy is returned if that copy exists.
193 * @return the differential mode value
194 * @since 19387
195 */
196 @Override
197 public Integer getGpsDiffMode() {
198 if (tmp != null)
199 return tmp.gpsDiffMode;
200 return gpsDiffMode;
201 }
202
203 /**
204 * Return the GPS 2d or 3d mode value. The GPS mode value form the temporary
205 * copy is returned if that copy exists.
206 * @return the GPS 2d/3d mode value
207 * @since 19387
208 */
209 @Override
210 public Integer getGps2d3dMode() {
211 if (tmp != null)
212 return tmp.gps2d3dMode;
213 return gps2d3dMode;
214 }
215
216 /**
217 * Return the GPS DOP value. The GPS DOP value from the temporary
218 * copy is returned if that copy exists.
219 * @return the DOP value
220 * @since 19387
221 */
222 @Override
223 public Double getExifGpsDop() {
224 if (tmp != null)
225 return tmp.exifGpsDop;
226 return exifGpsDop;
227 }
228
229 /**
230 * Return the EXIF GPS coordinates datum value.
231 * @return The datum value
232 * @since 19387
233 */
234 @Override
235 public String getExifGpsDatum() {
236 if (tmp != null)
237 return tmp.exifGpsDatum;
238 return exifGpsDatum;
239 }
240
241 /**
242 * Return the EXIF GPS processing method string
243 * @return the processing method string
244 * @since 19387
245 */
246 @Override
247 public String getExifGpsProcMethod() {
248 if (tmp != null)
249 return tmp.exifGpsProcMethod;
250 return exifGpsProcMethod;
251 }
252
253 /**
254 * Returns the GPS time value. The GPS time value from the temporary copy
255 * is returned if that copy exists.
256 * @return the GPS time value
257 */
258 @Override
259 public Instant getGpsInstant() {
260 return tmp != null ? tmp.gpsTime : gpsTime;
261 }
262
263 /**
264 * Convenient way to determine if this entry has a GPS time, without the cost of building a defensive copy.
265 * @return {@code true} if this entry has a GPS time
266 * @since 6450
267 */
268 @Override
269 public boolean hasGpsTime() {
270 return (tmp != null && tmp.gpsTime != null) || gpsTime != null;
271 }
272
273 /**
274 * Returns associated file.
275 * @return associated file
276 */
277 public File getFile() {
278 return file;
279 }
280
281 /**
282 * Returns a display name for this entry
283 * @return a display name for this entry
284 */
285 @Override
286 public String getDisplayName() {
287 return file == null ? "" : file.getName();
288 }
289
290 /**
291 * Returns EXIF orientation
292 * @return EXIF orientation
293 */
294 @Override
295 public Integer getExifOrientation() {
296 return exifOrientation != null ? exifOrientation : 1;
297 }
298
299 /**
300 * Returns EXIF time
301 * @return EXIF time
302 * @since 17715
303 */
304 @Override
305 public Instant getExifInstant() {
306 return exifTime;
307 }
308
309 /**
310 * Convenient way to determine if this entry has a EXIF time, without the cost of building a defensive copy.
311 * @return {@code true} if this entry has a EXIF time
312 * @since 6450
313 */
314 @Override
315 public boolean hasExifTime() {
316 return exifTime != null;
317 }
318
319 /**
320 * Returns the EXIF GPS time.
321 * @return the EXIF GPS time
322 * @since 17715
323 */
324 @Override
325 public Instant getExifGpsInstant() {
326 return exifGpsTime;
327 }
328
329 /**
330 * Convenient way to determine if this entry has a EXIF GPS time, without the cost of building a defensive copy.
331 * @return {@code true} if this entry has a EXIF GPS time
332 * @since 6450
333 */
334 @Override
335 public boolean hasExifGpsTime() {
336 return exifGpsTime != null;
337 }
338
339 private static Date getDefensiveDate(Instant date) {
340 if (date == null)
341 return null;
342 return Date.from(date);
343 }
344
345 @Override
346 public LatLon getExifCoor() {
347 return exifCoor;
348 }
349
350 @Override
351 public Double getExifImgDir() {
352 if (tmp != null)
353 return tmp.exifImgDir;
354 return exifImgDir;
355 }
356
357 /**
358 * Convenient way to determine if this entry has a EXIF GPS track angle value,
359 * without the cost of building a defensive copy.
360 * @return {@code true} if this entry has a EXIF track angle value
361 * @since 19387
362 */
363 @Override
364 public Double getExifGpsTrack() {
365 if (tmp != null)
366 return tmp.exifGpsTrack;
367 return exifGpsTrack;
368 }
369
370 /**
371 * Convenient way to determine if this entry has a EXIF GPS horizontal positionning error value,
372 * without the cost of building a defensive copy.
373 * @return {@code true} if this entry has a EXIF GPS horizontal positionning error value
374 * @since 19387
375 */
376 @Override
377 public Double getExifHPosErr() {
378 if (tmp != null)
379 return tmp.exifHPosErr;
380 return exifHPosErr;
381 }
382
383 @Override
384 public Instant getLastModified() {
385 return Instant.ofEpochMilli(this.getFile().lastModified());
386 }
387
388 /**
389 * Sets the width of this GpxImageEntry.
390 * @param width set the width of this GpxImageEntry
391 * @since 13220
392 */
393 @Override
394 public void setWidth(int width) {
395 this.width = width;
396 }
397
398 /**
399 * Sets the height of this GpxImageEntry.
400 * @param height set the height of this GpxImageEntry
401 * @since 13220
402 */
403 @Override
404 public void setHeight(int height) {
405 this.height = height;
406 }
407
408 /**
409 * Sets the position.
410 * @param pos cached position
411 */
412 public void setPos(CachedLatLon pos) {
413 this.pos = pos;
414 }
415
416 /**
417 * Sets the position.
418 * @param pos position (will be cached)
419 */
420 public void setPos(LatLon pos) {
421 setPos(pos != null ? new CachedLatLon(pos) : null);
422 }
423
424 @Override
425 public void setPos(ILatLon pos) {
426 if (pos instanceof CachedLatLon) {
427 this.setPos((CachedLatLon) pos);
428 } else if (pos instanceof LatLon) {
429 this.setPos((LatLon) pos);
430 } else if (pos != null) {
431 this.setPos(new LatLon(pos));
432 } else {
433 this.setPos(null);
434 }
435 }
436
437 /**
438 * Sets the speed.
439 * @param speed speed
440 */
441 @Override
442 public void setSpeed(Double speed) {
443 this.speed = speed;
444 }
445
446 /**
447 * Sets the elevation.
448 * @param elevation elevation
449 */
450 @Override
451 public void setElevation(Double elevation) {
452 this.elevation = elevation;
453 }
454
455 /**
456 * Sets GPS Differential mode.
457 * @param gpsDiffMode GPS Differential mode
458 * @since 19387
459 */
460 @Override
461 public void setGpsDiffMode(Integer gpsDiffMode) {
462 this.gpsDiffMode = gpsDiffMode;
463 }
464
465 /**
466 * Sets GPS 2d/3d mode.
467 * @param gps2d3dMode GPS 2d/3d mode value
468 * @since 19387
469 */
470 @Override
471 public void setGps2d3dMode(Integer gps2d3dMode) {
472 this.gps2d3dMode = gps2d3dMode;
473 }
474
475 /**
476 * Sets GPS DOP value.
477 * @param exifGpsDop GPS DOP value
478 * @since 19387
479 */
480 @Override
481 public void setExifGpsDop(Double exifGpsDop) {
482 this.exifGpsDop = exifGpsDop;
483 }
484
485 /**
486 * Sets the GPS Datum.
487 * @param exifGpsDatum GPS Datum
488 * @since 19387
489 */
490 @Override
491 public void setExifGpsDatum(String exifGpsDatum) {
492 this.exifGpsDatum = exifGpsDatum;
493 }
494
495 /**
496 * Sets the GPS Processing Method.
497 * @param exifGpsProcMethod GPS Processing Method
498 * @since 19387
499 */
500 @Override
501 public void setExifGpsProcMethod(String exifGpsProcMethod) {
502 this.exifGpsProcMethod = exifGpsProcMethod;
503 }
504
505 /**
506 * Sets associated file.
507 * @param file associated file
508 */
509 public void setFile(File file) {
510 this.file = file;
511 }
512
513 /**
514 * Sets EXIF orientation.
515 * @param exifOrientation EXIF orientation
516 */
517 @Override
518 public void setExifOrientation(Integer exifOrientation) {
519 this.exifOrientation = exifOrientation;
520 }
521
522 /**
523 * Sets EXIF time.
524 * @param exifTime EXIF time
525 * @since 17715
526 */
527 @Override
528 public void setExifTime(Instant exifTime) {
529 this.exifTime = exifTime;
530 }
531
532 /**
533 * Sets the EXIF GPS time.
534 * @param exifGpsTime the EXIF GPS time
535 * @since 17715
536 */
537 @Override
538 public void setExifGpsTime(Instant exifGpsTime) {
539 this.exifGpsTime = exifGpsTime;
540 }
541
542 /**
543 * Sets the GPS time.
544 * @param gpsTime the GPS time
545 * @since 17715
546 */
547 @Override
548 public void setGpsTime(Instant gpsTime) {
549 this.gpsTime = gpsTime;
550 }
551
552 /**
553 * Sets the EXIF coordinate.
554 * @param exifCoor the coordinate
555 */
556 public void setExifCoor(LatLon exifCoor) {
557 this.exifCoor = exifCoor;
558 }
559
560 @Override
561 public void setExifCoor(ILatLon exifCoor) {
562 if (exifCoor instanceof LatLon) {
563 this.exifCoor = (LatLon) exifCoor;
564 } else if (exifCoor != null) {
565 this.exifCoor = new LatLon(exifCoor);
566 } else {
567 this.exifCoor = null;
568 }
569 }
570
571 @Override
572 public void setExifImgDir(Double exifDir) {
573 this.exifImgDir = exifDir;
574 }
575
576 /**
577 * Sets the EXIF GPS track (move direction angle)
578 * @param exifGpsTrack the EXIF GPS track angle
579 * @since 19387
580 */
581 @Override
582 public void setExifGpsTrack(Double exifGpsTrack) {
583 this.exifGpsTrack = exifGpsTrack;
584 }
585
586 /**
587 * Sets the EXIF horizontal positioning error
588 * @param exifHPosErr the EXIF horizontal positionning error
589 * @since 19387
590 */
591 @Override
592 public void setExifHPosErr(Double exifHPosErr) {
593 this.exifHPosErr = exifHPosErr;
594 }
595
596 /**
597 * Sets the IPTC caption.
598 * @param iptcCaption the IPTC caption
599 * @since 15219
600 */
601 @Override
602 public void setIptcCaption(String iptcCaption) {
603 this.iptcCaption = iptcCaption;
604 }
605
606 /**
607 * Sets the IPTC headline.
608 * @param iptcHeadline the IPTC headline
609 * @since 15219
610 */
611 @Override
612 public void setIptcHeadline(String iptcHeadline) {
613 this.iptcHeadline = iptcHeadline;
614 }
615
616 /**
617 * Sets the IPTC keywords.
618 * @param iptcKeywords the IPTC keywords
619 * @since 15219
620 */
621 @Override
622 public void setIptcKeywords(List<String> iptcKeywords) {
623 this.iptcKeywords = iptcKeywords;
624 }
625
626 /**
627 * Sets the IPTC object name.
628 * @param iptcObjectName the IPTC object name
629 * @since 15219
630 */
631 @Override
632 public void setIptcObjectName(String iptcObjectName) {
633 this.iptcObjectName = iptcObjectName;
634 }
635
636 /**
637 * Returns the IPTC caption.
638 * @return the IPTC caption
639 * @since 15219
640 */
641 @Override
642 public String getIptcCaption() {
643 return iptcCaption;
644 }
645
646 /**
647 * Returns the IPTC headline.
648 * @return the IPTC headline
649 * @since 15219
650 */
651 @Override
652 public String getIptcHeadline() {
653 return iptcHeadline;
654 }
655
656 /**
657 * Returns the IPTC keywords.
658 * @return the IPTC keywords
659 * @since 15219
660 */
661 @Override
662 public List<String> getIptcKeywords() {
663 return iptcKeywords;
664 }
665
666 /**
667 * Returns the IPTC object name.
668 * @return the IPTC object name
669 * @since 15219
670 */
671 @Override
672 public String getIptcObjectName() {
673 return iptcObjectName;
674 }
675
676 @Override
677 public int compareTo(GpxImageEntry image) {
678 if (exifTime != null && image.exifTime != null)
679 return exifTime.compareTo(image.exifTime);
680 else if (exifTime == null && image.exifTime == null)
681 return 0;
682 else if (exifTime == null)
683 return -1;
684 else
685 return 1;
686 }
687
688 @Override
689 public int hashCode() {
690 return Objects.hash(height, width, isNewGpsData,
691 elevation, exifCoor, exifGpsTime, exifImgDir, exifGpsTrack, exifHPosErr,
692 exifGpsDop, gpsDiffMode, gps2d3dMode, exifGpsDatum, exifGpsProcMethod,
693 exifOrientation, exifTime, iptcCaption, iptcHeadline, iptcKeywords,
694 iptcObjectName, file, gpsTime, pos, speed, tmp, cameraProjection);
695 }
696
697 @Override
698 public boolean equals(Object obj) {
699 if (this == obj)
700 return true;
701 if (obj == null || getClass() != obj.getClass())
702 return false;
703 GpxImageEntry other = (GpxImageEntry) obj;
704 return height == other.height
705 && width == other.width
706 && isNewGpsData == other.isNewGpsData
707 && Objects.equals(elevation, other.elevation)
708 && Objects.equals(exifCoor, other.exifCoor)
709 && Objects.equals(exifGpsTime, other.exifGpsTime)
710 && Objects.equals(exifImgDir, other.exifImgDir)
711 && Objects.equals(exifGpsTrack, other.exifGpsTrack)
712 && Objects.equals(exifHPosErr, other.exifHPosErr)
713 && Objects.equals(gpsDiffMode, other.gpsDiffMode)
714 && Objects.equals(gps2d3dMode, other.gps2d3dMode)
715 && Objects.equals(exifGpsDop, other.exifGpsDop)
716 && Objects.equals(exifGpsDatum, other.exifGpsDatum)
717 && Objects.equals(exifGpsProcMethod, other.exifGpsProcMethod)
718 && Objects.equals(exifOrientation, other.exifOrientation)
719 && Objects.equals(exifTime, other.exifTime)
720 && Objects.equals(iptcCaption, other.iptcCaption)
721 && Objects.equals(iptcHeadline, other.iptcHeadline)
722 && Objects.equals(iptcKeywords, other.iptcKeywords)
723 && Objects.equals(iptcObjectName, other.iptcObjectName)
724 && Objects.equals(file, other.file)
725 && Objects.equals(gpsTime, other.gpsTime)
726 && Objects.equals(pos, other.pos)
727 && Objects.equals(speed, other.speed)
728 && Objects.equals(tmp, other.tmp)
729 && cameraProjection == other.cameraProjection;
730 }
731
732 /**
733 * Make a fresh copy and save it in the temporary variable. Use
734 * {@link #applyTmp()} or {@link #discardTmp()} if the temporary variable
735 * is not needed anymore.
736 * @return the fresh copy.
737 */
738 public GpxImageEntry createTmp() {
739 tmp = new GpxImageEntry(this);
740 tmp.tmp = null;
741 return tmp;
742 }
743
744 /**
745 * Get temporary variable that is used for real time parameter
746 * adjustments. The temporary variable is created if it does not exist
747 * yet. Use {@link #applyTmp()} or {@link #discardTmp()} if the temporary
748 * variable is not needed anymore.
749 * @return temporary variable
750 */
751 public GpxImageEntry getTmp() {
752 if (tmp == null) {
753 createTmp();
754 }
755 return tmp;
756 }
757
758 /**
759 * Copy the values from the temporary variable to the main instance. The
760 * temporary variable is deleted.
761 * @see #discardTmp()
762 * @since 19387 exifGpsTrack, exifHPosErr, gpsDiffMode, gps2d3dMode, exifGpsDop, exifGpsDatum, exifGpsProcMethod added
763 */
764 public void applyTmp() {
765 if (tmp != null) {
766 pos = tmp.pos;
767 speed = tmp.speed;
768 elevation = tmp.elevation;
769 gpsTime = tmp.gpsTime;
770 exifImgDir = tmp.exifImgDir;
771 exifGpsTrack = tmp.exifGpsTrack;
772 exifHPosErr = tmp.exifHPosErr;
773 gpsDiffMode = tmp.gpsDiffMode;
774 gps2d3dMode = tmp.gps2d3dMode;
775 exifGpsDop = tmp.exifGpsDop;
776 exifGpsDatum = tmp.exifGpsDatum;
777 exifGpsProcMethod = tmp.exifGpsProcMethod;
778 isNewGpsData = isNewGpsData || tmp.isNewGpsData;
779 tmp = null;
780 }
781 tmpUpdated();
782 }
783
784 /**
785 * Delete the temporary variable. Temporary modifications are lost.
786 * @see #applyTmp()
787 */
788 public void discardTmp() {
789 tmp = null;
790 tmpUpdated();
791 }
792
793 /**
794 * If it has been tagged i.e. matched to a gpx track or retrieved lat/lon from exif
795 * @return {@code true} if it has been tagged
796 */
797 public boolean isTagged() {
798 return pos != null;
799 }
800
801 /**
802 * String representation. (only partial info)
803 */
804 @Override
805 public String toString() {
806 return file.getName()+": "+
807 "pos = "+pos+" | "+
808 "exifCoor = "+exifCoor+" | "+
809 (tmp == null ? " tmp==null" :
810 " [tmp] pos = "+tmp.pos);
811 }
812
813 /**
814 * Indicates that the image has new GPS data.
815 * That flag is set by new GPS data providers. It is used e.g. by the photo_geotagging plugin
816 * to decide for which image file the EXIF GPS data needs to be (re-)written.
817 * @since 6392
818 */
819 public void flagNewGpsData() {
820 isNewGpsData = true;
821 }
822
823 /**
824 * Indicate that the temporary copy has been updated. Mostly used to prevent UI issues.
825 * By default, this is a no-op. Override when needed in subclasses.
826 * @since 17579
827 */
828 protected void tmpUpdated() {
829 // No-op by default
830 }
831
832 @Override
833 public BBox getBBox() {
834 // new BBox(LatLon) is null safe.
835 // Use `getPos` instead of `getExifCoor` since the image may be correlated against a GPX track
836 return new BBox(this.getPos());
837 }
838
839 /**
840 * Remove the flag that indicates new GPS data.
841 * The flag is cleared by a new GPS data consumer.
842 */
843 public void unflagNewGpsData() {
844 isNewGpsData = false;
845 }
846
847 /**
848 * Queries whether the GPS data changed. The flag value from the temporary
849 * copy is returned if that copy exists.
850 * @return {@code true} if GPS data changed, {@code false} otherwise
851 * @since 6392
852 */
853 public boolean hasNewGpsData() {
854 if (tmp != null)
855 return tmp.isNewGpsData;
856 return isNewGpsData;
857 }
858
859 /**
860 * Extract GPS metadata from image EXIF. Has no effect if the image file is not set
861 *
862 * If successful, fills in the LatLon, speed, elevation, image direction, and other attributes
863 * @since 9270
864 */
865 @Override
866 public void extractExif() {
867 ImageMetadata.super.extractExif();
868 }
869
870 @Override
871 public InputStream getInputStream() throws IOException {
872 return Files.newInputStream(this.getFile().toPath());
873 }
874
875 /**
876 * Reads the image represented by this entry in the given target dimension.
877 * @param target the desired dimension used for {@linkplain IIOParam#setSourceSubsampling subsampling} or {@code null}
878 * @return the read image, or {@code null}
879 * @throws IOException if any I/O error occurs
880 * @since 18246
881 */
882 public BufferedImage read(Dimension target) throws IOException {
883 throw new UnsupportedOperationException("read not implemented for " + this.getClass().getSimpleName());
884 }
885
886 /**
887 * Get the projection type for this entry
888 * @return The projection type
889 * @since 18246
890 */
891 @Override
892 public Projections getProjectionType() {
893 return this.cameraProjection;
894 }
895
896 @Override
897 public void setProjectionType(Projections newProjection) {
898 this.cameraProjection = newProjection;
899 }
900
901 /**
902 * Returns a {@link WayPoint} representation of this GPX image entry.
903 * @return a {@code WayPoint} representation of this GPX image entry (containing position, instant and elevation)
904 * @since 18065
905 */
906 public WayPoint asWayPoint() {
907 CachedLatLon position = getPos();
908 WayPoint wpt = null;
909 if (position != null) {
910 wpt = new WayPoint(position);
911 wpt.setInstant(exifTime);
912 Double ele = getElevation();
913 if (ele != null) {
914 wpt.put(GpxConstants.PT_ELE, ele.toString());
915 }
916 }
917 return wpt;
918 }
919}
Note: See TracBrowser for help on using the repository browser.