我正在使用
第一个问题
我需要使用GeoDjango来计算两点之间的距离。当我检查documentation时,它说 GeoQuerySet.distance()已弃用,而是使用 django.contrib.gis.db中的距离() .models.functions
以下代码可以正常工作:
from django.contrib.gis.db.models.functions import Distance
p1 = Instrument.objects.get(pk=151071000).coordinates
p2 = Instrument.objects.filter(pk=151071008)
for i in p2.annotate(distance=Distance('coordinates', p1)):
print i.distance
print i.distance.__class__
输出:
461.10913945 m
<class 'django.contrib.gis.measure.Distance'>
我的模特:
class Instrument(models.Model):
...
coordinates = gis_models.PointField(null=True, blank=True, dim=3)
但我只有两点,所以当我尝试使用Distance()而没有 annotate()时,它会返回类 django.contrib.gis.db.models.functions.Distance的实例()比 django.contrib.gis.measure.Distance():
p1 = Instrument.objects.get(pk=151071000).coordinates
p2 = Instrument.objects.get(pk=151071008).coordinates
print Distance(p1, p2)
输出:
Distance(Value(SRID=4326;POINT Z (-76.48623600000001 44.260223 0)), GeomValue(SRID=4326;POINT Z (-76.490923 44.262658 0)))
如何获得与使用 annotate()相同的结果?
第二个问题
我必须计算考虑深度/高度的3d距离。但是当我尝试这样做时,我得到与2d相同的结果。下面我在第一个对象中将高程更改为200:
p1 = Instrument.objects.get(pk=151071000)
p1.coordinates = 'SRID=4326;POINT Z (-76.48623600000001 44.260223 200)'
p2 = Instrument.objects.filter(pk=151071008)
for i in p2.annotate(distance=Distance('coordinates', p1.coordinates)):
print i.distance
输出:
461.10913945 m
答案 0 :(得分:1)
让我们解决问题:
在Distance课程文档中,我们可以阅读以下内容:
接受两个地理字段或表达式,并返回它们之间的距离,作为距离对象。
因此Distance(p1, p2)
会返回Distance
object
如果你这样做:
p1 = Instrument.objects.get(pk=151071000).coordinates
p2 = Instrument.objects.get(pk=151071008).coordinates
d = Distance(m=p1.distance(p2))
print d.m
您将以米为单位进行测量。
我会坚持使用annotate
解决方案,这似乎更加坚固! (见解答)
Distance
计算两点之间的2D距离。为了获得3D计算,您需要自己创建一个。
您可以从这个问题中查看我的方法:Calculating distance between two points using latitude longitude and altitude (elevation)
设polar_point_1 =(long_1,lat_1,alt_1)和polar_point_2 = (long_2,lat_2,alt_2)
利用此功能将每个点转换为笛卡尔等效值 式:
x = alt * cos(lat) * sin(long) y = alt * sin(lat) z = alt * cos(lat) * cos(long)
您将分别获得p_1 =(x_1,y_1,z_1)和p_2 =(x_2,y_2,z_2)点。
最后使用欧几里德公式:
dist = sqrt((x_2-x_1)**2 + (y_2-y_1)**2 + (z_2-z_1)**2)
答案 1 :(得分:0)
** python 3.7,Django 2.2.10
我写了一些有用的功能来帮助我处理应用程序中的经/纬度坐标
"ß".compareIgnoreCase("SS")
其中measurement_unit可以是以下任意一项:
from django.contrib.gis.geos import Point
from django.contrib.gis.measure import Distance
def get_point(lat, lon):
try:
lat = float(lat)
lon = float(lon)
if lat and lon:
return Point(x=float(round(lon, 6)), y=float(round(lat, 6)), srid=4326)
else:
return None
except Exception:
return None
def get_point_to_point_distance(point_one, point_two, measurement_unit="mile"):
return Distance(**{measurement_unit: point_one.distance(point_two)})