I have Nikon DSLR and I wanted to add GPS location so when I upload them to flickr I have it on a map and don’t need to add location by hand.
If you have android phone, you don’t need any extra GPS hardware, to have GPS location on your photos taken with your camera.
The solution, if you have GPS enabled in your phone is it take location history from google map using this url: https://www.google.com/maps/timeline?pb (export option is in dropdown in gear icon at the bottom)
You will have JSON file with GSP coordinates and timestamps for all your locations from your phone.
Now to extract the GPS out of JSON file I use this small script written in Python, it use exiftool to write EXIF back to the file because PIL can only read exif not write it.
#!/usr/bin/env python from __future__ import division import simplejson as json from PIL import Image from dateutil import parser from optparse import OptionParser from subprocess import call from datetime import datetime, timedelta def get_date_taken(path): return Image.open(path)._getexif() def nearest(items, pivot): return min(items, key=lambda x: abs(x - pivot)) def comparator(date, hours_shift = None): def compare(x): current = datetime.fromtimestamp(int(x['timestampMs']) / 1000.0) if hours_shift is not None: current = current + timedelta(seconds = hours_shift * 60 * 60) return abs(current - date) return compare def get_gps(gps, date, hours_shift = None): return min(gps['locations'], key=comparator(date, hours_shift)) def parse_date(str): return datetime.strptime(str, "%Y:%m:%d %H:%M:%S") def timestamp(dt, epoch=datetime(1970,1,1)): td = dt - epoch return (td.microseconds + (td.seconds + td.days * 86400) * 10**6) / 10**6 def timezone(date, hours): return date - timedelta(seconds = hours * 60 * 60) if __name__ == '__main__': from sys import argv opt = OptionParser() opt.add_option('-l', '--location') opt.add_option('-t', '--timezone') (options, args) = opt.parse_args() if options.location is None or len(args) != 1: print "usage %s [--timezone <hours shift>] --location [History JSON File] <IMAGE FILE>" % argv else: gps_list = json.loads(open(options.location).read()) date = parse_date(get_date_taken(args)) if options.timezone is not None: loc = get_gps(gps_list, date, -float(options.timezone)) else: loc = get_gps(gps_list, date) found = datetime.fromtimestamp( int(loc['timestampMs']) / 1000.0 ) print "%s == %s" % (date, found) call([ 'exiftool', '-m', '-GPSLatitude=%s' % str(int(loc['latitudeE7']) / 1e7), '-GPSLongitude=%s' % str(int(loc['longitudeE7']) / 1e7), args ])
To use it you need to use terminal and execute
gps.py --tomezone <hours shift> --location <Path to JSON> <Image File>
The only one issue I’ve found is that PIL can’t extract exif from RAW/NEF files, so you can only use JPEG but you can write exif to RAW/NEF but read create time out of JPG file, if you shot in both JPG and RAW like I do.
EDIT: I was on a trip to Cracow in March of 2019, I was walking from my hotel to train station taking pictures and when I was, at home GPS was connected without timezone so maybe the shift only came from Day Light saving. (I was in Tuscany in April 2018 the shift was 1 which would be about right because in April there is summer time in Poland).