Initial import of gpx gem.

master
Doug Fales 2006-10-14 13:20:23 +00:00
commit 371a3fa0b9
24 changed files with 9649 additions and 0 deletions

43
README 100644
View File

@ -0,0 +1,43 @@
= GPX Gem
Copyright (C) 2006 Doug Fales
Doug Fales mailto:doug.fales@gmail.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. 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 REXML 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.

81
Rakefile 100644
View File

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

37
lib/gpx.rb 100644
View File

@ -0,0 +1,37 @@
#--
# 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.
#++
$:.unshift(File.dirname(__FILE__))
require 'rexml/document'
require 'date'
require 'time'
require 'csv'
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'

83
lib/gpx/bounds.rb 100644
View File

@ -0,0 +1,83 @@
#--
# 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
def to_xml
bnd = REXML::Element.new('bounds')
bnd.attributes['min_lat'] = min_lat
bnd.attributes['min_lon'] = min_lon
bnd.attributes['max_lat'] = max_lat
bnd.attributes['max_lon'] = max_lon
bnd
end
# Returns true if the pt is within these bounds.
def contains?(pt)
(pt.lat >= min_lat and pt.lat <= max_lat and pt.lon >= min_lon and pt.lon <= max_lon)
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

53
lib/gpx/gpx.rb 100644
View File

@ -0,0 +1,53 @@
#--
# 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
VERSION = "0.1"
# A common base class which provides a useful initializer method to many
# class in the GPX library.
class Base
include REXML
# This initializer can take a REXML::Element 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|
unless parent.elements[el].nil?
val = parent.elements[el].text
code = <<-code
attr_accessor #{ el }
#{el}=#{val}
code
class_eval code
end
end
end
end
end

222
lib/gpx/gpx_file.rb 100644
View File

@ -0,0 +1,222 @@
#--
# 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_reader :tracks, :routes, :waypoints, :bounds, :lowest_point, :highest_point, :distance, :duration, :average_speed
# 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 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])
gpx_file = opts[:gpx_file]
case gpx_file
when String
gpx_file = File.open(gpx_file)
end
reset_meta_data
@xml = Document.new(gpx_file, :ignore_whitespace_nodes => :all)
bounds_element = (XPath.match(@xml, "/gpx/metadata/bounds").first rescue nil)
if bounds_element
@bounds.min_lat = bounds_element.attributes["min_lat"].to_f
@bounds.min_lon = bounds_element.attributes["min_lon"].to_f
@bounds.max_lat = bounds_element.attributes["max_lat"].to_f
@bounds.max_lon = bounds_element.attributes["max_lon"].to_f
else
get_bounds = true
end
@tracks = XPath.match(@xml, "/gpx/trk").collect do |trk|
trk = Track.new(:element => trk, :gpx_file => self)
update_meta_data(trk, get_bounds)
trk
end
@waypoints = XPath.match(@xml, "/gpx/wpt").collect { |wpt| Waypoint.new(:element => wpt, :gpx_file => self) }
@routes = XPath.match(@xml, "/gpx/rte").collect { |rte| 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
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.elevation < @lowest_point.elevation)
@highest_point = trk.highest_point if(@highest_point.nil? or 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)
doc = Document.new
gpx_elem = Element.new('gpx')
doc.add(gpx_elem)
gpx_elem.attributes['xmlns:xsi'] = "http://www.w3.org/2001/XMLSchema-instance"
gpx_elem.attributes['xmlns'] = "http://www.topografix.com/GPX/1/1"
gpx_elem.attributes['version'] = "1.1"
gpx_elem.attributes['creator'] = "GPX RubyGem 0.1 Copyright 2006 Doug Fales -- http://walkingboss.com"
gpx_elem.attributes['xsi:schemaLocation'] = "http://www.topografix.com/GPX/1/1 http://www.topografix.com/GPX/1/1/gpx.xsd"
meta_data_elem = Element.new('metadata')
name_elem = Element.new('name')
name_elem.text = File.basename(filename)
meta_data_elem.elements << name_elem
time_elem = Element.new('time')
time_elem.text = Time.now.xmlschema
meta_data_elem.elements << time_elem
meta_data_elem.elements << bounds.to_xml
gpx_elem.elements << meta_data_elem
tracks.each { |t| gpx_elem.add_element t.to_xml } unless tracks.nil?
waypoints.each { |w| gpx_elem.add_element w.to_xml } unless waypoints.nil?
routes.each { |r| gpx_elem.add_element r.to_xml } unless routes.nil?
File.open(filename, 'w') { |f| doc.write(f) }
end
private
# 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,134 @@
#--
# 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") 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

103
lib/gpx/point.rb 100644
View File

