gooby 1.2.0 → 2.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (257) hide show
  1. data/README +133 -341
  2. data/config/ballantyne.yaml +11 -0
  3. data/config/big_sur_marathon.yaml +11 -0
  4. data/config/crowders_mtn_hike.yaml +11 -0
  5. data/config/davidson1.yaml +16 -0
  6. data/config/gooby_config.yaml +28 -135
  7. data/cucumber.yml +1 -0
  8. data/features/build_gem.feature +88 -0
  9. data/features/gooby.feature +300 -0
  10. data/features/install.feature +78 -0
  11. data/features/steps/gooby_steps.rb +245 -0
  12. data/features/support/env.rb +4 -0
  13. data/lib/gooby.rb +24 -30
  14. data/lib/gooby_activity.rb +63 -0
  15. data/lib/gooby_base_object.rb +46 -0
  16. data/lib/gooby_base_sax_parser.rb +95 -0
  17. data/lib/gooby_configuration.rb +33 -115
  18. data/lib/gooby_counter_hash.rb +28 -87
  19. data/lib/gooby_dttm.rb +88 -66
  20. data/lib/gooby_environment.rb +48 -0
  21. data/lib/gooby_garmin_tcx_parser.rb +92 -0
  22. data/lib/gooby_google_kml_generator.rb +168 -0
  23. data/lib/gooby_google_map_generator.rb +284 -349
  24. data/lib/gooby_gpx_parser.rb +97 -0
  25. data/lib/gooby_help_producer.rb +40 -0
  26. data/lib/gooby_introspection.rb +25 -0
  27. data/lib/gooby_io.rb +30 -0
  28. data/lib/gooby_lap.rb +27 -18
  29. data/lib/gooby_process.rb +281 -0
  30. data/lib/gooby_sax_path_parser.rb +43 -0
  31. data/lib/gooby_tcx_extractor.rb +71 -0
  32. data/lib/gooby_track_log_parser.rb +114 -0
  33. data/lib/gooby_trackpoint.rb +276 -0
  34. data/lib/gooby_xml_object.rb +40 -0
  35. data/{img/gicons → out/images}/blank.png +0 -0
  36. data/{img/gicons → out/images}/dd-end.png +0 -0
  37. data/{img/gicons → out/images}/dd-start.png +0 -0
  38. data/{img/gicons → out/images}/marker.png +0 -0
  39. data/{img/gicons → out/images}/marker0.png +0 -0
  40. data/{img/gicons → out/images}/marker00.png +0 -0
  41. data/{img/gicons → out/images}/marker01.png +0 -0
  42. data/{img/gicons → out/images}/marker02.png +0 -0
  43. data/{img/gicons → out/images}/marker03.png +0 -0
  44. data/{img/gicons → out/images}/marker04.png +0 -0
  45. data/{img/gicons → out/images}/marker05.png +0 -0
  46. data/{img/gicons → out/images}/marker06.png +0 -0
  47. data/{img/gicons → out/images}/marker07.png +0 -0
  48. data/{img/gicons → out/images}/marker08.png +0 -0
  49. data/{img/gicons → out/images}/marker09.png +0 -0
  50. data/{img/gicons → out/images}/marker1.png +0 -0
  51. data/{img/gicons → out/images}/marker10.png +0 -0
  52. data/{img/gicons → out/images}/marker11.png +0 -0
  53. data/{img/gicons → out/images}/marker12.png +0 -0
  54. data/{img/gicons → out/images}/marker13.png +0 -0
  55. data/{img/gicons → out/images}/marker14.png +0 -0
  56. data/{img/gicons → out/images}/marker15.png +0 -0
  57. data/{img/gicons → out/images}/marker16.png +0 -0
  58. data/{img/gicons → out/images}/marker17.png +0 -0
  59. data/{img/gicons → out/images}/marker18.png +0 -0
  60. data/{img/gicons → out/images}/marker19.png +0 -0
  61. data/{img/gicons → out/images}/marker2.png +0 -0
  62. data/{img/gicons → out/images}/marker20.png +0 -0
  63. data/{img/gicons → out/images}/marker21.png +0 -0
  64. data/{img/gicons → out/images}/marker22.png +0 -0
  65. data/{img/gicons → out/images}/marker23.png +0 -0
  66. data/{img/gicons → out/images}/marker24.png +0 -0
  67. data/{img/gicons → out/images}/marker25.png +0 -0
  68. data/{img/gicons → out/images}/marker26.png +0 -0
  69. data/{img/gicons → out/images}/marker27.png +0 -0
  70. data/{img/gicons → out/images}/marker28.png +0 -0
  71. data/{img/gicons → out/images}/marker29.png +0 -0
  72. data/{img/gicons → out/images}/marker3.png +0 -0
  73. data/{img/gicons → out/images}/marker30.png +0 -0
  74. data/{img/gicons → out/images}/marker31.png +0 -0
  75. data/{img/gicons → out/images}/marker32.png +0 -0
  76. data/{img/gicons → out/images}/marker33.png +0 -0
  77. data/{img/gicons → out/images}/marker34.png +0 -0
  78. data/{img/gicons → out/images}/marker35.png +0 -0
  79. data/{img/gicons → out/images}/marker36.png +0 -0
  80. data/{img/gicons → out/images}/marker37.png +0 -0
  81. data/{img/gicons → out/images}/marker38.png +0 -0
  82. data/{img/gicons → out/images}/marker39.png +0 -0
  83. data/{img/gicons → out/images}/marker4.png +0 -0
  84. data/{img/gicons → out/images}/marker40.png +0 -0
  85. data/{img/gicons → out/images}/marker41.png +0 -0
  86. data/{img/gicons → out/images}/marker42.png +0 -0
  87. data/{img/gicons → out/images}/marker43.png +0 -0
  88. data/{img/gicons → out/images}/marker44.png +0 -0
  89. data/{img/gicons → out/images}/marker45.png +0 -0
  90. data/{img/gicons → out/images}/marker46.png +0 -0
  91. data/{img/gicons → out/images}/marker47.png +0 -0
  92. data/{img/gicons → out/images}/marker48.png +0 -0
  93. data/{img/gicons → out/images}/marker49.png +0 -0
  94. data/{img/gicons → out/images}/marker5.png +0 -0
  95. data/{img/gicons → out/images}/marker50.png +0 -0
  96. data/{img/gicons → out/images}/marker51.png +0 -0
  97. data/{img/gicons → out/images}/marker52.png +0 -0
  98. data/{img/gicons → out/images}/marker53.png +0 -0
  99. data/{img/gicons → out/images}/marker54.png +0 -0
  100. data/{img/gicons → out/images}/marker55.png +0 -0
  101. data/{img/gicons → out/images}/marker56.png +0 -0
  102. data/{img/gicons → out/images}/marker57.png +0 -0
  103. data/{img/gicons → out/images}/marker58.png +0 -0
  104. data/{img/gicons → out/images}/marker59.png +0 -0
  105. data/{img/gicons → out/images}/marker6.png +0 -0
  106. data/{img/gicons → out/images}/marker60.png +0 -0
  107. data/{img/gicons → out/images}/marker61.png +0 -0
  108. data/{img/gicons → out/images}/marker62.png +0 -0
  109. data/{img/gicons → out/images}/marker63.png +0 -0
  110. data/{img/gicons → out/images}/marker64.png +0 -0
  111. data/{img/gicons → out/images}/marker65.png +0 -0
  112. data/{img/gicons → out/images}/marker66.png +0 -0
  113. data/{img/gicons → out/images}/marker67.png +0 -0
  114. data/{img/gicons → out/images}/marker68.png +0 -0
  115. data/{img/gicons → out/images}/marker69.png +0 -0
  116. data/{img/gicons → out/images}/marker7.png +0 -0
  117. data/{img/gicons → out/images}/marker70.png +0 -0
  118. data/{img/gicons → out/images}/marker71.png +0 -0
  119. data/{img/gicons → out/images}/marker72.png +0 -0
  120. data/{img/gicons → out/images}/marker73.png +0 -0
  121. data/{img/gicons → out/images}/marker74.png +0 -0
  122. data/{img/gicons → out/images}/marker75.png +0 -0
  123. data/{img/gicons → out/images}/marker76.png +0 -0
  124. data/{img/gicons → out/images}/marker77.png +0 -0
  125. data/{img/gicons → out/images}/marker78.png +0 -0
  126. data/{img/gicons → out/images}/marker79.png +0 -0
  127. data/{img/gicons → out/images}/marker8.png +0 -0
  128. data/{img/gicons → out/images}/marker80.png +0 -0
  129. data/{img/gicons → out/images}/marker81.png +0 -0
  130. data/{img/gicons → out/images}/marker82.png +0 -0
  131. data/{img/gicons → out/images}/marker83.png +0 -0
  132. data/{img/gicons → out/images}/marker84.png +0 -0
  133. data/{img/gicons → out/images}/marker85.png +0 -0
  134. data/{img/gicons → out/images}/marker86.png +0 -0
  135. data/{img/gicons → out/images}/marker87.png +0 -0
  136. data/{img/gicons → out/images}/marker88.png +0 -0
  137. data/{img/gicons → out/images}/marker89.png +0 -0
  138. data/{img/gicons → out/images}/marker9.png +0 -0
  139. data/{img/gicons → out/images}/marker90.png +0 -0
  140. data/{img/gicons → out/images}/marker91.png +0 -0
  141. data/{img/gicons → out/images}/marker92.png +0 -0
  142. data/{img/gicons → out/images}/marker93.png +0 -0
  143. data/{img/gicons → out/images}/marker94.png +0 -0
  144. data/{img/gicons → out/images}/marker95.png +0 -0
  145. data/{img/gicons → out/images}/marker96.png +0 -0
  146. data/{img/gicons → out/images}/marker97.png +0 -0
  147. data/{img/gicons → out/images}/marker98.png +0 -0
  148. data/{img/gicons → out/images}/marker99.png +0 -0
  149. data/{img/gicons → out/images}/markerA.png +0 -0
  150. data/{img/gicons → out/images}/markerB.png +0 -0
  151. data/{img/gicons → out/images}/markerC.png +0 -0
  152. data/{img/gicons → out/images}/markerD.png +0 -0
  153. data/{img/gicons → out/images}/markerE.png +0 -0
  154. data/{img/gicons → out/images}/markerF.png +0 -0
  155. data/{img/gicons → out/images}/markerG.png +0 -0
  156. data/{img/gicons → out/images}/markerH.png +0 -0
  157. data/{img/gicons → out/images}/markerI.png +0 -0
  158. data/{img/gicons → out/images}/markerJ.png +0 -0
  159. data/{img/gicons → out/images}/mm_20_red.png +0 -0
  160. data/{img/gicons → out/images}/mm_20_shadow.png +0 -0
  161. data/{img/gicons → out/images}/shadow50.png +0 -0
  162. data/rakefile.rb +79 -0
  163. data/samples.sh +21 -0
  164. data/samples/2008_04_27_13_49_50_tcx.csv +2449 -0
  165. data/samples/2008_04_27_13_49_50_tcx.xml +24560 -0
  166. data/samples/2009_01_01_14_45_00_tcx.xml +10630 -0
  167. data/samples/ballantyne.csv +27 -0
  168. data/samples/ballantyne.gpx +117 -0
  169. data/samples/ballantyne.kml +91 -0
  170. data/samples/big_sur_marathon.html +2766 -0
  171. data/samples/big_sur_marathon.kml +685 -0
  172. data/samples/build_gem_test_results.txt +6 -0
  173. data/samples/crowders_mtn_hike.csv +1065 -0
  174. data/samples/crowders_mtn_hike.html +1283 -0
  175. data/samples/crowders_mtn_hike.log +1 -0
  176. data/samples/cucumber_test_results.txt +302 -0
  177. data/samples/davidson1.csv +1 -0
  178. data/samples/davidson1.html +75 -0
  179. data/samples/davidson_1_point_tcx.csv +0 -0
  180. data/samples/doc.kml +49 -0
  181. data/samples/gps_track_log_asheville_mt_pisgah.txt +1 -0
  182. data/samples/gps_track_logs.txt +1 -0
  183. data/samples/install_test_results.txt +81 -0
  184. data/samples/mt_pisgah.txt +1 -0
  185. data/samples/rspec_test_results.txt +5 -0
  186. data/setup.rb +66 -0
  187. data/spec/gooby_base_object_spec.rb +116 -0
  188. data/spec/gooby_counter_hash_spec.rb +34 -0
  189. data/spec/gooby_dttm_spec.rb +40 -0
  190. data/spec/gooby_spec_helper.rb +9 -0
  191. data/spec/gooby_xml_object_spec.rb +32 -0
  192. metadata +225 -226
  193. data/bin/code_scan.rb +0 -16
  194. data/bin/gooby_been_there.rb +0 -33
  195. data/bin/gooby_config.rb +0 -24
  196. data/bin/gooby_csv_validation.rb +0 -50
  197. data/bin/gooby_first_trackpoints_as_poi.rb +0 -31
  198. data/bin/gooby_gen_gmap.rb +0 -20
  199. data/bin/gooby_parser.rb +0 -21
  200. data/bin/gooby_splitter.rb +0 -21
  201. data/bin/gooby_version.rb +0 -20
  202. data/bin/run_all.sh +0 -33
  203. data/bin/run_been_there.sh +0 -19
  204. data/bin/run_config.sh +0 -12
  205. data/bin/run_csv_validation.sh +0 -15
  206. data/bin/run_db_gen.sh +0 -11
  207. data/bin/run_db_load.sh +0 -11
  208. data/bin/run_first_trackpoints_as_poi.sh +0 -16
  209. data/bin/run_gen_gmaps.sh +0 -21
  210. data/bin/run_parse_full.sh +0 -45
  211. data/bin/run_parse_samples.sh +0 -21
  212. data/bin/run_split.sh +0 -24
  213. data/bin/run_version.sh +0 -12
  214. data/data/20050305_corporate_cup_hm.csv +0 -251
  215. data/data/20050305_corporate_cup_hm.xml +0 -2208
  216. data/data/20050430_nashville_marathon.xml +0 -10043
  217. data/data/20050430_nashville_marathon_km.csv +0 -1208
  218. data/data/20060115_phoenix_marathon.csv +0 -1280
  219. data/data/20060115_phoenix_marathon.xml +0 -10620
  220. data/data/20070101_davidson_11m.csv +0 -251
  221. data/data/20070101_davidson_11m.xml +0 -2020
  222. data/data/20070505_davidson_5k.xml +0 -2875
  223. data/data/20070505_davidson_5k_km.csv +0 -286
  224. data/data/hrm1.csv +0 -5
  225. data/img/gicons/readme.txt +0 -14
  226. data/lib/gooby_code_scanner.rb +0 -288
  227. data/lib/gooby_command.rb +0 -210
  228. data/lib/gooby_course.rb +0 -117
  229. data/lib/gooby_csv_point.rb +0 -71
  230. data/lib/gooby_csv_reader.rb +0 -71
  231. data/lib/gooby_csv_run.rb +0 -28
  232. data/lib/gooby_delim_line.rb +0 -42
  233. data/lib/gooby_duration.rb +0 -86
  234. data/lib/gooby_forerunner_xml_parser.rb +0 -191
  235. data/lib/gooby_forerunner_xml_splitter.rb +0 -115
  236. data/lib/gooby_history.rb +0 -41
  237. data/lib/gooby_kernel.rb +0 -163
  238. data/lib/gooby_line.rb +0 -80
  239. data/lib/gooby_object.rb +0 -22
  240. data/lib/gooby_point.rb +0 -172
  241. data/lib/gooby_run.rb +0 -213
  242. data/lib/gooby_simple_xml_parser.rb +0 -50
  243. data/lib/gooby_test_helper.rb +0 -23
  244. data/lib/gooby_track.rb +0 -47
  245. data/lib/gooby_track_point.rb +0 -229
  246. data/lib/gooby_training_center_xml_parser.rb +0 -224
  247. data/lib/gooby_training_center_xml_splitter.rb +0 -116
  248. data/lib/split_code.sh +0 -29
  249. data/samples/20050305_corporate_cup_hm.html +0 -450
  250. data/samples/20050430_nashville_marathon.html +0 -1668
  251. data/samples/20060115_phoenix_marathon.html +0 -1596
  252. data/samples/20070101_davidson_11m.html +0 -432
  253. data/samples/20070505_davidson_5k.html +0 -413
  254. data/samples/been_there.txt +0 -92
  255. data/samples/hrm1.html +0 -87
  256. data/sql/gooby.ddl +0 -60
  257. data/sql/gooby_load.dml +0 -62
