001    // License: GPL. See LICENSE file for details.
002    // Copyright 2007 by Christian Gallioz (aka khris78)
003    // Parts of code from Geotagged plugin (by Rob Neild)
004    // and the core JOSM source code (by Immanuel Scholz and others)
005    
006    package org.openstreetmap.josm.gui.layer.geoimage;
007    
008    import java.awt.Image;
009    import java.io.File;
010    import java.util.Date;
011    
012    import org.openstreetmap.josm.data.coor.CachedLatLon;
013    import org.openstreetmap.josm.data.coor.LatLon;
014    
015    /*
016     * Stores info about each image
017     */
018    
019    final public class ImageEntry implements Comparable<ImageEntry>, Cloneable {
020        private File file;
021        private Integer exifOrientation;
022        private LatLon exifCoor;
023        private Double exifImgDir;
024        private Date exifTime;
025        Image thumbnail;
026    
027        /** The following values are computed from the correlation with the gpx track */
028        private CachedLatLon pos;
029        /** Speed in kilometer per second */
030        private Double speed;
031        /** Elevation (altitude) in meters */
032        private Double elevation;
033        /** The time after correlation with a gpx track */
034        private Date gpsTime;
035    
036        /**
037         * When the corralation dialog is open, we like to show the image position
038         * for the current time offset on the map in real time.
039         * On the other hand, when the user aborts this operation, the old values
040         * should be restored. We have a temprary copy, that overrides
041         * the normal values if it is not null. (This may be not the most elegant
042         * solution for this, but it works.)
043         */
044        ImageEntry tmp;
045    
046        /**
047         * getter methods that refer to the temporary value
048         */
049        public CachedLatLon getPos() {
050            if (tmp != null)
051                return tmp.pos;
052            return pos;
053        }
054        public Double getSpeed() {
055            if (tmp != null)
056                return tmp.speed;
057            return speed;
058        }
059        public Double getElevation() {
060            if (tmp != null)
061                return tmp.elevation;
062            return elevation;
063        }
064        public Date getGpsTime() {
065            if (tmp != null)
066                return tmp.gpsTime;
067            return gpsTime;
068        }
069    
070        /**
071         * other getter methods
072         */
073        public File getFile() {
074            return file;
075        }
076        public Integer getExifOrientation() {
077            return exifOrientation;
078        }
079        public Date getExifTime() {
080            return exifTime;
081        }
082        public LatLon getExifCoor() {
083            return exifCoor;
084        }
085        public Double getExifImgDir() {
086            return exifImgDir;
087        }
088    
089        public boolean hasThumbnail() {
090            return thumbnail != null;
091        }
092    
093        /**
094         * setter methods
095         */
096        public void setPos(CachedLatLon pos) {
097            this.pos = pos;
098        }
099        public void setPos(LatLon pos) {
100            this.pos = new CachedLatLon(pos);
101        }
102        public void setSpeed(Double speed) {
103            this.speed = speed;
104        }
105        public void setElevation(Double elevation) {
106            this.elevation = elevation;
107        }
108        public void setFile(File file) {
109            this.file = file;
110        }
111        public void setExifOrientation(Integer exifOrientation) {
112            this.exifOrientation = exifOrientation;
113        }
114        public void setExifTime(Date exifTime) {
115            this.exifTime = exifTime;
116        }
117        public void setGpsTime(Date gpsTime) {
118            this.gpsTime = gpsTime;
119        }
120        public void setExifCoor(LatLon exifCoor) {
121            this.exifCoor = exifCoor;
122        }
123        public void setExifImgDir(double exifDir) {
124            this.exifImgDir = exifDir;
125        }
126    
127        @Override
128        public ImageEntry clone() {
129            Object c;
130            try {
131                c = super.clone();
132            } catch (CloneNotSupportedException e) {
133                throw new RuntimeException();
134            }
135            return (ImageEntry) c;
136        }
137    
138        public int compareTo(ImageEntry image) {
139            if (exifTime != null && image.exifTime != null)
140                return exifTime.compareTo(image.exifTime);
141            else if (exifTime == null && image.exifTime == null)
142                return 0;
143            else if (exifTime == null)
144                return -1;
145            else
146                return 1;
147        }
148    
149        /**
150         * Make a fresh copy and save it in the temporary variable.
151         */
152        public void cleanTmp() {
153            tmp = clone();
154            tmp.setPos(null);
155            tmp.tmp = null;
156        }
157    
158        /**
159         * Copy the values from the temporary variable to the main instance.
160         */
161        public void applyTmp() {
162            if (tmp != null) {
163                pos = tmp.pos;
164                speed = tmp.speed;
165                elevation = tmp.elevation;
166                gpsTime = tmp.gpsTime;
167                tmp = null;
168            }
169        }
170    
171        /**
172         * If it has been tagged i.e. matched to a gpx track or retrieved lat/lon from exif
173         */
174        public boolean isTagged() {
175            return pos != null;
176        }
177    
178        /**
179         * String representation. (only partial info)
180         */
181        @Override
182        public String toString() {
183            String result = file.getName()+": "+
184            "pos = "+pos+" | "+
185            "exifCoor = "+exifCoor+" | "+
186            (tmp == null ? " tmp==null" :
187                " [tmp] pos = "+tmp.pos+"");
188            return result;
189        }
190    }