Class: Hillpace::Segment

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

Overview

Represents a geographic segment in the Earth, made out of sorted track points.

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(track_points) ⇒ Segment

Initializes a Segment object.

Parameters:

  • track_points (Array<TrackPoint>)

    The track points of the segment.

Raises:

  • (RuntimeError)

    if track_points is not a collection of [TrackPoint] objects.



12
13
14
15
16
# File 'lib/hillpace/segment.rb', line 12

def initialize(track_points)
  raise 'Invalid track point array to initialize Segment' unless track_points.respond_to?('each') &&
      track_points.all? {|track_point| track_point.is_a? TrackPoint}
  @track_points = track_points
end

Instance Attribute Details

#track_pointsObject (readonly)

Returns the value of attribute track_points.



6
7
8
# File 'lib/hillpace/segment.rb', line 6

def track_points
  @track_points
end

Instance Method Details

#==(other) ⇒ boolean

Overwrites the #== operator to be able to use custom getters.

Parameters:

  • other (Segment)

    The other segment to be compared.

Returns:

  • (boolean)


21
22
23
24
# File 'lib/hillpace/segment.rb', line 21

def ==(other)
  self.class == other.class &&
      track_points == other.track_points
end

#climbNumber

Measures the elevation difference from the start to the end of the segment, in meters.

Returns:

  • (Number)


43
44
45
46
# File 'lib/hillpace/segment.rb', line 43

def climb
  return 0 if track_points.length <= 1
  track_points.first.climb_to track_points.last
end

#distance_metersNumber

Measures the distance of the segment, in meters.

Returns:

  • (Number)


28
29
30
31
32
33
34
35
36
37
38
39
# File 'lib/hillpace/segment.rb', line 28

def distance_meters
  return 0 if track_points.length <= 1

  result = 0
  latest_track_point = track_points.first
  track_points.each do |track_point|
    next if track_point.equal? latest_track_point
    result += latest_track_point.distance_meters_to track_point
    latest_track_point = track_point
  end
  result
end

#durationNumber

Measures the duration of the segment, in seconds.

Returns:

  • (Number)


89
90
91
# File 'lib/hillpace/segment.rb', line 89

def duration
  track_points.last.time.to_f - track_points.first.time.to_f
end

#inclineNumber

Measures the climb of the segment relative to its distance.

Returns:

  • (Number)


50
51
52
53
# File 'lib/hillpace/segment.rb', line 50

def incline
  return 0 if track_points.length <= 1
  self.climb / self.distance_meters
end

#pacePace

Measures the pace of the segment.

Returns:



95
96
97
# File 'lib/hillpace/segment.rb', line 95

def pace
  Pace.from_meters_per_second(distance_meters / duration)
end

#split(distance_meters) ⇒ Array<Segment>

Returns an array of segments, result of splitting self in the distance indicated.

Parameters:

  • distance_meters (Number)

    The distance in the segment where it should be splitted.

Returns:



102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
# File 'lib/hillpace/segment.rb', line 102

def split(distance_meters)
  result = []
  accumulated_distance = 0
  latest_track_point = track_points.first
  subsegment_track_points = [latest_track_point]

  track_points.lazy.each_with_index do |track_point, index|
    next if index == 0
    distance_delta = latest_track_point.distance_meters_to track_point
    accumulated_distance += distance_delta

    if result.empty?
      # in case the distance exceeds the reference distance, we add an interpolated track point
      # both to the end of the actual subsegment and to the start of the next one
      if accumulated_distance > distance_meters
        bias = (distance_meters - (accumulated_distance - distance_delta)) / distance_delta
        interpolated_track_point = latest_track_point.get_linear_interpolation_with track_point, bias
        subsegment_track_points << interpolated_track_point
        result << (Segment.new subsegment_track_points)
        subsegment_track_points = [interpolated_track_point]
      end
    end

    subsegment_track_points << track_point.clone
    latest_track_point = track_point
  end

  result << (Segment.new subsegment_track_points)
end

#total_downhillsNumber

Measures the sum of downhills between track points of the segment.

Returns:

  • (Number)


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

def total_downhills
  return 0 if track_points.length <= 1

  result = 0
  latest_track_point = track_points.first
  track_points.each do |track_point|
    if track_point.elevation < latest_track_point.elevation
      result -= latest_track_point.climb_to(track_point)
    end
    latest_track_point = track_point
  end
  result
end

#total_uphillsNumber

Measures the sum of uphills between track points of the segment.

Returns:

  • (Number)


57
58
59
60
61
62
63
64
65
66
67
68
69
# File 'lib/hillpace/segment.rb', line 57

def total_uphills
  return 0 if track_points.length <= 1

  result = 0
  latest_track_point = track_points.first
  track_points.each do |track_point|
    if track_point.elevation > latest_track_point.elevation
      result += latest_track_point.climb_to(track_point)
    end
    latest_track_point = track_point
  end
  result
end