@@ -0,0 +1,48 @@
1
+ =begin
2
+
3
+ Gooby = Google APIs + Ruby. Copyright 2009 by Chris Joakim.
4
+ Gooby is available under GNU General Public License (GPL) license.
5
+
6
+ =end
7
+
8
+ module GoobyEnvironment
9
+
10
+ def command_line_arg(arg_name, default_value=nil)
11
+ value = ENV[arg_name]
12
+ (value.nil?) ? default_value : value
13
+ end
14
+
15
+ def boolean_param(name, default=false)
16
+ value = ENV[name.to_s]
17
+ return default if value.nil?
18
+ return true if (value.downcase == 'true') || (value.downcase == 't')
19
+ return false if (value.downcase == 'false') || (value.downcase == 'f')
20
+ default
21
+ end
22
+
23
+ def integer_param(name, default=0)
24
+ (ENV[name.to_s]) ? ENV[name.to_s].to_i : default.to_i
25
+ end
26
+
27
+ def float_param(name, default=0.0)
28
+ (ENV[name.to_s]) ? ENV[name.to_s].to_f : default.to_f
29
+ end
30
+
31
+ def string_param(name, default='')
32
+ (ENV[name.to_s]) ? ENV[name.to_s] : default.to_s
33
+ end
34
+
35
+ def array_param(name, default=[])
36
+ array = []
37
+ csv_value = string_param(name.to_s, nil)
38
+ if csv_value
39
+ FasterCSV.parse(csv_value) do | row |
40
+ row.each { | value | array << value }
41
+ end
42
+ array
43
+ else
44
+ default
45
+ end
46
+ end
47
+
48
+ end
@@ -0,0 +1,92 @@
1
+ =begin
2
+
3
+ Gooby = Google APIs + Ruby. Copyright 2009 by Chris Joakim.
4
+ Gooby is available under GNU General Public License (GPL) license.
5
+
6
+ ---
7
+
8
+ This class is used to parse a Garmin tcx xml file, such as from a Garmin 305 device
9
+ as exported by the Garmin Training Center software.
10
+
11
+ =end
12
+
13
+ class GoobyGarminTcxParser < GoobyBaseSaxParser
14
+
15
+ def subclass_initialize
16
+ @tags, @activities, @mappings = [], [], {}
17
+ end
18
+
19
+ def on_start_element(name, attributes, prefix=nil, uri=nil, namespaces=nil)
20
+ @tags.push(name)
21
+ @current_text = ''
22
+ path = current_path
23
+ if path == 'TrainingCenterDatabase|Activities|Activity'
24
+ @current_activity = GoobyActivity.new(attributes)
25
+ @activities << @current_activity
26
+
27
+ elsif path == 'TrainingCenterDatabase|Activities|Activity|Lap'
28
+ @current_lap = GoobyLap.new(attributes)
29
+ @current_activity.add_lap(@current_lap)
30
+
31
+ elsif path == 'TrainingCenterDatabase|Activities|Activity|Lap|Track|Trackpoint'
32
+ @current_trackpoint = GoobyTrackpoint.new
33
+ @current_trackpoint.set('ActivityId', @current_activity.id)
34
+ @current_trackpoint.set('LapSeq', @current_lap.sequence)
35
+ @current_trackpoint.set('LapStartTime', @current_lap.start_time)
36
+ @current_activity.add_trackpoint(@current_trackpoint)
37
+ end
38
+ end
39
+
40
+ def on_end_element(name, prefix=nil, uri=nil)
41
+ path = current_path
42
+ # Activity
43
+ if path == 'TrainingCenterDatabase|Activities|Activity|Id'
44
+ @current_activity.set(name, get_current_text)
45
+
46
+ # Lap
47
+ elsif path == 'TrainingCenterDatabase|Activities|Activity|Lap|DistanceMeters'
48
+ @current_lap.set(name, get_current_text)
49
+ elsif path == 'TrainingCenterDatabase|Activities|Activity|Lap|MaximumSpeed'
50
+ @current_lap.set(name, get_current_text)
51
+ elsif path == 'TrainingCenterDatabase|Activities|Activity|Lap|TotalTimeSeconds'
52
+ @current_lap.set(name, get_current_text)
53
+
54
+ # Trackpoint
55
+ elsif path == 'TrainingCenterDatabase|Activities|Activity|Lap|Track|Trackpoint|Time'
56
+ @current_trackpoint.set(name, get_current_text)
57
+ elsif path == 'TrainingCenterDatabase|Activities|Activity|Lap|Track|Trackpoint|Position|LatitudeDegrees'
58
+ @current_trackpoint.set(name, get_current_text)
59
+ elsif path == 'TrainingCenterDatabase|Activities|Activity|Lap|Track|Trackpoint|Position|LongitudeDegrees'
60
+ @current_trackpoint.set(name, get_current_text)
61
+ elsif path == 'TrainingCenterDatabase|Activities|Activity|Lap|Track|Trackpoint|AltitudeMeters'
62
+ @current_trackpoint.set(name, get_current_text)
63
+ elsif path == 'TrainingCenterDatabase|Activities|Activity|Lap|Track|Trackpoint|DistanceMeters'
64
+ @current_trackpoint.set(name, get_current_text)
65
+
66
+ end
67
+ @current_text = ''
68
+ @tags.pop
69
+ end
70
+
71
+ def current_path
72
+ @tags.join('|')
73
+ end
74
+
75
+ def dump_activities
76
+ @activities.each { | activity | activity.dump }
77
+ end
78
+
79
+ def post_process
80
+ @activities.each { | activity | activity.post_process }
81
+ end
82
+
83
+ def trackpoints_to_csv
84
+ lines = []
85
+ @activities.each { | activity |
86
+ activity_csv_lines = activity.trackpoints_csv
87
+ activity_csv_lines.each { | line | lines << line }
88
+ }
89
+ lines
90
+ end
91
+
92
+ end
@@ -0,0 +1,168 @@
1
+ =begin
2
+
3
+ Gooby = Google APIs + Ruby. Copyright 2009 by Chris Joakim.
4
+ Gooby is available under GNU General Public License (GPL) license.
5
+
6
+ =end
7
+
8
+ class GoobyGoogleKmlGenerator < GoobyBaseObject
9
+
10
+ include GoobyConfiguration
11
+
12
+ def initialize
13
+ @trackpoints = []
14
+ end
15
+
16
+ def generate(config_file)
17
+ read_configuration(config_file)
18
+ read_csv_file
19
+ collect_placemarks
20
+ collect_coordinates
21
+ template = ERB.new(kml_document_template, 0, "<>")
22
+ result = template.result(binding)
23
+ kmz_build = @configuration['kmz_build']
24
+ kmz_build_command = @configuration['kmz_build_command']
25
+ if kmz_build && kmz_build_command
26
+ out_file = 'out/doc.kml'
27
+ out = File.new out_file, "w+"
28
+ out.write result
29
+ out.flush
30
+ out.close
31
+ puts "file created: #{out_file}"
32
+ puts "executing kmz build command: #{kmz_build_command}"
33
+ `#{kmz_build_command}`
34
+ puts "kmz build completed"
35
+ else
36
+ out_file = @configuration['kml_file'] ||= 'kml/gooby_google_earth_map.kml'
37
+ out = File.new out_file, "w+"
38
+ out.write result
39
+ out.flush
40
+ out.close
41
+ puts "file created: #{out_file}"
42
+ end
43
+ end
44
+
45
+ def read_csv_file
46
+ csv_file = @configuration['csv_file']
47
+ first_point = @configuration['first_point'].to_i
48
+ last_point = @configuration['last_point'].to_i
49
+ puts "reading csv_file #{csv_file} first_point: #{first_point} last_point: #{last_point}"
50
+ row_number = 0
51
+ FasterCSV.foreach(csv_file) do | row |
52
+ row_number = row_number + 1
53
+ tkpt = GoobyTrackpoint.new
54
+ tkpt.from_csv(row)
55
+ if (row_number >= first_point) && (row_number <= last_point)
56
+ @trackpoints << tkpt
57
+ end
58
+ end
59
+ puts "csv_file #{csv_file} has been read; #{@trackpoints.size} trackpoints included"
60
+ end
61
+
62
+ def collect_placemarks
63
+ generate_mile_markers = @configuration['mile_markers']
64
+ @placemarks, next_checkpoint_f, next_checkpoint_i = [], 0.0, 0
65
+ first_tkpt, last_index = nil, @trackpoints.size - 1
66
+ @trackpoints.each_with_index { | tkpt, index |
67
+ if index == 0
68
+ first_tkpt = tkpt
69
+ end
70
+ if (tkpt.distance >= next_checkpoint_f) || (index == 0) || (index == last_index)
71
+ if next_checkpoint_i == 0
72
+ tkpt.set('PlacemarkName', 'Start')
73
+ tkpt.set('PlacemarkIcon', 'images/dd-start.png')
74
+ elsif index == last_index
75
+ tkpt.set('PlacemarkName', 'Finish')
76
+ tkpt.set('PlacemarkIcon', 'images/dd-end.png')
77
+ next_checkpoint_i = 999999
78
+ else
79
+ if generate_mile_markers
80
+ tkpt.set('PlacemarkName', '')
81
+ tkpt.set('PlacemarkIcon', "images/marker#{next_checkpoint_i.to_s}.png")
82
+ end
83
+ end
84
+ tkpt.set('PlacemarkDescription', tkpt.as_info_window_html(next_checkpoint_i, first_tkpt.dttm))
85
+ tkpt.set('PlacemarkCoordinates', "#{tkpt.longitude},#{tkpt.latitude},1")
86
+ @placemarks << tkpt
87
+ next_checkpoint_i = next_checkpoint_i + 1
88
+ next_checkpoint_f = next_checkpoint_f + 1.0
89
+ end
90
+ }
91
+ end
92
+
93
+ def collect_coordinates
94
+ tkpt_count = @trackpoints.size.to_f
95
+ last_idx = tkpt_count - 1
96
+ next_idx = 0
97
+ app_max = @configuration['approx_max_points'].to_f
98
+ ratio = tkpt_count / app_max
99
+ if ratio > 1.0
100
+ increment = (tkpt_count / app_max).to_i
101
+ else
102
+ increment = 1
103
+ end
104
+ @coordinates = ''
105
+ @trackpoints.each_with_index { | tkpt, idx |
106
+ if (idx == 0) || (idx == last_idx) || (idx == next_idx)
107
+ @coordinates << " #{tkpt.longitude},#{tkpt.latitude},1\n"
108
+ next_idx = idx + increment
109
+ end
110
+ }
111
+ end
112
+
113
+ def kml_document_template
114
+ template = <<HEREDOC
115
+ <?xml version="1.0" encoding="UTF-8"?>
116
+ <kml xmlns="http://www.opengis.net/kml/2.2">
117
+ <Document>
118
+ <!-- kml file generated by Gooby version 2.0.0 -->
119
+ <name><%= @configuration['map_title'] %></name>
120
+ <Style id="goobyStyle">
121
+ <BalloonStyle>
122
+ <text>$[description]</text>
123
+ </BalloonStyle>
124
+ <LineStyle>
125
+ <color>7f0000ff</color>
126
+ <width>4</width>
127
+ </LineStyle>
128
+ <PolyStyle>
129
+ <color>7f0000ff</color>
130
+ </PolyStyle>
131
+ </Style>
132
+ <% @placemarks.each do | tkpt | %>
133
+ <Placemark>
134
+ <name><%= tkpt.get('PlacemarkName') %></name>
135
+ <description><%= tkpt.get('PlacemarkDescription') %></description>
136
+ <Style>
137
+ <IconStyle>
138
+ <Icon>
139
+ <href><%= tkpt.get('PlacemarkIcon') %></href>
140
+ </Icon>
141
+ </IconStyle>
142
+ </Style>
143
+ <styleUrl>#goobyStyle</styleUrl>
144
+ <Point>
145
+ <coordinates><%= tkpt.get('PlacemarkCoordinates') %></coordinates>
146
+ </Point>
147
+ </Placemark>
148
+ <% end %>
149
+ <Placemark>
150
+ <name>Route</name>
151
+ <visibility>1</visibility>
152
+ <description>Route</description>
153
+ <styleUrl>#goobyStyle</styleUrl>
154
+ <LineString>
155
+ <tessellate>1</tessellate>
156
+ <altitudeMode>relativeToGround</altitudeMode>
157
+ <coordinates>
158
+ <%= @coordinates %>
159
+ </coordinates>
160
+ </LineString>
161
+ </Placemark>
162
+ </Document>
163
+ </kml>
164
+ HEREDOC
165
+ template
166
+ end
167
+
168
+ end
@@ -1,385 +1,320 @@
1
1
  =begin
