Tính khoảng cách giữa một điểm và một đường ảo hai lat / lngs


14

Vui lòng tham khảo ví dụ và hình ảnh tương ứng.

Tôi muốn đạt được những điều sau: cung cấp hai địa điểm (lat / lng), được trình bày dưới đây như mộtB . Từ đó, một đường ảo sẽ được rút ra và sau đó khoảng cách giữa đường này và C sẽ được tính (trong bất kỳ phép đo nào).

đang vẽ

Tôi đã đạt được điều này hiện tại trong Google Maps API v3 nhưng cũng muốn có thể thực hiện điều này đằng sau hậu trường bằng ngôn ngữ mà tôi chọn. Bất kỳ lời khuyên / ý tưởng sẽ được đánh giá rất cao!


AB có phải là một đường tròn lớn không?
Kirk Kuykendall

@Kirk, Không, AB chỉ là một đường thẳng
Tù nhân

@Michael, đó là một điểm thú vị. Tôi sẽ phải có một cái nhìn vào nó!
Tù nhân

@Prisoner @Kirk Theo nghĩa đen, một "đường thẳng" sẽ đi qua bên dưới bề mặt trái đất. Nhìn chung, hình chiếu xuyên tâm của nó trở lại bề mặt thực sự sẽ là một đoạn của một vòng tròn lớn (sử dụng mô hình trái đất hình cầu).
whuber

1
@Prisoner Đó là một thông tin cực kỳ hữu ích! Ư, bạn đung. Bạn vẫn phải bù đắp cho thực tế rằng việc sử dụng (lat, lon) khác biệt làm biến dạng khoảng cách đông-tây so với bắc-nam. Như @Jose khuyên, hãy chiếu tọa độ. Điều này có thể đơn giản như nhân trước các kinh độ với cosin của vĩ độ trung bình và sau đó giả vờ bạn đang ở trên mặt phẳng Euclide.
whuber

Câu trả lời:


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

Độ dài ngắn nhất là khoảng cách bạn yêu cầu, trừ khi tôi nhầm?


Có, tôi đang tìm khoảng cách ngắn nhất từ ​​C đến đoạn đường. Đây có phải là những gì toán học này tính toán?
Tù nhân

1
Nó thực sự hoạt động tốt, tôi đã vượt qua ba điểm (A, B, C) như sau: i.imgur.com/bK9oB.jpg và nó đã trở lại với lat / lng của X. Tuyệt vời!
Tù nhân

1
@Herry, Một điều cuối cùng, làm thế nào tôi sẽ sửa đổi điều này để đi đến điểm gần nhất (không chỉ đường) vì vậy nếu tôi đã đặt nó qua điểm nối một dòng, làm thế nào tôi có thể kiểm tra khoảng cách đến điểm?
Tù nhân

1
@Hawk Khởi đầu tốt, nhưng dường như quá thường xuyên mã này trở lại Nonekhi có giải pháp hợp pháp tồn tại. Vấn đề là điều kiện cuối cùng giả định X1 <X2 và Y1 <Y2, không thể luôn được đảm bảo. Một bài kiểm tra tốt hơn về sự giữa là cần thiết.
whuber

1
@Herry Nghe có vẻ như cuộc trao đổi giữa bạn và @prisoner đã có hiệu quả. Tôi muốn nhấn mạnh rằng tôi không liên quan gì (hoặc thậm chí bất kỳ sự kiểm soát nào) đối với bất kỳ thay đổi nào trong việc bỏ phiếu hoặc điểm có thể xảy ra và nhận xét của tôi chỉ nhằm mục đích giúp bạn cải thiện câu trả lời của mình.
whuber

11

Có thể tôi đang làm cho nó quá phức tạp, nhưng điều bạn muốn là khoảng cách từ một điểm đến một đường thẳng. Đó là khoảng cách từ một điểm dọc AB nối AB với C với đường thẳng trực giao với AB. Vectơ này vuông góc với AB được cho bởi

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

(Tôi đã sử dụng dấu ngoặc vuông để xác định một vectơ hoặc mảng hai phần tử). Khoảng cách giữa C [xp, yp] và điểm A là

u=[x1-xp, y1-xp]

Khoảng cách giữa dòng và C chỉ là hình chiếu của u trên v. Nếu chúng ta giả sử mod (v) = 1 (chỉ cần bình thường hóa nó), thì

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

