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
84
85
86
87
88
89
90
91
92
93
94
# 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
      gpx_file = gpx_file.name if gpx_file.is_a?(File) 
      
      @xml = XML::Document.file(gpx_file)
      
      # 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})
         @bounds.max_lat = get_bounds_attr_value(bounds_element, %w{ max_lat maxlat maxLat})
         @bounds.max_lon = get_bounds_attr_value(bounds_element, %w{ max_lon maxlon maxLon})
      else
         get_bounds = true
      end
      
      @tracks = [] 
      @xml.find("//gpx:gpx/gpx:trk", @ns).each do |trk| 
         trk = Track.new(:element => trk, :gpx_file => self) 
         (trk, get_bounds)
         @tracks << trk
      end
      @waypoints = [] 
      @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) }

      @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.



121
122
123
# File 'lib/gpx/gpx_file.rb', line 121

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.



107
108
109
# File 'lib/gpx/gpx_file.rb', line 107

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

#nsObject (readonly)

Returns the value of attribute ns.



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

def ns
  @ns
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.



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

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.



158
159
160
161
162
163
164
165
166
167
168
169
170
171
# File 'lib/gpx/gpx_file.rb', line 158

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

#get_bounds_attr_value(el, possible_names) ⇒ Object



96
97
98
99
100
101
102
103
# File 'lib/gpx/gpx_file.rb', line 96

def get_bounds_attr_value(el, possible_names)
   result = nil
   possible_names.each do |name|
      result = el[name]
      break unless result.nil?
   end
   return (result.to_f rescue nil)
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.



175
176
177
178
179
180
# File 'lib/gpx/gpx_file.rb', line 175

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.



186
187
188
189
190
191
# File 'lib/gpx/gpx_file.rb', line 186

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.



195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
# File 'lib/gpx/gpx_file.rb', line 195

def write(filename)

   doc = Document.new
   doc.root = Node.new('gpx')
   gpx_elem = doc.root
   gpx_elem['xmlns:xsi'] = "http://www.w3.org/2001/XMLSchema-instance" 
   gpx_elem['xmlns'] = "http://www.topografix.com/GPX/1/1" 
   gpx_elem['version'] = "1.1" 
   gpx_elem['creator'] = "GPX RubyGem 0.1 Copyright 2006 Doug Fales -- http://walkingboss.com" 
   gpx_elem['xsi:schemaLocation'] = "http://www.topografix.com/GPX/1/1 http://www.topografix.com/GPX/1/1/gpx.xsd"

    = Node.new('metadata')
   name_elem = Node.new('name')
   name_elem << File.basename(filename)
    << name_elem

   time_elem = Node.new('time')
   time_elem << Time.now.xmlschema
    << time_elem

    << bounds.to_xml

   gpx_elem << 

   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?

   doc.save(filename, true)
end