Class: GPX::GPXFile

Inherits:
Base
  • Object
show all
Defined in:
lib/gpx/gpx_file.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods inherited from Base

#instantiate_with_text_elements

Constructor Details

#initialize(opts = {}) ⇒ GPXFile

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])


43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
# File 'lib/gpx/gpx_file.rb', line 43

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
      
      @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) 
         (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
      
      opts.each { |attr_name, value| instance_variable_set("@#{attr_name.to_s}", value) }
      unless(@tracks.nil? or @tracks.size.zero?)
         @tracks.each { |trk| (trk) }
         calculate_duration
      end
   end
end

Instance Attribute Details

#average_speed(opts = { :units => 'kilometers' }) ⇒ Object (readonly)

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.



101
102
103
# File 'lib/gpx/gpx_file.rb', line 101

def average_speed
  @average_speed
end

#boundsObject (readonly)

Returns the value of attribute bounds.



25
26
27
# File 'lib/gpx/gpx_file.rb', line 25

def bounds
  @bounds
end

#distance(opts = { :units => 'kilometers' }) ⇒ Object (readonly)

Returns the distance, in kilometers, meters, or miles, of all of the tracks and segments contained in this GPXFile.



87
88
89
# File 'lib/gpx/gpx_file.rb', line 87

def distance
  @distance
end

#durationObject (readonly)

Returns the value of attribute duration.



25
26
27
# File 'lib/gpx/gpx_file.rb', line 25

def duration
  @duration
end

#highest_pointObject (readonly)

Returns the value of attribute highest_point.



25
26
27
# File 'lib/gpx/gpx_file.rb', line 25

def highest_point
  @highest_point
end

#lowest_pointObject (readonly)

Returns the value of attribute lowest_point.



25
26
27
# File 'lib/gpx/gpx_file.rb', line 25

def lowest_point
  @lowest_point
end

#routesObject (readonly)

Returns the value of attribute routes.



25
26
27
# File 'lib/gpx/gpx_file.rb', line 25

def routes
  @routes
end

#tracksObject (readonly)

Returns the value of attribute tracks.



25
26
27
# File 'lib/gpx/gpx_file.rb', line 25

def tracks
  @tracks
end

#waypointsObject (readonly)

Returns the value of attribute waypoints.



25
26
27
# File 'lib/gpx/gpx_file.rb', line 25

def waypoints
  @waypoints
end

Instance Method Details

#crop(area) ⇒ Object

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.



116
117
118
119
120
121
122
123
124
125
126
127
128
129
# File 'lib/gpx/gpx_file.rb', line 116

def crop(area)
   
   keep_tracks = []
   tracks.each do |trk| 
      trk.crop(area) 
      unless trk.empty?
         (trk)
         keep_tracks << trk 
      end
   end
   @tracks = keep_tracks
   routes.each { |rte| rte.crop(area) }
   waypoints.each { |wpt| wpt.crop(area) }
end

#delete_area(area) ⇒ Object

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.



138
139
140
141
142
143
144
145
146
147
148
149
150
151
# File 'lib/gpx/gpx_file.rb', line 138

def delete_area(area)
   
   keep_tracks = []
   tracks.each do |trk| 
      trk.delete_area(area) 
      unless trk.empty?
         (trk)
         keep_tracks << trk 
      end
   end
   @tracks =  keep_tracks
   routes.each { |rte| rte.delete_area(area) }
   waypoints.each { |wpt| wpt.delete_area(area) }
end

#reset_meta_dataObject

Resets the meta data for this GPX file. Meta data includes the bounds, the high and low points, and the distance.



155
156
157
158
159
160
# File 'lib/gpx/gpx_file.rb', line 155

def 
   @bounds = Bounds.new
   @highest_point = nil
   @lowest_point = nil
   @distance = 0.0
end

#update_meta_data(trk, get_bounds = true) ⇒ Object

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.



166
167
168
169
170
171
# File 'lib/gpx/gpx_file.rb', line 166

def (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

#write(filename) ⇒ Object

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.



175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
# File 'lib/gpx/gpx_file.rb', line 175

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"

    = Element.new('metadata')
   name_elem = Element.new('name')
   name_elem.text = File.basename(filename)
   .elements << name_elem

   time_elem = Element.new('time')
   time_elem.text = Time.now.xmlschema
   .elements << time_elem

   .elements << bounds.to_xml

   gpx_elem.elements << 

   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