直線上の最も近い点(球形/メルカトル図法)


9

私はメルカトル図法(グーグルマップ上の線(Ax、Ay-Bx、By)とその線に最も近いランダムな点(Cx、Cy)を持っています。ポイントするライン(画像の青)

編集:これがメルカトル図法(球形図法)であることを明確にする ここに画像の説明を入力してください


3
この記事はあなたに興味があり非常に便利な解決策があるstackoverflow.com/questions/3120357/get-closest-point-to-a-line
ビナヤン

1
その水色は最も近いようには見えません、最も近いとは、濃い青に接続したときに90度の角度を作成する必要があるということですか?
Glenn Plas

私は手で写真を作ったので、そうです、それは可能です
Colas

@vinayan参照する投稿は、線に最も近い点を見つけるという別の問題を解決しますが、ここで必要なのは、線分に最も近い点が必要なようです。
whuber

1
セグメントの長さは約20〜100メートルで、セグメントからの距離はセンチメートルから30メートルです
Colas

回答:


2

このリンクを確認してください。次の関数を使用して、線分までの距離を計算しました。

PHPの場合:

function point_to_line_segment_distance($startX,$startY, $endX,$endY, $pointX,$pointY) {

   // list($distanceSegment, $x, $y) = point_to_line_segment_distance($startX,$startY, $endX,$endY, $pointX,$pointY);

    // Adapted from Philip Nicoletti's function, found here: http://www.codeguru.com/forum/printthread.php?t=194400

    $r_numerator = ($pointX - $startX) * ($endX - $startX) + ($pointY - $startY) * ($endY - $startY);
    $r_denominator = ($endX - $startX) * ($endX - $startX) + ($endY - $startY) * ($endY - $startY);
    $r = $r_numerator / $r_denominator;

    $px = $startX + $r * ($endX - $startX);
    $py = $startY + $r * ($endY - $startY);

    $s = (($startY-$pointY) * ($endX - $startX) - ($startX - $pointX) * ($endY - $startY) ) / $r_denominator;

    $distanceLine = abs($s) * sqrt($r_denominator);

    $closest_point_on_segment_X = $px;
    $closest_point_on_segment_Y = $py;

    if ( ($r >= 0) && ($r <= 1) ) {
       $distanceSegment = $distanceLine;
    }
    else {
       $dist1 = ($pointX - $startX) * ($pointX - $startX) + ($pointY - $startY) * ($pointY - $startY);
       $dist2 = ($pointX - $endX) * ($pointX - $endX) + ($pointY - $endY) * ($pointY - $endY);
       if ($dist1 < $dist2) {
          $closest_point_on_segment_X = $startX;
          $closest_point_on_segment_Y = $startY;
          $distanceSegment = sqrt($dist1);
       }
       else {
          $closest_point_on_segment_X = $endX;
          $closest_point_on_segment_Y = $endY;
          $distanceSegment = sqrt($dist2);
       }
    }

    return array($distanceSegment, $closest_point_on_segment_X, $closest_point_on_segment_Y);
}

次に、投影関数を使用して距離を計算できます。私は上記の式を使用して、平均速度が与えられた場合のその時点の時間を計算しています。これは非常にうまく機能します。

PHPの座標間の距離を計算するための優れたPHPライブラリが必要な場合は、GeoCalcクラスを確認してください。


Glenn Plasさん、クラスの左右に少しオフセットがあるようです。GoogleEarthでスクリーンショットを作成しました。そのオフセットが表示されます。写真:リンク、使用したコードpoint_to_line_segment_distance(41.421649, 2.600410, 41.413851, 2.594356, 41.415710, 2.600638))
Colas

それは私のクラスではありません、たくさん検索した結果、見つかりました;-)しかし、私は問題で8桁の精度を使用しています。6を使用しているようです。それが理由である可能性があります。指摘してくれてありがとう。知っておく必要があるので、すぐに再確認します。
Glenn Plas

たぶんあなたは正しいです、私はgEarthでこれ以上デシマを得ることができません、最後の写真でセグメントは1000メートル長で、オフセットは約110メートルでした
Colas

それは私がそれを使用する規模についてです、それ以上ではありません。バス(公共交通機関)が最寄りの停留所を通過する時刻を確認するために使用します。私はそれをダブルチェックして、それが球にうまく映るかどうかを「見る」ためにマップに入れます。
Glenn Plas

ああ...私はその関数が球面投影のために作られたと思ったので、今私はオフセットを理解します
Colas

1

あなたはグーグルマップAPIからcomputeDistanceBetween()関数を使うことができます。

distance = google.maps.geometry.spherical.computeDistanceBetween(firstCoord, secondCoord);

2点間の距離は、2点間の最短経路の長さです。この最短経路は測地線と呼ばれます。球では、すべての測地線は大円のセグメントです。この距離を計算するには、computeDistanceBetween()を呼び出して、2つのLatLngオブジェクトを渡します。

複数の場所がある場合は、代わりにcomputeLength()を使用して特定のパスの長さを計算できます

お役に立てば幸いです...


まず、距離を計算するためのポイント(水色)を知る必要があります
Colas

以下の私の解決策はそれを行います、セグメント上のポイントは不明です。前述のように、私は実際にはかなり似た問題/解決策を持っています。小規模でも安心してお使いいただけます。
Glenn Plas
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.