GeoDjango距离查询返回错误结果

9

我刚在我的开发机上启动了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>]

问题在于这些地方距离point的距离远远超过1米。
我尝试了一些操作,但是没有太大的运气。这里有一个使用另一个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
你可能想在这里尝试询问:http://gis.stackexchange.com/ - pleasedontbelong
谢谢提醒,我不知道StackExchange有一个专门用于GIS相关问题的网站。不知道我应该在这里继续发布,还是等待管理员将其移动。 - dwlz
1个回答

9

很抱歉回答自己的问题,但没有其他人站出来解决问题,所以我想到了解决方案。

我深入研究了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的源代码,以弄清楚这里发生了什么,我意识到我在我的coordinates字段上设置了geography=True。显然,这会更改Django生成的PostGIS函数在创建SQL查询时的行为。虽然此功能未记录在文档中,但这是相关部分
简而言之,如果你遇到这个问题,请从你的模型中删除geography=True,这样就可以解决了。

1
嗨,丹,我有一个类似的问题:http://gis.stackexchange.com/questions/14232/using-a-geodjango-pointfield-with-geograph-true-my-distance-calculations-are-6-o。理论上,在geography=True下使用ST_Distance_Spheroid应该更准确地计算距离。除了删除geography=True(这会让我回到原点...)之外,您有什么建议吗?谢谢。 - Griffith Rees

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接