Skip to content

Commit f8ff4d7

Browse files
author
Rudde
committed
Adding altitude support to exif parser
1 parent d3ece94 commit f8ff4d7

File tree

5 files changed

+41
-2
lines changed

5 files changed

+41
-2
lines changed
2.56 MB
Loading
1.17 MB
Loading

MetadataExtractor.Tests/Formats/Exif/ExifDirectoryTest.cs

+22
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,28 @@ public void GeoLocation()
5252
Assert.Equal(-1.9141666666666666, geoLocation!.Longitude);
5353
}
5454

55+
[Fact]
56+
public void GeoLocationWithAltitude()
57+
{
58+
var metadata = ImageMetadataReader.ReadMetadata("Data/ABOVE_SEA_LEVEL.jpg");
59+
var gpsDirectory = metadata.OfType<GpsDirectory>().First();
60+
var geoLocation = gpsDirectory.GetGeoLocation();
61+
Assert.NotNull(geoLocation);
62+
Assert.True(geoLocation.Altitude > 1);
63+
}
64+
65+
[Fact]
66+
public void GetLocationWithAltitudeBelowSeaLevel()
67+
{
68+
var metadata = ImageMetadataReader.ReadMetadata("Data/BELOW_SEA_LEVEL.JPG");
69+
var gpsDirectory = metadata.OfType<GpsDirectory>().First();
70+
var geoLocation = gpsDirectory.GetGeoLocation();
71+
72+
Assert.NotNull(geoLocation);
73+
74+
Assert.True(geoLocation.Altitude < -1);
75+
}
76+
5577
[Fact]
5678
public void GpsDate()
5779
{

MetadataExtractor/Formats/Exif/GpsDirectory.cs

+13-1
Original file line numberDiff line numberDiff line change
@@ -163,8 +163,10 @@ public GpsDirectory() : base(_tagNameMap)
163163
{
164164
var latitudes = this.GetRationalArray(TagLatitude);
165165
var longitudes = this.GetRationalArray(TagLongitude);
166+
bool hasAltitude = this.TryGetRational(TagAltitude, out var altitude);
166167
var latitudeRef = this.GetString(TagLatitudeRef);
167168
var longitudeRef = this.GetString(TagLongitudeRef);
169+
bool hasAltitudeRef = this.TryGetByte(TagAltitudeRef, out var altitudeRef);
168170

169171
// Make sure we have the required values
170172
if (latitudes is null || latitudes.Length != 3)
@@ -183,7 +185,17 @@ public GpsDirectory() : base(_tagNameMap)
183185
if (lat == null || lon == null)
184186
return null;
185187

186-
return new GeoLocation((double)lat, (double)lon);
188+
double? alt = null;
189+
190+
if (hasAltitude)
191+
{
192+
alt = altitude.ToDouble();
193+
194+
if (hasAltitudeRef && altitudeRef == 0x01) // Invert value when ref i 1, indicates that the value is below sea level
195+
alt = -1.0 * alt;
196+
}
197+
198+
return new GeoLocation((double)lat, (double)lon, alt);
187199
}
188200

189201
/// <summary>

MetadataExtractor/GeoLocation.cs

+6-1
Original file line numberDiff line numberDiff line change
@@ -19,10 +19,12 @@ public sealed class GeoLocation
1919
/// </summary>
2020
/// <param name="latitude">the latitude, in degrees</param>
2121
/// <param name="longitude">the longitude, in degrees</param>
22-
public GeoLocation(double latitude, double longitude)
22+
/// <param name="altitude">the altitude, in meters</param>
23+
public GeoLocation(double latitude, double longitude, double? altitude)
2324
{
2425
Latitude = latitude;
2526
Longitude = longitude;
27+
Altitude = altitude;
2628
}
2729

2830
/// <value>the latitudinal angle of this location, in degrees.</value>
@@ -31,6 +33,9 @@ public GeoLocation(double latitude, double longitude)
3133
/// <value>the longitudinal angle of this location, in degrees.</value>
3234
public double Longitude { get; }
3335

36+
/// <value>the altitude of this location, in meters.</value>
37+
public double? Altitude { get; }
38+
3439
/// <value>true, if both latitude and longitude are equal to zero</value>
3540
public bool IsZero => Latitude == 0 && Longitude == 0;
3641

0 commit comments

Comments
 (0)