STGeometryN: примеры (SQL)
STGeometryN(n): geometryОписание функции STGeometryN
Функция STGeometryN в MS SQL Server применяется для извлечения конкретной геометрической фигуры из коллекции пространственных объектов. Она используется при работе с составными типами геометрий, такими как MultiPoint, MultiLineString, MultiPolygon и GeometryCollection.
Функция принимает один аргумент:
- integer_expression - целочисленный индекс (начиная с 1), указывающий на порядковый номер геометрии в коллекции.
Возвращаемое значение - объект типа geometry, соответствующий указанной позиции. Если индекс выходит за пределы количества элементов, функция возвращает NULL. Для одиночных геометрий (не коллекций) при индексе 1 возвращается сам объект, при других значениях - NULL.
Примеры использования STGeometryN
Извлечение первой геометрии из коллекции:
DECLARE @g geometry = 'MULTIPOINT((1 1), (2 2), (3 3))';
SELECT @g.STGeometryN(1).STAsText();POINT (1 1)
Получение второго элемента из MultiLineString:
DECLARE @g geometry = 'MULTILINESTRING((0 0, 10 10), (20 20, 30 30))';
SELECT @g.STGeometryN(2).STAsText();LINESTRING (20 20, 30 30)
Попытка доступа к несуществующему элементу:
DECLARE @g geometry = 'MULTIPOINT((1 1))';
SELECT @g.STGeometryN(2);NULL
Похожие функции в MS SQL
STNumGeometries() определяет количество геометрий в коллекции. Полезна для итерации по элементам.
STGeometryType() возвращает тип геометрического объекта. Помогает идентифицировать структуру данных.
STPointN() извлекает конкретную точку из объекта LineString. Специализирована для линейных объектов.
STGeometryN предпочтительнее для работы с коллекциями геометрий, в то время как STPointN используется исключительно для точек в составе LineString.
Аналоги функции в других СУБД
PostgreSQL/PostGIS: ST_GeometryN работает аналогично, но индексация начинается с 1.
SELECT ST_AsText(ST_GeometryN('MULTIPOINT(1 1, 2 2)'::geometry, 2));POINT(2 2)
MySQL: ST_GeometryN также поддерживается с версии 5.7.
Oracle Spatial: функция SDO_UTIL.EXTRACT работает с элементами коллекций, но имеет другой синтаксис.
SELECT SDO_UTIL.EXTRACT(SDO_GEOMETRY(2005, NULL, NULL,
SDO_ELEM_INFO_ARRAY(1, 1, 3),
SDO_ORDINATE_ARRAY(1,1, 2,2)), 1) FROM DUAL;SQLite с расширением SpatiaLite поддерживает функцию GeometryN.
Типичные ошибки
Обращение к индексу 0 вызывает ошибку:
DECLARE @g geometry = 'MULTIPOINT((1 1))';
SELECT @g.STGeometryN(0);Ошибка: Аргумент 0 недопустим для метода "STGeometryN"
Применение функции к одиночной геометрии с индексом больше 1:
DECLARE @g geometry = 'POINT(1 1)';
SELECT @g.STGeometryN(2);NULL
Использование отрицательных значений индекса:
DECLARE @g geometry = 'MULTIPOINT((1 1))';
SELECT @g.STGeometryN(-1);Ошибка: Аргумент -1 недопустим для метода "STGeometryN"
Изменения в последних версиях
Функция STGeometryN не претерпела значительных изменений в последних версиях MS SQL Server. Начиная с SQL Server 2008, где была введена поддержка пространственных данных, ее поведение остается стабильным. В SQL Server 2012 и более поздних версиях улучшена общая производительность пространственных операций, что косвенно влияет и на работу этой функции.
Расширенные примеры применения
Итерация по всем элементам коллекции:
DECLARE @g geometry = 'GEOMETRYCOLLECTION(POINT(1 1), LINESTRING(0 0, 10 10), POLYGON((0 0, 10 0, 10 10, 0 10, 0 0)))';
DECLARE @i int = 1;
WHILE @i <= @g.STNumGeometries()
BEGIN
SELECT @i AS Position, @g.STGeometryN(@i).STGeometryType() AS Type,
@g.STGeometryN(@i).STAsText() AS Geometry;
SET @i = @i + 1;
ENDPosition | Type | Geometry 1 | Point | POINT (1 1) 2 | LineString| LINESTRING (0 0, 10 10) 3 | Polygon | POLYGON ((0 0, 10 0, 10 10, 0 10, 0 0))
Фильтрация элементов коллекции по типу:
DECLARE @g geometry = 'GEOMETRYCOLLECTION(POINT(1 1), POLYGON((0 0, 5 0, 5 5, 0 5, 0 0)))';
SELECT @g.STGeometryN(2).STAsText() AS PolygonOnly;POLYGON ((0 0, 5 0, 5 5, 0 5, 0 0))
Вычисление площади каждого полигона в мультиполигоне:
DECLARE @g geometry = 'MULTIPOLYGON(((0 0, 10 0, 10 10, 0 10, 0 0)),
((20 20, 30 20, 30 30, 20 30, 20 20)))';
SELECT @g.STGeometryN(1).STArea() AS Area1,
@g.STGeometryN(2).STArea() AS Area2;Area1 | Area2 100 | 100