tallakt-gpsspeed 0.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/History.txt ADDED
@@ -0,0 +1,4 @@
1
+ == 0.0.1 2009-02-15
2
+
3
+ * First working version
4
+
data/LICENSE ADDED
@@ -0,0 +1,24 @@
1
+
2
+
3
+ The MIT License
4
+
5
+ Copyright (c) 2009 Tallak Tveide
6
+
7
+ Permission is hereby granted, free of charge, to any person obtaining a copy
8
+ of this software and associated documentation files (the "Software"), to deal
9
+ in the Software without restriction, including without limitation the rights
10
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11
+ copies of the Software, and to permit persons to whom the Software is
12
+ furnished to do so, subject to the following conditions:
13
+
14
+ The above copyright notice and this permission notice shall be included in
15
+ all copies or substantial portions of the Software.
16
+
17
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
23
+ THE SOFTWARE.
24
+
data/Manifest.txt ADDED
@@ -0,0 +1,17 @@
1
+ bin/gpsspeed
2
+ gpsspeed.gemspec
3
+ History.txt
4
+ lib/gpsspeed/runner.rb
5
+ lib/gpsspeed.rb
6
+ LICENSE
7
+ Manifest.txt
8
+ PostInstall.txt
9
+ Rakefile
10
+ README.rdoc
11
+ script/console
12
+ script/generate
13
+ script/destroy
14
+ test/test_helper.rb
15
+ test/test_gpsspeed.rb
16
+ test/input/test_walk.gpx
17
+ test/input/tracks.gpx
data/PostInstall.txt ADDED
@@ -0,0 +1,7 @@
1
+
2
+ For more information on gpsspeed, see http://gpsspeed.rubyforge.org
3
+
4
+ NOTE: Change this information in PostInstall.txt
5
+ You can also delete it if you don't want it.
6
+
7
+
data/README.rdoc ADDED
@@ -0,0 +1,92 @@
1
+ = gpsspeed
2
+
3
+ http://github.com/tallakt/plcutil
4
+
5
+ == DESCRIPTION:
6
+
7
+ GPS Track speed calculation utility
8
+
9
+ == FEATURES/PROBLEMS:
10
+
11
+ This utility will take a gpx file as input (created for instance by http://www.easygps.com/)
12
+ and display the statistics for the best speeds of the tracks in the file over a certain
13
+ distance that may be supplied
14
+
15
+ == SYNOPSIS:
16
+
17
+ A starting point for using gpsspeed, try the --help option
18
+
19
+ gpsspeed --help
20
+
21
+ Usage: gpsspeed [options] <input.gpx>
22
+ -l, --length DIST Minimum required length (default 500m)
23
+ Accepts km,m,ft,miles,nm
24
+ -s, --speed-format FMT Select speed format (default m/s)
25
+ Accepts knots,mph,m/s,km/h
26
+ -f, --length-format FMT Select length format (default m)
27
+ Accepts km,m,ft,miles,nm
28
+ -h, --help Show this message
29
+
30
+
31
+ A common usage would be to run the command without any special options
32
+
33
+ gpsspeed myfile.gpx
34
+
35
+ Which gives you an output like this
36
+
37
+ Speed [m/s] #frm #to #n time [s] Distance [m]
38
+ 1.6411 4 9 6 65.00 106.7
39
+ 1.4037 13 19 7 77.00 108.1
40
+
41
+ The utility finds the highest speeds in the track file over a
42
+ minimum distance. The best runs are listed in descending order
43
+ (ie. fastest run first). To use a different length, use the -l
44
+ parameter
45
+
46
+ gpsspeed -l 200m myfile.gpx
47
+
48
+ To display the results in different units, use the -s and -f
49
+ options, like this
50
+
51
+ gpsspeed -s knots -f nm
52
+
53
+ Which gives you a result table like this
54
+
55
+ Speed [knots] #frm #to #n time [s] Distance [nm]
56
+ 3.1901 4 9 6 65.00 0.0576
57
+ 2.7285 13 19 7 77.00 0.0584
58
+
59
+
60
+ == REQUIREMENTS:
61
+
62
+ Requires the gem tallakt-geoutm
63
+
64
+ == INSTALL:
65
+
66
+ sudo gem sources -a http://gems.github.com
67
+ sudo gem install tallakt-gpsspeed
68
+
69
+ == LICENSE:
70
+
71
+ (The MIT License)
72
+
73
+ Copyright (c) 2009 Tallak Tveide
74
+
75
+ Permission is hereby granted, free of charge, to any person obtaining
76
+ a copy of this software and associated documentation files (the
77
+ 'Software'), to deal in the Software without restriction, including
78
+ without limitation the rights to use, copy, modify, merge, publish,
79
+ distribute, sublicense, and/or sell copies of the Software, and to
80
+ permit persons to whom the Software is furnished to do so, subject to
81
+ the following conditions:
82
+
83
+ The above copyright notice and this permission notice shall be
84
+ included in all copies or substantial portions of the Software.
85
+
86
+ THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
87
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
88
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
89
+ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
90
+ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
91
+ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
92
+ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/Rakefile ADDED
@@ -0,0 +1,29 @@
1
+ %w[rubygems rake rake/clean fileutils newgem rubigen].each { |f| require f }
2
+ require File.dirname(__FILE__) + '/lib/gpsspeed'
3
+ require 'geoutm'
4
+
5
+ # Generate all the Rake tasks
6
+ # Run 'rake -T' to see list of generated tasks (from gem root directory)
7
+ $hoe = Hoe.new('gpsspeed', Gpsspeed::VERSION) do |p|
8
+ p.developer('Tallak Tveide', 'tallak@tveide.net')
9
+ p.changes = p.paragraphs_of("History.txt", 0..1).join("\n\n")
10
+ p.post_install_message = 'PostInstall.txt' # TODO remove if post-install message not required
11
+ p.rubyforge_name = p.name # TODO this is default value
12
+ p.extra_deps = [
13
+ ['tallakt-geoutm',">= #{::GeoUtm::VERSION}"],
14
+ ]
15
+ p.extra_dev_deps = [
16
+ ['newgem', ">= #{::Newgem::VERSION}"]
17
+ ]
18
+
19
+ p.clean_globs |= %w[**/.DS_Store tmp *.log]
20
+ path = (p.rubyforge_name == p.name) ? p.rubyforge_name : "\#{p.rubyforge_name}/\#{p.name}"
21
+ p.remote_rdoc_dir = File.join(path.gsub(/^#{p.rubyforge_name}\/?/,''), 'rdoc')
22
+ p.rsync_args = '-av --delete --ignore-errors'
23
+ end
24
+
25
+ require 'newgem/tasks' # load /tasks/*.rake
26
+ Dir['tasks/**/*.rake'].each { |t| load t }
27
+
28
+ # TODO - want other tests/tasks run by default? Add them to the list
29
+ # task :default => [:spec, :features]
data/bin/gpsspeed ADDED
@@ -0,0 +1,4 @@
1
+ #!/usr/bin/env ruby
2
+ require 'rubygems'
3
+ require 'gpsspeed/runner.rb'
4
+ GPSSpeed::Runner.new ARGV
data/gpsspeed.gemspec ADDED
@@ -0,0 +1,44 @@
1
+ # -*- encoding: utf-8 -*-
2
+
3
+ Gem::Specification.new do |s|
4
+ s.name = %q{gpsspeed}
5
+ s.version = "0.0.2"
6
+
7
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
8
+ s.authors = ["Tallak Tveide"]
9
+ s.date = %q{2009-02-16}
10
+ s.default_executable = %q{gpsspeed}
11
+ s.description = %q{GPS Track speed calculation utility}
12
+ s.email = ["tallak@tveide.net"]
13
+ s.executables = ["gpsspeed"]
14
+ s.extra_rdoc_files = ["History.txt", "Manifest.txt", "PostInstall.txt", "README.rdoc"]
15
+ s.files = ["bin/gpsspeed", "gpsspeed.gemspec", "History.txt", "lib/gpsspeed/runner.rb", "lib/gpsspeed.rb", "LICENSE", "Manifest.txt", "PostInstall.txt", "Rakefile", "README.rdoc", "script/console", "script/generate", "script/destroy", "test/test_helper.rb", "test/test_gpsspeed.rb", "test/input/test_walk.gpx", "test/input/tracks.gpx"]
16
+ s.has_rdoc = true
17
+ s.homepage = %q{http://github.com/tallakt/plcutil}
18
+ s.post_install_message = %q{PostInstall.txt}
19
+ s.rdoc_options = ["--main", "README.rdoc"]
20
+ s.require_paths = ["lib"]
21
+ s.rubyforge_project = %q{gpsspeed}
22
+ s.rubygems_version = %q{1.3.1}
23
+ s.summary = %q{GPS Track speed calculation utility}
24
+ s.test_files = ["test/test_helper.rb", "test/test_gpsspeed.rb"]
25
+
26
+ if s.respond_to? :specification_version then
27
+ current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
28
+ s.specification_version = 2
29
+
30
+ if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
31
+ s.add_runtime_dependency(%q<tallakt-geoutm>, [">= 0.0.3"])
32
+ s.add_development_dependency(%q<newgem>, [">= 1.2.3"])
33
+ s.add_development_dependency(%q<hoe>, [">= 1.8.0"])
34
+ else
35
+ s.add_dependency(%q<tallakt-geoutm>, [">= 0.0.3"])
36
+ s.add_dependency(%q<newgem>, [">= 1.2.3"])
37
+ s.add_dependency(%q<hoe>, [">= 1.8.0"])
38
+ end
39
+ else
40
+ s.add_dependency(%q<tallakt-geoutm>, [">= 0.0.3"])
41
+ s.add_dependency(%q<newgem>, [">= 1.2.3"])
42
+ s.add_dependency(%q<hoe>, [">= 1.8.0"])
43
+ end
44
+ end
data/lib/gpsspeed.rb ADDED
@@ -0,0 +1,6 @@
1
+ $:.unshift(File.dirname(__FILE__)) unless
2
+ $:.include?(File.dirname(__FILE__)) || $:.include?(File.expand_path(File.dirname(__FILE__)))
3
+
4
+ module Gpsspeed
5
+ VERSION = '0.0.2'
6
+ end
@@ -0,0 +1,159 @@
1
+ require 'rexml/document'
2
+ require 'ostruct'
3
+ require 'geoutm'
4
+ require 'enumerator'
5
+ require 'optparse'
6
+
7
+ class FloatA # necessary dt rexml bug
8
+ def each
9
+ end
10
+ end
11
+
12
+ module GPSSpeed
13
+ class Runner
14
+ DEFAULT_LENGTH = 500
15
+ DEFAULT_SPEED_FMT = 'm/s'
16
+ DEFAULT_LENGTH_FMT = 'm'
17
+
18
+ LengthUnits = {
19
+ 'm' => 1.0,
20
+ 'ft' => 3.2808399,
21
+ 'km' => 0.001,
22
+ 'miles' => 0.000621371192,
23
+ 'nm' => 0.000539956803
24
+ }
25
+
26
+ SpeedUnits = {
27
+ 'm/s' => 1.0,
28
+ 'knots' => 1.9438612860586,
29
+ 'km/h' => 3.6,
30
+ 'mph' => 2.23693629
31
+ }
32
+
33
+ def initialize(argv)
34
+ # Command line options
35
+ @opt = {}
36
+ parse_options argv
37
+ @opt[:length] ||= DEFAULT_LENGTH # Minimum required distance
38
+ @opt[:speed_fmt] ||= DEFAULT_SPEED_FMT
39
+ @opt[:length_fmt] ||= DEFAULT_LENGTH_FMT
40
+
41
+ filename, = argv
42
+
43
+ read_gpx filename
44
+ list_distance_speeds
45
+ filter_distance_speeds
46
+ print_results
47
+ end
48
+
49
+ def parse_length(l)
50
+ LengthUnits.each do |name, factor|
51
+ m = l.match /^(\d+(.\d+)?)\s?#{name}$/i
52
+ return m[1].to_f * factor if m
53
+ end
54
+ m = l.match /^(\d+(.\d+)?)$/i
55
+ throw RuntimeError.new('Illegal length format: ' + l) unless m
56
+ m[1].to_f
57
+ end
58
+
59
+ def parse_options(argv)
60
+ OptionParser.new do |op|
61
+ op.banner = "Usage: gpsspeed [options] <input.gpx>"
62
+ op.on("-l", "--length DIST", "Minimum required length (default #{DEFAULT_LENGTH}m)",
63
+ " Accepts #{LengthUnits.keys.join ','}") do |l|
64
+ @opt[:length] = parse_length l
65
+ end
66
+ op.on("-s", "--speed-format FMT", "Select speed format (default #{DEFAULT_SPEED_FMT})",
67
+ " Accepts #{SpeedUnits.keys.join ','}") do |fmt|
68
+ @opt[:speed_fmt] = fmt
69
+ end
70
+ op.on("-f", "--length-format FMT", "Select length format (default #{DEFAULT_LENGTH_FMT})",
71
+ " Accepts #{LengthUnits.keys.join ','}") do |fmt|
72
+ @opt[:length_fmt] = fmt
73
+ end
74
+ op.on_tail("-h", "--help", "Show this message") do
75
+ puts op
76
+ exit
77
+ end
78
+ end.parse! argv
79
+ end
80
+
81
+ def read_gpx filename
82
+ throw RuntimeError.new("Please specify file name") unless filename
83
+ doc = nil
84
+ File.open filename do |f|
85
+ doc = REXML::Document.new f
86
+ end
87
+
88
+ @points = []
89
+ REXML::XPath.each doc, '//trkpt' do |trkpt|
90
+ lat = trkpt.attributes['lat']
91
+ lon = trkpt.attributes['lon']
92
+ date_time = DateTime.strptime trkpt.get_elements('time').first.text
93
+ pp = OpenStruct.new
94
+ pp.latlon = GeoUtm::LatLon.new lat.to_f, lon.to_f
95
+ pp.utm = pp.latlon.to_utm GeoUtm::Ellipsoid::lookup(:wgs84), @points.first && @points.first.utm.zone
96
+ pp.date_time = date_time
97
+ @points << pp
98
+ end
99
+ @points.sort! {|a, b| a.date_time <=> b.date_time }
100
+ # puts "Read #{@points.size} track points"
101
+ end
102
+
103
+ def list_distance_speeds
104
+ @dist_speed_list = []
105
+ (0..(@points.size - 2)).each do |i|
106
+ ((i + 1)..(@points.size - 1)).each do |j|
107
+ dist = @points[i].utm.distance_to @points[j].utm
108
+ next if dist < @opt[:length]
109
+ ds = OpenStruct.new
110
+ ds.distance = dist
111
+ ds.begin = i
112
+ ds.end = j
113
+ ds.dt = (@points[j].date_time - @points[i].date_time) * 24.0 * 60.0 * 60.0
114
+ ds.speed_ms = dist / ds.dt
115
+ @dist_speed_list << ds
116
+ break
117
+ end
118
+ end
119
+ end
120
+
121
+ def filter_distance_speeds
122
+ @dist_speed_list.sort! {|a, b| a.speed_ms <=> b.speed_ms }.reverse!
123
+ @dist_speed_list.reject! do |candidate|
124
+ intersects_previous candidate
125
+ end
126
+ end
127
+
128
+ def intersects_previous candidate
129
+ intersects = nil
130
+ @dist_speed_list[0...@dist_speed_list.index(candidate)].each do |prev|
131
+ used = prev.begin..prev.end
132
+ intersects ||= ((prev.begin..prev.end).to_a & (candidate.begin..candidate.end).to_a).any?
133
+ break if intersects
134
+ end
135
+ intersects
136
+ end
137
+
138
+ def print_results
139
+ puts '%20s%10s%10s%10s%20s%20s' %
140
+ ["Speed [#{@opt[:speed_fmt]}]", '#frm', '#to', '#n', 'time [s]', "Distance [#{@opt[:length_fmt]}]"]
141
+ (@dist_speed_list[0..39] || []).each do |ds|
142
+ puts "%20.4f%10i%10i%10i%20.2f#{length_printf_fmt(20)}" % [speed_conv(ds.speed_ms), ds.begin,
143
+ ds.end, ds.end - ds.begin + 1, ds.dt, length_conv(ds.distance)]
144
+ end
145
+ end
146
+
147
+ def speed_conv(speed)
148
+ speed * SpeedUnits[@opt[:speed_fmt]]
149
+ end
150
+
151
+ def length_conv(length)
152
+ length * LengthUnits[@opt[:length_fmt]]
153
+ end
154
+
155
+ def length_printf_fmt(width)
156
+ "%#{width}.#{-Math::log10(LengthUnits[@opt[:length_fmt]]).to_i + 1}f"
157
+ end
158
+ end
159
+ end
data/script/console ADDED
@@ -0,0 +1,10 @@
1
+ #!/usr/bin/env ruby
2
+ # File: script/console
3
+ irb = RUBY_PLATFORM =~ /(:?mswin|mingw)/ ? 'irb.bat' : 'irb'
4
+
5
+ libs = " -r irb/completion"
6
+ # Perhaps use a console_lib to store any extra methods I may want available in the cosole
7
+ # libs << " -r #{File.dirname(__FILE__) + '/../lib/console_lib/console_logger.rb'}"
8
+ libs << " -r #{File.dirname(__FILE__) + '/../lib/gpsspeed.rb'}"
9
+ puts "Loading gpsspeed gem"
10
+ exec "#{irb} #{libs} --simple-prompt"
data/script/destroy ADDED
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+ APP_ROOT = File.expand_path(File.join(File.dirname(__FILE__), '..'))
3
+
4
+ begin
5
+ require 'rubigen'
6
+ rescue LoadError
7
+ require 'rubygems'
8
+ require 'rubigen'
9
+ end
10
+ require 'rubigen/scripts/destroy'
11
+
12
+ ARGV.shift if ['--help', '-h'].include?(ARGV[0])
13
+ RubiGen::Base.use_component_sources! [:rubygems, :newgem, :newgem_theme, :test_unit]
14
+ RubiGen::Scripts::Destroy.new.run(ARGV)
data/script/generate ADDED
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+ APP_ROOT = File.expand_path(File.join(File.dirname(__FILE__), '..'))
3
+
4
+ begin
5
+ require 'rubigen'
6
+ rescue LoadError
7
+ require 'rubygems'
8
+ require 'rubigen'
9
+ end
10
+ require 'rubigen/scripts/generate'
11
+
12
+ ARGV.shift if ['--help', '-h'].include?(ARGV[0])
13
+ RubiGen::Base.use_component_sources! [:rubygems, :newgem, :newgem_theme, :test_unit]
14
+ RubiGen::Scripts::Generate.new.run(ARGV)