我在具有GeoDjango默认SRID WGS84的Postgis数据库中有几何图形,并且发现直接以度为单位的查找比以公里为单位的查找要快得多,因为该数据库可以跳过我认为的投影。

基本上,Place.objects.filter(location__distance__lte=(point, D(km=10)))Place.objects.filter(location__dwithin=(point, 10))慢几个数量级,因为第一个查询会生成对表的完整扫描。但是有时我需要查找距离阈值(以公里为单位)的地点。

是否有某种精确的方法可以将10公里转换为查询度数?
也许另一个等效的查询具有与我应该使用的相同的性能?

最佳答案

您有几种解决问题的方法,以下是其中两种:

如果您对精度不太在乎,可以使用dwithin并使用朴素的计量表对degree(x meters) -> x / 40000000 * 360进行度转换。在赤道附近您将获得几乎精确的结果,但是当您向北或向南走时,距离会缩小(该死的我们生活在一个球体上)。想象一个区域,该区域在开始时是一个圆形,并逐渐缩小到接近其中一个极点的无限窄椭圆形。

如果您关心精度,则可以使用:

max_distance = 10000 # distance in meter
buffer_width = max_distance / 40000000. * 360. / math.cos(point.y / 360. * math.pi)
buffered_point = point.buffer(buffer_width)
Place.objects.filter(
    location__distance__lte=(point, D(m=max_distance)),
    location__overlaps=buffered_point
)

基本思想是查询以point为单位的圆内的所有点。该部分的性能非常好,因为圆是度数,可以使用geo索引。但是圆圈有时太大了,因此我们以米为单位放置过滤器,以过滤出可能比允许的max_distance更远的地方。

关于django - 在GeoDjango和Postgis中以米为单位的最佳查询位置,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/31940674/

10-10 16:00