Compare commits

..

31 Commits

Author SHA1 Message Date
19a5ab6104 REINDENT ALL THE FILES
Use 2 spaces for indentation and remove some tabs.
2013-06-16 23:36:44 +02:00
853b967974 Correct tests and Rakefile 2013-06-16 01:35:46 +02:00
917c437f94 Replace Hpricot with Nokogiri 2013-06-16 01:35:36 +02:00
b1d18e8261 Remove trailing whitespaces 2013-06-15 12:11:43 +02:00
66d384b46d Add bundle support 2013-06-15 12:07:59 +02:00
Doug Fales
4bca65aeec Merge pull request #3 from rb2k/master
Make tests and code ruby 1.9 compatible
2011-11-10 13:58:20 -08:00
Marc Seeger
0d5e31fe96 Added hpricot as a dependency 2011-11-07 22:56:18 +01:00
Marc Seeger
f2b1bd839e Fixed gemspec so it builds in 1.9 2011-11-07 22:52:45 +01:00
Marc Seeger
1ec7e02f63 Moved most stuff over from libxml to hpricot 2011-11-06 21:37:15 +01:00
Marc Seeger
2d665f2625 Make tests/code compatibile with ruby 1.9.3 2011-11-06 15:38:46 +01:00
Doug Fales
7cf19bfd70 Updating Changelog and fixing some indentation in waypoint.rb. 2010-02-28 08:41:58 -07:00
Doug Fales
bc994b9fa2 Putting the gem building stuff into a gemspec. 2010-02-27 17:03:59 -07:00
Doug Fales
0d35ac037a Fixing some tests since git does not believe in empty directories. 2010-02-27 16:52:21 -07:00
Doug Fales
8c49d49e26 README edits. 2010-02-27 16:20:17 -07:00
Doug Fales
39d1d89aad More rdoc tweaks. 2010-02-27 16:19:03 -07:00
Doug Fales
37886363be Changing README to rdoc ext for github. 2010-02-27 16:18:10 -07:00
Doug Fales
2cc725d4cf Fixing README formatting. 2010-02-27 16:13:14 -07:00
Doug Fales
287467de59 Adding the ability to write GPX to a string in addition to a file. Thanks to Douglas Robertson for the patch. 2009-10-13 00:19:29 +00:00
Doug Fales
9dfdfd8360 Adding a patch from Douglas Robertson that allows using version 1.0 of the schema for output. 2009-09-27 23:46:14 +00:00
Doug Fales
ad78aa47d5 Adding changelog. 2009-07-07 02:53:07 +00:00
Doug Fales
03994b4b42 Revving to version 0.5. 2009-07-07 02:51:34 +00:00
Doug Fales
0b92a4ee52 Changing my contact email address. 2009-07-07 02:43:17 +00:00
Doug Fales
cc5aa666bc Patches from Tom Verbeure (mtbguru.com) to work with libxml-ruby 1.x. 2009-07-07 02:41:33 +00:00
Doug Fales
73ea9e6309 Patch from Kang-min Liu to support speed element. 2009-06-17 14:20:26 +00:00
Doug Fales
9250b0ce45 Revving to 0.4. 2008-02-19 04:09:57 +00:00
Doug Fales
3abba74eef Adding some new unit tests and fixing several file export bugs reported by Jochen Topf.
New unit tests also uncovered a bug where the number of trackpoints reported in a file was twice the actual number.
2008-02-19 04:06:29 +00:00
Doug Fales
ef1eac8cbb Going to version 0.3. 2008-02-11 21:20:16 +00:00
Doug Fales
75d24706f4 Updating unit tests in light of recent fixes to routes and waypoints code. 2008-02-11 21:13:48 +00:00
Doug Fales
8df3cb1ea3 Thanks to Mike Gauland for discovering some route- and waypoint-related bugs. I've fixed them and also added #to_s on Waypoint so it's easier to debug. 2008-02-08 23:26:14 +00:00
Doug Fales
59aa3e5b9b Thanks to Christian Koerner for finding and fixing these bugs in the waypoint
code.
2007-12-04 17:58:48 +00:00
Doug Fales
a79761711b Another patch from Gaku Ueda. This one allows you to pass in a string of GPX
data using the :gpx_date => option.  Thanks Gaku!
2007-12-04 17:52:29 +00:00
32 changed files with 1302 additions and 953 deletions

3
.gitignore vendored Normal file
View File

