Compare commits

..

No commits in common. "gh-pages" and "master" have entirely different histories.

39 changed files with 10057 additions and 215 deletions

3
.gitignore vendored 100644
View File

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

60
ChangeLog 100644
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 100644
View File

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

46
README.rdoc 100644
View File

@ -0,0 +1,46 @@
= GPX Gem
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.
In addition to parsing GPX files, this library is capable of converting
Magellan NMEA files to GPX, and writing new GPX files. It can crop and delete
rectangular areas within a file, and it also calculates some meta-data about
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
gpx.crop(bounds) # Crop it
gpx.write(filename) # Save it
Converting a Magellan track log to GPX:
if GPX::MagellanTrackLog::is_magellan_file?(filename)
GPX::MagellanTrackLog::convert_to_gpx(filename, "#{filename}.gpx")
end
== Notes
This library was written to bridge the gap between my Garmin Geko
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.
Since this code uses XML to read an entire GPX file into memory, it is not
the fastest possible solution for working with GPX data, especially if you are
working with tracks from several days or weeks.
Finally, it should be noted that none of the distance/speed calculation or
crop/delete code has been tested under International Date Line-crossing
conditions. That particular part of the code will likely be unreliable if
you're zig-zagging across 180 degrees longitude routinely.

23
Rakefile 100644
View File

@ -0,0 +1,23 @@
require 'bundler/gem_tasks'
require 'rake/testtask'
require 'rdoc/task'
desc "Default Task"
task :default => [ :test ]
# Run the unit tests
desc "Run all unit tests"
Rake::TestTask.new("test") { |t|
t.libs << "lib"
t.pattern = 'tests/*_test.rb'
t.verbose = true
}
# Genereate the RDoc documentation
desc "Create documentation"
Rake::RDocTask.new("doc") { |rdoc|
rdoc.title = "Ruby GPX API"
rdoc.rdoc_dir = 'html'
rdoc.rdoc_files.include('README')
rdoc.rdoc_files.include('lib/**/*.rb')
}

129
gpx.css
View File

@ -1,129 +0,0 @@
.clearfix:after {
content: ".";
display: block;
height: 0;
clear: both;
visibility: hidden;
}
.clearfix {
display: inline-table;
}
/* Hides from IE-mac \*/
* html .clearfix {
height: 1%;
}
.clearfix {
display: block;
}
/* End hide from IE-mac */
body div, body span, body img {
border: 0;
padding: 0;
margin: 0;
}
body {
font: 11pt arial;
border: 0;
padding: 0;
margin: 0;
background: #ffffff url(/images/background.gif) repeat-x;
}
p {
margin: 0;
line-height: 1.5em;
color: #5d5952;
}
.mainbody h1 {
font: 22pt arial;
color: #5d5952;
font-weight: bold;
margin: 0;
margin-top: 20px;
margin-bottom: 10px;
}
.mainbody h2 {
font: 14pt arial;
color: #5d5952;
font-weight: bold;
margin: 0;
margin-top: 5px;
margin-bottom: 10px;
}
.mainbody h3 {
font: 10pt arial;
color: #5d5952;
font-weight: bold;
margin: 0;
margin-bottom: 10px;
}
a {
color: #396f94;
text-decoration: none;
}
a:link {
color: #396f94;
text-decoration: none;
}
a:active {
color: #ff8400;
text-decoration: none;
}
a:visited {
color: #396f94;
text-decoration: none;
}
a:hover {
color: #f1e637;
text-decoration: none;
}
.wholepage {
margin: auto;
padding: 0;
width: 800px;
margin-top: 0px;
margin-bottom: 80px;
border: 0px solid #ffffff;
}
.header { height: 78px; }
.logo { float: left; }
.logo h1 { color: #6b9c0d; }
.mainbody {
margin-top: -20px;
/* border-left: 1px solid #94b1c5;
border-right: 1px solid #94b1c5;
border-bottom: 1px solid #94b1c5;
*/
padding-left: 10px;
padding-right: 10px;
background-color: #fff;
padding-bottom: 100px;
/*min-height: 300px;*/
}

22
gpx.gemspec 100644
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

@ -1,86 +0,0 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:v="urn:schemas-microsoft-com:vml">
<head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8"/>
<title>GPX Gem</title>
<link href="gpx.css" media="screen" rel="Stylesheet" type="text/css" />
</head>
<body>
<div class="wholepage">
<div class="header">
<div class="logo">
<h1>GPX gem</h1>
</div>
</div>
<div class="mainbody clearfix">
<div class="body">
<br/>
<h2>What</h2>
<p> <a href="http://www.topografix.com/gpx.asp">GPX</a> is an XML
format for GPS data. Many personal GPS devices now support
outputting their track logs to GPX. If you want to do something
fun with the data from your GPS device, then this might be a
good place to start.
<br/>
<br/>
<h2>Where</h2>
<p> I'm now hosting this <a href="http://github.com/dougfales/gpx">project on github now</a>. Please fork if you'd like to make improvements!
(The rubyforge page will remain up, but I won't be checking-in any code there.)
<br/>
<br/>
<h2>Why</h2>
<p>
This gem is the direct result of my work on a site I once wrote called WalkingBoss (RIP).
It powered the trip creation and editing parts of the site. After talking
about WalkingBoss at a few different Ruby groups and RailsConf,
I was convinced that I really should release this code back to
the community. After all, a large portion of the site would not
exist were it not for the many other open source ruby projects I
used in creating it.
<br/>
<br/>
<h2>How</h2>
<p>
Version 0.1 of this library relied entirely on REXML for XML
parsing, which was convenient (no dependencies) but slow on
large GPX files. Since version 0.2, the library relies on
<a href="http://libxml.rubyforge.org/">the libxml-ruby bindings</a>.
Instead of taking minutes to run, the unit tests now take a matter
of seconds.
<br/>
<br/>
<!-- <h2>Examples/Docs</h2>
<p> See the README file in the <a href="rdoc/index.html">RDoc docs</a> for examples. -->
<!-- <br/>
<br/>
<h2>Download</h2>
<p> To download the latest version of this gem, please visit: <a href="http://rubyforge.org/projects/gpx/">http://rubyforge.org/projects/gpx/</a>.
<br/>
<br/> -->
<h2>Who</h2>
<p>My name is <a href="http://blog.falesafeconsulting.com">Doug Fales</a>. I'm a software consultant in Montana.
I enjoy writing software but would rather be outdoors making
more GPX files on most days. If you would like to contact me
about anything (bugs, patches, or freelance work), I can be
reached at: doug [at] falesafeconsulting [dot] com.
<br/>
</div>
</div>
</div>
</body>
</html>

38
lib/gpx.rb 100644
View File

@ -0,0 +1,38 @@
#--
# Copyright (c) 2006 Doug Fales
#
# Permission is hereby granted, free of charge, to any person obtaining
# a copy of this software and associated documentation files (the
# "Software"), to deal in the Software without restriction, including
# without limitation the rights to use, copy, modify, merge, publish,
# distribute, sublicense, and/or sell copies of the Software, and to
# permit persons to whom the Software is furnished to do so, subject to
# the following conditions:
#
# The above copyright notice and this permission notice shall be
# included in all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#++
require 'time'
require 'nokogiri'
require 'gpx/version'
require 'gpx/gpx'
require 'gpx/gpx_file'
require 'gpx/bounds'
require 'gpx/track'
require 'gpx/route'
require 'gpx/segment'
require 'gpx/point'
require 'gpx/trackpoint'
require 'gpx/waypoint'
require 'gpx/magellan_track_log'

74
lib/gpx/bounds.rb 100644
View File

@ -0,0 +1,74 @@
#--
# Copyright (c) 2006 Doug Fales
#
# Permission is hereby granted, free of charge, to any person obtaining
# a copy of this software and associated documentation files (the
# "Software"), to deal in the Software without restriction, including
# without limitation the rights to use, copy, modify, merge, publish,
# distribute, sublicense, and/or sell copies of the Software, and to
# permit persons to whom the Software is furnished to do so, subject to
# the following conditions:
#
# The above copyright notice and this permission notice shall be
# included in all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
# 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
class Bounds < Base
attr_accessor :min_lat, :max_lat, :max_lon, :min_lon, :center_lat, :center_lon
# Creates a new bounds object with the passed-in min and max longitudes
# and latitudes.
def initialize(opts = { :min_lat => 90.0, :max_lat => -90.0, :min_lon => 180.0, :max_lon => -180.0})
@min_lat, @max_lat = opts[:min_lat].to_f, opts[:max_lat].to_f
@min_lon, @max_lon = opts[:min_lon].to_f, opts[:max_lon].to_f
end
# Returns the middle latitude.
def center_lat
distance = (max_lat - min_lat)/2.0
(min_lat + distance)
end
# Returns the middle longitude.
def center_lon
distance = (max_lon - min_lon)/2.0
(min_lon + distance)
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)
end
# Adds an item to itself, expanding its min/max lat/lon as needed to
# contain the given item. The item can be either another instance of
# Bounds or a Point.
def add(item)
if(item.respond_to?(:lat) and item.respond_to?(:lon))
@min_lat = item.lat if item.lat < @min_lat
@min_lon = item.lon if item.lon < @min_lon
@max_lat = item.lat if item.lat > @max_lat
@max_lon = item.lon if item.lon > @max_lon
else
@min_lat = item.min_lat if item.min_lat < @min_lat
@min_lon = item.min_lon if item.min_lon < @min_lon
@max_lat = item.max_lat if item.max_lat > @max_lat
@max_lon = item.max_lon if item.max_lon > @max_lon
end
end
# Returns the min_lat, min_lon, max_lat, and max_lon in a labeled string.
def to_s
"min_lat: #{min_lat} min_lon: #{min_lon} max_lat: #{max_lat} max_lon: #{max_lon}"
end
end
end

46
lib/gpx/gpx.rb 100644
View File

@ -0,0 +1,46 @@
#--
# Copyright (c) 2006 Doug Fales
#
# Permission is hereby granted, free of charge, to any person obtaining
# a copy of this software and associated documentation files (the
# "Software"), to deal in the Software without restriction, including
# without limitation the rights to use, copy, modify, merge, publish,
# distribute, sublicense, and/or sell copies of the Software, and to
# permit persons to whom the Software is furnished to do so, subject to
# the following conditions:
#
# The above copyright notice and this permission notice shall be
# included in all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
# 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
# A common base class which provides a useful initializer method to many
# class in the GPX library.
class Base
# 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
# an attribute to be initialized on the instance. This means you don't
# have to pick out individual text elements in each initializer of each
# class (Route, TrackPoint, Track, etc). Just pass an array of possible
# attributes to this method.
def instantiate_with_text_elements(parent, text_elements)
text_elements.each do |el|
child_xpath = "#{el}"
unless parent.at(child_xpath).nil?
val = parent.at(child_xpath).inner_text
self.send("#{el}=", val)
end
end
end
end
end

288
lib/gpx/gpx_file.rb 100644
View File

@ -0,0 +1,288 @@
#--
# Copyright (c) 2006 Doug Fales
#
# Permission is hereby granted, free of charge, to any person obtaining
# a copy of this software and associated documentation files (the
# "Software"), to deal in the Software without restriction, including
# without limitation the rights to use, copy, modify, merge, publish,
# distribute, sublicense, and/or sell copies of the Software, and to
# permit persons to whom the Software is furnished to do so, subject to
# the following conditions:
#
# The above copyright notice and this permission notice shall be
# included in all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
# 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
class GPXFile < Base
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
# add tracks and points and write it out to a new file later).
# To read an existing GPX file, do this:
# gpx_file = GPXFile.new(:gpx_file => 'mygpxfile.gpx')
# puts "Speed: #{gpx_file.average_speed}"
# 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:
# some_track = get_track_from_csv('some_other_format.csv')
# gpx_file = GPXFile.new(:tracks => [some_track])
#
def initialize(opts = {})
@duration = 0
if(opts[:gpx_file] or opts[:gpx_data])
if opts[:gpx_file]
gpx_file = opts[:gpx_file]
gpx_file = File.open(gpx_file) unless gpx_file.is_a?(File)
@xml = Nokogiri::XML(gpx_file)
else
@xml = Nokogiri::XML(opts[:gpx_data])
end
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})
@bounds.max_lat = get_bounds_attr_value(bounds_element, %w{ max_lat maxlat maxLat})
@bounds.max_lon = get_bounds_attr_value(bounds_element, %w{ max_lon maxlon maxLon})
else
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.search("trk").each do |trk|
trk = Track.new(:element => trk, :gpx_file => self)
update_meta_data(trk, get_bounds)
@tracks << trk
end
@waypoints = []
@xml.search("wpt").each { |wpt| @waypoints << Waypoint.new(:element => wpt, :gpx_file => self) }
@routes = []
@xml.search("rte").each { |rte| @routes << Route.new(:element => rte, :gpx_file => self) }
@tracks.delete_if { |t| t.empty? }
calculate_duration
else
reset_meta_data
opts.each { |attr_name, value| instance_variable_set("@#{attr_name.to_s}", value) }
unless(@tracks.nil? or @tracks.size.zero?)
@tracks.each { |trk| update_meta_data(trk) }
calculate_duration
end
end
@tracks ||= []
@routes ||= []
@waypoints ||= []
end
def get_bounds_attr_value(el, possible_names)
result = nil
possible_names.each do |name|
result = el[name]
break unless result.nil?
end
return (result.to_f rescue nil)
end
# Returns the distance, in kilometers, meters, or miles, of all of the
# tracks and segments contained in this GPXFile.
def distance(opts = { :units => 'kilometers' })
case opts[:units]
when /kilometers/i
return @distance
when /meters/i
return (@distance * 1000)
when /miles/i
return (@distance * 0.62)
end
end
# Returns the average speed, in km/hr, meters/hr, or miles/hr, of this
# GPXFile. The calculation is based on the total distance divided by the
# total duration of the entire file.
def average_speed(opts = { :units => 'kilometers' })
case opts[:units]
when /kilometers/i
return @distance / (@duration/3600.0)
when /meters/i
return (@distance * 1000) / (@duration/3600.0)
when /miles/i
return (@distance * 0.62) / (@duration/3600.0)
end
end
# Crops any points falling within a rectangular area. Identical to the
# delete_area method in every respect except that the points outside of
# the given area are deleted. Note that this method automatically causes
# the meta data to be updated after deletion.
def crop(area)
reset_meta_data
keep_tracks = []
tracks.each do |trk|
trk.crop(area)
unless trk.empty?
update_meta_data(trk)
keep_tracks << trk
end
end
@tracks = keep_tracks
routes.each { |rte| rte.crop(area) }
waypoints.each { |wpt| wpt.crop(area) }
end
# Deletes any points falling within a rectangular area. The "area"
# parameter is usually an instance of the Bounds class. Note that this
# method cascades into similarly named methods of subordinate classes
# (i.e. Track, Segment), which means, if you want the deletion to apply
# to all the data, you only call this one (and not the one in Track or
# Segment classes). Note that this method automatically causes the meta
# data to be updated after deletion.
def delete_area(area)
reset_meta_data
keep_tracks = []
tracks.each do |trk|
trk.delete_area(area)
unless trk.empty?
update_meta_data(trk)
keep_tracks << trk
end
end
@tracks = keep_tracks
routes.each { |rte| rte.delete_area(area) }
waypoints.each { |wpt| wpt.delete_area(area) }
end
# Resets the meta data for this GPX file. Meta data includes the bounds,
# the high and low points, and the distance.
def reset_meta_data
@bounds = Bounds.new
@highest_point = nil
@lowest_point = nil
@distance = 0.0
end
# Updates the meta data for this GPX file. Meta data includes the
# bounds, the high and low points, and the distance. This is useful when
# 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.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, 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
def to_s(update_time = true)
@time = Time.now if(@time.nil? or update_time)
doc = generate_xml_doc
doc.to_xml
end
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.
def calculate_duration
@duration = 0
if(@tracks.nil? or @tracks.size.zero? or @tracks[0].segments.nil? or @tracks[0].segments.size.zero?)
return @duration
end
@duration = (@tracks[-1].segments[-1].points[-1].time - @tracks.first.segments.first.points.first.time)
rescue
@duration = 0
end
end
end

View File

