Сохранение центроида (мульти)многоугольника как геометрии точки в модели
У меня есть две таблицы, одна с многополигональными геометриями, другая с колонкой для точечных геометрий. Я хочу, чтобы центроид выбранного многоугольника сохранялся как геометрия точки для другой таблицы.
class matview_all_administrative_units(models.Model):
lau_id = models.IntegerField(primary_key=True)
ortsgemeinde = models.CharField(max_length=150)
verwaltungsgemeinde = models.CharField(max_length=150)
landkreis_bezirk = models.CharField(max_length=150)
bundesland_kanton = models.CharField(max_length=150)
staat = models.CharField(max_length=150)
geom = models.MultiPolygonField(srid=4326)
class Meta:
managed = False
db_table = 'administrative_hierarchy_full_geom'
class site(models.Model):
sid = models.AutoField(primary_key=True)
site_name = models.CharField(max_length=250)
site_notes = models.CharField(max_length=2500, blank=True, null=True)
municipality = models.ForeignKey('local_administrative_unit', on_delete=models.PROTECT)
geom = models.PointField(srid=4326)
def __str__(self):
return '{}, {} ({})'.format(self.sid, self.site_name, self.municipality)
Чтобы добавить новый сайт, с ним должна быть связана существующая административная единица, а центр ее полигона должен быть использован в качестве местоположения/геометрии сайта. На данный момент я сделал следующее:
class NewSiteView(CreateView):
model = models.site
form_class = forms.NewSiteForm
template_name = 'datamanager/newsite.html'
success_url = '/sites/'
вызов этой формы:
from django.forms import ModelForm, HiddenInput
from django.contrib.gis.db.models.functions import Centroid
from . import models
class NewSiteForm(ModelForm):
class Meta:
model = models.site
fields = ['site_name', 'site_notes', 'municipality','geom']
widgets = {
'geom': HiddenInput(),
}
def clean(self):
super().clean()
self.cleaned_data['geom'] = Centroid(models.matview_all_administrative_units.objects.values('geom').filter(lau_id=self.cleaned_data['municipality'].lau_id))
однако это приводит к такой ошибке:
Итак, я в основном вычисляю не точку, а "объект центроида" - пока все хорошо, документация django говорит нам об этом. Теперь я застрял, пытаясь получить что-то из этого центроида, что я могу засунуть в колонку геометрии. Насколько я понимаю, я беру правильные данные и передаю их правильной функции (иначе ошибка должна появиться раньше в этом коде, я думаю?), но результат не пригоден для вставки в колонку геометрии. Так как же мне добиться результата? (lol)
Наконец я нашел решение. Добавил это в CreateView:
def form_valid(self, form):
pol = models.local_administrative_unit.objects.values('geom').filter(lau_id=form.cleaned_data['municipality'].lau_id)[0]['geom']
cent_point = pol.centroid
form.instance.geom = cent_point.wkt
form.save()
return super().form_valid(form)
Я беру геометрию из полигона, вычисляю его центроид и вставляю его геометрию как известный текст в форму, затем сохраняю форму.