두 위도 / 경도의 점과 가상 선 사이의 거리 계산


14

예와 해당 이미지를 참조하십시오.

다음을 달성하고 싶습니다 . 아래에 AB 로 표시된 두 위치 (lat / lng)를 제공하십시오 . 이것으로부터 가상 선이 그려지고이 선과 C 사이의 거리 가 계산됩니다 (모든 측정에서).

그림

나는 현재 Google Maps API v3에서 이것을 달성했지만 원하는 언어로 무대 뒤에서 이것을 수행 할 수 있기를 원합니다. 모든 팁 / 아이디어는 대단히 감사하겠습니다!


AB는 그레이트 서클 라인입니까?
커크 Kuykendall

@Kirk, 아니오, AB는 직선입니다
죄수

@ 마이클, 그거 흥미로운 지적이야. 나는 그것을 들여다 봐야 할 것이다!
죄수

@Prisoner @Kirk 문자 그대로 "직선"이 지표면 아래를 통과합니다. 일반적으로 표면으로의 방사상 투영은 실제로 구형 지구 모델을 사용하여 큰 원의 세그먼트가됩니다.
whuber

1
@Prisoner 매우 유용한 추가 정보입니다! 그래 정확 해. (lat, lon)을 사용하면 남북과 비교하여 동서 거리가 차등 적으로 왜곡된다는 사실을 여전히 보상해야합니다. @Jose가 조언했듯이 좌표를 투영하십시오. 이것은 평균 위도의 코사인에 경도를 미리 곱한 다음 유클리드 비행기를 타는 것처럼 간단 할 수 있습니다.
whuber

답변:


6
def get_perp( X1, Y1, X2, Y2, X3, Y3):
    """************************************************************************************************ 
    Purpose - X1,Y1,X2,Y2 = Two points representing the ends of the line segment
              X3,Y3 = The offset point 
    'Returns - X4,Y4 = Returns the Point on the line perpendicular to the offset or None if no such
                        point exists
    '************************************************************************************************ """
    XX = X2 - X1 
    YY = Y2 - Y1 
    ShortestLength = ((XX * (X3 - X1)) + (YY * (Y3 - Y1))) / ((XX * XX) + (YY * YY)) 
    X4 = X1 + XX * ShortestLength 
    Y4 = Y1 + YY * ShortestLength
    if X4 < X2 and X4 > X1 and Y4 < Y2 and Y4 > Y1:
        return X4,Y4
    return None

내가 실수하지 않는 한 가장 짧은 길이는 필요한 거리입니까?


예, C에서 선분까지의 최단 거리를 찾고 있습니다. 이 수학이 계산하는 것입니까?
죄수

1
실제로 잘 작동했으며 다음과 같은 세 가지 점 (A, B, C)을 통과했습니다 .i.imgur.com / bK9oB.jpg 그리고 X의 위도 / 경도로 돌아 왔습니다.
죄수

1
@Hairy, 마지막으로, 가장 가까운 점 (선이 아닌)으로 이동하도록 수정하는 방법은 무엇입니까? 포인트?
죄수

1
@Hairy 좋은 시작이지만 None, 합법적 인 솔루션이 존재할 때이 코드가 너무 자주 반환 되는 것 같습니다 . 문제는 마지막 조건이 항상 보장 할 수없는 X1 <X2 및 Y1 <Y2를 가정한다는 것입니다. 사이의 더 나은 테스트가 필요합니다.
whuber

1
@Hairy 귀하와 @prisoner 간의 교환이 생산적인 것 같습니다. 본인은 투표 또는 변경 사항이 발생할 수있는 모든 변경 사항과 관련이 없으며 (또는 그에 대한 통제권이 없음), 본인의 의견은 귀하의 회신을 개선하는 데 도움을주기위한 것임을 강조하고 싶습니다.
whuber

11

어쩌면 나는 그것을 너무 복잡하게 만들지 만, 원하는 것은 점에서 선까지의 거리입니다. 그것은 AB와 직교하는 선으로 AB와 C를 연결하는 AB를 따른 점으로부터의 거리입니다. AB에 수직 인이 벡터는

v=[x2-x1, -(y2-y1)] # Point A is [x1,y1] Point B is [x2,y2]