@ -0,0 +1,132 @@
#--
# Copyright (c) 2006 Doug Fales
#
# Permission is hereby granted, free of charge, to any person obtaining
# a copy of this software and associated documentation files (the
# "Software"), to deal in the Software without restriction, including
# without limitation the rights to use, copy, modify, merge, publish,
# distribute, sublicense, and/or sell copies of the Software, and to
# permit persons to whom the Software is furnished to do so, subject to
# the following conditions:
#
# The above copyright notice and this permission notice shall be
# included in all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
# 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 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)
# which is often displayed on the plotter or map screen of the unit. The first field in this message
# is the Latitude, followed by N or S. The next field is the Longitude followed by E or W. The next
# field is the altitude followed by “F” for feet or “M” for meters. The next field is
# the UTC time of the fix. The next field consists of a status letter of “A” to indicated that
# the data is valid, or “V” to indicate that the data is not valid. The last character field is
# the name of the track, for those units that support named tracks. The last field contains the UTC date
# of the fix. Note that this field is (and its preceding comma) is only produced by the unit when the
# command PMGNCMD,TRACK,2 is given. It is not present when a simple command of PMGNCMD,TRACK is issued.
#NOTE: The Latitude and Longitude Fields are shown as having two decimal
# places. As many additional decimal places may be added as long as the total
# length of the message does not exceed 82 bytes.
# $PMGNTRK,llll.ll,a,yyyyy.yy,a,xxxxx,a,hhmmss.ss,A,c----c,ddmmyy*hh<CR><LF>
require 'csv'
LAT = 1
LAT_HEMI = 2
LON = 3
LON_HEMI = 4
ELE = 5
ELE_UNITS = 6
TIME = 7
INVALID_FLAG = 8
DATE = 10
FEET_TO_METERS = 0.3048
class << self
# Takes the name of a magellan file, converts the contents to GPX, and
# writes the result to gpx_filename.
def convert_to_gpx(magellan_filename, gpx_filename)
segment = Segment.new
CSV.open(magellan_filename, "r").each do |row|
next if(row.size < 10 or row[INVALID_FLAG] == 'V')
lat_deg = row[LAT][0..1]
lat_min = row[LAT][2...-1]
lat_hemi = row[LAT_HEMI]
lat = lat_deg.to_f + (lat_min.to_f / 60.0)
lat = (-lat) if(lat_hemi == 'S')
lon_deg = row[LON][0..2]
lon_min = row[LON][3..-1]
lon_hemi = row[LON_HEMI]
lon = lon_deg.to_f + (lon_min.to_f / 60.0)
lon = (-lon) if(lon_hemi == 'W')
ele = row[ELE]
ele_units = row[ELE_UNITS]
ele = ele.to_f
if(ele_units == 'F')
ele *= FEET_TO_METERS
end
hrs = row[TIME][0..1].to_i
mins = row[TIME][2..3].to_i
secs = row[TIME][4..5].to_i
day = row[DATE][0..1].to_i
mon = row[DATE][2..3].to_i
yr = 2000 + row[DATE][4..5].to_i
time = Time.gm(yr, mon, day, hrs, mins, secs)
#must create point
pt = TrackPoint.new(:lat => lat, :lon => lon, :time => time, :elevation => ele)
segment.append_point(pt)
end
trk = Track.new
trk.append_segment(segment)
gpx_file = GPXFile.new(:tracks => [trk])
gpx_file.write(gpx_filename)
end
# Tests to see if the given file is a magellan NMEA track log.
def is_magellan_file?(filename)
i = 0
File.open(filename, "r") do |f|
f.each do |line|
i += 1
if line =~ /^\$PMGNTRK/
return true
elsif line =~ /<\?xml/
return false
elsif(i > 10)
return false
end
end
end
return false
end
end
end
end

90
lib/gpx/point.rb 100644
View File

@ -0,0 +1,90 @@
#--
# Copyright (c) 2006 Doug Fales
#
# Permission is hereby granted, free of charge, to any person obtaining
# a copy of this software and associated documentation files (the
# "Software"), to deal in the Software without restriction, including
# without limitation the rights to use, copy, modify, merge, publish,
# distribute, sublicense, and/or sell copies of the Software, and to
# permit persons to whom the Software is furnished to do so, subject to
# the following conditions:
#
# The above copyright notice and this permission notice shall be
# included in all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
# 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
# The base class for all points. Trackpoint and Waypoint both descend from this base class.
class Point < Base
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
# addition, you can pass an XML element to this initializer, and the
# relevant info will be parsed out.
def initialize(opts = {:lat => 0.0, :lon => 0.0, :elevation => 0.0, :time => Time.now } )
@gpx_file = opts[:gpx_file]
if (opts[:element])
elem = opts[:element]
@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.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
# Returns the latitude and longitude (in that order), separated by the
# given delimeter. This is useful for passing a point into another API
# (i.e. the Google Maps javascript API).
def lat_lon(delim = ', ')
"#{lat}#{delim}#{lon}"
end
# Returns the longitude and latitude (in that order), separated by the
# given delimeter. This is useful for passing a point into another API
# (i.e. the Google Maps javascript API).
def lon_lat(delim = ', ')
"#{lon}#{delim}#{lat}"
end
# Latitude in radians.
def latr
@latr ||= (@lat * D_TO_R)
end
# Longitude in radians.
def lonr
@lonr ||= (@lon * D_TO_R)
end
# Set the latitude (in degrees).
def lat=(latitude)
@latr = (latitude * D_TO_R)
@lat = latitude
end
# Set the longitude (in degrees).
def lon=(longitude)
@lonr = (longitude * D_TO_R)
@lon = longitude
end
end
end

58
lib/gpx/route.rb 100644
View File

@ -0,0 +1,58 @@
#--
# Copyright (c) 2006 Doug Fales
#
# Permission is hereby granted, free of charge, to any person obtaining
# a copy of this software and associated documentation files (the
# "Software"), to deal in the Software without restriction, including
# without limitation the rights to use, copy, modify, merge, publish,
# distribute, sublicense, and/or sell copies of the Software, and to
# permit persons to whom the Software is furnished to do so, subject to
# the following conditions:
#
# The above copyright notice and this permission notice shall be
# included in all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
# 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
# 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_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.at("name").inner_text
@points = []
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
# Delete points outside of a given area.
def crop(area)
points.delete_if{ |pt| not area.contains? pt }
end
# Delete points within the given area.
def delete_area(area)
points.delete_if{ |pt| area.contains? pt }
end
end
end

214
lib/gpx/segment.rb 100644
View File

@ -0,0 +1,214 @@
#--
# Copyright (c) 2006 Doug Fales
#
# Permission is hereby granted, free of charge, to any person obtaining
# a copy of this software and associated documentation files (the
# "Software"), to deal in the Software without restriction, including
# without limitation the rights to use, copy, modify, merge, publish,
# distribute, sublicense, and/or sell copies of the Software, and to
# permit persons to whom the Software is furnished to do so, subject to
# the following conditions:
#
# The above copyright notice and this permission notice shall be
# included in all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
# 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
# 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
# latest points, distance, and bounds.
class Segment < Base
attr_reader :earliest_point, :latest_point, :bounds, :highest_point, :lowest_point, :distance
attr_accessor :points, :track
# If a XML::Node object is passed-in, this will initialize a new
# Segment based on its contents. Otherwise, a blank Segment is created.
def initialize(opts = {})
@gpx_file = opts[:gpx_file]
@track = opts[:track]
@points = []
@earliest_point = nil
@latest_point = nil
@highest_point = nil
@lowest_point = nil
@distance = 0.0
@bounds = Bounds.new
if(opts[:element])
segment_element = opts[:element]
last_pt = nil
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)
@latest_point = pt if(@latest_point.nil? or pt.time > @latest_point.time)
end
unless pt.elevation.nil?
@lowest_point = pt if(@lowest_point.nil? or pt.elevation < @lowest_point.elevation)
@highest_point = pt if(@highest_point.nil? or pt.elevation > @highest_point.elevation)
end
@bounds.min_lat = pt.lat if pt.lat < @bounds.min_lat
@bounds.min_lon = pt.lon if pt.lon < @bounds.min_lon
@bounds.max_lat = pt.lat if pt.lat > @bounds.max_lat
@bounds.max_lon = pt.lon if pt.lon > @bounds.max_lon
@distance += haversine_distance(last_pt, pt) unless last_pt.nil?
@points << pt
last_pt = pt
end
end
end
end
# Tack on a point to this Segment. All meta-data will be updated.
def append_point(pt)
last_pt = @points[-1]
@earliest_point = pt if(@earliest_point.nil? or pt.time < @earliest_point.time)
@latest_point = pt if(@latest_point.nil? or pt.time > @latest_point.time)
@lowest_point = pt if(@lowest_point.nil? or pt.elevation < @lowest_point.elevation)
@highest_point = pt if(@highest_point.nil? or pt.elevation > @highest_point.elevation)
@bounds.min_lat = pt.lat if pt.lat < @bounds.min_lat
@bounds.min_lon = pt.lon if pt.lon < @bounds.min_lon
@bounds.max_lat = pt.lat if pt.lat > @bounds.max_lat
@bounds.max_lon = pt.lon if pt.lon > @bounds.max_lon
@distance += haversine_distance(last_pt, pt) unless last_pt.nil?
@points << pt
end
# Returns true if the given time is within this Segment.
def contains_time?(time)
(time >= @earliest_point.time and time <= @latest_point.time) rescue false
end
# Finds the closest point in time to the passed-in time argument. Useful
# for matching up time-based objects (photos, video, etc) with a
# geographic location.
def closest_point(time)
find_closest(points, time)
end
# Deletes all points within this Segment that lie outside of the given
# area (which should be a Bounds object).
def crop(area)
delete_if { |pt| not area.contains?(pt) }
end
# Deletes all points in this Segment that lie within the given area.
def delete_area(area)
delete_if{ |pt| area.contains?(pt) }
end
# A handy method that deletes points based on a block that is passed in.
# If the passed-in block returns true when given a point, then that point
# is deleted. For example:
# delete_if{ |pt| area.contains?(pt) }
def delete_if
reset_meta_data
keep_points = []
last_pt = nil
points.each do |pt|
unless yield(pt)
keep_points << pt
update_meta_data(pt, last_pt)
last_pt = pt
end
end
@points = keep_points
end
# Returns true if this Segment has no points.
def empty?
(points.nil? or (points.size == 0))
end
# Prints out a nice summary of this Segment.
def to_s
result = "Track Segment\n"
result << "\tSize: #{points.size} points\n"
result << "\tDistance: #{distance} km\n"
result << "\tEarliest Point: #{earliest_point.time.to_s} \n"
result << "\tLatest Point: #{latest_point.time.to_s} \n"
result << "\tLowest Point: #{lowest_point.elevation} \n"
result << "\tHighest Point: #{highest_point.elevation}\n "
result << "\tBounds: #{bounds.to_s}"
result
end
protected
def find_closest(pts, time)
return pts.first if pts.size == 1
midpoint = pts.size/2
if pts.size == 2
diff_1 = pts[0].time - time
diff_2 = pts[1].time - time
return (diff_1 < diff_2 ? pts[0] : pts[1])
end
if time >= pts[midpoint].time and time <= pts[midpoint+1].time
return pts[midpoint]
elsif(time <= pts[midpoint].time)
return find_closest(pts[0..midpoint], time)
else
return find_closest(pts[(midpoint+1)..-1], time)
end
end
RADIUS = 6371; # earth's mean radius in km
# Calculate the Haversine distance between two points. This is the method
# the library uses to calculate the cumulative distance of GPX files.
def haversine_distance(p1, p2)
d_lat = p2.latr - p1.latr;
d_lon = p2.lonr - p1.lonr;
a = Math.sin(d_lat/2) * Math.sin(d_lat/2) + Math.cos(p1.latr) * Math.cos(p2.latr) * Math.sin(d_lon/2) * Math.sin(d_lon/2);
c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a));
d = RADIUS * c;
return d;
end
# Calculate the plain Pythagorean difference between two points. Not currently used.
def pythagorean_distance(p1, p2)
Math.sqrt((p2.latr - p1.latr)**2 + (p2.lonr - p1.lonr)**2)
end
# Calculates the distance between two points using the Law of Cosines formula. Not currently used.
def law_of_cosines_distance(p1, p2)
(Math.acos(Math.sin(p1.latr)*Math.sin(p2.latr) + Math.cos(p1.latr)*Math.cos(p2.latr)*Math.cos(p2.lonr-p1.lonr)) * RADIUS)
end
def reset_meta_data
@earliest_point = nil
@latest_point = nil
@highest_point = nil
@lowest_point = nil
@distance = 0.0
@bounds = Bounds.new
end
def update_meta_data(pt, last_pt)
unless pt.time.nil?
@earliest_point = pt if(@earliest_point.nil? or pt.time < @earliest_point.time)
@latest_point = pt if(@latest_point.nil? or pt.time > @latest_point.time)
end
unless pt.elevation.nil?
@lowest_point = pt if(@lowest_point.nil? or pt.elevation < @lowest_point.elevation)
@highest_point = pt if(@highest_point.nil? or pt.elevation > @highest_point.elevation)
end
@bounds.add(pt)
@distance += haversine_distance(last_pt, pt) unless last_pt.nil?
end
end
end

136
lib/gpx/track.rb 100644
View File