@ -0,0 +1,103 @@
#--
# 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.
#++
include Math
module GPX
# The base class for all points. Trackpoint and Waypoint both descend from this base class.
class Point < Base
D_TO_R = PI/180.0;
attr_accessor :lat, :lon, :time, :elevation
# 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 a REXML 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 } )
if (opts[:element])
elem = opts[:element]
@lat, @lon = elem.attributes["lat"].to_f, elem.attributes["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.elements["time"].text) rescue nil)
@elevation = elem.elements["ele"].text.to_f if elem.elements["ele"]
else
@lat = opts[:lat]
@lon = opts[:lon]
@elevation = opts[:elevation]
@time = opts[:time]
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
# Convert this point to a REXML::Element.
def to_xml(elem_name = 'trkpt')
pt = Element.new('trkpt')
pt.attributes['lat'] = lat
pt.attributes['lon'] = lon
time_elem = Element.new('time')
time_elem.text = time.xmlschema
pt.elements << time_elem
elev = Element.new('ele')
elev.text = elevation
pt.elements << elev
pt
end
end
end

65
lib/gpx/route.rb 100644
View File

@ -0,0 +1,65 @@
#--
# 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_reader :points, :name, :gpx_file
# Initialize a Route from a REXML::Element.
def initialize(opts = {})
rte_element = opts[:element]
@gpx_file = opts[:gpx_file]
@name = rte_element.elements["child::name"].text
@points = []
XPath.each(rte_element, "child::rtept") do |point|
@points << Point.new(:element => point)
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
# Convert this Route to a REXML::Element.
def to_xml
rte = Element.new('rte')
name_elem = Element.new('name')
name_elem.text = name
rte.elements << name_elem
points.each { |rte_pt| rte.elements << rte_pt.to_xml('rtept') }
rte
end
end
end

217
lib/gpx/segment.rb 100644
View File

@ -0,0 +1,217 @@
#--
# 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 REXML::Element object is passed-in, this will initialize a new
# Segment based on its contents. Otherwise, a blank Segment is created.
def initialize(opts = {})
@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
unless segment_element.is_a?(Text)
XPath.each(segment_element, "child::trkpt") do |trkpt|
pt = TrackPoint.new(:element => trkpt, :segment => self)
@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)
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)
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
# Converts this Segment to a REXML::Element object.
def to_xml
seg = Element.new('trkseg')
points.each { |pt| seg.elements << pt.to_xml }
seg
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)
@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)
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

149
lib/gpx/track.rb 100644
View File

@ -0,0 +1,149 @@
#--
# 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 REXML::Element, 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.elements["child::name"].text rescue "")
XPath.each(trk_element, "child::trkseg") do |seg_element|
seg = Segment.new(:element => seg_element, :track => self)
update_meta_data(seg)
@segments << seg
@points.concat(seg.points) unless seg.nil?
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.find { |s| s.contains_time?(time) }
segment.closest_point(time)
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
# Creates a new REXML::Element from the contents of this instance.
def to_xml
trk= Element.new('trk')
name_elem = Element.new('name')
name_elem.text = name
trk.elements << name_elem
segments.each do |seg|
trk.elements << seg.to_xml
end
trk
end
# Prints out a friendly summary of this track (sans points). Useful for
# debugging and sanity checks.
def to_s
result = "Track \n"
result << "\tName: #{name}\n"
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,73 @@
#--
# 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 = %q{ magvar geoidheight name cmt desc src link sym type fix sat hdop vdop pdop ageofdgpsdata dgpsid extensions }
attr_reader :gpx_file
# Not implemented
def crop(area)
end
# Not implemented
def delete_area(area)
end
# Initializes a waypoint from a REXML::Element.
def initialize(opts = {})
wpt_elem = opts[:element]
super(:element => wpt_elem)
instantiate_with_text_elements(wpt_elem, SUB_ELEMENTS)
@gpx_file = opts[:gpx_file]
end
# Converts a waypoint to a REXML::Element.
def to_xml
wpt = Element.new('wpt')
wpt.attributes['lat'] = lat
wpt.attributes['lon'] = lon
if self.respond_to? :name
name_elem = Element.new('name')
name_elem.text = self.name
wpt.elements << name_elem
end
if self.respond_to? :sym
sym_elem = Element.new('sym')
sym_elem.text = self.sym
wpt.elements << sym_elem
end
if self.respond_to? :ele
elev_elem = Element.new('ele')
elev_elem.text = self.ele
wpt.elements << elev_elem
end
wpt
end
end
end

File diff suppressed because one or more lines are too long

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

View File

@ -0,0 +1,18 @@
require 'test/unit'
require File.dirname(__FILE__) + '/../lib/gpx'
class TestMagellanTrackLog < 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,57 @@
require 'test/unit'
require File.dirname(__FILE__) + '/../lib/gpx'
class TestSegment < 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("Fri Apr 07 18:12:05 UTC 2006", @segment.earliest_point.time.to_s)
assert_equal("Fri Apr 07 19:26:31 UTC 2006", @segment.latest_point.time.to_s)
assert_equal(1334.447, @segment.lowest_point.elevation)
assert_equal(1480.087, @segment.highest_point.elevation)
assert_equal("6.98803359528853", @segment.distance.to_s)
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_equal("4.11422061733046", @segment.distance.to_s)
assert_equal("Fri Apr 07 18:37:21 UTC 2006", @segment.earliest_point.time.to_s)
assert_equal("Fri Apr 07 19:22:32 UTC 2006", @segment.latest_point.time.to_s)
assert_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_equal("3.35967118153605", @segment.distance.to_s)
assert_equal("Fri Apr 07 18:12:05 UTC 2006", @segment.earliest_point.time.to_s)
assert_equal("Fri Apr 07 19:26:31 UTC 2006", @segment.latest_point.time.to_s)
assert_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 File.dirname(__FILE__) + '/../lib/gpx'
class TestTrackFile < 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("myoutput.gpx")
end
end

View File

@ -0,0 +1,65 @@
require 'test/unit'
require File.dirname(__FILE__) + '/../lib/gpx'
class TestTrack < 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( 364, @track.points.size)
assert_equal(8, @track.segments.size)
assert_equal("3.07249668492626", @track.distance.to_s)
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_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
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