선에서 가장 가까운 점 (구형 / 메르카토르 투영)


9

나는 메르카토르 투영 (Google지도 ) 위에 선 (Ax, Ay-Bx, By) 이 있고 그 선에 가장 가까운 임의의 점 (Cx, Cy)이 있습니다. 가장 가까운 지점 (이미지의 투명한 파란색)을 알고 싶습니다. 그 선이 포인트 (이미지에서 파란색)

편집 : 이것이 Mercator 투영 (구면 투영)에 있음을 명확히하기 위해 여기에 이미지 설명을 입력하십시오


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 클래스를 확인하십시오.


글렌 플라스, 수업은 왼쪽이나 오른쪽에 약간의 오프셋 이있는 것 같습니다 . Google 어스에서 스크린 샷을 만들었습니다. 오프셋, 그림 : 링크 , 내가 사용한 코드point_to_line_segment_distance(41.421649, 2.600410, 41.413851, 2.594356, 41.415710, 2.600638))
Colas

그것은 내 수업이 아니며, 많은 것을 검색 한 후에 그것을 발견했습니다. ;-) 그러나 나는 내 문제에서 8 자리 정밀도를 사용합니다 .6을 사용하는 것 같습니다. 그 이유는 그 이유가 있습니다. 지적 해 주셔서 감사합니다. 알 필요가있는대로 다시 확인하겠습니다.
Glenn Plas

어쩌면 당신은 rihgt, 나는 gEarth에 더 많은 decilmas를 얻을 수 없습니다, 마지막 그림에서 btw 세그먼트는 1000 미터 길이, 오프셋은 ~ 110meters
Colas

그것은 내가 사용하는 규모에 관한 것입니다. 버스 (대중 교통)가 가장 가까운 정류장을 지나가는 시간을 확인하기 위해 사용합니다. 그래도 그것을 다시 확인하고 구체에 잘 투영되는지 '볼'지도에 넣을 것입니다.
Glenn Plas

오 ... 나는 구형 투영을 위해 기능이 만들어 졌다고 생각했습니다. 이제 오프셋을 이해합니다.
Colas

1

google map api 에서 computeDistanceBetween () 함수를 사용할 수 있습니다 .

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

두 점 사이의 거리는 두 점 사이의 최단 경로 길이입니다. 이 최단 경로를 측지선이라고합니다. 구체에서 모든 측지선은 큰 원의 세그먼트입니다. 이 거리를 계산하려면 computeDistanceBetween ()을 호출하여 두 LatLng 객체를 전달합니다.

대신 여러 위치가있는 경우 computeLength ()를 사용하여 주어진 경로의 길이를 계산할 수 있습니다

나는 그것이 당신에게 도움이되기를 바랍니다 ...


먼저 사이의 거리를 계산하기 위해 점 (연한 파란색)을 알아야합니다.
Colas

아래의 해결책은 세그먼트의 요점을 알 수 없습니다. 실제로 언급 한 것과 비슷한 문제 / 해결책이 있습니다. 소규모로 안전하게 사용할 수 있습니다.
Glenn Plas
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.