gooby 1.1.0 → 1.2.0
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/README +200 -35
- data/bin/code_scan.rb +1 -3
- data/bin/gooby_been_there.rb +12 -14
- data/bin/gooby_config.rb +11 -3
- data/bin/gooby_csv_validation.rb +50 -0
- data/bin/gooby_first_trackpoints_as_poi.rb +31 -0
- data/bin/gooby_gen_gmap.rb +7 -3
- data/bin/gooby_parser.rb +7 -5
- data/bin/gooby_splitter.rb +7 -4
- data/bin/gooby_version.rb +7 -3
- data/bin/run_all.sh +12 -2
- data/bin/run_been_there.sh +4 -1
- data/bin/run_config.sh +12 -0
- data/bin/run_csv_validation.sh +15 -0
- data/bin/run_db_gen.sh +1 -1
- data/bin/run_db_load.sh +1 -1
- data/bin/run_first_trackpoints_as_poi.sh +16 -0
- data/bin/run_gen_gmaps.sh +7 -6
- data/bin/run_parse_full.sh +45 -0
- data/bin/run_parse_samples.sh +21 -0
- data/bin/run_split.sh +5 -4
- data/bin/run_version.sh +12 -0
- data/config/gooby_config.yaml +130 -131
- data/data/20050305_corporate_cup_hm.csv +251 -251
- data/data/20050430_nashville_marathon_km.csv +1208 -0
- data/data/20060115_phoenix_marathon.csv +1280 -1280
- data/data/20070101_davidson_11m.csv +251 -0
- data/data/{davidson_11m_20070101.xml → 20070101_davidson_11m.xml} +0 -0
- data/data/{davidson_5K_20070505.xml → 20070505_davidson_5k.xml} +0 -0
- data/data/20070505_davidson_5k_km.csv +286 -0
- data/data/hrm1.csv +5 -0
- data/lib/gooby.rb +27 -3144
- data/lib/gooby_code_scanner.rb +288 -0
- data/lib/gooby_command.rb +210 -0
- data/lib/gooby_configuration.rb +123 -0
- data/lib/gooby_counter_hash.rb +95 -0
- data/lib/gooby_course.rb +117 -0
- data/lib/gooby_csv_point.rb +71 -0
- data/lib/gooby_csv_reader.rb +71 -0
- data/lib/gooby_csv_run.rb +28 -0
- data/lib/gooby_delim_line.rb +42 -0
- data/lib/gooby_dttm.rb +87 -0
- data/lib/gooby_duration.rb +86 -0
- data/lib/gooby_forerunner_xml_parser.rb +191 -0
- data/lib/gooby_forerunner_xml_splitter.rb +115 -0
- data/lib/gooby_google_map_generator.rb +385 -0
- data/lib/gooby_history.rb +41 -0
- data/lib/gooby_kernel.rb +163 -0
- data/lib/gooby_lap.rb +30 -0
- data/lib/gooby_line.rb +80 -0
- data/lib/gooby_object.rb +22 -0
- data/lib/gooby_point.rb +172 -0
- data/lib/gooby_run.rb +213 -0
- data/lib/gooby_simple_xml_parser.rb +50 -0
- data/lib/gooby_test_helper.rb +23 -0
- data/lib/gooby_track.rb +47 -0
- data/lib/gooby_track_point.rb +229 -0
- data/lib/gooby_training_center_xml_parser.rb +224 -0
- data/lib/gooby_training_center_xml_splitter.rb +116 -0
- data/lib/split_code.sh +29 -0
- data/samples/20050305_corporate_cup_hm.html +269 -269
- data/samples/20050430_nashville_marathon.html +1410 -1266
- data/samples/20060115_phoenix_marathon.html +1311 -1311
- data/samples/{davidson_11m_20070101.html → 20070101_davidson_11m.html} +267 -267
- data/samples/20070505_davidson_5k.html +413 -0
- data/samples/been_there.txt +52 -704
- data/samples/hrm1.html +87 -0
- data/sql/gooby.ddl +20 -16
- data/sql/gooby_load.dml +36 -9
- metadata +48 -14
- data/bin/example_usage.txt +0 -55
- data/bin/run_parse.sh +0 -43
- data/bin/run_parse_named.sh +0 -19
- data/data/20050430_nashville_marathon.csv +0 -1208
- data/data/davidson_11m_20070101.csv +0 -251
- data/data/davidson_5K_20070505.csv +0 -286
- data/data/test1.txt +0 -4
- data/samples/davidson_5K_20070505.html +0 -395
@@ -0,0 +1,50 @@
|
|
1
|
+
=begin
|
2
|
+
|
3
|
+
Gooby = Google APIs + Ruby
|
4
|
+
Gooby - Copyright 2007 by Chris Joakim.
|
5
|
+
Gooby is available under GNU General Public License (GPL) license.
|
6
|
+
|
7
|
+
=end
|
8
|
+
|
9
|
+
module Gooby
|
10
|
+
|
11
|
+
=begin rdoc
|
12
|
+
Sample implementation of a REXML::StreamListener SAX parser.
|
13
|
+
This class isn't actually used in Gooby, but is retained for future use.
|
14
|
+
=end
|
15
|
+
|
16
|
+
class SimpleXmlParser
|
17
|
+
|
18
|
+
include REXML::StreamListener
|
19
|
+
|
20
|
+
attr_accessor :tag_count, :watched_tags
|
21
|
+
|
22
|
+
def initialize
|
23
|
+
@tag_count = 0
|
24
|
+
@counter_hash = CounterHash.new
|
25
|
+
end
|
26
|
+
|
27
|
+
public
|
28
|
+
|
29
|
+
# SAX API method. Increments the tagname in the counter hash.
|
30
|
+
def tag_start(tag_name, attrs)
|
31
|
+
@tag_count = @tag_count + 1
|
32
|
+
@counter_hash.increment(tag_name)
|
33
|
+
end
|
34
|
+
|
35
|
+
# SAX API method. No impl.
|
36
|
+
def tag_end(tagname)
|
37
|
+
end
|
38
|
+
|
39
|
+
# SAX API method. No impl.
|
40
|
+
def text(txt)
|
41
|
+
end
|
42
|
+
|
43
|
+
# Prints the state of this object (the counter hash).
|
44
|
+
def dump
|
45
|
+
puts @counter_hash.to_s
|
46
|
+
end
|
47
|
+
|
48
|
+
end
|
49
|
+
|
50
|
+
end # end of module
|
@@ -0,0 +1,23 @@
|
|
1
|
+
=begin
|
2
|
+
|
3
|
+
Gooby = Google APIs + Ruby
|
4
|
+
Gooby - Copyright 2007 by Chris Joakim.
|
5
|
+
Gooby is available under GNU General Public License (GPL) license.
|
6
|
+
|
7
|
+
=end
|
8
|
+
|
9
|
+
module Gooby
|
10
|
+
|
11
|
+
module TestHelper
|
12
|
+
|
13
|
+
def setup
|
14
|
+
puts "test: #{name}"
|
15
|
+
end
|
16
|
+
|
17
|
+
def teardown
|
18
|
+
@debug = false
|
19
|
+
end
|
20
|
+
|
21
|
+
end
|
22
|
+
|
23
|
+
end # end of module
|
data/lib/gooby_track.rb
ADDED
@@ -0,0 +1,47 @@
|
|
1
|
+
=begin
|
2
|
+
|
3
|
+
Gooby = Google APIs + Ruby
|
4
|
+
Gooby - Copyright 2007 by Chris Joakim.
|
5
|
+
Gooby is available under GNU General Public License (GPL) license.
|
6
|
+
|
7
|
+
=end
|
8
|
+
|
9
|
+
module Gooby
|
10
|
+
|
11
|
+
=begin rdoc
|
12
|
+
Instances of this class represent a <Track> aggregate object from a Forerunner
|
13
|
+
XML file. Note that a <Run> may contain more than one <Track> aggregates.
|
14
|
+
=end
|
15
|
+
|
16
|
+
class Track < GoobyObject
|
17
|
+
|
18
|
+
attr_reader :number, :descr, :trackpoints
|
19
|
+
|
20
|
+
def initialize(num=0, descr='')
|
21
|
+
@number = num
|
22
|
+
@descr = descr
|
23
|
+
@trackpoints = Array.new
|
24
|
+
end
|
25
|
+
|
26
|
+
public
|
27
|
+
|
28
|
+
def add_trackpoint(tkpt)
|
29
|
+
@trackpoints.push(tkpt)
|
30
|
+
end
|
31
|
+
|
32
|
+
def size
|
33
|
+
@trackpoints.size
|
34
|
+
end
|
35
|
+
|
36
|
+
def to_s
|
37
|
+
return "Trk: #{@descr} tkpts: #{size}"
|
38
|
+
end
|
39
|
+
|
40
|
+
def dump
|
41
|
+
puts "Track: '#{@descr}' tkpts: #{size}"
|
42
|
+
@trackpoints.each { |tkpt| puts tkpt.to_csv }
|
43
|
+
end
|
44
|
+
|
45
|
+
end
|
46
|
+
|
47
|
+
end # end of module
|
@@ -0,0 +1,229 @@
|
|
1
|
+
=begin
|
2
|
+
|
3
|
+
Gooby = Google APIs + Ruby
|
4
|
+
Gooby - Copyright 2007 by Chris Joakim.
|
5
|
+
Gooby is available under GNU General Public License (GPL) license.
|
6
|
+
|
7
|
+
=end
|
8
|
+
|
9
|
+
module Gooby
|
10
|
+
|
11
|
+
class Trackpoint < Point
|
12
|
+
|
13
|
+
attr_accessor :first, :last, :number, :run_number, :dttm, :prev_tkpt, :lap_number, :lap_seq, :lap_distance, :lap_elapsed
|
14
|
+
attr_accessor :cumulative_distance, :cumulative_pace, :incremental_distance, :split, :prev_split
|
15
|
+
attr_accessor :first, :last, :run_id, :run_number
|
16
|
+
attr_accessor :run_start_dttm
|
17
|
+
|
18
|
+
def initialize(num, lat, lng, alt, hb, time_string, uom, auxInfoHash=Hash.new(''))
|
19
|
+
@number = num
|
20
|
+
@run_number = 0
|
21
|
+
@auxInfoHash = auxInfoHash
|
22
|
+
@lap_seq = 1
|
23
|
+
@lap_distance = 0
|
24
|
+
lap_num = @auxInfoHash['lap_number']
|
25
|
+
if (lap_num && lap_num.size > 0)
|
26
|
+
@lap_number = lap_num.to_i
|
27
|
+
else
|
28
|
+
@lap_number = 0
|
29
|
+
end
|
30
|
+
# initialize superclass variables:
|
31
|
+
@latitude = lat.to_s
|
32
|
+
@longitude = lng.to_s
|
33
|
+
@altitude = alt.to_f
|
34
|
+
@uom = uom
|
35
|
+
@altitude = @altitude * 3.2736 if (@uom == 'm')
|
36
|
+
@heartbeat = hb.to_s
|
37
|
+
if ((@heartbeat == nil) || (@heartbeat == ''))
|
38
|
+
@heartbeat = -1
|
39
|
+
end
|
40
|
+
@note = note.to_s
|
41
|
+
@dttm = DtTm.new(time_string)
|
42
|
+
@first = false
|
43
|
+
@last = false
|
44
|
+
@prev_tkpt = nil
|
45
|
+
@cumulative_distance, @incremental_distance, @split = 0.0, 0.0, 0.0
|
46
|
+
@cumulative_pace = ""
|
47
|
+
end
|
48
|
+
|
49
|
+
public
|
50
|
+
|
51
|
+
def point
|
52
|
+
Point.new(@latitude, @longitude, @altitude, @note)
|
53
|
+
end
|
54
|
+
|
55
|
+
def position
|
56
|
+
Point.new(@latitude, @longitude, @altitude, @note)
|
57
|
+
end
|
58
|
+
|
59
|
+
def to_s
|
60
|
+
"Tkpt: #{@number} #{super.to_s} date: #{@dttm.to_s} cdist: #{@cumulative_distance}"
|
61
|
+
end
|
62
|
+
|
63
|
+
def to_csv(prev_tkpt=nil)
|
64
|
+
first_lap_start_time_s = @auxInfoHash['first_lap_start_time']
|
65
|
+
curr_lap_start_time_s = @auxInfoHash['curr_lap_start_time']
|
66
|
+
lap_elapsed = ''
|
67
|
+
total_elapsed = ''
|
68
|
+
|
69
|
+
if (first_lap_start_time_s && (first_lap_start_time_s.size > 0) &&
|
70
|
+
curr_lap_start_time_s && (curr_lap_start_time_s.size > 0)) # garmin205 & 305
|
71
|
+
first_lap_start_time = DtTm.new(first_lap_start_time_s)
|
72
|
+
first_lap_start_time = @run_start_dttm
|
73
|
+
curr_lap_start_time = DtTm.new(curr_lap_start_time_s)
|
74
|
+
lap_elapsed = @dttm.hhmmss_diff(curr_lap_start_time)
|
75
|
+
total_elapsed = @dttm.hhmmss_diff(first_lap_start_time)
|
76
|
+
else # garmin 201
|
77
|
+
total_elapsed = @dttm.hhmmss_diff(@run_start_dttm)
|
78
|
+
lap_elapsed = total_elapsed
|
79
|
+
end
|
80
|
+
|
81
|
+
delim = csv_delim
|
82
|
+
csv = "#{@run_id}.#{@number}" # <-- primary key
|
83
|
+
csv << "#{delim}#{@run_id}"
|
84
|
+
csv << "#{delim}#{@dttm.yyyy_mm_dd_hh_mm_ss('|')}"
|
85
|
+
csv << "#{delim}#{@number}"
|
86
|
+
csv << "#{delim}#{position.to_csv}"
|
87
|
+
csv << "#{delim}#{@heartbeat}"
|
88
|
+
csv << "#{delim}#{@cumulative_distance}"
|
89
|
+
csv << "#{delim}#{uom}"
|
90
|
+
csv << "#{delim}#{total_elapsed}"
|
91
|
+
csv << "#{delim}#{@lap_seq}"
|
92
|
+
csv << "#{delim}#{@lap_distance}"
|
93
|
+
csv << "#{delim}#{lap_elapsed}"
|
94
|
+
csv
|
95
|
+
end
|
96
|
+
|
97
|
+
def self.csv_header
|
98
|
+
"#cols: primary_key|run_id|date|time|tkpt_num|latitude|longitude|altitude|heartbeat|run_distance|uom|run_elapsed|lap_tkpt_number|lap_distance|lap_elapsed"
|
99
|
+
end
|
100
|
+
|
101
|
+
def to_geo_s
|
102
|
+
ss = position.to_csv
|
103
|
+
"Tkpt: #{@number} | #{ss} | #{@descr}"
|
104
|
+
end
|
105
|
+
|
106
|
+
def compute_distance_and_pace(curr_index, start_dttm, prev_cumulative_dist, prev_trackpoint)
|
107
|
+
@prev_tkpt = prev_trackpoint
|
108
|
+
@cumulative_distance = prev_cumulative_dist.to_f
|
109
|
+
@run_start_dttm = start_dttm
|
110
|
+
|
111
|
+
if @prev_tkpt
|
112
|
+
@incremental_distance = proximity(@prev_tkpt, @uom)
|
113
|
+
if (!@incremental_distance.nan?)
|
114
|
+
@cumulative_distance = @cumulative_distance + @incremental_distance.to_f
|
115
|
+
if (@lap_number == prev_trackpoint.lap_number)
|
116
|
+
@lap_seq = prev_trackpoint.lap_seq + 1
|
117
|
+
@lap_distance = prev_trackpoint.lap_distance + @incremental_distance
|
118
|
+
else
|
119
|
+
@lap_seq = 1
|
120
|
+
@lap_distance = @incremental_distance
|
121
|
+
end
|
122
|
+
end
|
123
|
+
compute_cumulative_pace(start_dttm)
|
124
|
+
@cumulative_distance
|
125
|
+
else
|
126
|
+
@lap_seq = 1
|
127
|
+
0
|
128
|
+
end
|
129
|
+
end
|
130
|
+
|
131
|
+
def compute_cumulative_pace(start_dttm)
|
132
|
+
if @cumulative_distance > 0
|
133
|
+
secsDiff = @dttm.seconds_diff(start_dttm)
|
134
|
+
secsMile = ((secsDiff.to_f) / (@cumulative_distance.to_f))
|
135
|
+
minsMile = (secsMile / 60)
|
136
|
+
wholeMins = minsMile.floor
|
137
|
+
fractMins = minsMile - (wholeMins.to_f)
|
138
|
+
fractSecs = fractMins * 60
|
139
|
+
secsStr = fractSecs.to_s
|
140
|
+
tokens = secsStr.split('.')
|
141
|
+
whole, fract = '', ''
|
142
|
+
if tokens.size > 1
|
143
|
+
whole = tokens[0]
|
144
|
+
fract = tokens[1]
|
145
|
+
fract = fract[0,3] if fract.size > 3
|
146
|
+
if (whole.to_f < 10)
|
147
|
+
secsStr = "0#{whole}.#{fract}"
|
148
|
+
else
|
149
|
+
secsStr = "#{whole}.#{fract}"
|
150
|
+
end
|
151
|
+
end
|
152
|
+
#s1 = " | #{secsDiff} #{secsMile} #{minsMile} #{wholeMins} #{fractMins} #{fractSecs} #{whole} #{fract} #{@cumulative_distance} "
|
153
|
+
s2 = sprintf("%d:%5s", minsMile, secsStr)
|
154
|
+
@cumulative_pace = "#{s2} per #{@uom}"
|
155
|
+
else
|
156
|
+
@cumulative_pace = ""
|
157
|
+
end
|
158
|
+
end
|
159
|
+
|
160
|
+
def set_split(n, tkpt)
|
161
|
+
@split, @prev_split = n, tkpt
|
162
|
+
end
|
163
|
+
|
164
|
+
def is_split()
|
165
|
+
(@split >= 1)
|
166
|
+
end
|
167
|
+
|
168
|
+
def split_info(dtTm)
|
169
|
+
if is_split
|
170
|
+
hhmmss = ''
|
171
|
+
if @prev_split
|
172
|
+
return "#{@split} #{@dttm.hhmmss_diff(@prev_split.dttm())}"
|
173
|
+
else
|
174
|
+
return "#{@split} #{@dttm.hhmmss_diff(dtTm)}"
|
175
|
+
end
|
176
|
+
else
|
177
|
+
""
|
178
|
+
end
|
179
|
+
end
|
180
|
+
|
181
|
+
public
|
182
|
+
|
183
|
+
def as_glatlng(comment_out, gen_comments, tkpt_count, curr_idx, start_dttm)
|
184
|
+
comment_out ? comment = '// ' : comment = ''
|
185
|
+
if gen_comments
|
186
|
+
secs_diff = @dttm.seconds_diff(start_dttm)
|
187
|
+
fmt_time = @dttm.hhmmss_diff(start_dttm)
|
188
|
+
"\n #{comment}points.push(new GLatLng(#{latitude_as_float},#{longitude_as_float})); " +
|
189
|
+
"// (#{curr_idx + 1} of #{tkpt_count}) #{@dttm.to_s} #{secs_diff} #{fmt_time} #{@cumulative_distance} #{split_info(start_dttm)} #{project_embedded_comment} "
|
190
|
+
else
|
191
|
+
"\n #{comment}points.push(new GLatLng(#{latitude_as_float},#{longitude_as_float})); // #{project_embedded_comment} "
|
192
|
+
end
|
193
|
+
end
|
194
|
+
|
195
|
+
def as_info_window_html(checkpoint, start_dttm)
|
196
|
+
s = "\"<table align='left'>"
|
197
|
+
if checkpoint
|
198
|
+
secs_diff = @dttm.seconds_diff(start_dttm)
|
199
|
+
fmt_time = @dttm.hhmmss_diff(start_dttm)
|
200
|
+
|
201
|
+
if checkpoint == 'Start'
|
202
|
+
s << "<tr><td colspan='2'><b>Start!</b></td></tr>"
|
203
|
+
elsif checkpoint == 'Finish'
|
204
|
+
s << "<tr><td colspan='2'><b>Finish!</b></td></tr>"
|
205
|
+
else
|
206
|
+
if (@uom == 'km')
|
207
|
+
s << "<tr><td colspan='2'><b>Kilometer #{checkpoint}</b></td></tr>"
|
208
|
+
else
|
209
|
+
s << "<tr><td colspan='2'><b>Mile #{checkpoint}</b></td></tr>"
|
210
|
+
end
|
211
|
+
end
|
212
|
+
s << "<tr><td>Distance:</td><td>#{@cumulative_distance} #{@uom}</td></tr>"
|
213
|
+
s << "<tr><td>Time of Day:</td><td>#{@dttm.to_s}</td></tr>"
|
214
|
+
s << "<tr><td>Elapsed Time:</td><td>#{fmt_time}</td></tr>"
|
215
|
+
s << "<tr><td>Average Pace:</td><td>#{@cumulative_pace}</td></tr>"
|
216
|
+
s << "<tr><td>Lat/Lng:</td><td>#{latitude_as_float} , #{longitude_as_float}</td></tr>"
|
217
|
+
s << "<tr><td>Altitude:</td><td>#{altitude_as_float}</td></tr>"
|
218
|
+
if (@heartbeat && (@heartbeat.size > 1) && (@heartbeat.to_i > 0))
|
219
|
+
s << "<tr><td>Heartbeat:</td><td>#{@heartbeat}</td></tr>"
|
220
|
+
end
|
221
|
+
s
|
222
|
+
end
|
223
|
+
s << "</table>\""
|
224
|
+
s
|
225
|
+
end
|
226
|
+
|
227
|
+
end
|
228
|
+
|
229
|
+
end # end of module
|
@@ -0,0 +1,224 @@
|
|
1
|
+
=begin
|
2
|
+
|
3
|
+
Gooby = Google APIs + Ruby
|
4
|
+
Gooby - Copyright 2007 by Chris Joakim.
|
5
|
+
Gooby is available under GNU General Public License (GPL) license.
|
6
|
+
|
7
|
+
=end
|
8
|
+
|
9
|
+
module Gooby
|
10
|
+
|
11
|
+
=begin rdoc
|
12
|
+
Instances of this class are used to parse a Garmin TrainingCenter XML(TCX) file
|
13
|
+
in a SAX-like manner. Instances of the model classes - History, Run, Track,
|
14
|
+
Trackpoint, etc. are created in this parsing process.
|
15
|
+
|
16
|
+
See http://www.garmin.com/xmlschemas/TrainingCenterDatabasev2.xsd for the XML
|
17
|
+
Schema Definition for Garmin TrainingCenter XML.
|
18
|
+
=end
|
19
|
+
|
20
|
+
class TrainingCenterXmlParser
|
21
|
+
|
22
|
+
DETAIL_TAGS = %w( Notes StartTime Duration Length Time
|
23
|
+
TotalTimeSeconds DistanceMeters
|
24
|
+
LatitudeDegrees LongitudeDegrees AltitudeMeters HeartRateBpm Value BeginPosition EndPosition )
|
25
|
+
|
26
|
+
include REXML::StreamListener
|
27
|
+
|
28
|
+
attr_reader :uom, :history, :cvHash, :tagCount
|
29
|
+
|
30
|
+
def initialize(uom)
|
31
|
+
@uom = uom
|
32
|
+
@cv_hash = Hash.new("")
|
33
|
+
@tag_count = 0
|
34
|
+
@run_count = 0
|
35
|
+
@lap_count = 0
|
36
|
+
@track_count = 0
|
37
|
+
@trackpoint_count = 0
|
38
|
+
@curr_text = "";
|
39
|
+
@history = History.new
|
40
|
+
@curr_run = nil
|
41
|
+
@curr_lap = nil
|
42
|
+
@curr_track = nil
|
43
|
+
@curr_begin_position = nil
|
44
|
+
@@curr_end_position = nil
|
45
|
+
@first_lap_start_time = nil
|
46
|
+
@curr_lap_start_time = ''
|
47
|
+
@in_heart_rate_bpm = false
|
48
|
+
@in_value = false
|
49
|
+
end
|
50
|
+
|
51
|
+
public
|
52
|
+
|
53
|
+
# SAX API method; handles 'Activity', 'Lap', 'Track', 'HeartRateBpm'.
|
54
|
+
def tag_start(tagname, attrs)
|
55
|
+
@tag_count += 1
|
56
|
+
@currTag = tagname
|
57
|
+
@cv_hash[tagname] = ''
|
58
|
+
|
59
|
+
if detail_tag?(tagname)
|
60
|
+
@inDetail = true
|
61
|
+
end
|
62
|
+
|
63
|
+
if is_tag?('Activity', tagname)
|
64
|
+
@run_count = @run_count + 1
|
65
|
+
@lap_count = 0
|
66
|
+
@track_count = 0
|
67
|
+
@trackpoint_count = 0
|
68
|
+
@curr_run = Run.new(@run_count)
|
69
|
+
@history.add_run(@curr_run)
|
70
|
+
@cv_hash['Notes'] = ''
|
71
|
+
return
|
72
|
+
end
|
73
|
+
|
74
|
+
if is_tag?('Lap', tagname)
|
75
|
+
@lap_count = @lap_count + 1
|
76
|
+
@curr_lap = Lap.new(@lap_count)
|
77
|
+
|
78
|
+
attrs.each { |attr|
|
79
|
+
name = attr[0]
|
80
|
+
val = attr[1]
|
81
|
+
if (name && (name == 'StartTime'))
|
82
|
+
if (@first_lap_start_time == nil)
|
83
|
+
@first_lap_start_time = "#{val}"
|
84
|
+
end
|
85
|
+
@curr_lap_start_time = "#{val}"
|
86
|
+
end
|
87
|
+
}
|
88
|
+
return
|
89
|
+
end
|
90
|
+
|
91
|
+
if is_tag?('Track', tagname)
|
92
|
+
@track_count = @track_count + 1
|
93
|
+
@curr_track = Track.new(@track_count)
|
94
|
+
return
|
95
|
+
end
|
96
|
+
|
97
|
+
if is_tag?('HeartRateBpm', tagname)
|
98
|
+
@in_heart_rate_bpm = true
|
99
|
+
return
|
100
|
+
end
|
101
|
+
|
102
|
+
end
|
103
|
+
|
104
|
+
# SAX API method; handles 'Position', 'Trackpoint', 'Track', 'Lap', 'Run', 'HeartRateBpm', 'Value'.
|
105
|
+
def tag_end(tagname)
|
106
|
+
if @inDetail
|
107
|
+
if is_tag?('Value', tagname) && @in_heart_rate_bpm
|
108
|
+
@cv_hash['HeartRateBpm'] = "#{@curr_text.strip!}"
|
109
|
+
else
|
110
|
+
@cv_hash[tagname] = @curr_text
|
111
|
+
end
|
112
|
+
else
|
113
|
+
if is_tag?('Position', tagname)
|
114
|
+
lat = @cv_hash['LatitudeDegrees']
|
115
|
+
long = @cv_hash['LongitudeDegrees']
|
116
|
+
@curr_begin_position = Point.new(lat.strip, long.strip)
|
117
|
+
@@curr_end_position = Point.new(lat.strip, long.strip)
|
118
|
+
end
|
119
|
+
|
120
|
+
if is_tag?('BeginPosition', tagname)
|
121
|
+
lat = @cv_hash['LatitudeDegrees']
|
122
|
+
long = @cv_hash['LongitudeDegrees']
|
123
|
+
@curr_begin_position = Point.new(lat.strip, long.strip)
|
124
|
+
end
|
125
|
+
|
126
|
+
if is_tag?('EndPosition', tagname)
|
127
|
+
lat = @cv_hash['LatitudeDegrees']
|
128
|
+
long = @cv_hash['LongitudeDegrees']
|
129
|
+
@@curr_end_position = Point.new(lat.strip, long.strip)
|
130
|
+
end
|
131
|
+
|
132
|
+
if is_tag?('Trackpoint', tagname)
|
133
|
+
@trackpoint_count = @trackpoint_count + 1
|
134
|
+
lat = @cv_hash['LatitudeDegrees']
|
135
|
+
long = @cv_hash['LongitudeDegrees']
|
136
|
+
alt = @cv_hash['AltitudeMeters']
|
137
|
+
hb = @cv_hash['HeartRateBpm']
|
138
|
+
hb ? hb = hb.to_s : hb = '-1'
|
139
|
+
time = @cv_hash['Time']
|
140
|
+
hash = Hash.new('')
|
141
|
+
hash['lap_number'] = "#{@lap_count}"
|
142
|
+
hash['first_lap_start_time'] = "#{@first_lap_start_time}"
|
143
|
+
hash['curr_lap_start_time'] = "#{@curr_lap_start_time}"
|
144
|
+
tp = Trackpoint.new(@trackpoint_count, lat, long, alt, hb, time, @uom, hash)
|
145
|
+
@curr_track.add_trackpoint(tp) if tp.has_coordinates?
|
146
|
+
|
147
|
+
@cv_hash['LatitudeDegrees'] = ''
|
148
|
+
@cv_hash['LongitudeDegrees'] = ''
|
149
|
+
@cv_hash['AltitudeMeters'] = ''
|
150
|
+
@cv_hash['HeartRateBpm'] = ''
|
151
|
+
@cv_hash['Time'] = ''
|
152
|
+
end
|
153
|
+
|
154
|
+
if is_tag?('Track', tagname)
|
155
|
+
if @curr_run != nil
|
156
|
+
@curr_run.add_track(@curr_track)
|
157
|
+
end
|
158
|
+
end
|
159
|
+
|
160
|
+
if is_tag?('Lap', tagname)
|
161
|
+
@curr_run.add_lap(@curr_lap)
|
162
|
+
end
|
163
|
+
|
164
|
+
if is_tag?('Activity', tagname)
|
165
|
+
@curr_run.notes = @cv_hash['Notes']
|
166
|
+
end
|
167
|
+
|
168
|
+
if is_tag?('HeartRateBpm', tagname)
|
169
|
+
@in_heart_rate_bpm = false
|
170
|
+
return
|
171
|
+
end
|
172
|
+
|
173
|
+
end
|
174
|
+
|
175
|
+
@inDetail = false
|
176
|
+
@curr_text = ""
|
177
|
+
@currTag = ""
|
178
|
+
end
|
179
|
+
|
180
|
+
# SAX API method.
|
181
|
+
def text(txt)
|
182
|
+
if @inDetail
|
183
|
+
@curr_text = @curr_text + txt
|
184
|
+
end
|
185
|
+
end
|
186
|
+
|
187
|
+
# Iterate all parsed Run objects and print each with to_s.
|
188
|
+
def gdump()
|
189
|
+
@history.runs().each { |run| puts run.to_s }
|
190
|
+
end
|
191
|
+
|
192
|
+
# Iterate all parsed Run objects and print each with to_s.
|
193
|
+
def dump()
|
194
|
+
@history.runs().each { |run| puts run.to_s }
|
195
|
+
end
|
196
|
+
|
197
|
+
# Iterate all parsed Run objects and print each with put_csv.
|
198
|
+
def put_run_csv()
|
199
|
+
@history.runs().each { |run| run.put_csv() }
|
200
|
+
end
|
201
|
+
|
202
|
+
# Iterate all parsed Run objects and print each with put_tkpt_csv.
|
203
|
+
def put_all_run_tkpt_csv()
|
204
|
+
@history.runs.each { |run| run.put_tkpt_csv() }
|
205
|
+
end
|
206
|
+
|
207
|
+
private
|
208
|
+
|
209
|
+
def is_tag?(tagname, value)
|
210
|
+
tagname == value
|
211
|
+
end
|
212
|
+
|
213
|
+
def detail_tag?(tagname)
|
214
|
+
DETAIL_TAGS.each { |typ|
|
215
|
+
if typ == tagname
|
216
|
+
return true
|
217
|
+
end
|
218
|
+
}
|
219
|
+
return false
|
220
|
+
end
|
221
|
+
|
222
|
+
end
|
223
|
+
|
224
|
+
end # end of module
|