Généraliser des polygones en multi-polygones dans GeoDjango?

9

J'ai mis en place un modèle avec models.PolygonFielddans geodjango, en utilisant postgres comme base de données. J'essaie d'importer shp dans postgres. Le problème est que shp (compilé avec QGIS) mélange polygone et multipolygone, donc il échoue toujours à faire l'exportation à cause de la vérification des contraintes enforce_geotype.

Existe-t-il un moyen de supprimer la contrainte, afin de stocker à la fois des données de type multipolygone et polygonal?

ChanDon
la source

Réponses:

10

Le SQL pour supprimer la contrainte:

ALTER TABLE myapp_mymodel DROP CONSTRAINT enforce_geotype_mygeom;

Ou pour le modifier pour autoriser à la fois les polygones et les multi-polygones:

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);

Ces instructions SQL peuvent être exécutées à partir d'une migration Sud ou d'un script SQL de données initiales .

Une autre option consiste à en faire un GeometryFielddans votre définition de modèle Django - cela lui permettra de stocker n'importe quel type de géométrie.

Ou, remplacez la save()méthode sur votre modèle pour forcer tout à être un 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)
rcoup
la source
La dernière méthode pourrait être un bon choix
ChanDon
5

solution de contournement longue

on pourrait utiliser 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()
user1725066
la source
4

Je sais que cela est ancien, mais je viens de rencontrer ce problème moi-même et j'ai eu des problèmes avec les solutions suggérées ci-dessus:

  • L'utilisation GeometryFieldrend difficile l'utilisation de la OSMGeoAdminclasse intégrée . Le code templates/gis/admin/openlayers.js(et contrib/gis/admin/widgets.pyprobablement d'autres endroits que j'ai manqués) suppose souvent que la géométrie est un point, une ligne, un polygone ou une collection, et ne tient jamais compte des géométries génériques. Ce n'est pas nécessairement important ou insurmontable, mais si vous envisagez d'utiliser l'administrateur intégré, vous pourriez être déçu.

  • Le remplacement save()ne fonctionne pas car la vérification de type a lieu plus tôt, dans le modèle __set__().

Ma solution actuelle contraint explicitement tous mes Polygons dans MultiPolygons lors de l'importation et de la sauvegarde de mes données. Je pourrais passer outre __set__()si cela devient lourd.

Eric Brelsford
la source