Gooby = Google APIs + Ruby
Version: 1.2.0 - 2007/07/22
Gooby = Google APIs + Ruby. Release 1.2.0 generates Google maps from GPS data exported by your Garmin Forerunner GPS unit, or manually edited CSV file. Please see the README file. Feedback is requested.
Sample maps at: www.joakim-systems.com:8219/gmap/ www.joakim-systems.com:8219/gmap/ccc_half_2005 www.joakim-systems.com:8219/gmap/nashville_marathon_2005 www.joakim-systems.com:8219/gmap/phoenix_marathon_2006
This README document is available at: www.joakim-systems.com:8219/gooby/readme
This gem contains ‘Gooby’, a set of Ruby code to assist you with using and producing content for the various Google APIs. The initial focus of Gooby is on the Google Maps API, version 2.0.
Google Maps can be produced using Gooby from your data in CSV format, as created in one of the following three ways. 1) From exported and parsed Garmin ForerunnerLogbook XML files. 2) From exported and parsed Garmin TrainingCenter TCX(XML) files. 3) From your own manually edited Global Positioning System (GPS) data.
See any of the 'data/*.csv' files in the distribution for an example
of the CSV format.
Google maps are applicable really to any outdoor activity for which GPS data can be obtained. The focus of Gooby is on running, because the author is a marathon runner, and the Garmin Forerunner (I use models 201, 205, and 305) is primarily intended for running. Other activities, such as cycling, hiking, walking, driving, and even golfing are also well suited for Gooby. Please let me know how you use Gooby! Feedback is requested.
All Gooby functionality is intended to be invoked from a command line. Web and Rails integration may be done in a later release.
General
- Author
-
Chris Joakim <[email protected]>
- Requires
-
Ruby 1.8.4 or later
- License
-
Copyright 2007 by Chris Joakim. GNU General Public License (GPL) license. See www.gnu.org/copyleft/gpl.html
License
Gooby is available under GNU General Public License (GPL) license.
Download
The latest version of gooby can be found at
Installation
Gooby is packaged and installed as a ruby ‘gem’. Download the latest gem to your computer, then run the following command from your download directory.
gem install gooby-1.2.0.gem
Online Resources
-
The Gooby home page rubyforge.org/projects/gooby/. RubyForge provides CVS hosting for the project.
Sample Gooby-generated Google Maps are at www.joakim-systems.com, below:
www.joakim-systems.com:8219/gmap/ www.joakim-systems.com:8219/gmap/ccc_half_2005 www.joakim-systems.com:8219/gmap/nashville_marathon_2005 www.joakim-systems.com:8219/gmap/phoenix_marathon_2006 www.joakim-systems.com:8219/gmap/gps_data_capture
This Release - 1.2.0
-
Added support for the Garmin 305 Heartbeat monitor.
-
Heartbeat values are captured in the XML parsing process.
-
CSV file format expanded to include heartbeat.
-
Database DDL modified to add the heartbeat column.
-
Generated Google Maps now have heartbeat in the popup windows.
-
Legacy Garmin 201 and Garmin 205 CSV files and Google Maps simply omit the heartbeat information.
-
Heartbeat is displayed, if data is present, in the new Gooby 1.1.0 “been_there” reports. This may be interesting for hill-climbers and interval-trainers.
-
-
Added support for the English (miles) or Metric (kilometers) systems.
-
Either ‘mi’ or ‘km’ is specified in the XML parsing process.
-
mi or km unit-of-measure is retained in the CSV files.
-
Generated Google Maps now generate markers at either integer miles or kilometers, depending on the input CSV file.
-
Generated Google Map popup windows display the unit-of-measure.
Special thanks to Karl Otto Emanuelsson for his suggestion to add metric system support.
-
-
Refactored the codebase into individual class and module files, rather than the previous monolithic gooby.rb file.
Previous Release - 1.1.0
-
Greatly simplify usage and command-line argument handling. See the shell scripts and ruby files in the /bin directory for examples.
Special thanks to Davis Kitchel for his several suggestions that resulted in the following enhancements:
-
Gooby is a Garmin XML parser! The ‘marketing’ focus on Gooby prior to now has been on Google Map generation. However, some users simply use it as a Garmin XML to CSV parser, then use the parsed data for their own various needs without creating a Google map. This release recognizes that simple parsing of Garmin data is a significant and “core” use of Gooby.
-
Reformatted the parsed CSV files and added more fields to each output line, including a unique identifier (primary key), run_id, and lap-specific info such as lap number, lap distance, and lap elapsed time.
-
Renamed and enhanced yaml file ‘gooby_config.yaml’. Previously, this had been Google-map biased. This release allows you to define your own “points of interest” (poi) in the yaml file. Furthermore, you can define “courses” or “subcourses” which consist of a given series of points-of- interest. See ‘gooby_config.yaml’ for examples.
-
Added proximity-based “been_there” reporting logic (method ‘been_there’ of class GoobyCommand). This functionality allows you to scan your CVS data file(s) where you have been on user-specified “courses”, within a given proximity. Your courses are defined in the yaml file (see the above item). Proximity is specified in “degrees difference” between the course point definition coordinates, and the actual observed GPS coordinates. Degrees difference is defined as the absolute value of lat1 - lat2, plus the absolute value of lng1 - lng2.
For an example report, see file ‘been_there.txt’ in the /samples directory.
This functionality essentially lets you retroactively “click the Lap button” on your Garmin GPS receiver and examine split-times between given points. Typical usage is to examine “hill climb”, “time trial”, or “speedwork” zones within your runs or rides.
-
Optional support for loading your GPS data into a MySQL database. See the generate and load scripts in the /sql directory.
Note that Gooby data does NOT need to be loaded into a database; the CSV format is preferred. However, users may find it useful to store this data in a database for their required processing.
Road Map / TODO List
-
IE or Google Bug - The Google Map v2 JavaScript has not run properly in Internet Explorer at times. Script error after loading the map background, but before the map route is drawn.
Note: The Google Map v2 code seems to have been significantly improved for Windows Explorer during Q2 2007, as the Gooby-generated Google Maps now display properly in IE.
-
Add Rails support for realtime dynamic map/content generation.
-
Parse cadence information from Garmin export file for cyclists. Note: Please provide me a sample file.
-
Add other Google APIs (earth, search, sitemaps, froogle, etc).
Support
Please see rubyforge.org/projects/gooby/ to submit a request or report a bug, on the Tracker page.
Usage
See the ‘run_xxx.sh’ shell scripts and corresponding ruby files in the /bin directory for actual working examples used during Gooby development and testing.
The following in-line text shows both the shell and ruby code.
Function 1 - Gooby Version Information
shell: ruby /devtools/workspace/RF_Gooby/bin/gooby_version.rb
ruby:
require ‘rubygems’ require ‘gooby’ include REXML
config_filename = ‘/devtools/workspace/RF_Gooby/config/gooby_config.yaml’
gooby = Gooby::GoobyCommand.new(config_filename) gooby.display_version Function 2 - Gooby Configuration YAML Contents
shell:
ruby /devtools/workspace/RF_Gooby/bin/gooby_config.rb
ruby:
require ‘rubygems’ require ‘gooby’ include REXML
config_filename = ‘/devtools/workspace/RF_Gooby/config/gooby_config.yaml’
gooby = Gooby::GoobyCommand.new(config_filename) gooby.display_configuration
Function 3 - Garmin XML/TCX file splitting:
shell: rm /temp/splits/.
ruby /devtools/workspace/RF_Gooby/bin/gooby_splitter.rb garmin201 /devtools/workspace/RF_Gooby/data/raw/forerunner_201_2007.xml /temp/splits ruby /devtools/workspace/RF_Gooby/bin/gooby_splitter.rb garmin205 /devtools/workspace/RF_Gooby/data/raw/forerunner_205_2007.tcx /temp/splits ruby /devtools/workspace/RF_Gooby/bin/gooby_splitter.rb garmin305 /devtools/workspace/RF_Gooby/data/raw/forerunner_305_2007.tcx /temp/splits
ls -al /temp/splits
ruby:
require ‘rubygems’ require ‘gooby’ include REXML
config_filename = ‘/devtools/workspace/RF_Gooby/config/gooby_config.yaml’
gooby = Gooby::GoobyCommand.new(config_filename) gooby.display_version gooby.split_garmin_export_file(ARGV) Function 4 - Garmin XML/TCX file parsing:
shell:
ruby /devtools/workspace/RF_Gooby/bin/gooby_parser.rb garmin201 mi /devtools/workspace/RF_Gooby/data/20060115_phoenix_marathon.xml > /devtools/workspace/RF_Gooby/data/20060115_phoenix_marathon.csv
ruby /devtools/workspace/RF_Gooby/bin/gooby_parser.rb garmin205 km /devtools/workspace/RF_Gooby/data/20070505_davidson_5k.xml > /devtools/workspace/RF_Gooby/data/20070505_davidson_5k_km.csv
ruby:
require ‘rubygems’ require ‘gooby’ include REXML
config_filename = ‘/devtools/workspace/RF_Gooby/config/gooby_config.yaml’
gooby = Gooby::GoobyCommand.new(config_filename) gooby.parse_garmin_xml_file(ARGV)
Function 5 - CSV File Validation
shell:
ruby /devtools/workspace/RF_Gooby/bin/gooby_csv_validation.rb
ruby:
require ‘rubygems’ require ‘gooby’ include REXML
config_filename = ‘/devtools/workspace/RF_Gooby/config/gooby_config.yaml’
full_files = false
list = Array.new list << ‘/devtools/workspace/RF_Gooby/data/hrm1.csv’ list << ‘/devtools/workspace/RF_Gooby/data/20050305_corporate_cup_hm.csv’ list << ‘/devtools/workspace/RF_Gooby/data/20050430_nashville_marathon_km.csv’ list << ‘/devtools/workspace/RF_Gooby/data/20060115_phoenix_marathon.csv’ list << ‘/devtools/workspace/RF_Gooby/data/20070101_davidson_11m.csv’ list << ‘/devtools/workspace/RF_Gooby/data/20070505_davidson_5k_km.csv’
list << ‘/devtools/workspace/RF_Gooby/data/2007_g201.csv’ if full_files list << ‘/devtools/workspace/RF_Gooby/data/2007_g205.csv’ if full_files list << ‘/devtools/workspace/RF_Gooby/data/2007_g305.csv’ if full_files
gooby = Gooby::GoobyCommand.new(config_filename) @csv_points = gooby.read_csv_files(list) @csv_col_names = gooby.csv_col_names
puts “#@csv_points@csv_points.size points read from csv file(s).” puts “#@csv_col_names@csv_col_names.size fields per line.”
index = 0 @csv_col_names.each {|col_name| puts sprintf(“– %s %2s [%s]”, col_name.ljust(16), index, @csv_points.tokens) index = index + 1 }
@csv_points.each {|csv_point| puts csv_point.rawdata if csv_point.token_count != 15
}
Function 6 - “been_there”:
shell: ruby /devtools/workspace/RF_Gooby/bin/gooby_been_there.rb > /devtools/workspace/RF_Gooby/samples/been_there.txt
ruby /devtools/workspace/RF_Gooby/bin/gooby_been_there.rb ruby: require ‘rubygems’ require ‘gooby’ include REXML
config_filename = ‘/devtools/workspace/RF_Gooby/config/gooby_config.yaml’
gooby = Gooby::GoobyCommand.new(config_filename)
# first read the csv file(s) parsed from your Garmin export tcx/xml files. list = Array.new list << ‘/devtools/workspace/RF_Gooby/data/20070101_davidson_11m.csv’ list << ‘/devtools/workspace/RF_Gooby/data/hrm1.csv’ gooby.read_csv_files(list)
# first arg to ‘been_there’ is the course number, second arg is the ‘proximity’ specified as # ‘degrees difference’. Degrees difference is defined as the absolute value of lat1 - lat2, # plus the absolute value of lng1 - lng2. Your courses and points of interest (poi) are defined # in the yaml file.
gooby.been_there(‘1’, 0.0025) gooby.been_there(‘2’, 0.0025) gooby.been_there(‘999’, 0.0005)
Function 7 - Google Map Generation:
shell: ruby /devtools/workspace/RF_Gooby/bin/gooby_gen_gmap.rb /devtools/workspace/RF_Gooby/data/20060115_phoenix_marathon.csv > /devtools/workspace/RF_Gooby/samples/20060115_phoenix_marathon.html
ruby /devtools/workspace/RF_Gooby/bin/gooby_gen_gmap.rb /devtools/workspace/RF_Gooby/data/20070505_davidson_5k_km.csv > /devtools/workspace/RF_Gooby/samples/20070505_davidson_5k.html
ruby:
require ‘rubygems’ require ‘gooby’ include REXML
config_filename = ‘/devtools/workspace/RF_Gooby/config/gooby_config.yaml’
gooby = Gooby::GoobyCommand.new(config_filename) gooby.generate_google_map(ARGV)
Note: The input file passed to the Google Map generation process is the CSV file, not the Garmin XML file.
Function 8 - Extract First Trackpoints as (potential) Points-of-Interest (POI)
shell:
ruby /devtools/workspace/RF_Gooby/bin/gooby_first_trackpoints_as_poi.rb
ruby:
require ‘rubygems’ require ‘gooby’ include REXML
config_filename = ‘/devtools/workspace/RF_Gooby/config/gooby_config.yaml’
gooby = Gooby::GoobyCommand.new(config_filename)
# first read the csv file(s) parsed from your Garmin export tcx/xml files. list = Array.new list << ‘/devtools/workspace/RF_Gooby/data/hrm1.csv’ list << ‘/devtools/workspace/RF_Gooby/data/20050305_corporate_cup_hm.csv’ list << ‘/devtools/workspace/RF_Gooby/data/20050430_nashville_marathon_km.csv’ list << ‘/devtools/workspace/RF_Gooby/data/20060115_phoenix_marathon.csv’ list << ‘/devtools/workspace/RF_Gooby/data/20070101_davidson_11m.csv’ list << ‘/devtools/workspace/RF_Gooby/data/20070505_davidson_5k_km.csv’ gooby.read_csv_files(list)
# optional first arg is the date of the run, otherwise the all dates. gooby.first_trackpoints_as_poi(ARGV)
Function 9 - Create a MySQL database table for your parsed CSV data
shell: /usr/local/mysql/bin/mysql < /devtools/workspace/RF_Gooby/sql/gooby.ddl -u <your_db_id> -p
Function 10 - Populate the MySQL database table with your parsed CSV data
shell:
/usr/local/mysql/bin/mysql < /devtools/workspace/RF_Gooby/sql/gooby_load.dml -u <your_db_id> -p
Warranty
This software is provided “as is” and without any express or implied warranties, including, without limitation, the implied warranties of merchantibility and fitness for a particular purpose.