Class: GPX::Segment

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

Overview

A segment is the basic container in a GPX file. A Segment contains points (in this lib, they’re called TrackPoints). A Track contains Segments. An instance of Segment knows its highest point, lowest point, earliest and latest points, distance, and bounds.

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods inherited from Base

#instantiate_with_text_elements

Constructor Details

#initialize(opts = {}) ⇒ Segment

If a XML::Node object is passed-in, this will initialize a new Segment based on its contents. Otherwise, a blank Segment is created.



36
37
38
39
40
41
42
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
# File 'lib/gpx/segment.rb', line 36

def initialize(opts = {})
   @gpx_file = opts[:gpx_file]
   @track = opts[:track]
   @points = []
   @earliest_point = nil
   @latest_point = nil
   @highest_point = nil
   @lowest_point = nil
   @distance = 0.0
   @bounds = Bounds.new
   if(opts[:element])
      segment_element = opts[:element]
      last_pt = nil
      if segment_element.is_a?(XML::Node)
         segment_element.find("child::gpx:trkpt", @gpx_file.ns).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)
               @latest_point   = pt if(@latest_point.nil? or pt.time > @latest_point.time)
            end
            unless pt.elevation.nil?
               @lowest_point   = pt if(@lowest_point.nil? or pt.elevation < @lowest_point.elevation)
               @highest_point  = pt if(@highest_point.nil? or pt.elevation > @highest_point.elevation)
            end
            @bounds.min_lat = pt.lat if pt.lat < @bounds.min_lat
            @bounds.min_lon = pt.lon if pt.lon < @bounds.min_lon
            @bounds.max_lat = pt.lat if pt.lat > @bounds.max_lat
            @bounds.max_lon = pt.lon if pt.lon > @bounds.max_lon

            @distance += haversine_distance(last_pt, pt) unless last_pt.nil?

            @points << pt
            last_pt  = pt
         end
      end
   end
end

Instance Attribute Details

#boundsObject (readonly)

Returns the value of attribute bounds.



31
32
33
# File 'lib/gpx/segment.rb', line 31

def bounds
  @bounds
end

#distanceObject (readonly)

Returns the value of attribute distance.



31
32
33
# File 'lib/gpx/segment.rb', line 31

def distance
  @distance
end

#earliest_pointObject (readonly)

Returns the value of attribute earliest_point.



31
32
33
# File 'lib/gpx/segment.rb', line 31

def earliest_point
  @earliest_point
end

#highest_pointObject (readonly)

Returns the value of attribute highest_point.



31
32
33
# File 'lib/gpx/segment.rb', line 31

def highest_point
  @highest_point
end

#latest_pointObject (readonly)

Returns the value of attribute latest_point.



31
32
33
# File 'lib/gpx/segment.rb', line 31

def latest_point
  @latest_point
end

#lowest_pointObject (readonly)

Returns the value of attribute lowest_point.



31
32
33
# File 'lib/gpx/segment.rb', line 31

def lowest_point
  @lowest_point
end

#pointsObject

Returns the value of attribute points.



32
33
34
# File 'lib/gpx/segment.rb', line 32

def points
  @points
end

#trackObject

Returns the value of attribute track.



32
33
34
# File 'lib/gpx/segment.rb', line 32

def track
  @track
end

Instance Method Details

#append_point(pt) ⇒ Object

Tack on a point to this Segment. All meta-data will be updated.



75
76
77
78
79
80
81
82
83
84
85
86
87
# File 'lib/gpx/segment.rb', line 75

def append_point(pt)
   last_pt = @points[-1]
   @earliest_point = pt if(@earliest_point.nil? or pt.time < @earliest_point.time)
   @latest_point   = pt if(@latest_point.nil? or pt.time > @latest_point.time)
   @lowest_point   = pt if(@lowest_point.nil? or pt.elevation < @lowest_point.elevation)
   @highest_point  = pt if(@highest_point.nil? or pt.elevation > @highest_point.elevation)
   @bounds.min_lat = pt.lat if pt.lat < @bounds.min_lat
   @bounds.min_lon = pt.lon if pt.lon < @bounds.min_lon
   @bounds.max_lat = pt.lat if pt.lat > @bounds.max_lat
   @bounds.max_lon = pt.lon if pt.lon > @bounds.max_lon
   @distance += haversine_distance(last_pt, pt) unless last_pt.nil?
   @points << pt
end

#closest_point(time) ⇒ Object

Finds the closest point in time to the passed-in time argument. Useful for matching up time-based objects (photos, video, etc) with a geographic location.



97
98
99
# File 'lib/gpx/segment.rb', line 97

def closest_point(time)
   find_closest(points, time)
end

#contains_time?(time) ⇒ Boolean

Returns true if the given time is within this Segment.

Returns:

  • (Boolean)


90
91
92
# File 'lib/gpx/segment.rb', line 90

def contains_time?(time)
   (time >= @earliest_point.time and time <= @latest_point.time) rescue false
end

#crop(area) ⇒ Object

Deletes all points within this Segment that lie outside of the given area (which should be a Bounds object).



103
104
105
# File 'lib/gpx/segment.rb', line 103

def crop(area)
   delete_if { |pt| not area.contains?(pt) }
end

#delete_area(area) ⇒ Object

Deletes all points in this Segment that lie within the given area.



108
109
110
# File 'lib/gpx/segment.rb', line 108

def delete_area(area)
   delete_if{ |pt| area.contains?(pt) }
end

#delete_ifObject

A handy method that deletes points based on a block that is passed in. If the passed-in block returns true when given a point, then that point is deleted. For example:

delete_if{ |pt| area.contains?(pt) }


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

def delete_if
   
   keep_points = []
   last_pt = nil
   points.each do |pt| 
      unless yield(pt)
         keep_points << pt
         (pt, last_pt)
         last_pt = pt
      end
   end
   @points = keep_points
end

#empty?Boolean

Returns true if this Segment has no points.

Returns:

  • (Boolean)


131
132
133
# File 'lib/gpx/segment.rb', line 131

def empty?
   (points.nil? or (points.size == 0))
end

#to_sObject

Prints out a nice summary of this Segment.



143
144
145
146
147
148
149
150
151
152
153
# File 'lib/gpx/segment.rb', line 143

def to_s
   result = "Track Segment\n"
   result << "\tSize: #{points.size} points\n"
   result << "\tDistance: #{distance} km\n"
   result << "\tEarliest Point: #{earliest_point.time.to_s} \n"
   result << "\tLatest Point: #{latest_point.time.to_s} \n"
   result << "\tLowest Point: #{lowest_point.elevation} \n"
   result << "\tHighest Point: #{highest_point.elevation}\n "
   result << "\tBounds: #{bounds.to_s}"
   result
end

#to_xmlObject

Converts this Segment to a XML::Node object.



136
137
138
139
140
# File 'lib/gpx/segment.rb', line 136

def to_xml
   seg = Node.new('trkseg')
   points.each { |pt| seg <<  pt.to_xml }
   seg
end