2017-07-18 3 views
2

Ich versuche, einige Beiträge abhängig von ihrer geografischen Nähe abrufen.
Wie Sie im Code sehen können, verwende ich GeoDjango und der Code wird innerhalb einer Ansicht ausgeführt.
Das Problem ist, dass der Entfernungsfilter vollständig ignoriert wird.Geodjango Entfernung Abfrage nicht korrekte Ergebnisse abrufen

Wenn ich die Abstände auf dem Queryset überprüfe, bekomme ich die erwarteten Distanzen (1m und 18km), aber die 18km Post sollte nicht abgerufen werden.

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) 

Ergebnis:

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 

Antwort

1

Ich glaube, dass das Problem von den reverse order of lat and lon in Ihrem Punkt Schöpfung entsteht.

Als Randbemerkung, ziehe ich die Point() Methode für Punkt Erstellung:

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

bearbeiten aufgrund dieser Kommentar:

ich das initializer versucht, es scheint mir richtig zu sein danke. Es scheint jedoch das Problem nicht gelöst zu haben. Es sieht fast so aus, als ob die Standard-Entfernungseinheit Dekameter ist, weil dies korrekt funktioniert. posts = Post.objects.filter(point__distance_lte=(pnt, 0.05)) diese Suche in einem Bereich von 5km - Evan

Da die oben hatte Ihr Problem nicht lösen, Ich gehe davon aus, dass die dwithin's know problem with Distance objects als auch auf die distance Abfragen anwenden.

Wie in der oben verlinkten Lösung angegeben, sind Geometriefelder standardmäßig WGS84, die degrees als Standardmaßeinheit haben.

0.05 degrees ~= 5 km, und deshalb hat Ihre Lösung richtig funktioniert.

Vielleicht sollte das Geodjango-Team darüber informiert werden?

+0

Ich habe diesen Initialisierer ausprobiert, es scheint mir korrekter zu sein, danke. Es scheint jedoch das Problem nicht gelöst zu haben. Es sieht fast so aus, als ob die Standard-Entfernungseinheit Dekameter ist, weil dies korrekt funktioniert. 'posts = Post.objects.filter (point_distance_lte = (pnt, 0.05)) 'das sucht innerhalb einer Reichweite von 5km – Evan

+0

@Evan Wie ich hier sehe: https://epsg.io/28992, ist die Standardeinheit Meter. Ich habe meine Antwort so bearbeitet, dass sie eine mögliche Erklärung für das Problem enthält. –

0

Same SRID? Ich verwende dies viel, aber mit

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

und dann innerhalb eines Managers:

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

aber durchweg mit 4326

+0

Ja, das Srid ist das gleiche. Ich habe es irgendwie funktioniert, aber es ist nicht sehr elegant. Dies scheint zu funktionieren 'posts = Post.objects.filter (point_distance_lte = (pnt, meter * 1e-05))' – Evan

+0

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

+0

Nein, ich habe es nicht versucht, aber ich denke nicht, dass das Problem mit dem Punkt "pnt" ist, da ich es in der 'for' Schleife verwende und es gibt gute Entfernungen. – Evan

Verwandte Themen