使用 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 并且您需要在数据库中进行计算,您可能有一个替代方案:
您需要使用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"。)
我需要使用 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 并且您需要在数据库中进行计算,您可能有一个替代方案:
您需要使用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"。)