67°F

Aaron Parecki

  • Articles
  • Notes
  • Photos
  • Where was I when I took this photo?

    July 16, 2016

    My DSLR camera doesn't have GPS, so normally all my photos would not include the location of where I was when I took the photo. I used to use the Eye-Fi card that did geotagging, but that is no longer supported in the new "mobi" line. I could get an external GPS unit for my camera, but that sounds cumbersome and would only work with that one camera.

    Since I already track everywhere I go, I figured I could use this data to geotag my photos when I upload them to Flickr. It turns out, due to the limitations of Exif, the metadata format that digital cameras use to store information about photos, it wasn't so easy.

    Adventures in Exif

    Exif lets the camera write arbitrary text data into a jpg when it saves it. There are a handful of standard properties that most cameras write, such as the time the photo was taken, the camera settings such as shutter speed, f-stop, etc, and GPS location if the camera knows where it is. My thought was that if I know when the photo was taken, I can find out where I was at that time, and then add the GPS data to the photo.

    Unfortunately, the format for storing dates in Exif does not support specifying a timezone offset. The format for dates is YYYY:MM:DD HH:MM:SS. Without the timezone offset, this series of numbers corresponds to many different actual points in time, depending on which timezone you interpret it as. So what I need is a way to turn the camera time into a specific point in time in order to find out where I was at that time.

    A + B = C

    I realized that since I have a complete log of my GPS coordinates, I should have enough information to piece this together. Essentially the question I am asking is "where was I when my clock read 7:00pm on July 16 2016?" Note that there are two parts to the answer: my location, and the absolute point in time. It's kind of like solving an equation where there are three variables and you know two of them. The three variables are: my location, the clock time, and the timezone offset. If we knew my location and the clock time, we could find the timezone offset. If we knew the timezone offset and the clock time, then we could find my location. 

    Where was I when my clock read "7:00pm on July 16 2016"?

    If we knew what timezone I was in, then "7:00pm on July 16, 2016" becomes a single reference to an absolute point in time. But we don't know what timezone I was in yet, so there are actually 24 possible absolute points in time this could be. (I'm simplifying this problem slightly by ignoring the 30-minute offset timezones.)

    The solution is to find my location (which includes the absolute point in time) at all 24 possible points in time, find the timezone offset that corresponds to each location, then find the location where its timezone offset matches the candidate offset. Below is an example:

    Offset-less time in question: 2016-05-12 16:00:00

    This could be any of the absolute points in time:

    • 2016-05-12 16:00:00 -23:00
    • 2016-05-12 16:00:00 -22:00
    • ...
    • 2016-05-12 16:00:00 -07:00
    • 2016-05-12 16:00:00 -08:00
    • 2016-05-12 16:00:00 -06:00
    • 2016-05-12 16:00:00 -05:00
    • 2016-05-12 16:00:00 -04:00
    • 2016-05-12 16:00:00 -03:00
    • ...
    • 2016-05-12 16:00:00 +00:00
    • 2016-05-12 16:00:00 +01:00
    • 2016-05-12 16:00:00 +02:00
    • ...
    • 2016-05-12 16:00:00 +22:00
    • 2016-05-12 16:00:00 +23:00

    (I left out some of the less common timezone offsets I frequent for the sake of clarity in this example.) Now let's query my GPS database to find out what my local time actually was at each of these points in time:

    Potential Time Time from GPS Location
    2016-05-12 16:00:00 -23:00 2016-05-13 10:59:03 -04:00 New York
    2016-05-12 16:00:00 -22:00 2016-05-13 10:00:00 -04:00 New York
    ...
    2016-05-12 16:00:00 -07:00 2016-05-12 19:00:00 -04:00 New York
    2016-05-12 16:00:00 -08:00 no data
    2016-05-12 16:00:00 -06:00 2016-05-12 17:59:21 -04:00 New York
    2016-05-12 16:00:00 -05:00 2016-05-12 16:59:53 -04:00 New York
    2016-05-12 16:00:00 -04:00 2016-05-12 15:59:57 -04:00 New York
    2016-05-12 16:00:00 -03:00 2016-05-12 14:52:46 +02:00 France
    ...
    2016-05-12 16:00:00 +00:00 2016-05-12 14:52:46 +02:00 France
    2016-05-12 16:00:00 +01:00 2016-05-12 14:52:46 +02:00 France
    2016-05-12 16:00:00 +02:00 2016-05-12 14:52:46 +02:00 France
    ...
    2016-05-12 16:00:00 +22:00 2016-05-11 19:15:41 +02:00 Düsseldorf
    2016-05-12 16:00:00 +23:00 2016-05-11 18:46:26 +02:00 Düsseldorf

    (Note that the times aren't an exact match, because my GPS device doesn't log a point every second. In reality it's more like every second when I'm moving and have a good GPS lock, and when I'm not moving, it records less data. Also on plane flights I sometimes lose the GPS signal part way through the flight which is why many of the rows in this case show the same time from my GPS.)

    As you can see by comparing the potential timezone on the left with the actual timezone on the right, there are two offsets that match (highlighted in yellow), so we need to determine which is the correct one. This happens when I am traveling on a plane and cross timezones very quickly.

    If we take the two candidates and look at the actual time difference in seconds between the timestamps described, the answer becomes obvious.

    Potential Time Time from GPS Difference
    2016-05-12 16:00:00 -04:00
    unixtime: 1463083200
    2016-05-12 15:59:57 -04:00
    unixtime: 1463083197
    3
    2016-05-12 16:00:00 +02:00
    unixtime: 1463061600
    2016-05-12 14:52:46 +02:00
    unixtime: 1463057566
    4034

    From this, I can conclude that when my clock read "2016-05-12 16:00:00" it was at "2016-05-12 16:00:00 -0400" when I was in New York.

    Most of the time only one offset matches, so this last step isn't necessary. It's only when I quickly cross timezones that there are potentially more than one match.

    Turning this into an API

    Since I want to be able to use this to geotag photos, it makes sense to include it as an API in the same system that stores my GPS logs. I encapsulated this logic in my GPS server, Compass with a simple API that returns the answer given an offset-less time. Now I can use it in my geotagging script!

    Portland, Oregon
    Sat, Jul 16, 2016 8:59pm -07:00 #time #timezone #geotag #gps #p3k
    12 likes 9 replies 3 mentions
    • Jeena
    • Joschi Kuphal 吉
    • Leif (((Warner)))
    • Carlos Silva
    • Jonny Barnes
    • Antonio Bettencourt
    • Nick Furness
    • Ankur Naik
    • Amit Gupta
    • Mike Richmond
    • Amalia Parecki
    • Bo Milton
    • Peter Molnar petermolnar.net/about
      RE: aaronparecki.com/2016/07/16/8/ I recently batch-geotagged photos of mine for the first time ever; I ended up using http://www.carto.net/projects/photoTools/gpsPhoto/, it is quite handy. If you’re planning to make an API I suggest you make it gpx compatible; in case you ever obtain anything that is gpx already, it would save you a headache. Published 2016-07-18 10:50 Author Photo of Peter MolnarPeter Molnar Tags Reply Short URL 48276a0776517974a1c68f69aeba8cae https://petermolnar.net/oaibgf
      Mon, Jul 18, 2016 10:50am +00:00
    • Peter Molnar petermolnar.net
      RE: https://aaronparecki.com/2016/07/16/8/
      Mon, Jul 18, 2016 8:50am +00:00
    • Daniel Patrick Johnson www.facebook.com/10154065753200624
      Now you just need the flightstats API to figure out where your plane was when you lost GPS lock.
      Sun, Jul 17, 2016 6:02pm +00:00 (via brid-gy.appspot.com)
    • Justin C. Houk www.facebook.com/10203281425384206
      This is interesting, the do somthing similar with flight plans and photos.
      Sun, Jul 17, 2016 5:31pm +00:00 (via brid-gy.appspot.com)
    • Greg unrelenting.technology

      Lightroom can import .gpx logs to automatically tag photos. But looks like you’re not someone who would use Lightroom :)

      About the timezone problem — do you change the time on your camera when you travel to a different timezone? Why? Why not just let the camera’s clock stay in home time or UTC?

      Sun, Jul 17, 2016 8:14am -07:00
    • Rob Fairhead raretrack.uk
      @aaronpk I'm analog - at each location I take 1 shot with my GPS-enabled point-and-shoot, copy GPS co-ords over in post. Your way is cooler!
      Sun, Jul 17, 2016 2:31pm +00:00 (via brid-gy.appspot.com)
    • Antonio Bettencourt www.facebook.com/10153955032475562
      You often amaze me.
      Sun, Jul 17, 2016 12:24pm +00:00 (via brid-gy.appspot.com)
    • Ann Bassetti www.facebook.com/10153117899234347
      As I've come to expect from you -- impressive!
      Sun, Jul 17, 2016 7:40am +00:00 (via brid-gy.appspot.com)
    • Thubten Comerford www.facebook.com/779903175448557
      ❤️
      Sat, Jul 16, 2016 10:26pm -07:00 (via brid-gy.appspot.com)

    Other Mentions

    • Aaron Parecki aaronparecki.com
      Day 42: New Sleep Posts from FitBit #100DaysOfIndieWeb
      Tue, Jan 31, 2017 12:44pm -08:00
    • Aaron Parecki aaronparecki.com
      Sometimes I amaze even myself at the hoops I go through to do things like geotag my photos: https://aaronparecki.com/2016/07/16/8/geotagging-photos
      Sat, Jul 16, 2016 9:25pm -07:00
    • Aaron Parecki aaronparecki.com
      My GPS Logs
      Fri, Dec 2, 2022 9:29am -07:00
Posted in /articles using quill.p3k.io

Hi, I'm Aaron Parecki, Director of Identity Standards at Okta, and co-founder of IndieWebCamp. I maintain oauth.net, write and consult about OAuth, and participate in the OAuth Working Group at the IETF. I also help people learn about video production and livestreaming. (detailed bio)

I've been tracking my location since 2008 and I wrote 100 songs in 100 days. I've spoken at conferences around the world about owning your data, OAuth, quantified self, and explained why R is a vowel. Read more.

  • Director of Identity Standards at Okta
  • IndieWebCamp Founder
  • OAuth WG Editor
  • OpenID Board Member

  • 🎥 YouTube Tutorials and Reviews
  • 🏠 We're building a triplex!
  • ⭐️ Life Stack
  • ⚙️ Home Automation
  • All
  • Articles
  • Bookmarks
  • Notes
  • Photos
  • Replies
  • Reviews
  • Trips
  • Videos
  • Contact
© 1999-2025 by Aaron Parecki. Powered by p3k. This site supports Webmention.
Except where otherwise noted, text content on this site is licensed under a Creative Commons Attribution 3.0 License.
IndieWebCamp Microformats Webmention W3C HTML5 Creative Commons
WeChat ID
aaronpk_tv