@ -0,0 +1,136 @@
#--
# Copyright (c) 2006 Doug Fales
#
# Permission is hereby granted, free of charge, to any person obtaining
# a copy of this software and associated documentation files (the
# "Software"), to deal in the Software without restriction, including
# without limitation the rights to use, copy, modify, merge, publish,
# distribute, sublicense, and/or sell copies of the Software, and to
# permit persons to whom the Software is furnished to do so, subject to
# the following conditions:
#
# The above copyright notice and this permission notice shall be
# included in all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
# 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
# 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
# low point, high point, and distance. Of course, each track references an
# array of the segments that copmrise it, but additionally each track holds
# a reference to all of its points as one big array called "points".
class Track < Base
attr_reader :points, :bounds, :lowest_point, :highest_point, :distance
attr_accessor :segments, :name, :gpx_file
# Initialize a track from a XML::Node, or, if no :element option is
# passed, initialize a blank Track object.
def initialize(opts = {})
@gpx_file = opts[:gpx_file]
@segments = []
@points = []
reset_meta_data
if(opts[:element])
trk_element = opts[: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
end
end
end
# Append a segment to this track, updating its meta data along the way.
def append_segment(seg)
update_meta_data(seg)
@segments << seg
@points.concat(seg.points) unless seg.nil?
end
# Returns true if the given time occurs within any of the segments of this track.
def contains_time?(time)
segments.each do |seg|
return true if seg.contains_time?(time)
end
return false
end
# Finds the closest point (to "time") within this track. Useful for
# correlating things like pictures, video, and other events, if you are
# working with a timestamp.
def 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.
# The "area" paremeter is usually a Bounds object.
def crop(area)
reset_meta_data
segments.each do |seg|
seg.crop(area)
update_meta_data(seg) unless seg.empty?
end
segments.delete_if { |seg| seg.empty? }
end
# Deletes all points within a given area and updates the meta data.
def delete_area(area)
reset_meta_data
segments.each do |seg|
seg.delete_area(area)
update_meta_data(seg) unless seg.empty?
end
segments.delete_if { |seg| seg.empty? }
end
# Returns true if this track has no points in it. This should return
# true even when the track has empty segments.
def empty?
(points.nil? or points.size.zero?)
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"
result << "\tSize: #{points.size} points\n"
result << "\tSegments: #{segments.size} \n"
result << "\tDistance: #{distance} km\n"
result << "\tLowest Point: #{lowest_point.elevation} \n"
result << "\tHighest Point: #{highest_point.elevation}\n "
result << "\tBounds: #{bounds.to_s}"
result
end
protected
def update_meta_data(seg)
@lowest_point = seg.lowest_point if(@lowest_point.nil? or seg.lowest_point.elevation < @lowest_point.elevation)
@highest_point = seg.highest_point if(@highest_point.nil? or seg.highest_point.elevation > @highest_point.elevation)
@bounds.add(seg.bounds)
@distance += seg.distance
@points.concat(seg.points)
end
def reset_meta_data
@bounds = Bounds.new
@highest_point = nil
@lowest_point = nil
@distance = 0.0
@points = []
end
end
end

View File

@ -0,0 +1,35 @@
#--
# Copyright (c) 2006 Doug Fales
#
# Permission is hereby granted, free of charge, to any person obtaining
# a copy of this software and associated documentation files (the
# "Software"), to deal in the Software without restriction, including
# without limitation the rights to use, copy, modify, merge, publish,
# distribute, sublicense, and/or sell copies of the Software, and to
# permit persons to whom the Software is furnished to do so, subject to
# the following conditions:
#
# The above copyright notice and this permission notice shall be
# included in all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
# 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
# Basically the same as a point, the TrackPoint class is supposed to
# represent the points that are children of Segment elements. So, the only
# real difference is that TrackPoints hold a reference to their parent
# Segments.
class TrackPoint < Point
attr_accessor :segment
def initialize(opts = {})
super(opts)
@segment = opts[:segment]
end
end
end

View File

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

View File

@ -0,0 +1,74 @@
#--
# Copyright (c) 2006 Doug Fales
#
# Permission is hereby granted, free of charge, to any person obtaining
# a copy of this software and associated documentation files (the
# "Software"), to deal in the Software without restriction, including
# without limitation the rights to use, copy, modify, merge, publish,
# distribute, sublicense, and/or sell copies of the Software, and to
# permit persons to whom the Software is furnished to do so, subject to
# the following conditions:
#
# The above copyright notice and this permission notice shall be
# included in all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
# 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 = %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)
end
# Not implemented
def delete_area(area)
end
# Initializes a waypoint from a XML::Node.
def initialize(opts = {})
if(opts[:element] and opts[:gpx_file])
wpt_elem = opts[:element]
@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
# 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
result
end
end
end

View File

@ -0,0 +1,12 @@
require 'test/unit'
require 'gpx'
class GPX10Test < Test::Unit::TestCase
GPX_FILE = File.join(File.dirname(__FILE__), "gpx_files/gpx10.gpx")
def test_read
# make sure we can read a GPX 1.0 file
@gpx_file = GPX::GPXFile.new(:gpx_file => GPX_FILE)
end
end

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

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,17 @@
<?xml version="1.0" encoding="UTF-8"?>
<gpx version="1.0"
creator="GPSBabel - http://www.gpsbabel.org"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://www.topografix.com/GPX/1/0"
xsi:schemaLocation="http://www.topografix.com/GPX/1/0 http://www.topografix.com/GPX/1/0/gpx.xsd">
<trk>
<name>ACTIVE LOG #74</name>
<number>82</number>
<trkseg>
<trkpt lat="37.378388923" lon="-122.063654875">
<ele>35.706055</ele>
<time>2007-11-23T23:49:43Z</time>
</trkpt>
</trkseg>
</trk>
</gpx>

View File

@ -0,0 +1,306 @@
$PMGNTRK,4001.386,N,10515.295,W,01609,M,010748.87,A,,270506*69
$PMGNTRK,4001.342,N,10515.498,W,01610,M,010839.87,A,,270506*6B
$PMGNTRK,4001.259,N,10515.511,W,01609,M,010857.88,A,,270506*6F
$PMGNTRK,4000.894,N,10515.515,W,01611,M,011030.88,A,,270506*60
$PMGNTRK,4000.879,N,10516.346,W,01622,M,011237.88,A,,270506*65
$PMGNTRK,4000.924,N,10516.351,W,01622,M,011248.87,A,,270506*6D
$PMGNTRK,4000.927,N,10516.452,W,01623,M,011312.89,A,,270506*6B
$PMGNTRK,4000.934,N,10516.454,W,01629,M,011347.89,A,,270506*65
$PMGNTRK,4000.940,N,10516.452,W,01629,M,011449.87,A,,270506*67
$PMGNTRK,4013.479,N,10715.997,W,01634,M,170142.15,A,,280506*67
$PMGNTRK,4013.679,N,10716.238,W,02319,M,170241.14,A,,280506*60
$PMGNTRK,4013.671,N,10716.244,W,02324,M,170309.15,A,,280506*61
$PMGNTRK,4013.676,N,10716.240,W,02315,M,170702.14,A,,280506*6E
$PMGNTRK,4008.847,N,10708.162,W,02313,M,180916.27,A,,280506*66
$PMGNTRK,4008.985,N,10708.319,W,02977,M,180945.29,A,,280506*67
$PMGNTRK,4008.977,N,10708.328,W,02977,M,181304.28,A,,280506*67
$PMGNTRK,4008.968,N,10708.334,W,02979,M,181352.27,A,,280506*66
$PMGNTRK,4008.961,N,10708.321,W,02978,M,181441.27,A,,280506*6F
$PMGNTRK,4008.952,N,10708.305,W,02975,M,181516.27,A,,280506*67
$PMGNTRK,4008.930,N,10708.300,W,02974,M,181558.28,A,,280506*62
$PMGNTRK,4008.928,N,10708.280,W,02973,M,181638.27,A,,280506*6F
$PMGNTRK,4008.925,N,10708.269,W,02974,M,181708.28,A,,280506*6F
$PMGNTRK,4008.926,N,10708.256,W,02975,M,181744.27,A,,280506*66
$PMGNTRK,4008.932,N,10708.213,W,02976,M,181833.27,A,,280506*6E
$PMGNTRK,4008.935,N,10708.199,W,02977,M,181852.28,A,,280506*61
$PMGNTRK,4008.939,N,10708.173,W,02976,M,181922.27,A,,280506*61
$PMGNTRK,4008.942,N,10708.156,W,02977,M,181943.29,A,,280506*62
$PMGNTRK,4008.932,N,10708.139,W,02978,M,182008.29,A,,280506*66
$PMGNTRK,4008.925,N,10708.129,W,02979,M,182025.27,A,,280506*61
$PMGNTRK,4008.918,N,10708.121,W,02981,M,182046.29,A,,280506*6B
$PMGNTRK,4008.927,N,10708.118,W,02978,M,182104.28,A,,280506*6D
$PMGNTRK,4008.939,N,10708.121,W,02981,M,182129.28,A,,280506*61
$PMGNTRK,4008.951,N,10708.125,W,02982,M,182155.28,A,,280506*63
$PMGNTRK,4008.963,N,10708.112,W,02985,M,182226.28,A,,280506*66
$PMGNTRK,4008.966,N,10708.097,W,02985,M,182250.29,A,,280506*6F
$PMGNTRK,4008.965,N,10708.081,W,02989,M,182311.29,A,,280506*63
$PMGNTRK,4008.968,N,10708.063,W,02992,M,182348.28,A,,280506*65
$PMGNTRK,4008.978,N,10708.047,W,02991,M,182417.29,A,,280506*6D
$PMGNTRK,4008.983,N,10708.032,W,02993,M,182446.28,A,,280506*6C
$PMGNTRK,4008.983,N,10708.020,W,02992,M,182515.29,A,,280506*68
$PMGNTRK,4008.982,N,10708.000,W,02991,M,182543.29,A,,280506*6B
$PMGNTRK,4008.990,N,10707.990,W,02993,M,182610.28,A,,280506*61
$PMGNTRK,4008.983,N,10707.977,W,02997,M,182642.29,A,,280506*68
$PMGNTRK,4008.976,N,10707.970,W,02997,M,182702.30,A,,280506*68
$PMGNTRK,4008.977,N,10707.952,W,03000,M,182723.29,A,,280506*64
$PMGNTRK,4008.974,N,10707.937,W,03006,M,182806.30,A,,280506*62
$PMGNTRK,4008.967,N,10707.926,W,03012,M,182925.29,A,,280506*6D
$PMGNTRK,4008.958,N,10707.917,W,03012,M,182957.30,A,,280506*6E
$PMGNTRK,4008.948,N,10707.896,W,03011,M,183030.31,A,,280506*6C
$PMGNTRK,4008.947,N,10707.878,W,03006,M,183102.30,A,,280506*64
$PMGNTRK,4008.939,N,10707.878,W,03003,M,183128.30,A,,280506*60
$PMGNTRK,4008.928,N,10707.878,W,03003,M,183147.30,A,,280506*69
$PMGNTRK,4008.920,N,10707.871,W,03004,M,183217.30,A,,280506*69
$PMGNTRK,4008.910,N,10707.870,W,03000,M,183309.31,A,,280506*60
$PMGNTRK,4008.901,N,10707.869,W,03003,M,183358.30,A,,280506*6E
$PMGNTRK,4008.893,N,10707.862,W,03010,M,183753.32,A,,280506*60
$PMGNTRK,4008.901,N,10707.865,W,03008,M,184254.31,A,,280506*62
$PMGNTRK,4008.910,N,10707.863,W,03007,M,184328.31,A,,280506*61
$PMGNTRK,4008.918,N,10707.868,W,03008,M,184409.31,A,,280506*69
$PMGNTRK,4008.928,N,10707.871,W,03008,M,184441.32,A,,280506*6D
$PMGNTRK,4008.937,N,10707.871,W,03021,M,184504.32,A,,280506*68
$PMGNTRK,4008.941,N,10707.887,W,03020,M,184534.34,A,,280506*64
$PMGNTRK,4008.948,N,10707.902,W,03020,M,184601.33,A,,280506*63
$PMGNTRK,4008.956,N,10707.908,W,03019,M,184628.34,A,,280506*60
$PMGNTRK,4008.971,N,10707.917,W,03021,M,184647.88,A,,280506*6E
$PMGNTRK,4008.973,N,10707.935,W,03014,M,184737.33,A,,280506*6C
$PMGNTRK,4008.976,N,10707.950,W,03014,M,184759.34,A,,280506*65
$PMGNTRK,4008.983,N,10707.957,W,03014,M,184835.32,A,,280506*6B
$PMGNTRK,4008.985,N,10707.968,W,03002,M,184906.33,A,,280506*66
$PMGNTRK,4008.983,N,10707.985,W,02999,M,184927.33,A,,280506*6A
$PMGNTRK,4008.982,N,10707.996,W,02997,M,184945.33,A,,280506*63
$PMGNTRK,4008.986,N,10708.009,W,03008,M,185009.32,A,,280506*68
$PMGNTRK,4008.982,N,10708.025,W,03003,M,185030.32,A,,280506*63
$PMGNTRK,4008.974,N,10708.045,W,02998,M,185102.32,A,,280506*66
$PMGNTRK,4008.968,N,10708.080,W,02991,M,185135.32,A,,280506*6F
$PMGNTRK,4008.970,N,10708.094,W,02992,M,185210.32,A,,280506*64
$PMGNTRK,4008.962,N,10708.120,W,02989,M,185454.32,A,,280506*65
$PMGNTRK,4008.948,N,10708.141,W,02983,M,185535.33,A,,280506*67
$PMGNTRK,4008.939,N,10708.159,W,02981,M,185600.33,A,,280506*6F
$PMGNTRK,4008.934,N,10708.187,W,02981,M,185633.33,A,,280506*61
$PMGNTRK,4008.925,N,10708.266,W,02980,M,185806.33,A,,280506*64
$PMGNTRK,4008.928,N,10708.279,W,02977,M,185824.34,A,,280506*68
$PMGNTRK,4008.926,N,10708.294,W,02975,M,185847.33,A,,280506*65
$PMGNTRK,4008.918,N,10708.302,W,02977,M,185919.33,A,,280506*6E
$PMGNTRK,4008.913,N,10708.312,W,02979,M,185942.33,A,,280506*64
$PMGNTRK,4008.908,N,10708.327,W,02982,M,190007.34,A,,280506*67
$PMGNTRK,4008.906,N,10708.345,W,02986,M,190041.33,A,,280506*6C
$PMGNTRK,4008.890,N,10708.349,W,02990,M,190105.33,A,,280506*68
$PMGNTRK,4008.878,N,10708.349,W,02991,M,190122.34,A,,280506*6D
$PMGNTRK,4008.864,N,10708.351,W,02993,M,190143.34,A,,280506*6C
$PMGNTRK,4008.850,N,10708.353,W,02994,M,190204.34,A,,280506*6E
$PMGNTRK,4008.834,N,10708.354,W,02997,M,190228.33,A,,280506*61
$PMGNTRK,4008.821,N,10708.356,W,02999,M,190248.34,A,,280506*68
$PMGNTRK,4008.803,N,10708.358,W,02998,M,190322.33,A,,280506*6D
$PMGNTRK,4008.791,N,10708.360,W,02997,M,190340.34,A,,280506*6E
$PMGNTRK,4008.778,N,10708.358,W,02996,M,190357.33,A,,280506*62
$PMGNTRK,4008.756,N,10708.354,W,02995,M,190427.34,A,,280506*66
$PMGNTRK,4008.737,N,10708.353,W,02995,M,190451.33,A,,280506*60
$PMGNTRK,4008.722,N,10708.352,W,02994,M,190511.34,A,,280506*66
$PMGNTRK,4008.708,N,10708.349,W,02993,M,190532.34,A,,280506*62
$PMGNTRK,4008.694,N,10708.347,W,02989,M,190554.34,A,,280506*63
$PMGNTRK,4008.678,N,10708.345,W,02986,M,190619.34,A,,280506*66
$PMGNTRK,4008.671,N,10708.347,W,02989,M,190655.33,A,,280506*6D
$PMGNTRK,4008.661,N,10708.341,W,02990,M,191233.37,A,,280506*63
$PMGNTRK,4008.653,N,10708.338,W,02992,M,191309.34,A,,280506*65
$PMGNTRK,4008.646,N,10708.327,W,02989,M,191331.36,A,,280506*6C
$PMGNTRK,4008.632,N,10708.321,W,02984,M,191400.34,A,,280506*63
$PMGNTRK,4008.620,N,10708.316,W,02983,M,191420.36,A,,280506*63
$PMGNTRK,4008.612,N,10708.315,W,02983,M,191441.35,A,,280506*65
$PMGNTRK,4008.614,N,10708.327,W,02985,M,191553.35,A,,280506*66
$PMGNTRK,4008.625,N,10708.332,W,02987,M,191618.37,A,,280506*6C
$PMGNTRK,4008.636,N,10708.334,W,02991,M,191704.36,A,,280506*62
$PMGNTRK,4008.649,N,10708.337,W,02994,M,191733.35,A,,280506*6B
$PMGNTRK,4008.666,N,10708.341,W,02994,M,191757.35,A,,280506*65
$PMGNTRK,4008.687,N,10708.344,W,02993,M,191824.36,A,,280506*60
$PMGNTRK,4008.699,N,10708.345,W,02994,M,191840.37,A,,280506*6A
$PMGNTRK,4008.718,N,10708.351,W,02996,M,191907.37,A,,280506*67
$PMGNTRK,4008.740,N,10708.352,W,02999,M,191937.37,A,,280506*65
$PMGNTRK,4008.755,N,10708.354,W,03000,M,191958.36,A,,280506*67
$PMGNTRK,4008.769,N,10708.358,W,03004,M,192017.37,A,,280506*60
$PMGNTRK,4008.800,N,10708.360,W,03006,M,192124.37,A,,280506*68
$PMGNTRK,4008.814,N,10708.356,W,03006,M,192141.36,A,,280506*6A
$PMGNTRK,4008.831,N,10708.354,W,03005,M,192204.37,A,,280506*6F
$PMGNTRK,4008.846,N,10708.353,W,03004,M,192225.36,A,,280506*6B
$PMGNTRK,4008.858,N,10708.351,W,03005,M,192241.36,A,,280506*65
$PMGNTRK,4008.874,N,10708.349,W,03005,M,192304.38,A,,280506*6C
$PMGNTRK,4008.887,N,10708.348,W,03003,M,192320.37,A,,280506*6E
$PMGNTRK,4008.902,N,10708.349,W,03003,M,192339.36,A,,280506*6A
$PMGNTRK,4008.917,N,10708.347,W,03002,M,192357.37,A,,280506*68
$PMGNTRK,4008.932,N,10708.345,W,03002,M,192417.36,A,,280506*6F
$PMGNTRK,4008.950,N,10708.339,W,03001,M,192441.36,A,,280506*60
$PMGNTRK,4008.968,N,10708.332,W,02999,M,192506.36,A,,280506*6B
$PMGNTRK,4008.978,N,10708.327,W,02995,M,192531.37,A,,280506*67
$PMGNTRK,4008.984,N,10708.321,W,02990,M,192647.36,A,,280506*64
$PMGNTRK,4010.089,N,10705.151,W,02982,M,200016.76,A,,280506*6C
$PMGNTRK,4010.093,N,10705.143,W,02982,M,200033.77,A,,280506*62
$PMGNTRK,4010.101,N,10705.133,W,02982,M,200057.29,A,,280506*66
$PMGNTRK,4010.102,N,10705.122,W,02982,M,200114.78,A,,280506*67
$PMGNTRK,4010.103,N,10705.108,W,02982,M,200133.29,A,,280506*6F
$PMGNTRK,4010.111,N,10705.102,W,02973,M,200157.77,A,,280506*61
$PMGNTRK,4010.127,N,10705.100,W,02971,M,200209.77,A,,280506*6C
$PMGNTRK,4010.154,N,10705.099,W,02927,M,200227.33,A,,280506*66
$PMGNTRK,4010.159,N,10705.089,W,02928,M,200246.76,A,,280506*63
$PMGNTRK,4010.162,N,10705.079,W,02931,M,200330.76,A,,280506*6C
$PMGNTRK,4010.155,N,10705.080,W,02930,M,200440.77,A,,280506*6E
$PMGNTRK,4010.147,N,10705.086,W,02929,M,200502.77,A,,280506*64
$PMGNTRK,4010.148,N,10705.101,W,02933,M,200539.76,A,,280506*67
$PMGNTRK,4010.140,N,10705.122,W,02936,M,200611.78,A,,280506*6C
$PMGNTRK,4010.131,N,10705.119,W,02935,M,200636.77,A,,280506*6B
$PMGNTRK,4010.120,N,10705.114,W,02933,M,200658.78,A,,280506*67
$PMGNTRK,4010.113,N,10705.104,W,02938,M,200712.78,A,,280506*62
$PMGNTRK,4010.111,N,10705.091,W,02934,M,200731.78,A,,280506*60
$PMGNTRK,4010.111,N,10705.073,W,02925,M,200756.78,A,,280506*6D
$PMGNTRK,4010.114,N,10705.059,W,02913,M,200816.78,A,,280506*6E
$PMGNTRK,4010.112,N,10705.047,W,02910,M,200834.77,A,,280506*6B
$PMGNTRK,4010.111,N,10705.033,W,02906,M,200854.77,A,,280506*6A
$PMGNTRK,4010.115,N,10705.016,W,02901,M,200931.77,A,,280506*6C
$PMGNTRK,4010.120,N,10705.008,W,02904,M,201011.77,A,,280506*6A
$PMGNTRK,4010.129,N,10704.997,W,02901,M,201041.78,A,,280506*62
$PMGNTRK,4010.139,N,10704.991,W,02902,M,201113.78,A,,280506*60
$PMGNTRK,4010.149,N,10704.978,W,02893,M,201141.77,A,,280506*61
$PMGNTRK,4010.155,N,10704.970,W,02891,M,201201.77,A,,280506*61
$PMGNTRK,4010.166,N,10704.961,W,02888,M,201227.77,A,,280506*6D
$PMGNTRK,4010.176,N,10704.954,W,02891,M,201249.78,A,,280506*65
$PMGNTRK,4010.184,N,10704.950,W,02893,M,201323.77,A,,280506*6C
$PMGNTRK,4010.194,N,10704.954,W,02885,M,201417.79,A,,280506*60
$PMGNTRK,4010.206,N,10704.948,W,02883,M,201503.78,A,,280506*66
$PMGNTRK,4010.212,N,10704.935,W,02875,M,201525.78,A,,280506*64
$PMGNTRK,4010.220,N,10704.928,W,02871,M,201601.79,A,,280506*69
$PMGNTRK,4010.227,N,10704.907,W,02866,M,201642.77,A,,280506*6C
$PMGNTRK,4010.243,N,10704.898,W,02866,M,201707.79,A,,280506*67
$PMGNTRK,4010.255,N,10704.892,W,02864,M,201734.78,A,,280506*69
$PMGNTRK,4010.269,N,10704.885,W,02858,M,201804.77,A,,280506*6C
$PMGNTRK,4010.275,N,10704.875,W,02852,M,201821.78,A,,280506*6C
$PMGNTRK,4010.283,N,10704.862,W,02847,M,201844.78,A,,280506*64
$PMGNTRK,4010.294,N,10704.854,W,02846,M,201901.78,A,,280506*66
$PMGNTRK,4010.312,N,10704.838,W,02846,M,201944.78,A,,280506*62
$PMGNTRK,4010.320,N,10704.831,W,02844,M,202003.77,A,,280506*6E
$PMGNTRK,4010.338,N,10704.819,W,02842,M,202040.78,A,,280506*63
$PMGNTRK,4010.347,N,10704.813,W,02840,M,202058.78,A,,280506*6A
$PMGNTRK,4010.356,N,10704.813,W,02837,M,202128.78,A,,280506*6C
$PMGNTRK,4010.364,N,10704.812,W,02842,M,202316.78,A,,280506*61
$PMGNTRK,4010.377,N,10704.806,W,02843,M,202337.78,A,,280506*64
$PMGNTRK,4010.391,N,10704.800,W,02842,M,202404.80,A,,280506*6B
$PMGNTRK,4010.401,N,10704.795,W,02840,M,202422.79,A,,280506*66
$PMGNTRK,4010.412,N,10704.785,W,02836,M,202446.79,A,,280506*66
$PMGNTRK,4010.427,N,10704.782,W,02838,M,202514.79,A,,280506*6F
$PMGNTRK,4010.439,N,10704.782,W,02836,M,202535.79,A,,280506*6D
$PMGNTRK,4010.456,N,10704.780,W,02836,M,202602.78,A,,280506*60
$PMGNTRK,4010.474,N,10704.799,W,02832,M,202640.78,A,,280506*6A
$PMGNTRK,4010.484,N,10704.811,W,02833,M,202700.79,A,,280506*6F
$PMGNTRK,4010.489,N,10704.822,W,02829,M,202715.80,A,,280506*6B
$PMGNTRK,4010.498,N,10704.844,W,02823,M,202747.79,A,,280506*60
$PMGNTRK,4010.518,N,10704.868,W,02827,M,202823.79,A,,280506*6E
$PMGNTRK,4010.524,N,10704.879,W,02831,M,202838.80,A,,280506*6A
$PMGNTRK,4010.527,N,10704.910,W,02845,M,202913.80,A,,280506*6C
$PMGNTRK,4010.523,N,10704.921,W,02850,M,202938.78,A,,280506*60
$PMGNTRK,4010.519,N,10704.936,W,02852,M,203012.80,A,,280506*6A
$PMGNTRK,4010.517,N,10704.948,W,02856,M,203027.79,A,,280506*69
$PMGNTRK,4010.518,N,10704.967,W,02858,M,203058.81,A,,280506*6A
$PMGNTRK,4010.522,N,10704.978,W,02861,M,203114.79,A,,280506*69
$PMGNTRK,4010.533,N,10704.997,W,02870,M,203308.80,A,,280506*61
$PMGNTRK,4010.540,N,10705.008,W,02869,M,203323.81,A,,280506*6B
$PMGNTRK,4010.554,N,10705.022,W,02871,M,203347.79,A,,280506*6A
$PMGNTRK,4010.567,N,10705.026,W,02871,M,203404.81,A,,280506*69
$PMGNTRK,4010.581,N,10705.028,W,02874,M,203421.80,A,,280506*6C
$PMGNTRK,4010.591,N,10705.035,W,02876,M,203439.80,A,,280506*6A
$PMGNTRK,4010.608,N,10705.049,W,02880,M,203507.80,A,,280506*67
$PMGNTRK,4010.617,N,10705.053,W,02878,M,203521.80,A,,280506*61
$PMGNTRK,4010.634,N,10705.064,W,02875,M,203549.80,A,,280506*67
$PMGNTRK,4010.640,N,10705.070,W,02875,M,203633.80,A,,280506*6F
$PMGNTRK,4010.648,N,10705.065,W,02873,M,203701.79,A,,280506*63
$PMGNTRK,4010.636,N,10705.065,W,02874,M,203723.81,A,,280506*6A
$PMGNTRK,4010.628,N,10705.056,W,02875,M,203740.80,A,,280506*60
$PMGNTRK,4010.627,N,10705.038,W,02876,M,203756.80,A,,280506*63
$PMGNTRK,4010.634,N,10705.022,W,02878,M,203815.80,A,,280506*6C
$PMGNTRK,4010.644,N,10705.005,W,02878,M,203835.80,A,,280506*6C
$PMGNTRK,4010.654,N,10704.981,W,02883,M,203901.80,A,,280506*6B
$PMGNTRK,4010.664,N,10704.959,W,02889,M,203949.81,A,,280506*6A
$PMGNTRK,4010.672,N,10704.950,W,02885,M,204010.79,A,,280506*6D
$PMGNTRK,4010.686,N,10704.932,W,02885,M,204040.81,A,,280506*60
$PMGNTRK,4010.699,N,10704.921,W,02887,M,204102.81,A,,280506*69
$PMGNTRK,4010.706,N,10704.905,W,02889,M,204123.81,A,,280506*65
$PMGNTRK,4010.707,N,10704.893,W,02887,M,204137.79,A,,280506*66
$PMGNTRK,4010.701,N,10704.881,W,02886,M,204203.81,A,,280506*61
$PMGNTRK,4010.693,N,10704.876,W,02886,M,204228.80,A,,280506*6B
$PMGNTRK,4010.686,N,10704.869,W,02873,M,204303.81,A,,280506*62
$PMGNTRK,4010.679,N,10704.857,W,02868,M,204348.81,A,,280506*6A
$PMGNTRK,4010.669,N,10704.848,W,02867,M,204416.81,A,,280506*66
$PMGNTRK,4010.664,N,10704.840,W,02871,M,204431.80,A,,280506*60
$PMGNTRK,4010.659,N,10704.831,W,02861,M,204452.82,A,,280506*6E
$PMGNTRK,4010.651,N,10704.813,W,02863,M,204519.82,A,,280506*6A
$PMGNTRK,4010.636,N,10704.815,W,02853,M,204612.81,A,,280506*65
$PMGNTRK,4010.623,N,10704.817,W,02848,M,204636.40,A,,280506*62
$PMGNTRK,4010.608,N,10704.817,W,02846,M,204659.83,A,,280506*63
$PMGNTRK,4010.599,N,10704.822,W,02845,M,204715.82,A,,280506*65
$PMGNTRK,4010.587,N,10704.831,W,02844,M,204741.81,A,,280506*6B
$PMGNTRK,4010.577,N,10704.847,W,02848,M,204811.82,A,,280506*60
$PMGNTRK,4010.570,N,10704.858,W,02849,M,204830.81,A,,280506*68
$PMGNTRK,4010.559,N,10704.871,W,02851,M,204857.82,A,,280506*63
$PMGNTRK,4010.552,N,10704.881,W,02850,M,204914.82,A,,280506*60
$PMGNTRK,4010.542,N,10704.885,W,02853,M,204932.82,A,,280506*62
$PMGNTRK,4010.535,N,10704.875,W,02855,M,205010.82,A,,280506*63
$PMGNTRK,4010.527,N,10704.865,W,02854,M,205027.82,A,,280506*64
$PMGNTRK,4010.509,N,10704.869,W,02853,M,205036.80,A,,280506*61
$PMGNTRK,4010.507,N,10704.852,W,02852,M,205135.82,A,,280506*66
$PMGNTRK,4010.503,N,10704.835,W,02855,M,205155.82,A,,280506*62
$PMGNTRK,4010.494,N,10704.815,W,02859,M,205222.81,A,,280506*63
$PMGNTRK,4010.482,N,10704.794,W,02848,M,205251.82,A,,280506*65
$PMGNTRK,4010.476,N,10704.785,W,02849,M,205305.82,A,,280506*6F
$PMGNTRK,4010.465,N,10704.778,W,02846,M,205322.82,A,,280506*65
$PMGNTRK,4010.454,N,10704.778,W,02845,M,205346.82,A,,280506*66
$PMGNTRK,4010.441,N,10704.778,W,02845,M,205412.81,A,,280506*67
$PMGNTRK,4010.427,N,10704.780,W,02846,M,205431.81,A,,280506*62
$PMGNTRK,4010.415,N,10704.789,W,02847,M,205453.82,A,,280506*6C
$PMGNTRK,4010.399,N,10704.801,W,02842,M,205528.82,A,,280506*68
$PMGNTRK,4010.390,N,10704.804,W,02842,M,205542.82,A,,280506*68
$PMGNTRK,4010.379,N,10704.811,W,02837,M,205601.83,A,,280506*6C
$PMGNTRK,4010.370,N,10704.809,W,02838,M,205631.82,A,,280506*61
$PMGNTRK,4010.358,N,10704.809,W,02842,M,205737.83,A,,280506*60
$PMGNTRK,4010.342,N,10704.817,W,02845,M,205806.83,A,,280506*6E
$PMGNTRK,4010.329,N,10704.825,W,02847,M,205829.37,A,,280506*62
$PMGNTRK,4010.318,N,10704.832,W,02847,M,205854.84,A,,280506*64
$PMGNTRK,4010.307,N,10704.842,W,02849,M,205915.84,A,,280506*67
$PMGNTRK,4010.297,N,10704.850,W,02850,M,205934.83,A,,280506*60
$PMGNTRK,4010.288,N,10704.860,W,02854,M,205954.83,A,,280506*6F
$PMGNTRK,4010.276,N,10704.879,W,02860,M,210026.83,A,,280506*69
$PMGNTRK,4010.264,N,10704.888,W,02864,M,210049.83,A,,280506*69
$PMGNTRK,4010.248,N,10704.892,W,02869,M,210115.83,A,,280506*69
$PMGNTRK,4010.237,N,10704.899,W,02873,M,210137.83,A,,280506*61
$PMGNTRK,4010.226,N,10704.912,W,02875,M,210203.82,A,,280506*60
$PMGNTRK,4010.220,N,10704.923,W,02876,M,210220.82,A,,280506*66
$PMGNTRK,4010.213,N,10704.930,W,02879,M,210238.83,A,,280506*63
$PMGNTRK,4010.197,N,10704.935,W,02883,M,210309.82,A,,280506*6E
$PMGNTRK,4010.189,N,10704.941,W,02879,M,210334.38,A,,280506*68
$PMGNTRK,4010.178,N,10704.944,W,02890,M,210404.83,A,,280506*60
$PMGNTRK,4010.162,N,10704.951,W,02890,M,210417.82,A,,280506*6C
$PMGNTRK,4010.160,N,10704.969,W,02935,M,210458.83,A,,280506*61
$PMGNTRK,4010.153,N,10704.975,W,02908,M,210518.40,A,,280506*68
$PMGNTRK,4010.146,N,10704.972,W,02909,M,210603.82,A,,280506*6D
$PMGNTRK,4010.134,N,10704.982,W,02922,M,210612.83,A,,280506*6F
$PMGNTRK,4010.120,N,10704.990,W,02927,M,210631.36,A,,280506*63
$PMGNTRK,4010.114,N,10705.002,W,02926,M,210657.83,A,,280506*68
$PMGNTRK,4010.118,N,10705.015,W,02926,M,210713.82,A,,280506*62
$PMGNTRK,4010.112,N,10705.038,W,02922,M,210737.36,A,,280506*6A
$PMGNTRK,4010.114,N,10705.050,W,02916,M,210752.84,A,,280506*6F
$PMGNTRK,4010.118,N,10705.078,W,02922,M,210828.83,A,,280506*6B
$PMGNTRK,4010.111,N,10705.093,W,02926,M,210852.84,A,,280506*69
$PMGNTRK,4010.115,N,10705.105,W,02926,M,210909.84,A,,280506*6C
$PMGNTRK,4010.113,N,10705.115,W,02927,M,210925.84,A,,280506*64
$PMGNTRK,4010.111,N,10705.126,W,02933,M,210941.84,A,,280506*61
$PMGNTRK,4010.114,N,10705.138,W,02943,M,211005.84,A,,280506*64
$PMGNTRK,4010.118,N,10705.148,W,02939,M,211023.85,A,,280506*67
$PMGNTRK,4010.119,N,10705.164,W,02940,M,211049.84,A,,280506*6B
$PMGNTRK,4010.109,N,10705.183,W,02946,M,211132.84,A,,280506*68
$PMGNTRK,4010.098,N,10705.183,W,02946,M,211141.37,A,,280506*6D
$PMGNTRK,4010.088,N,10705.190,W,02943,M,211201.85,A,,280506*65
$PMGNTRK,4010.085,N,10705.203,W,02944,M,211220.85,A,,280506*65
$PMGNTRK,4010.079,N,10705.213,W,02944,M,211236.46,A,,280506*6F
$PMGNTRK,4010.089,N,10705.232,W,02974,M,211251.84,A,,280506*6F
$PMGNTRK,4010.095,N,10705.248,W,02974,M,211308.84,A,,280506*62
$PMGNTRK,4010.102,N,10705.260,W,02976,M,211335.37,A,,280506*63
$PMGNTRK,4010.109,N,10705.271,W,02976,M,211346.85,A,,280506*65
$PMGNTRK,4010.099,N,10705.278,W,02979,M,211410.86,A,,280506*6C
$PMGNTRK,4010.094,N,10705.283,W,02984,M,211552.85,A,,280506*63
$PMGNCMD,END*3D

View File

@ -0,0 +1,770 @@
<?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[rabbit_valley.gpx]]></name>
<time>2006-04-08T16:43:40Z</time>
<bounds min_lat="39.173834" min_lon="-109.016604" max_lat="39.188747" max_lon="-108.999546"/>
</metadata>
<extensions/>
<trk>
<name><![CDATA[RABBIT U]]></name>
<trkseg>
<trkpt lat="39.185185" lon="-109.016433">
<time>2006-04-07T18:12:05Z</time>
<ele>1334.447</ele>
</trkpt>
<trkpt lat="39.185143" lon="-109.016433">
<time>2006-04-07T18:12:07Z</time>
<ele>1338.292</ele>
</trkpt>
<trkpt lat="39.185143" lon="-109.016433">
<time>2006-04-07T18:12:09Z</time>
<ele>1344.061</ele>
</trkpt>
<trkpt lat="39.185143" lon="-109.016433">
<time>2006-04-07T18:12:19Z</time>
<ele>1364.729</ele>
</trkpt>
<trkpt lat="39.185121" lon="-109.016433">
<time>2006-04-07T18:12:23Z</time>
<ele>1371.938</ele>
</trkpt>
<trkpt lat="39.185121" lon="-109.016433">
<time>2006-04-07T18:12:25Z</time>
<ele>1375.303</ele>
</trkpt>
<trkpt lat="39.185121" lon="-109.016433">
<time>2006-04-07T18:12:37Z</time>
<ele>1389.723</ele>
</trkpt>
<trkpt lat="39.185121" lon="-109.016433">
<time>2006-04-07T18:12:45Z</time>
<ele>1396.452</ele>
</trkpt>
<trkpt lat="39.185143" lon="-109.016433">
<time>2006-04-07T18:12:52Z</time>
<ele>1400.778</ele>
</trkpt>
<trkpt lat="39.185143" lon="-109.016433">
<time>2006-04-07T18:13:00Z</time>
<ele>1404.143</ele>
</trkpt>
<trkpt lat="39.185143" lon="-109.016433">
<time>2006-04-07T18:13:17Z</time>
<ele>1410.391</ele>
</trkpt>
<trkpt lat="39.185143" lon="-109.016433">
<time>2006-04-07T18:13:30Z</time>
<ele>1413.756</ele>
</trkpt>
<trkpt lat="39.185164" lon="-109.016454">
<time>2006-04-07T18:14:25Z</time>
<ele>1414.237</ele>
</trkpt>
<trkpt lat="39.185271" lon="-109.016476">
<time>2006-04-07T18:14:29Z</time>
<ele>1415.679</ele>
</trkpt>
<trkpt lat="39.185207" lon="-109.016497">
<time>2006-04-07T18:19:14Z</time>
<ele>1415.679</ele>
</trkpt>
<trkpt lat="39.185228" lon="-109.016476">
<time>2006-04-07T18:19:29Z</time>
<ele>1415.679</ele>
</trkpt>
<trkpt lat="39.185271" lon="-109.016519">
<time>2006-04-07T18:19:51Z</time>
<ele>1415.198</ele>
</trkpt>
<trkpt lat="39.185228" lon="-109.016562">
<time>2006-04-07T18:20:13Z</time>
<ele>1414.717</ele>
</trkpt>
<trkpt lat="39.185207" lon="-109.016476">
<time>2006-04-07T18:20:57Z</time>
<ele>1415.679</ele>
</trkpt>
<trkpt lat="39.185185" lon="-109.016562">
<time>2006-04-07T18:21:14Z</time>
<ele>1415.679</ele>
</trkpt>
<trkpt lat="39.185164" lon="-109.016562">
<time>2006-04-07T18:21:17Z</time>
<ele>1415.679</ele>
</trkpt>
<trkpt lat="39.184735" lon="-109.016411">
<time>2006-04-07T18:21:42Z</time>
<ele>1415.198</ele>
</trkpt>
<trkpt lat="39.184864" lon="-109.016368">
<time>2006-04-07T18:21:52Z</time>
<ele>1415.679</ele>
</trkpt>
<trkpt lat="39.184928" lon="-109.016283">
<time>2006-04-07T18:21:57Z</time>
<ele>1415.198</ele>
</trkpt>
<trkpt lat="39.185121" lon="-109.015746">
<time>2006-04-07T18:22:14Z</time>
<ele>1416.159</ele>
</trkpt>
<trkpt lat="39.185357" lon="-109.015231">
<time>2006-04-07T18:22:31Z</time>
<ele>1417.601</ele>
</trkpt>
<trkpt lat="39.185572" lon="-109.014802">
<time>2006-04-07T18:22:50Z</time>
<ele>1417.601</ele>
</trkpt>
<trkpt lat="39.185593" lon="-109.014802">
<time>2006-04-07T18:22:53Z</time>
<ele>1417.601</ele>
</trkpt>
<trkpt lat="39.185143" lon="-109.015725">
<time>2006-04-07T18:23:18Z</time>
<ele>1417.601</ele>
</trkpt>
<trkpt lat="39.184928" lon="-109.016497">
<time>2006-04-07T18:23:32Z</time>
<ele>1415.679</ele>
</trkpt>
<trkpt lat="39.185164" lon="-109.016540">
<time>2006-04-07T18:23:42Z</time>
<ele>1416.159</ele>
</trkpt>
<trkpt lat="39.185164" lon="-109.016540">
<time>2006-04-07T18:23:52Z</time>
<ele>1415.679</ele>
</trkpt>
<trkpt lat="39.185185" lon="-109.016540">
<time>2006-04-07T18:24:09Z</time>
<ele>1413.756</ele>
</trkpt>
<trkpt lat="39.185164" lon="-109.016540">
<time>2006-04-07T18:25:59Z</time>
<ele>1414.237</ele>
</trkpt>
<trkpt lat="39.185185" lon="-109.016497">
<time>2006-04-07T18:26:12Z</time>
<ele>1414.237</ele>
</trkpt>
<trkpt lat="39.184992" lon="-109.016497">
<time>2006-04-07T18:26:22Z</time>
<ele>1414.717</ele>
</trkpt>
<trkpt lat="39.184949" lon="-109.016283">
<time>2006-04-07T18:26:29Z</time>
<ele>1415.198</ele>
</trkpt>
<trkpt lat="39.184992" lon="-109.016197">
<time>2006-04-07T18:26:31Z</time>
<ele>1414.237</ele>
</trkpt>
<trkpt lat="39.185207" lon="-109.015596">
<time>2006-04-07T18:26:43Z</time>
<ele>1418.082</ele>
</trkpt>
<trkpt lat="39.185593" lon="-109.014781">
<time>2006-04-07T18:27:02Z</time>
<ele>1418.562</ele>
</trkpt>
<trkpt lat="39.185636" lon="-109.014652">
<time>2006-04-07T18:27:10Z</time>
<ele>1417.121</ele>
</trkpt>
<trkpt lat="39.185593" lon="-109.014587">
<time>2006-04-07T18:27:18Z</time>
<ele>1416.64</ele>
</trkpt>
<trkpt lat="39.185379" lon="-109.014523">
<time>2006-04-07T18:27:29Z</time>
<ele>1419.043</ele>
</trkpt>
<trkpt lat="39.185078" lon="-109.014480">
<time>2006-04-07T18:27:46Z</time>
<ele>1419.043</ele>
</trkpt>
<trkpt lat="39.184628" lon="-109.014266">
<time>2006-04-07T18:28:17Z</time>
<ele>1416.159</ele>
</trkpt>
<trkpt lat="39.184155" lon="-109.013836">
<time>2006-04-07T18:28:46Z</time>
<ele>1415.198</ele>
</trkpt>
<trkpt lat="39.183791" lon="-109.013665">
<time>2006-04-07T18:29:04Z</time>
<ele>1414.717</ele>
</trkpt>
<trkpt lat="39.183018" lon="-109.013150">
<time>2006-04-07T18:29:31Z</time>
<ele>1411.353</ele>
</trkpt>
<trkpt lat="39.182611" lon="-109.012806">
<time>2006-04-07T18:29:48Z</time>
<ele>1409.911</ele>
</trkpt>
<trkpt lat="39.182053" lon="-109.012463">
<time>2006-04-07T18:30:08Z</time>
<ele>1409.43</ele>
</trkpt>
<trkpt lat="39.181623" lon="-109.012463">
<time>2006-04-07T18:31:56Z</time>
<ele>1408.469</ele>
</trkpt>
<trkpt lat="39.181173" lon="-109.012377">
<time>2006-04-07T18:32:12Z</time>
<ele>1407.027</ele>
</trkpt>
<trkpt lat="39.180572" lon="-109.012098">
<time>2006-04-07T18:32:41Z</time>
<ele>1403.662</ele>
</trkpt>
<trkpt lat="39.180572" lon="-109.012098">
<time>2006-04-07T18:33:22Z</time>
<ele>1402.701</ele>
</trkpt>
<trkpt lat="39.180980" lon="-109.012270">
<time>2006-04-07T18:33:52Z</time>
<ele>1406.065</ele>
</trkpt>
<trkpt lat="39.181516" lon="-109.012442">
<time>2006-04-07T18:34:11Z</time>
<ele>1407.508</ele>
</trkpt>
<trkpt lat="39.181795" lon="-109.012420">
<time>2006-04-07T18:34:23Z</time>
<ele>1408.469</ele>
</trkpt>
<trkpt lat="39.182010" lon="-109.012098">
<time>2006-04-07T18:34:39Z</time>
<ele>1408.469</ele>
</trkpt>
<trkpt lat="39.182417" lon="-109.011734">
<time>2006-04-07T18:34:57Z</time>
<ele>1409.43</ele>
</trkpt>
<trkpt lat="39.182675" lon="-109.011455">
<time>2006-04-07T18:35:10Z</time>
<ele>1409.43</ele>
</trkpt>
<trkpt lat="39.183040" lon="-109.011133">
<time>2006-04-07T18:35:28Z</time>
<ele>1411.353</ele>
</trkpt>
<trkpt lat="39.183340" lon="-109.010768">
<time>2006-04-07T18:35:44Z</time>
<ele>1411.833</ele>
</trkpt>
<trkpt lat="39.183555" lon="-109.010468">
<time>2006-04-07T18:36:00Z</time>
<ele>1412.314</ele>
</trkpt>
<trkpt lat="39.183576" lon="-109.010403">
<time>2006-04-07T18:36:14Z</time>
<ele>1411.833</ele>
</trkpt>
<trkpt lat="39.183490" lon="-109.010253">
<time>2006-04-07T18:36:56Z</time>
<ele>1412.314</ele>
</trkpt>
<trkpt lat="39.183040" lon="-109.010017">
<time>2006-04-07T18:37:11Z</time>
<ele>1409.911</ele>
</trkpt>
<trkpt lat="39.182954" lon="-109.009759">
<time>2006-04-07T18:37:21Z</time>
<ele>1410.391</ele>
</trkpt>
<trkpt lat="39.183104" lon="-109.009287">
<time>2006-04-07T18:37:34Z</time>
<ele>1409.911</ele>
</trkpt>
<trkpt lat="39.183168" lon="-109.008901">
<time>2006-04-07T18:37:45Z</time>
<ele>1408.469</ele>
</trkpt>
<trkpt lat="39.183104" lon="-109.008794">
<time>2006-04-07T18:37:50Z</time>
<ele>1407.027</ele>
</trkpt>
<trkpt lat="39.182847" lon="-109.008622">
<time>2006-04-07T18:38:03Z</time>
<ele>1408.469</ele>
</trkpt>
<trkpt lat="39.182568" lon="-109.008386">
<time>2006-04-07T18:38:15Z</time>
<ele>1411.353</ele>
</trkpt>
<trkpt lat="39.182396" lon="-109.008107">
<time>2006-04-07T18:38:30Z</time>
<ele>1411.353</ele>
</trkpt>
<trkpt lat="39.182181" lon="-109.007485">
<time>2006-04-07T18:38:47Z</time>
<ele>1414.237</ele>
</trkpt>
<trkpt lat="39.181924" lon="-109.006777">
<time>2006-04-07T18:39:05Z</time>
<ele>1416.159</ele>
</trkpt>
<trkpt lat="39.181602" lon="-109.005575">
<time>2006-04-07T18:39:39Z</time>
<ele>1416.64</ele>
</trkpt>
<trkpt lat="39.181881" lon="-109.003923">
<time>2006-04-07T18:40:22Z</time>
<ele>1419.524</ele>
</trkpt>
<trkpt lat="39.181924" lon="-109.003301">
<time>2006-04-07T18:40:36Z</time>
<ele>1420.485</ele>
</trkpt>
<trkpt lat="39.181709" lon="-109.002807">
<time>2006-04-07T18:40:50Z</time>
<ele>1421.447</ele>
</trkpt>
<trkpt lat="39.181387" lon="-109.002571">
<time>2006-04-07T18:41:02Z</time>
<ele>1424.331</ele>
</trkpt>
<trkpt lat="39.180851" lon="-109.002357">
<time>2006-04-07T18:41:18Z</time>
<ele>1425.772</ele>
</trkpt>
<trkpt lat="39.180465" lon="-109.002035">
<time>2006-04-07T18:41:33Z</time>
<ele>1427.695</ele>
</trkpt>
<trkpt lat="39.180379" lon="-109.001606">
<time>2006-04-07T18:41:46Z</time>
<ele>1428.656</ele>
</trkpt>
<trkpt lat="39.180207" lon="-109.001198">
<time>2006-04-07T18:41:59Z</time>
<ele>1430.579</ele>
</trkpt>
<trkpt lat="39.180057" lon="-109.001133">
<time>2006-04-07T18:42:59Z</time>
<ele>1429.137</ele>
</trkpt>
<trkpt lat="39.180100" lon="-109.001112">
<time>2006-04-07T18:44:04Z</time>
<ele>1429.618</ele>
</trkpt>
<trkpt lat="39.180100" lon="-109.001133">
<time>2006-04-07T18:44:21Z</time>
<ele>1428.176</ele>
</trkpt>
<trkpt lat="39.178984" lon="-109.001412">
<time>2006-04-07T18:45:42Z</time>
<ele>1433.463</ele>
</trkpt>
<trkpt lat="39.178491" lon="-109.001348">
<time>2006-04-07T18:45:58Z</time>
<ele>1433.944</ele>
</trkpt>
<trkpt lat="39.177632" lon="-109.001391">
<time>2006-04-07T18:46:26Z</time>
<ele>1438.27</ele>
</trkpt>
<trkpt lat="39.177010" lon="-109.001498">
<time>2006-04-07T18:47:21Z</time>
<ele>1445.479</ele>
</trkpt>
<trkpt lat="39.176774" lon="-109.001584">
<time>2006-04-07T18:47:53Z</time>
<ele>1451.728</ele>
</trkpt>
<trkpt lat="39.176452" lon="-109.001520">
<time>2006-04-07T18:48:29Z</time>
<ele>1454.132</ele>
</trkpt>
<trkpt lat="39.176345" lon="-109.001584">
<time>2006-04-07T18:48:46Z</time>
<ele>1455.573</ele>
</trkpt>
<trkpt lat="39.176259" lon="-109.001820">
<time>2006-04-07T18:49:08Z</time>
<ele>1457.015</ele>
</trkpt>
<trkpt lat="39.176152" lon="-109.001949">
<time>2006-04-07T18:49:36Z</time>
<ele>1458.457</ele>
</trkpt>
<trkpt lat="39.175916" lon="-109.002013">
<time>2006-04-07T18:49:50Z</time>
<ele>1461.341</ele>
</trkpt>
<trkpt lat="39.175766" lon="-109.001927">
<time>2006-04-07T18:50:17Z</time>
<ele>1463.264</ele>
</trkpt>
<trkpt lat="39.175594" lon="-109.001863">
<time>2006-04-07T18:50:45Z</time>
<ele>1467.109</ele>
</trkpt>
<trkpt lat="39.175422" lon="-109.001756">
<time>2006-04-07T18:51:43Z</time>
<ele>1469.032</ele>
</trkpt>
<trkpt lat="39.175444" lon="-109.001756">
<time>2006-04-07T18:52:03Z</time>
<ele>1469.032</ele>
</trkpt>
<trkpt lat="39.175379" lon="-109.001713">
<time>2006-04-07T18:52:16Z</time>
<ele>1469.993</ele>
</trkpt>
<trkpt lat="39.175122" lon="-109.001455">
<time>2006-04-07T18:52:32Z</time>
<ele>1471.916</ele>
</trkpt>
<trkpt lat="39.174886" lon="-109.001005">
<time>2006-04-07T18:53:11Z</time>
<ele>1469.993</ele>
</trkpt>
<trkpt lat="39.174864" lon="-109.000769">
<time>2006-04-07T18:55:09Z</time>
<ele>1468.551</ele>
</trkpt>
<trkpt lat="39.174650" lon="-109.000533">
<time>2006-04-07T18:55:47Z</time>
<ele>1469.032</ele>
</trkpt>
<trkpt lat="39.174092" lon="-108.999996">
<time>2006-04-07T18:56:58Z</time>
<ele>1474.319</ele>
</trkpt>
<trkpt lat="39.173985" lon="-108.999803">
<time>2006-04-07T18:57:53Z</time>
<ele>1476.242</ele>
</trkpt>
<trkpt lat="39.173834" lon="-108.999546">
<time>2006-04-07T18:58:31Z</time>
<ele>1480.087</ele>
</trkpt>
<trkpt lat="39.173834" lon="-108.999588">
<time>2006-04-07T18:58:50Z</time>
<ele>1478.645</ele>
</trkpt>
<trkpt lat="39.173963" lon="-108.999760">
<time>2006-04-07T18:59:05Z</time>
<ele>1478.164</ele>
</trkpt>
<trkpt lat="39.174092" lon="-108.999975">
<time>2006-04-07T18:59:38Z</time>
<ele>1474.319</ele>
</trkpt>
<trkpt lat="39.174156" lon="-109.000061">
<time>2006-04-07T18:59:51Z</time>
<ele>1472.396</ele>
</trkpt>
<trkpt lat="39.174178" lon="-109.000061">
<time>2006-04-07T19:00:05Z</time>
<ele>1471.435</ele>
</trkpt>
<trkpt lat="39.174178" lon="-109.000103">
<time>2006-04-07T19:00:27Z</time>
<ele>1471.916</ele>
</trkpt>
<trkpt lat="39.174178" lon="-109.000082">
<time>2006-04-07T19:01:14Z</time>
<ele>1473.358</ele>
</trkpt>
<trkpt lat="39.174414" lon="-109.000275">
<time>2006-04-07T19:01:46Z</time>
<ele>1470.955</ele>
</trkpt>
<trkpt lat="39.174500" lon="-109.000382">
<time>2006-04-07T19:02:02Z</time>
<ele>1469.993</ele>
</trkpt>
<trkpt lat="39.174736" lon="-109.000576">
<time>2006-04-07T19:02:34Z</time>
<ele>1468.071</ele>
</trkpt>
<trkpt lat="39.174864" lon="-109.000790">
<time>2006-04-07T19:03:00Z</time>
<ele>1468.551</ele>
</trkpt>
<trkpt lat="39.174993" lon="-109.001155">
<time>2006-04-07T19:03:39Z</time>
<ele>1471.435</ele>
</trkpt>
<trkpt lat="39.174950" lon="-109.001155">
<time>2006-04-07T19:03:48Z</time>
<ele>1471.435</ele>
</trkpt>
<trkpt lat="39.174972" lon="-109.001155">
<time>2006-04-07T19:03:56Z</time>
<ele>1468.071</ele>
</trkpt>
<trkpt lat="39.174972" lon="-109.001155">
<time>2006-04-07T19:03:57Z</time>
<ele>1472.877</ele>
</trkpt>
<trkpt lat="39.174993" lon="-109.001176">
<time>2006-04-07T19:04:49Z</time>
<ele>1469.513</ele>
</trkpt>
<trkpt lat="39.174993" lon="-109.001133">
<time>2006-04-07T19:05:14Z</time>
<ele>1470.474</ele>
</trkpt>
<trkpt lat="39.174972" lon="-109.001176">
<time>2006-04-07T19:06:26Z</time>
<ele>1471.435</ele>
</trkpt>
<trkpt lat="39.175208" lon="-109.001541">
<time>2006-04-07T19:06:43Z</time>
<ele>1471.435</ele>
</trkpt>
<trkpt lat="39.175508" lon="-109.001799">
<time>2006-04-07T19:06:59Z</time>
<ele>1468.551</ele>
</trkpt>
<trkpt lat="39.175680" lon="-109.001863">
<time>2006-04-07T19:07:35Z</time>
<ele>1465.667</ele>
</trkpt>
<trkpt lat="39.175766" lon="-109.001949">
<time>2006-04-07T19:07:53Z</time>
<ele>1462.302</ele>
</trkpt>
<trkpt lat="39.175894" lon="-109.002013">
<time>2006-04-07T19:08:08Z</time>
<ele>1461.341</ele>
</trkpt>
<trkpt lat="39.176023" lon="-109.002035">
<time>2006-04-07T19:08:21Z</time>
<ele>1459.899</ele>
</trkpt>
<trkpt lat="39.176280" lon="-109.001799">
<time>2006-04-07T19:08:35Z</time>
<ele>1457.977</ele>
</trkpt>
<trkpt lat="39.176366" lon="-109.001606">
<time>2006-04-07T19:08:50Z</time>
<ele>1456.054</ele>
</trkpt>
<trkpt lat="39.176431" lon="-109.001541">
<time>2006-04-07T19:09:01Z</time>
<ele>1455.093</ele>
</trkpt>
<trkpt lat="39.176495" lon="-109.001520">
<time>2006-04-07T19:09:07Z</time>
<ele>1453.651</ele>
</trkpt>
<trkpt lat="39.176838" lon="-109.001541">
<time>2006-04-07T19:09:46Z</time>
<ele>1449.805</ele>
</trkpt>
<trkpt lat="39.176967" lon="-109.001498">
<time>2006-04-07T19:10:04Z</time>
<ele>1446.921</ele>
</trkpt>
<trkpt lat="39.177954" lon="-109.001391">
<time>2006-04-07T19:11:13Z</time>
<ele>1437.308</ele>
</trkpt>
<trkpt lat="39.178534" lon="-109.001369">
<time>2006-04-07T19:11:28Z</time>
<ele>1435.385</ele>
</trkpt>
<trkpt lat="39.178941" lon="-109.001434">
<time>2006-04-07T19:11:41Z</time>
<ele>1434.424</ele>
</trkpt>
<trkpt lat="39.180057" lon="-109.001176">
<time>2006-04-07T19:12:12Z</time>
<ele>1432.021</ele>
</trkpt>
<trkpt lat="39.180207" lon="-109.001176">
<time>2006-04-07T19:12:17Z</time>
<ele>1430.579</ele>
</trkpt>
<trkpt lat="39.180357" lon="-109.001412">
<time>2006-04-07T19:12:24Z</time>
<ele>1429.618</ele>
</trkpt>
<trkpt lat="39.180443" lon="-109.001970">
<time>2006-04-07T19:12:38Z</time>
<ele>1427.215</ele>
</trkpt>
<trkpt lat="39.180808" lon="-109.002335">
<time>2006-04-07T19:12:51Z</time>
<ele>1425.772</ele>
</trkpt>
<trkpt lat="39.181001" lon="-109.002421">
<time>2006-04-07T19:12:56Z</time>
<ele>1425.772</ele>
</trkpt>
<trkpt lat="39.181516" lon="-109.002678">
<time>2006-04-07T19:13:10Z</time>
<ele>1423.369</ele>
</trkpt>
<trkpt lat="39.181881" lon="-109.003043">
<time>2006-04-07T19:13:24Z</time>
<ele>1422.889</ele>
</trkpt>
<trkpt lat="39.181945" lon="-109.003515">
<time>2006-04-07T19:13:35Z</time>
<ele>1420.966</ele>
</trkpt>
<trkpt lat="39.181902" lon="-109.004202">
<time>2006-04-07T19:13:50Z</time>
<ele>1420.005</ele>
</trkpt>
<trkpt lat="39.181688" lon="-109.005189">
<time>2006-04-07T19:14:14Z</time>
<ele>1416.64</ele>
</trkpt>
<trkpt lat="39.181623" lon="-109.005618">
<time>2006-04-07T19:14:26Z</time>
<ele>1417.121</ele>
</trkpt>
<trkpt lat="39.181881" lon="-109.006648">
<time>2006-04-07T19:14:52Z</time>
<ele>1416.64</ele>
</trkpt>
<trkpt lat="39.182224" lon="-109.007592">
<time>2006-04-07T19:15:11Z</time>
<ele>1413.275</ele>
</trkpt>
<trkpt lat="39.182482" lon="-109.008279">
<time>2006-04-07T19:15:27Z</time>
<ele>1413.275</ele>
</trkpt>
<trkpt lat="39.182739" lon="-109.008536">
<time>2006-04-07T19:15:37Z</time>
<ele>1409.43</ele>
</trkpt>
<trkpt lat="39.183125" lon="-109.008794">
<time>2006-04-07T19:15:51Z</time>
<ele>1408.469</ele>
</trkpt>
<trkpt lat="39.183190" lon="-109.009137">
<time>2006-04-07T19:16:05Z</time>
<ele>1409.43</ele>
</trkpt>
<trkpt lat="39.182954" lon="-109.009953">
<time>2006-04-07T19:16:25Z</time>
<ele>1409.43</ele>
</trkpt>
<trkpt lat="39.183147" lon="-109.010081">
<time>2006-04-07T19:16:32Z</time>
<ele>1409.43</ele>
</trkpt>
<trkpt lat="39.183533" lon="-109.010210">
<time>2006-04-07T19:16:46Z</time>
<ele>1412.314</ele>
</trkpt>
<trkpt lat="39.183555" lon="-109.009995">
<time>2006-04-07T19:16:57Z</time>
<ele>1412.314</ele>
</trkpt>
<trkpt lat="39.183662" lon="-109.009867">
<time>2006-04-07T19:17:14Z</time>
<ele>1411.353</ele>
</trkpt>
<trkpt lat="39.183683" lon="-109.009888">
<time>2006-04-07T19:17:28Z</time>
<ele>1411.833</ele>
</trkpt>
<trkpt lat="39.183640" lon="-109.010146">
<time>2006-04-07T19:17:41Z</time>
<ele>1412.795</ele>
</trkpt>
<trkpt lat="39.183726" lon="-109.010231">
<time>2006-04-07T19:17:47Z</time>
<ele>1413.756</ele>
</trkpt>
<trkpt lat="39.183941" lon="-109.010210">
<time>2006-04-07T19:18:10Z</time>
<ele>1414.717</ele>
</trkpt>
<trkpt lat="39.184821" lon="-109.009330">
<time>2006-04-07T19:18:52Z</time>
<ele>1418.562</ele>
</trkpt>
<trkpt lat="39.185207" lon="-109.009094">
<time>2006-04-07T19:19:07Z</time>
<ele>1420.005</ele>
</trkpt>
<trkpt lat="39.185593" lon="-109.009008">
<time>2006-04-07T19:19:24Z</time>
<ele>1420.966</ele>
</trkpt>
<trkpt lat="39.185979" lon="-109.008815">
<time>2006-04-07T19:19:38Z</time>
<ele>1420.005</ele>
</trkpt>
<trkpt lat="39.187181" lon="-109.008451">
<time>2006-04-07T19:20:14Z</time>
<ele>1420.005</ele>
</trkpt>
<trkpt lat="39.187181" lon="-109.008536">
<time>2006-04-07T19:21:03Z</time>
<ele>1421.447</ele>
</trkpt>
<trkpt lat="39.187353" lon="-109.008343">
<time>2006-04-07T19:22:16Z</time>
<ele>1420.966</ele>
</trkpt>
<trkpt lat="39.187868" lon="-109.008129">
<time>2006-04-07T19:22:32Z</time>
<ele>1421.447</ele>
</trkpt>
<trkpt lat="39.188468" lon="-109.007978">
<time>2006-04-07T19:22:50Z</time>
<ele>1424.811</ele>
</trkpt>
<trkpt lat="39.188747" lon="-109.008000">
<time>2006-04-07T19:23:01Z</time>
<ele>1426.253</ele>
</trkpt>
<trkpt lat="39.188683" lon="-109.008687">
<time>2006-04-07T19:23:21Z</time>
<ele>1428.176</ele>
</trkpt>
<trkpt lat="39.188533" lon="-109.009759">
<time>2006-04-07T19:23:42Z</time>
<ele>1424.811</ele>
</trkpt>
<trkpt lat="39.188018" lon="-109.010983">
<time>2006-04-07T19:24:05Z</time>
<ele>1423.85</ele>
</trkpt>
<trkpt lat="39.187031" lon="-109.012635">
<time>2006-04-07T19:24:37Z</time>
<ele>1420.485</ele>
</trkpt>
<trkpt lat="39.186172" lon="-109.013815">
<time>2006-04-07T19:25:03Z</time>
<ele>1418.562</ele>
</trkpt>
<trkpt lat="39.185464" lon="-109.014995">
<time>2006-04-07T19:25:27Z</time>
<ele>1416.64</ele>
</trkpt>
<trkpt lat="39.185014" lon="-109.016004">
<time>2006-04-07T19:25:50Z</time>
<ele>1414.717</ele>
</trkpt>
<trkpt lat="39.184971" lon="-109.016604">
<time>2006-04-07T19:26:04Z</time>
<ele>1414.717</ele>
</trkpt>
<trkpt lat="39.185057" lon="-109.016583">
<time>2006-04-07T19:26:08Z</time>
<ele>1415.198</ele>
</trkpt>
<trkpt lat="39.185228" lon="-109.016540">
<time>2006-04-07T19:26:31Z</time>
<ele>1413.756</ele>
</trkpt>
</trkseg>
</trk>
</gpx>

