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 REXML::Element 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
# File 'lib/gpx/segment.rb', line 36

def initialize(opts = {})
   @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
      unless segment_element.is_a?(Text)
         XPath.each(segment_element, "child::trkpt") do |trkpt| 
            pt = TrackPoint.new(:element => trkpt, :segment => self)  
            @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)
            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.



72
73
74
75
76
77
78
79
80
81
82
83
84
# File 'lib/gpx/segment.rb', line 72

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.



94
95
96
# File 'lib/gpx/segment.rb', line 94

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)


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

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

#crop(area) ⇒ Object

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



100
101
102
# File 'lib/gpx/segment.rb', line 100

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.



105
106
107
# File 'lib/gpx/segment.rb', line 105

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


113
114
115
116
117
118
119
120
121
122
123
124
125
# File 'lib/gpx/segment.rb', line 113

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)


128
129
130
# File 'lib/gpx/segment.rb', line 128

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

#to_sObject

Prints out a nice summary of this Segment.



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

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 REXML::Element object.



133
134
135
136
137
# File 'lib/gpx/segment.rb', line 133

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