The Vincenty formula has a high precision of 0.5 mm, but is very slow.
Haversine formula semi-normal vector formula, faster than Vincenty, precision is not vincenty high, also long use.
The Vincenty--------------------------------------------------------implemented in the-------------------------------------------openlayers --
Angle to radians
/**
* Function:rad
*
* Parameters:
* x-{Float}
*
* Returns:
* {Float}
*/
OpenLayers.Util.rad = function (x) {return x*math.pi/180;};
Radian to Angle
/**
* Function:deg
*
* Parameters:
* x-{Float}
*
* Returns:
* {Float}
*/
OpenLayers.Util.deg = function (x) {return x*180/math.pi;};
A long half shaft
b Short half Shaft
C Flat Rate
/**
* Property:vincentyconstants
* {Object} Constants for Vincenty functions.
*/
OpenLayers.Util.VincentyConstants = {
a:6378137,
b:6356752.3142,
f:1/298.257223563
};
|
WGS-84 |
a = 6 378 137 m (±2 m) |
b ≈6 356 752.314245 m |
F ≈1/298.257223563 |
|
GRS-80 |
a = 6 378 137 m |
b ≈6 356 752.314140 m |
F = 1/298.257222101 |
|
Airy 1830 |
a = 6 377 563.396 m |
b = 6 356 256.910 m |
F ≈1/299.3249646 |
|
Internat ' L 1924 |
a = 6 378 388 m |
b ≈6 356 911.946 m |
F = 1/297 |
|
Clarke mod.1880 |
a = 6 378 249.145 m |
b ≈6 356 514.86955 m |
F = 1/293.465 |
|
GRS-67 |
a = 6 378 m |
b ≈6 356 774.719 m |
F = 1/298.247167 |
Given two geographical coordinates (latitude and longitude) return km distance
/**
* Apifunction:distvincenty
* Given-objects representing points with geographic coordinates, this
*&N bsp; calculates the distance between those points on the surface of a
* Elli Psoid.
*
* Parameters:
* p1-{<openlayers.lonlat>} (or any object with both. lat,. Lon properties)
* P2-{&L T;openlayers.lonlat>} (or any object with both. lat,. Lon properties)
*
* Returns:
* {Float} The distance (in KM) between the both input points as measured on a
* ellipsoid. Note that the input point objects must be in geographic
* coordinates (decimal degrees) and the return distance are in Ki Lometers.
*/
OpenLayers.Util.distVincenty = function (P1, p2) {
var ct = OpenLayers.Util.VincentyConstants;
var a = ct.a, B = ct.b, f = ct.f;
var L = OpenLayers.Util.rad (P2.lon-p1.lon);
var U1 = Math.atan ((1-f) * Math.tan (OpenLayers.Util.rad (P1.lat)));
var U2 = Math.atan ((1-f) * Math.tan (OpenLayers.Util.rad (P2.lat)));
var sinU1 = Math.sin (U1), cosU1 = Math.Cos (U1);
var sinU2 = Math.sin (U2), cosU2 = Math.Cos (U2);
var lambda = L, lambdap = 2*math.pi;
var iterlimit = 20;
while (Math.Abs (LAMBDA-LAMBDAP) > 1e-12 &&--iterlimit>0) {
var sinlambda = Math.sin (lambda), Coslambda = Math.Cos (lambda);
var sinsigma = math.sqrt ((COSU2*SINLAMBDA) * (COSU2*SINLAMBDA) +
(COSU1*SINU2-SINU1*COSU2*COSLAMBDA) * (COSU1*SINU2-SINU1*COSU2*COSLAMBDA));
if (sinsigma==0) {
return 0; Co-incident points
}
var cossigma = sinu1*sinu2 + Cosu1*cosu2*coslambda;
var sigma = math.atan2 (Sinsigma, Cossigma);
var alpha = Math.asin (cosU1 * cosU2 * sinlambda/sinsigma);
var cossqalpha = Math.Cos (Alpha) * Math.Cos (Alpha);
var cos2sigmam = Cossigma-2*sinu1*sinu2/cossqalpha;
var C = f/16*cossqalpha* (4+f* (4-3*cossqalpha));
Lambdap = lambda;
Lambda = L + (1-c) * f * Math.sin (Alpha) *
(Sigma + c*sinsigma* (cos2sigmam+c*cossigma* ( -1+2*cos2sigmam*cos2sigmam)));
}
if (iterlimit==0) {
return NaN; Formula failed to converge
}
var usq = Cossqalpha * (a*a-b*b)/(B*B);
var A = 1 + usq/16384* (4096+usq* ( -768+usq* (320-175*USQ)));
var B = usq/1024 * (256+usq* ( -128+usq* (74-47*USQ)));
var deltasigma = b*sinsigma* (cos2sigmam+b/4* (cossigma* ( -1+2*cos2sigmam*cos2sigmam)-
b/6*cos2sigmam* ( -3+4*sinsigma*sinsigma) * ( -3+4*cos2sigmam*cos2sigmam));
var s = b*a* (Sigma-deltasigma);
var d = s.tofixed (3)/1000; Round to 1mm precision
return D;
};
-------------------------------------------End----------------------------------------------------------
Haversine Formula Implementation
function Toradians (degree) {
return degree * math.pi/180;
}
function distance (latitude1, Longitude1, Latitude2, Longitude2) {
R is the radius of the earth in kilometers
var R = 6371;
var deltalatitude = Toradians (latitude2-latitude1);
var deltalongitude = Toradians (longitude2-longitude1);
Latitude1 =toradians (LATITUDE1);
Latitude2 =toradians (LATITUDE2);
var a = Math.sin (DELTALATITUDE/2) *
Math.sin (DELTALATITUDE/2) +
Math.Cos (LATITUDE1) *
Math.Cos (LATITUDE2) *
Math.sin (DELTALONGITUDE/2) *
Math.sin (DELTALONGITUDE/2);
var c = 2 * MATH.ATAN2 (MATH.SQRT (a),
MATH.SQRT (1-a));
var d = R * C;
return D;
}
Calculate the distance between the spherical two points to achieve vincenty+haversine