2
2
 
3
- Gooby = Google APIs + Ruby
4
- Gooby - Copyright 2007 by Chris Joakim.
3
+ Gooby = Google APIs + Ruby. Copyright 2009 by Chris Joakim.
5
4
  Gooby is available under GNU General Public License (GPL) license.
6
5
 
7
6
  =end
8
7
 
9
- module Gooby
8
+ class GoobyGoogleMapGenerator < GoobyBaseObject
10
9
 
11
- =begin rdoc
12
- Instances of this class represent a <Run> aggregate object from a
13
- Forerunner XML file.
14
-
15
- Additionally, there is distance, pace, and Google Map generation logic
16
- in this class.
17
- =end
10
+ include GoobyConfiguration
18
11
 
19
- class GoogleMapGenerator < GoobyObject
12
+ attr_reader :csv_file, :csv_lines, :dttm_idx, :num_idx, :lat_idx, :lng_idx, :alt_idx, :cdist_idx
13
+ attr_reader :run, :tkpts, :content_hash, :center_longitude, :center_latitude, :gpoint_array, :overlay_points, :notes
14
+ attr_reader :center_longitude, :center_latitude
20
15
 
21
- attr_reader :csv_file, :csv_lines, :dttm_idx, :num_idx, :lat_idx, :lng_idx, :alt_idx, :cdist_idx
22
- attr_reader :run, :tkpts, :content_hash, :center_longitude, :center_latitude, :gpoint_array, :overlay_points, :notes
23
- attr_reader :center_longitude, :center_latitude
24
-
25
- # The default csv input file format is as follows:
26
- # 1 | 2006-01-15T18:31:10Z | 1279 | 33.42601 | -111.92927 | 347.654 | 26.3514930151813
27
- # 1 | 2004-11-13T13:05:20Z | 2 | 37.54318 | -77.43636 | -58.022 | 0.00297286231747969
28
-
29
- def initialize(csv_file, dttm_idx=1, num_idx=4, lat_idx=5, lng_idx=6, alt_idx=7, cdist_idx=8)
30
- @csv_file = csv_file
31
- @dttm_idx = dttm_idx
32
- @num_idx = num_idx
33
- @lat_idx = lat_idx
34
- @lng_idx = lng_idx
35
- @alt_idx = alt_idx
36
- @cdist_idx = cdist_idx
37
-
38
- # Override default csv value indices if specified in the configuration yaml file.
39
- @configuration = Gooby::Configuration.get_config
40
- @dttm_idx = @configuration.get('csv_dttm_idx') if @configuration.get('csv_dttm_idx')
41
- @num_idx = @configuration.get('csv_num_idx') if @configuration.get('csv_num_idx')
42
- @lat_idx = @configuration.get('csv_lat_idx') if @configuration.get('csv_lat_idx')
43
- @lng_idx = @configuration.get('csv_lng_idx') if @configuration.get('csv_lng_idx')
44
- @alt_idx = @configuration.get('csv_alt_idx') if @configuration.get('csv_alt_idx')
45
- @title = @configuration.get("#{@csv_file}")
46
-
47
- @content_hash = Hash.new('')
48
- @run = Gooby::Run.new(1)
49
- @track = Gooby::Track.new(1)
50
- @run.add_track(@track)
51
- @tkpts = Array.new
52
- @icon_url_base = @configuration.get('gmap_icon_url_base')
53
-
54
- list = Array.new
55
- list << @csv_file
56
- @csv_reader = Gooby::CsvReader.new(list)
57
- @csv_points = @csv_reader.read
58
- @csv_points.each { |csv_point|
59
- tkpt = csv_point.as_trackpoint
60
- if tkpt
61
- @track.add_trackpoint(tkpt)
62
- end
63
- }
64
- @run.finish
65
- end
66
-
67
- =begin
68
- Returns a Hash with specific generated content at the following keys:
69
- =end
70
- def generate(configuration)
71
- if (configuration == nil)
72
- @configuration = Gooby::Configuration.get_config
73
- else
74
- @configuration = configuration
75
- end
76
- @content_hash['when_generated'] = Time.now
77
- @content_hash['title'] = @title
78
- @icon_url_base = @configuration.get('gmap_icon_url_base')
79
- filter_trackpoints
80
- compute_center_point
81
- generate_key_js
82
- generate_map_div
83
- generate_messages_div
84
- generate_main_js_start
85
- generate_main_js_route_overlay
86
- generate_main_js_checkpoint_overlays
87
- generate_main_js_map_clicked_listeners
88
- generate_main_js_end
89
- @content_hash
90
- end
91
-
92
- def filter_trackpoints
93
- count, @tkpts = 0, Array.new
94
- firstTkpt = @configuration.get('gmap_first_tkpt_number')
95
- lastTkpt = @configuration.get('gmap_last_tkpt_number')
96
- @run.tracks.each { |trk|
97
- trk.trackpoints.each { |tkpt|
98
- count = count + 1
99
- if ((count >= firstTkpt) && (count <= lastTkpt))
100
- @tkpts.push(tkpt)
101
- end
102
- }
103
- }
104
- end
105
-
106
- =begin
107
- Returns a Hash with specific generated content at the following keys:
108
- =end
109
- def generate_page(configuration)
110
-
111
- # puts "generate_page #{@csv_file} #{@csv_lines.size}"
112
- content_hash = generate(nil)
113
- s = String.new(@csv_file)
114
- s.gsub("/", " ")
115
- tokens = tokenize(s, nil)
116
- out_file = "#{tokens[-2]}.html"
117
- #content_hash.keys.sort.each { | key | puts key }
16
+ def initialize
17
+ @content_hash, @trackpoints = Hash.new(''), []
18
+ end
19
+
20
+ # 2009_01_01_14_45_00_tcx.xml
21
+
22
+ def generate(config_file)
23
+ read_configuration(config_file)
24
+ read_csv_file
25
+ compute_center_point
26
+ generate_key_js
27
+ generate_map_div
28
+ generate_messages_div
29
+ generate_main_js_start
30
+ generate_main_js_route_overlay
31
+ generate_main_js_checkpoint_overlays
32
+ generate_main_js_map_clicked_listeners
33
+ generate_main_js_end
118
34
 
