GeoDjango – Generalizing Polygons to MultiPolygons

geodjangopolygonpostgisqgis

I set up a model with models.PolygonField in geodjango, using postgres as database. I try to import shp into postgres. The problem is, shp (compiled with QGIS) mixes polygon and multipolygon, hence it always fails to do the export because of the constraint check enforce_geotype.

Is there a way to clear the constraint, so as to store both multipolygon and polygon type data?

Best Answer

The SQL to drop the constraint:

ALTER TABLE myapp_mymodel DROP CONSTRAINT enforce_geotype_mygeom;

Or to alter it to allow both Polygons & MultiPolygons:

ALTER TABLE myapp_mymodel DROP CONSTRAINT enforce_geotype_mygeom;
ALTER TABLE myapp_mymodel ADD CONSTRAINT enforce_geotype_mygeom CHECK (geometrytype(mygeom) = 'POLYGON'::text OR geometrytype(mygeom) = 'MULTIPOLYGON'::text OR mygeom IS NULL);

These SQL statements could be run from a South migration or an initial-data SQL script.

Another option is to make it a GeometryField in your Django model definition - this will allow it to store any geometry type.

Or, override the save() method on your model to force everything to be a MultiPolygon:

from django.contrib.gis.db import models
from django.contrib.gis import geos

class MyModel(models.Model):
  mygeom = models.MultiPolygonField()
  ... other fields....

  def save(self, *args, **kwargs):
    # if mygeom ends up as a Polgon, make it into a MultiPolygon
    if self.mygeom and isinstance(self.mygeom, geos.Polygon):
      self.mygeom = geos.MultiPolygon(self.mygeom)

    super(MyModel).save(*args, **kwargs)
Related Question