diff --git a/src/tags_int.cpp b/src/tags_int.cpp index 923dc2b4ef..1921c2873c 100644 --- a/src/tags_int.cpp +++ b/src/tags_int.cpp @@ -2117,14 +2117,14 @@ namespace Exiv2 { //! GPS status, tag 0x0009 extern const TagDetails exifGPSStatus[] = { - { 'A', N_("Measurement in progress") }, - { 'V', N_("Measurement Interoperability") } + { 'A', N_("Measurement in progress") }, + { 'V', N_("Measurement interrupted") } }; //! GPS measurement mode, tag 0x000a extern const TagDetails exifGPSMeasureMode[] = { - { '2', N_("Two-dimensional measurement") }, - { '3', N_("Three-dimensional measurement") } + { '2', N_("2-dimensional measurement") }, + { '3', N_("3-dimensional measurement") } }; //! GPS speed reference, tag 0x000c @@ -2134,20 +2134,20 @@ namespace Exiv2 { { 'N', N_("knots") } }; - //! GPS direction ref, tags 0x000e, 0x0010, 0x0017 + //! GPS direction reference, tags 0x000e, 0x0010, 0x0017 extern const TagDetails exifGPSDirRef[] = { { 'T', N_("True direction") }, { 'M', N_("Magnetic direction") } }; - //! GPS Destination distance ref, tag 0x0019 + //! GPS destination distance reference, tag 0x0019 extern const TagDetails exifGPSDestDistanceRef[] = { - { 'K', N_("Kilometers") }, - { 'M', N_("Miles") }, - { 'N', N_("Knots") } + { 'K', N_("km") }, + { 'M', N_("miles") }, + { 'N', N_("nautical miles") } }; - //! GPS Differential, tag 0x001e + //! GPS differential correction, tag 0x001e extern const TagDetails exifGPSDifferential[] = { { 0, N_("Without correction") }, { 1, N_("Correction applied") } @@ -2222,14 +2222,14 @@ namespace Exiv2 { TagInfo(0x000b, "GPSDOP", N_("GPS Data Degree of Precision"), N_("Indicates the GPS DOP (data degree of precision). An HDOP value is written " "during two-dimensional measurement, and PDOP during three-dimensional measurement."), - gpsId, gpsTags, unsignedRational, 1, printValue), + gpsId, gpsTags, unsignedRational, 1, printFloat), TagInfo(0x000c, "GPSSpeedRef", N_("GPS Speed Reference"), N_("Indicates the unit used to express the GPS receiver speed of movement. " "\"K\" \"M\" and \"N\" represents kilometers per hour, miles per hour, and knots."), gpsId, gpsTags, asciiString, 2, print0x000c), TagInfo(0x000d, "GPSSpeed", N_("GPS Speed"), N_("Indicates the speed of GPS receiver movement."), - gpsId, gpsTags, unsignedRational, 1, printValue), + gpsId, gpsTags, unsignedRational, 1, printFloat), TagInfo(0x000e, "GPSTrackRef", N_("GPS Track Ref"), N_("Indicates the reference for giving the direction of GPS receiver movement. " "\"T\" denotes true direction and \"M\" is magnetic direction."), @@ -2237,7 +2237,7 @@ namespace Exiv2 { TagInfo(0x000f, "GPSTrack", N_("GPS Track"), N_("Indicates the direction of GPS receiver movement. The range of values is " "from 0.00 to 359.99."), - gpsId, gpsTags, unsignedRational, 1, printValue), + gpsId, gpsTags, unsignedRational, 1, printFloat), TagInfo(0x0010, "GPSImgDirectionRef", N_("GPS Image Direction Reference"), N_("Indicates the reference for giving the direction of the image when it is captured. " "\"T\" denotes true direction and \"M\" is magnetic direction."), @@ -2245,7 +2245,7 @@ namespace Exiv2 { TagInfo(0x0011, "GPSImgDirection", N_("GPS Image Direction"), N_("Indicates the direction of the image when it was captured. The range of values " "is from 0.00 to 359.99."), - gpsId, gpsTags, unsignedRational, 1, printValue), + gpsId, gpsTags, unsignedRational, 1, printFloat), TagInfo(0x0012, "GPSMapDatum", N_("GPS Map Datum"), N_("Indicates the geodetic survey data used by the GPS receiver. If the survey data " "is restricted to Japan, the value of this tag is \"TOKYO\" or \"WGS-84\"."), @@ -2280,14 +2280,14 @@ namespace Exiv2 { TagInfo(0x0018, "GPSDestBearing", N_("GPS Destination Bearing"), N_("Indicates the bearing to the destination point. The range of values is from " "0.00 to 359.99."), - gpsId, gpsTags, unsignedRational, 1, printValue), + gpsId, gpsTags, unsignedRational, 1, printFloat), TagInfo(0x0019, "GPSDestDistanceRef", N_("GPS Destination Distance Reference"), N_("Indicates the unit used to express the distance to the destination point. " - "\"K\", \"M\" and \"N\" represent kilometers, miles and knots."), + "\"K\", \"M\" and \"N\" represent kilometers, miles and nautical miles."), gpsId, gpsTags, asciiString, 2, print0x0019), TagInfo(0x001a, "GPSDestDistance", N_("GPS Destination Distance"), N_("Indicates the distance to the destination point."), - gpsId, gpsTags, unsignedRational, 1, printValue), + gpsId, gpsTags, unsignedRational, 1, printFloat), TagInfo(0x001b, "GPSProcessingMethod", N_("GPS Processing Method"), N_("A character string recording the name of the method used for location finding. " "The string encoding is defined using the same scheme as UserComment."), @@ -2305,7 +2305,7 @@ namespace Exiv2 { gpsId, gpsTags, unsignedShort, 1, print0x001e), TagInfo(0x001f, "GPSHPositioningError", N_("GPS Horizontal positioning error"), N_("This tag indicates horizontal positioning errors in meters."), - gpsId, gpsTags, unsignedRational, 1, printValue), + gpsId, gpsTags, unsignedRational, 1, printFloat), // End of list marker TagInfo(0xffff, "(UnknownGpsTag)", N_("Unknown GPSInfo tag"), N_("Unknown GPSInfo tag"), @@ -2625,14 +2625,33 @@ namespace Exiv2 { { std::ios::fmtflags f( os.flags() ); if (value.count() == 3) { - static const char* unit[] = { "deg", "'", "\"" }; - for (int i = 0; i < value.count() ; ++i) { - const int v = (int) (value.toFloat(i)+0.5f); // nearest integer - os << (i != 0? " " : "") << v << unit[i]; + Rational deg = value.toRational(0); + Rational min = value.toRational(1); + Rational sec = value.toRational(2); + if ((deg.second != 1) || (min.second == 0) || (sec.second == 0)) { + return os << "(" << value << ")"; } + const int32_t dd = deg.first; + const int32_t mm = min.first / min.second; + const int32_t rem = min.first % min.second; + if ((min.second > 1) && (rem > 0)) { + if ((sec.first == 0) && (sec.second == 1)) { + sec.first = 60 * rem; + sec.second = min.second; + } else { + return os << "(" << value << ")"; + } + } + const float ss = (float)sec.first / sec.second; + os << dd << " deg "; + os << mm << "' "; + std::ostringstream oss; + oss.copyfmt(os); + os << std::fixed << std::setprecision(sec.second > 1 ? 2 : 0) << ss << "\""; + os.copyfmt(oss); } else { - os << value; + os << "(" << value << ")"; } os.flags(f); return os; diff --git a/test/data/geotag-test.out b/test/data/geotag-test.out index 081f25824e..677bf33818 100644 --- a/test/data/geotag-test.out +++ b/test/data/geotag-test.out @@ -1,9 +1,9 @@ --- show GPSInfo tags --- Exif.GPSInfo.GPSVersionID Byte 4 2.2.0.0 Exif.GPSInfo.GPSLatitudeRef Ascii 2 North -Exif.GPSInfo.GPSLatitude Rational 3 36deg 26' 54" +Exif.GPSInfo.GPSLatitude Rational 3 36 deg 26' 54" Exif.GPSInfo.GPSLongitudeRef Ascii 2 West -Exif.GPSInfo.GPSLongitude Rational 3 116deg 51' 18" +Exif.GPSInfo.GPSLongitude Rational 3 116 deg 51' 18" Exif.GPSInfo.GPSAltitudeRef Byte 1 Below sea level Exif.GPSInfo.GPSAltitude Rational 1 14.3 m Exif.GPSInfo.GPSTimeStamp Rational 3 09:54:28 @@ -16,9 +16,9 @@ Exif.GPSInfo.GPSDateStamp Ascii 20 2008:05:08 09:54:28 --- show GPSInfo tags --- Exif.GPSInfo.GPSVersionID Byte 4 2.2.0.0 Exif.GPSInfo.GPSLatitudeRef Ascii 2 North -Exif.GPSInfo.GPSLatitude Rational 3 36deg 26' 54" +Exif.GPSInfo.GPSLatitude Rational 3 36 deg 26' 54" Exif.GPSInfo.GPSLongitudeRef Ascii 2 West -Exif.GPSInfo.GPSLongitude Rational 3 116deg 51' 18" +Exif.GPSInfo.GPSLongitude Rational 3 116 deg 51' 18" Exif.GPSInfo.GPSAltitudeRef Byte 1 Below sea level Exif.GPSInfo.GPSAltitude Rational 1 14.3 m Exif.GPSInfo.GPSTimeStamp Rational 3 09:54:28 diff --git a/tests/bugfixes/github/test_issue_1046.py b/tests/bugfixes/github/test_issue_1046.py index 347a437546..f1a2509ae3 100644 --- a/tests/bugfixes/github/test_issue_1046.py +++ b/tests/bugfixes/github/test_issue_1046.py @@ -26,9 +26,9 @@ class test_issue_1046Test(metaclass=CaseMeta): stdout = ["""Exif.Photo.UserComment Undefined 12 charset=Unicode AB Exif.GPSInfo.GPSVersionID Byte 4 2.2.0.0 Exif.GPSInfo.GPSLatitudeRef Ascii 2 North -Exif.GPSInfo.GPSLatitude Rational 3 51deg 23' 13" +Exif.GPSInfo.GPSLatitude Rational 3 51 deg 23' 13" Exif.GPSInfo.GPSLongitudeRef Ascii 2 West -Exif.GPSInfo.GPSLongitude Rational 3 0deg 44' 27" +Exif.GPSInfo.GPSLongitude Rational 3 0 deg 44' 27" Exif.GPSInfo.GPSAltitudeRef Byte 1 Above sea level Exif.GPSInfo.GPSAltitude Rational 1 104.2 m Exif.GPSInfo.GPSTimeStamp Rational 3 10:34:11 diff --git a/tests/bugfixes/redmine/test_issue_1024.py b/tests/bugfixes/redmine/test_issue_1024.py index d98d530d61..8a3a3ac4ea 100644 --- a/tests/bugfixes/redmine/test_issue_1024.py +++ b/tests/bugfixes/redmine/test_issue_1024.py @@ -10,9 +10,9 @@ class CheckRegularExpressionSupport(metaclass=system_tests.CaseMeta): commands = [ "$exiv2 -pa --grep gpsl/i $filename" ] stdout = [ """Exif.GPSInfo.GPSLatitudeRef Ascii 2 North -Exif.GPSInfo.GPSLatitude Rational 3 52deg 4' 0" +Exif.GPSInfo.GPSLatitude Rational 3 52 deg 3' 49.02" Exif.GPSInfo.GPSLongitudeRef Ascii 2 East -Exif.GPSInfo.GPSLongitude Rational 3 1deg 14' 0" +Exif.GPSInfo.GPSLongitude Rational 3 1 deg 13' 49.16" """ ] stderr = [""] diff --git a/tests/bugfixes/redmine/test_issue_1137.py b/tests/bugfixes/redmine/test_issue_1137.py index 8cdecf71a0..d6d0293eb9 100644 --- a/tests/bugfixes/redmine/test_issue_1137.py +++ b/tests/bugfixes/redmine/test_issue_1137.py @@ -36,8 +36,8 @@ class MetadataPiping(metaclass=system_tests.CaseMeta): output_grep_GPSL, "", """Exif.GPSInfo.GPSLatitudeRef Ascii 2 North -Exif.GPSInfo.GPSLatitude Rational 3 51deg 11' 0" +Exif.GPSInfo.GPSLatitude Rational 3 51 deg 10' 41.81" Exif.GPSInfo.GPSLongitudeRef Ascii 2 West -Exif.GPSInfo.GPSLongitude Rational 3 1deg 50' 0" +Exif.GPSInfo.GPSLongitude Rational 3 1 deg 49' 35.90" """ ] diff --git a/tests/bugfixes/redmine/test_issue_528.py b/tests/bugfixes/redmine/test_issue_528.py index b7ce0e8a2c..635fa9d383 100644 --- a/tests/bugfixes/redmine/test_issue_528.py +++ b/tests/bugfixes/redmine/test_issue_528.py @@ -69,9 +69,9 @@ class TypeSizeForExifOnly(metaclass=system_tests.CaseMeta): Exif.Image.GPSTag Long 1 870 Exif.GPSInfo.GPSVersionID Byte 4 2.0.0.0 Exif.GPSInfo.GPSLatitudeRef Ascii 2 North -Exif.GPSInfo.GPSLatitude Rational 3 47deg 36' 58" +Exif.GPSInfo.GPSLatitude Rational 3 47 deg 36' 58.02" Exif.GPSInfo.GPSLongitudeRef Ascii 2 East -Exif.GPSInfo.GPSLongitude Rational 3 1deg 31' 1" +Exif.GPSInfo.GPSLongitude Rational 3 1 deg 31' 0.94" Exif.GPSInfo.GPSAltitudeRef Byte 1 Above sea level Exif.GPSInfo.GPSAltitude Rational 1 86 m Exif.Thumbnail.Compression Short 1 JPEG (old-style)