import argparse from pathlib import Path import gpxpy import piexif import pytz from PIL import Image from lib.geotags import generate_geotags from lib.gpx import get_closest_point from lib.image import get_image_timestamp from lib.time import get_local_timezone def main(args): with open(args.gpx, 'r') as gpxfile: gpx = gpxpy.parse(gpxfile) for file in args.photos.glob('*'): if file.name.lower().endswith(('.jpg', '.jpeg')): img = Image.open(file) timestamp = get_image_timestamp(img, args.timezone) del img if not timestamp: print(f'FAIL - "{file.name}" does not have a timestamp.') continue point = get_closest_point(gpx, timestamp, args.max_diff) if not point: point_forced = get_closest_point(gpx, timestamp, 99999999999999999999999999) print(f'FAIL - Could not match image "{file.name}" @ {timestamp}. Closest point: {point_forced.latitude},{point_forced.longitude} @ {point_forced.time.astimezone(pytz.timezone(args.timezone))}') continue else: original_exif = piexif.load(str(file)) geotags = generate_geotags(point.latitude, point.longitude, point.elevation, point.time, original_exif) exif_bytes = piexif.dump(geotags) piexif.insert(exif_bytes, str(file)) print('OKAY - ', file.name) if __name__ == "__main__": parser = argparse.ArgumentParser(description='Add location tags to photos based on a GPX track.') parser.add_argument('photos', help='Path to the directory containing the photos') parser.add_argument('gpx', help='Path to the GPX file') parser.add_argument('--max-diff', type=int, default=300, help='Maximum allowed difference in seconds between image timestamp and track point. Default: 300') parser.add_argument('--timezone', default=get_local_timezone(), help='Three letter timezone the photos are in (e.g. EST). Default: auto-detect your local timezone') args = parser.parse_args() args.photos = Path(args.photos).expanduser().absolute().resolve() if args.photos.is_file() or not args.photos.exists(): print('Invalid path to photos. Must be a directory.') quit(1) args.gpx = Path(args.gpx).expanduser().absolute().resolve() if args.gpx.is_dir() or not args.gpx.exists(): print('Invalid path to GPX file.') quit(1) main(args)