10 votos

Generalizando Polígonos a MultiPolígonos en GeoDjango?

Configuré un modelo con models.PolygonField en Geodjango, usando Postgres como base de datos. Intenté importar un archivo SHP en Postgres. El problema es que el SHP (compilado con QGIS) mezcla polígonos y multipolígonos, por lo que siempre falla al exportar debido a la restricción de verificación enforce_geotype.

¿Existe alguna manera de eliminar la restricción para poder almacenar tanto datos de tipo multipolígono como de polígono?

11voto

trent Puntos 2940

El SQL para eliminar la restricción:

ALTER TABLE myapp_mymodel DROP CONSTRAINT enforce_geotype_mygeom;

O para modificarlo para permitir tanto Polígonos como 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);

Estas declaraciones SQL podrían ser ejecutadas desde una migración de South o un script SQL de datos iniciales.

Otra opción es hacerlo un GeometryField en la definición de tu modelo de Django - esto permitirá que almacene cualquier tipo de geometría.

O, sobrescribe el método save() en tu modelo para forzar que todo sea un MultiPolígono:

from django.contrib.gis.db import models
from django.contrib.gis import geos

class MyModel(models.Model):
  mygeom = models.MultiPolygonField()
  ... otros campos....

  def save(self, *args, **kwargs):
    # si mygeom termina siendo un Polígono, conviértelo en un MultiPolígono
    if self.mygeom and isinstance(self.mygeom, geos.Polygon):
      self.mygeom = geos.MultiPolygon(self.mygeom)

    super(MyModel).save(*args, **kwargs)

1 votos

El último método podría ser una buena elección

6voto

Se que esto es antiguo, pero acabo de encontrarme con este problema yo mismo y tuve problemas al usar las soluciones sugeridas arriba:

  • Usar GeometryField hace difícil usar la clase OSMGeoAdmin incorporada. El código en templates/gis/admin/openlayers.js (y contrib/gis/admin/widgets.py y probablemente otros lugares que me perdí) asume frecuentemente que la geometría es un punto, línea, polígono o colección, y nunca considera geometrías genéricas. Esto no es necesariamente importante ni insalvable, pero si planeabas usar el admin incorporado podrías quedar decepcionado.

  • Anular save() no funciona porque la verificación de tipo sucede antes, en el __set__() del modelo.

Mi solución actual es coercer explícitamente todos mis Polygons en MultiPolygons cuando importo y guardo mis datos. Podría anular __set__() si esto se vuelve engorroso.

Coercer de esta manera:

from django.contrib.gis.geos import MultiPolygon

multipolygon = MultiPolygon([polygon])

6voto

bortzmeyer Puntos 12246

Solución un poco larga

se podría usar fromstr()

from django.contrib.gis.geos import fromstr

p = Polygon()
# esto parece funcionar correctamente
mp = MultiPolygon(fromstr(str(p)),)

modelo1.campo_geom = mp

modelo1.save()

i-Ciencias.com

I-Ciencias es una comunidad de estudiantes y amantes de la ciencia en la que puedes resolver tus problemas y dudas.
Puedes consultar las preguntas de otros usuarios, hacer tus propias preguntas o resolver las de los demás.

Powered by:

X