View File

@ -0,0 +1,756 @@
<?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[active_log.gpx]]></name>
<time>2006-04-08T16:44:28Z</time>
<bounds min_lat="38.681488" min_lon="-109.606948" max_lat="38.791759" max_lon="-109.447045"/>
</metadata>
<extensions/>
<trk>
<name><![CDATA[ACTIVE LOG]]></name>
<trkseg>
<trkpt lat="38.782575" lon="-109.595146">
<time>2006-04-08T18:25:33Z</time>
<ele>1564.683</ele>
</trkpt>
<trkpt lat="38.782575" lon="-109.595146">
<time>2006-04-08T18:25:38Z</time>
<ele>1563.721</ele>
</trkpt>
<trkpt lat="38.782575" lon="-109.595211">
<time>2006-04-08T18:26:15Z</time>
<ele>1565.164</ele>
</trkpt>
<trkpt lat="38.782554" lon="-109.595211">
<time>2006-04-08T18:26:30Z</time>
<ele>1565.645</ele>
</trkpt>
<trkpt lat="38.782575" lon="-109.595189">
<time>2006-04-08T18:27:17Z</time>
<ele>1565.164</ele>
</trkpt>
<trkpt lat="38.782511" lon="-109.595211">
<time>2006-04-08T18:28:25Z</time>
<ele>1566.125</ele>
</trkpt>
<trkpt lat="38.782747" lon="-109.595146">
<time>2006-04-08T18:28:45Z</time>
<ele>1566.125</ele>
</trkpt>
<trkpt lat="38.782747" lon="-109.595082">
<time>2006-04-08T18:28:50Z</time>
<ele>1565.645</ele>
</trkpt>
<trkpt lat="38.782876" lon="-109.594996">
<time>2006-04-08T18:29:09Z</time>
<ele>1566.606</ele>
</trkpt>
<trkpt lat="38.783026" lon="-109.595039">
<time>2006-04-08T18:29:23Z</time>
<ele>1566.606</ele>
</trkpt>
<trkpt lat="38.783133" lon="-109.595082">
<time>2006-04-08T18:29:32Z</time>
<ele>1566.606</ele>
</trkpt>
<trkpt lat="38.783133" lon="-109.595125">
<time>2006-04-08T18:29:35Z</time>
<ele>1566.606</ele>
</trkpt>
<trkpt lat="38.783219" lon="-109.595318">
<time>2006-04-08T18:29:49Z</time>
<ele>1567.086</ele>
</trkpt>
<trkpt lat="38.783305" lon="-109.595447">
<time>2006-04-08T18:29:56Z</time>
<ele>1566.606</ele>
</trkpt>
<trkpt lat="38.783391" lon="-109.595704">
<time>2006-04-08T18:30:12Z</time>
<ele>1567.086</ele>
</trkpt>
<trkpt lat="38.783476" lon="-109.595940">
<time>2006-04-08T18:30:28Z</time>
<ele>1566.606</ele>
</trkpt>
<trkpt lat="38.783627" lon="-109.596112">
<time>2006-04-08T18:30:45Z</time>
<ele>1566.606</ele>
</trkpt>
<trkpt lat="38.783798" lon="-109.596348">
<time>2006-04-08T18:31:10Z</time>
<ele>1567.086</ele>
</trkpt>
<trkpt lat="38.783906" lon="-109.596670">
<time>2006-04-08T18:31:35Z</time>
<ele>1568.528</ele>
</trkpt>
</trkseg>
<trkseg>
<trkpt lat="38.783927" lon="-109.596992">
<time>2006-04-08T18:32:04Z</time>
<ele>1570.451</ele>
</trkpt>
<trkpt lat="38.783991" lon="-109.597099">
<time>2006-04-08T18:32:05Z</time>
<ele>1570.451</ele>
</trkpt>
<trkpt lat="38.784184" lon="-109.597421">
<time>2006-04-08T18:32:31Z</time>
<ele>1572.374</ele>
</trkpt>
<trkpt lat="38.784206" lon="-109.597464">
<time>2006-04-08T18:32:35Z</time>
<ele>1572.374</ele>
</trkpt>
<trkpt lat="38.784506" lon="-109.597485">
<time>2006-04-08T18:32:57Z</time>
<ele>1573.335</ele>
</trkpt>
<trkpt lat="38.784764" lon="-109.597721">
<time>2006-04-08T18:33:25Z</time>
<ele>1573.335</ele>
</trkpt>
<trkpt lat="38.785043" lon="-109.597721">
<time>2006-04-08T18:33:49Z</time>
<ele>1575.257</ele>
</trkpt>
<trkpt lat="38.785257" lon="-109.597635">
<time>2006-04-08T18:34:07Z</time>
<ele>1575.257</ele>
</trkpt>
<trkpt lat="38.785408" lon="-109.597614">
<time>2006-04-08T18:34:22Z</time>
<ele>1575.257</ele>
</trkpt>
<trkpt lat="38.785558" lon="-109.597464">
<time>2006-04-08T18:34:40Z</time>
<ele>1575.257</ele>
</trkpt>
<trkpt lat="38.785665" lon="-109.597378">
<time>2006-04-08T18:34:56Z</time>
<ele>1574.777</ele>
</trkpt>
<trkpt lat="38.785772" lon="-109.597292">
<time>2006-04-08T18:35:07Z</time>
<ele>1572.854</ele>
</trkpt>
<trkpt lat="38.785901" lon="-109.597249">
<time>2006-04-08T18:35:18Z</time>
<ele>1569.97</ele>
</trkpt>
<trkpt lat="38.785901" lon="-109.597228">
<time>2006-04-08T18:35:19Z</time>
<ele>1569.49</ele>
</trkpt>
<trkpt lat="38.786051" lon="-109.597163">
<time>2006-04-08T18:35:32Z</time>
<ele>1565.645</ele>
</trkpt>
<trkpt lat="38.786137" lon="-109.597077">
<time>2006-04-08T18:35:43Z</time>
<ele>1563.721</ele>
</trkpt>
<trkpt lat="38.786137" lon="-109.596992">
<time>2006-04-08T18:35:48Z</time>
<ele>1562.76</ele>
</trkpt>
<trkpt lat="38.786051" lon="-109.596734">
<time>2006-04-08T18:36:07Z</time>
<ele>1559.876</ele>
</trkpt>
<trkpt lat="38.785815" lon="-109.596541">
<time>2006-04-08T18:36:26Z</time>
<ele>1560.357</ele>
</trkpt>
<trkpt lat="38.785665" lon="-109.596391">
<time>2006-04-08T18:36:45Z</time>
<ele>1560.357</ele>
</trkpt>
<trkpt lat="38.785536" lon="-109.596305">
<time>2006-04-08T18:37:08Z</time>
<ele>1560.838</ele>
</trkpt>
<trkpt lat="38.785536" lon="-109.596305">
<time>2006-04-08T18:37:19Z</time>
<ele>1557.954</ele>
</trkpt>
<trkpt lat="38.785536" lon="-109.596305">
<time>2006-04-08T18:37:20Z</time>
<ele>1562.28</ele>
</trkpt>
<trkpt lat="38.785536" lon="-109.596305">
<time>2006-04-08T18:37:28Z</time>
<ele>1561.799</ele>
</trkpt>
<trkpt lat="38.785536" lon="-109.596305">
<time>2006-04-08T18:37:30Z</time>
<ele>1560.838</ele>
</trkpt>
<trkpt lat="38.785558" lon="-109.596326">
<time>2006-04-08T18:37:44Z</time>
<ele>1560.357</ele>
</trkpt>
<trkpt lat="38.785536" lon="-109.596326">
<time>2006-04-08T18:37:47Z</time>
<ele>1561.799</ele>
</trkpt>
<trkpt lat="38.785515" lon="-109.596348">
<time>2006-04-08T18:38:06Z</time>
<ele>1559.876</ele>
</trkpt>
<trkpt lat="38.785558" lon="-109.596369">
<time>2006-04-08T18:38:24Z</time>
<ele>1561.799</ele>
</trkpt>
<trkpt lat="38.785558" lon="-109.596369">
<time>2006-04-08T18:38:25Z</time>
<ele>1561.799</ele>
</trkpt>
<trkpt lat="38.785579" lon="-109.596391">
<time>2006-04-08T18:38:35Z</time>
<ele>1561.799</ele>
</trkpt>
<trkpt lat="38.785686" lon="-109.596455">
<time>2006-04-08T18:38:51Z</time>
<ele>1561.318</ele>
</trkpt>
<trkpt lat="38.785858" lon="-109.596648">
<time>2006-04-08T18:39:11Z</time>
<ele>1560.838</ele>
</trkpt>
<trkpt lat="38.786030" lon="-109.596756">
<time>2006-04-08T18:39:27Z</time>
<ele>1561.318</ele>
</trkpt>
<trkpt lat="38.786137" lon="-109.597013">
<time>2006-04-08T18:39:50Z</time>
<ele>1563.721</ele>
</trkpt>
<trkpt lat="38.786159" lon="-109.597034">
<time>2006-04-08T18:39:57Z</time>
<ele>1564.202</ele>
</trkpt>
<trkpt lat="38.786309" lon="-109.597013">
<time>2006-04-08T18:40:12Z</time>
<ele>1564.202</ele>
</trkpt>
<trkpt lat="38.786330" lon="-109.597034">
<time>2006-04-08T18:40:15Z</time>
<ele>1564.202</ele>
</trkpt>
<trkpt lat="38.786502" lon="-109.597034">
<time>2006-04-08T18:40:32Z</time>
<ele>1562.28</ele>
</trkpt>
<trkpt lat="38.786631" lon="-109.597185">
<time>2006-04-08T18:40:49Z</time>
<ele>1563.241</ele>
</trkpt>
<trkpt lat="38.786716" lon="-109.597292">
<time>2006-04-08T18:41:01Z</time>
<ele>1563.721</ele>
</trkpt>
<trkpt lat="38.786738" lon="-109.597313">
<time>2006-04-08T18:41:05Z</time>
<ele>1564.683</ele>
</trkpt>
<trkpt lat="38.786888" lon="-109.597571">
<time>2006-04-08T18:41:28Z</time>
<ele>1564.202</ele>
</trkpt>
<trkpt lat="38.787038" lon="-109.597785">
<time>2006-04-08T18:41:50Z</time>
<ele>1565.645</ele>
</trkpt>
<trkpt lat="38.787060" lon="-109.597807">
<time>2006-04-08T18:41:59Z</time>
<ele>1565.645</ele>
</trkpt>
<trkpt lat="38.787081" lon="-109.597893">
<time>2006-04-08T18:42:05Z</time>
<ele>1565.645</ele>
</trkpt>
<trkpt lat="38.787081" lon="-109.598000">
<time>2006-04-08T18:42:13Z</time>
<ele>1565.645</ele>
</trkpt>
<trkpt lat="38.787124" lon="-109.598279">
<time>2006-04-08T18:42:34Z</time>
<ele>1569.97</ele>
</trkpt>
<trkpt lat="38.787210" lon="-109.598451">
<time>2006-04-08T18:42:51Z</time>
<ele>1571.412</ele>
</trkpt>
<trkpt lat="38.787339" lon="-109.598751">
<time>2006-04-08T18:43:16Z</time>
<ele>1572.374</ele>
</trkpt>
<trkpt lat="38.787425" lon="-109.598880">
<time>2006-04-08T18:43:43Z</time>
<ele>1569.97</ele>
</trkpt>
<trkpt lat="38.787510" lon="-109.598751">
<time>2006-04-08T18:45:38Z</time>
<ele>1570.451</ele>
</trkpt>
<trkpt lat="38.787510" lon="-109.598708">
<time>2006-04-08T18:45:55Z</time>
<ele>1569.49</ele>
</trkpt>
<trkpt lat="38.787489" lon="-109.598687">
<time>2006-04-08T18:46:13Z</time>
<ele>1569.009</ele>
</trkpt>
<trkpt lat="38.787382" lon="-109.598730">
<time>2006-04-08T18:46:39Z</time>
<ele>1570.932</ele>
</trkpt>
<trkpt lat="38.787317" lon="-109.598665">
<time>2006-04-08T18:46:53Z</time>
<ele>1571.893</ele>
</trkpt>
<trkpt lat="38.787274" lon="-109.598536">
<time>2006-04-08T18:47:18Z</time>
<ele>1572.374</ele>
</trkpt>
<trkpt lat="38.787339" lon="-109.598451">
<time>2006-04-08T18:47:34Z</time>
<ele>1572.374</ele>
</trkpt>
<trkpt lat="38.787296" lon="-109.598408">
<time>2006-04-08T18:47:41Z</time>
<ele>1572.374</ele>
</trkpt>
<trkpt lat="38.787189" lon="-109.598150">
<time>2006-04-08T18:48:03Z</time>
<ele>1570.451</ele>
</trkpt>
<trkpt lat="38.787103" lon="-109.597914">
<time>2006-04-08T18:48:20Z</time>
<ele>1567.086</ele>
</trkpt>
<trkpt lat="38.786995" lon="-109.597635">
<time>2006-04-08T18:48:40Z</time>
<ele>1566.606</ele>
</trkpt>
<trkpt lat="38.786802" lon="-109.597421">
<time>2006-04-08T18:49:03Z</time>
<ele>1565.645</ele>
</trkpt>
<trkpt lat="38.786674" lon="-109.597163">
<time>2006-04-08T18:49:21Z</time>
<ele>1566.606</ele>
</trkpt>
<trkpt lat="38.786438" lon="-109.596927">
<time>2006-04-08T18:49:46Z</time>
<ele>1565.164</ele>
</trkpt>
<trkpt lat="38.786330" lon="-109.596927">
<time>2006-04-08T18:49:57Z</time>
<ele>1566.125</ele>
</trkpt>
<trkpt lat="38.786116" lon="-109.597013">
<time>2006-04-08T18:50:15Z</time>
<ele>1567.086</ele>
</trkpt>
<trkpt lat="38.785944" lon="-109.597142">
<time>2006-04-08T18:50:33Z</time>
<ele>1570.451</ele>
</trkpt>
<trkpt lat="38.785815" lon="-109.597270">
<time>2006-04-08T18:50:49Z</time>
<ele>1573.335</ele>
</trkpt>
<trkpt lat="38.785665" lon="-109.597335">
<time>2006-04-08T18:51:04Z</time>
<ele>1577.18</ele>
</trkpt>
<trkpt lat="38.785644" lon="-109.597399">
<time>2006-04-08T18:51:10Z</time>
<ele>1576.699</ele>
</trkpt>
<trkpt lat="38.785536" lon="-109.597442">
<time>2006-04-08T18:51:17Z</time>
<ele>1577.661</ele>
</trkpt>
<trkpt lat="38.785493" lon="-109.597528">
<time>2006-04-08T18:51:26Z</time>
<ele>1577.661</ele>
</trkpt>
<trkpt lat="38.785515" lon="-109.597635">
<time>2006-04-08T18:51:35Z</time>
<ele>1577.661</ele>
</trkpt>
<trkpt lat="38.785622" lon="-109.597700">
<time>2006-04-08T18:51:50Z</time>
<ele>1578.622</ele>
</trkpt>
<trkpt lat="38.785729" lon="-109.597828">
<time>2006-04-08T18:52:07Z</time>
<ele>1579.103</ele>
</trkpt>
<trkpt lat="38.785880" lon="-109.598022">
<time>2006-04-08T18:52:25Z</time>
<ele>1576.219</ele>
</trkpt>
<trkpt lat="38.785944" lon="-109.598129">
<time>2006-04-08T18:52:42Z</time>
<ele>1576.219</ele>
</trkpt>
<trkpt lat="38.786094" lon="-109.598300">
<time>2006-04-08T18:53:01Z</time>
<ele>1576.219</ele>
</trkpt>
<trkpt lat="38.786159" lon="-109.598386">
<time>2006-04-08T18:53:09Z</time>
<ele>1575.738</ele>
</trkpt>
<trkpt lat="38.786201" lon="-109.598408">
<time>2006-04-08T18:53:13Z</time>
<ele>1576.219</ele>
</trkpt>
<trkpt lat="38.786244" lon="-109.598536">
<time>2006-04-08T18:53:30Z</time>
<ele>1577.661</ele>
</trkpt>
<trkpt lat="38.786330" lon="-109.598687">
<time>2006-04-08T18:53:45Z</time>
<ele>1578.622</ele>
</trkpt>
<trkpt lat="38.786373" lon="-109.598730">
<time>2006-04-08T18:53:52Z</time>
<ele>1579.103</ele>
</trkpt>
<trkpt lat="38.786523" lon="-109.598966">
<time>2006-04-08T18:54:11Z</time>
<ele>1580.064</ele>
</trkpt>
<trkpt lat="38.786695" lon="-109.599137">
<time>2006-04-08T18:54:30Z</time>
<ele>1581.026</ele>
</trkpt>
<trkpt lat="38.786888" lon="-109.599266">
<time>2006-04-08T18:54:49Z</time>
<ele>1581.506</ele>
</trkpt>
<trkpt lat="38.787017" lon="-109.599524">
<time>2006-04-08T18:55:08Z</time>
<ele>1581.987</ele>
</trkpt>
<trkpt lat="38.787124" lon="-109.599781">
<time>2006-04-08T18:55:28Z</time>
<ele>1581.026</ele>
</trkpt>
<trkpt lat="38.787231" lon="-109.600060">
<time>2006-04-08T18:55:52Z</time>
<ele>1581.506</ele>
</trkpt>
</trkseg>
<trkseg>
<trkpt lat="38.787339" lon="-109.600317">
<time>2006-04-08T18:56:30Z</time>
<ele>1582.948</ele>
</trkpt>
</trkseg>
<trkseg>
<trkpt lat="38.789527" lon="-109.599695">
<time>2006-04-08T18:57:12Z</time>
<ele>1582.468</ele>
</trkpt>
<trkpt lat="38.787532" lon="-109.600210">
<time>2006-04-08T18:57:22Z</time>
<ele>1584.871</ele>
</trkpt>
<trkpt lat="38.787618" lon="-109.600339">
<time>2006-04-08T18:57:39Z</time>
<ele>1587.755</ele>
</trkpt>
<trkpt lat="38.787618" lon="-109.600360">
<time>2006-04-08T18:57:42Z</time>
<ele>1586.313</ele>
</trkpt>
<trkpt lat="38.787661" lon="-109.600468">
<time>2006-04-08T18:57:53Z</time>
<ele>1592.081</ele>
</trkpt>
<trkpt lat="38.787704" lon="-109.600511">
<time>2006-04-08T18:58:01Z</time>
<ele>1592.561</ele>
</trkpt>
<trkpt lat="38.787854" lon="-109.600618">
<time>2006-04-08T18:58:17Z</time>
<ele>1594.003</ele>
</trkpt>
<trkpt lat="38.788004" lon="-109.600682">
<time>2006-04-08T18:58:33Z</time>
<ele>1592.561</ele>
</trkpt>
<trkpt lat="38.788176" lon="-109.600811">
<time>2006-04-08T18:58:49Z</time>
<ele>1588.716</ele>
</trkpt>
<trkpt lat="38.788369" lon="-109.600940">
<time>2006-04-08T18:59:07Z</time>
<ele>1585.832</ele>
</trkpt>
<trkpt lat="38.788583" lon="-109.601047">
<time>2006-04-08T18:59:27Z</time>
<ele>1582.468</ele>
</trkpt>
<trkpt lat="38.788712" lon="-109.601197">
<time>2006-04-08T18:59:44Z</time>
<ele>1583.429</ele>
</trkpt>
<trkpt lat="38.788862" lon="-109.601412">
<time>2006-04-08T19:00:02Z</time>
<ele>1581.026</ele>
</trkpt>
<trkpt lat="38.789012" lon="-109.601669">
<time>2006-04-08T19:00:24Z</time>
<ele>1580.064</ele>
</trkpt>
<trkpt lat="38.789120" lon="-109.601884">
<time>2006-04-08T19:00:41Z</time>
<ele>1580.545</ele>
</trkpt>
<trkpt lat="38.789141" lon="-109.601905">
<time>2006-04-08T19:00:52Z</time>
<ele>1580.545</ele>
</trkpt>
<trkpt lat="38.789313" lon="-109.601991">
<time>2006-04-08T19:01:10Z</time>
<ele>1582.468</ele>
</trkpt>
<trkpt lat="38.789485" lon="-109.602056">
<time>2006-04-08T19:01:26Z</time>
<ele>1585.351</ele>
</trkpt>
<trkpt lat="38.789656" lon="-109.602292">
<time>2006-04-08T19:01:47Z</time>
<ele>1586.313</ele>
</trkpt>
<trkpt lat="38.789828" lon="-109.602506">
<time>2006-04-08T19:02:07Z</time>
<ele>1587.274</ele>
</trkpt>
<trkpt lat="38.790021" lon="-109.602764">
<time>2006-04-08T19:02:31Z</time>
<ele>1585.832</ele>
</trkpt>
<trkpt lat="38.790150" lon="-109.602957">
<time>2006-04-08T19:02:48Z</time>
<ele>1588.235</ele>
</trkpt>
<trkpt lat="38.790300" lon="-109.603193">
<time>2006-04-08T19:03:08Z</time>
<ele>1588.716</ele>
</trkpt>
<trkpt lat="38.790407" lon="-109.603450">
<time>2006-04-08T19:03:29Z</time>
<ele>1589.197</ele>
</trkpt>
<trkpt lat="38.790407" lon="-109.603665">
<time>2006-04-08T19:03:45Z</time>
<ele>1588.235</ele>
</trkpt>
<trkpt lat="38.790450" lon="-109.603965">
<time>2006-04-08T19:04:04Z</time>
<ele>1588.235</ele>
</trkpt>
<trkpt lat="38.790472" lon="-109.604266">
<time>2006-04-08T19:04:24Z</time>
<ele>1585.351</ele>
</trkpt>
<trkpt lat="38.790514" lon="-109.604373">
<time>2006-04-08T19:04:36Z</time>
<ele>1585.351</ele>
</trkpt>
<trkpt lat="38.790514" lon="-109.604437">
<time>2006-04-08T19:04:40Z</time>
<ele>1584.39</ele>
</trkpt>
<trkpt lat="38.790536" lon="-109.604545">
<time>2006-04-08T19:04:51Z</time>
<ele>1584.39</ele>
</trkpt>
<trkpt lat="38.790557" lon="-109.604759">
<time>2006-04-08T19:05:08Z</time>
<ele>1584.871</ele>
</trkpt>
<trkpt lat="38.790665" lon="-109.604845">
<time>2006-04-08T19:05:23Z</time>
<ele>1584.871</ele>
</trkpt>
<trkpt lat="38.790686" lon="-109.604867">
<time>2006-04-08T19:05:30Z</time>
<ele>1584.39</ele>
</trkpt>
<trkpt lat="38.790708" lon="-109.605081">
<time>2006-04-08T19:05:46Z</time>
<ele>1584.871</ele>
</trkpt>
<trkpt lat="38.790793" lon="-109.605124">
<time>2006-04-08T19:05:54Z</time>
<ele>1584.871</ele>
</trkpt>
<trkpt lat="38.790815" lon="-109.605231">
<time>2006-04-08T19:06:10Z</time>
<ele>1586.313</ele>
</trkpt>
<trkpt lat="38.790836" lon="-109.605339">
<time>2006-04-08T19:06:30Z</time>
<ele>1587.274</ele>
</trkpt>
<trkpt lat="38.790793" lon="-109.605381">
<time>2006-04-08T19:06:56Z</time>
<ele>1586.793</ele>
</trkpt>
<trkpt lat="38.790815" lon="-109.605360">
<time>2006-04-08T19:07:59Z</time>
<ele>1588.235</ele>
</trkpt>
<trkpt lat="38.790815" lon="-109.605360">
<time>2006-04-08T19:08:16Z</time>
<ele>1588.235</ele>
</trkpt>
<trkpt lat="38.790815" lon="-109.605381">
<time>2006-04-08T19:08:42Z</time>
<ele>1587.755</ele>
</trkpt>
<trkpt lat="38.790772" lon="-109.605553">
<time>2006-04-08T19:09:04Z</time>
<ele>1589.197</ele>
</trkpt>
<trkpt lat="38.790836" lon="-109.605768">
<time>2006-04-08T19:09:20Z</time>
<ele>1589.677</ele>
</trkpt>
<trkpt lat="38.790987" lon="-109.605918">
<time>2006-04-08T19:09:39Z</time>
<ele>1589.197</ele>
</trkpt>
<trkpt lat="38.791115" lon="-109.606047">
<time>2006-04-08T19:10:08Z</time>
<ele>1588.716</ele>
</trkpt>
<trkpt lat="38.791158" lon="-109.606240">
<time>2006-04-08T19:10:33Z</time>
<ele>1590.158</ele>
</trkpt>
<trkpt lat="38.791158" lon="-109.606261">
<time>2006-04-08T19:10:34Z</time>
<ele>1589.677</ele>
</trkpt>
<trkpt lat="38.791137" lon="-109.606390">
<time>2006-04-08T19:10:53Z</time>
<ele>1591.6</ele>
</trkpt>
<trkpt lat="38.791072" lon="-109.606583">
<time>2006-04-08T19:11:11Z</time>
<ele>1589.677</ele>
</trkpt>
<trkpt lat="38.791115" lon="-109.606755">
<time>2006-04-08T19:11:27Z</time>
<ele>1589.677</ele>
</trkpt>
<trkpt lat="38.791137" lon="-109.606776">
<time>2006-04-08T19:11:31Z</time>
<ele>1593.522</ele>
</trkpt>
<trkpt lat="38.791158" lon="-109.606948">
<time>2006-04-08T19:11:52Z</time>
<ele>1592.081</ele>
</trkpt>
<trkpt lat="38.791158" lon="-109.606841">
<time>2006-04-08T19:12:21Z</time>
<ele>1592.081</ele>
</trkpt>
<trkpt lat="38.791158" lon="-109.606712">
<time>2006-04-08T19:12:42Z</time>
<ele>1590.638</ele>
</trkpt>
<trkpt lat="38.791137" lon="-109.606626">
<time>2006-04-08T19:12:52Z</time>
<ele>1589.197</ele>
</trkpt>
<trkpt lat="38.791137" lon="-109.606454">
<time>2006-04-08T19:13:09Z</time>
<ele>1591.119</ele>
</trkpt>
<trkpt lat="38.791158" lon="-109.606304">
<time>2006-04-08T19:13:25Z</time>
<ele>1590.638</ele>
</trkpt>
<trkpt lat="38.791180" lon="-109.606154">
<time>2006-04-08T19:13:45Z</time>
<ele>1590.158</ele>
</trkpt>
<trkpt lat="38.791201" lon="-109.606154">
<time>2006-04-08T19:14:19Z</time>
<ele>1587.755</ele>
</trkpt>
<trkpt lat="38.791265" lon="-109.606240">
<time>2006-04-08T19:14:48Z</time>
<ele>1589.197</ele>
</trkpt>
<trkpt lat="38.791265" lon="-109.606261">
<time>2006-04-08T19:14:49Z</time>
<ele>1589.197</ele>
</trkpt>
</trkseg>
<trkseg>
<trkpt lat="38.791609" lon="-109.606647">
<time>2006-04-08T19:15:32Z</time>
<ele>1590.158</ele>
</trkpt>
<trkpt lat="38.791759" lon="-109.606240">
<time>2006-04-08T19:16:06Z</time>
<ele>1590.158</ele>
</trkpt>
</trkseg>
<trkseg>
<trkpt lat="38.791716" lon="-109.604588">
<time>2006-04-08T19:18:43Z</time>
<ele>1584.39</ele>
</trkpt>
<trkpt lat="38.790622" lon="-109.604352">
<time>2006-04-08T19:19:03Z</time>
<ele>1585.351</ele>
</trkpt>
<trkpt lat="38.790493" lon="-109.604223">
<time>2006-04-08T19:19:18Z</time>
<ele>1586.313</ele>
</trkpt>
<trkpt lat="38.790600" lon="-109.603901">
<time>2006-04-08T19:19:34Z</time>
<ele>1588.716</ele>
</trkpt>
<trkpt lat="38.790386" lon="-109.603364">
<time>2006-04-08T19:20:21Z</time>
<ele>1589.677</ele>
</trkpt>
<trkpt lat="38.790128" lon="-109.602721">
<time>2006-04-08T19:21:11Z</time>
<ele>1586.313</ele>
</trkpt>
</trkseg>
<trkseg>
<trkpt lat="38.782532" lon="-109.595146">
<time>2006-04-08T19:39:11Z</time>
<ele>1575.738</ele>
</trkpt>
<trkpt lat="38.782532" lon="-109.595168">
<time>2006-04-08T19:39:18Z</time>
<ele>1572.854</ele>
</trkpt>
</trkseg>
<trkseg>
<trkpt lat="38.681488" lon="-109.447045">
<time>2006-04-08T22:39:30Z</time>
<ele>1267.155</ele>
</trkpt>
</trkseg>
</trk>
</gpx>