(대괄호를 사용하여 벡터 또는 두 요소 배열을 정의했습니다). C [xp, yp]와 점 A 사이의 거리는

u=[x1-xp, y1-xp]

선과 C 사이의 거리는 u를 v에 투영 한 것입니다. mod (v) = 1이라고 가정하면 (정규화)

distance = u*v = abs( (x2-x1)*(y1-yp) - (x1-xp)*(y2-y1) )

유일한 합병증은 좌표가 WGS84 위도 / 로그 쌍이 아니라 투영 (또는 측지 좌표 사용)하는지 확인하려는 것입니다. 이를 위해 OGR 또는 Proj4 를 사용할 수 있습니다 .


3
그런데 삼각 함수를 사용하지 않는 것에 대한 수백만의 의사 포인트. 너무 많은 사람들이 이것을보고 싶을 때 ArcTan을 꺼냅니다 : en.wikipedia.org/wiki/Dot_product
Herb

@ 조세, 답변 주셔서 감사합니다! Google Maps API의 위도 / 경도를 사용하고 있습니다. 수학 부분은 나에게 매우 새롭기 때문에 한 번 살펴보고 내가 생각 해낼 수있는 것을 살펴 보겠습니다. 수학에 대한 팁? 예를 들어 [x2-x1,-(y2-y1)]는 무엇을 의미합니까?
죄수

이에 대한 간단한 편집을 추가했습니다. 기본적으로 배열 표기법이지만 변수 x1, x2, y1, y2 및 xp, yp에 좌표를 저장하면 마지막으로 제공 한 방정식의 오른쪽 만 작성하면됩니다. 이것은 매우 유효한 C, Java, JS, Python 등의 코드입니다 :)
Jose

1
@Jose C에서 AB 까지의 거리를 계산합니다 . 그림을 바탕으로 OP는 C에서 선분 AB 까지의 거리를 원한다고 생각합니다 . 이것은 선 AB에 C의 투영이 A와 B 사이에 있는지 여부를 확인하기 위해 추가 작업이 필요합니다. 후자의 경우 두 길이의 CA 및 CB 중에서 더 짧은 길이를 사용하십시오.
whuber

1
@Prisoner 주요 차이점은 선이 영원히 연장된다는 것입니다 (방향 벡터와 점 또는 두 점으로 만 정의 됨). A와 B 사이의 세그먼트는 A와 B 사이의 무한 선의 비트입니다 B (유한 한 길이
Jose

4

이 모든 수학에 약간의 역점을두기 때문에 다른 각도에서 나올 것입니다. 가상 라인이 아닌 '실제'라인으로 만든 다음 기존 도구를 사용합니다.

A와 B가 속성을 공유하는 경우 선을 그려서 연결할 수 있습니다 (Kosmo GIS에는 점에서 선을 만드는 도구가 있으며 QGIS 플러그인도 있다고 생각합니다). 선이 있으면 'C'포인트 레이어의 '가까이'기능이 선까지의 거리를 제공합니다. 소프트웨어가 당신을 위해 수학을 처리하자!


의견에 감사드립니다.
죄수

1
(+1) 당신은 훌륭한 지적을합니다. 계산 지오메트리 알고리즘은 실제로 완벽하게 적용하기가 까다로울 수 있습니다 (지금까지 제공된 모든 코드에서 볼 수 있듯이 유용하고 예시 적이지만 아직 완전히 작동하지는 않습니다). 높은 수준의 GIS 절차를 사용하는 것은 종종 당신이 기대하는 답을 얻었고 그것이 옳다는 것을 확신 할 수있는 좋은 방법입니다 (GIS ;-).
whuber

1

Android에서 Java를 사용하는 경우 라이브러리 함수가있는 유일한 한 줄

import static com.google.maps.android.PolyUtil.distanceToLine;

distanceToLine :

public static double distanceToLine(LatLng p, LatLng start,LatLng end)

점 p와 선분 시작점 사이의 구에서 거리를 계산합니다.

매개 변수 : p-측정점

start-선분의 시작

end-선분의 끝

반환 : 미터 단위의 거리 (구면 지구를 가정)

라이브러리를 추가하십시오.

dependencies {
    compile 'com.google.maps.android:android-maps-utils:0.5+'
}
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.