2013-11-15 2 views
1

Во-первых, вот моя установка:GeoDjango касается функции медленно

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

Я загрузил наборы данных Earth Earth countries и states в 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)} 

Этот запрос работает нормально для некоторых местах (как Ангола), но это катастрофически медленно для некоторых других (например, в США). I do имеют индекс GiST, созданный на geometry, но я не вижу ожидаемой скорости. Когда я запускаю запрос для U.S., панель инструментов django-debug сообщает мне, что запрос (https://gist.github.com/gfairchild/7476754) занимает целых 106260,14 мс для завершения, что явно неприемлемо.

В таблице местоположений всего 4865 записей, так что происходит? Правильно ли я выдаю этот запрос?

ответ

2

Да, я бы ожидать, что это будет медленно, поскольку геометрия, что вы связаны с массивно:

[[ MULTIPOLYGON - 346 elements, 36054 pts ]] 

индекс GiST не поможет, так как CPU выжигая к тому, если в точке определения находится внутри этого конкретного подробного мультиполигона, а не определяется, находится ли он в ограничивающей рамке (bbox) из тысяч строк данных. Обратите внимание, здесь геометрия и BBOX, что перекрывает несколько континентов:

enter image description here

Поскольку BBOX перекосы по дате линии с + в долгот, она охватывает Европу. Это означает, что если вы запрашиваете точку в Европе, она пересечет bbox для Соединенных Штатов, и PostGIS, возможно, потребуется проверить эту большую геометрию, чтобы увидеть, касается ли она полигона. См. R-Tree, чтобы понять, как работает индекс GiST, и почему более короткие поля с меньшим количеством запросов на перекрытие быстрее.


Лучшее решение заключается в использовании меньшего размера геометрии, которые по своей природе имеют меньше элементов/пунктов и, как правило, имеют меньшие bboxes, чтобы помочь индекс GIST. Упомянутый вами набор данных «состояний» более идеален, поскольку они имеют ограниченный географический экстент и, вероятно, меньше вершин (помогает детальный запрос пространственных отношений). Помимо Природной Земли, действительно хороший набор данных для определения административных границ по всему миру: http://www.gadm.org

Оба эти варианта будут перемещать границы и изменять то, что означает «касается», поскольку границы различны, и это имеет огромное значение для «прикосновений» ».Обратите внимание, что есть несколько других операторов, которые являются более распространенными и означают разные вещи, такие как «пересекает», «содержит» и «внутри»; см. https://en.wikipedia.org/wiki/DE-9IM

+0

Это действительно отличное объяснение, а не то, что я ожидал. Другое решение состоит в том, что мы могли бы просто обрезать те внешние гавайские/аляскинские точки, чтобы bbox намного меньше. Если бы мы пошли в набор данных состояний, проблема на самом деле не была бы решена, потому что bbox для Гавайских островов/Аляски все равно обернется. – Geoff

Смежные вопросы