Updates courtesy of Gaku Ueda:
* Adding support for GPX 1.0 as well as 1.1 (since libxml namespace parsing was hard-coded to 1.1. previously). * Adding a GPX 1.0 unit test file. * Miscellaneous updates to make it work with Ruby 1.8.6.master
parent
022c7c6813
commit
5aa64f2c3a
|
@ -28,7 +28,6 @@ module GPX
|
|||
class Base
|
||||
include XML
|
||||
|
||||
NS = 'gpx:http://www.topografix.com/GPX/1/1'
|
||||
# This initializer can take an XML::Node and scrape out any text
|
||||
# elements with the names given in the "text_elements" array. Each
|
||||
# element found underneath "parent" with a name in "text_elements" causes
|
||||
|
|
|
@ -22,7 +22,7 @@
|
|||
#++
|
||||
module GPX
|
||||
class GPXFile < Base
|
||||
attr_reader :tracks, :routes, :waypoints, :bounds, :lowest_point, :highest_point, :distance, :duration, :average_speed
|
||||
attr_reader :tracks, :routes, :waypoints, :bounds, :lowest_point, :highest_point, :distance, :duration, :average_speed, :ns
|
||||
|
||||
|
||||
# This initializer can be used to create a new GPXFile from an existing
|
||||
|
@ -50,9 +50,16 @@ module GPX
|
|||
#end
|
||||
gpx_file = gpx_file.name if gpx_file.is_a?(File)
|
||||
reset_meta_data
|
||||
@xml = Document.file(gpx_file)
|
||||
@xml = XML::Document.file(gpx_file)
|
||||
|
||||
bounds_element = (@xml.find("//gpx:gpx/gpx:metadata/gpx:bounds", NS).to_a.first rescue nil)
|
||||
# set XML namespace for XML find
|
||||
if @xml.root.namespace_node
|
||||
@ns = 'gpx:' + @xml.root.namespace_node.href
|
||||
else
|
||||
@ns = 'gpx:http://www.topografix.com/GPX/1/1' # default to GPX 1.1
|
||||
end
|
||||
|
||||
bounds_element = (@xml.find("//gpx:gpx/gpx:metadata/gpx:bounds", @ns).to_a.first rescue nil)
|
||||
if bounds_element
|
||||
@bounds.min_lat = get_bounds_attr_value(bounds_element, %w{ min_lat minlat minLat })
|
||||
@bounds.min_lon = get_bounds_attr_value(bounds_element, %w{ min_lon minlon minLon})
|
||||
|
@ -63,15 +70,15 @@ module GPX
|
|||
end
|
||||
|
||||
@tracks = []
|
||||
@xml.find("//gpx:gpx/gpx:trk", NS).each do |trk|
|
||||
@xml.find("//gpx:gpx/gpx:trk", @ns).each do |trk|
|
||||
trk = Track.new(:element => trk, :gpx_file => self)
|
||||
update_meta_data(trk, get_bounds)
|
||||
@tracks << trk
|
||||
end
|
||||
@waypoints = []
|
||||
@xml.find("//gpx:gpx/gpx:wpt", NS).each { |wpt| @waypoints << Waypoint.new(:element => wpt, :gpx_file => self) }
|
||||
@xml.find("//gpx:gpx/gpx:wpt", @ns).each { |wpt| @waypoints << Waypoint.new(:element => wpt, :gpx_file => self) }
|
||||
@routes = []
|
||||
@xml.find("//gpx:gpx/gpx:rte", NS).each { |rte| @routes << Route.new(:element => rte, :gpx_file => self) }
|
||||
@xml.find("//gpx:gpx/gpx:rte", @ns).each { |rte| @routes << Route.new(:element => rte, :gpx_file => self) }
|
||||
|
||||
@tracks.delete_if { |t| t.empty? }
|
||||
|
||||
|
|
|
@ -32,13 +32,14 @@ module GPX
|
|||
# addition, you can pass an XML element to this initializer, and the
|
||||
# relevant info will be parsed out.
|
||||
def initialize(opts = {:lat => 0.0, :lon => 0.0, :elevation => 0.0, :time => Time.now } )
|
||||
@gpx_file = opts[:gpx_file]
|
||||
if (opts[:element])
|
||||
elem = opts[:element]
|
||||
@lat, @lon = elem["lat"].to_f, elem["lon"].to_f
|
||||
@latr, @lonr = (D_TO_R * @lat), (D_TO_R * @lon)
|
||||
#'-'? yyyy '-' mm '-' dd 'T' hh ':' mm ':' ss ('.' s+)? (zzzzzz)?
|
||||
@time = (Time.xmlschema(elem.find("gpx:time", NS).first.content) rescue nil)
|
||||
@elevation = elem.find("gpx:ele", NS).first.content.to_f unless elem.find("gpx:ele", NS).empty?
|
||||
@time = (Time.xmlschema(elem.find("gpx:time", @gpx_file.ns).first.content) rescue nil)
|
||||
@elevation = elem.find("gpx:ele", @gpx_file.ns).first.content.to_f unless elem.find("gpx:ele", @gpx_file.ns).empty?
|
||||
else
|
||||
@lat = opts[:lat]
|
||||
@lon = opts[:lon]
|
||||
|
|
|
@ -33,9 +33,9 @@ module GPX
|
|||
def initialize(opts = {})
|
||||
rte_element = opts[:element]
|
||||
@gpx_file = opts[:gpx_file]
|
||||
@name = rte_element.find("child::gpx:name", NS).first.content
|
||||
@name = rte_element.find("child::gpx:name", @ns).first.content
|
||||
@points = []
|
||||
rte_element.find("child::gpx:rtept", NS).each do |point|
|
||||
rte_element.find("child::gpx:rtept", @ns).each do |point|
|
||||
@points << Point.new(:element => point)
|
||||
end
|
||||
|
||||
|
|
|
@ -34,6 +34,7 @@ module GPX
|
|||
# If a XML::Node object is passed-in, this will initialize a new
|
||||
# Segment based on its contents. Otherwise, a blank Segment is created.
|
||||
def initialize(opts = {})
|
||||
@gpx_file = opts[:gpx_file]
|
||||
@track = opts[:track]
|
||||
@points = []
|
||||
@earliest_point = nil
|
||||
|
@ -46,8 +47,8 @@ module GPX
|
|||
segment_element = opts[:element]
|
||||
last_pt = nil
|
||||
if segment_element.is_a?(XML::Node)
|
||||
segment_element.find("child::gpx:trkpt", NS).each do |trkpt|
|
||||
pt = TrackPoint.new(:element => trkpt, :segment => self)
|
||||
segment_element.find("child::gpx:trkpt", @gpx_file.ns).each do |trkpt|
|
||||
pt = TrackPoint.new(:element => trkpt, :segment => self, :gpx_file => @gpx_file)
|
||||
unless pt.time.nil?
|
||||
@earliest_point = pt if(@earliest_point.nil? or pt.time < @earliest_point.time)
|
||||
@latest_point = pt if(@latest_point.nil? or pt.time > @latest_point.time)
|
||||
|
|
|
@ -41,9 +41,9 @@ module GPX
|
|||
reset_meta_data
|
||||
if(opts[:element])
|
||||
trk_element = opts[:element]
|
||||
@name = (trk_element.find("child::gpx:name", NS).first.content rescue "")
|
||||
trk_element.find("child::gpx:trkseg", NS).each do |seg_element|
|
||||
seg = Segment.new(:element => seg_element, :track => self)
|
||||
@name = (trk_element.find("child::gpx:name", @gpx_file.ns).first.content rescue "")
|
||||
trk_element.find("child::gpx:trkseg", @gpx_file.ns).each do |seg_element|
|
||||
seg = Segment.new(:element => seg_element, :track => self, :gpx_file => @gpx_file)
|
||||
update_meta_data(seg)
|
||||
@segments << seg
|
||||
@points.concat(seg.points) unless seg.nil?
|
||||
|
|
|
@ -0,0 +1,12 @@
|
|||
require 'test/unit'
|
||||
require File.dirname(__FILE__) + '/../lib/gpx'
|
||||
|
||||
class TestGPX10 < Test::Unit::TestCase
|
||||
GPX_FILE = File.join(File.dirname(__FILE__), "gpx_files/gpx10.gpx")
|
||||
|
||||
def test_read
|
||||
# make sure we can read a GPX 1.0 file
|
||||
@gpx_file = GPX::GPXFile.new(:gpx_file => GPX_FILE)
|
||||
end
|
||||
|
||||
end
|
|
@ -0,0 +1,17 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<gpx version="1.0"
|
||||
creator="GPSBabel - http://www.gpsbabel.org"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns="http://www.topografix.com/GPX/1/0"
|
||||
xsi:schemaLocation="http://www.topografix.com/GPX/1/0 http://www.topografix.com/GPX/1/0/gpx.xsd">
|
||||
<trk>
|
||||
<name>ACTIVE LOG #74</name>
|
||||
<number>82</number>
|
||||
<trkseg>
|
||||
<trkpt lat="37.378388923" lon="-122.063654875">
|
||||
<ele>35.706055</ele>
|
||||
<time>2007-11-23T23:49:43Z</time>
|
||||
</trkpt>
|
||||
</trkseg>
|
||||
</trk>
|
||||
</gpx>
|
Loading…
Reference in New Issue