001// License: GPL. For details, see LICENSE file. 002package org.openstreetmap.josm.plugins.streetside; 003 004import java.awt.image.BufferedImage; 005import java.io.File; 006import java.io.IOException; 007import java.text.ParseException; 008import java.util.Calendar; 009 010import javax.imageio.ImageIO; 011 012import org.openstreetmap.josm.data.coor.CachedLatLon; 013import org.openstreetmap.josm.data.coor.LatLon; 014import org.openstreetmap.josm.gui.MapView; 015import org.openstreetmap.josm.gui.layer.geoimage.GeoImageLayer; 016import org.openstreetmap.josm.gui.layer.geoimage.ImageEntry; 017import org.openstreetmap.josm.plugins.streetside.utils.StreetsideUtils; 018 019import org.openstreetmap.josm.plugins.streetside.cubemap.CubemapUtils; 020 021/** 022 * A StreetsideImoprtedImage object represents a picture imported locally. 023 * 024 * @author nokutu 025 * 026 */ 027public class StreetsideImportedImage extends StreetsideAbstractImage { 028 029 /** The picture file. */ 030 protected File file; 031 032 /** 033 * Creates a new StreetsideImportedImage object using as date the current date. 034 * Using when the EXIF tags doesn't contain that info. 035 * 036 * @param id The Streetside image id 037 * @param latLon The latitude and longitude where the picture was taken. 038 * @param ca Direction of the picture (0 means north). 039 * @param file The file containing the picture. 040 */ 041 public StreetsideImportedImage(final String id, final LatLon latLon, final double ca, final File file) { 042 this(id, latLon, ca, file, Calendar.getInstance().getTimeInMillis()); 043 } 044 045 /** 046 * Main constructor of the class. 047 * 048 * @param id The Streetside image id 049 * @param latLon Latitude and Longitude where the picture was taken. 050 * @param ca Direction of the picture (0 means north), 051 * @param file The file containing the picture. 052 * @param datetimeOriginal The date the picture was taken. 053 */ 054 public StreetsideImportedImage(final String id, final LatLon latLon, final double ca, final File file, final String datetimeOriginal) { 055 this(id, latLon, ca, file, parseTimestampElseCurrentTime(datetimeOriginal)); 056 } 057 058 /** 059 * Constructs a new image from an image entry of a {@link GeoImageLayer}. 060 * @param geoImage the {@link ImageEntry}, from which the corresponding fields are taken 061 * @return new image 062 */ 063 public static StreetsideImportedImage createInstance(final ImageEntry geoImage) { 064 if (geoImage == null) { 065 return null; 066 } 067 if (geoImage.getFile() == null) { 068 throw new IllegalArgumentException("Can't create an imported image from an ImageEntry without associated file."); 069 } 070 final CachedLatLon cachedCoord = geoImage.getPos(); 071 LatLon coord = cachedCoord == null ? null : cachedCoord.getRoundedToOsmPrecision(); 072 if (coord == null) { 073 final MapView mv = StreetsidePlugin.getMapView(); 074 coord = mv == null ? new LatLon(0, 0) : mv.getProjection().eastNorth2latlon(mv.getCenter()); 075 } 076 final double ca = geoImage.getExifImgDir() == null ? 0 : geoImage.getExifImgDir(); 077 final long time = geoImage.hasGpsTime() 078 ? geoImage.getGpsTime().getTime() 079 : geoImage.hasExifTime() ? geoImage.getExifTime().getTime() : System.currentTimeMillis(); 080 return new StreetsideImportedImage(CubemapUtils.IMPORTED_ID, coord, ca, geoImage.getFile(), time); 081 } 082 083 private static long parseTimestampElseCurrentTime(final String timestamp) { 084 try { 085 return StreetsideUtils.getEpoch(timestamp, "yyyy:MM:dd HH:mm:ss"); 086 } catch (ParseException e) { 087 try { 088 return StreetsideUtils.getEpoch(timestamp, "yyyy/MM/dd HH:mm:ss"); 089 } catch (ParseException e1) { 090 return StreetsideUtils.currentTime(); 091 } 092 } 093 } 094 095 public StreetsideImportedImage(final String id, final LatLon latLon, final double he, final File file, final long ca) { 096 super(id, latLon, he); 097 this.file = file; 098 this.cd = ca; 099 } 100 101 /** 102 * Returns the pictures of the file. 103 * 104 * @return A {@link BufferedImage} object containing the picture, or null if 105 * the {@link File} given in the constructor was null. 106 * @throws IOException 107 * If the file parameter of the object isn't an image. 108 */ 109 public BufferedImage getImage() throws IOException { 110 if (file != null) 111 return ImageIO.read(file); 112 return null; 113 } 114 115 /** 116 * Returns the {@link File} object where the picture is located. 117 * 118 * @return The {@link File} object where the picture is located. 119 */ 120 public File getFile() { 121 return file; 122 } 123 124 @Override 125 public int compareTo(StreetsideAbstractImage image) { 126 if (image instanceof StreetsideImportedImage) 127 return file.compareTo(((StreetsideImportedImage) image).getFile()); 128 return hashCode() - image.hashCode(); 129 } 130 131 @Override 132 public int hashCode() { 133 final int prime = 31; 134 int result = 1; 135 result = prime * result + ((file == null) ? 0 : file.hashCode()); 136 return result; 137 } 138 139 @Override 140 public boolean equals(Object obj) { 141 if (this == obj) { 142 return true; 143 } 144 if (obj == null) { 145 return false; 146 } 147 if (!(obj instanceof StreetsideImportedImage)) { 148 return false; 149 } 150 StreetsideImportedImage other = (StreetsideImportedImage) obj; 151 if (file == null) { 152 if (other.file != null) { 153 return false; 154 } 155 } else if (!file.equals(other.file)) { 156 return false; 157 } 158 return true; 159 } 160}