STIntersects: примеры (SQL)

Использование STIntersects для анализа пространственных данных
Раздел: Геопространственные функции, Пространственные
STIntersects(other_geography geography): bit

Описание функции STIntersects

Функция STIntersects() является методом для геопространственных типов данных geometry и geography в Microsoft SQL Server. Она применяется для определения факта пересечения между двумя пространственными объектами. Если объекты имеют хотя бы одну общую точку, функция возвращает 1 (TRUE). В противном случае возвращается 0 (FALSE). Если оба экземпляра не содержат данных (STIsEmpty() = 1), функция также возвращает 0.

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

Аргументы и возвращаемое значение

Метод вызывается для одного экземпляра пространственного типа и принимает один обязательный аргумент:

  • other_geometry (geometry или geography) - второй пространственный объект для сравнения.

Необязательный второй аргумент:

  • flag (varchar(15)) - доступен только для типа geography, начиная с SQL Server 2019. Управляет точностью вычислений: 'FALSE' (точные вычисления) или 'DEFAULT' (быстрые вычисления с возможной погрешностью).

Возвращаемый тип: bit. Возвращает 1 при пересечении объектов, 0 - если пересечения нет, и NULL, если идентификаторы пространственных ссылок (SRID) экземпляров не совпадают.

Базовые примеры использования

Пример с типом geometry: проверка пересечения двух линий.

DECLARE @g1 geometry = 'LINESTRING(0 0, 2 2)';
DECLARE @g2 geometry = 'LINESTRING(1 1, 3 3)';
SELECT @g1.STIntersects(@g2) AS IntersectResult;
IntersectResult
----------------
1

Пример с типом geography: проверка пересечения двух точек.

DECLARE @geo1 geography = geography::Point(51.5074, -0.1278, 4326);
DECLARE @geo2 geography = geography::Point(55.7558, 37.6173, 4326);
SELECT @geo1.STIntersects(@geo2) AS IntersectResult;
IntersectResult
----------------
0

Использование флага для типа geography (SQL Server 2019 и выше).

DECLARE @g1 geography = geography::STGeomFromText('POLYGON((0 0, 10 0, 10 10, 0 10, 0 0))', 4326);
DECLARE @g2 geography = geography::Point(5, 5, 4326);
SELECT @g1.STIntersects(@g2, 'DEFAULT') AS FastCheck,
@g1.STIntersects(@g2, 'FALSE') AS PreciseCheck;
FastCheck  PreciseCheck
--------- ------------
1 1

Другие пространственные функции в MS SQL

Помимо STIntersects, существует ряд функций для анализа пространственных отношений.

  • STContains() - возвращает 1, если объект полностью содержит другой, не учитывая общие границы. Для пересекающихся, но не полностью содержащихся объектов, вернет 0.
  • STWithin() - обратная функция к STContains. Проверяет, находится ли объект внутри другого.
  • STOverlaps() - определяет, перекрываются ли объекты одного измерения (например, полигон с полигоном), но один не полностью содержит другой.
  • STTouches() - проверяет, соприкасаются ли объекты по границе, но их внутренние области не пересекаются.
  • STCrosses() - используется для объектов с меньшей размерностью (например, линия, пересекающая полигон).

Функцию STIntersects предпочтительнее использовать для первоначальной быстрой фильтрации объектов, которые могут взаимодействовать, так как она наиболее оптимизирована для индексов пространственных данных. Для уточнения характера взаимодействия применяются более специфичные функции (STContains, STTouches).

Аналоги функции в других СУБД

PostgreSQL/PostGIS: Функция ST_Intersects(geom1, geom2). Аналогична по логике. Работает с типом geometry и geography.

SELECT ST_Intersects(
ST_GeomFromText('LINESTRING(0 0, 2 2)'),
ST_GeomFromText('LINESTRING(1 1, 3 3)')
);
st_intersects
--------------
t

MySQL: Функция ST_Intersects(g1, g2). Поддерживается с версии 5.7. Работает с геометрическими типами, но без поддержки geography.

SELECT ST_Intersects(
ST_GeomFromText('POLYGON((0 0,5 0,5 5,0 5,0 0))'),
ST_GeomFromText('POINT(2 2)')
);
1

Oracle Spatial: Функция SDO_GEOM.RELATE(geom1, 'ANYINTERACT', geom2) или предикат SDO_ANYINTERACT. Более сложная система пространственных отношений.

SELECT SDO_GEOM.RELATE(
SDO_GEOMETRY(2003, NULL, NULL, SDO_ELEM_INFO_ARRAY(1,1003,1), SDO_ORDINATE_ARRAY(0,0, 5,0, 5,5, 0,5, 0,0)),
'ANYINTERACT',
SDO_GEOMETRY(2001, NULL, SDO_POINT_TYPE(2,2, NULL), NULL, NULL)
) FROM dual;
TRUE

