#!/usr/bin/python3 """!@brief: helper routines for dealing with GPS Data from exif @author: Luzia Christiane Tesar @date Mi 12. Aug 13:12:33 CEST 2026 """ import os import sys import requests import json from datetime import datetime from PIL import Image from PIL.ExifTags import TAGS, GPSTAGS REV_API_URL = "https://nominatim.openstreetmap.org/reverse" headers = {"User-Agent": "Purrrrrpic :3"} def get_exif_data(image): """Returns a dictionary from the exif data of an PIL Image item. Also converts the GPS Tags""" exif_data = {} try: info = image._getexif() if info: for tag, value in info.items(): decoded = TAGS.get(tag, tag) if decoded == "GPSInfo": gps_data = {} for t in value: sub_decoded = GPSTAGS.get(t, t) gps_data[sub_decoded] = value[t] exif_data[decoded] = gps_data else: exif_data[decoded] = value except: pass return exif_data def _get_if_exist(data, key): if key in data: return data[key] return None def _convert_to_degress(value): """Helper function to convert the GPS coordinates stored in the EXIF to degress in float format""" d = float(value[0]) m = float(value[1]) s = float(value[2]) return d + (m / 60.0) + (s / 3600.0) def get_lat_lon(exif_data): """Returns the latitude and longitude, if available, from the provided exif_data (obtained through get_exif_data above)""" lat = None lon = None if "GPSInfo" in exif_data: gps_info = exif_data["GPSInfo"] gps_latitude = _get_if_exist(gps_info, "GPSLatitude") gps_latitude_ref = _get_if_exist(gps_info, "GPSLatitudeRef") gps_longitude = _get_if_exist(gps_info, "GPSLongitude") gps_longitude_ref = _get_if_exist(gps_info, "GPSLongitudeRef") if gps_latitude and gps_latitude_ref and gps_longitude and gps_longitude_ref: lat = _convert_to_degress(gps_latitude) if gps_latitude_ref != "N": lat = 0 - lat lon = _convert_to_degress(gps_longitude) if gps_longitude_ref != "E": lon = 0 - lon return lat, lon def getReverseAPI(lat, lon): try: payload = {"lat": lat, "lon": lon, "format": "json", "addressdetails": "1"} r = requests.get(REV_API_URL, headers=headers, params=payload) return r.json() except requests.exceptions.HTTPError as errh: print ("Http Error:",errh) except requests.exceptions.ConnectionError as errc: print ("Error Connecting:",errc) except requests.exceptions.Timeout as errt: print ("Timeout Error:",errt) except requests.exceptions.RequestException as err: print ("OOps: Something Else",err) def getCity(geo): return geo["address"]["city"] or "" def getCountry(geo): return geo["address"]["country"] or "" def getRoad(geo): return geo["address"]["road"] or "" def getHouseNumber(geo): return geo["address"]["house_number"] or "" def getPostCode(geo): return geo["address"]["postcode"] or "" if __name__ == "__main__": img = Image.open("eh23/IMG20260403174725.jpg") exifdata = get_exif_data(img) lat, lon = get_lat_lon(exifdata) geo = getReverseAPI(lat, lon) print(getCity(geo)) print(getCountry(geo)) print(getRoad(geo))