I have two tables, one with multipolygon geometries, the other with a column for point geometries. I want the centroid of the selected polygon to be saved as the point geometry for the other table.
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)
To add a new site, an existing administrative unit must be associated with it and the center of it's polygon should be used as the location/geometry of the site. For now I made this:
class NewSiteView(CreateView):
model = models.site
form_class = forms.NewSiteForm
template_name = 'datamanager/newsite.html'
success_url = '/sites/'
calling this form:
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))
however, this leads to this error:
So I am basically not calculating a point but a 'centroid object' - so far so good, the django documentation tells us that. Now I am stuck trying to get something out of this centroid thingy that I can shove into that geometry column. As far as I understand I take the right data and handle it over to the right function (otherwise the error should appear earlier in this code i think?), but the result is not useful for inserting it into a geometry column. So how do i get my point? (lol)
finally I found a solution. Added this to the 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)
I takes the geometry from the polygon, calculates the centroid of it and inserts it's geometry as well-known text into the form, then saves the form.