119
- s = <<HERE
35
+ s = <<HERE
120
36
  <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
121
- "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
37
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
122
38
  <html xmlns="http://www.w3.org/1999/xhtml">
123
- <head>
124
- <meta http-equiv="content-type" content="text/html; charset=utf-8"/>
125
- <meta name="description" content="Google Map generated with #{project_embedded_comment}">
126
- <meta name="keywords" content="Google Map #{project_embedded_comment} GPS">
127
- <title> Google Map by Gooby </title>
128
- #{content_hash['key_js']}
129
- #{content_hash['main_js_start']}
130
- #{content_hash['main_js_route_overlay']}
131
- #{content_hash['main_js_checkpoint_overlays']}
132
- #{content_hash['main_js_map_clicked_listeners']}
133
- #{content_hash['main_js_end']}
134
- </head>
135
- <body onload="load()" onunload="GUnload()">
136
- <center>
137
- <h3> #{@title} </h3>
138
- <h5> Generated by Gooby #{content_hash['when_generated']} <br> Gooby = Google APIs + Ruby </h5>
139
- #{content_hash['map_div']}
140
- #{content_hash['messages_div']}
141
- </center>
142
- </body>
39
+ <head>
40
+ <meta http-equiv="content-type" content="text/html; charset=utf-8"/>
41
+ <meta name="description" content="Google Map generated by Gooby version 2.0.0">
42
+ <meta name="keywords" content="Google Map Generated by Gooby version 2.0.0">
43
+ <title> #{@configuration['map_title']} </title>
44
+ #{@content_hash['key_js']}
45
+ #{@content_hash['main_js_start']}
46
+ #{@content_hash['main_js_route_overlay']}
47
+ #{@content_hash['main_js_checkpoint_overlays']}
48
+ #{@content_hash['main_js_map_clicked_listeners']}
49
+ #{@content_hash['main_js_end']}
50
+ </head>
51
+ <body onload="load()" onunload="GUnload()">
52
+ <center>
53
+ <h3> #{@configuration['map_title']} </h3>
54
+ #{@content_hash['map_div']}
55
+ #{@content_hash['messages_div']}
56
+ </center>
57
+ </body>
143
58
  </html>
