Помогите написать функцию. Найти ближайшую станцию метро
Помогите написать функцию на Python. У менять есть список (долгота и широта) станций метро. Функцию должна брать на вход долготу и широту объекта и находить из этого списка ближайшую станцию и выводить расстояние в метрах (или км).
В list_metro находиться координаты станций. Она возвращает коэффициенты: 3 - если расстояние до метро меньше км. , 2 - если до 2х км,и если больше 2х - 1. Вот функция. Но она показывает неправильные результаты если сравнивать с гуглом. Помогите ее исправить. Спасибо.
from math import radians, cos, sin, asin, sqrt
def metro_distance(lat1, long1):
list_dist = []
for i in list_metro:
lat1 = radians(lat1)
long1 = radians(long1)
lat2 = radians(i[0])
long2 = radians(i[1])
dlong = long2 - long1
dlat = lat2 - lat1
g = sin(dlat / 2)**2 + cos(lat1) * cos(lat2) * sin(dlong / 2)**2
c = 2 * asin(sqrt(g))
r = 6371 # Radius of earth in kilometers.
dist = (c * r)
list_dist.append(dist)
min_dist = min(list_dist)
if min_dist < 1.0:
dist_coef = 3
elif 1.0 < min_dist < 2.0:
dist_coef = 2
else:
dist_coef = 1
return dist_coef
Ответы (1 шт):
Немного пофантазировал на тему) Разбил на две функции с поиском расстояния и поиском ближайшей станции.
Формулы расчета можно подсмотреть на Вики: https://en.wikipedia.org/wiki/Haversine_formula
На вход, для примера, подаю словарь станций с координатами (брал отсюда https://api.hh.ru/metro/1, но если сравнение будет с Гуглом или Яндексом, то нужны от них координаты, т.к. они немного не совпадают между сервисами, как писал в комментариях).
from math import radians, cos, sin, asin
def distance_haversine(point_1: tuple, point_2: tuple):
d_earth = 2.0 * 6372.8
lat1, long1 = tuple(radians(c) for c in point_1)
lat2, long2 = tuple(radians(c) for c in point_2)
d = sin((lat2 - lat1) / 2.0) ** 2.0 + cos(lat1) * cos(lat2) * sin(
(long2 - long1) / 2.0) ** 2.0
return d_earth * asin(d ** 0.5)
def find_nearest(point_1: tuple, points: dict):
dists = {p: distance_haversine(point_1, points[p]) for p in points}
name, dist = min(dists.items(), key=lambda d: d[1])
return {'name': name, 'distance': dist,
'dist_coef': 3 if dist <= 1.0 else 2 if dist < 2.0 else 1}
metro_points = {
'Новокосино': (55.745113, 37.864052),
'Перово': (55.75098, 37.78422),
'Ховрино': (55.8777, 37.4877),
}
point_1 = (55.741298984107324, 37.415756143334846)
print(find_nearest(point_1, metro_points))
# {'name': 'Ховрино', 'distance': 15.823760672698684, 'dist_coef': 1}