1

私はVincenty の数式を次のように実装しようとしています。

    /* Implemented using Vincenty's formulae from http://en.wikipedia.org/wiki/Vincenty%27s_formulae,
 * answers "Direct Problem".
 * $latlng is a ('lat'=>x1, 'lng'=>y1) array
 * $distance is in miles
 * $angle is in degrees
 */
function addDistance($latlng, $distance, $bearing) {
    //variables
    $bearing = deg2rad($bearing);
    $iterations = 20; //avoid too-early termination while avoiding the non-convergant case

    //knowns
    $f = EARTH_SPHEROID_FLATTENING; //1/298.257223563
    $a = EARTH_RADIUS_EQUATOR_MILES; //3963.185 mi
    $phi1 = deg2rad($latlng['lat']);
    $l1 = deg2rad($latlng['lng']);
    $b = (1 - $f) * $a;

    //first block
    $tanU1 = (1-$f)*tan($phi1);
    $U1 = atan($tanU1);
    $sigma1 = atan($tanU1 / cos($bearing));
    $sinalpha = cos($U1)*sin($bearing);
    $cos2alpha = (1 - $sinalpha) * (1 + $sinalpha);
    $usquared = $cos2alpha * (($a*$a - $b*$b) / 2);
    $A = 1 + ($usquared)/16384 * (4096+$usquared*(-768+$usquared*(320 - 175*$usquared)));
    $B = ($usquared / 1024)*(256*$usquared*(-128 + $usquared * (74 - 47*$usquared)));

    //the loop - determining our value
    $sigma = $distance / ($b * $A);
    for($i = 0; $i < $iterations; ++$i) {
        $twosigmam = 2*$sigma1 + $sigma;
        $delta_sigma = $B * sin($sigma) * (cos($twosigmam)+(1/4)*$B*(cos(-1 + 2*cos(cos($twosigmam))) - (1/6)*$B*cos($twosigmam)*(-3+4*sin(sin($sigma)))*(-3+4*cos(cos($twosigmam)))));
        $sigma = $distance / ($b * $A) + $delta_sigma;
    }

    //second block
    $phi2 = atan((sin($U1)*cos($sigma)+cos($U1)*sin($sigma)*cos($bearing)) / ((1-$f) * sqrt(sin($sinalpha) + pow(sin($U1)*sin($sigma) - cos($U1)*cos($sigma)*cos($bearing), 2))));
    $lambda = atan((sin($sigma) * sin($bearing)) / (cos($U1)*cos($sigma) - sin($U1)*sin($sigma)*cos($bearing)));
    $C = ($f / 16)* $cos2alpha * (4+$f*(4-3*$cos2alpha));
    $L = $lambda - (1 - $C) * $f * $sinalpha * ($sigma + $C*sin($sigma)*(cos($twosigmam)+$C*cos($sigma)*(-1+2*cos(cos($twosigmam)))));
    $alpha2 = atan($sinalpha / (-sin($U1)*sin($sigma) + cos($U1)*cos($sigma)*cos($bearing)));

    //and return our results
    return array('lat' => rad2deg($phi2), 'lng' => rad2deg($lambda));
}

    var_dump(addDistance(array('lat' => 93.129, 'lng' => -43.221), 20, 135);

問題は、結果が妥当でないことです。距離を 20 に保ったまま、最大 20 の緯度と経度の分散が得られます。球の楕円距離の単位ではありませんか? 私は何かを誤解していますか、それとも私の実装に欠陥がありますか?

4

2 に答える 2

3

ウィキペディアのページの直接問題セクションからの文字起こしには多くのエラーがあります。

  • あなたのu2式は分母に22があるべきところにあります。b
  • あなたAB式は、正しく表現するために最初の分数係数を括弧で囲む必要があるかどうかについて一貫性がありませんa / b * c-(a/b) * c括弧なしで起こることは、私が答えを知らないphp構文の問題ですが、明確にする必要があります。
  • 「シグマに大きな変化がなくなるまで」反復する必要があります。これは、固定された反復回数で発生する場合と発生しない場合があります。
  • DELTA_sigma式にエラーがあります。
    • ウィキペディアのページでは、角括弧内の最初の用語[cos sigma (-1etcですが、cos (-1etcは非常に異なります。
    • cos同じ式で、また後で、 2 x(cos x)(cos x)、ではなく 、を意味することに注意してくださいcos cos x
  • phi_2式には、 ;sin($sinalpha)が必要な場所があります。sin($sinalpha)*sin($sinalpha)

それだけだと思います。

于 2012-07-11T08:24:10.103 に答える
0

これを試しましたか:

https://github.com/trefynnon/Geographic-Calculations-in-PHP

于 2012-07-10T15:43:01.220 に答える