Take the 2-minute tour ×
Geographic Information Systems Stack Exchange is a question and answer site for cartographers, geographers and GIS professionals. It's 100% free, no registration required.

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. So is there a way to clear the constraint, so as to store both multipolygon and polygon type data?

share|improve this question
add comment

3 Answers

up vote 5 down vote accepted

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 extent 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)
share|improve this answer
    
The last method might be a good choice –  ChanDon Sep 7 '11 at 3:02
add comment

I know this is old, but I just ran into this issue myself and had problems using the above suggested solutions:

  • Using GeometryField makes it difficult to use the built-in OSMGeoAdmin class. The code in templates/gis/admin/openlayers.js (and contrib/gis/admin/widgets.py and probably other places I missed) frequently assumes that the geometry is a point, line, polygon, or collection, and never accounts for generic geometries. This isn't necessarily important or insurmountable, but if you were planning on using the built-in admin you might be disappointed.

  • Overriding save() doesn't work because the type-checking happens sooner, in the model's __set__().

My current solution is explicitly coercing all of my Polygons into MultiPolygons when importing and saving my data. I might override __set__() if this becomes cumbersome.

share|improve this answer
add comment

longish workaround

one could use fromstr()

from django.contrib.gis.geos import fromstr

p = Polygon()
# this seems to work correctly
mp = MultiPolygon(fromstr(str(p)),)

model1.geom_field = mp

model1.save()
share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.