Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
manu
committed
Apr 1, 2017
1 parent
27821be
commit a71b149
Showing
7 changed files
with
313 additions
and
3 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
#!/usr/bin/env python2 | ||
# -*- coding: utf-8 -*- | ||
|
||
from memacs.gpx import GPX | ||
|
||
PROG_VERSION_NUMBER = u"0.1" | ||
PROG_VERSION_DATE = u"2017-03-02" | ||
PROG_SHORT_DESCRIPTION = u"Memacs for GPX files" | ||
PROG_TAG = u"gps" | ||
|
||
COPYRIGHT_YEAR = "2017" | ||
COPYRIGHT_AUTHORS = """Manuel Koell <mankoell@gmail.com>""" | ||
|
||
|
||
if __name__ == "__main__": | ||
memacs = GPX(prog_version=PROG_VERSION_NUMBER, | ||
prog_version_date=PROG_VERSION_DATE, | ||
prog_short_description=PROG_SHORT_DESCRIPTION, | ||
prog_tag=PROG_TAG, | ||
copyright_year=COPYRIGHT_YEAR, | ||
copyright_authors=COPYRIGHT_AUTHORS) | ||
memacs.handle_main() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,63 @@ | ||
## This file is best viewed with GNU Emacs Org-mode: http://orgmode.org/ | ||
|
||
* memacs-gpx | ||
|
||
Parse GPX files + reverse geocoding. Make sure to read about the usage policy and limits of both, | ||
[[https://developers.google.com/maps/documentation/geocoding/usage-limits?hl=de][Google]] and | ||
[[https://operations.osmfoundation.org/policies/nominatim/][OSM]] or setup your own | ||
[[https://github.com/openstreetmap/Nominatim][Nominatim]] server. | ||
There is also a great app for android, called [[https://play.google.com/store/apps/details?id=com.mendhak.gpslogger&hl=de][GPSLogger]], | ||
a battery efficient GPS logging application to log your position throughout the day. | ||
It is free software and open source (FOSS), thus available on [[https://github.com/mendhak/gpslogger][GitHub]] and | ||
[[https://f-droid.org/repository/browse/?fdfilter=gps+logger&fdid=com.mendhak.gpslogger][F-Droid]] as well. | ||
|
||
** Options | ||
- ~-f~, ~--file~ path to gpx file or folder | ||
- ~-p~, ~--provider~ geocode provider, ~google~ (default) or ~osm~ | ||
- ~-u~, ~--url~ url to nominatim server (osm only) | ||
- ~--output-format~ use ~--verbose~ flag to see available placeholder, default ~{address}~ | ||
|
||
** Example | ||
#+BEGIN_EXAMPLE | ||
memacs_gpx.py -f memacs/tests/data/sample.gpx | ||
#+END_EXAMPLE | ||
|
||
#+BEGIN_EXAMPLE | ||
* Memacs for GPX files :Memacs:gps: | ||
** <2017-04-01 Sat 10:50> Eggenberger Allee 9, 8020 Graz, Austria :network: | ||
:PROPERTIES: | ||
:LATITUDE: 47.0693 | ||
:LONGITUDE: 15.4076001 | ||
:ID: c2dc4f2289d79cff4cf27faa95863f8cb5b8cb21 | ||
:END: | ||
|
||
** <2017-04-01 Sat 10:51> Alte Poststraße 149, 8020 Graz, Austria :network: | ||
:PROPERTIES: | ||
:LATITUDE: 47.0690816 | ||
:LONGITUDE: 15.4099195 | ||
:ID: 17ad7a67128b74b85d04998bca02d11abe66dd1f | ||
:END: | ||
#+END_EXAMPLE | ||
|
||
----- | ||
|
||
#+BEGIN_EXAMPLE | ||
memacs_gpx.py -f memacs/tests/data/sample.gpx -p osm | ||
#+END_EXAMPLE | ||
|
||
#+BEGIN_EXAMPLE | ||
* Memacs for GPX files :Memacs:location: | ||
** <2017-04-01 Sat 10:50> FH Joanneum - Prüffeld, 150, Alte Poststraße, Gries, Graz, Steiermark, 8020, Österreich :network: | ||
:PROPERTIES: | ||
:LATITUDE: 47.0693 | ||
:LONGITUDE: 15.4076001 | ||
:ID: c2dc4f2289d79cff4cf27faa95863f8cb5b8cb21 | ||
:END: | ||
|
||
** <2017-04-01 Sat 10:51> FH Joanneum, 149, Alte Poststraße, Gries, Graz, Steiermark, 8020, Österreich :network: | ||
:PROPERTIES: | ||
:LATITUDE: 47.0690816 | ||
:LONGITUDE: 15.4099195 | ||
:ID: 17ad7a67128b74b85d04998bca02d11abe66dd1f | ||
:END: | ||
#+END_EXAMPLE |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,138 @@ | ||
#!/usr/bin/env python2 | ||
# -*- coding: utf-8 -*- | ||
|
||
import logging | ||
import time | ||
import json | ||
import sys | ||
import os | ||
|
||
import gpxpy | ||
import gpxpy.gpx | ||
import geocoder | ||
|
||
from lib.orgproperty import OrgProperties | ||
from lib.orgformat import OrgFormat | ||
from lib.memacs import Memacs | ||
|
||
|
||
class GPX(Memacs): | ||
def _parser_add_arguments(self): | ||
""" | ||
overwritten method of class Memacs | ||
add additional arguments | ||
""" | ||
Memacs._parser_add_arguments(self) | ||
|
||
self._parser.add_argument( | ||
"-f", "--folder", dest="source", | ||
action="store", required=True, | ||
help="path to gpx file or folder") | ||
|
||
self._parser.add_argument( | ||
"-p", "--provider", dest="provider", | ||
action="store", default="google", | ||
help="geocode provider, default google") | ||
|
||
self._parser.add_argument( | ||
"-u", "--url", dest="url", | ||
action="store", help="url to nominatim server (osm only)") | ||
|
||
self._parser.add_argument( | ||
"--output-format", dest="output_format", | ||
action="store", default="{address}", | ||
help="format string to use for the headline") | ||
|
||
def _parser_parse_args(self): | ||
""" | ||
overwritten method of class Memacs | ||
all additional arguments are parsed in here | ||
""" | ||
Memacs._parser_parse_args(self) | ||
|
||
if not os.path.exists(self._args.source): | ||
self._parser.error("source file or folder does not exist") | ||
|
||
if self._args.url and not self._args.url.startswith("http"): | ||
self._parser.error("invalid url given") | ||
|
||
def reverse_geocode(self, lat, lng): | ||
"""get address for latitude/longitude""" | ||
|
||
if 'google' in self._args.provider: | ||
geocode = geocoder.google([lat, lng], method='reverse') | ||
|
||
elif 'osm' in self._args.provider: | ||
if not self._args.url: | ||
geocode = geocoder.osm([lat, lng], method='reverse') | ||
time.sleep(1) # Nominatim Usage Policy | ||
else: | ||
if 'localhost' in self._args.url: | ||
geocode = geocoder.osm([lat, lng], method='reverse', url='http://localhost/nominatim/search') | ||
else: | ||
geocode = geocoder.osm([lat, lng], method='reverse', url=self._args.url) | ||
|
||
else: | ||
self._parser.error("invalid provider given") | ||
sys.exit(1) | ||
|
||
if not geocode.ok: | ||
logging.error("geocoding failed or api limit exceeded") | ||
sys.exit(1) | ||
else: | ||
logging.debug(geocode.json) | ||
return geocode.json | ||
|
||
def write_point(self, p): | ||
"""write a point (including geocoding)""" | ||
|
||
timestamp = OrgFormat.datetime(p.time) | ||
geocode = self.reverse_geocode(p.latitude, p.longitude) | ||
output = self._args.output_format.decode('utf-8').format(**geocode) | ||
|
||
tags = [] | ||
|
||
properties = OrgProperties(data_for_hashing=timestamp) | ||
|
||
if p.latitude: | ||
properties.add('LATITUDE', p.latitude) | ||
|
||
if p.longitude: | ||
properties.add('LONGITUDE', p.longitude) | ||
|
||
if p.source: | ||
tags.append(p.source.lower()) | ||
|
||
if timestamp: | ||
self._writer.write_org_subitem(timestamp=timestamp, | ||
output=output, | ||
properties=properties, | ||
tags=tags) | ||
|
||
def handle_file(self, f): | ||
"""iterate through a file""" | ||
|
||
data = open(f) | ||
gpx = gpxpy.parse(data) | ||
|
||
for track in gpx.tracks: | ||
for segment in track.segments: | ||
for point in segment.points: | ||
self.write_point(point) | ||
logging.debug(point) | ||
|
||
def _main(self): | ||
""" | ||
get's automatically called from Memacs class | ||
""" | ||
|
||
if os.path.isfile(self._args.source): | ||
self.handle_file(self._args.source) | ||
|
||
else: | ||
for root, dirs, files in os.walk(self._args.source): | ||
for f in files: | ||
if f.endswith('.gpx'): | ||
self.handle_file(os.path.join(root, f)) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
<?xml version="1.0" encoding="UTF-8" ?> | ||
|
||
<gpx version="1.0" creator="GPSLogger 79 - http://gpslogger.mendhak.com/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.topografix.com/GPX/1/0" xsi:schemaLocation="http://www.topografix.com/GPX/1/0 http://www.topografix.com/GPX/1/0/gpx.xsd"> | ||
<time>2017-04-01T10:15:24Z</time> | ||
<trk> | ||
<trkseg> | ||
<trkpt lat="47.0693" lon="15.4076001"><time>2017-04-01T10:50:00Z</time><src>network</src></trkpt> | ||
<trkpt lat="47.0690816" lon="15.4099195"><time>2017-04-01T10:51:00Z</time><src>network</src></trkpt> | ||
</trkseg> | ||
</trk> | ||
</gpx> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,72 @@ | ||
# -*- coding: utf-8 -*- | ||
|
||
import unittest | ||
import os | ||
|
||
from memacs.gpx import GPX | ||
|
||
|
||
class TestGPX(unittest.TestCase): | ||
|
||
def test_google(self): | ||
sample = os.path.join( | ||
os.path.dirname(os.path.abspath(__file__)), 'data', 'sample.gpx' | ||
) | ||
|
||
argv = [] | ||
argv.append('-f') | ||
argv.append(sample) | ||
|
||
memacs = GPX(argv=argv) | ||
data = memacs.test_get_entries() | ||
|
||
self.assertEqual( | ||
data[0], | ||
u"** <2017-04-01 Sat 10:50> Eggenberger Allee 9, 8020 Graz, Austria :network:") | ||
self.assertEqual( | ||
data[1], | ||
" :PROPERTIES:") | ||
self.assertEqual( | ||
data[2], | ||
" :LATITUDE: 47.0693") | ||
self.assertEqual( | ||
data[3], | ||
" :LONGITUDE: 15.4076001") | ||
self.assertEqual( | ||
data[4], | ||
" :ID: c2dc4f2289d79cff4cf27faa95863f8cb5b8cb21") | ||
self.assertEqual( | ||
data[5], | ||
" :END:") | ||
|
||
def test_osm(self): | ||
sample = os.path.join( | ||
os.path.dirname(os.path.abspath(__file__)), 'data', 'sample.gpx' | ||
) | ||
|
||
argv = [] | ||
argv.append('-f') | ||
argv.append(sample) | ||
argv.append('-p osm') | ||
|
||
memacs = GPX(argv=argv) | ||
data = memacs.test_get_entries() | ||
|
||
self.assertEqual( | ||
data[0], | ||
u"** <2017-04-01 Sat 10:50> FH Joanneum - Prüffeld, 150, Alte Poststraße, Gries, Graz, Steiermark, 8020, Österreich :network:") | ||
self.assertEqual( | ||
data[1], | ||
" :PROPERTIES:") | ||
self.assertEqual( | ||
data[2], | ||
" :LATITUDE: 47.0693") | ||
self.assertEqual( | ||
data[3], | ||
" :LONGITUDE: 15.4076001") | ||
self.assertEqual( | ||
data[4], | ||
" :ID: c2dc4f2289d79cff4cf27faa95863f8cb5b8cb21") | ||
self.assertEqual( | ||
data[5], | ||
" :END:") |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,8 +1,10 @@ | ||
nose | ||
nose==1.3.7 | ||
Pillow==2.4.0 | ||
argparse==1.2.1 | ||
feedparser==5.1.2 | ||
icalendar==3.1 | ||
pylast==1.8.0 | ||
twython | ||
batinfo | ||
batinfo==0.4.2 | ||
twython==3.4.0 | ||
gpxpy==1.1.2 | ||
geocoder==1.20.0 |