package de.blau.android.photos; import java.io.File; import java.io.IOException; import android.content.Context; import android.media.ExifInterface; import android.net.Uri; import android.support.v4.content.FileProvider; import android.util.Log; import de.blau.android.osm.BoundingBox; import de.blau.android.util.ExtendedExifInterface; import de.blau.android.util.rtree.BoundedObject; /** * a photo somewhere on the device or possibly on the network * exif accessing code from http://www.blog.nathanhaze.com/how-to-get-exif-tags-gps-coordinates-time-date-from-a-picture/ */ public class Photo implements BoundedObject { private static final String DEBUG_TAG = "Photo"; /** */ private final String ref; /** Latitude *1E7. */ private final int lat; /** Longitude *1E7. */ private final int lon; /** * compass direction */ private int direction = 0; private String directionRef = null; // if null direction not present /** * Create a Bug from an OSB GPX XML wpt element. * @param parser Parser up to a wpt element. * @throws IOException If there was a problem parsing the XML. * @throws NumberFormatException If there was a problem parsing the XML. */ public Photo(File d, File f) throws IOException, NumberFormatException { // ExtendedExifInterface exif = new ExtendedExifInterface(f.toString()); // create the ExifInterface file /** get the attribute. rest of the attributes are the same. i will add convertToDegree on the bottom (not required) **/ String lonStr = exif.getAttribute(ExifInterface.TAG_GPS_LONGITUDE); if (lonStr == null) { throw new IOException("No EXIF tag"); } float lonf = convertToDegree(lonStr); String lonRef = exif.getAttribute(ExifInterface.TAG_GPS_LONGITUDE_REF); if(lonRef != null && !lonRef.equals("E")) { // deal with the negative degrees lonf = -lonf; } float latf = convertToDegree(exif.getAttribute(ExifInterface.TAG_GPS_LATITUDE)); String latRef = exif.getAttribute(ExifInterface.TAG_GPS_LATITUDE_REF); if(latRef != null && !latRef.equals("N")) { latf = -latf; } lat = (int)(latf * 1E7d); lon = (int)(lonf * 1E7d); Log.d(DEBUG_TAG,"lat: " + lat + " lon: " + lon); ref = d.getAbsolutePath() + "/" + f.getName(); String dir = exif.getAttribute(ExtendedExifInterface.TAG_GPS_IMG_DIRECTION); if (dir != null) { direction =(int) Double.parseDouble(dir); directionRef = exif.getAttribute(ExtendedExifInterface.TAG_GPS_IMG_DIRECTION_REF); Log.d(DEBUG_TAG,"dir " + dir + " direction " + direction + " ref " + directionRef); } } public Photo(int lat, int lon, String ref) { this.lat = lat; this.lon = lon; this.ref = ref; } public Photo(int lat, int lon, int direction, String ref) { this.lat = lat; this.lon = lon; this.direction = direction; this.directionRef = "M"; // magnetic north // Log.d("Photo","constructor direction " + direction + " ref " + directionRef); this.ref = ref; } private Float convertToDegree(String stringDMS) throws NumberFormatException { try { Float result = null; String[] DMS = stringDMS.split(",", 3); String[] stringD = DMS[0].split("/", 2); Double D0 = Double.valueOf(stringD[0]); Double D1 = Double.valueOf(stringD[1]); Double FloatD = D0/D1; String[] stringM = DMS[1].split("/", 2); Double M0 = Double.valueOf(stringM[0]); Double M1 = Double.valueOf(stringM[1]); Double FloatM = M0/M1; String[] stringS = DMS[2].split("/", 2); Double S0 = Double.valueOf(stringS[0]); Double S1 = Double.valueOf(stringS[1]); Double FloatS = S0/S1; result = new Float(FloatD + (FloatM/60) + (FloatS/3600)); return result; } catch (Exception ex) { Log.e(DEBUG_TAG,"couldn't parse >" + stringDMS + "< exception " + ex); throw new NumberFormatException("couldn't parse: " + stringDMS); } } /** * Get the latitude of the bug. * @return The latitude *1E7. */ public int getLat() { return lat; } /** * Get the longitude of the bug. * @return The longitude *1E7. */ public int getLon() { return lon; } /** * * @param context * @return ref as content Uri */ public Uri getRef(Context context) { try { return FileProvider.getUriForFile(context, "de.blau.android.osmeditor4android.provider", new File(ref)); } catch (Exception ex) { Log.d(DEBUG_TAG,"Problem with Uri " + ex); return null; } } /** * * @return ref as String */ public String getRef() { return ref; } /** * did we have a direction attribute */ public boolean hasDirection() { return directionRef != null; } /** * get the direction value * @return */ public int getDirection() { return direction; } /** * BoundedObject interface */ @SuppressWarnings("UnnecessaryLocalVariable") public BoundingBox getBounds() { return new BoundingBox(lon,lat); } }