Diese beiden sind nicht so eng miteinander verwandt. Dokumente sagen tatsächlich, dass es Distance-Objekt "zurückgibt", aber es gibt einen zusätzlichen Schritt:
django.contrib.gis. db.models .functions.Distance ist eine Datenbank Funktion, es dauert zwei Ausdrücke (die Datenbankfeldnamen enthalten können) und gibt ein Func Objekt zurück, das als Teil einer Abfrage verwendet werden kann.
Also einfach gesagt, es muss in einer Datenbank ausgeführt werden. Er berechnet die Entfernung unter Verwendung der Datenbankfunktion (z. B. postgis ST_Distance) und bringt sie dann als django.contrib.gis.measure.Distance Objekt zurück.
Also, es sei denn man zu Chaos mit SQL-Compiler und DB-Verbindungen will, einfachste Weg, Entfernung zwischen zwei Punkten zu erhalten, ist Distance(m=p1.distance(p2))
EDIT: Einige Code, um den Punkt zu illustrieren:
Sie können prüfen, Out-Code für die Entfernung (Messung) Klasse in django/contrib/gis/measure.py. Es ist ziemlich klein und leicht zu verstehen.Alles, was Sie eine bequeme Möglichkeit ist, was es tut zu tun Umwandlung, Vergleichs- und Rechenoperationen mit Entfernungen:
In [1]: from django.contrib.gis.measure import Distance
In [2]: d1 = Distance(mi=10)
In [3]: d2 = Distance(km=15)
In [4]: d1 > d2
Out[4]: True
In [5]: d1 + d2
Out[5]: Distance(mi=19.32056788356001)
In [6]: _.km
Out[6]: 31.09344
Nun schauen wir uns die Entfernung Funktion einen Blick:
hinzufügen __str__
Methode zum Modell, so dass wir siehe Distanzwert kann, wenn es durch die queryset api und kurze db_table Namen zurückgegeben, so dass wir in den Abfragen aussehen:
class MyModel(models.Model):
coordinates = models.PointField()
class Meta:
db_table = 'mymodel'
def __str__(self):
return f"{self.coordinates} {getattr(self, 'distance', '')}"
einige Objekte erstellen und machen eine einfache select * from
Abfrage:
012.351.
In [7]: from gisexperiments.models import MyModel
In [8]: from django.contrib.gis.geos import Point
In [10]: some_places = MyModel.objects.bulk_create(
...: MyModel(coordinates=Point(i, i, srid=4326)) for i in range(1, 5)
...:)
In [11]: MyModel.objects.all()
Out[11]: <QuerySet [<MyModel: SRID=4326;POINT (1 1) >, <MyModel: SRID=4326;POINT (2 2) >, <MyModel: SRID=4326;POINT (3 3) >, <MyModel: SRID=4326;POINT (4 4) >]>
In [12]: str(MyModel.objects.all().query)
Out[12]: 'SELECT "mymodel"."id", "mymodel"."coordinates" FROM "mymodel"'
Bohren. Lassen Sie sich Entfernung Funktion verwenden, um Abstandswert zum Ergebnis hinzu: berechne Abstand unter Verwendung von Werten aus "mymodel"."coordinates"
und Byte-Darstellung unseres origin
Punkt
In [14]: from django.contrib.gis.db.models.functions import Distance
In [15]: from django.contrib.gis.measure import D # an alias
In [16]: q = MyModel.objects.annotate(dist=Distance('coordinates', origin))
In [17]: list(q)
Out[17]:
[<MyModel: SRID=4326;POINT (1 1) 157249.597768505 m>,
<MyModel: SRID=4326;POINT (2 2) 314475.238061007 m>,
<MyModel: SRID=4326;POINT (3 3) 471652.937856715 m>,
<MyModel: SRID=4326;POINT (4 4) 628758.663018087 m>]
In [18]: str(q.query)
Out[18]: 'SELECT "mymodel"."id", "mymodel"."coordinates", ST_distance_sphere("mymodel"."coordinates", ST_GeomFromEWKB(\'\\001\\001\\000\\000 \\346\\020\\000\\000\\000\\000\\000\\000\\000\\000\\000\\000\\000\\000\\000\\000\\000\\000\\000\\000\'::bytea)) AS "distance" FROM "mymodel"'
Sie können sehen, es ST_distance_sphere
SQL-Funktion verwendet.
wir sie jetzt für die Filterung und Ordnung und viele andere Dinge verwenden können, die alle in der Datenbank-Management-System (schnell):
In [19]: q = q.filter(distance__lt=D(km=400).m)
In [20]: list(q)
Out[20]:
[<MyModel: SRID=4326;POINT (1 1) 157249.597768505 m>,
<MyModel: SRID=4326;POINT (2 2) 314475.238061007 m>]
Hinweis .m
Sie müssen Schwimmer Nummer an den Filter passieren, es gewann Objekt "Entfernung" kann nicht erkannt werden.
Lassen Sie mich wissen, wenn ich der Antwort einen Code hinzufügen muss. Ich wollte, aber kämpfte darum, etwas Minimales zu bekommen. Ich werde es später noch einmal versuchen – Igonato
Vielen Dank für die Antwort @Igonato, wenn Sie ein Code-Beispiel zur Verfügung stellen können, das wäre schön! Ich werde das Kopfgeld bei anderen Antworten behalten :) –
@JohnMoutafis hat etwas Code hinzugefügt. Ich bin ziemlich neu in GeoDjango, vielleicht gibt es einen besseren Weg, es zu erklären, aber das ist mein Bestes. Außerdem wurde ein Fehler behoben. Function Distance gibt Func zurück, kein Lookup-Objekt – Igonato