Menyamaratakan Poligon ke MultiPoligon di GeoDjango?

9

Saya membuat model dengan models.PolygonFielddi geodjango, menggunakan postgres sebagai basis data. Saya mencoba mengimpor shp ke postgres. Masalahnya adalah, shp (dikompilasi dengan QGIS) mencampur poligon dan multipoligon, karenanya selalu gagal untuk melakukan ekspor karena kendala pemeriksaan enforce_geotype.

Apakah ada cara untuk menghapus batasan tersebut, sehingga dapat menyimpan data jenis multipoligon dan poligon?

ChanDon
sumber

Jawaban:

10

SQL to drop the constraint:

ALTER TABLE myapp_mymodel DROP CONSTRAINT enforce_geotype_mygeom;

Atau untuk mengubahnya agar memungkinkan kedua Poligon & MultiPoligon:

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

Pernyataan SQL ini dapat dijalankan dari migrasi Selatan atau skrip SQL data awal .

Pilihan lain adalah membuatnya GeometryFielddalam definisi model Django Anda - ini akan memungkinkannya untuk menyimpan semua jenis geometri.

Atau, save()ganti metode pada model Anda untuk memaksa semuanya menjadi 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
sumber
Metode terakhir mungkin merupakan pilihan yang baik
ChanDon
5

solusi gondrong

satu dapat menggunakan 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()
pengguna1725066
sumber
4

Saya tahu ini sudah tua, tetapi saya sendiri mengalami masalah ini dan mengalami masalah dalam menggunakan solusi yang disarankan di atas:

  • Menggunakan GeometryFieldmembuatnya sulit untuk menggunakan OSMGeoAdminkelas bawaan. Kode dalam templates/gis/admin/openlayers.js(dan contrib/gis/admin/widgets.pydan mungkin tempat lain yang saya lewatkan) sering mengasumsikan bahwa geometri adalah titik, garis, poligon, atau koleksi, dan tidak pernah menjelaskan geometri generik. Ini tidak selalu penting atau tidak dapat diatasi, tetapi jika Anda berencana menggunakan admin bawaan, Anda mungkin akan kecewa.

  • Overriding save()tidak berfungsi karena pengecekan tipe terjadi lebih cepat, pada model __set__().

Solusi saya saat ini secara eksplisit memaksa semua saya Polygons ke MultiPolygons ketika mengimpor dan menyimpan data saya. Saya mungkin menimpa __set__()jika ini menjadi rumit.

eric brelsford
sumber