Generalizando polígonos para multi polígonos no GeoDjango?

9

Eu configurei um modelo models.PolygonFieldno geodjango, usando o postgres como banco de dados. Eu tento importar o shp para o postgres. O problema é que o shp (compilado com QGIS) combina polígono e multipolígono, portanto, sempre falha na exportação devido à verificação de restrição enforce_geotype.

Existe uma maneira de limpar a restrição, de modo a armazenar dados do tipo multipolígono e polígono?

ChanDon
fonte

Respostas:

10

O SQL para eliminar a restrição:

ALTER TABLE myapp_mymodel DROP CONSTRAINT enforce_geotype_mygeom;

Ou altere-o para permitir Polígonos e MultiPolígonos:

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

Essas instruções SQL podem ser executadas a partir de uma migração do Sul ou de um script SQL de dados iniciais .

Outra opção é transformá-lo GeometryFieldem sua definição de modelo do Django - isso permitirá armazenar qualquer tipo de geometria.

Ou substitua o save()método no seu modelo para forçar tudo a ser um 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
fonte
O último método pode ser uma boa escolha
Chandon
5

solução alternativa demorada

alguém poderia usar 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
fonte
4

Sei que isso é antigo, mas acabei de me deparar com esse problema e tive problemas ao usar as soluções sugeridas acima:

  • O uso GeometryFielddificulta o uso da OSMGeoAdminclasse interna. O código templates/gis/admin/openlayers.js(e contrib/gis/admin/widgets.pyprovavelmente outros lugares que eu perdi) freqüentemente pressupõe que a geometria é um ponto, linha, polígono ou coleção e nunca é responsável por geometrias genéricas. Isso não é necessariamente importante ou intransponível, mas se você planeja usar o administrador interno, pode se decepcionar.

  • A substituição save()não funciona porque a verificação de tipo acontece mais cedo, no modelo __set__().

Minha solução atual é explicitamente coagir todos os meus Polygons em MultiPolygons ao importar e salvar meus dados. Eu poderia substituir __set__()se isso se tornar complicado.

Eric Brelsford
fonte