Replace Hpricot with Nokogiri
parent
b1d18e8261
commit
917c437f94
|
@ -18,5 +18,5 @@ Gem::Specification.new do |s|
|
|||
|
||||
s.homepage = "http://dougfales.github.com/gpx/"
|
||||
s.rubyforge_project = "gpx"
|
||||
s.add_dependency 'hpricot'
|
||||
s.add_dependency 'nokogiri'
|
||||
end
|
||||
|
|
10
lib/gpx.rb
10
lib/gpx.rb
|
@ -20,12 +20,12 @@
|
|||
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
#++
|
||||
$:.unshift(File.dirname(__FILE__))
|
||||
require 'rubygems'
|
||||
require 'hpricot'
|
||||
require 'date'
|
||||
|
||||
require 'time'
|
||||
require 'csv'
|
||||
require 'nokogiri'
|
||||
|
||||
require 'gpx/version'
|
||||
|
||||
require 'gpx/gpx'
|
||||
require 'gpx/gpx_file'
|
||||
require 'gpx/bounds'
|
||||
|
|
|
@ -43,15 +43,6 @@ module GPX
|
|||
(min_lon + distance)
|
||||
end
|
||||
|
||||
def to_xml
|
||||
bnd = XML::Node.new('bounds')
|
||||
bnd['minlat'] = min_lat.to_s
|
||||
bnd['minlon'] = min_lon.to_s
|
||||
bnd['maxlat'] = max_lat.to_s
|
||||
bnd['maxlon'] = max_lon.to_s
|
||||
bnd
|
||||
end
|
||||
|
||||
# Returns true if the pt is within these bounds.
|
||||
def contains?(pt)
|
||||
(pt.lat >= min_lat and pt.lat <= max_lat and pt.lon >= min_lon and pt.lon <= max_lon)
|
||||
|
|
|
@ -34,7 +34,7 @@ module GPX
|
|||
# attributes to this method.
|
||||
def instantiate_with_text_elements(parent, text_elements)
|
||||
text_elements.each do |el|
|
||||
child_xpath = "//#{el}"
|
||||
child_xpath = "#{el}"
|
||||
unless parent.at(child_xpath).nil?
|
||||
val = parent.at(child_xpath).inner_text
|
||||
self.send("#{el}=", val)
|
||||
|
|
|
@ -22,7 +22,7 @@
|
|||
#++
|
||||
module GPX
|
||||
class GPXFile < Base
|
||||
attr_accessor :tracks, :routes, :waypoints, :bounds, :lowest_point, :highest_point, :duration, :ns, :version, :time, :name
|
||||
attr_accessor :tracks, :routes, :waypoints, :bounds, :lowest_point, :highest_point, :duration, :ns, :time, :name
|
||||
|
||||
|
||||
# This initializer can be used to create a new GPXFile from an existing
|
||||
|
@ -47,24 +47,14 @@ module GPX
|
|||
if(opts[:gpx_file] or opts[:gpx_data])
|
||||
if opts[:gpx_file]
|
||||
gpx_file = opts[:gpx_file]
|
||||
#case gpx_file
|
||||
#when String
|
||||
# gpx_file = File.open(gpx_file)
|
||||
#end
|
||||
gpx_file = gpx_file.name if gpx_file.is_a?(File)
|
||||
@xml = Hpricot(File.open(gpx_file))
|
||||
gpx_file = File.open(gpx_file) unless gpx_file.is_a?(File)
|
||||
@xml = Nokogiri::XML(gpx_file)
|
||||
else
|
||||
@xml = Hpricot(opts[:gpx_data])
|
||||
@xml = Nokogiri::XML(opts[:gpx_data])
|
||||
end
|
||||
# set XML namespace for XML find
|
||||
#if @xml.root.namespaces.namespace
|
||||
# @ns = 'gpx:' + @xml.root.namespaces.namespace.href
|
||||
#else
|
||||
# @ns = 'gpx:http://www.topografix.com/GPX/1/1' # default to GPX 1.1
|
||||
#end
|
||||
|
||||
reset_meta_data
|
||||
bounds_element = (@xml.at("//metadata/bounds") rescue nil)
|
||||
bounds_element = (@xml.at("metadata/bounds") rescue nil)
|
||||
if bounds_element
|
||||
@bounds.min_lat = get_bounds_attr_value(bounds_element, %w{ min_lat minlat minLat })
|
||||
@bounds.min_lon = get_bounds_attr_value(bounds_element, %w{ min_lon minlon minLon})
|
||||
|
@ -74,18 +64,18 @@ module GPX
|
|||
get_bounds = true
|
||||
end
|
||||
|
||||
@time = Time.parse(@xml.at("//metadata/time").inner_text) rescue nil
|
||||
@name = @xml.at("//metadata/name").inner_text rescue nil
|
||||
@time = Time.parse(@xml.at("metadata/time").inner_text) rescue nil
|
||||
@name = @xml.at("metadata/name").inner_text rescue nil
|
||||
@tracks = []
|
||||
@xml.search("//trk").each do |trk|
|
||||
@xml.search("trk").each do |trk|
|
||||
trk = Track.new(:element => trk, :gpx_file => self)
|
||||
update_meta_data(trk, get_bounds)
|
||||
@tracks << trk
|
||||
end
|
||||
@waypoints = []
|
||||
@xml.search("//wpt").each { |wpt| @waypoints << Waypoint.new(:element => wpt, :gpx_file => self) }
|
||||
@xml.search("wpt").each { |wpt| @waypoints << Waypoint.new(:element => wpt, :gpx_file => self) }
|
||||
@routes = []
|
||||
@xml.search("//rte").each { |rte| @routes << Route.new(:element => rte, :gpx_file => self) }
|
||||
@xml.search("rte").each { |rte| @routes << Route.new(:element => rte, :gpx_file => self) }
|
||||
@tracks.delete_if { |t| t.empty? }
|
||||
|
||||
calculate_duration
|
||||
|
@ -205,52 +195,83 @@ module GPX
|
|||
@time = Time.now if(@time.nil? or update_time)
|
||||
@name ||= File.basename(filename)
|
||||
doc = generate_xml_doc
|
||||
doc.save(filename, :indent => true)
|
||||
File.open(filename, 'w') { |f| f.write(doc.to_xml) }
|
||||
end
|
||||
|
||||
def to_s(update_time = true)
|
||||
@time = Time.now if(@time.nil? or update_time)
|
||||
doc = generate_xml_doc
|
||||
doc.to_s
|
||||
doc.to_xml
|
||||
end
|
||||
|
||||
def inspect
|
||||
"<#{self.class.name}:...>"
|
||||
end
|
||||
|
||||
private
|
||||
def generate_xml_doc
|
||||
doc = Document.new
|
||||
doc.root = Node.new('gpx')
|
||||
gpx_elem = doc.root
|
||||
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_dir = @version.gsub('.','/')
|
||||
gpx_elem['xmlns'] = @ns || "http://www.topografix.com/GPX/#{version_dir}"
|
||||
gpx_elem['version'] = "#{@version}"
|
||||
gpx_elem['creator'] = "GPX RubyGem #{GPX::VERSION} Copyright 2006-2009 Doug Fales -- http://gpx.rubyforge.org/"
|
||||
gpx_elem['xsi:schemaLocation'] = "http://www.topografix.com/GPX/#{version_dir} http://www.topografix.com/GPX/#{version_dir}/gpx.xsd"
|
||||
version = '1.1'
|
||||
version_dir = version.gsub('.','/')
|
||||
|
||||
# setup the metadata elements
|
||||
name_elem = Node.new('name')
|
||||
name_elem << @name
|
||||
time_elem = Node.new('time')
|
||||
time_elem << @time.xmlschema
|
||||
doc = Nokogiri::XML::Builder.new do |xml|
|
||||
xml.gpx(
|
||||
'xsi' => "http://www.w3.org/2001/XMLSchema-instance",
|
||||
'version' => version.to_s,
|
||||
'creator' => "GPX RubyGem #{GPX::VERSION}",
|
||||
'xsi:schemaLocation' => "http://www.topografix.com/GPX/#{version_dir} http://www.topografix.com/GPX/#{version_dir}/gpx.xsd") \
|
||||
{
|
||||
xml.metadata {
|
||||
xml.name @name
|
||||
xml.time @time.xmlschema
|
||||
xml.bound(
|
||||
minlat: bounds.min_lat,
|
||||
minlon: bounds.min_lon,
|
||||
maxlat: bounds.max_lat,
|
||||
maxlon: bounds.max_lon,
|
||||
)
|
||||
}
|
||||
|
||||
# version 1.0 of the schema doesn't support the metadata element, so push them straight to the root 'gpx' element
|
||||
if (@version == '1.0') then
|
||||
gpx_elem << name_elem
|
||||
gpx_elem << time_elem
|
||||
gpx_elem << bounds.to_xml
|
||||
else
|
||||
meta_data_elem = Node.new('metadata')
|
||||
meta_data_elem << name_elem
|
||||
meta_data_elem << time_elem
|
||||
meta_data_elem << bounds.to_xml
|
||||
gpx_elem << meta_data_elem
|
||||
end
|
||||
tracks.each do |t|
|
||||
xml.trk {
|
||||
xml.name t.name
|
||||
|
||||
tracks.each { |t| gpx_elem << t.to_xml } unless tracks.nil?
|
||||
waypoints.each { |w| gpx_elem << w.to_xml } unless waypoints.nil?
|
||||
routes.each { |r| gpx_elem << r.to_xml } unless routes.nil?
|
||||
t.segments.each do |seg|
|
||||
xml.trkseg {
|
||||
seg.points.each do |p|
|
||||
xml.trkpt(lat: p.lat, lon: p.lon) {
|
||||
xml.time p.time.xmlschema unless p.time.nil?
|
||||
xml.ele p.elevation unless p.elevation.nil?
|
||||
}
|
||||
end
|
||||
}
|
||||
end
|
||||
}
|
||||
end unless tracks.nil?
|
||||
|
||||
return doc
|
||||
waypoints.each do |w|
|
||||
xml.wpt(lat: w.lat, lon: w.lon) {
|
||||
Waypoint::SUB_ELEMENTS.each do |sub_elem|
|
||||
xml.send(sub_elem, w.send(sub_elem)) if w.respond_to?(sub_elem) && !w.send(sub_elem).nil?
|
||||
end
|
||||
}
|
||||
end unless waypoints.nil?
|
||||
|
||||
routes.each do |r|
|
||||
xml.rte {
|
||||
xml.name r.name
|
||||
|
||||
r.points.each do |p|
|
||||
xml.rtept(lat: p.lat, lon: p.lon) {
|
||||
xml.time p.time.xmlschema unless p.time.nil?
|
||||
xml.ele p.elevation unless p.elevation.nil?
|
||||
}
|
||||
end
|
||||
}
|
||||
end unless routes.nil?
|
||||
}
|
||||
end
|
||||
|
||||
return doc
|
||||
end
|
||||
|
||||
# Calculates and sets the duration attribute by subtracting the time on
|
||||
|
|
|
@ -20,6 +20,9 @@
|
|||
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
#++
|
||||
|
||||
require 'csv'
|
||||
|
||||
module GPX
|
||||
|
||||
# This class will parse the lat/lon and time data from a Magellan track log,
|
||||
|
|
|
@ -87,22 +87,5 @@ module GPX
|
|||
@lonr = (longitude * D_TO_R)
|
||||
@lon = longitude
|
||||
end
|
||||
|
||||
# Convert this point to a XML::Node.
|
||||
def to_xml(elem_name = 'trkpt')
|
||||
pt = Node.new(elem_name)
|
||||
pt['lat'] = lat.to_s
|
||||
pt['lon'] = lon.to_s
|
||||
unless time.nil?
|
||||
time_elem = Node.new('time')
|
||||
time_elem << time.xmlschema
|
||||
pt << time_elem
|
||||
end
|
||||
elev = Node.new('ele')
|
||||
elev << elevation
|
||||
pt << elev
|
||||
pt
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
|
|
|
@ -34,9 +34,9 @@ module GPX
|
|||
if(opts[:gpx_file] and opts[:element])
|
||||
rte_element = opts[:element]
|
||||
@gpx_file = opts[:gpx_file]
|
||||
@name = rte_element.at("//name").inner_text
|
||||
@name = rte_element.at("name").inner_text
|
||||
@points = []
|
||||
rte_element.search("//rtept").each do |point|
|
||||
rte_element.search("rtept").each do |point|
|
||||
@points << Point.new(:element => point, :gpx_file => @gpx_file)
|
||||
end
|
||||
else
|
||||
|
@ -55,16 +55,5 @@ module GPX
|
|||
def delete_area(area)
|
||||
points.delete_if{ |pt| area.contains? pt }
|
||||
end
|
||||
|
||||
# Convert this Route to a XML::Node.
|
||||
def to_xml
|
||||
rte = Node.new('rte')
|
||||
name_elem = Node.new('name')
|
||||
name_elem << name
|
||||
rte << name_elem
|
||||
points.each { |rte_pt| rte << rte_pt.to_xml('rtept') }
|
||||
rte
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
|
|
|
@ -46,8 +46,8 @@ module GPX
|
|||
if(opts[:element])
|
||||
segment_element = opts[:element]
|
||||
last_pt = nil
|
||||
if segment_element.is_a?(Hpricot::Elem)
|
||||
segment_element.search("//trkpt").each do |trkpt|
|
||||
if segment_element.is_a?(Nokogiri::XML::Node)
|
||||
segment_element.search("trkpt").each do |trkpt|
|
||||
pt = TrackPoint.new(:element => trkpt, :segment => self, :gpx_file => @gpx_file)
|
||||
unless pt.time.nil?
|
||||
@earliest_point = pt if(@earliest_point.nil? or pt.time < @earliest_point.time)
|
||||
|
@ -132,13 +132,6 @@ module GPX
|
|||
(points.nil? or (points.size == 0))
|
||||
end
|
||||
|
||||
# Converts this Segment to a XML::Node object.
|
||||
def to_xml
|
||||
seg = Node.new('trkseg')
|
||||
points.each { |pt| seg << pt.to_xml }
|
||||
seg
|
||||
end
|
||||
|
||||
# Prints out a nice summary of this Segment.
|
||||
def to_s
|
||||
result = "Track Segment\n"
|
||||
|
|
|
@ -41,8 +41,8 @@ module GPX
|
|||
reset_meta_data
|
||||
if(opts[:element])
|
||||
trk_element = opts[:element]
|
||||
@name = (trk_element.at("//name").inner_text rescue "")
|
||||
trk_element.search("//trkseg").each do |seg_element|
|
||||
@name = (trk_element.at("name").inner_text rescue "")
|
||||
trk_element.search("trkseg").each do |seg_element|
|
||||
seg = Segment.new(:element => seg_element, :track => self, :gpx_file => @gpx_file)
|
||||
update_meta_data(seg)
|
||||
@segments << seg
|
||||
|
@ -100,18 +100,6 @@ module GPX
|
|||
(points.nil? or points.size.zero?)
|
||||
end
|
||||
|
||||
# Creates a new XML::Node from the contents of this instance.
|
||||
def to_xml
|
||||
trk= Node.new('trk')
|
||||
name_elem = Node.new('name')
|
||||
name_elem << name
|
||||
trk << name_elem
|
||||
segments.each do |seg|
|
||||
trk << seg.to_xml
|
||||
end
|
||||
trk
|
||||
end
|
||||
|
||||
# Prints out a friendly summary of this track (sans points). Useful for
|
||||
# debugging and sanity checks.
|
||||
|
||||
|
|
|
@ -27,7 +27,7 @@ module GPX
|
|||
# not seen much use yet, since WalkingBoss does not use waypoints right now.
|
||||
class Waypoint < Point
|
||||
|
||||
SUB_ELEMENTS = %w{ magvar geoidheight name cmt desc src link sym type fix sat hdop vdop pdop ageofdgpsdata dgpsid extensions }
|
||||
SUB_ELEMENTS = %w{ magvar geoidheight name cmt desc src link sym type fix sat hdop vdop pdop ageofdgpsdata dgpsid extensions ele}
|
||||
|
||||
attr_reader :gpx_file
|
||||
SUB_ELEMENTS.each { |sub_el| attr_accessor sub_el.to_sym }
|
||||
|
@ -72,25 +72,5 @@ module GPX
|
|||
end
|
||||
result
|
||||
end
|
||||
|
||||
# Converts a waypoint to a XML::Node.
|
||||
def to_xml(elem_name = 'wpt')
|
||||
wpt = Node.new(elem_name)
|
||||
wpt['lat'] = lat.to_s
|
||||
wpt['lon'] = lon.to_s
|
||||
SUB_ELEMENTS.each do |sub_element_name|
|
||||
if(self.respond_to?(sub_element_name) and (!self.send(sub_element_name).nil?))
|
||||
sub_elem_node = Node.new(sub_element_name)
|
||||
sub_elem_node << self.send(sub_element_name)
|
||||
wpt << sub_elem_node
|
||||
end
|
||||
end
|
||||
unless(self.elevation.nil?)
|
||||
ele_node = Node.new('ele')
|
||||
ele_node << self.elevation
|
||||
wpt << ele_node
|
||||
end
|
||||
wpt
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
Loading…
Reference in New Issue