Javascript&;谷歌地图圈

Javascript&;谷歌地图圈,javascript,google-maps-api-3,Javascript,Google Maps Api 3,目前我使用的公式如下,但不如Vincenty公式准确,你可以在这个链接上找到: 我的问题是,有人能帮我简化javascript代码,让我在公式中实现它吗?我正在尝试学习javascript,但它有点超出了我的能力 ex=lat2 ey=2 我认为最简单的方法是运行代码,然后做一个360度的数组来计算ex/ey坐标 <script type="text/javascript"> function drawCircle(point, radius, dir, addtoBounds

目前我使用的公式如下,但不如Vincenty公式准确,你可以在这个链接上找到:

我的问题是,有人能帮我简化javascript代码,让我在公式中实现它吗?我正在尝试学习javascript,但它有点超出了我的能力

ex=lat2 ey=2

我认为最简单的方法是运行代码,然后做一个360度的数组来计算ex/ey坐标

<script type="text/javascript"> 

function drawCircle(point, radius, dir, addtoBounds) { 
var d2r = Math.PI / 180;   // degrees to radians 
var r2d = 180 / Math.PI;   // radians to degrees 
var earthsradius = 6378137;

   var points = 360; 

   // find the radius in lat/lon 
   var rlat = (radius / earthsradius) * r2d; 
   var rlng = rlat / Math.cos(point.lat() * d2r); 


   var extp = new Array(); 
   if (dir==1)  {var start=0;var end=points+1} // one extra here makes sure we connect the
   else     {var start=points+1;var end=0}
   for (var i=start; (dir==1 ? i < end : i > end); i=i+dir)  
   { 
    var theta = Math.PI * (i / (points/2));//i is number of points + 1 
var lat1=point.lat()*d2r;
var lon1=point.lng()*d2r;
var d=radius;
var R=earthsradius;

var ex = Math.asin( Math.sin(lat1)*Math.cos(d/R) + 
                Math.cos(lat1)*Math.sin(d/R)*Math.cos(theta));
var ey = lon1 + Math.atan2(Math.sin(theta)*Math.sin(d/R)*Math.cos(lat1), 
                 Math.cos(d/R)-Math.sin(lat1)*Math.sin(ex));
  extp.push(new google.maps.LatLng(ex*r2d, ey*r2d)); 
  if (addtoBounds) bounds.extend(extp[extp.length-1]);



   } 
   // alert(extp.length);
   return extp;


   }

函数drawCircle(点、半径、方向、添加边界){
var d2r=Math.PI/180;//度到弧度
var r2d=180/Math.PI;//弧度到度
var earthsradius=6378137;
var点=360;
//以lat/lon为单位查找半径
var rlat=(半径/地球半径)*r2d;
var rlng=rlat/Math.cos(point.lat()*d2r);
var extp=新数组();
如果(dir==1){var start=0;var end=points+1}//这里有一个额外的值确保我们连接
else{var start=points+1;var end=0}
对于(变量i=start;(dir==1?iend);i=i+dir)
{ 
var theta=Math.PI*(i/(点数/2));//i是点数+1
var lat1=point.lat()*d2r;
var lon1=point.lng()*d2r;
var d=半径;
var R=地球半径;
var ex=数学asin(数学sin(lat1)*数学cos(d/R)+
数学cos(lat1)*数学sin(d/R)*数学cos(theta));
变量ey=lon1+Math.atan2(Math.sin(θ)*Math.sin(d/R)*Math.cos(lat1),
数学cos(d/R)-数学sin(lat1)*数学sin(ex));
extp.push(新的google.maps.LatLng(ex*r2d,ey*r2d));
if(addtoBounds)bounds.extend(extp[extp.length-1]);
} 
//警报(扩展长度);
返回extp;
}
下面是转换为php的直接公式。我正在尝试将此代码放入谷歌地图代码中。movable type链接实际上在javascript中有这段代码,但由于我对php了解得更多,所以我将其转换为测试代码,这段代码运行得非常完美

<?php 
 $lat1 = 29.10860062;
 $lon1 = -95.46209717;
 $a = 6378137;
 $b = 6356752.314245;
 $f = 1/298.257223563;  // WGS-84 ellipsoid params
 $brng = 32.8;


 $s = 1796884.48;
 $alpha1 = deg2rad($brng);
 $sinAlpha1 = sin($alpha1);
 $cosAlpha1 = cos($alpha1);
 $tanU1 = (1-$f) * tan(deg2rad($lat1));
 $cosU1 = 1 / sqrt((1 + pow($tanU1,2)));
 $sinU1 = $tanU1*$cosU1;
 $sigma1 = atan2($tanU1, $cosAlpha1);
 $sinAlpha = $cosU1 * $sinAlpha1;
 $cosSqAlpha = 1 - pow($sinAlpha,2);
 $uSq = $cosSqAlpha * (pow($a,2) - pow($b,2)) / (pow($b,2));
 $A = 1 + $uSq/16384*(4096+$uSq*(-768+$uSq*(320-175*$uSq)));
 $B = $uSq/1024 * (256+$uSq*(-128+$uSq*(74-47*$uSq)));
 $sigma = $s / ($b*$A);
 $sigmaP = 2*pi;

 $limit = 100; 
 $counter = 1;

 while ( $counter <= $limit ) {
 $cos2SigmaM = cos(2*$sigma1 + $sigma);
 $sinSigma = sin($sigma);
 $cosSigma = cos($sigma);
 $deltaSigma = $B*$sinSigma*($cos2SigmaM+$B/4*($cosSigma*(-1+2*pow($cos2SigmaM,2))-$B/6*$cos2SigmaM*(-3+4*pow($sinSigma,2))*(-3+4*pow($cos2SigmaM,2))));
 $sigmaP = $sigma;
 $sigma = $s / ($b*$A) + $deltaSigma;
$counter = $counter+1;
};

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

 if (deg2rad($lon1)+$L+(3*pi)<(2*pi)) {
 (  $lon2 = (deg2rad($lon1)+$L+(3*pi))-pi);
 } else {
 (  $lon2 = ((deg2rad($lon1)+$L+3*pi))%(2*pi))-pi;}

 $revAz = atan2($sinAlpha, -$tmp);  // final bearing, if required

?>

由于您提供的链接已经在javascript中提供了公式,所以硬部分已经完成,您可以复制它并调用它,而不是将其重写到您的函数中。只需记住对源进行属性设置。我删除了没有被使用的变量。另外,我只是将
361
硬编码到公式中,因为您只是将其分配给一个points变量。如果要将度数传递到公式中,可以将其更改回原来的值。我为循环分离了
,对我来说这更具可读性,而且我认为您以前的工作方式与您的预期不符。在处理度和弧度时,我总是将这些转换打包成函数,因为这样可以提高可读性。为此,我使用
prototype
将它们连接到JavaScript中的
Number
对象,如下所示:

Number.prototype.toRad = function() {
   //'this' is the current number the function is acting on.  
   //e.g. 360.toRad() == 2PI radians
  return this * Math.PI / 180;
}

Number.prototype.toDeg = function() {
  return this * 180 / Math.PI;
}
不太难理解,prototype允许您在JavaScript中扩展对象,类似于基于类的语言中的继承。网上有很多资源可以帮助澄清

以下是经过修改的drawCircle函数:

function drawCircle(point, radius, dir, addtoBounds) {
    //best practice is to use [] rather then new Array(), 
    //both do the same thing.   
    var extp = [];
    if (dir == 1) {
        for (var i = 0; i < 361; i++) {
            //destVincenty function returns a object with 
            //lat, lon, and final bearing.     
            var destPoint = destVincenty(point.lat(), point.lng(), i, radius);

            //add new point 
            extp.push(new google.maps.LatLng(destPoint.lat, destPoint.lon));
            if (addtoBounds) bounds.extend(extp[extp.length - 1]);
        }
    }
    else {
        for (var i = 361; i > 0; i--) {    
            var destPoint = destVincenty(point.lat(), point.lng(), i, radius);
            extp.push(new google.maps.LatLng(destPoint.lat, destPoint.lon));
            if (addtoBounds) bounds.extend(extp[extp.length - 1]);
        }
    }

    return extp;
}
函数绘图圆(点、半径、方向、添加边界){
//最佳做法是使用[],而不是使用新数组(),
//两者都做同样的事情。
var extp=[];
if(dir==1){
对于(变量i=0;i<361;i++){
//destVincenty函数返回具有
//lat、lon和最终轴承。
var destPoint=destVincenty(point.lat(),point.lng(),i,半径);
//添加新点
extp.push(新的google.maps.LatLng(destPoint.lat,destPoint.lon));
if(addtoBounds)bounds.extend(extp[extp.length-1]);
}
}
否则{
对于(var i=361;i>0;i--){
var destPoint=destVincenty(point.lat(),point.lng(),i,半径);
extp.push(新的google.maps.LatLng(destPoint.lat,destPoint.lon));
if(addtoBounds)bounds.extend(extp[extp.length-1]);
}
}
返回extp;
}

下面是一个。

有帮助吗?我感谢您花时间编写代码。我很感激,但在我挖掘的过程中。我发现哈弗森公式对我需要的东西不太准确。Vincenty公式就是我想要的。我正试图使你的代码适应新的公式。任何帮助都会很好。再次感谢你。啊哈。名称不匹配。我已经确定了为什么我学习javascript速度慢,它不会像php那样告诉你错误在哪里。布莱恩,在你给我这个代码后,我花了大约一个小时才让它开始工作,不得不改变一些关于ect的事情,这个公式是完美的。我添加了Andrew Leach上周提供的阴影(参见他发布的链接)。非常感谢您花这么多时间。是的,JavaScript调试有时会很痛苦。有许多工具可以帮助定位和调试错误。下面列出了一些最常见的方法。就个人而言,我喜欢Firebug和IE9内置开发工具。