Рассчитайте расстояние между городами и найдите близлежащие города на основе GeoPT в Python на Google App Engine.

У меня определена модель города, которая сохраняет geoname_id и location (как GeoPt) города. Есть две вещи, которых я хочу достичь.

  1. Я хочу получить все города в радиусе 500km от заданного города.
  2. Я хочу рассчитать расстояние в km между двумя заданными городами.

Каким будет лучший способ добиться этого, имея в виду, что у меня очень большая база данных городов, и я не хочу сильно жертвовать фактором производительности. Любая помощь или совет приветствуются.


person Amyth    schedule 21.05.2012    source источник


Ответы (3)


Это работает отлично, но немного медленно:

Функция для расчета расстояния. Аргументы, передаваемые этой функции, представляют собой кортежи широты и долготы местоположения или Geopt():

def HaversineDistance(location1, location2):
  """Method to calculate Distance between two sets of Lat/Lon."""
  lat1, lon1 = location1
  lat2, lon2 = location2
  earth = 6371 #Earth's Radius in Kms.

 #Calculate Distance based in Haversine Formula
 dlat = math.radians(lat2-lat1)
 dlon = math.radians(lon2-lon1)
 a = math.sin(dlat/2) * math.sin(dlat/2) + math.cos(math.radians(lat1)) * math.cos(math.radians(lat2)) * math.sin(dlon/2) * math.sin(dlon/2)
 c = 2 * math.atan2(math.sqrt(a), math.sqrt(1-a))
 d = earth * c
 return d

Функция для расчета близлежащих городов в радиусе. Это метод модели City, в которой хранятся все города:

def get_closest_cities(self, kms):
  cities = []
  #Find surrounding Cities of a given city within a given radius
  allcities = self.country.city_set
  for city in allcities:
    distance = HaversineDistance((self.location.lat, self.location.lon),(city.location.lat, city.location.lon))
    if not distance >= kms:
      cities.append((city.name, int(distance)))
  cities.remove(cities[0])
  return cities
person Amyth    schedule 22.05.2012

Google App Engine не поддерживает геопространственные запросы, но вы можете обратиться к Геопространственные запросы с Google App Engine с помощью GeoModel. .

Вы также можете рассмотреть возможность использования других баз данных, таких как mongoDB, которые поддерживают геопространственное индексирование и, возможно, имея его как внешний сервис, который делает только это.

person Lipis    schedule 22.05.2012
comment
я действительно не хочу использовать для этого отдельную библиотеку, так как у меня уже есть широта и долгота городов, сохраненные в хранилище данных. Вам не кажется, что достаточно простого расчета, или вы предлагаете использовать геомодель? как это повлияет на производительность приложения? Спасибо за ваш ответ. :) - person Amyth; 22.05.2012
comment
Другого пути нет... если только вы не собираетесь реализовывать свою собственную геопространственную индексацию... потому что GAE просто не поддерживает ее. Вы должны хотя бы попробовать с GeoModel. Производительность зависит от размера вашего хранилища данных, и это определенно увеличит размер ваших индексов. Прочтите документацию, чтобы понять, как они этого добиваются. - person Lipis; 22.05.2012
comment
Спасибо, Липис, сейчас пройдусь! - person Amyth; 22.05.2012