使用Django

时间:2018-03-19 16:51:25

标签: python django geodjango centroid

我需要使用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”功能仅适用于多边形。

有任何线索吗?

2 个答案:

答案 0 :(得分:0)

您可以迭代查询集并在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)每次通过覆盖City或使用signals更改save()上的fkey关系时运行计算

OR

2)每次需要数据时将其计算为GroupOfCities

的方法

最后,如果这些都不起作用并且您正在使用Postgres并且您需要在数据库中进行计算,那么您可以使用以下方法进行计算:

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

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

答案 1 :(得分:0)

您需要使用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()

(它基本上会创建“中心”所需的“多边形”。)