Moved most stuff over from libxml to hpricot

master
Marc Seeger 2011-11-06 21:37:15 +01:00
parent 2d665f2625
commit 1ec7e02f63
8 changed files with 32 additions and 35 deletions

View File

@ -22,7 +22,7 @@
#++ #++
$:.unshift(File.dirname(__FILE__)) $:.unshift(File.dirname(__FILE__))
require 'rubygems' require 'rubygems'
require 'xml/libxml' require 'hpricot'
require 'date' require 'date'
require 'time' require 'time'
require 'csv' require 'csv'

View File

@ -26,7 +26,6 @@ module GPX
# A common base class which provides a useful initializer method to many # A common base class which provides a useful initializer method to many
# class in the GPX library. # class in the GPX library.
class Base class Base
include XML
# This initializer can take an XML::Node and scrape out any text # This initializer can take an XML::Node and scrape out any text
# elements with the names given in the "text_elements" array. Each # elements with the names given in the "text_elements" array. Each
@ -35,11 +34,11 @@ module GPX
# have to pick out individual text elements in each initializer of each # have to pick out individual text elements in each initializer of each
# class (Route, TrackPoint, Track, etc). Just pass an array of possible # class (Route, TrackPoint, Track, etc). Just pass an array of possible
# attributes to this method. # attributes to this method.
def instantiate_with_text_elements(parent, text_elements, ns) def instantiate_with_text_elements(parent, text_elements)
text_elements.each do |el| text_elements.each do |el|
child_xpath = "gpx:#{el}" child_xpath = "//#{el}"
unless parent.find(child_xpath, ns).empty? unless parent.at(child_xpath).nil?
val = parent.find(child_xpath, ns).first.content val = parent.at(child_xpath).inner_text
self.send("#{el}=", val) self.send("#{el}=", val)
end end
end end

View File

