Verallgemeinern von Polygonen zu MultiPolygonen in GeoDjango?

9

Ich habe ein Modell mit models.PolygonFieldin Geodjango erstellt und Postgres als Datenbank verwendet. Ich versuche shp in postgres zu importieren. Das Problem ist, dass shp (kompiliert mit QGIS) Polygon und Multipolygon mischt und daher den Export aufgrund der Einschränkungsprüfung immer nicht ausführt enforce_geotype.

Gibt es eine Möglichkeit, die Einschränkung zu löschen, um sowohl Multipolygon- als auch Polygontypdaten zu speichern?

ChanDon
quelle

Antworten:

10

Die SQL zum Löschen der Einschränkung:

ALTER TABLE myapp_mymodel DROP CONSTRAINT enforce_geotype_mygeom;

Oder um es zu ändern, um sowohl Polygone als auch MultiPolygone zuzulassen:

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

Diese SQL-Anweisungen können über eine South-Migration oder ein SQL-Skript mit Anfangsdaten ausgeführt werden .

Eine andere Möglichkeit besteht darin, es GeometryFieldin Ihre Django-Modelldefinition aufzunehmen. Dadurch kann es jeden Geometrietyp speichern.

Oder überschreiben Sie die save()Methode in Ihrem Modell, um zu erzwingen, dass alles ein MultiPolygon ist:

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
quelle
Die letzte Methode könnte eine gute Wahl sein
ChanDon
5

längere Problemumgehung

man könnte fromstr () verwenden

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
quelle
4

Ich weiß, dass dies alt ist, aber ich bin gerade selbst auf dieses Problem gestoßen und hatte Probleme mit den oben vorgeschlagenen Lösungen:

  • Die Verwendung GeometryFieldmacht es schwierig, die integrierte OSMGeoAdminKlasse zu verwenden. Der Code an templates/gis/admin/openlayers.js(und contrib/gis/admin/widgets.pywahrscheinlich an anderen Stellen, die ich verpasst habe) geht häufig davon aus, dass die Geometrie ein Punkt, eine Linie, ein Polygon oder eine Sammlung ist und niemals generische Geometrien berücksichtigt. Dies ist nicht unbedingt wichtig oder unüberwindbar, aber wenn Sie vorhaben, den integrierten Administrator zu verwenden, werden Sie möglicherweise enttäuscht sein.

  • Das Überschreiben save()funktioniert nicht, da die Typprüfung im Modell früher erfolgt __set__().

Meine aktuelle Lösung besteht darin, beim Importieren und Speichern meiner Daten alle meine Polygons explizit in MultiPolygons zu zwingen . Ich könnte überschreiben, __set__()wenn dies umständlich wird.

Eric Brelsford
quelle