Điều phức tạp duy nhất là bạn có thể muốn đảm bảo tọa độ của mình không phải là cặp lat / log WGS84, nhưng được chiếu (hoặc sử dụng tọa độ trắc địa). Bạn có thể sử dụng OGR hoặc Proj4 cho việc này.


3
+ Nhân tiện, vài triệu điểm giả vì không sử dụng các hàm lượng giác. Tất cả quá nhiều người rút ArcTan khi họ nên xem xét điều này: en.wikipedia.org/wiki/Dot_product
Herb

@Jose, cảm ơn đã trả lời! Tôi đang sử dụng lat / long từ API google maps. Phần toán khá mới đối với tôi vì vậy tôi sẽ thử và xem những gì tôi có thể nghĩ ra. Bất kỳ lời khuyên với các toán học? Ví dụ: [x2-x1, - (y2-y1)], nó dịch cái gì?
Tù nhân

Tôi đã thêm một chỉnh sửa ngắn cho việc này. Về cơ bản, đó là một ký hiệu mảng, nhưng nếu bạn lưu trữ tọa độ của mình trong các biến x1, x2, y1, y2 và xp, yp, bạn chỉ cần viết phía bên phải của phương trình cuối cùng tôi đã cung cấp. Đây là khá nhiều mã C, Java, JS, Python, v.v. :)
Jose

1
@Jose Bạn đang tính khoảng cách từ C đến dòng AB. Dựa trên hình vẽ, tôi tin rằng OP muốn khoảng cách từ C đến đoạn AB. Điều này đòi hỏi phải làm thêm để kiểm tra xem hình chiếu của C lên đường thẳng AB có nằm giữa A và B hay không. Trong trường hợp sau, sử dụng ngắn hơn hai chiều dài CA và CB.
whuber

1
@Prisoner Sự khác biệt chính là một đường kéo dài mãi mãi (nó chỉ được xác định bởi một vectơ chỉ phương và một điểm, hoặc bởi hai điểm), trong khi một đoạn giữa A và B là bit của đường vô hạn đi giữa A và B (nó có độ dài hữu hạn)
Jose

4

Cũng hơi ác cảm với tất cả toán học này, tôi sẽ nhìn nó từ một góc độ khác. Tôi sẽ biến nó thành một dòng 'thực tế', thay vì một dòng ảo, và sau đó sử dụng các công cụ hiện có.

Nếu A và B chia sẻ một thuộc tính, bạn có thể kết nối chúng bằng cách vẽ một đường (Kosmo GIS có một công cụ sẽ tạo các đường từ các điểm và tôi tin rằng cũng có một plugin QGIS cho việc này). Khi bạn có các dòng, chức năng 'gần' trên lớp điểm 'C' sẽ cung cấp cho bạn khoảng cách đến dòng. Hãy để phần mềm xử lý toán học cho bạn!


Cảm ơn vì nhận xét nhưng Hairy đã đưa ra những vấp ngã trên cái này!
Tù nhân

1
(+1) Bạn thực hiện một điểm xuất sắc. Các thuật toán hình học tính toán nổi tiếng là khó khăn để hoàn toàn đúng trong thực tế (như chúng ta có thể thấy từ tất cả các mã được cung cấp cho đến nay, rất hữu ích và minh họa nhưng chưa hoạt động đầy đủ). Sử dụng một quy trình GIS cấp cao thường là một cách tốt để đảm bảo bạn sẽ nhận được câu trả lời mà bạn mong đợi và điều đó đúng (miễn là bạn tin tưởng vào hệ thống GIS của mình ;-).
whuber

1

Nếu bạn đang sử dụng java trên Android, thì chỉ có một dòng với chức năng thư viện

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

khoảng cách:

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

Tính khoảng cách trên mặt cầu giữa điểm p và đoạn đường bắt đầu kết thúc.

Các thông số: p - điểm cần đo

bắt đầu - bắt đầu của phân khúc dòng

kết thúc - kết thúc của phân khúc dòng

Trả về: khoảng cách tính bằng mét (giả sử trái đất hình cầu)

Chỉ cần thêm thư viện vào

dependencies {
    compile 'com.google.maps.android:android-maps-utils:0.5+'
}
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.