From 55362b60e0294f67a783102a2dccd7f8874ab7c3 Mon Sep 17 00:00:00 2001 From: Daniel Friesel Date: Fri, 14 May 2021 15:43:25 +0200 Subject: add reverse geocoding support via nominatim --- bin/pyggle | 72 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 66 insertions(+), 6 deletions(-) diff --git a/bin/pyggle b/bin/pyggle index 781863e..7d19b37 100755 --- a/bin/pyggle +++ b/bin/pyggle @@ -15,6 +15,9 @@ from progress.bar import Bar import shutil import sys +geocoder = None +location_cache = dict() + class ProgressBar(Bar): suffix = "%(percent).0f%% [%(elapsed_td)s/%(eta_td)s]" @@ -42,6 +45,56 @@ def format_f(value, precision=1): return f"{value:.{precision}f}" +def format_gps(exif_tag): + try: + lat = exif_tag["GPS GPSLatitude"] + latref = exif_tag["GPS GPSLatitudeRef"].values[0] + lon = exif_tag["GPS GPSLongitude"] + lonref = exif_tag["GPS GPSLongitudeRef"].values[0] + except KeyError: + return None + + try: + lat = ( + float(lat.values[0]) + + float(lat.values[1]) / 60 + + float(lat.values[2]) / 3600 + ) + lon = ( + float(lon.values[0]) + + float(lon.values[1]) / 60 + + float(lon.values[2]) / 3600 + ) + except (IndexError, ZeroDivisionError): + return None + + if latref == "S": + lat = -lat + + if lonref == "W": + lon = -lon + + global location_cache + global geocoder + + latlon = f"{lat:.3f}/{lon:.3f}" + + if latlon in location_cache: + return f"""{location_cache[latlon]}""" + + if geocoder is None: + from geopy.geocoders import Nominatim + + geocoder = Nominatim(user_agent="pyggle +https://github.com/derf/pyggle") + + # zoom level: 15 -> district, 16/17 -> street, 18 -> house no + res = geocoder.reverse((lat, lon), zoom=15) + location = res.address.split(",")[0] + location_cache[latlon] = location + + return f"""{location}""" + + def format_fsi(exif_tag): entries = list() @@ -113,24 +166,30 @@ def format_make_model_lens(exif_tag): def format_exif(exif_tag): exif_lines = list() + date_and_loc = "" + try: dt = datetime.strptime( exif_tag["EXIF DateTimeOriginal"].values, "%Y:%m:%d %H:%M:%S" ) - exif_lines.append( - dt.strftime("""%d.%m.%Y %H:%M""") - ) + date_and_loc += dt.strftime("%d.%m.%Y %H:%M") except (KeyError, ValueError): try: dt = datetime.strptime( exif_tag["Image DateTimeOriginal"].values, "%Y:%m:%d %H:%M:%S" ) - exif_lines.append( - dt.strftime("""%d.%m.%Y %H:%M""") - ) + date_and_loc += dt.strftime("%d.%m.%Y %H:%M") except (KeyError, ValueError): pass + if args.with_nominatim: + gps_line = format_gps(exif_tag) + if gps_line is not None: + date_and_loc = f"{date_and_loc} in {gps_line}" + + if len(date_and_loc): + exif_lines.append(f"""{date_and_loc}""") + exif_lines.append(format_make_model_lens(exif_tag)) exif_lines.append(format_fsi(exif_tag)) @@ -197,6 +256,7 @@ if __name__ == "__main__": "--spacing", type=float, default=1.1, help="Thumbnail spacing ratio" ) parser.add_argument("--title", type=str, help="HTML title", default="") + parser.add_argument("--with-nominatim", action="store_true") parser.add_argument("images", type=str, nargs="+") args = parser.parse_args() -- cgit v1.2.3