jjNford
jjNford

Reputation: 5270

Is the Haversine Formula or the Vincenty's Formula better for calculating distance?

Which is better for calculating the distance between two latitude/longitude points, The Haversine Formula or The Vincenty's Formula? Why?

The distance is obviously being calculated on Earth. Does WGS84 vs GCJ02 coordinates impact the calculation or distance (The Vincenty's formula takes the WGS84 axis into consideration)?

For example, in Android, the Haversine Formula is used in Google Map Utils, but the Vincenty Formula is used by the android.Location object (Location.distanceBetween()).

Upvotes: 40

Views: 35408

Answers (3)

Azmisov
Azmisov

Reputation: 7253

Lets compare Haversine vs Karney (a faster, more stable reformulation of Vincenty) distance calculations. If we assume the ellipsoid model of the Earth is accurate, and also ignore GPS elevation in distances, Karney's calculation will be exact. Haversine distances will have errors, because they assume a spherical rather than ellipsoid Earth.

For minimum error, the Haversine calculation should use a spherical Earth radius that matches the radial distance on the ellipsoid near your GPS points of interest. For GPS points that are randomly distributed on the Earth, a radius that is halfway between the polar and equatorial radii lengths will minimize error. For the WGS84 reference ellipsoid, this is 6367444.65712259 meters.

Using this radius, we can measure Haversine distances for random GPS points and compare to Karney. The maximum relative absolute error is a constant ~0.5052%. For a 1km distance, that means Haversine distances will be off by at most 5.052 meters.

The Haversine calculation is much simpler and faster to calculate, so it should be preferred if 0.5052% relative error is acceptable for your application.

Here is some Python code you can play with to measure errors for different Haversine radii, or for different distances:

""" Compare haversine vs karney distances """
import math
from random import random
from geographiclib_cython import Geodesic
from geographiclib.constants import Constants

# distance in meters
karney_distance = 100000

def lerp(t, a, b):
    if t < 0.5:
        return a+(b-a)*t
    return b-(b-a)*(1-t)

equatorial_radius = Constants.WGS84_a
polar_radius = Constants.WGS84_a*(1-Constants.WGS84_f)
radius = lerp(0.5, equatorial_radius, polar_radius)
print(f"Haversine radius: {radius}")

def haversine(A, B):
    A = tuple(map(math.radians, A))
    B = tuple(map(math.radians, B))
    dlat = A[0] - B[0]
    dlon = A[1] - B[1]
    a = math.sin(dlat/2)**2 + math.cos(A[0]) * math.cos(B[0]) * math.sin(dlon/2)**2
    c = 2 * math.asin(math.sqrt(a))
    return c * radius

max_error = 0
for sample in range(100000):
    A = (
        lerp(random(), -90.0, 90.0),
        lerp(random(), -180.0, 180.0)
    )
    azimuth = lerp(random(), 0.0, 360.0)
    res = Geodesic.WGS84.Direct(*A, azimuth, karney_distance)
    B = (
        res["lat2"],
        res["lon2"]
    )
    haversine_distance = haversine(A, B)
    err = abs(haversine_distance - karney_distance)
    if err > max_error:
        max_error = err

# haversine formula error in meters
print(f"Maximum relative absolute error: {max_error/karney_distance*100:.04f}%")

Upvotes: 1

cffk
cffk

Reputation: 1929

Haversine and Vincenty are two algorithms for solving different problems. Haversine computes the great circle distance on a sphere while Vincenty computes the shortest (geodesic) distance on the surface of an ellipsoid of revolution. So the answer to your question can be broken into 2 parts:

  1. Do you want to compute the distance on a sphere on an ellipsoid?
  2. How accurate is Haversine or Vincenty at calculating the given problem?

For terrestrial applications, an ellipsoid of revolution is a reasonable approximation to "mean sea level"; the error is ± 100 m. The flattening of this ellipsoid is small, about 1/300, and so can be approximated by a sphere (of equal volume, for example).

Great circle distances differ from geodesic distances by up to 0.5%. In some applications, e.g., what's the distance from the Cape to Cairo?, this error can be neglected. In other applications, e.g., determining maritime boundaries, it is far too large (it's 5 m over a distance of 1 km). In general, you're safer using the geodesic distance.

If you're interested is distance traveled (by car, boat, or plane), there are lots of constraints on the path taken and neither the great circle or geodesic distance, which measure the length of shortest paths on an ideal surface, would be appropriate.

On the question of whether the algorithms are accurate:

Haversine is accurate to round-off unless the points are nearly antipodal. Better formulas are given in the Wikipedia article on great-circle distances.

Vincenty is usually accurate to about 0.1 mm. However if the points are nearly antipodal, the algorithm fails to converge and the error is much larger. I give a better algorithm for solving the geodesic problem in Algorithms for geodesics. See also the Wikipedia article on geodesics on an ellipsoid.

Solving the geodesic problem is slower than solving for the great-circle. But it's still very fast (about 1 μs per calculation), so this shouldn't be a reason to prefer great circle distances.

ADENDUM

Here is the Java package which implements my algorithm for finding geodesic distances. Unlike Vincenty's method, this is accurate to round-off and converges everywhere.

Upvotes: 70

andand
andand

Reputation: 17487

Haversine is a simpler computation but it does not provide the high accuracy Vincenty offers.

Vincenty is more accurate but is also more computationally intensive and will therefore perform slower and increase battery usage.

As with anything "better" is a matter of your particular application. For your application, Vincenty may be a "better" choice than Haversine, but for a different application, Haversine may be a better choice. You will have to look at the particulars of your use cases and make a determination based upon what you find there.

Upvotes: 26

Related Questions