[OpenLayers-Dev] Vincenty with 1 Point, Bearing and Distance

Vincent-Gabriel Vallée vgvallee at hotmail.com
Fri Oct 5 16:33:43 EDT 2007


Hi all,

There is another formula from Vincenty that permits to use 1 point, a bearing and a distance to obtain the coordinates of the target there. You can find the original JavaScript here:
http://www.movable-type.co.uk- /scripts- /latlong-vincenty-direct.html

I think this function should also be part of OpenLayers.Util as the distVincenty is. However, what would be the best return value type? I thought that since a OpenLayers.LonLat is used as a parameter, maybe that should be the return type. On the other hand, I needed such a function to create a geometry, which takes in an OpenLayers.Geometry.Point as a parameter so that I need to convert all points (what's the best way to do that?).

Vincent

Here is the function from the link above dapted for OpenLayers:
/**
 * Function: destVincenty
 *
 * Parameters:
 * p1 - {<OpenLayers.LonLat>}
 * bearing - {Float} The bearing, with 0 degree being true north and clockwise positive.
 * dist - {Float} The distance, in kilometers.
 *
 * Returns:
 * {<OpenLayers.LonLat>}
 *
 * Note:
 * Adapted from Vincenty 'Direct' formula: (<http://www.movable-type.co.uk/scripts/latlong-vincenty-direct.html>).
 */
OpenLayers.Util.destVincenty=function(p1, bearing, dist) {
  var a = 6378137, b = 6356752.3142,  f = 1/298.257223563;  // WGS-84 ellipsiod
  var s = dist * 1000;
  var alpha1 = OpenLayers.Util.rad(bearing);
  var sinAlpha1 = Math.sin(alpha1), cosAlpha1 = Math.cos(alpha1);
  
  var tanU1 = (1-f) * Math.tan(OpenLayers.Util.rad(p1.lat));
  var cosU1 = 1 / Math.sqrt((1 + tanU1*tanU1)), sinU1 = tanU1*cosU1;
  var sigma1 = Math.atan2(tanU1, cosAlpha1);
  var sinAlpha = cosU1 * sinAlpha1;
  var cosSqAlpha = 1 - sinAlpha*sinAlpha;
  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 sigma = s / (b*A), sigmaP = 2*Math.PI;
  while (Math.abs(sigma-sigmaP) > 1e-12) {
    var cos2SigmaM = Math.cos(2*sigma1 + sigma);
    var sinSigma = Math.sin(sigma), cosSigma = Math.cos(sigma);
    var deltaSigma = B*sinSigma*(cos2SigmaM+B/4*(cosSigma*(-1+2*cos2SigmaM*cos2SigmaM)-
      B/6*cos2SigmaM*(-3+4*sinSigma*sinSigma)*(-3+4*cos2SigmaM*cos2SigmaM)));
    sigmaP = sigma;
    sigma = s / (b*A) + deltaSigma;
  }

  var tmp = sinU1*sinSigma - cosU1*cosSigma*cosAlpha1;
  var lat2 = Math.atan2(sinU1*cosSigma + cosU1*sinSigma*cosAlpha1, 
      (1-f)*Math.sqrt(sinAlpha*sinAlpha + tmp*tmp));
  var lambda = Math.atan2(sinSigma*sinAlpha1, cosU1*cosSigma - sinU1*sinSigma*cosAlpha1);
  var C = f/16*cosSqAlpha*(4+f*(4-3*cosSqAlpha));
  var L = lambda - (1-C) * f * sinAlpha *
      (sigma + C*sinSigma*(cos2SigmaM+C*cosSigma*(-1+2*cos2SigmaM*cos2SigmaM)));

  var revAz = Math.atan2(sinAlpha, -tmp);  // final bearing

  return new OpenLayers.LonLat(p1.lon+OpenLayers.Util.deg(L),OpenLayers.Util.deg(lat2));
}

-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.osgeo.org/pipermail/openlayers-dev/attachments/20071005/711ea90d/attachment.html


More information about the Dev mailing list