Sometime back in May I wrote some utilities to manage the GPX files from my Royaltek RGM 3800. I’ve used rexml to parse the XML file. Now after I’ve read about libxml for ruby I’ve had tried this little gem and I have registered that parsing the GPX file is significantly faster.
This was the old code from May with rexml:
def parse_gpx(file)
require 'rexml/document'
include REXML
a = Array.new
doc = Document.new File.new(file)
i =
doc.elements.each("gpx/trk/trkseg/trkpt") { |e|
a << {:time => Time.parse(e.elements["time"].to_a.first.to_s)}
a[i][:lat] = e.attributes["lat"].to_s;
a[i][:lon] = e.attributes["lon"].to_s;
a[i][:ele] = e.elements["ele"].to_a.first.to_s
a[i][:speed] = e.elements["speed"].to_a.first.to_s
a[i][:course] = e.elements["course"].to_a.first.to_s
a[i][:fix] = e.elements["fix"].to_a.first.to_s
i += 1
}
return a
end
require 'rexml/document'
include REXML
a = Array.new
doc = Document.new File.new(file)
i =
doc.elements.each("gpx/trk/trkseg/trkpt") { |e|
a << {:time => Time.parse(e.elements["time"].to_a.first.to_s)}
a[i][:lat] = e.attributes["lat"].to_s;
a[i][:lon] = e.attributes["lon"].to_s;
a[i][:ele] = e.elements["ele"].to_a.first.to_s
a[i][:speed] = e.elements["speed"].to_a.first.to_s
a[i][:course] = e.elements["course"].to_a.first.to_s
a[i][:fix] = e.elements["fix"].to_a.first.to_s
i += 1
}
return a
end
And this is the code using libxml which I wrote after learning a little bit more ruby 😉
def parse_gpx(file)
require 'rubygems'
require 'libxml'
a = Array.new
doc = LibXML::XML::Document.file(file)
nodes = doc.find '/ns:gpx/ns:trk/ns:trkseg/ns:trkpt',
"ns:http://www.topografix.com/GPX/1/0"
nodes.each do |e|
a << {:lat => e[:lat], :lon => e[:lon]}
node = a.last
e.each do |n|
node[n.name.to_sym] = n.children.to_s if n.children?
end
node[:time] = Time.parse(node[:time])
end
return a
end
require 'rubygems'
require 'libxml'
a = Array.new
doc = LibXML::XML::Document.file(file)
nodes = doc.find '/ns:gpx/ns:trk/ns:trkseg/ns:trkpt',
"ns:http://www.topografix.com/GPX/1/0"
nodes.each do |e|
a << {:lat => e[:lat], :lon => e[:lon]}
node = a.last
e.each do |n|
node[n.name.to_sym] = n.children.to_s if n.children?
end
node[:time] = Time.parse(node[:time])
end
return a
end
This code is part of a little script which I use to combine data from the GPS logger device with the data which is provided by my cycle computer (heart rate, barometric height, cadence, speed etc.).