简体   繁体   中英

Convert DMS to Decimal with PIEXIF on Python?

Here is the script I am Using Python 3:

from print import print
from PIL import Image
import piexif

codec = 'ISO-8859-1'  # or latin-1

def exif_to_tag(exif_dict):
    exif_tag_dict = {}
    thumbnail = exif_dict.pop('thumbnail')
    exif_tag_dict['thumbnail'] = thumbnail.decode(codec)

    for ifd in exif_dict:
        exif_tag_dict[ifd] = {}
        for tag in exif_dict[ifd]:
            try:
                element = exif_dict[ifd][tag].decode(codec)

            except AttributeError:
                element = exif_dict[ifd][tag]

            exif_tag_dict[ifd][piexif.TAGS[ifd][tag]["name"]] = element

    return exif_tag_dict

def main():
    filename = 'subb.jpeg'  # obviously one of your own pictures
    im = Image.open(filename)

    exif_dict = piexif.load(im.info.get('exif'))
    exif_dict = exif_to_tag(exif_dict)

    pprint(exif_dict['GPS'])

if __name__ == '__main__':
   main()e here

Output is:

  {'GPSDateStamp': '2022:09:04',
     'GPSLatitude': ((43, 1), (35, 1), (28845, 1277)),
     'GPSLatitudeRef': 'N',
     'GPSLongitude': ((13, 1), (12, 1), (30645, 1024)),
     'GPSLongitudeRef': 'E'}

Well, the problem is, i dont know how to translate the Output to decimal. So, how to translate it from dms to decimal? Thank you.

The formula to convert DMS to DD is described by ESRI as:

Decimal Degrees = Degrees + ((Minutes / 60) + (Seconds / 3600))

Also note that depending on orientation, you might need to make your numbers negative:

Degrees Minutes Seconds is often followed by the hemisphere labels of N, S, E, or W. When converting to decimal degrees, convert longitude values that are in the western hemisphere or latitude values that are in the southern hemisphere to negative decimal degree values.

But before that, GPSLatitude and GPSLongitude are stored as 3 tuples of rational numbers, each of which are in the format of (numerator, denominator) , so you have to do some division to get the values.

Using your image's EXIF GPS metadata, here's code that can calculate DMS.

def dms_to_dd(gps_exif):
     # convert the rational tuples by dividing each (numerator, denominator) pair
     lat = [n/d for n, d in gps_exif['GPSLatitude']]
     lon = [n/d for n, d in gps_exif['GPSLongitude']]

     # now you have lat and lon, which are lists of [degrees, minutes, seconds]
     # from the formula above
     dd_lat = lat[0] + lat[1]/60 + lat[2]/3600
     dd_lon = lon[0] + lon[1]/60 + lon[2]/3600

     # if latitude ref is 'S', make latitude negative
     if gps_exif['GPSLatitudeRef'] == 'S':
        dd_lat = -dd_lat
     
     # if longitude ref is 'W', make longitude negative
     if gps_exif['GPSLongitudeRef'] == 'W':
        dd_lon = -dd_lon

     return (dd_lat, dd_lon)

     
if __name__ == '__main__':
    coords = { 
        'GPSDateStamp': '2022:09:04',
        'GPSLatitude': ((43, 1), (35, 1), (28845, 1277)),
        'GPSLatitudeRef': 'N',
        'GPSLongitude': ((13, 1), (12, 1), (30645, 1024)),
        'GPSLongitudeRef': 'E'
    }
    print(dms_to_dd(coords))

And your sample EXIF coordinates return:

(43.58960780475072, 13.20831298828125)

Which, if my math is correct, is somewhere in Italy.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM