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)
Advertisement
Answer
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.