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 latLon The latitude and longitude where the picture was taken. 037 * @param cd Direction of the picture (0 means north). 038 * @param file The file containing the picture. 039 */ 040 public StreetsideImportedImage(final String id, final LatLon latLon, final double ca, final File file) { 041 this(id, latLon, ca, file, Calendar.getInstance().getTimeInMillis()); 042 } 043 044 /** 045 * Main constructor of the class. 046 * 047 * @param latLon Latitude and Longitude where the picture was taken. 048 * @param cd Direction of the picture (0 means north), 049 * @param file The file containing the picture. 050 * @param datetimeOriginal The date the picture was taken. 051 */ 052 public StreetsideImportedImage(final String id, final LatLon latLon, final double ca, final File file, final String datetimeOriginal) { 053 this(id, latLon, ca, file, parseTimestampElseCurrentTime(datetimeOriginal)); 054 } 055 056 /** 057 * Constructs a new image from an image entry of a {@link GeoImageLayer}. 058 * @param geoImage the {@link ImageEntry}, from which the corresponding fields are taken 059 * @return new image 060 */ 061 public static StreetsideImportedImage createInstance(final ImageEntry geoImage) { 062 if (geoImage == null) { 063 return null; 064 } 065 if (geoImage.getFile() == null) { 066 throw new IllegalArgumentException("Can't create an imported image from an ImageEntry without associated file."); 067 } 068 final CachedLatLon cachedCoord = geoImage.getPos(); 069 LatLon coord = cachedCoord == null ? null : cachedCoord.getRoundedToOsmPrecision(); 070 if (coord == null) { 071 final MapView mv = StreetsidePlugin.getMapView(); 072 coord = mv == null ? new LatLon(0, 0) : mv.getProjection().eastNorth2latlon(mv.getCenter()); 073 } 074 final double ca = geoImage.getExifImgDir() == null ? 0 : geoImage.getExifImgDir(); 075 final long time = geoImage.hasGpsTime() 076 ? geoImage.getGpsTime().getTime() 077 : geoImage.hasExifTime() ? geoImage.getExifTime().getTime() : System.currentTimeMillis(); 078 return new StreetsideImportedImage(CubemapUtils.IMPORTED_ID, coord, ca, geoImage.getFile(), time); 079 } 080 081 private static long parseTimestampElseCurrentTime(final String timestamp) { 082 try { 083 return StreetsideUtils.getEpoch(timestamp, "yyyy:MM:dd HH:mm:ss"); 084 } catch (ParseException e) { 085 try { 086 return StreetsideUtils.getEpoch(timestamp, "yyyy/MM/dd HH:mm:ss"); 087 } catch (ParseException e1) { 088 return StreetsideUtils.currentTime(); 089 } 090 } 091 } 092 093 public StreetsideImportedImage(final String id, final LatLon latLon, final double he, final File file, final long ca) { 094 super(id, latLon, he); 095 this.file = file; 096 this.cd = ca; 097 } 098 099 /** 100 * Returns the pictures of the file. 101 * 102 * @return A {@link BufferedImage} object containing the picture, or null if 103 * the {@link File} given in the constructor was null. 104 * @throws IOException 105 * If the file parameter of the object isn't an image. 106 */ 107 public BufferedImage getImage() throws IOException { 108 if (file != null) 109 return ImageIO.read(file); 110 return null; 111 } 112 113 /** 114 * Returns the {@link File} object where the picture is located. 115 * 116 * @return The {@link File} object where the picture is located. 117 */ 118 public File getFile() { 119 return file; 120 } 121 122 @Override 123 public int compareTo(StreetsideAbstractImage image) { 124 if (image instanceof StreetsideImportedImage) 125 return file.compareTo(((StreetsideImportedImage) image).getFile()); 126 return hashCode() - image.hashCode(); 127 } 128 129 @Override 130 public int hashCode() { 131 final int prime = 31; 132 int result = 1; 133 result = prime * result + ((file == null) ? 0 : file.hashCode()); 134 return result; 135 } 136 137 @Override 138 public boolean equals(Object obj) { 139 if (this == obj) { 140 return true; 141 } 142 if (obj == null) { 143 return false; 144 } 145 if (!(obj instanceof StreetsideImportedImage)) { 146 return false; 147 } 148 StreetsideImportedImage other = (StreetsideImportedImage) obj; 149 if (file == null) { 150 if (other.file != null) { 151 return false; 152 } 153 } else if (!file.equals(other.file)) { 154 return false; 155 } 156 return true; 157 } 158}