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


14

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

다음을 달성하고 싶습니다 . 아래에 A 및 B 로 표시된 두 위치 (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.