SQLite с расширением SpatiaLite: Используется функция ST_Intersects(geom1, geom2).

Главное отличие MS SQL - разделение типов geometry (плоская система координат) и geography (эллипсоидальная модель Земли). В PostgreSQL это часто регулируется типом данных (geometry/geography), а в MySQL поддержка geography ограничена.

Типичные ошибки

1. Несовпадение SRID (Spatial Reference Identifier). Если SRID у сравниваемых объектов разный, функция вернет NULL.

DECLARE @g1 geometry = geometry::STGeomFromText('POINT(0 0)', 4326);
DECLARE @g2 geometry = geometry::STGeomFromText('POINT(1 1)', 0);
SELECT @g1.STIntersects(@g2) AS Result;
Result
-------
NULL

2. Сравнение пустых объектов (EMPTY). Для двух пустых множеств функция возвращает 0.

DECLARE @g1 geometry = geometry::STGeomFromText('POINT EMPTY', 0);
DECLARE @g2 geometry = geometry::STGeomFromText('LINESTRING EMPTY', 0);
SELECT @g1.STIntersects(@g2) AS Result;
Result
-------
0

3. Использование флага для типа geometry. Флаг доступен только для geography, его указание для geometry вызовет ошибку.

DECLARE @g1 geometry = 'POINT(0 0)';
DECLARE @g2 geometry = 'POINT(1 1)';
SELECT @g1.STIntersects(@g2, 'DEFAULT'); -- Ошибка
Msg 206, Level 16, State 2...
Операция конфликтует с типом...

Изменения в последних версиях

В SQL Server 2019 для типа geography был добавлен необязательный параметр flag. Он позволяет управлять компромиссом между производительностью и точностью вычислений при определении пересечения.

  • 'DEFAULT': Используется быстрый, но приближенный алгоритм. Может вернуть 1 для объектов, которые очень близки, но фактически не пересекаются (ложноположительный результат).
  • 'FALSE': Включает точный расчет, но требует больше вычислительных ресурсов.

Это изменение направлено на ускорение пространственных запросов в сценариях, где допустима некоторая погрешность. Для типа geometry данный параметр недоступен.

Расширенные примеры

Пример 1: Использование в запросе к таблице с пространственным индексом.

Пример sql
-- Создание таблицы и индекса
CREATE TABLE Buildings (
Id INT PRIMARY KEY,
Name NVARCHAR(100),
Footprint geometry
);
CREATE SPATIAL INDEX IX_Buildings_Footprint ON Buildings(Footprint);

-- Поиск всех зданий, пересекающихся с заданным полигоном (например, зона застройки)
DECLARE @Zone geometry = 'POLYGON((10 10, 100 10, 100 100, 10 100, 10 10))';
SELECT Id, Name
FROM Buildings
WHERE Footprint.STIntersects(@Zone) = 1;

Пример 2: Сравнение объектов типа geography с большими расстояниями.

Пример sql
DECLARE @SeaRoute geography = geography::STGeomFromText(
'LINESTRING(-10 50, 0 52, 10 53, 20 54)', 4326);
DECLARE @StormArea geography = geography::STGeomFromText(
'POLYGON((5 51, 15 51, 15 55, 5 55, 5 51))', 4326);
-- Проверка, пересекается ли маршрут с зоной шторма
SELECT @SeaRoute.STIntersects(@StormArea) AS IsInDanger;
IsInDanger
----------
1

Пример 3: Анализ иерархии пространственных отношений.

Пример sql
DECLARE @Country geometry = 'POLYGON((0 0, 100 0, 100 100, 0 100, 0 0))';
DECLARE @City geometry = 'POLYGON((20 20, 40 20, 40 40, 20 40, 20 20))';
DECLARE @Road geometry = 'LINESTRING(50 50, 150 150)';

SELECT
@Country.STIntersects(@City) AS Country_Intersects_City, -- 1
@Country.STContains(@City) AS Country_Contains_City, -- 1
@Country.STIntersects(@Road) AS Country_Intersects_Road, -- 1
@Country.STContains(@Road) AS Country_Contains_Road; -- 0
Country_Intersects_City  Country_Contains_City  Country_Intersects_Road  Country_Contains_Road
----------------------- --------------------- ----------------------- ----------------------
1 1 1 0

Пример 4: Работа с коллекциями (GeometryCollection).

Пример sql
DECLARE @Collection1 geometry = 'GEOMETRYCOLLECTION(POINT(10 10), LINESTRING(0 0, 20 20))';
DECLARE @Point geometry = 'POINT(15 15)';
SELECT @Collection1.STIntersects(@Point) AS Result;
Result
-------
1

MS SQL STIntersects function comments

En
STIntersects Determines whether two geography instances intersect