геоиндексация: эффективный расчет близости на основе широты / долготы - PullRequest
4 голосов
/ 17 марта 2010

Мое простое веб-приложение (WSGI, Python) поддерживает текстовые запросы для поиска элементов в базе данных. Теперь я хотел бы расширить это, чтобы разрешить такие запросы, как «найти все элементы в пределах 1 мили от {lat, long}».

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

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

Ответы [ 2 ]

2 голосов
/ 02 июня 2011

Вы уже просмотрели dong Монго, у них есть функция геоиндексации. http://www.mongodb.org/display/DOCS/Geospatial+Indexing

1 голос
/ 26 августа 2011

Я мог бы подумать только об атаке в полусреднем порядке, если вы планируете реализовать ее напрямую с помощью Python, что я уже делал с аналогичными целями:

#!/usr/bin/python
from math import *
def distance(p1,p2):  # uses the haversine function and an ellipsoid model
    lat1, long1 = p1; lat2, long2 = p2
    lat1=radians(lat1); long1=radians(long1); lat2=radians(lat2); long2=radians(long2)
    maior=6378.137; menor=6356.7523142
    R=(maior*menor)/sqrt((maior*cos(lat1))**2 + (menor*sin(lat1))**2)
    d_lat = lat2 - lat1; d_long = long2 - long1
    a = sin(d_lat/2)**2 + cos(lat1) * cos(lat2) * sin(d_long/2)**2
    c = 2 * atan2(sqrt(a), sqrt(1-a))
    length = R * c
    x = sin(d_long) * cos(lat2)
    y = cos(lat2) * sin(lat1) - sin(lat2) * cos (lat1) * cos(d_long)
    bearing = 90-(degrees(atan2(y, -x)))
    return length, bearing

Для скрининга точек на расстояние вы можете сначала найти точки-кандидаты, чьи координаты "x" и "y" находятся внутри квадрата с центром в вашей тестовой позиции (намного быстрее), а затем просто проверить фактическое геодезическое расстояние.

Надеюсь, это поможет!

...