@ -0,0 +1,3 @@
tests/output/*
.*.swp
Gemfile.lock

60
ChangeLog Normal file
View File

@ -0,0 +1,60 @@
2010-02-27 Doug Fales <doug@falesafeconsulting.com>
* Putting the gem building stuff into a gemspec.
* Fixing some tests since git does not believe in empty directories.
* Fixing README formatting.
2010-02-27 Doug Fales <doug@falesafeconsulting.com>
* README edits.
* More rdoc tweaks.
* Changing README to rdoc ext for github.
2009-10-13 Doug Fales <doug@falesafeconsulting.com>
* Adding the ability to write GPX to a string in addition to a file. Thanks to Douglas Robertson for the patch.
2009-09-27 Doug Fales <doug@falesafeconsulting.com>
* Adding a patch from Douglas Robertson that allows using version 1.0 of the schema for output.
2009-07-07 Doug Fales <doug@falesafeconsulting.com>
* Adding changelog.
* Revving to version 0.5.
* Changing my contact email address.
* Patches from Tom Verbeure (mtbguru.com) to work with libxml-ruby 1.x.
2009-06-17 Doug Fales <doug@falesafeconsulting.com>
* Patch from Kang-min Liu to support speed element.
2008-02-19 Doug Fales <doug@falesafeconsulting.com>
* Revving to 0.4.
* Adding some new unit tests and fixing several file export bugs reported by Jochen Topf. New unit tests also uncovered a bug where the number of trackpoints reported in a file was twice the actual number.
2008-02-11 Doug Fales <doug@falesafeconsulting.com>
* Going to version 0.3.
* Updating unit tests in light of recent fixes to routes and waypoints code.
2008-02-08 Doug Fales <doug@falesafeconsulting.com>
* Thanks to Mike Gauland for discovering some route- and waypoint-related bugs. I've fixed them and also added #to_s on Waypoint so it's easier to debug.
2007-12-04 Doug Fales <doug@falesafeconsulting.com>
* Thanks to Christian Koerner for finding and fixing these bugs in the waypoint code.
* Another patch from Gaku Ueda. This one allows you to pass in a string of GPX data using the :gpx_date => option. Thanks Gaku!
2007-11-30 Doug Fales <doug@falesafeconsulting.com>
* Updating the version #.
* Updates courtesy of Gaku Ueda: * Adding support for GPX 1.0 as well as 1.1 (since libxml namespace parsing was hard-coded to 1.1. previously). * Adding a GPX 1.0 unit test file. * Miscellaneous updates to make it work with Ruby 1.8.6.
2006-12-04 Doug Fales <doug@falesafeconsulting.com>
* First stab at using libxml-ruby instead of REXML. I'm seeing the unit tests finish in under 14 seconds. That is compared to 2 minutes using REXML.
2006-12-03 Doug Fales <doug@falesafeconsulting.com>
* Fixing more nil time exceptions.
* Fixing an exception in contains_time?.
2006-11-28 Doug Fales <doug@falesafeconsulting.com>
* A couple of fixes to make the library comply with the different attribute names possible on the bounds element.
2006-10-28 Doug Fales <doug@falesafeconsulting.com>
* Fixing nil time bug.
2006-10-14 Doug Fales <doug@falesafeconsulting.com>
* Initial import of gpx gem.

4
Gemfile Normal file
View File

@ -0,0 +1,4 @@
source 'https://rubygems.org'
# Specify your gem's dependencies in seryz.gemspec
gemspec

View File

@ -1,8 +1,9 @@
= GPX Gem
Copyright (C) 2006 Doug Fales
Doug Fales mailto:doug.fales@gmail.com
Copyright (C) 2006 Doug Fales mailto:doug@falesafeconsulting.com
== What It Does
This library reads GPX files and provides an API for reading and manipulating
the data as objects. For more info on the GPX format, see
http://www.topografix.com/gpx.asp.
@ -14,6 +15,7 @@ the tracks and points in a file (such as distance, duration, average speed,
etc).
== Examples
Reading a GPX file, and cropping its contents to a given area:
gpx = GPX::GPXFile.new(:gpx_file => filename) # Read GPX file
bounds = GPX::Bounds.new(params) # Create a rectangular area to crop
@ -27,8 +29,9 @@ Converting a Magellan track log to GPX:
== Notes
This library was written to bridge the gap between my Garmin Geko
and my website, WalkingBoss.org. For that reason, it has always been more of a
and my website, WalkingBoss.org (RIP). For that reason, it has always been more of a
work-in-progress than an attempt at full GPX compliance. The track side of the
library has seen much more use than the route/waypoint side, so if you're doing
something with routes or waypoints, you may need to tweak some things.

View File

@ -1,20 +1,6 @@
require 'rubygems'
require 'rake'
require 'bundler/gem_tasks'
require 'rake/testtask'
require 'rake/rdoctask'
require 'rake/gempackagetask'
require File.dirname(__FILE__) + '/lib/gpx'
PKG_VERSION = GPX::VERSION
PKG_NAME = "gpx"
PKG_FILE_NAME = "#{PKG_NAME}-#{PKG_VERSION}"
RUBY_FORGE_PROJECT = "gpx"
RUBY_FORGE_USER = ENV['RUBY_FORGE_USER'] || "dougfales"
RELEASE_NAME = "#{PKG_NAME}-#{PKG_VERSION}"
PKG_FILES = FileList[
"lib/**/*", "bin/*", "tests/**/*", "[A-Z]*", "Rakefile", "doc/**/*"
]
require 'rdoc/task'
desc "Default Task"
task :default => [ :test ]
@ -27,12 +13,6 @@ Rake::TestTask.new("test") { |t|
t.verbose = true
}
# Make a console, useful when working on tests
desc "Generate a test console"
task :console do
verbose( false ) { sh "irb -I lib/ -r 'gpx'" }
end
# Genereate the RDoc documentation
desc "Create documentation"
Rake::RDocTask.new("doc") { |rdoc|
@ -41,41 +21,3 @@ Rake::RDocTask.new("doc") { |rdoc|
rdoc.rdoc_files.include('README')
rdoc.rdoc_files.include('lib/**/*.rb')
}
# Genereate the package
spec = Gem::Specification.new do |s|
s.name = 'gpx'
s.version = PKG_VERSION
s.summary = <<-EOF
A basic API for reading and writing GPX files.
EOF
s.description = <<-EOF
A basic API for reading and writing GPX files.
EOF
s.files = PKG_FILES
s.require_path = 'lib'
s.autorequire = 'gpx'
s.has_rdoc = true
s.author = "Doug Fales"
s.email = "doug.fales@gmail.com"
s.homepage = "http://gpx.rubyforge.com/"
end
Rake::GemPackageTask.new(spec) do |pkg|
pkg.need_zip = true
pkg.need_tar = true
end
desc "Report code statistics (KLOCs, etc) from the application"
task :stats do
require 'code_statistics'
CodeStatistics.new(
["Library", "lib"],
["Units", "tests"]
).to_s
end

22
gpx.gemspec Normal file
View File

@ -0,0 +1,22 @@
# coding: utf-8
lib = File.expand_path('../lib', __FILE__)
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
require 'gpx/version'
Gem::Specification.new do |s|
s.name = 'gpx'
s.version = GPX::VERSION
s.authors = ["Guillaume Dott", "Doug Fales"]
s.email = ["guillaume+github@dott.fr", "doug.fales@gmail.com"]
s.summary = %q{A basic API for reading and writing GPX files.}
s.description = %q{A basic API for reading and writing GPX files.}
s.files = `git ls-files`.split($/)
s.test_files = s.files.grep(%r{^(test|spec|features)/})
s.require_paths = ["lib"]
s.has_rdoc = true
s.homepage = "http://dougfales.github.com/gpx/"
s.rubyforge_project = "gpx"
s.add_dependency 'nokogiri'
end

View File

@ -20,12 +20,12 @@
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#++
$:.unshift(File.dirname(__FILE__))
require 'rubygems'
require 'xml/libxml'
require 'date'
require 'time'
require 'csv'
require 'nokogiri'
require 'gpx/version'
require 'gpx/gpx'
require 'gpx/gpx_file'
require 'gpx/bounds'

View File

@ -43,15 +43,6 @@ module GPX
(min_lon + distance)
end
def to_xml
bnd = XML::Node.new('bounds')
bnd['minlat'] = min_lat.to_s
bnd['minlon'] = min_lon.to_s
bnd['maxlat'] = max_lat.to_s
bnd['maxlon'] = max_lon.to_s
bnd
end
# Returns true if the pt is within these bounds.
def contains?(pt)
(pt.lat >= min_lat and pt.lat <= max_lat and pt.lon >= min_lon and pt.lon <= max_lon)

View File

@ -21,13 +21,9 @@
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#++
module GPX
VERSION = "0.2"
# A common base class which provides a useful initializer method to many
# class in the GPX library.
class Base
include XML
# This initializer can take an XML::Node and scrape out any text
# elements with the names given in the "text_elements" array. Each
# element found underneath "parent" with a name in "text_elements" causes
@ -37,13 +33,10 @@ module GPX
# attributes to this method.
def instantiate_with_text_elements(parent, text_elements)
text_elements.each do |el|
unless parent.find(el).empty?
val = parent.find(el).first.content
code = <<-code
attr_accessor #{ el }
#{el}=#{val}
code
class_eval code
child_xpath = "#{el}"
unless parent.at(child_xpath).nil?
val = parent.at(child_xpath).inner_text
self.send("#{el}=", val)
end
end

View File

@ -22,8 +22,7 @@
#++
module GPX
class GPXFile < Base
attr_reader :tracks, :routes, :waypoints, :bounds, :lowest_point, :highest_point, :distance, :duration, :average_speed, :ns
attr_accessor :tracks, :routes, :waypoints, :bounds, :lowest_point, :highest_point, :duration, :ns, :time, :name
# This initializer can be used to create a new GPXFile from an existing
# file or to create a new GPXFile instance with no data (so that you can
@ -34,6 +33,8 @@ module GPX
# puts "Duration: #{gpx_file.duration}"
# puts "Bounds: #{gpx_file.bounds}"
#
# To read a GPX file from a string, use :gpx_data.
# gpx_file = GPXFile.new(:gpx_data => '<xml ...><gpx>...</gpx>)
# To create a new blank GPXFile instance:
# gpx_file = GPXFile.new
# Note that you can pass in any instance variables to this form of the initializer, including Tracks or Segments:
@ -42,24 +43,17 @@ module GPX
#
def initialize(opts = {})
@duration = 0
if(opts[:gpx_file])
if(opts[:gpx_file] or opts[:gpx_data])
if opts[:gpx_file]
gpx_file = opts[:gpx_file]
#case gpx_file
#when String
# gpx_file = File.open(gpx_file)
#end
gpx_file = gpx_file.name if gpx_file.is_a?(File)
reset_meta_data
@xml = XML::Document.file(gpx_file)
# set XML namespace for XML find
if @xml.root.namespace_node
@ns = 'gpx:' + @xml.root.namespace_node.href
gpx_file = File.open(gpx_file) unless gpx_file.is_a?(File)
@xml = Nokogiri::XML(gpx_file)
else
@ns = 'gpx:http://www.topografix.com/GPX/1/1' # default to GPX 1.1
@xml = Nokogiri::XML(opts[:gpx_data])
end
bounds_element = (@xml.find("//gpx:gpx/gpx:metadata/gpx:bounds", @ns).to_a.first rescue nil)
reset_meta_data
bounds_element = (@xml.at("metadata/bounds") rescue nil)
if bounds_element
@bounds.min_lat = get_bounds_attr_value(bounds_element, %w{ min_lat minlat minLat })
@bounds.min_lon = get_bounds_attr_value(bounds_element, %w{ min_lon minlon minLon})
@ -69,17 +63,18 @@ module GPX
get_bounds = true
end
@time = Time.parse(@xml.at("metadata/time").inner_text) rescue nil
@name = @xml.at("metadata/name").inner_text rescue nil
@tracks = []
@xml.find("//gpx:gpx/gpx:trk", @ns).each do |trk|
@xml.search("trk").each do |trk|
trk = Track.new(:element => trk, :gpx_file => self)
update_meta_data(trk, get_bounds)
@tracks << trk
end
@waypoints = []
@xml.find("//gpx:gpx/gpx:wpt", @ns).each { |wpt| @waypoints << Waypoint.new(:element => wpt, :gpx_file => self) }
@xml.search("wpt").each { |wpt| @waypoints << Waypoint.new(:element => wpt, :gpx_file => self) }
@routes = []
@xml.find("//gpx:gpx/gpx:rte", @ns).each { |rte| @routes << Route.new(:element => rte, :gpx_file => self) }
@xml.search("rte").each { |rte| @routes << Route.new(:element => rte, :gpx_file => self) }
@tracks.delete_if { |t| t.empty? }
calculate_duration
@ -91,6 +86,9 @@ module GPX
calculate_duration
end
end
@tracks ||= []
@routes ||= []
@waypoints ||= []
end
def get_bounds_attr_value(el, possible_names)
@ -184,46 +182,96 @@ module GPX
# you modify the GPX data (i.e. by adding or deleting points) and you
# want the meta data to accurately reflect the new data.
def update_meta_data(trk, get_bounds = true)
@lowest_point = trk.lowest_point if(@lowest_point.nil? or trk.lowest_point.elevation < @lowest_point.elevation)
@highest_point = trk.highest_point if(@highest_point.nil? or trk.highest_point.elevation > @highest_point.elevation)
@lowest_point = trk.lowest_point if(@lowest_point.nil? or (!trk.lowest_point.nil? and trk.lowest_point.elevation < @lowest_point.elevation))
@highest_point = trk.highest_point if(@highest_point.nil? or (!trk.highest_point.nil? and trk.highest_point.elevation > @highest_point.elevation))
@bounds.add(trk.bounds) if get_bounds
@distance += trk.distance
end
# Serialize the current GPXFile to a gpx file named <filename>.
# If the file does not exist, it is created. If it does exist, it is overwritten.
def write(filename)
def write(filename, update_time = true)
@time = Time.now if(@time.nil? or update_time)
@name ||= File.basename(filename)
doc = generate_xml_doc
File.open(filename, 'w') { |f| f.write(doc.to_xml) }
end
doc = Document.new
doc.root = Node.new('gpx')
gpx_elem = doc.root
gpx_elem['xmlns:xsi'] = "http://www.w3.org/2001/XMLSchema-instance"
gpx_elem['xmlns'] = "http://www.topografix.com/GPX/1/1"
gpx_elem['version'] = "1.1"
gpx_elem['creator'] = "GPX RubyGem 0.1 Copyright 2006 Doug Fales -- http://walkingboss.com"
gpx_elem['xsi:schemaLocation'] = "http://www.topografix.com/GPX/1/1 http://www.topografix.com/GPX/1/1/gpx.xsd"
def to_s(update_time = true)
@time = Time.now if(@time.nil? or update_time)
doc = generate_xml_doc
doc.to_xml
end
meta_data_elem = Node.new('metadata')
name_elem = Node.new('name')
name_elem << File.basename(filename)
meta_data_elem << name_elem
time_elem = Node.new('time')
time_elem << Time.now.xmlschema
meta_data_elem << time_elem
meta_data_elem << bounds.to_xml
gpx_elem << meta_data_elem
tracks.each { |t| gpx_elem << t.to_xml } unless tracks.nil?
waypoints.each { |w| gpx_elem << w.to_xml } unless waypoints.nil?
routes.each { |r| gpx_elem << r.to_xml } unless routes.nil?
doc.save(filename, true)
def inspect
"<#{self.class.name}:...>"
end
private
def generate_xml_doc
version = '1.1'
version_dir = version.gsub('.','/')
doc = Nokogiri::XML::Builder.new do |xml|
xml.gpx(
'xsi' => "http://www.w3.org/2001/XMLSchema-instance",
'version' => version.to_s,
'creator' => "GPX RubyGem #{GPX::VERSION}",
'xsi:schemaLocation' => "http://www.topografix.com/GPX/#{version_dir} http://www.topografix.com/GPX/#{version_dir}/gpx.xsd") \
{
xml.metadata {
xml.name @name
xml.time @time.xmlschema
xml.bound(
minlat: bounds.min_lat,
minlon: bounds.min_lon,
maxlat: bounds.max_lat,
maxlon: bounds.max_lon,
)
}
tracks.each do |t|
xml.trk {
xml.name t.name
t.segments.each do |seg|
xml.trkseg {
seg.points.each do |p|
xml.trkpt(lat: p.lat, lon: p.lon) {
xml.time p.time.xmlschema unless p.time.nil?
xml.ele p.elevation unless p.elevation.nil?
}
end
}
end
}
end unless tracks.nil?
waypoints.each do |w|
xml.wpt(lat: w.lat, lon: w.lon) {
Waypoint::SUB_ELEMENTS.each do |sub_elem|
xml.send(sub_elem, w.send(sub_elem)) if w.respond_to?(sub_elem) && !w.send(sub_elem).nil?
end
}
end unless waypoints.nil?
routes.each do |r|
xml.rte {
xml.name r.name
r.points.each do |p|
xml.rtept(lat: p.lat, lon: p.lon) {
xml.time p.time.xmlschema unless p.time.nil?
xml.ele p.elevation unless p.elevation.nil?
}
end
}
end unless routes.nil?
}
end
return doc
end
# Calculates and sets the duration attribute by subtracting the time on
# the very first point from the time on the very last point.
@ -236,7 +284,5 @@ module GPX
rescue
@duration = 0
end
end
end

View File

@ -21,10 +21,8 @@
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#++
module GPX
# This class will parse the lat/lon and time data from a Magellan track log,
# which is a NMEA formatted CSV list of points.
class MagellanTrackLog
#PMGNTRK
# This message is to be used to transmit Track information (basically a list of previous position fixes)
@ -64,7 +62,7 @@ module GPX
segment = Segment.new
CSV.open(magellan_filename, "r") do |row|
CSV.open(magellan_filename, "r").each do |row|
next if(row.size < 10 or row[INVALID_FLAG] == 'V')
lat_deg = row[LAT][0..1]

View File

@ -20,12 +20,11 @@
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#++
include Math
module GPX
# The base class for all points. Trackpoint and Waypoint both descend from this base class.
class Point < Base
D_TO_R = PI/180.0;
attr_accessor :lat, :lon, :time, :elevation
D_TO_R = Math::PI/180.0;
attr_accessor :lat, :lon, :time, :elevation, :gpx_file, :speed
# When you need to manipulate individual points, you can create a Point
# object with a latitude, a longitude, an elevation, and a time. In
@ -38,13 +37,15 @@ module GPX
@lat, @lon = elem["lat"].to_f, elem["lon"].to_f
@latr, @lonr = (D_TO_R * @lat), (D_TO_R * @lon)
#'-'? yyyy '-' mm '-' dd 'T' hh ':' mm ':' ss ('.' s+)? (zzzzzz)?
@time = (Time.xmlschema(elem.find("gpx:time", @gpx_file.ns).first.content) rescue nil)
@elevation = elem.find("gpx:ele", @gpx_file.ns).first.content.to_f unless elem.find("gpx:ele", @gpx_file.ns).empty?
@time = (Time.xmlschema(elem.at("time").inner_text) rescue nil)
@elevation = elem.at("ele").inner_text.to_f unless elem.at("ele").nil?
@speed = elem.at("speed").inner_text.to_f unless elem.at("speed").nil?
else
@lat = opts[:lat]
@lon = opts[:lon]
@elevation = opts[:elevation]
@time = opts[:time]
@speed = opts[:speed]
end
end
@ -85,22 +86,5 @@ module GPX
@lonr = (longitude * D_TO_R)
@lon = longitude
end
# Convert this point to a XML::Node.
def to_xml(elem_name = 'trkpt')
pt = Node.new('trkpt')
pt['lat'] = lat.to_s
pt['lon'] = lon.to_s
unless time.nil?
time_elem = Node.new('time')
time_elem << time.xmlschema
pt << time_elem
end
elev = Node.new('ele')
elev << elevation
pt << elev
pt
end
end
end

View File

@ -21,22 +21,26 @@
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#++
module GPX
# A Route in GPX is very similar to a Track, but it is created by a user
# from a series of Waypoints, whereas a Track is created by the GPS device
# automatically logging your progress at regular intervals.
class Route < Base
attr_reader :points, :name, :gpx_file
attr_accessor :points, :name, :gpx_file
# Initialize a Route from a XML::Node.
def initialize(opts = {})
if(opts[:gpx_file] and opts[:element])
rte_element = opts[:element]
@gpx_file = opts[:gpx_file]
@name = rte_element.find("child::gpx:name", @ns).first.content
@name = rte_element.at("name").inner_text
@points = []
rte_element.find("child::gpx:rtept", @ns).each do |point|
@points << Point.new(:element => point)
rte_element.search("rtept").each do |point|
@points << Point.new(:element => point, :gpx_file => @gpx_file)
end
else
@points = (opts[:points] or [])
@name = (opts[:name])
end
end
@ -50,16 +54,5 @@ module GPX
def delete_area(area)
points.delete_if{ |pt| area.contains? pt }
end
# Convert this Route to a XML::Node.
def to_xml
rte = Node.new('rte')
name_elem = Node.new('name')
name_elem << name
rte << name_elem
points.each { |rte_pt| rte << rte_pt.to_xml('rtept') }
rte
end
end
end

View File

@ -21,7 +21,6 @@
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#++
module GPX
# A segment is the basic container in a GPX file. A Segment contains points
# (in this lib, they're called TrackPoints). A Track contains Segments. An
# instance of Segment knows its highest point, lowest point, earliest and
@ -46,8 +45,8 @@ module GPX
if(opts[:element])
segment_element = opts[:element]
last_pt = nil
if segment_element.is_a?(XML::Node)
segment_element.find("child::gpx:trkpt", @gpx_file.ns).each do |trkpt|
if segment_element.is_a?(Nokogiri::XML::Node)
segment_element.search("trkpt").each do |trkpt|
pt = TrackPoint.new(:element => trkpt, :segment => self, :gpx_file => @gpx_file)
unless pt.time.nil?
@earliest_point = pt if(@earliest_point.nil? or pt.time < @earliest_point.time)
@ -132,13 +131,6 @@ module GPX
(points.nil? or (points.size == 0))
end
# Converts this Segment to a XML::Node object.
def to_xml
seg = Node.new('trkseg')
points.each { |pt| seg << pt.to_xml }
seg
end
# Prints out a nice summary of this Segment.
def to_s
result = "Track Segment\n"

View File

@ -21,7 +21,6 @@
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#++
module GPX
# In GPX, a single Track can hold multiple Segments, each of which hold
# multiple points (in this library, those points are instances of
# TrackPoint). Each instance of this class has its own meta-data, including
@ -41,12 +40,11 @@ module GPX
reset_meta_data
if(opts[:element])
trk_element = opts[:element]
@name = (trk_element.find("child::gpx:name", @gpx_file.ns).first.content rescue "")
trk_element.find("child::gpx:trkseg", @gpx_file.ns).each do |seg_element|
@name = (trk_element.at("name").inner_text rescue "")
trk_element.search("trkseg").each do |seg_element|
seg = Segment.new(:element => seg_element, :track => self, :gpx_file => @gpx_file)
update_meta_data(seg)
@segments << seg
@points.concat(seg.points) unless seg.nil?
end
end
end
@ -70,8 +68,8 @@ module GPX
# correlating things like pictures, video, and other events, if you are
# working with a timestamp.
def closest_point(time)
segment = segments.find { |s| s.contains_time?(time) }
segment.closest_point(time)
segment = segments.select { |s| s.contains_time?(time) }
segment.first
end
# Removes all points outside of a given area and updates the meta data.
@ -101,20 +99,9 @@ module GPX
(points.nil? or points.size.zero?)
end
# Creates a new XML::Node from the contents of this instance.
def to_xml
trk= Node.new('trk')
name_elem = Node.new('name')
name_elem << name
trk << name_elem
segments.each do |seg|
trk << seg.to_xml
end
trk
end
# Prints out a friendly summary of this track (sans points). Useful for
# debugging and sanity checks.
def to_s
result = "Track \n"
result << "\tName: #{name}\n"

3
lib/gpx/version.rb Normal file
View File

@ -0,0 +1,3 @@
module GPX
VERSION = "0.7"
end

View File

@ -20,16 +20,15 @@
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#++
module GPX
# This class supports the concept of a waypoint. Beware that this class has
# not seen much use yet, since WalkingBoss does not use waypoints right now.
class Waypoint < Point
SUB_ELEMENTS = %q{ magvar geoidheight name cmt desc src link sym type fix sat hdop vdop pdop ageofdgpsdata dgpsid extensions }
SUB_ELEMENTS = %w{ magvar geoidheight name cmt desc src link sym type fix sat hdop vdop pdop ageofdgpsdata dgpsid extensions ele}
attr_reader :gpx_file
SUB_ELEMENTS.each { |sub_el| attr_accessor sub_el.to_sym }
# Not implemented
def crop(area)
@ -41,33 +40,35 @@ module GPX
# Initializes a waypoint from a XML::Node.
def initialize(opts = {})
if(opts[:element] and opts[:gpx_file])
wpt_elem = opts[:element]
super(:element => wpt_elem)
instantiate_with_text_elements(wpt_elem, SUB_ELEMENTS)
@gpx_file = opts[:gpx_file]
super(:element => wpt_elem, :gpx_file => @gpx_file)
instantiate_with_text_elements(wpt_elem, SUB_ELEMENTS)
else
opts.each do |key, value|
assignment_method = "#{key}="
if self.respond_to?(assignment_method)
self.send(assignment_method, value)
end
end
end
end
# Converts a waypoint to a XML::Node.
def to_xml
wpt = Node.new('wpt')
wpt.attributes['lat'] = lat
wpt.attributes['lon'] = lon
if self.respond_to? :name
name_elem = Node.new('name')
name_elem << self.name
wpt << name_elem
# Prints out a friendly summary of this track (sans points). Useful for
# debugging and sanity checks.
def to_s
result = "Waypoint \n"
result << "\tName: #{name}\n"
result << "\tLatitude: #{lat} \n"
result << "\tLongitude: #{lon} \n"
result << "\tElevation: #{elevation}\n "
result << "\tTime: #{time}\n"
SUB_ELEMENTS.each do |sub_element_attribute|
val = self.send(sub_element_attribute)
result << "\t#{sub_element_attribute}: #{val}\n" unless val.nil?
end
if self.respond_to? :sym
sym_elem = Node.new('sym')
sym_elem << self.sym
wpt << sym_elem
end
if self.respond_to? :ele
elev_elem = Node.new('ele')
elev_elem << self.ele
wpt << elev_elem
end
wpt
result
end
end
end

View File

@ -1,7 +1,7 @@
require 'test/unit'
require File.dirname(__FILE__) + '/../lib/gpx'
require 'gpx'
class TestGPX10 < Test::Unit::TestCase
class GPX10Test < Test::Unit::TestCase
GPX_FILE = File.join(File.dirname(__FILE__), "gpx_files/gpx10.gpx")
def test_read

48
tests/gpx_file_test.rb Normal file
View File

@ -0,0 +1,48 @@
require 'test/unit'
require 'gpx'
class GPXFileTest < Test::Unit::TestCase
ONE_TRACK_FILE = File.join(File.dirname(__FILE__), "gpx_files/one_track.gpx")
WITH_OR_WITHOUT_ELEV_FILE = File.join(File.dirname(__FILE__), "gpx_files/with_or_without_elev.gpx")
BIG_FILE = File.join(File.dirname(__FILE__), "gpx_files/big.gpx")
def test_load_data_from_string
gpx_file = GPX::GPXFile.new(:gpx_data => open(ONE_TRACK_FILE).read)
assert_equal(1, gpx_file.tracks.size)
assert_equal(8, gpx_file.tracks.first.segments.size)
assert_equal("ACTIVE LOG", gpx_file.tracks.first.name)
assert_equal("active_log.gpx", gpx_file.name)
assert_equal("2006-04-08T16:44:28Z", gpx_file.time.xmlschema)
assert_equal(38.681488, gpx_file.bounds.min_lat)
assert_equal(-109.606948, gpx_file.bounds.min_lon)
assert_equal(38.791759, gpx_file.bounds.max_lat)
assert_equal(-109.447045, gpx_file.bounds.max_lon)
end
def test_load_data_from_file
gpx_file = GPX::GPXFile.new(:gpx_file => ONE_TRACK_FILE)
assert_equal(1, gpx_file.tracks.size)
assert_equal(8, gpx_file.tracks.first.segments.size)
assert_equal("ACTIVE LOG", gpx_file.tracks.first.name)
assert_equal("active_log.gpx", gpx_file.name)
assert_equal("2006-04-08T16:44:28Z", gpx_file.time.xmlschema)
assert_equal(38.681488, gpx_file.bounds.min_lat)
assert_equal(-109.606948, gpx_file.bounds.min_lon)
assert_equal(38.791759, gpx_file.bounds.max_lat)
assert_equal(-109.447045, gpx_file.bounds.max_lon)
end
def test_big_file
gpx_file = GPX::GPXFile.new(:gpx_file => BIG_FILE)
assert_equal(1, gpx_file.tracks.size)
assert_equal(7968, gpx_file.tracks.first.points.size)
end
def test_with_or_with_elev
gpx_file = GPX::GPXFile.new(:gpx_file => WITH_OR_WITHOUT_ELEV_FILE)
assert_equal(2, gpx_file.tracks.size)
#assert_equal(7968, gpx_file.tracks.first.points.size)
end
end

File diff suppressed because one or more lines are too long

1
tests/gpx_files/big.gpx Normal file

File diff suppressed because one or more lines are too long

View File

@ -1 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?><gpx xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.topografix.com/GPX/1/1" version="1.1" creator="Link2GPS - 2.0.2 - http://www.hiketech.com" xsi:schemaLocation="ttp://www.topografix.com/GPX/1/1 http://www.topografix.com/GPX/1/1/gpx.xsd"><metadata><name><![CDATA[routes.gpx]]></name><time>2006-01-02T08:55:34Z</time><bounds min_lat="39.989739" min_lon="-105.295285" max_lat="39.999840" max_lon="-105.214696"/></metadata><extensions/><rte><name><![CDATA[GRG-CA-TO]]></name><rtept lat="39.997298" lon="-105.292674"><name><![CDATA[GRG-CA]]></name><sym>Waypoint</sym><ele>1766.535</ele></rtept><rtept lat="39.995700" lon="-105.292805"><name><![CDATA[AMPTHT]]></name><sym>Waypoint</sym><ele>1854.735</ele></rtept><rtept lat="39.989739" lon="-105.295285"><name><![CDATA[TO]]></name><sym>Waypoint</sym><ele>2163.556</ele></rtept></rte><rte><name><![CDATA[SBDR-SBDR]]></name><rtept lat="39.999840" lon="-105.214696"><name><![CDATA[SBDR]]></name><sym>Waypoint</sym><ele>1612.965</ele></rtept></rte></gpx>
<?xml version="1.0" encoding="UTF-8"?>
<gpx xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.topografix.com/GPX/1/1" version="1.1" creator="Link2GPS - 2.0.2 - http://www.hiketech.com" xsi:schemaLocation="ttp://www.topografix.com/GPX/1/1 http://www.topografix.com/GPX/1/1/gpx.xsd"><metadata><name><![CDATA[routes.gpx]]></name><time>2006-01-02T08:55:34Z</time><bounds min_lat="39.989739" min_lon="-105.295285" max_lat="39.999840" max_lon="-105.214696"/></metadata><extensions/>
<rte><name><![CDATA[GRG-CA-TO]]></name>
<rtept lat="39.997298" lon="-105.292674"><name><![CDATA[GRG-CA]]></name><sym>Waypoint</sym><ele>1766.535</ele></rtept>
<rtept lat="39.995700" lon="-105.292805"><name><![CDATA[AMPTHT]]></name><sym>Waypoint</sym><ele>1854.735</ele></rtept>
<rtept lat="39.989739" lon="-105.295285"><name><![CDATA[TO]]></name><sym>Waypoint</sym><ele>2163.556</ele></rtept></rte>
<rte><name><![CDATA[SBDR-SBDR]]></name>
<rtept lat="39.999840" lon="-105.214696"><name><![CDATA[SBDR]]></name><sym>Waypoint</sym><ele>1612.965</ele></rtept></rte>
</gpx>

View File

@ -1 +1,20 @@
<?xml version="1.0" encoding="UTF-8"?><gpx xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.topografix.com/GPX/1/1" version="1.1" creator="Link2GPS - 2.0.2 - http://www.hiketech.com" xsi:schemaLocation="ttp://www.topografix.com/GPX/1/1 http://www.topografix.com/GPX/1/1/gpx.xsd"><metadata><name><![CDATA[waypoints.gpx]]></name><time>2006-01-02T08:55:21Z</time><bounds min_lat="25.061783" min_lon="-111.946110" max_lat="50.982883" max_lon="121.640267"/></metadata><extensions/><wpt lat="40.035557" lon="-105.248268"><name><![CDATA[001]]></name><sym>Waypoint</sym><ele>1639.161</ele></wpt><wpt lat="39.993070" lon="-105.296588"><name><![CDATA[002]]></name><sym>Waypoint</sym><ele>1955.192</ele></wpt><wpt lat="39.990151" lon="-105.295680"><name><![CDATA[003]]></name><sym>Waypoint</sym><ele>2129.91</ele></wpt><wpt lat="39.990157" lon="-105.295686"><name><![CDATA[004]]></name><sym>Waypoint</sym><ele>2136.399</ele></wpt><wpt lat="39.990134" lon="-105.295251"><name><![CDATA[005]]></name><sym>Waypoint</sym><ele>2174.612</ele></wpt><wpt lat="39.990116" lon="-105.295147"><name><![CDATA[006]]></name><sym>Waypoint</sym><ele>2156.106</ele></wpt><wpt lat="39.990099" lon="-105.295207"><name><![CDATA[007]]></name><sym>Waypoint</sym><ele>2155.145</ele></wpt><wpt lat="39.990067" lon="-105.295185"><name><![CDATA[008]]></name><sym>Waypoint</sym><ele>2152.021</ele></wpt><wpt lat="39.995700" lon="-105.292805"><name><![CDATA[AMPTHT]]></name><sym>Waypoint</sym><ele>1854.735</ele></wpt><wpt lat="38.855550" lon="-94.799017"><name><![CDATA[GARMIN]]></name><sym>Waypoint</sym><ele>325.0491</ele></wpt><wpt lat="39.997298" lon="-105.292674"><name><![CDATA[GRG-CA]]></name><sym>Waypoint</sym><ele>1766.535</ele></wpt><wpt lat="50.982883" lon="-1.463900"><name><![CDATA[GRMEUR]]></name><sym>Waypoint</sym><ele>35.93469</ele></wpt><wpt lat="33.330190" lon="-111.946110"><name><![CDATA[GRMPHX]]></name><sym>Waypoint</sym><ele>361.0981</ele></wpt><wpt lat="25.061783" lon="121.640267"><name><![CDATA[GRMTWN]]></name><sym>Waypoint</sym><ele>38.09766</ele></wpt><wpt lat="39.999840" lon="-105.214696"><name><![CDATA[SBDR]]></name><sym>Waypoint</sym><ele>1612.965</ele></wpt><wpt lat="39.989739" lon="-105.295285"><name><![CDATA[TO]]></name><sym>Waypoint</sym><ele>2163.556</ele></wpt><wpt lat="40.035301" lon="-105.254443"><name><![CDATA[VICS]]></name><sym>Waypoint</sym><ele>1535.34</ele></wpt></gpx>
<?xml version="1.0" encoding="UTF-8"?>
<gpx xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.topografix.com/GPX/1/1" version="1.1" creator="Link2GPS - 2.0.2 - http://www.hiketech.com" xsi:schemaLocation="ttp://www.topografix.com/GPX/1/1 http://www.topografix.com/GPX/1/1/gpx.xsd"><metadata><name><![CDATA[waypoints.gpx]]></name><time>2006-01-02T08:55:21Z</time><bounds min_lat="25.061783" min_lon="-111.946110" max_lat="50.982883" max_lon="121.640267"/></metadata><extensions/>
<wpt lat="40.035557" lon="-105.248268"><name><![CDATA[001]]></name><sym>Waypoint</sym><ele>1639.161</ele><cmt><![CDATA[001]]></cmt><desc><![CDATA[Just some waypoint...]]></desc></wpt>
<wpt lat="39.993070" lon="-105.296588"><name><![CDATA[002]]></name><sym>Waypoint</sym><ele>1955.192</ele></wpt>
<wpt lat="39.990151" lon="-105.295680"><name><![CDATA[003]]></name><sym>Waypoint</sym><ele>2129.91</ele></wpt>
<wpt lat="39.990157" lon="-105.295686"><name><![CDATA[004]]></name><sym>Waypoint</sym><ele>2136.399</ele></wpt>
<wpt lat="39.990134" lon="-105.295251"><name><![CDATA[005]]></name><sym>Waypoint</sym><ele>2174.612</ele></wpt>
<wpt lat="39.990116" lon="-105.295147"><name><![CDATA[006]]></name><sym>Waypoint</sym><ele>2156.106</ele></wpt>
<wpt lat="39.990099" lon="-105.295207"><name><![CDATA[007]]></name><sym>Waypoint</sym><ele>2155.145</ele></wpt>
<wpt lat="39.990067" lon="-105.295185"><name><![CDATA[008]]></name><sym>Waypoint</sym><ele>2152.021</ele></wpt>
<wpt lat="39.995700" lon="-105.292805"><name><![CDATA[AMPTHT]]></name><sym>Waypoint</sym><ele>1854.735</ele></wpt>
<wpt lat="38.855550" lon="-94.799017"><name><![CDATA[GARMIN]]></name><sym>Waypoint</sym><ele>325.0491</ele></wpt>
<wpt lat="39.997298" lon="-105.292674"><name><![CDATA[GRG-CA]]></name><sym>Waypoint</sym><ele>1766.535</ele></wpt>
<wpt lat="50.982883" lon="-1.463900"><name><![CDATA[GRMEUR]]></name><sym>Waypoint</sym><ele>35.93469</ele></wpt>
<wpt lat="33.330190" lon="-111.946110"><name><![CDATA[GRMPHX]]></name><sym>Waypoint</sym><ele>361.0981</ele></wpt>
<wpt lat="25.061783" lon="121.640267"><name><![CDATA[GRMTWN]]></name><sym>Waypoint</sym><ele>38.09766</ele></wpt>
<wpt lat="39.999840" lon="-105.214696"><name><![CDATA[SBDR]]></name><sym>Waypoint</sym><ele>1612.965</ele></wpt>
<wpt lat="39.989739" lon="-105.295285"><name><![CDATA[TO]]></name><sym>Waypoint</sym><ele>2163.556</ele></wpt>
<wpt lat="40.035301" lon="-105.254443"><name><![CDATA[VICS]]></name><sym>Waypoint</sym><ele>1535.34</ele></wpt>
</gpx>

View File

@ -0,0 +1,29 @@
<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
<gpx xmlns="http://www.topografix.com/GPX/1/1" creator="MapSource 6.5" version="1.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.topografix.com/GPX/1/1 http://www.topografix.com/GPX/1/1/gpx.xsd">
<metadata>
<link href="http://www.garmin.com">
<text>Garmin International</text>
</link>
<time>2007-04-16T18:11:47Z</time>
<bounds maxlat="40.207429" maxlon="116.670578" minlat="39.876895" minlon="101.636217"/>
</metadata>
<trk>
<name>ACTIVE LOG</name>
<trkseg>
<trkpt lat="40.079434" lon="116.295948">
<ele>50.606567</ele>
<time>2007-03-25T05:17:34Z</time>
</trkpt>
</trkseg>
</trk>
<trk>
<name>LINE-13</name>
<trkseg>
<trkpt lat="39.949744" lon="116.427398"/>
</trkseg>
</trk>
</gpx>

View File

@ -1,7 +1,7 @@
require 'test/unit'
require File.dirname(__FILE__) + '/../lib/gpx'
require 'gpx'
class TestMagellanTrackLog < Test::Unit::TestCase
class MagellanTest < Test::Unit::TestCase
MAGELLAN_TRACK_LOG = File.join(File.dirname(__FILE__), "gpx_files/magellan_track.log")
GPX_FILE = File.join(File.dirname(__FILE__), "gpx_files/one_segment.gpx")

115
tests/output_test.rb Normal file
View File

@ -0,0 +1,115 @@
require 'test/unit'
require 'fileutils'
require 'gpx'
class OutputTest < Test::Unit::TestCase
include GPX
def setup
FileUtils.mkdir_p(File.join(File.dirname(__FILE__), "output"))
end
def test_new_gpx_file_from_scratch
gpx_file = GPXFile.new
track = Track.new(:name => "My First Track")
segment = Segment.new
track_point_data = [
{:lat => 40.036926, :lon =>-105.253487, :time => Time.parse('2005-12-31T22:01:24Z'), :elevation => 1737.24},
{:lat => 40.036604, :lon =>-105.253487, :time => Time.parse("2005-12-31T22:02:01Z"), :elevation => 1738.682},
{:lat => 40.036347, :lon =>-105.253830, :time => Time.parse("2005-12-31T22:02:08Z"), :elevation => 1738.682},
{:lat => 40.035574, :lon =>-105.254045, :time => Time.parse("2005-12-31T22:02:20Z"), :elevation => 1737.24},
{:lat => 40.035467, :lon =>-105.254366, :time => Time.parse("2005-12-31T22:02:29Z"), :elevation => 1735.798},
{:lat => 40.035317, :lon =>-105.254388, :time => Time.parse("2005-12-31T22:02:33Z"), :elevation => 1735.798},
{:lat => 40.035274, :lon =>-105.254431, :time => Time.parse("2005-12-31T22:02:49Z"), :elevation => 1736.278},
{:lat => 40.035274, :lon =>-105.254431, :time => Time.parse("2005-12-31T22:02:54Z"), :elevation => 1739.643},
{:lat => 40.035317, :lon =>-105.254431, :time => Time.parse("2005-12-31T22:05:08Z"), :elevation => 1732.433},
{:lat => 40.035317, :lon =>-105.254431, :time => Time.parse("2005-12-31T22:05:09Z"), :elevation => 1726.665}]
track_point_data.each do |trk_pt_hash|
segment.points << TrackPoint.new(trk_pt_hash)
end
track.segments << segment
gpx_file.tracks << track
waypoint_data = [
{:lat => 39.997298, :lon => -105.292674, :name => 'GRG-CA', :sym => 'Waypoint', :ele => '1766.535'},
{:lat => 33.330190, :lon => -111.946110, :name => 'GRMPHX', :sym => 'Waypoint', :ele => '361.0981',
:cmt => "Hey here's a comment.", :desc => "Somewhere in my backyard.", :fix => '3d', :sat => "8", :hdop => "50.5", :vdop => "6.8", :pdop => "7.6"},
{:lat => 25.061783, :lon => 121.640267, :name => 'GRMTWN', :sym => 'Waypoint', :ele => '38.09766'},
{:lat => 39.999840, :lon => -105.214696, :name => 'SBDR', :sym => 'Waypoint', :ele => '1612.965'},
{:lat => 39.989739, :lon => -105.295285, :name => 'TO', :sym => 'Waypoint', :ele => '2163.556'},
{:lat => 40.035301, :lon => -105.254443, :name => 'VICS', :sym => 'Waypoint', :ele => '1535.34'}
]
waypoint_data.each do |wpt_hash|
gpx_file.waypoints << Waypoint.new(wpt_hash)
end
route_point_data = [
{:lat => 40.035467, :lon =>-105.254366, :time => Time.parse("2005-12-31T22:02:29Z"), :elevation => 1735.798},
{:lat => 40.035317, :lon =>-105.254388, :time => Time.parse("2005-12-31T22:02:33Z"), :elevation => 1735.798},
{:lat => 40.035274, :lon =>-105.254431, :time => Time.parse("2005-12-31T22:02:49Z"), :elevation => 1736.278} ]
route = Route.new()
route_point_data.each do |rte_pt_hash|
route.points << Point.new(rte_pt_hash)
end
gpx_file.routes << route
gpx_file.write(output_file(name_of_test))
written_gpx_file = GPXFile.new(:gpx_file => output_file(name_of_test))
assert_equal(File.basename(output_file(name_of_test)), written_gpx_file.name)
assert_equal(1, written_gpx_file.tracks.size)
assert_equal(1, written_gpx_file.tracks[0].segments.size)
assert_equal(track_point_data.size, written_gpx_file.tracks[0].segments[0].points.size)
assert_equal(track_point_data.size, written_gpx_file.tracks[0].points.size)
# Make sure each point in the segment has the attributes it was initialized with
written_segment = written_gpx_file.tracks[0].segments[0]
track_point_data.each_with_index do |trk_pt_hash, index|
trk_pt_hash.each do |key, value|
assert_equal(value, written_segment.points[index].send(key))
end
end
# Make sure the one route has the attributes we initialized it with
assert_equal(1, written_gpx_file.routes.size)
written_route = written_gpx_file.routes[0]
assert_equal(route_point_data.size, written_route.points.size)
route_point_data.each_with_index do |rte_pt_hash, index|
rte_pt_hash.each do |key, value|
assert_equal(value, written_route.points[index].send(key))
end
end
# Make sure the waypoints have all of the attributes we initialized them with
written_waypoints = written_gpx_file.waypoints
assert_equal(waypoint_data.size, written_waypoints.size)
waypoint_data.each_with_index do |wpt_hash, index|
wpt_hash.each do |key, value|
assert_equal(value, written_waypoints[index].send(key.to_s), key)
end
end
end
def name_of_test
caller[0] =~ /`test_([^']*)'/ and $1
end
def output_file(test_name)
File.join(File.dirname(__FILE__), "output/#{test_name}.gpx")
end
THE_WORKS = "<?xml version=\"1.0\"?>\n<gpx xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns=\"http://www.topografix.com/GPX/1/1\" version=\"1.1\" creator=\"GPX RubyGem #{GPX::VERSION} Copyright 2006-2009 Doug Fales -- http://gpx.rubyforge.org/\" xsi:schemaLocation=\"http://www.topografix.com/GPX/1/1 http://www.topografix.com/GPX/1/1/gpx.xsd\">\n <metadata>\n <name>new_gpx_file_from_scratch.gpx</name>\n <time>%s</time>\n <bounds minlat=\"90.0\" minlon=\"180.0\" maxlat=\"-90.0\" maxlon=\"-180.0\"/>\n </metadata>\n <trk>\n <name/>\n <trkseg>\n <trkpt lat=\"40.036926\" lon=\"-105.253487\">\n <time>2005-12-31T22:01:24Z</time>\n <ele>1737.24</ele>\n </trkpt>\n <trkpt lat=\"40.036604\" lon=\"-105.253487\">\n <time>2005-12-31T22:02:01Z</time>\n <ele>1738.682</ele>\n </trkpt>\n <trkpt lat=\"40.036347\" lon=\"-105.25383\">\n <time>2005-12-31T22:02:08Z</time>\n <ele>1738.682</ele>\n </trkpt>\n <trkpt lat=\"40.035574\" lon=\"-105.254045\">\n <time>2005-12-31T22:02:20Z</time>\n <ele>1737.24</ele>\n </trkpt>\n <trkpt lat=\"40.035467\" lon=\"-105.254366\">\n <time>2005-12-31T22:02:29Z</time>\n <ele>1735.798</ele>\n </trkpt>\n <trkpt lat=\"40.035317\" lon=\"-105.254388\">\n <time>2005-12-31T22:02:33Z</time>\n <ele>1735.798</ele>\n </trkpt>\n <trkpt lat=\"40.035274\" lon=\"-105.254431\">\n <time>2005-12-31T22:02:49Z</time>\n <ele>1736.278</ele>\n </trkpt>\n <trkpt lat=\"40.035274\" lon=\"-105.254431\">\n <time>2005-12-31T22:02:54Z</time>\n <ele>1739.643</ele>\n </trkpt>\n <trkpt lat=\"40.035317\" lon=\"-105.254431\">\n <time>2005-12-31T22:05:08Z</time>\n <ele>1732.433</ele>\n </trkpt>\n <trkpt lat=\"40.035317\" lon=\"-105.254431\">\n <time>2005-12-31T22:05:09Z</time>\n <ele>1726.665</ele>\n </trkpt>\n </trkseg>\n </trk>\n <wpt lat=\"39.997298\" lon=\"-105.292674\">\n <name>GRG-CA</name>\n <sym>Waypoint</sym>\n <ele>1766.535</ele>\n </wpt>\n <wpt lat=\"33.33019\" lon=\"-111.94611\">\n <name>GRMPHX</name>\n <cmt>Hey here's a comment.</cmt>\n <desc>Somewhere in my backyard.</desc>\n <sym>Waypoint</sym>\n <fix>3d</fix>\n <sat>8</sat>\n <hdop>50.5</hdop>\n <vdop>6.8</vdop>\n <pdop>7.6</pdop>\n <ele>361.0981</ele>\n </wpt>\n <wpt lat=\"25.061783\" lon=\"121.640267\">\n <name>GRMTWN</name>\n <sym>Waypoint</sym>\n <ele>38.09766</ele>\n </wpt>\n <wpt lat=\"39.99984\" lon=\"-105.214696\">\n <name>SBDR</name>\n <sym>Waypoint</sym>\n <ele>1612.965</ele>\n </wpt>\n <wpt lat=\"39.989739\" lon=\"-105.295285\">\n <name>TO</name>\n <sym>Waypoint</sym>\n <ele>2163.556</ele>\n </wpt>\n <wpt lat=\"40.035301\" lon=\"-105.254443\">\n <name>VICS</name>\n <sym>Waypoint</sym>\n <ele>1535.34</ele>\n </wpt>\n <rte>\n <name/>\n <rtept lat=\"40.035467\" lon=\"-105.254366\">\n <time>2005-12-31T22:02:29Z</time>\n <ele>1735.798</ele>\n </rtept>\n <rtept lat=\"40.035317\" lon=\"-105.254388\">\n <time>2005-12-31T22:02:33Z</time>\n <ele>1735.798</ele>\n </rtept>\n <rtept lat=\"40.035274\" lon=\"-105.254431\">\n <time>2005-12-31T22:02:49Z</time>\n <ele>1736.278</ele>\n </rtept>\n </rte>\n</gpx>\n"
end

63
tests/route_test.rb Normal file
View File

@ -0,0 +1,63 @@
require 'test/unit'
require 'gpx'
class RouteTest < Test::Unit::TestCase
def test_read_routes
gpx = GPX::GPXFile.new(:gpx_file => File.join(File.dirname(__FILE__), "gpx_files/routes.gpx"))
assert_equal(2, gpx.routes.size)
first_route = gpx.routes.first
assert_equal(3, first_route.points.size)
assert_equal('GRG-CA-TO', first_route.name)
# Route 1, First Point
# <rtept lat="39.997298" lon="-105.292674">
# <name><![CDATA[GRG-CA]]></name>
# <sym>Waypoint</sym>
# <ele>1766.535</ele>
# </rtept>
assert_equal(39.997298, first_route.points[0].lat)
assert_equal(-105.292674, first_route.points[0].lon)
assert_equal(1766.535, first_route.points[0].elevation)
# Route 1, Second Point
# <rtept lat="39.995700" lon="-105.292805">
# <name><![CDATA[AMPTHT]]></name>
# <sym>Waypoint</sym>
# <ele>1854.735</ele>
# </rtept>
assert_equal(39.995700, first_route.points[1].lat)
assert_equal(-105.292805, first_route.points[1].lon)
assert_equal(1854.735, first_route.points[1].elevation)
# Route 1, Third Point
# <rtept lat="39.989739" lon="-105.295285">
# <name><![CDATA[TO]]></name>
# <sym>Waypoint</sym>
# <ele>2163.556</ele>
# </rtept>
assert_equal(39.989739, first_route.points[2].lat)
assert_equal(-105.295285, first_route.points[2].lon)
assert_equal(2163.556, first_route.points[2].elevation)
second_route = gpx.routes[1]
assert_equal(1, second_route.points.size)
assert_equal('SBDR-SBDR', second_route.name)
# Route 2, Only Point
# <rtept lat="39.999840" lon="-105.214696">
# <name><![CDATA[SBDR]]></name>
# <sym>Waypoint</sym>
# <ele>1612.965</ele>
# </rtept>
assert_equal(39.999840, second_route.points[0].lat)
assert_equal(-105.214696, second_route.points[0].lon)
assert_equal(1612.965, second_route.points[0].elevation)
end
end

View File

@ -1,8 +1,8 @@
require 'test/unit'
require 'yaml'
require File.dirname(__FILE__) + '/../lib/gpx'
require 'gpx'
class TestSegment < Test::Unit::TestCase
class SegmentTest < Test::Unit::TestCase
ONE_SEGMENT = File.join(File.dirname(__FILE__), "gpx_files/one_segment.gpx")
def setup
@ -12,11 +12,11 @@ class TestSegment < Test::Unit::TestCase
def test_segment_read
assert_equal(189, @segment.points.size)
assert_equal("Fri Apr 07 18:12:05 UTC 2006", @segment.earliest_point.time.to_s)
assert_equal("Fri Apr 07 19:26:31 UTC 2006", @segment.latest_point.time.to_s)
assert_equal(1144433525, @segment.earliest_point.time.to_i)
assert_equal(1144437991, @segment.latest_point.time.to_i)
assert_equal(1334.447, @segment.lowest_point.elevation)
assert_equal(1480.087, @segment.highest_point.elevation)
assert_equal("6.98803359528853", @segment.distance.to_s)
assert_in_delta(6.98803359528853, @segment.distance, 0.001)
end
def test_segment_crop
@ -27,9 +27,9 @@ class TestSegment < Test::Unit::TestCase
@segment.crop(crop_rectangle)
assert_equal(106, @segment.points.size)
assert_equal("4.11422061733046", @segment.distance.to_s)
assert_equal("Fri Apr 07 18:37:21 UTC 2006", @segment.earliest_point.time.to_s)
assert_equal("Fri Apr 07 19:22:32 UTC 2006", @segment.latest_point.time.to_s)
assert_in_delta(4.11422061733046, @segment.distance, 0.001)
assert_equal(1144435041, @segment.earliest_point.time.to_i)
assert_equal(1144437752, @segment.latest_point.time.to_i)
assert_equal(1407.027, @segment.lowest_point.elevation)
assert_equal(1480.087, @segment.highest_point.elevation)
assert_equal(39.173834, @segment.bounds.min_lat)
@ -45,9 +45,9 @@ class TestSegment < Test::Unit::TestCase
:max_lon=> -108.999000)
@segment.delete_area(delete_rectangle)
assert_equal(83, @segment.points.size)
assert_equal("3.35967118153605", @segment.distance.to_s)
assert_equal("Fri Apr 07 18:12:05 UTC 2006", @segment.earliest_point.time.to_s)
assert_equal("Fri Apr 07 19:26:31 UTC 2006", @segment.latest_point.time.to_s)
assert_in_delta(3.35967118153605, @segment.distance, 0.001)
assert_equal(1144433525, @segment.earliest_point.time.to_i)
assert_equal(1144437991, @segment.latest_point.time.to_i)
assert_equal(1334.447, @segment.lowest_point.elevation)
assert_equal(1428.176, @segment.highest_point.elevation)
assert_equal(39.180572, @segment.bounds.min_lat)

View File

@ -1,7 +1,7 @@
require 'test/unit'
require File.dirname(__FILE__) + '/../lib/gpx'
require 'gpx'
class TestTrackFile < Test::Unit::TestCase
class TrackFileTest < Test::Unit::TestCase
TRACK_FILE = File.join(File.dirname(__FILE__), "gpx_files/tracks.gpx")
OTHER_TRACK_FILE = File.join(File.dirname(__FILE__), "gpx_files/arches.gpx")
@ -69,7 +69,7 @@ class TestTrackFile < Test::Unit::TestCase
end
def test_write
@other_track_file.write("myoutput.gpx")
@other_track_file.write("tests/output/myoutput.gpx")
end
end

View File

@ -1,7 +1,7 @@
require 'test/unit'
require File.dirname(__FILE__) + '/../lib/gpx'
require 'gpx'
class TestTrack < Test::Unit::TestCase
class TrackTest < Test::Unit::TestCase
ONE_TRACK = File.join(File.dirname(__FILE__), "gpx_files/one_track.gpx")
def setup
@ -11,9 +11,9 @@ class TestTrack < Test::Unit::TestCase
def test_track_read
assert_equal("ACTIVE LOG", @track.name)
assert_equal( 364, @track.points.size)
assert_equal( 182, @track.points.size)
assert_equal(8, @track.segments.size)
assert_equal("3.07249668492626", @track.distance.to_s)
assert_in_delta(3.07249668492626, @track.distance, 0.001)
assert_equal(1267.155, @track.lowest_point.elevation)
assert_equal(1594.003, @track.highest_point.elevation)
assert_equal(38.681488, @track.bounds.min_lat)
@ -32,7 +32,7 @@ class TestTrack < Test::Unit::TestCase
assert_equal("ACTIVE LOG", @track.name)
assert_equal( 111, @track.points.size)
assert_equal(4, @track.segments.size)
assert_equal("1.62136024923607", @track.distance.to_s)
assert_in_delta(1.62136024923607, @track.distance, 0.001)
assert_equal(1557.954, @track.lowest_point.elevation)
assert_equal(1582.468, @track.highest_point.elevation)
assert_equal(38.782511, @track.bounds.min_lat)

44
tests/waypoint_test.rb Executable file
View File

@ -0,0 +1,44 @@
require 'test/unit'
require 'gpx'
class WaypointTest < Test::Unit::TestCase
def test_read_waypoints
gpx = GPX::GPXFile.new(:gpx_file => File.join(File.dirname(__FILE__), "gpx_files/waypoints.gpx"))
assert_equal(17, gpx.waypoints.size)
# First Waypoint
# <wpt lat="40.035557" lon="-105.248268">
# <name><![CDATA[001]]></name>
# <sym>Waypoint</sym>
# <ele>1639.161</ele>
# <cmt><![CDATA[001]]></cmt>
# <desc><![CDATA[Just some waypoint...]]></desc>
# </wpt>
first_wpt = gpx.waypoints[0]
assert_equal(40.035557, first_wpt.lat)
assert_equal(-105.248268, first_wpt.lon)
assert_equal('001', first_wpt.name)
assert_equal('001', first_wpt.cmt)
assert_equal('Just some waypoint...', first_wpt.desc)
assert_equal('Waypoint', first_wpt.sym)
assert_equal(1639.161, first_wpt.elevation)
# Second Waypoint
# <wpt lat="39.993070" lon="-105.296588">
# <name><![CDATA[002]]></name>
# <sym>Waypoint</sym>
# <ele>1955.192</ele>
# </wpt>
second_wpt = gpx.waypoints[1]
assert_equal(39.993070, second_wpt.lat)
assert_equal(-105.296588, second_wpt.lon)
assert_equal('002', second_wpt.name)
assert_equal('Waypoint', second_wpt.sym)
assert_equal(1955.192, second_wpt.elevation)
end
end