2017-07-18 137 views
2

我想检索一些职位,取决于他们的地理位置邻近。
正如您在代码中看到的,我正在使用GeoDjango,代码在视图中执行。
问题是距离过滤器似乎被完全忽略。Geodjango距离查询不检索正确的结果

当我检查查询集的距离时,我得到预期的距离(1米和18公里),但18公里的职位不应该被检索。

def get(self, request, format=None): 
    latlon=request.query_params 
    pnt = GEOSGeometry('SRID=28992;POINT(%s %s)'%(latlon['lat'],latlon['lon'])) 
    posts = Post.objects.filter(point__distance_lte=(pnt, D(km=1))) 
    serialized = PostSerializer(posts, many=True) 
    for post in posts: 
     distance = pnt.distance(post.point) 
     print("Km distance:",distance * 100) 
    return JsonResponse(serialized.data, safe=False) 

结果:

Km distance: 0.00015231546206626192 
Km distance: 18.317378752081577 
[18/Jul/2017 13:24:35] "GET /api/posts/?lon=5.8372264&lat=51.8125626 HTTP/1.1" 200 144 

回答

1

我相信,你的问题在你点创建的reverse order of lat and lon出现。

作为一个方面说明,我更喜欢使用的点创建Point()方法:

ptn = Point(x=latlon['lon'], y=latlon['lat'], srid=28992) 

编辑由于此评论:

我试过了初始化,它对我来说似乎是正确的谢谢你。然而,它似乎没有解决这个问题。它几乎看起来像默认距离单位是十进制数,因为这可以正常工作。 posts = Post.objects.filter(point__distance_lte=(pnt, 0.05))范围5公里之内这个搜索 - 埃文

由于上述未解决您的问题,我会假设dwithin's know problem with Distance objects适用于distance查询也是如此。

正如上面链接的解决方案中所述,几何字段默认为WGS84,其中degrees作为默认测量单位。

0.05 degrees ~= 5 km,这就是您的解决方案正常工作的原因。

也许geodjango团队应该被告知这个?

+0

我试过这个初始化器,对我来说似乎更正确的谢谢你。但它似乎并没有解决这个问题。它几乎看起来像默认距离单位是十进制数,因为这可以正常工作。 'posts = Post.objects.filter(point__distance_lte =(pnt,0。05))'这个搜索范围在5km以内 – Evan

+0

@Evan正如我在这里看到的:https://epsg.io/28992,默认单位是米。我编辑了我的答案,包括对该问题的可能解释。 –

0

相同SRID?我使用这个有很多,但与

source = models.PointField(geography=True, srid=4326) 

然后管理器中:

def starts_within_range_of(self, my_start, distance): 
    ret_value = self.filter(
     source__distance_lte=(my_start, distance)) 
    return ret_value 

但百达与4326

+0

是的,srid是一样的。我有点使它的工作,但它不是很优雅。 这似乎工作'您= Post = Post.objects.filter(point__distance_lte =(pnt,米* 1e-05))' – Evan

+0

:'pnt = django.contrib.gis.geos.Point(x = 51.8125626,y = 5.8372264,srid = 28992)'? – mbieren

+0

不,我没有尝试过,但我不认为问题是'pnt'因为我在'for'循环中使用它,它提供了很好的距离。 – Evan