2012-05-21 8 views
5

Mam zdefiniowany model miasta, który zapisuje geoname_id i location (jako GeoPt) miasta. Są dwie rzeczy, które chcę osiągnąć.Oblicz odległość między miastami i znajduj okoliczne miasta na podstawie GeoPT, w Pythonie na Google App Engine

  1. Chcę uzyskać wszystkie miasta w promieniu 500km od danego miasta.
  2. Chcę obliczyć odległość w km między dwoma podanymi miastami.

Jaki byłby najlepszy sposób, aby to osiągnąć, mając na uwadze, że mam bardzo dużą bazę danych miast i nie chcę poświęcać dużo na wydajności. Każda pomoc lub porada jest doceniana.

Odpowiedz

7

Działa to idealne, ale to lil slow:

Funkcja obliczyć odległość. Argumenty przekazywane do tej funkcji są krotki od szerokości i długości geograficznej lokalizacji lub 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 

Funkcja obliczania Sąsiednie miasta w promieniu. Jest to metoda w modelu City, w której są przechowywane wszystkie miasta:

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 nie obsługuje zapytań geoprzestrzennych, ale można odnieść się do: Geospatial Queries with Google App Engine using GeoModel.

Możesz również rozważyć użycie innych baz danych, takich jak mongoDB, które obsługują Geospatial Indexing i być może jako usługa zewnętrzna, która robi tylko to.

+0

Naprawdę nie chcę używać oddzielnej biblioteki, ponieważ mam już szerokość i długość geograficzną miast zapisanych w magazynie danych. Czy nie sądzisz, że proste obliczenia powinny zrobić, czy może sugerujesz użycie geomodelu? w jaki sposób wpłynie to na wydajność aplikacji? Dzięki za twoją odpowiedź. :) – Amyth

+0

Nie ma innej drogi ... chyba że masz zamiar zaimplementować własny indeksowanie gespatial .. ponieważ GAE po prostu go nie obsługuje. Powinieneś przynajmniej dać mu szansę na GeoModel. Wydajność zależy od wielkości magazynu danych i zdecydowanie zwiększy rozmiar indeksów. Przeczytaj dokumentację, aby zrozumieć, w jaki sposób ją osiągają. – Lipis

+0

Dzięki Lipis, przejdę teraz! – Amyth