使用 Django 获取点查询集 (PointField) 的质心

Obtain centroid of a queryset of points (PointField) with Django

我需要使用 Django 获取点查询集 (PointField) 的质心

这是我的模型:

class GroupOfCities(models.Model)
    geomcentroid = models.PointField(srid=4326, blank=True, null=True)

class City(models.Model):
    centroid = models.PointField(srid=4326, blank=True, null=True)
    groupofcities = models.ForeignKey(GroupOfCities, null=True)

我需要获取每组城市的质心并将其保存到 geomcentroid

我想为一组城市做的例子:

from django.contrib.gis.db.models.functions import Centroid

firstgroupofcities = GroupeOfCities.objects.get(id=1)
cities = City.objects.filter(groupofcities=firstgroupofcities).annotate(cent=Centroid('centroid'))
firstgroupofcities.geomcentroid = cities.cent
firstgroupofcities.save()    

但是此 "Centroid" 功能仅适用于多边形。

有线索吗?

您可以遍历查询集并在 Python 中计算质心 -- 下面的代码未经测试,但该方法应该有效。

from django.contrib.gis.geos import Point

firstgroupofcities = GroupeOfCities.objects.get(id=1)
cities = City.objects.filter(groupofcities=firstgroupofcities)
x_average = 0
y_average = 0

for idx, city in enumerate(cities):
    x_average = x_average*(idx/(idx+1)) + city.centroid.coords[0]/(idx+1)
    y_average = y_average*(idx/(idx+1)) + city.centroid.coords[1]/(idx+1)

cent = Point(x_average, y_average)

firstgroupofcities.geomcentroid = cent
firstgroupofcities.save()

此外,您可能想要:

1) 运行 每次通过覆盖 save() 或使用 signals

更改 City 上的 fkey 关系时的计算

2) 每次需要数据时计算它,把它放在GroupOfCities

的方法中

最后,如果 none 有效并且您使用的是 Postgres 并且您需要在数据库中进行计算,您可能有一个替代方案:

https://postgis.net/docs/ST_MakePolygon.html

https://docs.djangoproject.com/en/2.0/topics/db/sql/

您需要使用Union聚合函数:

from django.contrib.gis.db.models.aggregates import Union
from django.contrib.gis.db.models.functions import Centroid

for goc in GroupOfCities.objects.annotate(cent=Centroid(Union('city_set__centroid')):
    goc.geomcentroid = goc.cent
    goc.save()

(它基本上创建了 "Centroid" 所需的 "polygon"。)