gooby 1.1.0 → 1.2.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|