View File

@ -0,0 +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>

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +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><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

@ -0,0 +1,18 @@
require 'test/unit'
require 'gpx'
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")
def test_convert
GPX::MagellanTrackLog.convert_to_gpx(MAGELLAN_TRACK_LOG, "/tmp/gpx_from_magellan.gpx")
@gpx_file = GPX::GPXFile.new(:gpx_file => "/tmp/gpx_from_magellan.gpx")
end
def test_file_type
assert(GPX::MagellanTrackLog::is_magellan_file?(MAGELLAN_TRACK_LOG))
assert(!GPX::MagellanTrackLog::is_magellan_file?(GPX_FILE))
end
end

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

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

@ -0,0 +1,58 @@
require 'test/unit'
require 'yaml'
require 'gpx'
class SegmentTest < Test::Unit::TestCase
ONE_SEGMENT = File.join(File.dirname(__FILE__), "gpx_files/one_segment.gpx")
def setup
@gpx_file = GPX::GPXFile.new(:gpx_file => ONE_SEGMENT)
@segment = @gpx_file.tracks.first.segments.first
end
def test_segment_read
assert_equal(189, @segment.points.size)
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_in_delta(6.98803359528853, @segment.distance, 0.001)
end
def test_segment_crop
crop_rectangle = GPX::Bounds.new( :min_lat=> 39.173000,
:min_lon=> -109.010000,
:max_lat=> 39.188000,
:max_lon=> -108.999000)
@segment.crop(crop_rectangle)
assert_equal(106, @segment.points.size)
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)
assert_equal(-109.009995, @segment.bounds.min_lon)
assert_equal(39.187868, @segment.bounds.max_lat)
assert_equal(-108.999546, @segment.bounds.max_lon)
end
def test_segment_delete
delete_rectangle = GPX::Bounds.new( :min_lat=> 39.173000,
:min_lon=> -109.010000,
:max_lat=> 39.188000,
:max_lon=> -108.999000)
@segment.delete_area(delete_rectangle)
assert_equal(83, @segment.points.size)
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)
assert_equal(-109.016604, @segment.bounds.min_lon)
assert_equal(39.188747, @segment.bounds.max_lat)
assert_equal(-109.007978, @segment.bounds.max_lon)
end
end

