using System; using System.Collections; using System.Text; using System.IO; using com.drew.metadata; using com.drew.lang; /// /// This class was first written by Drew Noakes in Java. /// /// This is public domain software - that is, you can do whatever you want /// with it, and include it software that is licensed under the GNU or the /// BSD license, or whatever other licence you choose, including proprietary /// closed source licenses. I do ask that you leave this header in tact. /// /// If you make modifications to this code that you think would benefit the /// wider community, please send me a copy and I'll post it on my site. /// /// If you make use of this code, Drew Noakes will appreciate hearing /// about it: drew@drewnoakes.com /// /// Latest Java version of this software kept at /// http://drewnoakes.com/ /// /// The C# class was made by Ferret Renaud: /// renaud91@free.fr /// If you find a bug in the C# code, feel free to mail me. /// namespace com.drew.metadata.exif { /// /// Tag descriptor for GPS /// public class GpsDescriptor : TagDescriptor { /// /// Constructor of the object /// /// a directory public GpsDescriptor(Directory directory) : base(directory) { } /// /// Returns a descriptive value of the the specified tag for this image. /// Where possible, known values will be substituted here in place of the raw tokens actually /// kept in the Exif segment. /// If no substitution is available, the value provided by GetString(int) will be returned. /// This and GetString(int) are the only 'get' methods that won't throw an exception. /// /// the tag to find a description for /// a description of the image's value for the specified tag, or null if the tag hasn't been defined. public override string GetDescription(int tagType) { switch(tagType) { case GpsDirectory.TAG_GPS_ALTITUDE : return GetGpsAltitudeDescription(); case GpsDirectory.TAG_GPS_ALTITUDE_REF : return GetGpsAltitudeRefDescription(); case GpsDirectory.TAG_GPS_STATUS : return GetGpsStatusDescription(); case GpsDirectory.TAG_GPS_MEASURE_MODE : return GetGpsMeasureModeDescription(); case GpsDirectory.TAG_GPS_SPEED_REF : return GetGpsSpeedRefDescription(); case GpsDirectory.TAG_GPS_TRACK_REF : case GpsDirectory.TAG_GPS_IMG_DIRECTION_REF : case GpsDirectory.TAG_GPS_DEST_BEARING_REF : return GetGpsDirectionReferenceDescription(tagType); case GpsDirectory.TAG_GPS_TRACK : case GpsDirectory.TAG_GPS_IMG_DIRECTION : case GpsDirectory.TAG_GPS_DEST_BEARING : return GetGpsDirectionDescription(tagType); case GpsDirectory.TAG_GPS_DEST_DISTANCE_REF : return GetGpsDestinationReferenceDescription(); case GpsDirectory.TAG_GPS_TIME_STAMP : return GetGpsTimeStampDescription(); // three rational numbers -- displayed in HH"MM"SS.ss case GpsDirectory.TAG_GPS_LONGITUDE : return GetGpsLongitudeDescription(); case GpsDirectory.TAG_GPS_LATITUDE : return GetGpsLatitudeDescription(); default : return _directory.GetString(tagType); } } /// /// Returns the Gps Latitude Description. /// /// the Gps Latitude Description. private string GetGpsLatitudeDescription() { if (!_directory.ContainsTag(GpsDirectory.TAG_GPS_LATITUDE)) return null; return GetHoursMinutesSecondsDescription(GpsDirectory.TAG_GPS_LATITUDE); } /// /// Returns the Gps Longitude Description. /// /// the Gps Longitude Description. private string GetGpsLongitudeDescription() { if (!_directory.ContainsTag(GpsDirectory.TAG_GPS_LONGITUDE)) return null; return GetHoursMinutesSecondsDescription( GpsDirectory.TAG_GPS_LONGITUDE); } /// /// Returns the Hours Minutes Seconds Description. /// /// the Hours Minutes Seconds Description. private string GetHoursMinutesSecondsDescription(int tagType) { Rational[] components = _directory.GetRationalArray(tagType); // TODO create an HoursMinutesSecods class ?? int deg = components[0].IntValue(); float min = components[1].FloatValue(); float sec = components[2].FloatValue(); // carry fractions of minutes into seconds -- thanks Colin Briton sec += (min % 1) * 60; string[] tab = new string[] {deg.ToString(), ((int) min).ToString(), sec.ToString()}; return BUNDLE["HOURS_MINUTES_SECONDS", tab]; } /// /// Returns the Gps Time Stamp Description. /// /// the Gps Time Stamp Description. private string GetGpsTimeStampDescription() { // time in hour, min, sec if (!_directory.ContainsTag(GpsDirectory.TAG_GPS_TIME_STAMP)) return null; int[] timeComponents = _directory.GetIntArray(GpsDirectory.TAG_GPS_TIME_STAMP); string[] tab = new string[] {timeComponents[0].ToString(), timeComponents[1].ToString(), timeComponents[2].ToString()}; return BUNDLE["GPS_TIME_STAMP", tab]; } /// /// Returns the Gps Destination Reference Description. /// /// the Gps Destination Reference Description. private string GetGpsDestinationReferenceDescription() { if (!_directory.ContainsTag(GpsDirectory.TAG_GPS_DEST_DISTANCE_REF)) return null; string destRef = _directory.GetString(GpsDirectory.TAG_GPS_DEST_DISTANCE_REF).Trim().ToUpper(); if ("K".Equals(destRef)) { return BUNDLE["KILOMETERS"]; } else if ("M".Equals(destRef)) { return BUNDLE["MILES"]; } else if ("N".Equals(destRef)) { return BUNDLE["KNOTS"]; } else { return BUNDLE["UNKNOWN", destRef]; } } /// /// Returns the Gps Direction Description. /// /// the Gps Direction Description. private string GetGpsDirectionDescription(int tagType) { if (!_directory.ContainsTag(tagType)) return null; string gpsDirection = _directory.GetString(tagType).Trim(); return BUNDLE["DEGREES", gpsDirection]; } /// /// Returns the Gps Direction Reference Description. /// /// the Gps Direction Reference Description. private string GetGpsDirectionReferenceDescription(int tagType) { if (!_directory.ContainsTag(tagType)) return null; string gpsDistRef = _directory.GetString(tagType).Trim().ToUpper(); if ("T".Equals(gpsDistRef)) { return BUNDLE["TRUE_DIRECTION"]; } else if ("M".Equals(gpsDistRef)) { return BUNDLE["MAGNETIC_DIRECTION"]; } else { return BUNDLE["UNKNOWN", gpsDistRef]; } } /// /// Returns the Gps Speed Ref Description. /// /// the Gps Speed Ref Description. private string GetGpsSpeedRefDescription() { if (!_directory.ContainsTag(GpsDirectory.TAG_GPS_SPEED_REF)) return null; string gpsSpeedRef = _directory.GetString(GpsDirectory.TAG_GPS_SPEED_REF).Trim().ToUpper(); if ("K".Equals(gpsSpeedRef)) { return BUNDLE["KPH"]; } else if ("M".Equals(gpsSpeedRef)) { return BUNDLE["MPH"]; } else if ("N".Equals(gpsSpeedRef)) { return BUNDLE["KNOTS"]; } else { return BUNDLE["UNKNOWN", gpsSpeedRef]; } } /// /// Returns the Gps Measure Mode Description. /// /// the Gps Measure Mode Description. private string GetGpsMeasureModeDescription() { if (!_directory.ContainsTag(GpsDirectory.TAG_GPS_MEASURE_MODE)) return null; string gpsSpeedMeasureMode = _directory.GetString(GpsDirectory.TAG_GPS_MEASURE_MODE).Trim().ToUpper(); if ("2".Equals(gpsSpeedMeasureMode) || "3".Equals(gpsSpeedMeasureMode)) { return BUNDLE["DIMENSIONAL_MEASUREMENT", gpsSpeedMeasureMode]; } else { return BUNDLE["UNKNOWN", gpsSpeedMeasureMode]; } } /// /// Returns the Gps Status Description. /// /// the Gps Status Description. private string GetGpsStatusDescription() { if (!_directory.ContainsTag(GpsDirectory.TAG_GPS_STATUS)) return null; string gpsStatus = _directory.GetString(GpsDirectory.TAG_GPS_STATUS).Trim().ToUpper(); if ("A".Equals(gpsStatus)) { return BUNDLE["MEASUREMENT_IN_PROGESS"]; } else if ("V".Equals(gpsStatus)) { return BUNDLE["MEASUREMENT_INTEROPERABILITY"]; } else { return BUNDLE["UNKNOWN", gpsStatus]; } } /// /// Returns the Gps Altitude Ref Description. /// /// the Gps Altitude Ref Description. private string GetGpsAltitudeRefDescription() { if (!_directory.ContainsTag(GpsDirectory.TAG_GPS_ALTITUDE_REF)) return null; int alititudeRef = _directory.GetInt(GpsDirectory.TAG_GPS_ALTITUDE_REF); if (alititudeRef == 0) { return BUNDLE["SEA_LEVEL"]; } else { return BUNDLE["UNKNOWN", alititudeRef.ToString()]; } } /// /// Returns the Gps Altitude Description. /// /// the Gps Altitude Description. private string GetGpsAltitudeDescription() { if (!_directory.ContainsTag(GpsDirectory.TAG_GPS_ALTITUDE)) return null; string alititude = _directory.GetRational( GpsDirectory.TAG_GPS_ALTITUDE).ToSimpleString( true); return BUNDLE["METRES", alititude]; } } }