| | 952 | |
|---|
| | 953 | OpenLayers.Util.rad = function(x) {return x*Math.PI/180;}; |
|---|
| | 954 | OpenLayers.Util.distVincenty=function(p1, p2) { |
|---|
| | 955 | var a = 6378137, b = 6356752.3142, f = 1/298.257223563; |
|---|
| | 956 | var L = OpenLayers.Util.rad(p2.lon - p1.lon); |
|---|
| | 957 | var U1 = Math.atan((1-f) * Math.tan(OpenLayers.Util.rad(p1.lat))); |
|---|
| | 958 | var U2 = Math.atan((1-f) * Math.tan(OpenLayers.Util.rad(p2.lat))); |
|---|
| | 959 | var sinU1 = Math.sin(U1), cosU1 = Math.cos(U1); |
|---|
| | 960 | var sinU2 = Math.sin(U2), cosU2 = Math.cos(U2); |
|---|
| | 961 | var lambda = L, lambdaP = 2*Math.PI; |
|---|
| | 962 | var iterLimit = 20; |
|---|
| | 963 | while (Math.abs(lambda-lambdaP) > 1e-12 && --iterLimit>0) { |
|---|
| | 964 | var sinLambda = Math.sin(lambda), cosLambda = Math.cos(lambda); |
|---|
| | 965 | var sinSigma = Math.sqrt((cosU2*sinLambda) * (cosU2*sinLambda) + |
|---|
| | 966 | (cosU1*sinU2-sinU1*cosU2*cosLambda) * (cosU1*sinU2-sinU1*cosU2*cosLambda)); |
|---|
| | 967 | if (sinSigma==0) return 0; // co-incident points |
|---|
| | 968 | var cosSigma = sinU1*sinU2 + cosU1*cosU2*cosLambda; |
|---|
| | 969 | var sigma = Math.atan2(sinSigma, cosSigma); |
|---|
| | 970 | var alpha = Math.asin(cosU1 * cosU2 * sinLambda / sinSigma); |
|---|
| | 971 | var cosSqAlpha = Math.cos(alpha) * Math.cos(alpha); |
|---|
| | 972 | var cos2SigmaM = cosSigma - 2*sinU1*sinU2/cosSqAlpha; |
|---|
| | 973 | var C = f/16*cosSqAlpha*(4+f*(4-3*cosSqAlpha)); |
|---|
| | 974 | lambdaP = lambda; |
|---|
| | 975 | lambda = L + (1-C) * f * Math.sin(alpha) * |
|---|
| | 976 | (sigma + C*sinSigma*(cos2SigmaM+C*cosSigma*(-1+2*cos2SigmaM*cos2SigmaM))); |
|---|
| | 977 | } |
|---|
| | 978 | if (iterLimit==0) return NaN // formula failed to converge |
|---|
| | 979 | var uSq = cosSqAlpha * (a*a - b*b) / (b*b); |
|---|
| | 980 | var A = 1 + uSq/16384*(4096+uSq*(-768+uSq*(320-175*uSq))); |
|---|
| | 981 | var B = uSq/1024 * (256+uSq*(-128+uSq*(74-47*uSq))); |
|---|
| | 982 | var deltaSigma = B*sinSigma*(cos2SigmaM+B/4*(cosSigma*(-1+2*cos2SigmaM*cos2SigmaM)- |
|---|
| | 983 | B/6*cos2SigmaM*(-3+4*sinSigma*sinSigma)*(-3+4*cos2SigmaM*cos2SigmaM))); |
|---|
| | 984 | var s = b*A*(sigma-deltaSigma); |
|---|
| | 985 | var d = s.toFixed(3)/1000; // round to 1mm precision |
|---|
| | 986 | return d; |
|---|
| | 987 | }; |
|---|