Generalizzare poligoni a multipoli in GeoDjango?


9

Ho creato un modello con models.PolygonFieldin geodjango, usando Postgres come database. Provo a importare shp in postgres. Il problema è che shp (compilato con QGIS) mescola poligono e multipoligono, quindi non riesce sempre a fare l'esportazione a causa del controllo dei vincoli enforce_geotype.

Esiste un modo per eliminare il vincolo, in modo da memorizzare sia i dati di tipo multipoligono che poligonale?

Risposte:


10

L'SQL per eliminare il vincolo:

ALTER TABLE myapp_mymodel DROP CONSTRAINT enforce_geotype_mygeom;

O per modificarlo per consentire sia poligoni che multipoli:

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

Queste istruzioni SQL possono essere eseguite da una migrazione sud o da uno script SQL con dati iniziali .

Un'altra opzione è di renderlo un GeometryFieldnella tua definizione del modello Django - questo gli permetterà di memorizzare qualsiasi tipo di geometria.

Oppure, sovrascrivi il save()metodo sul tuo modello per forzare tutto ad essere un multipoligono:

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)

L'ultimo metodo potrebbe essere una buona scelta
ChanDon

5

soluzione a lungo termine

si potrebbe usare 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()

4

So che questo è vecchio, ma mi sono appena imbattuto in questo problema e ho avuto problemi con le soluzioni suggerite sopra:

  • L'utilizzo GeometryFieldrende difficile l'utilizzo della OSMGeoAdminclasse integrata . Il codice in templates/gis/admin/openlayers.js(e contrib/gis/admin/widgets.pyprobabilmente in altri luoghi che mi sono perso) presume spesso che la geometria sia un punto, una linea, un poligono o una raccolta e non tiene mai conto di geometrie generiche. Questo non è necessariamente importante o insormontabile, ma se stavi pianificando di utilizzare l'amministratore integrato potresti essere deluso.

  • L'override save()non funziona perché il controllo del tipo avviene prima, nel modello __set__().

La mia soluzione attuale sta esplicitamente riunendo tutte le mie Polygons in MultiPolygons durante l'importazione e il salvataggio dei miei dati. Potrei scavalcare __set__()se questo diventa ingombrante.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.