Finding the closest coordinates to a point

落花浮王杯 提交于 2021-01-29 11:55:47

问题


I have coordinates of city: (52.2319581, 21.0067249) and Python dictionary with cities around mentioned city. How to get 3 closest cities from given coordinates:

({'Brwinów': (52.133333, 20.716667), 'Warszawa Bielany': (52.283333, 20.966667), 'Legionowo': (52.4, 20.966667), 'Warszawa-Okęcie': (52.16039, 20.961674), 'Warszawa': (52.280957, 20.961348), 'Belsk Duży': (51.833333, 20.8)}, {})

Thanks for help.


回答1:


Without any external libraries

from math import acos, cos, sin

def gc_distance(first_point, second_point):
    return acos(sin(first_point[1]) * sin(second_point[1]) + cos(first_point[1]) * cos(second_point[1]) * cos(first_point[0] - second_point[0]))

def three_closest(city, cities):
    cities_distances = { key: gc_distance(city, value) for key, value in cities.items()}
    return [k for k, v in sorted(cities_distances.items(), key=lambda item: item[1])][:3]

Sample test:

>>> city = (52.2319581, 21.0067249)
>>> cities = {'Brwinów': (52.133333, 20.716667), 'Warszawa Bielany': (52.283333, 20.966667), 'Legionowo': (52.4, 20.966667), 'Warszawa-Okęcie': (52.16039, 20.961674), 'Warszawa': (52.280957, 20.961348), 'Belsk Duży': (51.833333, 20.8)}
>>> three_closest(city, cities)
['Warszawa Bielany', 'Warszawa', 'Warszawa-Okęcie']

If you want to return keys and values instead:

for result in three_closest(city, cities):
    print(result + " : " + str(cities[result]))

To get:

Warszawa Bielany : (52.283333, 20.966667)
Warszawa : (52.280957, 20.961348)
Warszawa-Okęcie : (52.16039, 20.961674)



回答2:


Everybody is recommending Euclidean distance for what are clearly spherical coordinates, which is very wrong when you're not close to the equator. In the example coordinates (Poland), around 52° latitude:
1° of latitude is still about 10000 km / 90° = 111 km, but
1° of longitude is only 10000 km * cos(52°) / 90° = 68 km.
So at the very least we have to use great-circle distance instead!

from math import sin, cos, acos

def angle(c1, 2):
  l1, p1 = c1
  l2, p2 = c2
  return acos(sin(p1) * sin(p2) + cos(p1) * cos(p2) * cos(l2 - l1))

sorted_coords = sorted(coords, key=lambda city: angle(city, center))
print(sorted_coords[:3])

More likely, these are not even spherical coordinates but WGS84, which uses a spheroid, but that distinction is unlikely to matter if an entire city can be treated as a point.




回答3:


Maybe this would work (this doesn't take into account the fact that one degree of longitude mean different distance at different latitudes).

the_city = (52.2319581, 21.0067249)
cities = ({'Brwinów': (52.133333, 20.716667), 'Warszawa Bielany': (52.283333, 20.966667), 'Legionowo': (52.4, 20.966667), 'Warszawa-Okęcie': (52.16039, 20.961674), 'Warszawa': (52.280957, 20.961348), 'Belsk Duży': (51.833333, 20.8)}, {})

closest3 = sorted(cities[0], key=lambda k: (cities[0][k][0]-the_city[0])**2 + (cities[0][k][1]-the_city[1])**2)[:3]


来源:https://stackoverflow.com/questions/61304137/finding-the-closest-coordinates-to-a-point

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!