Sweet little lies my GPS told me
Apple’s Core Location system - Apple’s GPS system - has a significant shortcoming when used for calculating distances between GPS points during workout activities: it doesn’t include altitude change in the distances. Apple’s developer documentation for WatchOS clearly states that “The distance is calculated by tracing a line between the two points that follows the curvature of the Earth, and measuring the length of the resulting arc. The arc is a smooth curve that doesn’t take into account altitude changes between the two locations.” But, if you are cycling up a steep hill, or skiing down a steep descent, much of your distance traveled will be the altitude change between your starting and end points.
This may not have a huge impact on the distance calculations for a sport like cycling. Climbing a moderate 10% grade would result in only a 0.5% error in distance over the length of the climb. But, skiing down a 45% grade ski run - a standard grade for an advanced ski run - would result in a 10% error in distance over the length of the ski run. Someone brave enough to send it down the 133% grade (53° pitch) on Jackson Hole’s infamous Corbet’s Couloir would see a 66% error in distance. Failing to account for altitude change would completely miss the initial 3-6 meter vertical drop-in off the cornice at the top. That level of error is unacceptable and disappointing to anyone who felt shortchanged when their GPS failed to fully account for each meter of their epic plunge down Corbet’s.
Thankfully, the correct calculations are reasonably straight forward to implement using the standard Euclidean distance formula taught in trigonometry class. The Euclidean distance is the square root of the sum of squares of the distances between the cartesian coordinates for each location.
There is one slight complication: GPS data is given in spherical coordinates with radius (ρ), latitude (θ), and longitude (φ). But, the standard Euclidean distance formula uses cartesian coordinates. The altitude is the height of the coordinate above the radius of the earth, so the spherical radius coordinate is the sum of the altitude and the Earth’s average radius of 6,371 kilometers. Further complicating matters is that the inclination term in spherical coordinates uses colatitude instead of latitude, where colatitude = 90° - latitude. Though one might surmise that you could just use the standard Euclidean distance formula with the Apple’s distance value, and the change in altitude, since Apple claims the distance value “doesn’t take into account altitude changes between the two locations.” But, Apple actually incorporates the altitudes into its distance calculation - contradicting their own documentation - by using the mean altitude of the points as the reference altitude to add to the average radius of the Earth. Calculating the Euclidean distance in spherical coordinates is somewhat more complex, but it provides a more accurate distance value than simply adding the change in altitude to the distance value provided by Apple.
Now, let’s dive into some technical implementation details to perform this calculation in practice. First, GPS coordinate data is provided in units of degrees, but the trigonometric functions in the C programming language use units of radians. To convert to radians from degrees, you must multiply by the constant π and divide by 180. Apple provides special cospi, sinpi, and tanpi math functions in their SIMD (Single Instruction Multiple Data) framework that multiply the input value by π prior to calculating the final trigonometric value which are both faster and more accurate than performing the multiplication by π step separately. SIMD instructions boost performance by performing multiple simultaneous computations with one computer instruction.
Next note that the cos(φ1 - φ2) value can be computationally problematic since φ1 ≈ φ2 for most GPS data. The cos(φ1 - φ2) computation can be expanded as cos(φ1)cos(φ2) + sin(φ1)sin(φ2) which improves numerical stability to some extent at the cost of requiring two extra multiplications and three additional transcendental functions. But, by simply converting the GPS points from spherical to cartesian coordinate points, and then employing the standard Euclidean distance formula, numerical stability is improved substantially. A further benefit of this approach is that it is marginally faster by 5% when the compiler is set to the -O3 (fastest) optimization level in Apple’s Xcode development environment.