2012-01-13 62 views
8

Tôi đang thiết lập một chương trình nhỏ để lấy 2 toạ độ địa lý từ người dùng và sau đó tính khoảng cách giữa chúng (tính đến độ cong của trái đất). Vì vậy, tôi tra cứu wikipedia về công thức là here.Cần trợ giúp tính khoảng cách địa lý

tôi về cơ bản thiết lập chức năng python của tôi dựa trên đó và đây là những gì tôi đã đưa ra:

def geocalc(start_lat, start_long, end_lat, end_long): 
    start_lat = math.radians(start_lat) 
    start_long = math.radians(start_long) 
    end_lat = math.radians(end_long) 
    end_long = math.radians(end_long) 

    d_lat = start_lat - end_lat 
    d_long = start_long - end_long 

    EARTH_R = 6372.8 

    c = math.atan((math.sqrt((math.cos(end_lat)*d_long)**2 +((math.cos(start_lat)*math.sin(end_lat)) - (math.sin(start_lat)*math.cos(end_lat)*math.cos(d_long)))**2))/((math.sin(start_lat)*math.sin(end_lat)) + (math.cos(start_lat)*math.cos(end_lat)*math.cos(d_long)))) 

    return EARTH_R*c 

Vấn đề là kết quả đi ra thực sự không chính xác. Tôi mới để python nên một số trợ giúp hoặc tư vấn sẽ được đánh giá rất nhiều!

+2

Xin vui lòng cho một ví dụ cụ thể (đầu vào, đầu ra dự kiến, sản lượng thực tế). –

+0

Tôi đã nhập các tọa độ này (-6.508, 55.071) và (-8.886, 51.622). Sản lượng dự kiến ​​là 414Km. Kết quả thực tế là 6473Km – Darkphenom

+0

Tôi muốn nói điều này là không chính xác, điều này là sai>. hochl

Trả lời

10

Bạn đã có 4 hoặc 5 hoặc 6 vấn đề:

(1) end_lat = math.radians(end_long) nên end_lat = math.radians(end_lat)

(2) bạn đang thiếu một số nội dung như ai đó đã đề cập, có lẽ hầu hết vì

(3) mã của bạn là không đọc được (dòng quá dài, ngoặc thừa, 17 trường hợp vô nghĩa của "toán học").

(4), bạn không để ý nhận xét trong bài viết Wikipedia về việc sử dụng atan2()

(5) Bạn có thể đã được trao đổi lat và lon khi nhập tọa độ của bạn

(6) delta(latitude) được tính cách không cần thiết; nó không xuất hiện trong công thức

Đưa nó tất cả cùng nhau:

from math import radians, sqrt, sin, cos, atan2 

def geocalc(lat1, lon1, lat2, lon2): 
    lat1 = radians(lat1) 
    lon1 = radians(lon1) 
    lat2 = radians(lat2) 
    lon2 = radians(lon2) 

    dlon = lon1 - lon2 

    EARTH_R = 6372.8 

    y = sqrt(
     (cos(lat2) * sin(dlon)) ** 2 
     + (cos(lat1) * sin(lat2) - sin(lat1) * cos(lat2) * cos(dlon)) ** 2 
     ) 
    x = sin(lat1) * sin(lat2) + cos(lat1) * cos(lat2) * cos(dlon) 
    c = atan2(y, x) 
    return EARTH_R * c 



>>> geocalc(36.12, -86.67, 33.94, -118.40) 
2887.2599506071115 
>>> geocalc(-6.508, 55.071, -8.886, 51.622) 
463.09798886300376 
>>> geocalc(55.071, -6.508, 51.622, -8.886) 
414.7830891822618 
+0

Cảm ơn bạn đã chỉ ra tất cả những vấn đề đó. Nó chắc chắn trông sạch hơn rất nhiều so với những gì tôi đã làm và nó hoạt động! – Darkphenom

4

Bạn có thể sử dụng các mô-đun geopy trong đó có một chức năng built-in để tính toán khoảng cách, di chuyển xuống "Khoảng cách tính toán" trong liên kết dưới đây: https://pypi.python.org/pypi/geopy

+0

Đó là một gợi ý tốt, nhưng câu trả lời của bạn sẽ tốt hơn nếu bạn có thể bao gồm một số mã về cách đạt được mục tiêu của OP . – MERose

3

Tôi nghĩ rằng bạn bỏ lỡ một Math.sin (d_long) về phía đầu, có lẽ phải được điều này:

c = math.atan((math.sqrt((math.cos(end_lat)*math.sin(d_long))**2 +((math.cos(start_lat)*math.sin(end_lat)) - (math.sin(start_lat)*math.cos(end_lat)*math.cos(d_long)))**2))/((math.sin(start_lat)*math.sin(end_lat)) + (math.cos(start_lat)*math.cos(end_lat)*math.cos(d_long)))) 
+0

Bạn đã chính xác ở đó. Tuy nhiên, tôi vẫn nhận được câu trả lời hoàn toàn sai. – Darkphenom

4

này hoạt động (in f trả 2.887,26 km theo ví dụ cách @http://en.wikipedia.org/wiki/Great-circle_distance):

import math 

def geocalc(start_lat, start_long, end_lat, end_long): 

    start_lat = math.radians(start_lat) 
    start_long = math.radians(start_long) 
    end_lat = math.radians(end_lat) 
    end_long = math.radians(end_long) 

    d_lat = math.fabs(start_lat - end_lat) 
    d_long = math.fabs(start_long - end_long) 

    EARTH_R = 6372.8 

    y = ((math.sin(start_lat)*math.sin(end_lat)) + (math.cos(start_lat)*math.cos(end_lat)*math.cos(d_long))) 

    x = math.sqrt((math.cos(end_lat)*math.sin(d_long))**2 + ((math.cos(start_lat)*math.sin(end_lat)) - (math.sin(start_lat)*math.cos(end_lat)*math.cos(d_long)))**2) 

    c = math.atan(x/y) 

    return EARTH_R*c 

f = geocalc(36.12, -86.67, 33.94, -118.40) 
print f 

Thông báo dòng này trong trình của bạn: end_lat = math.radians(end_long)

+0

Bạn không cần 'fabs()', vì 'cos (-x) == cos (x)' –

+0

-1 Điều này có thể đi sai một cách ngoạn mục vì bạn đang sử dụng 'atan' thay vì' atan2'. Ví dụ: đi về phía nam từ 45 độ lat đến -45 độ lat là 10010 km (OK) nhưng từ 45,1 deg đến -45,1 deg (khoảng cách hơi xa) tạo ra MINUS 9988 km. Một chuyến đi từ cực bắc đến cực nam tạo ra ZERO km! –

+0

@JohnMachin liên quan đến fabs() bình luận bạn là chính xác cho việc thực hiện cụ thể này nhưng khi dạy khái niệm về vùng đồng bằng, việc sử dụng các giá trị tuyệt đối là đúng trừ phép trừ đơn giản. – sgallen

Các vấn đề liên quan