Module: TrackCalculator
- Included in:
- Calcpace
- Defined in:
- lib/calcpace/track_calculator.rb
Overview
Module for GPS track calculations
This module provides pure mathematical methods for computing distances, elevation changes, and pace splits from arrays of GPS coordinate points. It does not perform any file I/O or GPX parsing — callers are responsible for supplying arrays of hashes with the required keys.
Constant Summary collapse
- EARTH_RADIUS_KM =
Mean radius of the Earth in kilometers (IAU standard)
6371.0
Instance Method Summary collapse
-
#elevation_gain(points) ⇒ Hash
Calculates cumulative elevation gain and loss along a GPS track.
-
#haversine_distance(lat1, lon1, lat2, lon2) ⇒ Float
Computes the great-circle distance between two GPS coordinates using the Haversine formula.
-
#track_distance(points) ⇒ Float
Calculates the total distance of a GPS track by summing Haversine distances between consecutive points.
-
#track_splits(points, split_km = 1.0) ⇒ Array<Hash>
Calculates pace splits at regular distance intervals along a GPS track.
Instance Method Details
#elevation_gain(points) ⇒ Hash
Calculates cumulative elevation gain and loss along a GPS track.
Only consecutive pairs where both points have an :ele value are considered. Points missing :ele are silently skipped.
99 100 101 102 103 104 105 106 107 108 109 |
# File 'lib/calcpace/track_calculator.rb', line 99 def elevation_gain(points) gain = 0.0 loss = 0.0 return { gain: gain, loss: loss } if points.nil? || points.size < 2 points.each_cons(2) do |a, b| gain, loss = accumulate_elevation(gain, loss, fetch_ele(a), fetch_ele(b)) end { gain: gain.round(1), loss: loss.round(1) } end |
#haversine_distance(lat1, lon1, lat2, lon2) ⇒ Float
Computes the great-circle distance between two GPS coordinates using the Haversine formula.
The Haversine formula calculates the shortest distance over the Earth’s surface between two points defined by latitude and longitude. It assumes a spherical Earth (error < 0.3% vs. WGS84 ellipsoid), which is accurate enough for running and cycling purposes.
Formula:
a = sin²(Δlat/2) + cos(lat1) × cos(lat2) × sin²(Δlon/2)
c = 2 × atan2(√a, √(1−a))
d = R × c
53 54 55 56 57 |
# File 'lib/calcpace/track_calculator.rb', line 53 def haversine_distance(lat1, lon1, lat2, lon2) validate_coordinates(lat1, lon1) validate_coordinates(lat2, lon2) haversine_km(lat1, lon1, lat2, lon2) end |
#track_distance(points) ⇒ Float
Calculates the total distance of a GPS track by summing Haversine distances between consecutive points.
73 74 75 76 77 78 79 80 81 82 |
# File 'lib/calcpace/track_calculator.rb', line 73 def track_distance(points) return 0.0 if points.nil? || points.size < 2 total = points.each_cons(2).sum do |a, b| haversine_distance(fetch_coord(a, :lat), fetch_coord(a, :lon), fetch_coord(b, :lat), fetch_coord(b, :lon)) end total.round(2) end |
#track_splits(points, split_km = 1.0) ⇒ Array<Hash>
Calculates pace splits at regular distance intervals along a GPS track.
Accumulates Haversine distance between consecutive points until the target split distance is reached, then records elapsed time and pace for that split. Any remaining distance at the end is included as a partial split.
134 135 136 137 138 139 140 |
# File 'lib/calcpace/track_calculator.rb', line 134 def track_splits(points, split_km = 1.0) raise ArgumentError, 'split_km must be positive' unless split_km.is_a?(Numeric) && split_km.positive? return [] if points.nil? || points.size < 2 validate_points_have_time(points) collect_splits(points, split_km) end |