144
59
  HERE
145
- puts s # Redirect output via shell.
146
- end
147
-
148
- private
149
-
150
- def compute_center_point
151
- highLat = -999.0
152
- highLong = -999.0
153
- lowLat = 999.0
154
- lowLong = 999.0
155
- @tkpts.each { |tkpt|
156
- highLat = tkpt.latitude_as_float if tkpt.latitude_as_float > highLat
157
- lowLat = tkpt.latitude_as_float if tkpt.latitude_as_float < lowLat
158
- highLong = tkpt.longitude_as_float if tkpt.longitude_as_float > highLong
159
- lowLong = tkpt.longitude_as_float if tkpt.longitude_as_float < lowLong
160
- }
161
- @center_longitude = (highLong + lowLong) / 2
162
- @center_latitude = (highLat + lowLat) / 2
163
- @content_hash['center_longitude'] = @center_longitude
164
- @content_hash['center_latitude'] = @center_latitude
165
- end
166
-
167
- def generate_key_js
168
- key = @configuration.get('gmap_key')
169
- key.strip!
170
- # <script src="http://maps.google.com/maps?file=api&v=2&key=<%= @gmap_key -%>" type="text/javascript"></script>
171
- s = "<script src='http://maps.google.com/maps?file=api&v=2&key="
172
- s << key
173
- s << "' type='text/javascript'></script>"
174
- @content_hash['key_js'] = s
175
- end
176
-
177
- def generate_map_div
178
- width = @configuration.get('gmap_width')
179
- height = @configuration.get('gmap_height')
180
- id = @configuration.get('gmap_map_element_id')
181
- s = '<div id="'
182
- s << id
183
- s << '" style="width: '
184
- s << width
185
- s << '; height: '
186
- s << height
187
- s << '"></div>'
188
- @content_hash['map_width'] = width
189
- @content_hash['map_height'] = height
190
- @content_hash['map_div'] = s
60
+ out_file = @configuration['html_file'] ||= 'html/gooby_google_map.html'
61
+ write_file(out_file, s)
62
+ puts "file created: #{out_file}"
63
+ end
64
+
65
+ def read_csv_file
66
+ csv_file = @configuration['csv_file']
67
+ first_point = @configuration['first_point'].to_i
68
+ last_point = @configuration['last_point'].to_i
69
+ puts "reading csv_file #{csv_file} first_point: #{first_point} last_point: #{last_point}"
70
+ row_number = 0
71
+ FasterCSV.foreach(csv_file) do | row |
72
+ row_number = row_number + 1
73
+ tkpt = GoobyTrackpoint.new
74
+ tkpt.from_csv(row)
75
+ if (row_number >= first_point) && (row_number <= last_point)
76
+ @trackpoints << tkpt
77
+ end
191
78
  end
