Gooby 0.9.0
Sign up to get free protection for your applications and to get access to all the features.
- data/README +218 -0
- data/bin/forerunner_xml_parser.rb +28 -0
- data/bin/forerunner_xml_parser.sh +16 -0
- data/bin/forerunner_xml_splitter.rb +60 -0
- data/bin/gen_gmap.rb +30 -0
- data/bin/gen_gmap.sh +19 -0
- data/bin/tests_gen.rb +13 -0
- data/data/20041113_richmond_marathon.csv +1036 -0
- data/data/20041113_richmond_marathon.xml +8663 -0
- data/data/20050305_corporate_cup_hm.csv +251 -0
- data/data/20050305_corporate_cup_hm.xml +2208 -0
- data/data/20050430_nashville_marathon.csv +1208 -0
- data/data/20050430_nashville_marathon.xml +10043 -0
- data/data/20051119_dowd_ymca_hm.csv +251 -0
- data/data/20051119_dowd_ymca_hm.xml +2210 -0
- data/data/20051124_hyatt_turkey_trot_8K.csv +321 -0
- data/data/20051124_hyatt_turkey_trot_8K.xml +2651 -0
- data/data/forerunner_2005.xml +259620 -0
- data/data/forerunner_2006.xml +190853 -0
- data/data/forerunner_2007.xml +259014 -0
- data/data/geo_data.txt +171 -0
- data/data/phx.csv +1280 -0
- data/data/phx.xml +10620 -0
- data/data/run_2007_01_01_16_38_27.xml +2020 -0
- data/data/run_2007_01_06_15_27_31.xml +2020 -0
- data/data/run_2007_01_10_12_25_47.xml +820 -0
- data/data/run_2007_01_10_22_44_54.csv +112 -0
- data/data/run_2007_01_10_22_44_54.xml +908 -0
- data/data/run_2007_01_11_10_48_45.xml +1292 -0
- data/data/run_2007_01_13_15_37_06.xml +1964 -0
- data/data/run_2007_01_14_15_46_02.xml +1368 -0
- data/data/run_2007_01_15_14_01_48.xml +1868 -0
- data/data/run_2007_01_20_16_22_05.xml +1702 -0
- data/data/run_2007_01_27_17_32_13.xml +3626 -0
- data/data/run_2007_01_28_19_14_52.xml +2538 -0
- data/data/run_2007_02_03_14_30_20.xml +2016 -0
- data/data/run_2007_02_04_18_02_30.xml +1476 -0
- data/data/run_2007_02_17_16_29_35.xml +1236 -0
- data/data/run_2007_02_19_14_44_33.xml +1816 -0
- data/data/run_2007_02_23_15_53_55.xml +36 -0
- data/data/run_2007_02_23_15_55_20.xml +1296 -0
- data/data/run_2007_02_24_15_01_35.csv +484 -0
- data/data/run_2007_02_24_15_01_35.xml +3884 -0
- data/data/test1.txt +4 -0
- data/lib/cls_counter_hash.rb +83 -0
- data/lib/cls_delim_line.rb +40 -0
- data/lib/cls_dttm.rb +84 -0
- data/lib/cls_duration.rb +87 -0
- data/lib/cls_forerunner_xml_parser.rb +183 -0
- data/lib/cls_forerunner_xml_splitter.rb +113 -0
- data/lib/cls_geo_data.rb +186 -0
- data/lib/cls_gooby_object.rb +23 -0
- data/lib/cls_google_map_generator.rb +368 -0
- data/lib/cls_history.rb +38 -0
- data/lib/cls_lap.rb +27 -0
- data/lib/cls_line.rb +78 -0
- data/lib/cls_options.rb +74 -0
- data/lib/cls_position.rb +49 -0
- data/lib/cls_run.rb +199 -0
- data/lib/cls_simple_xml_parser.rb +46 -0
- data/lib/cls_test_regen.rb +187 -0
- data/lib/cls_track.rb +52 -0
- data/lib/cls_trackpoint.rb +205 -0
- data/lib/mod_introspect.rb +33 -0
- data/lib/mod_io.rb +65 -0
- data/lib/mod_project_info.rb +81 -0
- data/lib/mod_string.rb +26 -0
- data/lib/mod_test_helper.rb +22 -0
- data/samples/20041113_richmond_marathon.html +532 -0
- data/samples/20050305_corporate_cup_hm.html +448 -0
- data/samples/20050430_nashville_marathon.html +530 -0
- data/samples/gps_point_capture.html +54 -0
- data/samples/phoenix_marathon.html +542 -0
- data/samples/run_2007_01_10_22_44_54.html +146 -0
- data/samples/run_2007_02_24_15_01_35.html +298 -0
- data/tests/tst_cls_counter_hash.rb +105 -0
- data/tests/tst_cls_delim_line.rb +72 -0
- data/tests/tst_cls_dttm.rb +129 -0
- data/tests/tst_cls_duration.rb +49 -0
- data/tests/tst_cls_forerunner_xml_parser.rb +68 -0
- data/tests/tst_cls_geo_data.rb +69 -0
- data/tests/tst_cls_gooby_object.rb +24 -0
- data/tests/tst_cls_google_map_generator.rb +107 -0
- data/tests/tst_cls_history.rb +44 -0
- data/tests/tst_cls_lap.rb +36 -0
- data/tests/tst_cls_line.rb +108 -0
- data/tests/tst_cls_options.rb +77 -0
- data/tests/tst_cls_position.rb +64 -0
- data/tests/tst_cls_run.rb +140 -0
- data/tests/tst_cls_simple_xml_parser.rb +48 -0
- data/tests/tst_cls_track.rb +68 -0
- data/tests/tst_cls_trackpoint.rb +143 -0
- data/tests/tst_gooby.rb +28 -0
- data/tests/tst_mod_introspect.rb +30 -0
- data/tests/tst_mod_io.rb +51 -0
- data/tests/tst_mod_project_info.rb +77 -0
- data/tests/tst_mod_string.rb +56 -0
- metadata +142 -0
data/lib/cls_history.rb
ADDED
@@ -0,0 +1,38 @@
|
|
1
|
+
=begin rdoc
|
2
|
+
|
3
|
+
Instances of this class represent a <History> aggregate object from a
|
4
|
+
Forerunner XML file.
|
5
|
+
|
6
|
+
Gooby - Copyright 2007 by Chris Joakim.
|
7
|
+
Gooby is available under GNU General Public License (GPL) license.
|
8
|
+
|
9
|
+
=end
|
10
|
+
|
11
|
+
module Gooby
|
12
|
+
|
13
|
+
class History < GoobyObject
|
14
|
+
|
15
|
+
attr_reader :runs
|
16
|
+
|
17
|
+
def initialize
|
18
|
+
@runs = Array.new
|
19
|
+
end
|
20
|
+
|
21
|
+
# Adds a Run during XML parsing.
|
22
|
+
def add_run(run)
|
23
|
+
@runs.push(run)
|
24
|
+
end
|
25
|
+
|
26
|
+
def to_s
|
27
|
+
return "Hist: runs: #{@runs.size}"
|
28
|
+
end
|
29
|
+
|
30
|
+
def print_string
|
31
|
+
s = "History: run count=#{@runs.size} \n"
|
32
|
+
runs.each { | run | s << run.print_string }
|
33
|
+
s
|
34
|
+
end
|
35
|
+
|
36
|
+
end
|
37
|
+
|
38
|
+
end
|
data/lib/cls_lap.rb
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
=begin rdoc
|
2
|
+
|
3
|
+
Instances of this class represent a <Lap> aggregate object from a
|
4
|
+
Forerunner XML file.
|
5
|
+
|
6
|
+
Gooby - Copyright 2007 by Chris Joakim.
|
7
|
+
Gooby is available under GNU General Public License (GPL) license.
|
8
|
+
|
9
|
+
=end
|
10
|
+
|
11
|
+
module Gooby
|
12
|
+
|
13
|
+
class Lap < GoobyObject
|
14
|
+
|
15
|
+
attr_accessor :number, :startTime, :duration, :length, :beginPosition, :endPosition
|
16
|
+
|
17
|
+
def initialize(num)
|
18
|
+
@number = num
|
19
|
+
end
|
20
|
+
|
21
|
+
def to_s
|
22
|
+
return "Lap: num: #{@number} start: #{@startTime} dur: #{@duration} len: #{@length} begin: #{@beginPosition.to_s} end: #{@endPosition.to_s}"
|
23
|
+
end
|
24
|
+
|
25
|
+
end
|
26
|
+
|
27
|
+
end
|
data/lib/cls_line.rb
ADDED
@@ -0,0 +1,78 @@
|
|
1
|
+
=begin rdoc
|
2
|
+
|
3
|
+
Gooby - Copyright 2007 by Chris Joakim.
|
4
|
+
Gooby is available under GNU General Public License (GPL) license.
|
5
|
+
|
6
|
+
=end
|
7
|
+
|
8
|
+
module Gooby
|
9
|
+
|
10
|
+
class Line < GoobyObject
|
11
|
+
|
12
|
+
attr_accessor :raw_data, :tokens
|
13
|
+
|
14
|
+
def initialize(raw='', delim=nil, strip=false)
|
15
|
+
if strip
|
16
|
+
@raw_data = raw.strip
|
17
|
+
else
|
18
|
+
@raw_data = raw
|
19
|
+
end
|
20
|
+
|
21
|
+
@tokens = tokenize(@raw_data, delim, strip=false)
|
22
|
+
end
|
23
|
+
|
24
|
+
public
|
25
|
+
|
26
|
+
def token(idx)
|
27
|
+
@tokens[idx]
|
28
|
+
end
|
29
|
+
|
30
|
+
def token_count
|
31
|
+
@tokens.size
|
32
|
+
end
|
33
|
+
|
34
|
+
def token_idx_equals(idx, value)
|
35
|
+
if idx < token_count
|
36
|
+
if @tokens[idx] == value
|
37
|
+
return true
|
38
|
+
end
|
39
|
+
end
|
40
|
+
false
|
41
|
+
end
|
42
|
+
|
43
|
+
def match(pattern)
|
44
|
+
@raw_data.match(pattern)
|
45
|
+
end
|
46
|
+
|
47
|
+
def is_comment
|
48
|
+
s = @raw_data.strip
|
49
|
+
(s.match('^#')) ? true : false
|
50
|
+
end
|
51
|
+
|
52
|
+
def is_populated_non_comment
|
53
|
+
s = @raw_data.strip
|
54
|
+
if s.size == 0
|
55
|
+
return false
|
56
|
+
end
|
57
|
+
if is_comment
|
58
|
+
return false
|
59
|
+
end
|
60
|
+
return true
|
61
|
+
end
|
62
|
+
|
63
|
+
def concatinate_tokens(start_idx = 0)
|
64
|
+
s = ''
|
65
|
+
idx = -1
|
66
|
+
@tokens.each { |tok|
|
67
|
+
idx = idx + 1
|
68
|
+
if idx >= start_idx
|
69
|
+
s << tok
|
70
|
+
s << ' '
|
71
|
+
end
|
72
|
+
}
|
73
|
+
s.strip!
|
74
|
+
s
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
end
|
data/lib/cls_options.rb
ADDED
@@ -0,0 +1,74 @@
|
|
1
|
+
=begin rdoc
|
2
|
+
|
3
|
+
Gooby - Copyright 2007 by Chris Joakim.
|
4
|
+
Gooby is available under GNU General Public License (GPL) license.
|
5
|
+
|
6
|
+
=end
|
7
|
+
|
8
|
+
module Gooby
|
9
|
+
|
10
|
+
class Options < GoobyObject
|
11
|
+
|
12
|
+
attr_reader :yamlFilename, :options
|
13
|
+
|
14
|
+
def initialize(filename) # Constructor.
|
15
|
+
filename ? @yamlFilename = filename : @yamlFilename = 'gooby_options.yaml'
|
16
|
+
loadFile()
|
17
|
+
end
|
18
|
+
|
19
|
+
public
|
20
|
+
|
21
|
+
# Load the @yamlFilename
|
22
|
+
def loadFile
|
23
|
+
File.open("#{@yamlFilename}") { |fn|
|
24
|
+
@options = YAML::load(fn)
|
25
|
+
}
|
26
|
+
end
|
27
|
+
|
28
|
+
def get(name)
|
29
|
+
if name == nil
|
30
|
+
return ''
|
31
|
+
end
|
32
|
+
s = @options["#{name}"]
|
33
|
+
|
34
|
+
# Provide "sensible defaults".
|
35
|
+
if s == nil
|
36
|
+
if (name == '')
|
37
|
+
return ''
|
38
|
+
elsif (name == 'gmap_first_tkpt_number')
|
39
|
+
return 1
|
40
|
+
elsif (name == 'gmap_last_tkpt_number')
|
41
|
+
return 5000
|
42
|
+
elsif (name == 'gmap_map_element_id')
|
43
|
+
return 'map'
|
44
|
+
elsif (name == 'gmap_height')
|
45
|
+
return '600'
|
46
|
+
elsif (name == 'gmap_key')
|
47
|
+
return 'enter your Google Map Key here'
|
48
|
+
elsif (name == 'gmap_type_control')
|
49
|
+
return true
|
50
|
+
elsif (name == 'gmap_approx_max_points')
|
51
|
+
return '200'
|
52
|
+
elsif (name == 'gmap_gen_comments')
|
53
|
+
return true
|
54
|
+
elsif (name == 'gmap_size_control')
|
55
|
+
return nil
|
56
|
+
elsif (name == 'gmap_type')
|
57
|
+
return 'G_NORMAL_MAP'
|
58
|
+
elsif (name == 'gmap_zoom_level')
|
59
|
+
return 5
|
60
|
+
else
|
61
|
+
return ''
|
62
|
+
end
|
63
|
+
end
|
64
|
+
s
|
65
|
+
end
|
66
|
+
|
67
|
+
# Return a String containing yaml filename and entry count.
|
68
|
+
def to_s
|
69
|
+
return "Options: filename: #{@yamlFilename} entries: #{@options.size}"
|
70
|
+
end
|
71
|
+
|
72
|
+
end
|
73
|
+
|
74
|
+
end
|
data/lib/cls_position.rb
ADDED
@@ -0,0 +1,49 @@
|
|
1
|
+
=begin rdoc
|
2
|
+
|
3
|
+
Instances of this class represent a <Position> aggregate object from a
|
4
|
+
Forerunner XML file. Each contains a latitude and longitude.
|
5
|
+
Instances within a Trackpoint will also contain an altitude.
|
6
|
+
|
7
|
+
Gooby - Copyright 2007 by Chris Joakim.
|
8
|
+
Gooby is available under GNU General Public License (GPL) license.
|
9
|
+
|
10
|
+
=end
|
11
|
+
|
12
|
+
module Gooby
|
13
|
+
|
14
|
+
class Position < GoobyObject
|
15
|
+
|
16
|
+
attr_accessor :latitude, :longitude, :altitude, :note
|
17
|
+
|
18
|
+
def initialize(lat, lng, alt='0', note='')
|
19
|
+
@latitude = lat.to_s
|
20
|
+
@longitude = lng.to_s
|
21
|
+
@altitude = alt.to_s
|
22
|
+
@note = note.to_s
|
23
|
+
end
|
24
|
+
|
25
|
+
public
|
26
|
+
|
27
|
+
def to_s
|
28
|
+
return "lat: #{@latitude} lng: #{@longitude} alt: #{@altitude} note: #{@note}"
|
29
|
+
end
|
30
|
+
|
31
|
+
def to_csv
|
32
|
+
return "#{@latitude} | #{@longitude} | #{@altitude}"
|
33
|
+
end
|
34
|
+
|
35
|
+
def latitude_as_float
|
36
|
+
@latitude ? @latitude.to_f : invalid_latitude
|
37
|
+
end
|
38
|
+
|
39
|
+
def longitude_as_float
|
40
|
+
@longitude ? @longitude.to_f : invalid_longitude
|
41
|
+
end
|
42
|
+
|
43
|
+
def altitude_as_float
|
44
|
+
@altitude ? @altitude.to_f : invalid_altitude
|
45
|
+
end
|
46
|
+
|
47
|
+
end
|
48
|
+
|
49
|
+
end
|
data/lib/cls_run.rb
ADDED
@@ -0,0 +1,199 @@
|
|
1
|
+
=begin rdoc
|
2
|
+
|
3
|
+
Instances of this class represent a <Run> aggregate object from a
|
4
|
+
Forerunner XML file.
|
5
|
+
|
6
|
+
Additionally, there is distance, pace, and Google Map generation logic
|
7
|
+
in this class.
|
8
|
+
|
9
|
+
Gooby - Copyright 2007 by Chris Joakim.
|
10
|
+
Gooby is available under GNU General Public License (GPL) license.
|
11
|
+
|
12
|
+
=end
|
13
|
+
|
14
|
+
module Gooby
|
15
|
+
|
16
|
+
class Run < GoobyObject
|
17
|
+
|
18
|
+
attr_accessor :number, :descr, :notes, :tracks, :tkpts, :laps, :distance
|
19
|
+
|
20
|
+
def initialize(number=0, descr='')
|
21
|
+
@number = number
|
22
|
+
@descr = descr
|
23
|
+
@notes = ''
|
24
|
+
@tracks = Array.new
|
25
|
+
@tkpts = Array.new
|
26
|
+
@laps = Array.new
|
27
|
+
@distance = 0
|
28
|
+
@options = Hash.new
|
29
|
+
@logProgress = true
|
30
|
+
@finished = false
|
31
|
+
end
|
32
|
+
|
33
|
+
public
|
34
|
+
|
35
|
+
# This method is invoked at end-of-parsing.
|
36
|
+
def finish()
|
37
|
+
@logProgress = false
|
38
|
+
unless @finished
|
39
|
+
@tracks.each { |trk|
|
40
|
+
trk.trackpoints().each { |tkpt|
|
41
|
+
tkpt.runNumber = @number
|
42
|
+
@tkpts.push(tkpt)
|
43
|
+
}
|
44
|
+
}
|
45
|
+
compute_distance_and_pace
|
46
|
+
compute_splits
|
47
|
+
@finished = true
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
public
|
52
|
+
|
53
|
+
def add_track(trk)
|
54
|
+
if trk != nil
|
55
|
+
@tracks.push(trk)
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
def trackpoint_count()
|
60
|
+
@tkpts.size()
|
61
|
+
end
|
62
|
+
|
63
|
+
def add_lap(lap)
|
64
|
+
@laps.push(lap)
|
65
|
+
end
|
66
|
+
|
67
|
+
def lapCount()
|
68
|
+
@laps.size
|
69
|
+
end
|
70
|
+
|
71
|
+
def start_dttm()
|
72
|
+
count = 0
|
73
|
+
@tracks.each { |trk|
|
74
|
+
trk.trackpoints().each { |tkpt|
|
75
|
+
return tkpt.dttm()
|
76
|
+
}
|
77
|
+
}
|
78
|
+
return nil
|
79
|
+
end
|
80
|
+
|
81
|
+
def end_dttm()
|
82
|
+
lastOne = nil
|
83
|
+
@tracks.each { |trk|
|
84
|
+
trk.trackpoints().each { |tkpt|
|
85
|
+
lastOne = tkpt.dttm()
|
86
|
+
}
|
87
|
+
}
|
88
|
+
lastOne
|
89
|
+
end
|
90
|
+
|
91
|
+
def duration()
|
92
|
+
first = start_dttm()
|
93
|
+
last = end_dttm()
|
94
|
+
if first
|
95
|
+
if last
|
96
|
+
return last.hhmmss_diff(first)
|
97
|
+
end
|
98
|
+
end
|
99
|
+
return "??:??:??"
|
100
|
+
end
|
101
|
+
|
102
|
+
def start_yyyy_mm_dd
|
103
|
+
if start_dttm()
|
104
|
+
start_dttm().yyyy_mm_dd()
|
105
|
+
else
|
106
|
+
""
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
def start_hh_mm_ss
|
111
|
+
if start_dttm()
|
112
|
+
start_dttm().hh_mm_ss()
|
113
|
+
else
|
114
|
+
""
|
115
|
+
end
|
116
|
+
end
|
117
|
+
|
118
|
+
def end_hh_mm_ss
|
119
|
+
if end_dttm()
|
120
|
+
end_dttm().hh_mm_ss()
|
121
|
+
else
|
122
|
+
""
|
123
|
+
end
|
124
|
+
end
|
125
|
+
|
126
|
+
def to_s
|
127
|
+
finish() unless @finished
|
128
|
+
s = "Run: #{@number} date: #{start_yyyy_mm_dd} distance: #{distance} duration: #{duration} "
|
129
|
+
s << " tracks: #{@tracks.size} tkpts: #{trackpoint_count} laps: #{lapCount} "
|
130
|
+
s << " notes: #{@notes} "
|
131
|
+
s
|
132
|
+
end
|
133
|
+
|
134
|
+
def print_string
|
135
|
+
finish() unless @finished
|
136
|
+
"Run number=#{@number} tracks=#{@tracks.size} tkpts=#{@tkpts.size} laps=#{@laps.size} distance=#{@distance} "
|
137
|
+
end
|
138
|
+
|
139
|
+
def put_csv()
|
140
|
+
finish() unless @finished
|
141
|
+
puts "#{@number}|#{}|#{start_yyyy_mm_dd()}|#{start_hh_mm_ss()}|#{end_hh_mm_ss}|#{duration()}|#{@distance}|#{@tracks.size}|#{trackpoint_count()}|#{lapCount}|#{@notes.strip}"
|
142
|
+
end
|
143
|
+
|
144
|
+
def put_tkpt_csv(with_header_comment=false)
|
145
|
+
finish() unless @finished
|
146
|
+
if with_header_comment
|
147
|
+
puts "# Run: #{@number} date: #{start_yyyy_mm_dd} dist: #{distance} dur: #{duration} trks: #{@tracks.size} tkpts: #{trackpoint_count} laps: #{lapCount} "
|
148
|
+
end
|
149
|
+
@tkpts.each { | tkpt | puts tkpt.to_csv }
|
150
|
+
end
|
151
|
+
|
152
|
+
def put_laps
|
153
|
+
@laps.each { | lap | puts lap.to_s }
|
154
|
+
end
|
155
|
+
|
156
|
+
private
|
157
|
+
|
158
|
+
def compute_distance_and_pace
|
159
|
+
cumulative_dist = 0.to_f;
|
160
|
+
curr_index = -1
|
161
|
+
prev_tkpt = nil
|
162
|
+
start_dttm = nil
|
163
|
+
@tkpts.each { | tkpt |
|
164
|
+
curr_index = curr_index + 1
|
165
|
+
if curr_index == 0
|
166
|
+
start_dttm = tkpt.dttm()
|
167
|
+
prev_tkpt = tkpt
|
168
|
+
else
|
169
|
+
cumulative_dist = tkpt.compute_distance_and_pace(curr_index, start_dttm, cumulative_dist, prev_tkpt, 'M')
|
170
|
+
prev_tkpt = tkpt
|
171
|
+
end
|
172
|
+
}
|
173
|
+
@distance = cumulative_dist
|
174
|
+
end
|
175
|
+
|
176
|
+
def compute_splits
|
177
|
+
nextSplitDist = 1.00
|
178
|
+
prevSplitTkpt = nil
|
179
|
+
loop1Count = 0;
|
180
|
+
@tkpts.each { |tkpt|
|
181
|
+
loop1Count = loop1Count + 1
|
182
|
+
if tkpt.cumulativeDistance() >= nextSplitDist
|
183
|
+
tkpt.set_split(0 + nextSplitDist, prevSplitTkpt)
|
184
|
+
nextSplitDist = nextSplitDist + 1.00
|
185
|
+
prevSplitTkpt = tkpt
|
186
|
+
end
|
187
|
+
}
|
188
|
+
# set first and last booleans
|
189
|
+
count = 0
|
190
|
+
@tkpts.each { |tkpt|
|
191
|
+
count = count + 1
|
192
|
+
tkpt.first = true if count == 1
|
193
|
+
tkpt.last = true if count == loop1Count
|
194
|
+
}
|
195
|
+
end
|
196
|
+
|
197
|
+
end
|
198
|
+
|
199
|
+
end
|