Обобщать полигоны в мультиполигоны в GeoDjango?

9

Я настроил модель models.PolygonFieldв Geodjango, используя Postgres в качестве базы данных. Я пытаюсь импортировать shp в postgres. Проблема в том, что shp (скомпилированный с QGIS) смешивает многоугольник и многоугольник, поэтому он всегда не может выполнить экспорт из-за проверки ограничений enforce_geotype.

Есть ли способ снять ограничение, чтобы хранить данные как многоугольника, так и многоугольника?

Chandon
источник

Ответы:

10

SQL для удаления ограничения:

ALTER TABLE myapp_mymodel DROP CONSTRAINT enforce_geotype_mygeom;

Или изменить его, чтобы разрешить как полигоны, так и мультиполигоны:

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

Эти операторы SQL могут быть выполнены из миграции на юг или сценария SQL с исходными данными .

Другой вариант - включить его GeometryFieldв определение модели Django - это позволит хранить любой тип геометрии.

Или переопределите save()метод в вашей модели, чтобы заставить все быть 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
источник
Последний метод может быть хорошим выбором
ChanDon
5

длинный обходной путь

можно использовать 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
источник
4

Я знаю, что это старая версия, но я сам столкнулся с этой проблемой и столкнулся с проблемами при использовании предложенных выше решений:

  • Использование GeometryFieldзатрудняет использование встроенного OSMGeoAdminкласса. Код в templates/gis/admin/openlayers.js(и, contrib/gis/admin/widgets.pyвозможно, в других местах, которые я пропустил) часто предполагает, что геометрия является точкой, линией, многоугольником или коллекцией, и никогда не учитывает общие геометрии. Это не обязательно важно или непреодолимо, но если вы планируете использовать встроенного администратора, вы можете быть разочарованы.

  • Переопределение save()не работает, потому что проверка типа происходит раньше, в модели __set__().

Мое текущее решение явно принуждает все мои Polygons к MultiPolygonимпорту и сохранению моих данных. Я мог бы переопределить, __set__()если это становится громоздким.

Эрик Брелсфорд
источник