gooby 0.9.3
Sign up to get free protection for your applications and to get access to all the features.
- data/README +242 -0
- data/bin/example_usage.rb +38 -0
- data/bin/tests_gen.rb +16 -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/2007_03_03.tcx +6207 -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/img/gicons/blank.png +0 -0
- data/img/gicons/dd-end.png +0 -0
- data/img/gicons/dd-start.png +0 -0
- data/img/gicons/marker.png +0 -0
- data/img/gicons/marker0.png +0 -0
- data/img/gicons/marker00.png +0 -0
- data/img/gicons/marker01.png +0 -0
- data/img/gicons/marker02.png +0 -0
- data/img/gicons/marker03.png +0 -0
- data/img/gicons/marker04.png +0 -0
- data/img/gicons/marker05.png +0 -0
- data/img/gicons/marker06.png +0 -0
- data/img/gicons/marker07.png +0 -0
- data/img/gicons/marker08.png +0 -0
- data/img/gicons/marker09.png +0 -0
- data/img/gicons/marker1.png +0 -0
- data/img/gicons/marker10.png +0 -0
- data/img/gicons/marker11.png +0 -0
- data/img/gicons/marker12.png +0 -0
- data/img/gicons/marker13.png +0 -0
- data/img/gicons/marker14.png +0 -0
- data/img/gicons/marker15.png +0 -0
- data/img/gicons/marker16.png +0 -0
- data/img/gicons/marker17.png +0 -0
- data/img/gicons/marker18.png +0 -0
- data/img/gicons/marker19.png +0 -0
- data/img/gicons/marker2.png +0 -0
- data/img/gicons/marker20.png +0 -0
- data/img/gicons/marker21.png +0 -0
- data/img/gicons/marker22.png +0 -0
- data/img/gicons/marker23.png +0 -0
- data/img/gicons/marker24.png +0 -0
- data/img/gicons/marker25.png +0 -0
- data/img/gicons/marker26.png +0 -0
- data/img/gicons/marker27.png +0 -0
- data/img/gicons/marker28.png +0 -0
- data/img/gicons/marker29.png +0 -0
- data/img/gicons/marker3.png +0 -0
- data/img/gicons/marker30.png +0 -0
- data/img/gicons/marker31.png +0 -0
- data/img/gicons/marker32.png +0 -0
- data/img/gicons/marker33.png +0 -0
- data/img/gicons/marker34.png +0 -0
- data/img/gicons/marker35.png +0 -0
- data/img/gicons/marker36.png +0 -0
- data/img/gicons/marker37.png +0 -0
- data/img/gicons/marker38.png +0 -0
- data/img/gicons/marker39.png +0 -0
- data/img/gicons/marker4.png +0 -0
- data/img/gicons/marker40.png +0 -0
- data/img/gicons/marker41.png +0 -0
- data/img/gicons/marker42.png +0 -0
- data/img/gicons/marker43.png +0 -0
- data/img/gicons/marker44.png +0 -0
- data/img/gicons/marker45.png +0 -0
- data/img/gicons/marker46.png +0 -0
- data/img/gicons/marker47.png +0 -0
- data/img/gicons/marker48.png +0 -0
- data/img/gicons/marker49.png +0 -0
- data/img/gicons/marker5.png +0 -0
- data/img/gicons/marker50.png +0 -0
- data/img/gicons/marker51.png +0 -0
- data/img/gicons/marker52.png +0 -0
- data/img/gicons/marker53.png +0 -0
- data/img/gicons/marker54.png +0 -0
- data/img/gicons/marker55.png +0 -0
- data/img/gicons/marker56.png +0 -0
- data/img/gicons/marker57.png +0 -0
- data/img/gicons/marker58.png +0 -0
- data/img/gicons/marker59.png +0 -0
- data/img/gicons/marker6.png +0 -0
- data/img/gicons/marker60.png +0 -0
- data/img/gicons/marker61.png +0 -0
- data/img/gicons/marker62.png +0 -0
- data/img/gicons/marker63.png +0 -0
- data/img/gicons/marker64.png +0 -0
- data/img/gicons/marker65.png +0 -0
- data/img/gicons/marker66.png +0 -0
- data/img/gicons/marker67.png +0 -0
- data/img/gicons/marker68.png +0 -0
- data/img/gicons/marker69.png +0 -0
- data/img/gicons/marker7.png +0 -0
- data/img/gicons/marker70.png +0 -0
- data/img/gicons/marker71.png +0 -0
- data/img/gicons/marker72.png +0 -0
- data/img/gicons/marker73.png +0 -0
- data/img/gicons/marker74.png +0 -0
- data/img/gicons/marker75.png +0 -0
- data/img/gicons/marker76.png +0 -0
- data/img/gicons/marker77.png +0 -0
- data/img/gicons/marker78.png +0 -0
- data/img/gicons/marker79.png +0 -0
- data/img/gicons/marker8.png +0 -0
- data/img/gicons/marker80.png +0 -0
- data/img/gicons/marker81.png +0 -0
- data/img/gicons/marker82.png +0 -0
- data/img/gicons/marker83.png +0 -0
- data/img/gicons/marker84.png +0 -0
- data/img/gicons/marker85.png +0 -0
- data/img/gicons/marker86.png +0 -0
- data/img/gicons/marker87.png +0 -0
- data/img/gicons/marker88.png +0 -0
- data/img/gicons/marker89.png +0 -0
- data/img/gicons/marker9.png +0 -0
- data/img/gicons/marker90.png +0 -0
- data/img/gicons/marker91.png +0 -0
- data/img/gicons/marker92.png +0 -0
- data/img/gicons/marker93.png +0 -0
- data/img/gicons/marker94.png +0 -0
- data/img/gicons/marker95.png +0 -0
- data/img/gicons/marker96.png +0 -0
- data/img/gicons/marker97.png +0 -0
- data/img/gicons/marker98.png +0 -0
- data/img/gicons/marker99.png +0 -0
- data/img/gicons/markerA.png +0 -0
- data/img/gicons/markerB.png +0 -0
- data/img/gicons/markerC.png +0 -0
- data/img/gicons/markerD.png +0 -0
- data/img/gicons/markerE.png +0 -0
- data/img/gicons/markerF.png +0 -0
- data/img/gicons/markerG.png +0 -0
- data/img/gicons/markerH.png +0 -0
- data/img/gicons/markerI.png +0 -0
- data/img/gicons/markerJ.png +0 -0
- data/img/gicons/mm_20_red.png +0 -0
- data/img/gicons/mm_20_shadow.png +0 -0
- data/img/gicons/readme.txt +11 -0
- data/img/gicons/shadow50.png +0 -0
- data/lib/gooby/cls_counter_hash.rb +78 -0
- data/lib/gooby/cls_delim_line.rb +35 -0
- data/lib/gooby/cls_dttm.rb +79 -0
- data/lib/gooby/cls_duration.rb +79 -0
- data/lib/gooby/cls_forerunner_xml_parser.rb +178 -0
- data/lib/gooby/cls_forerunner_xml_splitter.rb +109 -0
- data/lib/gooby/cls_geo_data.rb +181 -0
- data/lib/gooby/cls_gooby_command.rb +35 -0
- data/lib/gooby/cls_gooby_object.rb +18 -0
- data/lib/gooby/cls_google_map_generator.rb +363 -0
- data/lib/gooby/cls_history.rb +33 -0
- data/lib/gooby/cls_lap.rb +22 -0
- data/lib/gooby/cls_line.rb +75 -0
- data/lib/gooby/cls_options.rb +67 -0
- data/lib/gooby/cls_position.rb +44 -0
- data/lib/gooby/cls_run.rb +194 -0
- data/lib/gooby/cls_simple_xml_parser.rb +41 -0
- data/lib/gooby/cls_test_regen.rb +182 -0
- data/lib/gooby/cls_track.rb +47 -0
- data/lib/gooby/cls_trackpoint.rb +200 -0
- data/lib/gooby/mod_introspect.rb +26 -0
- data/lib/gooby/mod_io.rb +58 -0
- data/lib/gooby/mod_project_info.rb +80 -0
- data/lib/gooby/mod_string.rb +19 -0
- data/lib/gooby/mod_test_helper.rb +15 -0
- data/lib/gooby.rb +2265 -0
- data/pkg/code_header.txt +21 -0
- data/pkg/pkg.rb +236 -0
- data/pkg/test_header.txt +19 -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 +201 -0
- data/samples/run_2007_02_24_15_01_35.html +298 -0
- data/tests/tc_cls_counter_hash.rb +107 -0
- data/tests/tc_cls_delim_line.rb +74 -0
- data/tests/tc_cls_dttm.rb +131 -0
- data/tests/tc_cls_duration.rb +51 -0
- data/tests/tc_cls_forerunner_xml_parser.rb +70 -0
- data/tests/tc_cls_geo_data.xxx +71 -0
- data/tests/tc_cls_gooby_object.rb +26 -0
- data/tests/tc_cls_google_map_generator.rb +109 -0
- data/tests/tc_cls_history.rb +46 -0
- data/tests/tc_cls_lap.rb +38 -0
- data/tests/tc_cls_line.rb +110 -0
- data/tests/tc_cls_options.rb +79 -0
- data/tests/tc_cls_position.rb +66 -0
- data/tests/tc_cls_run.rb +142 -0
- data/tests/tc_cls_simple_xml_parser.rb +50 -0
- data/tests/tc_cls_track.rb +70 -0
- data/tests/tc_cls_trackpoint.rb +145 -0
- data/tests/tc_mod_introspect.rb +32 -0
- data/tests/tc_mod_io.rb +53 -0
- data/tests/tc_mod_project_info.rb +79 -0
- data/tests/tc_mod_string.rb +58 -0
- data/tests/ts_gooby.rb +1237 -0
- metadata +270 -0
@@ -0,0 +1,178 @@
|
|
1
|
+
module Gooby
|
2
|
+
|
3
|
+
=begin rdoc
|
4
|
+
Instances of this class are used to parse a Forerunner XML file in a SAX-like
|
5
|
+
manner. Instances of the model classes - History, Run, Track, Trackpoint,
|
6
|
+
etc. are created in this parsing process.
|
7
|
+
|
8
|
+
See http://www.garmin.com/xmlschemas/ForerunnerLogbookv1.xsd for the XML Schema
|
9
|
+
Definition for the Garmin Forerunner XML. The Gooby object model mirrors this XSD.
|
10
|
+
=end
|
11
|
+
|
12
|
+
class ForerunnerXmlParser
|
13
|
+
|
14
|
+
DETAIL_TAGS = %w( Notes StartTime Duration Length Latitude Longitude Altitude Time BeginPosition EndPosition )
|
15
|
+
|
16
|
+
include REXML::StreamListener
|
17
|
+
|
18
|
+
attr_reader :history, :cvHash, :tagCount
|
19
|
+
|
20
|
+
def initialize
|
21
|
+
@cvHash = Hash.new("")
|
22
|
+
@tagCount = 0
|
23
|
+
@runCount = 0
|
24
|
+
@lapCount = 0
|
25
|
+
@trackCount = 0
|
26
|
+
@trackpoint_count = 0
|
27
|
+
@currText = "";
|
28
|
+
@history = History.new
|
29
|
+
@currRun = nil
|
30
|
+
@currLap = nil
|
31
|
+
@currTrack = nil
|
32
|
+
@currBeginPosition = nil
|
33
|
+
@currEndPosition = nil
|
34
|
+
end
|
35
|
+
|
36
|
+
public
|
37
|
+
|
38
|
+
# SAX API method; handles 'Run', 'Lap', 'Track'.
|
39
|
+
def tag_start(tagname, attrs)
|
40
|
+
@tagCount += 1
|
41
|
+
@currTag = tagname
|
42
|
+
@cvHash[tagname] = ''
|
43
|
+
|
44
|
+
if detail_tag?(tagname)
|
45
|
+
@inDetail = true
|
46
|
+
end
|
47
|
+
|
48
|
+
if is_tag?('Run', tagname)
|
49
|
+
@runCount = @runCount + 1
|
50
|
+
@lapCount = 0
|
51
|
+
@trackCount = 0
|
52
|
+
@currRun = Run.new(@runCount)
|
53
|
+
@history.add_run(@currRun)
|
54
|
+
@cvHash['Notes'] = ''
|
55
|
+
return
|
56
|
+
end
|
57
|
+
|
58
|
+
if is_tag?('Lap', tagname)
|
59
|
+
@lapCount = @lapCount + 1
|
60
|
+
@currLap = Lap.new(@lapCount)
|
61
|
+
return
|
62
|
+
end
|
63
|
+
|
64
|
+
if is_tag?('Track', tagname)
|
65
|
+
@trackCount = @trackCount + 1
|
66
|
+
@currTrack = Track.new(@trackCount)
|
67
|
+
@trackpoint_count = 0
|
68
|
+
return
|
69
|
+
end
|
70
|
+
|
71
|
+
end
|
72
|
+
|
73
|
+
# SAX API method; handles 'Position', 'Trackpoint', 'Track', 'Lap', 'Run'.
|
74
|
+
def tag_end(tagname)
|
75
|
+
if @inDetail
|
76
|
+
@cvHash[tagname] = @currText
|
77
|
+
else
|
78
|
+
if is_tag?('Position', tagname)
|
79
|
+
lat = @cvHash['Latitude']
|
80
|
+
long = @cvHash['Longitude']
|
81
|
+
@currBeginPosition = Position.new(lat.strip, long.strip, '')
|
82
|
+
@currEndPosition = Position.new(lat.strip, long.strip, '')
|
83
|
+
end
|
84
|
+
|
85
|
+
if is_tag?('BeginPosition', tagname)
|
86
|
+
lat = @cvHash['Latitude']
|
87
|
+
long = @cvHash['Longitude']
|
88
|
+
@currBeginPosition = Position.new(lat.strip, long.strip, '')
|
89
|
+
end
|
90
|
+
|
91
|
+
if is_tag?('EndPosition', tagname)
|
92
|
+
lat = @cvHash['Latitude']
|
93
|
+
long = @cvHash['Longitude']
|
94
|
+
@currEndPosition = Position.new(lat.strip, long.strip, '')
|
95
|
+
end
|
96
|
+
|
97
|
+
if is_tag?('Trackpoint', tagname)
|
98
|
+
@trackpoint_count = @trackpoint_count + 1
|
99
|
+
lat = @cvHash['Latitude']
|
100
|
+
long = @cvHash['Longitude']
|
101
|
+
alt = @cvHash['Altitude']
|
102
|
+
time = @cvHash['Time']
|
103
|
+
tp = Trackpoint.new(@trackpoint_count, lat, long, alt, time)
|
104
|
+
@currTrack.add_trackpoint(tp)
|
105
|
+
end
|
106
|
+
|
107
|
+
if is_tag?('Track', tagname)
|
108
|
+
if @currRun != nil
|
109
|
+
@currRun.add_track(@currTrack)
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
if is_tag?('Lap', tagname)
|
114
|
+
@currLap.startTime = @cvHash['StartTime']
|
115
|
+
@currLap.duration = Duration.new(@cvHash['Duration'])
|
116
|
+
@currLap.length = @cvHash['Length']
|
117
|
+
@currLap.beginPosition = @currBeginPosition
|
118
|
+
@currLap.endPosition = @currEndPosition
|
119
|
+
@currRun.add_lap(@currLap)
|
120
|
+
end
|
121
|
+
|
122
|
+
if is_tag?('Run', tagname)
|
123
|
+
@currRun.notes = @cvHash['Notes']
|
124
|
+
end
|
125
|
+
end
|
126
|
+
|
127
|
+
@inDetail = false
|
128
|
+
@currText = ""
|
129
|
+
@currTag = ""
|
130
|
+
end
|
131
|
+
|
132
|
+
# SAX API method.
|
133
|
+
def text(txt)
|
134
|
+
if @inDetail
|
135
|
+
@currText = @currText + txt
|
136
|
+
end
|
137
|
+
end
|
138
|
+
|
139
|
+
# Iterate all parsed Run objects and print each with to_s.
|
140
|
+
def gdump()
|
141
|
+
@history.runs().each { |run| puts run.to_s }
|
142
|
+
end
|
143
|
+
|
144
|
+
# Iterate all parsed Run objects and print each with to_s.
|
145
|
+
def dump()
|
146
|
+
@history.runs().each { |run| puts run.to_s }
|
147
|
+
end
|
148
|
+
|
149
|
+
# Iterate all parsed Run objects and print each with put_csv.
|
150
|
+
def put_run_csv()
|
151
|
+
@history.runs().each { |run| run.put_csv() }
|
152
|
+
end
|
153
|
+
|
154
|
+
# Iterate all parsed Run objects and print each with put_tkpt_csv.
|
155
|
+
def put_all_run_tkpt_csv(with_header_comment)
|
156
|
+
@history.runs.each { |run|
|
157
|
+
run.put_tkpt_csv(with_header_comment)
|
158
|
+
}
|
159
|
+
end
|
160
|
+
|
161
|
+
private
|
162
|
+
|
163
|
+
def is_tag?(tagname, value)
|
164
|
+
tagname == value
|
165
|
+
end
|
166
|
+
|
167
|
+
def detail_tag?(tagname)
|
168
|
+
DETAIL_TAGS.each { |typ|
|
169
|
+
if typ == tagname
|
170
|
+
return true
|
171
|
+
end
|
172
|
+
}
|
173
|
+
return false
|
174
|
+
end
|
175
|
+
|
176
|
+
end
|
177
|
+
|
178
|
+
end # end of module
|
@@ -0,0 +1,109 @@
|
|
1
|
+
module Gooby
|
2
|
+
|
3
|
+
=begin rdoc
|
4
|
+
Instances of this class are used to split a large ForerunnerLogbook
|
5
|
+
XML file into individual 'run_' files.
|
6
|
+
=end
|
7
|
+
|
8
|
+
class ForerunnerXmlSplitter < GoobyObject
|
9
|
+
|
10
|
+
attr_reader :out_dir, :forerunner_files, :out_files_hash
|
11
|
+
|
12
|
+
def initialize(xml_file, out_dir)
|
13
|
+
@out_dir = out_dir
|
14
|
+
@forerunner_files = Array.new
|
15
|
+
@forerunner_files << xml_file
|
16
|
+
@out_files_hash = Hash.new
|
17
|
+
end
|
18
|
+
|
19
|
+
def split
|
20
|
+
@forerunner_files.each { |f| process_file(f) }
|
21
|
+
write_files
|
22
|
+
end
|
23
|
+
|
24
|
+
private
|
25
|
+
|
26
|
+
def process_file(forerunnerXmlFile)
|
27
|
+
@file_name = forerunnerXmlFile
|
28
|
+
@xml_lines = read_lines(@file_name, false)
|
29
|
+
@line_num = 0
|
30
|
+
@run_num = 0
|
31
|
+
@curr_run_lines = Array.new
|
32
|
+
@curr_run_tkpts = 0
|
33
|
+
@start_line_num = 0
|
34
|
+
@end_line_num = 0
|
35
|
+
@first_start_time = nil
|
36
|
+
|
37
|
+
@xml_lines.each { |line|
|
38
|
+
@line_num = @line_num + 1
|
39
|
+
if (line.match(/<Run>/))
|
40
|
+
@run_num = @run_num + 1
|
41
|
+
@start_line_num = @line_num
|
42
|
+
@curr_run_lines = Array.new
|
43
|
+
@curr_run_lines << line
|
44
|
+
elsif (line.match(/<StartTime>/)) # <StartTime>2007-01-13T15:37:06Z</StartTime>
|
45
|
+
@curr_run_lines << line
|
46
|
+
if @first_start_time == nil
|
47
|
+
clone = String.new(line)
|
48
|
+
clone.gsub!(/[<>]/, ' ')
|
49
|
+
clone.gsub!(/[-:T]/, '_')
|
50
|
+
clone.gsub!(/[Z]/, '')
|
51
|
+
tokens = clone.split
|
52
|
+
@first_start_time = tokens[1]
|
53
|
+
end
|
54
|
+
elsif (line.match(/<Trackpoint>/))
|
55
|
+
@curr_run_tkpts = @curr_run_tkpts + 1
|
56
|
+
@curr_run_lines << line
|
57
|
+
elsif (line.match(/<\/Run>/))
|
58
|
+
@end_line_num = @line_num
|
59
|
+
@curr_run_lines << line
|
60
|
+
end_run
|
61
|
+
elsif (@curr_run_lines.size > 0)
|
62
|
+
@curr_run_lines << line
|
63
|
+
end
|
64
|
+
}
|
65
|
+
end
|
66
|
+
|
67
|
+
def end_run
|
68
|
+
out_file = "#{@out_dir}/run_#{@first_start_time}.xml"
|
69
|
+
comment = "<!-- file: #{out_file} lines: #{@curr_run_lines.size} (#{@start_line_num} to #{@end_line_num}) tkpts: #{@curr_run_tkpts} --> \n"
|
70
|
+
@curr_run_lines.insert(0, comment)
|
71
|
+
|
72
|
+
prev_entry = @out_files_hash[out_file]
|
73
|
+
if prev_entry
|
74
|
+
if (@curr_run_lines.size >= prev_entry.size)
|
75
|
+
puts "previous entry overlaid for #{out_file}. curr=#{@curr_run_lines.size} prev=#{prev_entry.size}"
|
76
|
+
@out_files_hash[out_file] = @curr_run_lines
|
77
|
+
else
|
78
|
+
puts "previous entry retained for #{out_file}. curr=#{@curr_run_lines.size} prev=#{prev_entry.size}"
|
79
|
+
end
|
80
|
+
else
|
81
|
+
puts "new entry for #{out_file}. curr=#{@curr_run_lines.size}"
|
82
|
+
@out_files_hash[out_file] = @curr_run_lines
|
83
|
+
end
|
84
|
+
|
85
|
+
@curr_run_lines = Array.new
|
86
|
+
@curr_run_tkpts = 0
|
87
|
+
@start_line_num = 0
|
88
|
+
@end_line_num = 0
|
89
|
+
@first_start_time = nil
|
90
|
+
end
|
91
|
+
|
92
|
+
def write_files
|
93
|
+
out_names = @out_files_hash.keys.sort
|
94
|
+
puts "Writing #{out_names.size} extract files..."
|
95
|
+
out_names.each { |out_name|
|
96
|
+
lines = @out_files_hash[out_name]
|
97
|
+
out = File.new out_name, "w+"
|
98
|
+
lines.each { |line| out.write line }
|
99
|
+
out.flush
|
100
|
+
out.close
|
101
|
+
puts "File written: #{out_name}"
|
102
|
+
}
|
103
|
+
puts "output files written."
|
104
|
+
end
|
105
|
+
|
106
|
+
end
|
107
|
+
|
108
|
+
end # end of module
|
109
|
+
|
@@ -0,0 +1,181 @@
|
|
1
|
+
module Gooby
|
2
|
+
|
3
|
+
=begin rdoc
|
4
|
+
Instances of this class represent a the set of Geographic data defined in file geo.txt
|
5
|
+
=end
|
6
|
+
|
7
|
+
class GeoData < GoobyObject
|
8
|
+
|
9
|
+
attr_reader :filename, :lines, :poi_hash, :poi_array, :track_hash, :track_array, :route_hash, :route_array
|
10
|
+
|
11
|
+
def initialize(filename)
|
12
|
+
@filename = filename
|
13
|
+
@filename = 'data/geo_data.txt' if @filename == nil
|
14
|
+
@lines = read_lines(@filename, true)
|
15
|
+
@poi_hash = Hash.new
|
16
|
+
@poi_array = Array.new
|
17
|
+
@track_hash = Hash.new
|
18
|
+
@track_array = Array.new
|
19
|
+
@route_hash = Hash.new
|
20
|
+
@route_array = Array.new
|
21
|
+
parse_poi
|
22
|
+
parse_tracks
|
23
|
+
parse_routes
|
24
|
+
end
|
25
|
+
|
26
|
+
private
|
27
|
+
|
28
|
+
def parse_poi
|
29
|
+
in_poi, poi_number = false, 0
|
30
|
+
@lines.each { |line|
|
31
|
+
line_obj = Line.new(line, nil, true)
|
32
|
+
tok_count = line_obj.token_count
|
33
|
+
is_point = line_obj.token_idx_equals(0, '.')
|
34
|
+
|
35
|
+
if line_obj.is_populated_non_comment
|
36
|
+
if line_obj.match('points_of_interest_start')
|
37
|
+
in_poi = true
|
38
|
+
elsif line_obj.match('points_of_interest_end')
|
39
|
+
in_poi = false
|
40
|
+
elsif in_poi && tok_count > 2 && is_point
|
41
|
+
poi_number = poi_number + 1
|
42
|
+
tkpt = Trackpoint.new(
|
43
|
+
poi_number, line_obj.tokens[1], line_obj.tokens[2],
|
44
|
+
'0', '', line_obj.concatinate_tokens(3))
|
45
|
+
add_poi(tkpt)
|
46
|
+
end
|
47
|
+
end
|
48
|
+
}
|
49
|
+
end
|
50
|
+
|
51
|
+
def parse_tracks
|
52
|
+
in_track, trk_number, tkpt_number = false, 0, 0
|
53
|
+
curr_trk, curr_run = nil, nil
|
54
|
+
@lines.each { |line|
|
55
|
+
line_obj = Line.new(line, nil, true)
|
56
|
+
tok_count = line_obj.token_count
|
57
|
+
is_point = line_obj.token_idx_equals(0, '.')
|
58
|
+
|
59
|
+
if line_obj.is_populated_non_comment
|
60
|
+
if line_obj.match('track_start')
|
61
|
+
in_track = true
|
62
|
+
trk_number = trk_number + 1
|
63
|
+
tkpt_number = 0
|
64
|
+
curr_trk = Track.new(0, line_obj.concatinate_tokens(1))
|
65
|
+
curr_run = Run.new(trk_number, line_obj.concatinate_tokens(1))
|
66
|
+
curr_run.add_track(curr_trk)
|
67
|
+
elsif line_obj.match('track_end')
|
68
|
+
in_track = false
|
69
|
+
curr_run.finish
|
70
|
+
add_track(curr_trk)
|
71
|
+
add_route(curr_run)
|
72
|
+
elsif in_track && tok_count > 2 && is_point
|
73
|
+
tkpt_number = tkpt_number + 1
|
74
|
+
tkpt = Trackpoint.new(
|
75
|
+
tkpt_number, line_obj.tokens[1], line_obj.tokens[2],
|
76
|
+
'0', '', line_obj.concatinate_tokens(3))
|
77
|
+
curr_trk.add_trackpoint(tkpt)
|
78
|
+
end
|
79
|
+
end
|
80
|
+
}
|
81
|
+
end
|
82
|
+
|
83
|
+
def parse_routes
|
84
|
+
in_route, route_number, trk_number, tkpt_number = false, 0, 0, 0
|
85
|
+
curr_trk, curr_run = nil, nil
|
86
|
+
@lines.each { |line|
|
87
|
+
line_obj = Line.new(line, nil, true)
|
88
|
+
tok_count = line_obj.token_count
|
89
|
+
is_point = line_obj.token_idx_equals(0, '.')
|
90
|
+
|
91
|
+
if line_obj.is_populated_non_comment
|
92
|
+
if line_obj.match('route_start')
|
93
|
+
in_route = true
|
94
|
+
trk_number = trk_number + 1
|
95
|
+
tkpt_number = 0
|
96
|
+
curr_trk = Track.new(0, line_obj.concatinate_tokens(1))
|
97
|
+
curr_run = Run.new(trk_number, line_obj.concatinate_tokens(1))
|
98
|
+
curr_run.add_track(curr_trk)
|
99
|
+
elsif line_obj.match('route_end')
|
100
|
+
in_route = false
|
101
|
+
curr_run.finish
|
102
|
+
add_route(curr_run)
|
103
|
+
elsif in_route && tok_count > 2 && is_point
|
104
|
+
tkpt_number = tkpt_number + 1
|
105
|
+
tkpt = Trackpoint.new(
|
106
|
+
tkpt_number, line_obj.tokens[1], line_obj.tokens[2],
|
107
|
+
'0', '', line_obj.concatinate_tokens(3))
|
108
|
+
curr_trk.add_trackpoint(tkpt)
|
109
|
+
elsif in_route && line_obj.token_idx_equals(0, 'track') && tok_count > 1
|
110
|
+
trk_desc = line_obj.concatinate_tokens(1)
|
111
|
+
trk = @track_hash[trk_desc]
|
112
|
+
if trk
|
113
|
+
trk.trackpoints.each { |tkpt| curr_trk.add_trackpoint(tkpt) }
|
114
|
+
end
|
115
|
+
elsif in_route && line_obj.token_idx_equals(0, 'track_rev') && tok_count > 1
|
116
|
+
trk_desc = line_obj.concatinate_tokens(1)
|
117
|
+
trk = @track_hash[trk_desc]
|
118
|
+
if trk
|
119
|
+
array = trk.trackpoints
|
120
|
+
trk.trackpoints.each { |tkpt| curr_trk.add_trackpoint(tkpt) }
|
121
|
+
end
|
122
|
+
end
|
123
|
+
end
|
124
|
+
}
|
125
|
+
end
|
126
|
+
|
127
|
+
def add_poi(tkpt)
|
128
|
+
if tkpt
|
129
|
+
descr = tkpt.descr
|
130
|
+
if @poi_hash.has_key? descr
|
131
|
+
puts "Duplicate POI key ignored - '#{descr}'"
|
132
|
+
else
|
133
|
+
#puts "Adding POI: #{tkpt.to_poi_csv}"
|
134
|
+
@poi_hash[descr] = tkpt
|
135
|
+
@poi_array << tkpt
|
136
|
+
end
|
137
|
+
end
|
138
|
+
end
|
139
|
+
|
140
|
+
def add_track(trk)
|
141
|
+
if trk
|
142
|
+
descr = trk.descr
|
143
|
+
if @track_hash.has_key? descr
|
144
|
+
puts "Duplicate Track key ignored - '#{descr}'"
|
145
|
+
else
|
146
|
+
@track_hash[descr] = trk
|
147
|
+
@track_array << trk
|
148
|
+
end
|
149
|
+
end
|
150
|
+
end
|
151
|
+
|
152
|
+
def add_route(run)
|
153
|
+
if run
|
154
|
+
descr = run.descr
|
155
|
+
if @route_hash.has_key? descr
|
156
|
+
puts "Duplicate Route key ignored - '#{descr}'"
|
157
|
+
else
|
158
|
+
@route_hash[descr] = run
|
159
|
+
@route_array << run
|
160
|
+
end
|
161
|
+
end
|
162
|
+
end
|
163
|
+
|
164
|
+
public
|
165
|
+
|
166
|
+
def to_s
|
167
|
+
return "GeoData lines: #{lines.size} poi: #{@poi_hash.size} tracks: #{@track_hash.size} routes: #{@route_hash.size} "
|
168
|
+
end
|
169
|
+
|
170
|
+
def dump
|
171
|
+
puts "#{self.class} dump:"
|
172
|
+
@poi_array.each { |tkpt| puts "POI: #{tkpt.to_geo_s}" }
|
173
|
+
@track_array.each { |trk| trk.dump }
|
174
|
+
@route_hash.keys.sort.each { |key|
|
175
|
+
puts "Route: '#{key}'"
|
176
|
+
}
|
177
|
+
end
|
178
|
+
|
179
|
+
end
|
180
|
+
|
181
|
+
end # end of module
|
@@ -0,0 +1,35 @@
|
|
1
|
+
module Gooby
|
2
|
+
|
3
|
+
=begin rdoc
|
4
|
+
This class provides "user friendly DSL" functionality for the use
|
5
|
+
of Gooby.
|
6
|
+
=end
|
7
|
+
|
8
|
+
class GoobyCommand < GoobyObject
|
9
|
+
|
10
|
+
def initialize
|
11
|
+
end
|
12
|
+
|
13
|
+
def options(yaml_filename)
|
14
|
+
Gooby::Options.new(yaml_filename)
|
15
|
+
end
|
16
|
+
|
17
|
+
def split_forerunner_xml(xml_filename, out_dir)
|
18
|
+
splitter = Gooby::ForerunnerXmlSplitter.new(xml_filename, out_dir)
|
19
|
+
splitter.split
|
20
|
+
end
|
21
|
+
|
22
|
+
def parse_forerunner_xml(xml_filename)
|
23
|
+
handler = Gooby::ForerunnerXmlParser.new
|
24
|
+
Document.parse_stream((File.new xml_filename), handler)
|
25
|
+
handler.put_all_run_tkpt_csv(true)
|
26
|
+
end
|
27
|
+
|
28
|
+
def generate_google_map(csv_filename, options_obj)
|
29
|
+
generator = Gooby::GoogleMapGenerator.new(csv_filename)
|
30
|
+
generator.generate_page(options_obj)
|
31
|
+
end
|
32
|
+
|
33
|
+
end
|
34
|
+
|
35
|
+
end # end of module
|
@@ -0,0 +1,18 @@
|
|
1
|
+
module Gooby
|
2
|
+
|
3
|
+
=begin rdoc
|
4
|
+
This is the abstract superclass of several Gooby classes.
|
5
|
+
Includes modules GoobyIO, Introspect, and GoobyProjectInfo.
|
6
|
+
=end
|
7
|
+
|
8
|
+
class GoobyObject
|
9
|
+
|
10
|
+
include Gooby::GoobyIO
|
11
|
+
include Gooby::GoobyString
|
12
|
+
include Gooby::Introspect
|
13
|
+
include Gooby::GoobyProjectInfo
|
14
|
+
include Gooby::Con
|
15
|
+
|
16
|
+
end
|
17
|
+
|
18
|
+
end # end of module
|