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

Использование STNumGeometries в геопространственных запросах
Раздел: Функции для работы с пространственными данными, Пространственные
STNumGeometries: int

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

Функция STNumGeometries() является методом типа данных geometry в Microsoft SQL Server. Она возвращает количество геометрических объектов, содержащихся в экземпляре geometry. Основное применение функции связано с мультигеометрическими типами, такими как MultiPoint, MultiLineString, MultiPolygon и GeometryCollection.

Метод не принимает параметров и вызывается для конкретного экземпляра геометрического объекта. Синтаксис вызова: geometry_instance.STNumGeometries().

Возвращаемое значение имеет тип int. Функция возвращает:

  • 1 для простых геометрических типов (Point, LineString, Polygon)
  • Число больше 1 для мультигеометрических типов
  • NULL, если экземпляр geometry является NULL

Функция доступна начиная с SQL Server 2008 и поддерживается во всех последующих версиях.

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

Пример с простой геометрией:

DECLARE @point geometry = geometry::STGeomFromText('POINT(10 20)', 0);
SELECT @point.STNumGeometries() AS NumberOfGeometries;
NumberOfGeometries
------------------
1

Пример с мультиточкой:

DECLARE @multiPoint geometry = geometry::STGeomFromText('MULTIPOINT((10 20), (30 40), (50 60))', 0);
SELECT @multiPoint.STNumGeometries() AS NumberOfGeometries;
NumberOfGeometries
------------------
3

Пример с коллекцией геометрий:

DECLARE @collection geometry = geometry::STGeomFromText('GEOMETRYCOLLECTION(POINT(10 20), LINESTRING(0 0, 10 10), POLYGON((0 0, 10 0, 10 10, 0 10, 0 0)))', 0);
SELECT @collection.STNumGeometries() AS NumberOfGeometries;
NumberOfGeometries
------------------
3

Похожие функции в MS SQL Server

В MS SQL Server существуют другие функции для работы с геометрическими объектами:

  • STGeometryN(индекс) возвращает конкретную геометрию из мультигеометрического объекта по указанному индексу (начинается с 1). Эта функция полезна для извлечения отдельных компонентов.
  • STNumPoints() возвращает общее количество точек в геометрическом объекте, включая все его компоненты.
  • STNumCurves() специфична для типов данных geometry и geography, возвращает количество кривых в объекте.

Функцию STNumGeometries предпочтительнее использовать для получения количества компонентов в мультигеометрических объектах, в то время как STGeometryN применяют для доступа к конкретным компонентам.

Альтернативы в других СУБД

PostgreSQL/PostGIS: Функция ST_NumGeometries работает аналогично. Пример:

SELECT ST_NumGeometries(ST_GeomFromText('MULTIPOINT(0 0, 1 1, 2 2)'));
3

MySQL: Функция ST_NumGeometries доступна с версии 5.6. Пример:

SELECT ST_NumGeometries(ST_GeomFromText('MultiPoint(1 1, 2 2, 3 3)'));
3

Oracle Spatial: Используется функция SDO_UTIL.GETNUMELEM или атрибут SDO_ORDINATE_ARRAY. Пример отличается структурой:

SELECT SDO_UTIL.GETNUMELEM(SDO_GEOMETRY(2005, NULL, NULL, SDO_ELEM_INFO_ARRAY(1,1,3), SDO_ORDINATE_ARRAY(1,1, 2,2, 3,3))) FROM DUAL;
3

SQLite с SpatiaLite: Функция NumGeometries. Пример:

SELECT NumGeometries(GeomFromText('MULTIPOINT(0 0, 1 1)'));
2

Типичные ошибки при использовании

Ошибка при вызове для неинициализированного объекта:

DECLARE @geom geometry;
SELECT @geom.STNumGeometries();
NULL

Ошибочное ожидание возврата 0 для пустой коллекции. Фактически пустая коллекция возвращает 1:

DECLARE @empty geometry = geometry::Parse('GEOMETRYCOLLECTION EMPTY');
SELECT @empty.STNumGeometries();
1

Путаница с индексацией. Метод STGeometryN использует 1-базовую индексацию, что может привести к ошибкам:

DECLARE @mp geometry = geometry::STGeomFromText('MULTIPOINT((1 1), (2 2))', 0);
SELECT @mp.STGeometryN(0).ToString(); -- Неверный индекс
NULL

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

Функция STNumGeometries не претерпела значительных изменений в синтаксисе или поведении с момента первоначального внедрения в SQL Server 2008. Основные улучшения касались общей производительности пространственных запросов и оптимизации обработки геометрических данных.

В SQL Server 2012 и более поздних версиях были улучшены алгоритмы обработки мультигеометрических объектов, что может незначительно влиять на скорость выполнения STNumGeometries для сложных объектов.

В последних версиях SQL Server также расширена совместимость со стандартами OGC (Open Geospatial Consortium), но базовое поведение функции остается неизменным.

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

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

Пример sql
WITH SpatialData AS (
    SELECT 1 AS id, geometry::STGeomFromText('MULTIPOINT((1 1), (2 2), (3 3))', 0) AS geom
    UNION ALL
    SELECT 2, geometry::STGeomFromText('POINT(4 4)', 0)
    UNION ALL
    SELECT 3, geometry::STGeomFromText('MULTIPOINT((5 5), (6 6))', 0)
)
SELECT id, geom.STNumGeometries() AS geom_count
FROM SpatialData
WHERE geom.STNumGeometries() > 1;
id | geom_count
---|-----------
1  | 3
3  | 2

Анализ GeometryCollection с разными типами объектов:

Пример sql
DECLARE @complex geometry = geometry::STGeomFromText('GEOMETRYCOLLECTION(
    POLYGON((0 0, 10 0, 10 10, 0 10, 0 0)),
    LINESTRING(0 0, 20 20),
    POINT(5 5),
    MULTIPOINT((1 1), (2 2))
)', 0);

SELECT 
    @complex.STNumGeometries() AS total_geometries,
    @complex.STGeometryN(1).STGeometryType() AS geom1_type,
    @complex.STGeometryN(4).STNumGeometries() AS multipoint_count;
total_geometries | geom1_type | multipoint_count
-----------------|------------|-----------------
4                | Polygon    | 2

Построение динамического SQL на основе количества геометрий:

Пример sql
DECLARE @geom geometry = geometry::STGeomFromText('MULTIPOINT((1 1), (2 2), (3 3), (4 4))', 0);
DECLARE @count INT = @geom.STNumGeometries();
DECLARE @i INT = 1;
DECLARE @sql NVARCHAR(MAX) = 'SELECT ';

WHILE @i <= @count
BEGIN
    SET @sql = @sql + 'geometry' + CAST(@i AS NVARCHAR) + ' = ''' + 
               @geom.STGeometryN(@i).ToString() + '''';    
    IF @i < @count SET @sql = @sql + ', ';
    SET @i = @i + 1;
END

PRINT @sql;
SELECT geometry1 = 'POINT (1 1)', geometry2 = 'POINT (2 2)', geometry3 = 'POINT (3 3)', geometry4 = 'POINT (4 4)'

MS SQL STNumGeometries function comments

En
STNumGeometries Returns the number of geometries that comprise a geometry instance