1

まず、私のセットアップは次のとおりです。

  • パイソン 2.7.6
  • ジャンゴ1.6
  • PostgreSQL 9.3.1
  • PostGIS 2.1.1

Natural Earth の州のデータセットを PostGIS にロードしました。私が使用しているDjangoモデルは次のとおりです。

class Location(models.Model):
    name = models.CharField(max_length=255)
    imported_from = models.CharField(max_length=255)
    admin_level = models.CharField(max_length=255, blank=True)
    geometry = models.MultiPolygonField(blank=True, default=None, null=True)
    objects = models.GeoManager() #override the default manager with a GeoManager instance
    parent = models.ForeignKey('self', blank=True, default=None, null=True)

    def __unicode__(self):
            return self.name

    @staticmethod
    def get_countries(continent):
            return Location.objects.filter(parent=continent).order_by('name')

    @staticmethod
    def get_continents():
            return Location.objects.filter(parent=None).order_by('name')

    @staticmethod
    def get_states(country):
            return Location.objects.filter(parent=country).order_by('name')

これは一目瞭然ですが、注意すべき重要なことは、これにより場所の階層が可能になるということです (たとえば、テキサスは米国にあり、北米にあるなど)。

他の場所に接する一連の場所を取得する必要があります。ビューでこれを行う方法は次のとおりです。

touching_locations = {x for x in Location.objects.filter(geometry__touches=Location.objects.get(name='LOCATION_NAME').geometry).values_list('name', flat=True)}

このクエリは、一部の場所 (アンゴラなど) では問題なく動作しますが、他の場所 (米国など) では非常に遅くなります。にGiST インデックスを作成しましたが、期待した速度が得られませgeometryん。米国のクエリを実行すると、django-debug-toolbar はクエリ ( https://gist.github.com/gfairchild/7476754 ) が完了するまでになんと 106260.14 ミリ秒かかることを教えてくれますが、これは明らかに受け入れられません。

ロケーション テーブル全体には 4865 エントリしかないので、何が起こっているのでしょうか? このクエリを正しく発行していますか?

4

1 に答える 1

2

はい、リンク先のジオメトリが大きいため、遅くなると思います。

[[ MULTIPOLYGON - 346 elements, 36054 pts ]]

ポイントが数千行のデータの境界ボックス (bbox) 内にあるかどうかを判断するのではなく、ポイントがこの特定の詳細なマルチポリゴン内にあるかどうかを判断するために CPU が燃え尽きてしまうため、GiST インデックスも役に立ちません。注意してください、これはいくつかの大陸に重なるジオメトリと bbox です:

ここに画像の説明を入力

bbox は +ve 経度で日付変更線をワープするため、ヨーロッパをカバーします。これは、ヨーロッパのポイントをクエリしている場合、それが米国の bbox と交差することを意味し、PostGIS はこの大きなジオメトリをチェックして、ポリゴンに接触しているかどうかを確認する必要がある場合があります。R-Treeを参照して、GiST インデックスがどのように機能するか、およびオーバーラップが少ない小さなボックスがクエリを最も高速に実行する理由を理解してください。


最善の解決策は、より小さなジオメトリを使用することです。これは、本質的に要素/ポイントが少なく、通常、GiST インデックスを支援するために小さな bbox を持ちます。あなたが言及した「状態」データセットは、地理的範囲が制限されており、おそらく頂点が少ないため、より理想的です(詳細な空間関係のクエリに役立ちます)。Natural Earth の他に、世界中の行政境界を決定するための非常に優れたデータセットは次のとおりです: http://www.gadm.org

これらのオプションはどちらも境界を移動し、「接触」の意味を変更します。境界が異なり、これが「接触」に大きな違いをもたらすからです。「交差」、「含む」、「内」など、より一般的で異なる意味を持つ演算子が他にもいくつかあることに注意してください。https://en.wikipedia.org/wiki/DE-9IMを参照

于 2013-11-15T03:06:44.053 に答える