2012-05-21 43 views
5

Tengo un modelo de ciudades define lo que ahorra el geoname_id y location (como GeoPt) de una ciudad. Hay dos cosas que quiero lograr.Calcular distancia entre ciudades y encontrar ciudades que rodean a base de GeoPt, en Python en Google App Engine

  1. Quiero obtener todas las ciudades dentro de 500km radio de una ciudad determinada.
  2. Quiero calcular la distancia en km entre dos ciudades determinadas.

¿Cuál sería la mejor manera de lograr esto, teniendo en cuenta que tengo una gran base de datos de ciudades y no quiero sacrificar mucho en el factor de rendimiento. Cualquier ayuda o consejo es apreciado.

Respuesta

7

Esto funciona perfecto, pero es un lil lento:

Función para calcular la distancia. Los argumentos que se pasan a esta función son tuplas de latitud y longitud de un lugar o una 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 

función para calcular las ciudades circundantes dentro de un radio. Este es un método bajo el modelo City que almacena todas las ciudades:

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 
3

Google App Engine no admite consultas geoespaciales, pero puede consultar Geospatial Queries with Google App Engine using GeoModel.

También podría considerar el uso de otras bases de datos como mongoDB que admitan Geospatial Indexing y quizás tenerlo como un servicio externo que solo hace eso.

+0

Realmente no quiero utilizar una biblioteca separada para esto ya que ya tengo la latitud y la longitud de las ciudades guardadas en el almacén de datos. ¿No cree que debería hacer un simple cálculo o sugeriría usar geomodel? ¿Cómo afectaría el rendimiento de la aplicación? Gracias por su respuesta. :) – Amyth

+0

No hay otra manera ... a menos que vayas a implementar tu propia indexación gespatial ... porque GAE simplemente no la admite. Al menos debería darle una oportunidad con GeoModel. El rendimiento depende del tamaño de su almacén de datos, y definitivamente va a aumentar el tamaño de sus índices. Lea la documentación para comprender cómo la están logrando. – Lipis

+0

Gracias Lipis, voy a pasar por eso ahora! – Amyth

Cuestiones relacionadas