@ -52,20 +52,19 @@ module GPX
# gpx_file = File.open(gpx_file) # gpx_file = File.open(gpx_file)
#end #end
gpx_file = gpx_file.name if gpx_file.is_a?(File) gpx_file = gpx_file.name if gpx_file.is_a?(File)
@xml = XML::Document.file(gpx_file) @xml = Hpricot(File.open(gpx_file))
else else
parser = XML::Parser.string(opts[:gpx_data]) @xml = Hpricot(opts[:gpx_data])
@xml = parser.parse
end end
# set XML namespace for XML find # set XML namespace for XML find
if @xml.root.namespaces.namespace #if @xml.root.namespaces.namespace
@ns = 'gpx:' + @xml.root.namespaces.namespace.href # @ns = 'gpx:' + @xml.root.namespaces.namespace.href
else #else
@ns = 'gpx:http://www.topografix.com/GPX/1/1' # default to GPX 1.1 # @ns = 'gpx:http://www.topografix.com/GPX/1/1' # default to GPX 1.1
end #end
reset_meta_data reset_meta_data
bounds_element = (@xml.find("//gpx:gpx/gpx:metadata/gpx:bounds", @ns).to_a.first rescue nil) bounds_element = (@xml.at("//metadata/bounds") rescue nil)
if bounds_element if bounds_element
@bounds.min_lat = get_bounds_attr_value(bounds_element, %w{ min_lat minlat minLat }) @bounds.min_lat = get_bounds_attr_value(bounds_element, %w{ min_lat minlat minLat })
@bounds.min_lon = get_bounds_attr_value(bounds_element, %w{ min_lon minlon minLon}) @bounds.min_lon = get_bounds_attr_value(bounds_element, %w{ min_lon minlon minLon})
@ -75,20 +74,18 @@ module GPX
get_bounds = true get_bounds = true
end end
@time = Time.parse(@xml.find("//gpx:gpx/gpx:metadata/gpx:time", @ns).first.content) rescue nil @time = Time.parse(@xml.at("//metadata/time").inner_text) rescue nil
@name = @xml.find("//gpx:gpx/gpx:metadata/gpx:name", @ns).first.content rescue nil @name = @xml.at("//metadata/name").inner_text rescue nil
@tracks = [] @tracks = []
@xml.find("//gpx:gpx/gpx:trk", @ns).each do |trk| @xml.search("//trk").each do |trk|
trk = Track.new(:element => trk, :gpx_file => self) trk = Track.new(:element => trk, :gpx_file => self)
update_meta_data(trk, get_bounds) update_meta_data(trk, get_bounds)
@tracks << trk @tracks << trk
end end
@waypoints = [] @waypoints = []
@xml.find("//gpx:gpx/gpx:wpt", @ns).each { |wpt| @waypoints << Waypoint.new(:element => wpt, :gpx_file => self) } @xml.search("//wpt").each { |wpt| @waypoints << Waypoint.new(:element => wpt, :gpx_file => self) }
@routes = [] @routes = []
@xml.find("//gpx:gpx/gpx:rte", @ns).each { |rte| @routes << Route.new(:element => rte, :gpx_file => self) } @xml.search("//rte").each { |rte| @routes << Route.new(:element => rte, :gpx_file => self) }
@tracks.delete_if { |t| t.empty? } @tracks.delete_if { |t| t.empty? }
calculate_duration calculate_duration
@ -222,7 +219,7 @@ module GPX
doc = Document.new doc = Document.new
doc.root = Node.new('gpx') doc.root = Node.new('gpx')
gpx_elem = doc.root gpx_elem = doc.root
gpx_elem['xmlns:xsi'] = "http://www.w3.org/2001/XMLSchema-instance" gpx_elem['xsi'] = "http://www.w3.org/2001/XMLSchema-instance"
@version = '1.1' if (@version.nil? || !(['1.0', '1.1'].include?(@version))) # default to version 1.1 of the schema (only version 1.0 and 1.1 of the schema exist) @version = '1.1' if (@version.nil? || !(['1.0', '1.1'].include?(@version))) # default to version 1.1 of the schema (only version 1.0 and 1.1 of the schema exist)
version_dir = @version.gsub('.','/') version_dir = @version.gsub('.','/')
gpx_elem['xmlns'] = @ns || "http://www.topografix.com/GPX/#{version_dir}" gpx_elem['xmlns'] = @ns || "http://www.topografix.com/GPX/#{version_dir}"

View File

@ -38,9 +38,9 @@ module GPX
@lat, @lon = elem["lat"].to_f, elem["lon"].to_f @lat, @lon = elem["lat"].to_f, elem["lon"].to_f
@latr, @lonr = (D_TO_R * @lat), (D_TO_R * @lon) @latr, @lonr = (D_TO_R * @lat), (D_TO_R * @lon)
#'-'? yyyy '-' mm '-' dd 'T' hh ':' mm ':' ss ('.' s+)? (zzzzzz)? #'-'? yyyy '-' mm '-' dd 'T' hh ':' mm ':' ss ('.' s+)? (zzzzzz)?
@time = (Time.xmlschema(elem.find("gpx:time", @gpx_file.ns).first.content) rescue nil) @time = (Time.xmlschema(elem.at("time").inner_text) rescue nil)
@elevation = elem.find("gpx:ele", @gpx_file.ns).first.content.to_f unless elem.find("gpx:ele", @gpx_file.ns).empty? @elevation = elem.at("ele").inner_text.to_f unless elem.at("ele").nil?
@speed = elem.find("gpx:speed", @gpx_file.ns).first.content.to_f unless elem.find("gpx:speed", @gpx_file.ns).empty? @speed = elem.at("speed").inner_text.to_f unless elem.at("speed").nil?
else else
@lat = opts[:lat] @lat = opts[:lat]
@lon = opts[:lon] @lon = opts[:lon]

View File

