Это большой жирный комментарий к коду, опубликованному в (принятом в настоящее время) ответе @Sven Marnach.
Оригинальный код с сайта zip проекта, с отредактированным мной отступом:
from math import *
def calcDist(lat_A, long_A, lat_B, long_B):
distance = (sin(radians(lat_A)) *
sin(radians(lat_B)) +
cos(radians(lat_A)) *
cos(radians(lat_B)) *
cos(radians(long_A - long_B)))
distance = (degrees(acos(distance))) * 69.09
return distance
Код, отправленный Свеном:
from math import sin, cos, radians, degrees
def calc_dist(lat_a, long_a, lat_b, long_b):
lat_a = radians(lat_a)
lat_b = radians(lat_b)
distance = (sin(lat_a) * sin(lat_b) +
cos(lat_a) * cos(lat_b) * cos(long_a - long_b))
return degrees(acos(distance)) * 69.09
Проблема 1: НЕ ЗАПУСКАЕТСЯ : необходимо импортировать acos
Задача 2: НЕПРАВИЛЬНЫЕ ОТВЕТЫ : необходимо преобразовать
разница долготы с радианами во второй последней строке
Проблема 3: Имя переменной «расстояние» является крайне неправильным.
Эта величина на самом деле является cos угла между двумя линиями
от центра земли до входных точек. Изменить на "cos_x"
Проблема 4: Нет необходимости преобразовывать угол x в градусы. Просто
умножить x на радиус Земли в выбранных единицах (км, нм или «статутных милях»)
После исправления всего этого мы получаем:
from math import sin, cos, radians, acos
# http://en.wikipedia.org/wiki/Earth_radius
# """For Earth, the mean radius is 6,371.009 km (˜3,958.761 mi; ˜3,440.069 nmi)"""
EARTH_RADIUS_IN_MILES = 3958.761
def calc_dist_fixed(lat_a, long_a, lat_b, long_b):
"""all angles in degrees, result in miles"""
lat_a = radians(lat_a)
lat_b = radians(lat_b)
delta_long = radians(long_a - long_b)
cos_x = (
sin(lat_a) * sin(lat_b) +
cos(lat_a) * cos(lat_b) * cos(delta_long)
)
return acos(cos_x) * EARTH_RADIUS_IN_MILES
Примечание: после исправления проблем 1 и 2 это «сферический закон косинусов», как обычно реализуется.
Это нормально для таких приложений, как «расстояние между двумя почтовыми индексами США».
Предостережение 1: Оно не является точным для небольших расстояний, таких как от вашей входной двери до улицы, настолько, что оно может дать ненулевое расстояние или вызвать исключение (cos_x> 1,0), если две точки идентичны; эта ситуация может быть особой.
Предупреждение 2: Если две точки противоположны (прямая линия проходит через центр Земли), это может вызвать исключение (cos_x <-1.0). Любой, кто обеспокоен этим, может проверить cos_x перед выполнением acos (cos_x). </p>
Пример: * * тысяча тридцать-один
SFO (37,676, -122,433) в Нью-Йорк (40,733, -73,917)
calcDist -> 2570.7758043869976
calc_dist -> 5038.599866130089
calc_dist_fixed -> 2570.9028268899356
Сайт правительства США (http://www.nhc.noaa.gov/gccalc.shtml) -> 2569
)
Этот веб-сайт (http://www.timeanddate.com/worldclock/distanceresult.html?p1=179&p2=224),, с которого я получил координаты SFO и NYC, -> 2577