Использование SQL-запросов при работе с векторными данными
Где используется в QGIS:
- Добавить виртуальный слой (Virtual Layer)
- Инструменты анализа - Выполнить SQL-запрос
Чаще всего используется SQL-оператор SELECT.
Форма записи:
SELECT [список полей через запятую, которые должны присутствовать в результате] FROM [список слоев через запятую] или FROM [слой1] JOIN [слой2] ON [условие соединения] WHERE [условия фильтрации] GROUP BY [список полей, по которым группируются результаты] HAVING [условия фильтрации после группировки] ORDER BY [список полей сортировки] ASC | DESC LIMIT [ограничить вывод заданным числом строк]
Для работы с геометрией используются следующие функции:
boolean st_intersects(geometry1, geometry2) - Возвращает Да или Нет (пересескаются две геометрии или нет) real st_area(geometry) - Возвращает площадь геометрии полигона. Для градусной системы координат не имеет смысла. real st_length(geometry) - Возвращает длину геометрии линии. Для градусной системы координат не имеет смысла. geometry st_transform(geometry, EPSG_CODE) - Перепроецирование. Возвращает новую геометрию указанной системе координат EPSG_CODE. geometry st_buffer(geometry, radius) - Возвращает полигональную геометрию в виде буфера указанного радиуса вокруг исходной геометрии.
Список основных функций работы с геометрией.
В запросах, использующих группировку (GROUP BY), часто применяются "агрегатные" функции: sum(), max(), min(), count(), avg().
Примеры:
1. Набор данных "Аляска"
Данные можно взять с сайта qgis.org - Демонстрационный набор данных.
Слои - alaska, airports.
Задача: Найти острова размером меньше 1000 квадратных милей, на которых есть аэропорты.
Добавить виртуальный слой (Virtual Layer).
В поле Запрос написать:
SELECT alaska.* FROM alaska JOIN airports ON st_intersects(alaska.geometry, airports.geometry) WHERE alaska.AREA_MI < 1000;
2. Лабораторная с сайта qgistutorials.com - Выполнение пространственных присоединений
Задача: посчитать число мест в приютах по каждому району Нью-Йорка.
Пусть слои называются nybb, nursing.
Добавить виртуальный слой (Virtual Layer).
В поле Запрос написать:
select nybb.*, sum(nursing.Capacity) as sumcap from nybb join nursing on st_intersects(nybb.geometry, nursing.geometry) group by nybb.geometry;
3. Лабораторная с сайта qgistutorials.com - Анализ количества точек в полигонах
Задача: Посчитать число землетрясений в России (NAME='Russia')
Пусть слои называются countries, signif.
Добавить виртуальный слой (Virtual Layer).
В поле Запрос написать:
select countries.*, count(signif.geometry) as cnt from countries join signif on st_intersects(countries.geometry, signif.geometry) where countries.NAME='Russia' group by countries.geometry;
Примечание. Запрос может выполняться очень долго!
4. Задача: Найти три самые длинные реки, протекающие по территории Удмуртии
Слой water-line из набора данных по Удмуртии RU-UD.zip.
Переименовать слой water-line в rivers (слои с дефисами в названии придется в кавычки заключать).
Добавить виртуальный слой (Virtual Layer).
В поле Запрос написать:
select NAME, sum(st_length(st_transform(geometry, 3395))) as length /*:real*/ from rivers group by NAME having NAME <> '' order by length desc limit 3;
Примечание. Результирующая таблица не будет иметь геометрии, так как мы ее не включили в список полей.
5. Задача: Найти города в мире, расположенные на водоемах (не далее 10 км от водоема)
Данные по городам и водоемам следует взять из Лабораторной - Выполнение пространственных запросов.
Пусть слои называются: towns, rivers.
Добавить виртуальный слой (Virtual Layer).
В поле Запрос написать:
select towns.geometry, towns.name, rivers.name from towns join rivers on st_intersects(st_transform(st_buffer(st_transform(towns.geometry, 3395), 10000), 4326),rivers.geometry);
Примечание. В запросе происходит перепроецирование геометрий городов в World Mercator для построения буфера/радиуса в 10 км, и затем обратно в WGS'84.
Примечание 1. Запрос может выполняться очень долго!
Задачу 5 для ускорения расчетов можно разбить на части. Для этого мы дополнительно ограничим поиск территорией России.
Будем использовать инструмент "Выполнить SQL-запрос" (найти в инструментах анализа).
5.1. Добавим еще один слой со странами. Переименуем в countries.
5.2. Создадим полигональный слой rustowns с российскими городами, очертив радиус в 10 км вокруг точечного слоя towns (Попутно сделав трансформацию в метрическую проекцию).
select st_transform(st_buffer(st_transform(geometry,3857),10000),4326) as geom/*:polygon:4326*/, name, adm0name from towns where adm0name='Russia'
Переименуем результат SQL-запроса в rustowns.
5.3. Ограничим все реки территорией России (кроме странной реки "Луара"). Для этого используем слой countries.
select rivers.geometry, rivers.name_ru from rivers join countries on st_intersects(rivers.geometry, countries.geometry) where countries.name='Russia' and rivers.name_ru <> 'Луара'
Переименовать в rusrivers.
5.4. Вычислим города, стоящие на реках:
select rustowns.geometry, rustowns.name, rusrivers.name_ru from rustowns join rusrivers on st_intersects(rustowns.geometry, rusrivers.geometry)
Переименовать в rivtowns.
5.5. Запросы (5.2 - 5.4) можно объединить в один:
select rustowns.geom, rustowns.name, rusrivers.name_ru from ( select st_transform(st_buffer(st_transform(geometry,3857),10000),4326) as geom/*:polygon:4326*/, name, adm0name from towns where adm0name='Russia' ) as rustowns join ( select rivers.geometry, rivers.name_ru from rivers join countries on st_intersects(rivers.geometry, countries.geometry) where countries.name='Russia' and rivers.name_ru <> 'Луара' ) as rusrivers on st_intersects(rustowns.geom, rusrivers.geometry)
5.6. Дополнительно. Найти города, стоящие на слиянии нескольких рек.
select geometry, name, count(distinct name_ru) as cnt /*:int*/ from rivtowns group by geometry having cnt > 1
Подпишите названия рек и городов.
- Войдите или зарегистрируйтесь, чтобы отправлять комментарии