#!/usr/bin/env python
# Copyright (C) 2012 Michael Gorven
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
from datetime import timedelta
from optparse import OptionParser
from sys import argv, stderr, stdout
from gpxdata import Document, TrackSegment, Track
parser = OptionParser(usage='%prog [ ...]')
parser.add_option('-s', '--segments', help=u'Single track segment or comma separated start and end segments.')
parser.add_option('--min-distance', type='int', help=u'Minimum distance in metres for a track segment to be selected.')
parser.add_option('--max-distance', type='int', help=u'Maximum distance in metres for a track segment to be selected.')
parser.add_option('--max-displacement', type='int', help=u'Maximum displacement in metres for a track segment to be selected.')
parser.add_option('--min-duration', type='int', help=u'Minimum duration in seconds for a track segment to be selected.')
parser.add_option('--max-duration', type='int', help=u'Maximum duration in seconds for a track segment to be selected.')
parser.add_option('--min-speed', type='float', help=u'Minimum speed in metres/second for a track segment to be selected.')
parser.add_option('--max-speed', type='float', help=u'Maximum speed in metres/second for a track segment to be selected.')
parser.set_defaults(
min_distance=500,
max_distance=10000,
max_displacement=100,
min_duration=300,
max_duration=3600,
min_speed=1.5,
max_speed=4,
)
tracks = []
opts, args = parser.parse_args()
start, end = None, None
if opts.segments:
if len(opts.segments.split(',')) == 1:
start = end = int(opts.segments)
elif len(opts.segments.split(',')) == 2:
start, end = [int(part) for part in opts.segments.split(',')]
else:
parser.error(u'Invalid segment specification.')
for infile in args:
print >> stderr, "Reading", infile
indoc = Document.readGPX(infile)
if start != None:
points = []
for segment in indoc.tracks[0].segments[start:end]:
points.extend(segment.points)
tracks.append(Track(name=points[0].t.strftime('%Y-%m-%d'), segments=[TrackSegment(points)]))
continue
for segment in indoc.tracks[0].segments:
if len(segment.points) < 2:
continue
length = segment.length()
displacement = segment.points[0].distance(segment.points[-1])
time = segment.points[-1].t - segment.points[0].t
speed = segment.length() / time.seconds
print >> stderr, "%s covers %dm over %s at %.1fm/s average speed with %dm displacement" % (segment, length, time, speed, displacement)
if length < opts.min_distance or length > opts.max_distance:
continue
if displacement > opts.max_displacement:
continue
if time < timedelta(seconds=opts.min_duration) or time > timedelta(seconds=opts.max_duration):
continue
if speed > opts.max_speed or speed < opts.min_speed:
continue
print >> stderr, "Adding", str(segment)
tracks.append(Track(name=segment.points[0].t.strftime('%Y-%m-%d'), segments=[segment]))
outdoc = Document(tracks=tracks)
outdoc.writeGPX(stdout)