79
+ puts "csv_file #{csv_file} has been read; #{@trackpoints.size} trackpoints included"
80
+ end
81
+
82
+ def compute_center_point
83
+ highLat, highLong, lowLat, lowLong = -999.0, -999.0, 999.0, 999.0
84
+ @trackpoints.each { | tkpt |
85
+ highLat = tkpt.latitude if tkpt.latitude > highLat
86
+ lowLat = tkpt.latitude if tkpt.latitude < lowLat
87
+ highLong = tkpt.longitude if tkpt.longitude > highLong
88
+ lowLong = tkpt.longitude if tkpt.longitude < lowLong
89
+ }
90
+ @center_longitude = (highLong + lowLong) / 2
91
+ @center_latitude = (highLat + lowLat) / 2
92
+ @content_hash['center_longitude'] = @center_longitude
93
+ @content_hash['center_latitude'] = @center_latitude
94
+ end
95
+
96
+ def generate_key_js
97
+ key = @configuration['gmap_key']
98
+ key.strip!
99
+ s = "<script src='http://maps.google.com/maps?file=api&v=2&key="
100
+ s << key
101
+ s << "' type='text/javascript'></script>"
102
+ @content_hash['key_js'] = s
103
+ end
104
+
105
+ def generate_map_div
106
+ width = @configuration['gmap_width']
107
+ height = @configuration['gmap_height']
108
+ id = @configuration['map_element_id']
109
+ s = '<div id="'
110
+ s << id
111
+ s << '" style="width: '
112
+ s << width
113
+ s << '; height: '
114
+ s << height
115
+ s << '"></div>'
116
+ @content_hash['map_width'] = width
117
+ @content_hash['map_height'] = height
118
+ @content_hash['map_div'] = s
119
+ end
192
120
 
193
- def generate_messages_div
194
- s = "<div id=\"messages\"></div>"
195
- @content_hash['messages_div'] = s
121
+ def generate_messages_div
122
+ s = "<div id=\"messages\"></div>"
123
+ @content_hash['messages_div'] = s
124
+ end
125
+
126
+ def generate_main_js_start
127
+ id = @configuration['map_element_id']
128
+ size = @configuration['gmap_size_control']
129
+ type = @configuration['gmap_type']
130
+ zoom = @configuration['gmap_zoom_level']
131
+ title = @configuration["#{@csv_file}"]
132
+ title = '' if title == nil
133
+ zoom_tab = @configuration['gmap_zoom_tab']
134
+ if size
135
+ if size == 'smallmap'
136
+ size = 'GSmallMapControl'
137
+ elsif size == 'smallzoom'
138
+ size = 'GSmallMapControl'
139
+ else
140
+ size = 'GLargeMapControl'
141
+ end
196
142
  end
197
-
198
- def generate_main_js_start
199
- id = @configuration.get('gmap_map_element_id')
200
- size = @configuration.get('gmap_size_control')
201
- type = @configuration.get('gmap_type')
202
- zoom = @configuration.get('gmap_zoom_level')
203
- title = @configuration.get("#{@csv_file}")
204
- title = '' if title == nil
205
- zoom_tab = @configuration.get('gmap_zoom_tab')
206
- if size
207
- if size == 'smallmap'
208
- size = 'GSmallMapControl'
209
- elsif size == 'smallzoom'
210
- size = 'GSmallMapControl'
211
- else
212
- size = 'GLargeMapControl'
213
- end
214
- end
215
-
216
- if type
217
- if type == 'satellite'
218
- type = 'G_SATELLITE_MAP'
219
- elsif type == 'hybrid'
220
- type = 'G_HYBRID_MAP'
221
- else
222
- type = 'G_NORMAL_MAP'
223
- end
143
+
144
+ if type
145
+ if type == 'satellite'
146
+ type = 'G_SATELLITE_MAP'
147
+ elsif type == 'hybrid'
148
+ type = 'G_HYBRID_MAP'
224
149
  else
225
150
  type = 'G_NORMAL_MAP'
226
151
  end