View File

@ -0,0 +1,75 @@
require 'test/unit'
require 'gpx'
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")
def setup
@track_file = GPX::GPXFile.new(:gpx_file => TRACK_FILE)
@other_track_file = GPX::GPXFile.new(:gpx_file => OTHER_TRACK_FILE)
end
def test_track_read
assert_equal(3, @track_file.tracks.size)
assert_equal("First Track", @track_file.tracks[0].name)
assert_equal("Second Track", @track_file.tracks[1].name)
assert_equal("Third Track", @track_file.tracks[2].name)
end
def test_track_segment_and_point_counts
# One segment with 398 points...
assert_equal(1, @track_file.tracks[0].segments.size)
assert_equal(389, @track_file.tracks[0].segments.first.points.size)
# One segment with 299 points...
assert_equal(1, @track_file.tracks[1].segments.size)
assert_equal(299, @track_file.tracks[1].segments.first.points.size)
# Many segments of many different sizes
segment_sizes = %w{ 2 2 5 4 2 1 197 31 54 1 15 54 19 26 109 18 9 2 8 3 10 23 21 11 25 32 66 21 2 3 3 4 6 4 4 4 3 3 6 6 27 13 2 }
assert_equal(43, @track_file.tracks[2].segments.size)
@track_file.tracks[2].segments.each_with_index do |seg, i|
assert_equal(segment_sizes[i].to_i, seg.points.size)
end
last_segment = @track_file.tracks[2].segments.last
assert_equal(1680.041, last_segment.points.last.elevation)
second_to_last_segment = @track_file.tracks[2].segments[-2]
assert_equal("2006-01-02T00:00:51Z", second_to_last_segment.points.last.time.strftime("%Y-%m-%dT%H:%M:%SZ"))
assert_equal(39.998045, second_to_last_segment.points.last.lat)
assert_equal(-105.292368, second_to_last_segment.points.last.lon)
end
def test_find_nearest_point_by_time
time = Time.parse("2005-12-31T22:02:01Z")
pt = @track_file.tracks[0].closest_point(time)
#puts "pt: #{pt.lat_lon}"
end
def test_find_distance
#puts "Distance: #{@other_track_file.distance(:units => 'miles')} miles"
#puts "Distance: #{@track_file.distance(:units => 'miles')} miles"
end
def test_high_low_elevation
#puts "Lowest: #{@track_file.lowest_point.elevation} m"
#puts "Highest: #{@track_file.highest_point.elevation} m"
end
def test_duration
#puts "Duration 1: #{@other_track_file.duration} "
#puts "Duration 2: #{@track_file.duration} "
end
def test_average_speed
#puts "Speed 1: #{@other_track_file.average_speed} "
#puts "Speed 2: #{@track_file.average_speed} "
end
def test_write
@other_track_file.write("tests/output/myoutput.gpx")
end
end

