GeoDjangoでポリゴンをマルチポリゴンに一般化しますか?


9

models.PolygonFieldデータベースとしてpostgresを使用して、geodjangoでモデルを設定しました。私はshpをpostgresにインポートしようとします。問題は、shp(QGISでコンパイル)がポリゴンとマルチポリゴンを混合しているため、制約チェックのために常にエクスポートに失敗することですenforce_geotype

マルチポリゴンとポリゴンタイプの両方のデータを格納するために、制約をクリアする方法はありますか?

回答:


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ステートメントは、South移行または初期データSQLスクリプトから実行できます

別のオプションは、それをGeometryFieldDjangoモデル定義に含めることです。これにより、任意のジオメトリタイプを格納できます。

または、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)

最後の方法は良い選択かもしれません
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()

4

私はこれが古いことを知っていますが、私は自分でこの問題に遭遇し、上記の提案された解決策を使用して問題を抱えていました:

  • を使用GeometryFieldすると、組み込みOSMGeoAdminクラスの使用が困難になります。templates/gis/admin/openlayers.js(そしてcontrib/gis/admin/widgets.pyおそらく私が見逃した他の場所にある)コードは、ジオメトリがポイント、ライン、ポリゴン、またはコレクションであり、一般的なジオメトリを考慮しないことを頻繁に想定しています。これは必ずしも重要または乗り越えられないわけではありませんが、組み込みの管理者を使用することを計画していた場合、がっかりするかもしれません。

  • save()モデルので型チェックが早く行われるため、オーバーライドは機能しません__set__()

私の現在のソリューションは、明示的に私のすべての強制変換されるPolygonにSをMultiPolygonインポートする際の、私のデータを保存します。__set__()これが面倒になった場合はオーバーライドするかもしれません。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.