我在具有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/