GeoDjango дистанционные запросы, возвращающие неверные результаты - PullRequest
8 голосов
/ 28 июля 2011

Я только что запустил GeoDjango на моей машине для разработки. Проблема в том, что я не могу заставить дистанционный запрос работать правильно. Независимо от того, какой SRID я использую, результаты на расстоянии полностью отключены. Вот пример.

>>> from django.contrib.gis.measure import D
>>> from app.models import Place
>>> from django.contrib.gis.geos import Point
>>> qs = Place.objects.all()
>>> point = Point(-118, 34)
>>> qs.filter(coordinates__distance_lte=(point, D(m=1)))
[<Place: 7-Eleven>, <Place: Arthur Murray Dance Studio>, <Place: Costco>, <Place: AMC Century City 15>, <Place: 24 Hour Fitness>, <Place: Ralphs>, <Place: Houston's Restaurant>, <Place: CVS/pharmacy>, <Place: Shaky Alibi>, <Place: Sephora>, <Place: Trader Joe's>]

Проблема в том, что эти места намного дальше, чем 1 м от point.

Я пытался поиграть с этим, но мне не повезло. Вот пример с другим SRID.

>>> qs = Place.objects.all().transform(3786)
>>> point = Point(-118, 34, srid=3786)
>>> qs.filter(coordinates__distance_lte=(point, D(m=1)))
[<Place: 7-Eleven>, <Place: Arthur Murray Dance Studio>, <Place: Costco>, <Place: AMC Century City 15>, <Place: 24 Hour Fitness>, <Place: Ralphs>, <Place: Houston's Restaurant>, <Place: CVS/pharmacy>, <Place: Shaky Alibi>, <Place: Sephora>, <Place: Trader Joe's>]

У меня такое ощущение, что я просто выбираю неправильные идентификаторы SRID, но ни один из них, с которыми я сталкивался в сети, не сработал или дал какой-либо ответ, который даже умеренно полезен.

Любая помощь очень ценится!

1 Ответ

9 голосов
/ 29 июля 2011

Ненавижу отвечать на свой вопрос, но никто не подошел к тарелке, и я нашел решение.

Я углубился в PostGIS, чтобы изолировать проблему либо в самой базе данных локаций, либо в Django. Поэтому я преобразовал запрос Django ORM, который я использовал выше, в идеальный запрос, который я ожидал получить от бэкэнда PostGIS. К моему удивлению, производимый запрос был эквивалентен:

SELECT id
FROM app_place
WHERE ST_DWithin(coordinates, ST_SetSRID(ST_Point(-118, 34), 3768), 1);

В этом и была проблема. Мне нужен был запрос:

SELECT id
FROM app_place
WHERE ST_Distance_Sphere(ST_SetSRID(ST_Point(-118, 34), 3768), coordinates) < 1;

Я прочитал источник Django, чтобы выяснить, что здесь происходит, и понял, что установил geography=True в своем поле coordinates. Очевидно, это изменяет функции PostGIS, которые Django генерирует при создании SQL-запроса. Это недокументировано, но вот соответствующий раздел .

Короче говоря, если у вас возникла эта проблема, удалите geography=True из вашей модели, и все будет хорошо.

...