Практики · занятие 5

Пространственные отношения

О чём это занятие
Главный инструментарий пространственного SQL: предикаты отношений между геометриями — от ST_Intersects до ST_DWithin. Каждый предикат можно «пощупать» в интерактивной сцене, а затем применить к настоящим улицам, районам и станциям метро Нью-Йорка.
Аннотация
Занятие начинается с повторения функций свойств геометрии из практики 4 — координаты точки, длина и концы линии, площадь и кольца полигона. Затем вводится понятие пространственных отношений и их топологической природы. По одному разбираются предикаты PostGIS: ST_Intersects и его противоположность ST_Disjoint, ST_Overlaps для частичного перекрытия, ST_Touches для касания границами, пара ST_Within / ST_Contains для вложенности, ST_Distance для расстояния и ST_DWithin как индекс-дружественная замена сравнению расстояния. Интерактивная сцена позволяет двигать одну фигуру относительно другой и наблюдать, какие предикаты истинны в каждом положении. Практическая часть — три классические задачи на учебной базе: улицы, пересекающие Гринвич-Виллидж, районы-соседи Чайнатауна через самосоединение и улицы в 500 метрах от станции метро, с сохранением результата в таблицу и отображением в QGIS. Дополнительные задания — плотность населения Манхэттена и площадь Гарлема в трёх проекциях.
Пререквизиты
Практика 4 — геометрические типы и функции свойств; теория пространственного анализа — лекция 4.
Материалы к занятию
Учебная база nyc_data (восстановлена в практике 3). Работа ведётся в pgAdmin (Query Tool) и QGIS.

1. Повторение: свойства объектов

Выпишите основные свойства объектов и функции, которые их возвращают, — это разминка по практике 4:

ГеометрияФункцииСвойства
точкаST_X, ST_Yкоординаты X (долгота) и Y (широта)
линияST_Length, ST_StartPoint, ST_EndPoint, ST_NPointsдлина, первая и последняя точки, число вершин
полигонST_Area, ST_NRings, ST_ExteriorRingплощадь, число колец, внешнее кольцо

Запомните эти функции — они постоянно комбинируются с предикатами отношений: «длина улиц, пересекающих район», «площадь блоков в радиусе от станции».

2. Пространственные отношения

Пространственные отношения в ГИС — это внутренние взаимоотношения между пространственными объектами. Топологические пространственные отношения — отношения между географическими объектами, которые определяют, где и как точки и линии соединяются в узлах на карте, порядок соединения, форму дуги или полигона.

Топологические пространственные отношения

2.1. Предикаты PostGIS

Пересечение. ST_Intersects(геометрия A, геометрия B) возвращает значение TRUE, если у двух фигур есть какое-либо общее пространство — если их границы или внутренние области пересекаются.

ST_Intersects

Находится вне. Противоположность ST_Intersects — ST_Disjoint(геометрия A, геометрия B): истинно, если две геометрии не пересекаются.

ST_Disjoint

Пересечение по области. ST_Overlaps(геометрия A, геометрия B) сравнивает две геометрии одинаковой размерности и возвращает TRUE, если при их пересечении получается геометрия, отличная от обеих, но той же размерности.

ST_Overlaps

Имеет границу (соприкасается). ST_Touches(геометрия A, геометрия B) проверяет, соприкасаются ли две геометрии на своих границах, но не пересекаются ли внутренними областями: TRUE, если границы геометрий пересекаются или если только одна из внутренних областей пересекает границу другой.

ST_Touches

Находится внутри. ST_Within и ST_Contains проверяют, полностью ли одна геометрия находится внутри другой: ST_Within(A, B) возвращает TRUE, если первая геометрия полностью лежит во второй; ST_Contains(A, B) — если вторая геометрия полностью содержится в первой. ST_Within даёт результат, прямо противоположный ST_Contains (при переставленных аргументах).

ST_Within и ST_Contains

Расстояние между объектами. ST_Distance(A, B) вычисляет кратчайшее расстояние между двумя геометриями и возвращает его числом с плавающей точкой.

ST_Distance

Находится на расстоянии. Используйте ST_DWithin(A, B, R) вместо ST_Distance(A, B) < R, чтобы получить преимущество от пространственного индекса.

ST_DWithin
Типичная ошибка Фильтровать по расстоянию через ST_Distance(A, B) < R. Такое условие вынуждает СУБД вычислить расстояние до каждой строки — GiST-индекс не используется. ST_DWithin сначала отбрасывает заведомо далёкие объекты по индексу (см. лекцию 3), а честное расстояние считает только для кандидатов.

2.2. Сводная таблица

ФункцияОписание
ST_Contains(A, B)TRUE, если B полностью содержится в A, и хотя бы одна точка внутренней области B — внутри A
ST_Crosses(A, B)TRUE, если геометрии имеют некоторые, но не все общие внутренние точки
ST_Disjoint(A, B)TRUE, если геометрии не пересекаются — не имеют общих точек
ST_Distance(A, B)минимальное евклидово расстояние между геометриями в проекционных единицах
ST_DWithin(A, B, R)TRUE, если геометрии находятся на расстоянии не более R друг от друга
ST_Equals(A, B)TRUE, если геометрии представляют одну и ту же геометрию, независимо от направления
ST_Intersects(A, B)TRUE, если геометрии пересекаются — имеют общие области
ST_Overlaps(A, B)TRUE, если геометрии имеют общую область, но не содержатся полностью друг в друге
ST_Touches(A, B)TRUE, если геометрии касаются, но их внутренние области не пересекаются
ST_Within(A, B)TRUE, если геометрия A полностью содержится внутри геометрии B

