【问题标题】:GeoDjango touches function is slowGeoDjango 的触摸功能很慢
【发布时间】:2013-11-28 06:04:16
【问题描述】:

首先,这是我的设置:

  • Python 2.7.6
  • Django 1.6
  • PostgreSQL 9.3.1
  • PostGIS 2.1.1

我已将 Natural Earth countriesstates 数据集加载到 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)}

此查询在某些地方(如安哥拉)工作得很好,但在其他一些地方(如美国)却非常缓慢。我确实geometry 上创建了一个GiST 索引,但我没有看到我预期的速度。当我为美国运行查询时,django-debug-toolbar 告诉我查询 (https://gist.github.com/gfairchild/7476754) 需要 106260.14 毫秒才能完成,这显然是不可接受的。

整个位置表只有 4865 个条目,这是怎么回事?我发出这个查询对吗?

【问题讨论】:

    标签: python django postgresql postgis geodjango


    【解决方案1】:

    是的,我希望它会很慢,因为您链接到的几何图形很大:

    [[ MULTIPOLYGON - 346 elements, 36054 pts ]]
    

    GiST 索引也无济于事,因为 CPU 会消耗以确定该点是否在这个特定的详细多多边形内,而不是确定它是否在数千行数据的边界框 (bbox) 内。请注意,这里是几何图形和重叠几个大陆的 bbox:

    由于 bbox 在 +ve 经度的日期变更线上弯曲,因此它覆盖了欧洲。这意味着如果您在欧洲查询一个点,它将与美国的 bbox 相交,并且 PostGIS 可能需要检查这个大几何图形以查看它是否触及多边形。请参阅 R-Tree 以了解 GiST 索引的工作原理,以及为什么具有较少重叠的较小框的查询速度最快。


    最好的解决方案是使用较小的几何图形,这些几何图形本质上具有较少的元素/点,并且通常具有较小的 bbox 以帮助 GiST 索引。您提到的“状态”数据集更理想,因为它们的地理范围有限,顶点可能更少(有助于详细的空间关系查询)。除了 Natural Earth,一个非常好的用于确定全球行政边界的数据集是:http://www.gadm.org

    这两个选项都会移动边界并改变“触摸”的含义,因为边界不同,这对“触摸”产生了巨大的影响。请注意,还有其他几个更常见且含义不同的运算符,例如“intersects”、“contains”和“within”;见https://en.wikipedia.org/wiki/DE-9IM

    【讨论】:

    • 这是一个非常好的解释,完全不是我所期望的。另一个解决方案是我们可以简单地修剪那些外部夏威夷/阿拉斯加点,使 bbox 更小。如果我们转到 states 数据集,问题实际上不会得到解决,因为夏威夷/阿拉斯加的 bbox 仍然会环绕。
    猜你喜欢
    • 2011-04-24
    • 2017-08-01
    • 1970-01-01
    • 2020-04-13
    • 1970-01-01
    • 2023-01-15
    • 1970-01-01
    • 1970-01-01
    • 2016-02-28
    相关资源
    最近更新 更多