FieldPyculator - калькулятор полей с использованием выражений на Python для QGIS

Материал из GIS-Lab
Перейти к навигации Перейти к поиску
Эта страница является черновиком статьи.


Одной из наиболее частых задач при работе с векторными данными является обработка атрибутивных полей. Не менее часто приходится производить массовое изменение атрибутивных данных, как например заполнение поля значениями, вычисленными на основе других столбцов слоя. Возможность вычисления поля для всех записей в слое - обязательный признак современной ГИС общего назначения, и от удобства использования этого инструмента напрямую зависит скорость обработки атрибутивной информации.

Ядро QGIS имеет достаточно продвинутый калькулятор полей. Но его основной минус - невозможность использования функций, отличных от тех, что заложены разработчиками. На этот случай, в других ГИС обычно предусматривается возможность использования скриптовых языков, для создания необходимых функций обработки (например ArcGIS Desktop позволяет в калькуляторе полей активировать режим, при котором вычисление полей можно производить с использованием JavaScript или VB Script).

Для исправления этого недостатка QGIS было разработано расширение, позволяющее производить вычисление полей с помощью интерпретатора языка Python и использовать практически все доступные для него библиотеки. Идея впервые была предложена Raymond Nijssen. Но к сожалению, его плагин FieldEvaluator до сих пор находится на стадии глубокой разработки и позволяет вычислять лишь выражения на Python, не давая возможности использовать всю мощь этого языка. Данное расширение, по сути, позволяет пользователю создавать сколь угодно сложный алгоритм для вычисления значений, и имеет чуть более удобный интерфейс. Будем надеяться, Раймонд не обидится за то что мы предложили еще одну реализацию его идеи.

Получение и установка

Расширение доступно из репозитория ГИС-Лаб.

FieldPyculator разработан для QGIS версии 1.7.0 или старше и не имеет зависимостей.

Исходный код модуля можно получить выполнив команду:

git clone git://github.com/yellow-sky/FieldPyculator.git


Работа с расширением

После подключения и запуска расширения с помощью кнопки FieldPyculatorIcon.png или из меню Plugins->Field puculator->Field pyculator появится главное окно.

FieldPyculatorMainForm.png

Верхняя часть окна содержит название активного векторного слоя, выпадающий список для выбора редактируемого поля и кнопка начала/завершения редактирования активного слоя. Так же, с помощью флажка "Update only selected features" можно регулировать какие из записей будут обновлены - все или только выбранные с использованием стандартных инструментов QGIS.

Панель "Advanced" содержит поле для ввода "глобального" кода. Этот код будет выполнен только один раз, перед циклом обработки каждой записи. В этом блоке удобно производить все подготовительные действия: импортировать необходимые модули, расчитывать переменные, которые будут использоваться при вычислении каждой из записей.

Панель "Existing fields and vars" содержит название всех полей редактируемого слоя. Двойной клик по элементу списка "Fields" приводит к его добавлению в выражение для расчета поля, а так же заполнению списка "Values" урезанным набором значений выбранного поля. При нажатии кнопки "Get all" урезанный набор значений будет замещен полным, что может занять достаточно продолжительный период времени.
Так же на панели расположены кнопки добавления в выражение специальных переменных: "$id" и "$geom". При обработке выражения, эти переменные будут содержать соответственно идентификатор обрабатываемой записи и её геометрию.

Код, вычисляющий значение редактируемого поля содержится в "Field Expression". Код может содержать функции, объявления переменных, и иметь сколь угодно сложную структуру. Но обязательным условием является объявление переменной "value"для всех веток выполнения кода. Значение этой переменной будет присвоенно редактируемому полю. Имена полей слоя необходимо заключать в угловые скобки (При добавления из списка, скобки добавляются автоматически).


Примеры работы

Для примеров воспользуемся результатми проекта проверки УИКов г. Москвы. Точечный слой можно скачать тут.

Заполнения поля GUID'ами

Допустим, нам необходимо каждому объекту слоя присвоить уникальный идентификатор, что бы в дальнейшем иметь возможность связывать наш слой с данными, созданными на базе этого слоя (id типа int крайне ненадежная штука). Создадим новый столбец 'guid' типа string размером 36 символов. Запустив расширение и включив редактирование слоя, выбираем в выпадающем списке созданное поле 'guid'. В поле глобального кода добавляем импорт нужного нам модуля (для этого нужно активировать переключатель 'Advanced'):

import uuid


Код, для вычисления поля выглядит следующим образом:

value = str( uuid.uuid4() )

В результате новое поле будет заполнено сгенерированными guid'ами.


Обработка текстовых полей

Заполнение поля только для определенных строк

Достаточно часто необходимо обновить в слои только записи, удовлетворяющие определенному условию. Для выполнения этой операции с помощью стандартного калькулятора полей необходимо последовательно выполнить два действия: выбрать необходимые строки (с помощью расширенного поиска в таблице атрбутов) и при выполнении расчета в окне калькуляторе активировать переключатель "Обновить только выделенные объекты". Такая двухходовка неудобна по многим причинам - стандартный механизм выбора может далеко не все, калькулятор так же ограничен стандартным набором операций, и, если необходимо выполнить такие присвоения несколько раз, то можно легко ошибиться в выборках.
Попробуем выполнить это с помощью плагина. Создадим в слое УИКов новое поле - "Type" типа string размером 100 символов. Для всех школ и гимназий присвоим значение "school", для библиотек - "library", а всем остальным - "other".

Код вычисления поля:

addr_ext_lower = <ADDR_V_EXT>.lower()
value = 'other'
if  u'школа' in addr_ext_lower or u'гимназия' in addr_ext_lower:
	value = 'school'
if u'библиотека' in addr_ext_lower:
	value = 'library'

Результат выполнения:

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

Замещение JOIN'a с последующем присвоением значений

Контакты

Баг трекер на GitHub