gooby 1.2.0 → 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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