Библиотека сетевого анализа QGIS: описание и примеры

Материал из GIS-Lab
Перейти к навигации Перейти к поиску

QGIS network-analysis library - библиотека входящая в состав свободной ГИС Quantum GIS реализует следующие возможности

  • создание математического графа из географических данных (линейных векторных слоев) пригодного для анализа методами теории графов
  • реализация базовых методов теории графов (в настоящее время только метод Дейкстры)

История

Библиотека QGIS network-analysis появилась путем экспорта базовых функций из плагина RoadGraph в отдельную библиотеку.

Начиная с ee19294562, появилась возможность использовать функционал библиотеки в своих расширениях, а также из Консоли Python QGIS.

Применение

Чтобы получить доступ к функциям библиотеки сетевого анализа необходимо импортировать модуль networkanalysis

 from qgis.networkanalysis import *

Первое, что нужно сделать — это подготовить исходные данные, т.е. преобразовать векторный слой в граф. Все дальнейшие действия будут выполняться именно с ним. За построение графа дорог отвечает так называемый Director. В настоящее время бибилотека располагает только одним директором: QgsLineVectorLayerDirector, которой строит граф по линейному векторному слою.

В конструктор директора передается линейный векторный слой, по которому будет строиться граф, а также информация о характере движения по каждому сегменту дороги (разрешенное направление, одностороннее или двустороннее движение). Рассмотрим эти параметры:

  • vl — векторный слой, по которому будет строиться граф.
  • directionFieldId — индекс поля атрибутивной таблицы, которое содержит информацию о направлении движения
  • directDirectionValue — значение поля, соответствующее прямому направлению движения (т.е. движению в порядке создания точек линии, от первой к последней)
  • reverseDirectionValue — значение поля, соответствующее обратному направлению движения (от последней точки к первой)
  • bothDirectionValue — значение поля, соответствующее двустроннему движению (т.е. допускается движение как от первой точки к последней, так и в обратном направлении)
  • defaultDirection — направление движения по умолчанию. Будет использоваться для тех участков дорог, у которых значение поля directionFieldId не задано или не совпадает ни с одним из вышеперечисленных.

Например

 # не использовать информацию о направлении движения из атрибутов слоя, все дороги трактуются как двустронние
 director = QgsLineVectorLayerDirector( vLayer, -1, , , , 3 )
 # информация о направлении движения находится в поле с индексом 5. Односторонние дороги с прямым направлением
 # движения имееют значение атрибута "yes", односторонние дороги с обратным направлением — "1", и соответственно
 # двусторонние ­дороги — "no". По умолчанию дороги считаются двусторонними. Такая схема подходит для использования
 # c данными OpenStreetMap
 director = QgsLineVectorLayerDirector( vLayer, 5, 'yes', '1', 'no', 3 )

Следующим шагом необходимо создать стратегию назначения свойств ребрам графа. Стратегия рассчитывает свойства ребра, запрашивая данные у директора, и именно основываясь на свойствах ребер будет выполняться поиск оптимального маршрута. Пока в библиотеке реализована только одна стратегия, учитывающая длину маршрута: QgsDistanceArcProperter. При необходимости, можно создать свою стратегию, которая будет учитывать необходимые параметры. Например, в модуле Road graph используется стратегия, учитывающая время движения по ребру графа.

 properter = QgsDistanceArcProperter()

Сообщаем директору об используемой стратегии. Один директор может использовать несколько стратегий

 director.addProperter( properter )

Теперь создаем строителя, который собственно и будет строить граф заданного типа. Стандартный строитель QgsGraphBuilder строит граф типа QgsGraph. При желании можно написать свою реализацию, которая будет строить граф, совместимый с такими библиотеками как Boost или networkX.

Строитель принимает следующие параметры:

  • crs — используемая система координат. Обязательный параметр.
  • otfEnabled — указывает на использование перепроецирования «на лету». По умолчанию true.
  • topologyTolerance — топологическая толерантность. Значение по умолчанию 0.
  • ellipsoidID — используемый эллипсоид. По умолчанию "WGS84".
 # задана только используемая СК, все остальные параметры по умолчанию
 builder = QgsGraphBuilder( myCRS )

Также необходимо задать одну или несколько точек, которые будет использоваться при анализе. Например так:

 startPoint = QgsPoint( 82.7112, 55.1672 )
 endPoint = QgsPoint( 83.1879, 54.7079 )

Затем строим граф и «привязываем» к нему точки

 tiedPoints = director.makeGraph( builder, [ startPoint, endPoint ] )

Построение графа может занять некоторое время (зависит от количества обектов в слое и размера самого слоя). После построения мы получим граф, пригодный для анализа

 graph = builder.graph()

Теперь можно получить индексы наших точек

 startId = graph.findVertex( tiedPoints[ 0 ] )
 endId = graph.findVertex( tiedPoints[ 1 ] )

Анализ графа выполняет QgsGraphAnalyzer. Вот так можно получить дерево кратчайших путей с корнем в точке startPoint

 tree = QgsGraphAnalyzer.shortestTree( graph, startId, 0 )

Метод shortestTree принимает три аргумента:

  • source — исходный граф
  • startVertexIdx — ндекс точки на графе (корень дерева)
  • criterionNum — порядковый номер используемой стратегии (отсчет ведется от 0).

На выходе мы получим граф, тип которого зависит от используемого строителя. Отобразить дерево на карте можно при помощи следующего кода

 id = tree.findVertex( tiedPoint[ 0 ] )
 not_begin = [ id ]
 rb = QgsRubberBand( qgis.utils.iface.mapCanvas() )
 rb.setWidth( 3 )
 while len( not_begin ) > 0:
   curId = not_begin[ 0 ]
   not_begin = not_begin[ 1: ]
   rb.addPoint( tree.vertex( curId ).point() )
   f = 1
   for i in tree.vertex( curId ).outArc():
     if f==1:
       not_begin = [ tree.arc( i ).inVertex() ] + not_begin
       f=0
     else:
       not_begin = not_begin + [ tree.arc( i ).inVertex() ]

Для получения кратчайшего маршрута между двумя точками используется метод shortestpath.

Актуальная документация

Актуальную документацию всегда можно получить в разделе QGIS network analysis library описания QGIS API.