I like to hike. On these hikes, I take photographs:
It tracks my every move and outputs useful data:
Most GPS devices output data in a format called GPX (GPS Exchange Format) or KML (Google's Keyhole Markup Language)
GPX looks like this:
<?xml version="1.0" encoding="UTF-8"?>
<gpx xmlns="http://www.topografix.com/GPX/1/1" creator="GPS Kit iOS App by Garafa" version="1.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.topografix.com/GPX/1/1 http://www.topografix.com/GPX/1/1/gpx.xsd">
<metadata>
<name>Sun Jul 15 2012</name>
</metadata>
<trk>
<name>7/15/12 12:49:13</name>
<trkseg>
<trkpt lat="47.724010" lon="-121.266878">
<ele>827</ele>
<time>2012-07-15T19:49:13.0980Z</time>
</trkpt>
<trkpt lat="47.724065" lon="-121.266835">
<ele>831</ele>
<time>2012-07-15T19:49:53.9880Z</time>
</trkpt>
<trkpt lat="47.724113" lon="-121.266840">
<ele>838</ele>
<time>2012-07-15T19:51:21.0600Z</time>
</trkpt>
<trkpt lat="47.724161" lon="-121.266838">
<ele>837</ele>
<time>2012-07-15T19:51:25.1110Z</time>
</trkpt>
<trkpt lat="47.724207" lon="-121.266816">
<ele>833</ele>
<time>2012-07-15T19:52:30.0850Z</time>
</trkpt>
<trkpt lat="47.724252" lon="-121.266782">
<ele>837</ele>
<time>2012-07-15T19:52:36.1230Z</time>
</trkpt>
* 1000…
There's a good chance that when the photo is taken, a GPS reading was taken around the same time.
I wrote a python command-line tool that reads and parses these GPX files, takes a folder of images, and links a GPX trackpoint to each image.
In its current state, it generates a GPX (or geojson) file with trackpoints that link to the photo's filename.
$ pip install GpxImageLinkifier
// Checkout that sweet help (thanks to argparse):
$ gil --help
$ cd ~/Dropbox/work/Smashing\ Ideas/GpxImageLinkifier-example/
$ gil GPSKitData.gpx . --offset-gpx=1h13m --tz-images=US/Pacific --accuracy=20m
// Output looks like:
{
"type": "FeatureCollection",
"features": [
{
"geometry": {
"type": "Point",
"coordinates": [
-121.479383,
48.054684,
1020.0
]
},
"type": "Feature",
"properties": {
"content": "IMG_7177.JPG"
}
},
{
"geometry": {
"type": "Point",
"coordinates": [
-121.479584,
48.05951,
1254.0
]
},
"type": "Feature",
"properties": {
"content": "IMG_7182.JPG"
}
},
{
"geometry": {
"type": "Point",
"coordinates": [
-121.479584,
48.05951,
1254.0
]
},
"type": "Feature",
"properties": {
"content": "IMG_7185.JPG"
}
},
{
"geometry": {
"type": "Point",
"coordinates": [
-121.471116,
48.068929,
1743.0
]
},
"type": "Feature",
"properties": {
"content": "IMG_7233.JPG"
}
},
{
"geometry": {
"type": "Point",
"coordinates": [
-121.471157,
48.068906,
1743.0
]
},
"type": "Feature",
"properties": {
"content": "IMG_7241.JPG"
}
}
]
Paste that output into geojsonlint.com and see the result.
This module is seriously just a mashup of other modules people have made. I just put them all together:
- PIL (for photo exif reading)
- gpxpy (parses GPX files)
- argparse (for argument parsing)
- json + my code (generates geojson)
- pytz (timezone conversions if necessary)
- datetime (for timestamp comparisons)
- nose (for testing)
My end result: http://austinhappel.github.io/Hikes/
Creating a python package is probably the least intuitive thing about Python.
The basics (folder structure, etc) are fairly straightforward: Here's a nice starter guide
There are way too many tools for package creation/management in python, and it was really not clear to me at all what I should do.
Distutils is the standard tool used for packaging. It works rather well for simple needs, but is limited and not trivial to extend.
Setuptools is a project born from the desire to fill missing distutils functionality and explore new directions. In some subcommunities, it’s a de facto standard. It uses monkey-patching and magic that is frowned upon by Python core developers.
Distribute is a fork of Setuptools that was started by developers feeling that its development pace was too slow and that it was not possible to evolve it. Its development was considerably slowed when distutils2 was started by the same group. 2013-August update: distribute is merged back into setuptools and discontinued.
Distutils2 is a new distutils library, started as a fork of the distutils codebase, with good ideas taken from setup tools (of which some were thoroughly discussed in PEPs), and a basic installer inspired by pip. The actual name you use to import Distutils2 is packaging
in the Python 3.3+ standard library, or distutils2 in 2.4+ and 3.1–3.2. (A backport will be available soon.)Distutils2 did not make the Python 3.3 release, and it was put on hold.
The main one is installing external dependencies along with your module.
See this. Only with distribute am I able to add a "install_requires" which will be automatically installed along with my module.