2.3. Тренажёр: подвигайте геометрию

Перетаскивайте оранжевый квадрат B мышью относительно синего полигона A — панель показывает, какие предикаты истинны в текущем положении. Найдите положения, в которых: фигуры не связаны (Disjoint), касаются краями (Touches), частично перекрываются (Overlaps), B целиком внутри A (Within/Contains), и проследите, как меняется ST_Distance. Пунктирное кольцо — зона ST_DWithin с радиусом 80.

Тренажёр: предикаты пространственных отношений

Фигуры — прямоугольники, предикаты вычисляются честно по их координатам; при сближении меньше 4 пикселей квадрат «прилипает» к границе, чтобы касание (Touches) было достижимо мышью.

3. Практика на базе Нью-Йорка

3.1. Улицы через Гринвич-Виллидж

Задача

Найдите все улицы, которые пересекают границы района Greenwich Village, и выведите их геометрию.

показать пошаговое решение

Шаг 1 — источники: районы и улицы лежат в разных таблицах, обе нужны в FROM:

FROM nyc_neighborhoods, nyc_streets

Шаг 2 — столбцы: название района, название улицы и геометрия улицы:

SELECT nyc_neighborhoods.name AS neighborhood,
       nyc_streets.name AS street,
       nyc_streets.wkb_geometry

Шаг 3 — условие: конкретный район и предикат пересечения:

SELECT nyc_neighborhoods.name AS neighborhood,
       nyc_streets.name AS street,
       nyc_streets.wkb_geometry
FROM nyc_neighborhoods, nyc_streets
WHERE nyc_neighborhoods.name = 'Greenwich Village'
  AND ST_Intersects(nyc_neighborhoods.geom, nyc_streets.wkb_geometry);

3.2. Соседи Чайнатауна

Задача

Найдите все районы, которые граничат с районом Chinatown, и выведите их геометрию.

показать решение

Районы сравниваются с районами — таблица соединяется сама с собой через псевдонимы (как в главе 2 РГР с регионами-соседями):

SELECT b.name, b.geom
FROM nyc_neighborhoods a, nyc_neighborhoods b
WHERE a.name = 'Chinatown'
  AND ST_Touches(a.geom, b.geom);

ST_Touches выбирает именно граничащие районы: границы соприкасаются, а внутренние области не пересекаются.

3.3. Улицы у станции метро

Задача

Найдите улицы, находящиеся на расстоянии менее 500 метров от станции метро East Broadway.

показать решение
SELECT st.name AS street, st.wkb_geometry
FROM nyc_streets st, nyc_subway_stations s
WHERE s.name = 'East Broadway'
  AND ST_DWithin(st.wkb_geometry, s.geom, 500);

Данные хранятся в метрической проекции, поэтому 500 — это метры.

Сохраним результат в таблицу и откроем её в QGIS:

DROP TABLE IF EXISTS streets_near_east_broadway;

CREATE TABLE streets_near_east_broadway AS
SELECT st.name AS street, st.wkb_geometry
FROM nyc_streets st, nyc_subway_stations s
WHERE s.name = 'East Broadway'
  AND ST_DWithin(st.wkb_geometry, s.geom, 500);

SELECT * FROM streets_near_east_broadway;

После выполнения запроса в QGIS откройте «Подключения» и нажмите «Подключиться» — это работает как «обновить страницу»; новая таблица появится в списке слоёв.

Слой улиц около станции в QGIS

3.4. Дополнительные задания

Задание со звёздочкой

Вычислите плотность населения для каждого блока в районе Manhattan и сохраните результаты в новую таблицу.

подсказка

Плотность — это popn_total / ST_Area(geom). Отберите блоки WHERE boroname = 'Manhattan', результат оберните в CREATE TABLE … AS SELECT. Площадь возвращается в квадратных метрах — при желании переведите в км², умножив на 1 000 000.

Задание со звёздочкой

Вычислите площадь Гарлема (Harlem) в разных проекциях: 2263, 32618 и 26918. Функции: ST_Area — расчёт площади, ST_Transform(геометрия, код_проекции) — преобразование проекции.

подсказка
SELECT
  ST_Area(ST_Transform(geom, 2263))  AS area_2263,
  ST_Area(ST_Transform(geom, 32618)) AS area_32618,
  ST_Area(ST_Transform(geom, 26918)) AS area_26918
FROM nyc_neighborhoods
WHERE name = 'Harlem';

Обратите внимание на единицы: 2263 — футы, 32618 и 26918 — метры; о выборе проекций — лекция 4.

Контрольные вопросы

Источники

  1. PostGIS Documentation. Spatial Relationships : [сайт]. — URL: https://postgis.net/workshops/postgis-intro/spatial_relationships.html (дата обращения: 18.08.2026).
  2. PostGIS Reference. ST_DWithin : [сайт]. — URL: https://postgis.net/docs/ST_DWithin.html (дата обращения: 18.08.2026).
  3. Egenhofer, M. J. Point-Set Topological Spatial Relations / M. J. Egenhofer, R. D. Franzosa // International Journal of Geographical Information Systems. — 1991. — Vol. 5, № 2. — P. 161–174.