GeoDjango和Postgis中以米为单位的位置的最佳查询

问题描述 投票:3回答:1

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

基本上,Place.objects.filter(location__distance__lte=(point, D(km=10)))Place.objects.filter(location__dwithin=(point, 10))慢几个数量级,因为第一个查询将对表进行全面扫描。但是有时我需要查找距离阈值以千米为单位的地方。

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

django geolocation gis postgis geodjango
1个回答
2
投票

您有几种解决问题的方法,这里有两种:

如果您不太在乎精度,则可以使用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远一些的地方。

© www.soinside.com 2019 - 2024. All rights reserved.