Skip to content

Commit

Permalink
Modify get_gps_coords util to handle tags in native Python
Browse files Browse the repository at this point in the history
  • Loading branch information
EtiennePelletier committed Nov 5, 2020
1 parent 4ae0439 commit 039f7ad
Showing 1 changed file with 40 additions and 24 deletions.
64 changes: 40 additions & 24 deletions exifread/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
"""

from fractions import Fraction
from typing import Tuple, Union


def ord_(dta):
Expand Down Expand Up @@ -41,32 +42,47 @@ def make_string_uc(seq) -> str:
return make_string(seq)


def get_gps_coords(tags: dict) -> tuple:

lng_ref_tag_name = 'GPS GPSLongitudeRef'
lng_tag_name = 'GPS GPSLongitude'
lat_ref_tag_name = 'GPS GPSLatitudeRef'
lat_tag_name = 'GPS GPSLatitude'

# Check if these tags are present
gps_tags = [lng_ref_tag_name, lng_tag_name, lat_tag_name, lat_tag_name]
for tag in gps_tags:
if not tag in tags.keys():
return ()

lng_ref_val = tags[lng_ref_tag_name].values
lng_coord_val = [c.decimal() for c in tags[lng_tag_name].values]

lat_ref_val = tags[lat_ref_tag_name].values
lat_coord_val = [c.decimal() for c in tags[lat_tag_name].values]

lng_coord = sum([c/60**i for i, c in enumerate(lng_coord_val)])
lng_coord *= (-1) ** (lng_ref_val == 'W')
def degrees_to_decimal(degrees: float, minutes: float, seconds: float) -> float:
"""
Converts coordinates from a degrees minutes seconds format to a decimal degrees format.
Reference: https://en.wikipedia.org/wiki/Geographic_coordinate_conversion
"""
return degrees + minutes/60 + seconds/3600

lat_coord = sum([c/60**i for i, c in enumerate(lat_coord_val)])
lat_coord *= (-1) ** (lat_ref_val == 'S')

return (lat_coord, lng_coord)
def get_gps_coords(tags: dict) -> Union[Tuple[float, float], None]:
"""
Extract tuple of latitude and longitude values in decimal degrees format from EXIF tags.
Return None if no GPS coordinates are found.
Handles regular and serialized Exif tags.
"""
gps = {
'lat_coord': 'GPS GPSLatitude',
'lat_ref': 'GPS GPSLatitudeRef',
'lng_coord': 'GPS GPSLongitude',
'lng_ref': 'GPS GPSLongitudeRef'
}

# Verify if required keys are a subset of provided tags
if not set(gps.values()) <= tags.keys():
return None

# If tags have not been converted to native Python types, do it
if not isinstance(tags[gps['lat_coord']], list):
tags[gps['lat_coord']] = [c.decimal() for c in tags[gps['lat_coord']].values]
tags[gps['lng_coord']] = [c.decimal() for c in tags[gps['lng_coord']].values]
tags[gps['lat_ref']] = tags[gps['lat_ref']].values
tags[gps['lng_ref']] = tags[gps['lng_ref']].values

lat = degrees_to_decimal(*tags[gps['lat_coord']])
if tags[gps['lat_ref']] == 'S':
lat *= -1

lng = degrees_to_decimal(*tags[gps['lng_coord']])
if tags[gps['lng_ref']] == 'W':
lng *= -1

return lat, lng


class Ratio(Fraction):
Expand Down

0 comments on commit 039f7ad

Please sign in to comment.