227
-
228
- s = '<script type="text/javascript">'
229
- s << "\n"
230
- s << "//<![CDATA[ \n"
231
- s << " function load() { \n"
232
- s << " if (GBrowserIsCompatible()) { \n"
233
- s << ' var map = new GMap2(document.getElementById("'
234
- s << id
235
- s << '")); '
152
+ else
153
+ type = 'G_NORMAL_MAP'
154
+ end
155
+ s = '<script type="text/javascript">'
156
+ s << "\n"
157
+ s << "//<![CDATA[ \n"
158
+ s << " function load() { \n"
159
+ s << " if (GBrowserIsCompatible()) { \n"
160
+ s << ' var map = new GMap2(document.getElementById("'
161
+ s << id
162
+ s << '")); '
163
+ s << "\n"
164
+
165
+ if size
166
+ s << ' map.addControl(new '
167
+ s << size
168
+ s << '());'
236
169
  s << "\n"
170
+ end
237
171
 
238
- if size
239
- s << ' map.addControl(new '
240
- s << size
241
- s << '());'
242
- s << "\n"
243
- end
244
-
245
- if type
246
- s << ' map.addControl(new GMapTypeControl());'
247
- s << "\n"
248
- # s << ' map.setMapType('
249
- # s << type
250
- # s << ');'
251
- s << "\n"
252
- end
253
- s << " var centerPoint = new GLatLng(#{@center_latitude}, #{@center_longitude}); // #{project_embedded_comment} \n"
254
- s << " map.setCenter(centerPoint, #{zoom}); \n"
172
+ if type
173
+ s << ' map.addControl(new GMapTypeControl());'
174
+ s << "\n"
175
+ # s << ' map.setMapType('
176
+ # s << type
177
+ # s << ');'
255
178
  s << "\n"
256
- @content_hash['main_js_start'] = s
257
- @content_hash['title'] = title
179
+ end
180
+ s << " var centerPoint = new GLatLng(#{@center_latitude}, #{@center_longitude}); // #{project_embedded_comment} \n"
181
+ s << " map.setCenter(centerPoint, #{zoom}); \n"
182
+ @content_hash['main_js_start'] = s
183
+ end
184
+
185
+ def project_embedded_comment
186
+ "Map generated by Gooby"
187
+ end
188
+
189
+ def generate_main_js_route_overlay
190
+ tkpt_count = @trackpoints.size.to_f
191
+ app_max = @configuration['approx_max_points'].to_f
192
+ gen_comments = @configuration['gen_comments']
193
+ ratio = tkpt_count / app_max
194
+ @start_dttm = nil
195
+ if ratio > 1.0
196
+ increment = (tkpt_count / app_max).to_i
197
+ else
198
+ increment = 1
258
199
  end
