Uogólniasz wielokąty na wielokąty w GeoDjango?

9

Skonfigurowałem model models.PolygonFieldw geodjango, używając bazy danych postgres. Próbuję zaimportować shp do postgres. Problem polega na tym, że shp (skompilowane z QGIS) miesza wielokąty i wieloboki, dlatego zawsze nie wykonuje eksportu z powodu sprawdzenia ograniczenia enforce_geotype.

Czy istnieje sposób na usunięcie ograniczenia, aby przechowywać zarówno dane typu wielokąta, jak i wielokąta?

ChanDon
źródło

Odpowiedzi:

10

Kod SQL do usunięcia ograniczenia:

ALTER TABLE myapp_mymodel DROP CONSTRAINT enforce_geotype_mygeom;

Lub zmień go, aby zezwolił zarówno na wielokąty, jak i na wielokąty:

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

Te instrukcje SQL można uruchomić z migracji południowej lub ze skryptu SQL danych początkowych .

Inną opcją jest ustawienie go GeometryFieldw definicji modelu Django - pozwoli to na przechowywanie dowolnego typu geometrii.

Lub zastąp save()metodę w swoim modelu, aby wymusić, aby wszystko było 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
źródło
Ostatnia metoda może być dobrym wyborem
ChanDon,
5

długotrwałe obejście

można użyć 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()
użytkownik1725066
źródło
4

Wiem, że to stare, ale sam wpadłem na ten problem i miałem problemy z użyciem wyżej sugerowanych rozwiązań:

  • Używanie GeometryFieldutrudnia korzystanie z wbudowanej OSMGeoAdminklasy. Kod w templates/gis/admin/openlayers.js(i contrib/gis/admin/widgets.pyprawdopodobnie w innych miejscach, za którymi tęskniłem) często zakłada, że ​​geometria to punkt, linia, wielokąt lub zbiór i nigdy nie uwzględnia ogólnych geometrii. Niekoniecznie jest to ważne lub nie do pokonania, ale jeśli planujesz korzystać z wbudowanego administratora, możesz być rozczarowany.

  • Przesłanianie save()nie działa, ponieważ sprawdzanie typu odbywa się wcześniej w modelu __set__().

Moje obecne rozwiązanie wyraźnie zmusza wszystkie moje Polygonpliki do MultiPolygonimportowania i zapisywania moich danych. Mogę to zmienić, __set__()jeśli stanie się to uciążliwe.

Eric Brelsford
źródło