OpenLayers OpenLayers

Changeset 554

Show
Ignore:
Timestamp:
06/07/06 23:37:20 (2 years ago)
Author:
crschmidt
Message:

Add vincenty great circle formula.

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • trunk/openlayers/lib/OpenLayers/Util.js

    r531 r554  
    950950    return (target != div); 
    951951}; 
     952 
     953OpenLayers.Util.rad = function(x) {return x*Math.PI/180;}; 
     954OpenLayers.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};