@ -34,9 +34,9 @@ module GPX
if(opts[:gpx_file] and opts[:element]) if(opts[:gpx_file] and opts[:element])
rte_element = opts[:element] rte_element = opts[:element]
@gpx_file = opts[:gpx_file] @gpx_file = opts[:gpx_file]
@name = rte_element.find("child::gpx:name", @gpx_file.ns).first.content @name = rte_element.at("//name").inner_text
@points = [] @points = []
rte_element.find("child::gpx:rtept", @gpx_file.ns).each do |point| rte_element.search("//rtept").each do |point|
@points << Point.new(:element => point, :gpx_file => @gpx_file) @points << Point.new(:element => point, :gpx_file => @gpx_file)
end end
else else

View File

@ -46,8 +46,8 @@ module GPX
if(opts[:element]) if(opts[:element])
segment_element = opts[:element] segment_element = opts[:element]
last_pt = nil last_pt = nil
if segment_element.is_a?(XML::Node) if segment_element.is_a?(Hpricot::Elem)
segment_element.find("child::gpx:trkpt", @gpx_file.ns).each do |trkpt| segment_element.search("//trkpt").each do |trkpt|
pt = TrackPoint.new(:element => trkpt, :segment => self, :gpx_file => @gpx_file) pt = TrackPoint.new(:element => trkpt, :segment => self, :gpx_file => @gpx_file)
unless pt.time.nil? unless pt.time.nil?
@earliest_point = pt if(@earliest_point.nil? or pt.time < @earliest_point.time) @earliest_point = pt if(@earliest_point.nil? or pt.time < @earliest_point.time)

View File

@ -41,8 +41,8 @@ module GPX
reset_meta_data reset_meta_data
if(opts[:element]) if(opts[:element])
trk_element = opts[:element] trk_element = opts[:element]
@name = (trk_element.find("child::gpx:name", @gpx_file.ns).first.content rescue "") @name = (trk_element.at("//name").inner_text rescue "")
trk_element.find("child::gpx:trkseg", @gpx_file.ns).each do |seg_element| trk_element.search("//trkseg").each do |seg_element|
seg = Segment.new(:element => seg_element, :track => self, :gpx_file => @gpx_file) seg = Segment.new(:element => seg_element, :track => self, :gpx_file => @gpx_file)
update_meta_data(seg) update_meta_data(seg)
@segments << seg @segments << seg
@ -69,8 +69,8 @@ module GPX
# correlating things like pictures, video, and other events, if you are # correlating things like pictures, video, and other events, if you are
# working with a timestamp. # working with a timestamp.
def closest_point(time) def closest_point(time)
segment = segments.find { |s| s.contains_time?(time) } segment = segments.select { |s| s.contains_time?(time) }
segment.closest_point(time) segment.first
end end
# Removes all points outside of a given area and updates the meta data. # Removes all points outside of a given area and updates the meta data.
@ -114,6 +114,7 @@ module GPX
# Prints out a friendly summary of this track (sans points). Useful for # Prints out a friendly summary of this track (sans points). Useful for
# debugging and sanity checks. # debugging and sanity checks.
def to_s def to_s
result = "Track \n" result = "Track \n"
result << "\tName: #{name}\n" result << "\tName: #{name}\n"

View File

@ -46,7 +46,7 @@ module GPX
wpt_elem = opts[:element] wpt_elem = opts[:element]
@gpx_file = opts[:gpx_file] @gpx_file = opts[:gpx_file]
super(:element => wpt_elem, :gpx_file => @gpx_file) super(:element => wpt_elem, :gpx_file => @gpx_file)
instantiate_with_text_elements(wpt_elem, SUB_ELEMENTS, @gpx_file.ns) instantiate_with_text_elements(wpt_elem, SUB_ELEMENTS)
else else
opts.each do |key, value| opts.each do |key, value|
assignment_method = "#{key}=" assignment_method = "#{key}="