2012-04-16 6 views
2

現在、私が使用しています式は以下の通りですが、それはあなたがこのリンクを見つけることができますVincenty式、としてはあまり正確である: http://www.movable-type.co.uk/scripts/latlong-vincenty-direct.htmlJavascriptの&Googleマップサークル

私の質問は、誰かが簡素化することができ、ありますjavascriptのコード私は私の公式でそれを実装することができますか?私はJavaScriptを学ぼうとしていますが、私の能力をはるかに超えています。

EX = LAT2 EY = lon2

イムコードを実行して、EX/EY座標を計算するために360度のアレイを実行することで簡単な方法を考えます。

<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; 


    } 

これは、phpに変換された直接式です。私はこのコードをgoogle mapsのコードに入れようとしています。移動可能なリンクは実際に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 

?> 
+1

[この質問とその回答](http://stackoverflow.com/questions/10027094/holes-in-a-polygon)は役に立ちますか? –

+1

私はあなたがそのコードを書く時を感謝します。私はそれに非常に感謝していましたが、私はいくつかの掘り出し物をしました。私は、Haversine式が私の必要とするものに対してあまり正確でないことを発見しました。 Vincenty式が私が探しているものです。あなたのコードを新しい式に適合させようとしています。どんな助けも素晴らしいだろう。ありがとうございました。 –

+1

Aha。名前が一致しませんでした。 –

答えて

2

すでに提供されたリンクは、ハードの部分が完了したJavaScriptで式を提供するので、あなたはそれをコピーして、むしろあなたの関数にそれを書き換えるよりも、それを呼び出すことができます。ソースの属性を覚えておいてください。私は使用されていない変数を削除しました。また、ちょうどポイント変数に割り当てていたので、私はちょうど361をハードにコード化しました。数を数式に渡す場合は、これを元に戻すことができます。私はforのループを分けましたが、これはもっと読みやすく、私が思っていたやり方はあなたが意図したように働いていたとは思えません。度とラジアンで作業する場合、私は常にこれらの変換を関数にラップします。これは読みやすさを向上させるからです。

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; 
} 

ない理解するにはあまりにも厳しいが、プロトタイプは、クラスベースの言語での継承に似たJavaScriptでのオブジェクトを、拡張することができます:ここに見られるようにこれを行うために、私はprototypeを使ってJavaScriptでNumberオブジェクトにそれらをフックアップ。明確にするのに役立つオンラインリソースはたくさんあります。ここで

は、再加工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; 
} 

fiddle of it workingです。

+1

IveはなぜJavaScript JavaScriptを学ぶのが遅いのか判断しましたが、phpのようなエラーがどこにないか教えてくれません。ブライアン、それを働かせるために私にこのコードを与えてから約1時間かかりました、いくつかの事柄を変えなければならなかった、数式は完璧です。私はAndrew Leachが先週提供した陰影を付け加えました(彼が投稿したリンクを参照)。当時はありがとうございました。 –

+1

さて、JavaScriptデバッグは時々苦痛になることがあります。エラーの特定とデバッグに役立つツールがいくつかあります。ここには最も一般的なもののリストがあります。個人的には、FirebugとIE9の組み込み開発ツールが好きです。 http://www.smashingmagazine.com/2008/11/18/15-helpful-in-browser-web-development-tools/ –