I just added my favorite new relatively unimportant feature to my website!
I added my Swarm checkins to my website a few weeks ago, which has been super fun. One thing I always thought was missing from Swarm was knowing whether a friend was still at a venue they checked in to. Since I have checkins on my own website, I can do that now!
So now, when you're viewing a checkin on my site, if I am still at that location, you will see a pulsing blue dot next to the venue name!
This works because my phone always tracks my GPS location and reports it to my website already. My website compares my last location with the last checkin, and if I'm still nearby, will show the dot!
I track my location continuously using an iOS app I wrote a few years ago. The app is not published on the app store, but it is open source. Today I added a bunch of documentation describing what all the controls in the interface are for.
The settings screen is somewhat overwhelming, mostly because this is actually intended to be an app for learning what the various iOS location APIs do.
So now the readme file has a description of each of these controls.
Head over to the readme for the details! https://github.com/aaronpk/GPS-Logger-iOS#documentation
I also added a new control, "points per batch", which controls how many location updates are sent to the server in each HTTP request. Prior to this setting, it was always sending 200, which works well but sometimes causes problems. When I take a long plane flight and queue up thousands of points on the device before I am back to a data connection, sending them 200 at a time actually takes quite a while to send them all. Now I can set the batch size to 1000 which should flush them much more quickly.
During this process, I also discovered a weird bug where none of the controls in the settings screen could be tapped! I suspect this is some iOS 10 API change that caused this, since I haven't changed anything about the app since I used it on iOS 9. I still don't know the underlying cause, but I was able to fix it by removing one level of nesting of the UI elements. Previously, a ScrollView contained a ContentView which contained the StackView that has all the controls. I removed the ContentView from the middle and now the buttons are tappable again. No idea what went wrong! I am clearly not an iOS developer.
"Using these ideas we can construct a table of what each digit in a decimal degree signifies: The sign tells us whether we are north or south, east or west on the globe. A nonzero hundreds digit tells us we're using longitude, not latitude! • The tens digit gives a position to about 1,000 kilometers. It gives us useful information about what continent or ocean we are on. • The units digit (one decimal degree) gives a position up to 111 kilometers (60 nautical miles, about 69 miles). It can tell us roughly what large state or country we are in. • The first decimal place is worth up to 11.1 km: it can distinguish the position of one large city from a neighboring large city. • The second decimal place is worth up to 1.1 km: it can separate one village from the next. • The third decimal place is worth up to 110 m: it can identify a large agricultural field or institutional campus. • The fourth decimal place is worth up to 11 m: it can identify a parcel of land. It is comparable to the typical accuracy of an uncorrected GPS unit with no interference. • The fifth decimal place is worth up to 1.1 m: it distinguish trees from each other. Accuracy to this level with commercial GPS units can only be achieved with differential correction. • The sixth decimal place is worth up to 0.11 m: you can use this for laying out structures in detail, for designing landscapes, building roads. It should be more than good enough for tracking movements of glaciers and rivers. This can be achieved by taking painstaking measures with GPS, such as differentially corrected GPS. • The seventh decimal place is worth up to 11 mm: this is good for much surveying and is near the limit of what GPS-based techniques can achieve. • The eighth decimal place is worth up to 1.1 mm: this is good for charting motions of tectonic plates and movements of volcanoes. Permanent, corrected, constantly-running GPS base stations might be able to achieve this level of accuracy. • The ninth decimal place is worth up to 110 microns: we are getting into the range of microscopy. For almost any conceivable application with earth positions, this is overkill and will be more precise than the accuracy of any surveying device. • Ten or more decimal places indicates a computer or calculator was used and that no attention was paid to the fact that the extra decimals are useless. Be careful, because unless you are the one reading these numbers off the device, this can indicate low quality processing!"
"Nearest neighbor-finding is one of the most important spatial operations in the field of spatial data structures concerned with proximity. Because the goal of the space-filling curves is to preserve the spatial proximity, the nearest neighbor queries can be handled by these space-filling curves."
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.
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.
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:
(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
|2016-05-12 15:59:57 -04:00
|2016-05-12 16:00:00 +02:00
|2016-05-12 14:52:46 +02:00
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.
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!