259
-
260
- def generate_main_js_route_overlay
261
- tkpt_count = @tkpts.size.to_f
262
- app_max = @configuration.get('gmap_approx_max_points').to_f
263
- gen_comments = @configuration.get('gmap_gen_comments')
264
- ratio = tkpt_count / app_max
265
- @start_dttm = nil
266
- if ratio > 1.0
267
- increment = (tkpt_count / app_max).to_i
200
+ curr_idx, next_idx, gpoint_count, last_idx = -1, 0, 0, @trackpoints.size - 1
201
+ s = " var points = new Array(); "
202
+ @trackpoints.each { |tkpt|
203
+ curr_idx = curr_idx + 1
204
+ if curr_idx == 0
205
+ @start_dttm, @start_pos = tkpt.dttm, tkpt
206
+ end
207
+ if ((curr_idx == next_idx) || (curr_idx == last_idx) || (tkpt.split?))
208
+ gpoint_count = gpoint_count + 1
209
+ s << tkpt.as_glatlng(false, gen_comments, tkpt_count, curr_idx, @start_dttm)
210
+ next_idx = curr_idx + increment
268
211
  else
269
- increment = 1
212
+ s << tkpt.as_glatlng(true, gen_comments, tkpt_count, curr_idx, @start_dttm)
270
213
  end
271
- curr_idx, next_idx, gpoint_count, last_idx = -1, 0, 0, @tkpts.size - 1
272
- s = " var points = new Array(); "
273
- @tkpts.each { |tkpt|
274
- curr_idx = curr_idx + 1
275
- if curr_idx == 0
276
- @start_dttm = tkpt.dttm
277
- @start_pos = tkpt.point
278
-
279
- time = Time.parse(@start_dttm.dateTime().to_s)
280
- end
281
- if ((curr_idx == next_idx) || (curr_idx == last_idx) || (tkpt.is_split()))
282
- gpoint_count = gpoint_count + 1
283
- s << tkpt.as_glatlng(false, gen_comments, tkpt_count, curr_idx, @start_dttm)
284
- next_idx = curr_idx + increment
214
+ }
215
+ s << "\n"
216
+ s << "\n // app_max=#{app_max} ratio=#{ratio} increment=#{increment}"
217
+ s << "\n"
218
+ s << "\n var routePolyline = new GPolyline(points); "
219
+ s << "\n map.addOverlay(routePolyline); "
220
+ @content_hash['main_js_route_overlay'] = s
221
+ @content_hash['main_js_route_overlay_increment'] = increment
222
+ end
223
+
224
+ def generate_main_js_checkpoint_overlays
225
+ generate_mile_markers = @configuration['mile_markers']
226
+ s = "\n // Create a base icon for all of our markers that specifies the "
227
+ s << "\n // shadow, icon dimensions, etc."
228
+ s << "\n var baseIcon = new GIcon();"
229
+ s << "\n baseIcon.shadow = \"#{icon_url_base}shadow50.png\";"
230
+ s << "\n baseIcon.iconSize = new GSize(20, 34);"
231
+ s << "\n baseIcon.shadowSize = new GSize(37, 34);"
232
+ s << "\n baseIcon.iconAnchor = new GPoint(9, 34);"
233
+ s << "\n baseIcon.infoWindowAnchor = new GPoint(9, 2);"
234
+ s << "\n baseIcon.infoShadowAnchor = new GPoint(18, 25);"
235
+ s << "\n"
236
+ curr_idx = -1
237
+ last_idx = @trackpoints.size - 1
238
+ next_checkpoint = 0.0
239
+ @start_dttm = nil
240
+ @trackpoints.each { | tkpt |
241
+ curr_idx = curr_idx + 1
242
+ if curr_idx == 0
243
+ @start_dttm = tkpt.dttm
244
+ if @trackpoints.size == 1
245
+ label = @configuration['gmap_1_point_map_info_window_label']
246
+ info_window_html = tkpt.as_one_point_info_window_html(label)
285
247
  else
286
- s << tkpt.as_glatlng(true, gen_comments, tkpt_count, curr_idx, @start_dttm)
248
+ info_window_html = tkpt.as_quoted_info_window_html(0, @start_dttm)
287
249
  end
288
- }
289
- s << "\n"
290
- s << "\n var routePolyline = new GPolyline(points); "
291
- s << "\n map.addOverlay(routePolyline); "
292
- @content_hash['main_js_route_overlay'] = s
293
- @content_hash['main_js_route_overlay_increment'] = increment
294
- end
295
-
296
- def generate_main_js_checkpoint_overlays
297
- s = "\n // Create a base icon for all of our markers that specifies the "
298
- s << "\n // shadow, icon dimensions, etc."
299
- s << "\n var baseIcon = new GIcon();"
300
- s << "\n baseIcon.shadow = \"#{@icon_url_base}shadow50.png\";"
301
- s << "\n baseIcon.iconSize = new GSize(20, 34);"
302
- s << "\n baseIcon.shadowSize = new GSize(37, 34);"
303
- s << "\n baseIcon.iconAnchor = new GPoint(9, 34);"
304
- s << "\n baseIcon.infoWindowAnchor = new GPoint(9, 2);"
305
- s << "\n baseIcon.infoShadowAnchor = new GPoint(18, 25);"
306
- s << "\n"
307
-
308
- curr_idx = -1
309
- last_idx = @tkpts.size - 1
310
- next_checkpoint = 0.0
311
- @start_dttm = nil
312
- @tkpts.each { | tkpt |
313
- curr_idx = curr_idx + 1
314
- if curr_idx == 0
315
- @start_dttm = tkpt.dttm
316
- info_window_html = tkpt.as_info_window_html('Start', @start_dttm)
317
- s << "\n var iconStart = new GIcon(baseIcon); "
318
- s << "\n iconStart.image = \"#{@icon_url_base}dd-start.png\";"
319
- s << "\n var pStart = new GPoint(#{tkpt.longitude_as_float}, #{tkpt.latitude_as_float});"
320
- s << "\n var mStart = new GMarker(pStart, iconStart);"
321
- s << "\n GEvent.addListener(mStart, \"click\", function() { "
322
- s << "\n mStart.openInfoWindowHtml(#{info_window_html});"
323
- s << "\n }); "
324
- s << "\n map.addOverlay(mStart);"
325
- s << "\n "
326
- next_checkpoint = 1.0
327
- elsif curr_idx == last_idx
328
- info_window_html = tkpt.as_info_window_html('Finish', @start_dttm)
329
- s << "\n var iconFinish = new GIcon(baseIcon); "
330
- s << "\n iconFinish.image = \"#{@icon_url_base}dd-end.png\";"
331
- s << "\n var pFinish = new GPoint(#{tkpt.longitude_as_float}, #{tkpt.latitude_as_float});"
332
- s << "\n var mFinish = new GMarker(pFinish, iconFinish);"
333
- s << "\n GEvent.addListener(mFinish, \"click\", function() { "
334
- s << "\n mFinish.openInfoWindowHtml(#{info_window_html});"
335
- s << "\n }); "
336
- s << "\n map.addOverlay(mFinish);"
337
- s << "\n "
338
- next_checkpoint = 999999
339
- else
340
- if (tkpt.cumulative_distance >= next_checkpoint)
341
- integer = next_checkpoint.to_i
342
- info_window_html = tkpt.as_info_window_html("#{integer}", @start_dttm)
250
+ s << "\n var iconStart = new GIcon(baseIcon); "
251
+ s << "\n iconStart.image = \"#{icon_url_base}dd-start.png\";"
252
+ s << "\n var pStart = new GPoint(#{tkpt.longitude}, #{tkpt.latitude});"
253
+ s << "\n var mStart = new GMarker(pStart, iconStart);"
254
+ s << "\n GEvent.addListener(mStart, \"click\", function() { "
255
+ s << "\n mStart.openInfoWindowHtml(#{info_window_html});"
256
+ s << "\n }); "
257
+ s << "\n map.addOverlay(mStart);"
258
+ s << "\n "
259
+ next_checkpoint = 1.0
260
+ elsif curr_idx == last_idx
261
+ info_window_html = tkpt.as_quoted_info_window_html(999999, @start_dttm)
262
+ s << "\n var iconFinish = new GIcon(baseIcon); "
263
+ s << "\n iconFinish.image = \"#{icon_url_base}dd-end.png\";"
264
+ s << "\n var pFinish = new GPoint(#{tkpt.longitude}, #{tkpt.latitude});"
265
+ s << "\n var mFinish = new GMarker(pFinish, iconFinish);"
266
+ s << "\n GEvent.addListener(mFinish, \"click\", function() { "
267
+ s << "\n mFinish.openInfoWindowHtml(#{info_window_html});"
268
+ s << "\n }); "
269
+ s << "\n map.addOverlay(mFinish);"
270
+ s << "\n "
271
+ next_checkpoint = 999999
272
+ else
273
+ if (tkpt.distance >= next_checkpoint)
274
+ integer = next_checkpoint.to_i
275
+ if generate_mile_markers
276
+ info_window_html = tkpt.as_quoted_info_window_html("#{integer}", @start_dttm)
343
277
  s << "\n var icon#{integer} = new GIcon(baseIcon); "
344
- s << "\n icon#{integer}.image = \"#{@icon_url_base}marker#{integer}.png\";"
345
- s << "\n var p#{integer} = new GPoint(#{tkpt.longitude_as_float}, #{tkpt.latitude_as_float});"
278
+ s << "\n icon#{integer}.image = \"#{icon_url_base}marker#{integer}.png\";"
279
+ s << "\n var p#{integer} = new GPoint(#{tkpt.longitude}, #{tkpt.latitude});"
346
280
  s << "\n var m#{integer} = new GMarker(p#{integer}, icon#{integer});"
347
281
  s << "\n GEvent.addListener(m#{integer}, \"click\", function() { "
348
- s << "\n m#{integer}.openInfoWindowHtml(#{info_window_html});"
282
+ s << "\n m#{integer}.openInfoWindowHtml(#{info_window_html});"
349
283
  s << "\n }); "
350
284
  s << "\n map.addOverlay(m#{integer});"
351
285
  s << "\n "
352
- next_checkpoint = next_checkpoint + 1.0
353
- end
354
- end
355
- }
356
- s << "\n"
357
- @content_hash['main_js_checkpoint_overlays'] = s
358
-
359
- end
360
-
361
- def generate_main_js_map_clicked_listeners
362
- s = "\n"
363
- s << "\n GEvent.addListener(map, \"click\", function() { "
364
- s << "\n var center = map.getCenter(); \n"
365
- s << "\n document.getElementById(\"messages\").innerHTML = 'click: ' + center.toString(); "
366
- s << "\n });"
367
- s << "\n GEvent.addListener(map, \"moveend\", function() { "
368
- s << "\n var center = map.getCenter(); \n"
369
- s << "\n document.getElementById(\"messages\").innerHTML = 'moveend: ' + center.toString(); "
370
- s << "\n });"
371
- @content_hash['main_js_map_clicked_listeners'] = s
372
- end
373
-
374
- def generate_main_js_end
375
- s = "\n } "
376
- s << "\n } "
377
- s << "\n//]]> \n"
378
- s << "\n</script>"
379
-
380
- @content_hash['main_js_end'] = s
381
- end
382
-
286
+ end
287
+ next_checkpoint = next_checkpoint + 1.0
288
+ end
289
+ end
290
+ }
291
+ s << "\n"
292
+ @content_hash['main_js_checkpoint_overlays'] = s
293
+ end
294
+
295
+ def generate_main_js_map_clicked_listeners
296
+ s = "\n"
297
+ s << "\n GEvent.addListener(map, \"click\", function() { "
298
+ s << "\n var center = map.getCenter(); \n"
299
+ s << "\n document.getElementById(\"messages\").innerHTML = 'click: ' + center.toString(); "
300
+ s << "\n });"
301
+ s << "\n GEvent.addListener(map, \"moveend\", function() { "
302
+ s << "\n var center = map.getCenter(); \n"
303
+ s << "\n document.getElementById(\"messages\").innerHTML = 'moveend: ' + center.toString(); "
304
+ s << "\n });"
305
+ @content_hash['main_js_map_clicked_listeners'] = s
306
+ end
307
+
308
+ def generate_main_js_end
309
+ s = "\n } "
310
+ s << "\n } "
311
+ s << "\n//]]> \n"
312
+ s << "\n</script>"
313
+ @content_hash['main_js_end'] = s
314
+ end
315
+
316
+ def icon_url_base
317
+ @configuration['gmap_icon_url_base']
383
318
  end
384
319
 
385
- end # end of module
320
+ end