View File

@ -0,0 +1,65 @@
require 'test/unit'
require 'gpx'
class TrackTest < Test::Unit::TestCase
ONE_TRACK = File.join(File.dirname(__FILE__), "gpx_files/one_track.gpx")
def setup
@gpx_file = GPX::GPXFile.new(:gpx_file => ONE_TRACK)
@track = @gpx_file.tracks.first
end
def test_track_read
assert_equal("ACTIVE LOG", @track.name)
assert_equal( 182, @track.points.size)
assert_equal(8, @track.segments.size)
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)
assert_equal(-109.606948, @track.bounds.min_lon)
assert_equal(38.791759, @track.bounds.max_lat)
assert_equal(-109.447045, @track.bounds.max_lon)
end
def test_track_crop
area = GPX::Bounds.new(
:min_lat => 38.710000,
:min_lon => -109.600000,
:max_lat => 38.791759,
:max_lon => -109.450000)
@track.crop(area)
assert_equal("ACTIVE LOG", @track.name)
assert_equal( 111, @track.points.size)
assert_equal(4, @track.segments.size)
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)
assert_equal(-109.599781, @track.bounds.min_lon)
assert_equal(38.789527, @track.bounds.max_lat)
assert_equal(-109.594996, @track.bounds.max_lon)
end
def test_track_delete
area = GPX::Bounds.new(
:min_lat => 38.710000,
:min_lon => -109.600000,
:max_lat => 38.791759,
:max_lon => -109.450000)
@track.delete_area(area)
#puts @track
#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_equal(1557.954, @track.lowest_point.elevation)
#assert_equal(1582.468, @track.highest_point.elevation)
#assert_equal(38.782511, @track.bounds.min_lat)
#assert_equal(-109.599781, @track.bounds.min_lon)
#assert_equal(38.789527, @track.bounds.max_lat)
#assert_equal(-109.594996, @track.bounds.max_lon)
end
end

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