STLength: примеры (SQL)
STLength: floatОписание функции STLength
Функция STLength() в Microsoft SQL Server применяется для вычисления длины экземпляра данных геометрического или географического типа. Она принадлежит к методам пространственных данных и возвращает суммарную длину всех элементов объекта. Использование функции актуально при работе с линейными объектами, такими как дороги, реки, границы, или для определения периметра полигональных фигур.
Синтаксис функции: geometry_instance.STLength() или geography_instance.STLength(). Метод не принимает аргументов. При вызове для объекта типа geometry возвращаемое значение имеет тип float и соответствует длине в единицах измерения, определённых для системы координат этого экземпляра. Для объекта типа geography результат также имеет тип float и выражается в метрах.
Если экземпляр является коллекцией (GeometryCollection, MultiLineString и т.д.), функция возвращает сумму длин всех входящих в неё элементов. Для пустого экземпляра возвращается 0. Для точечных объектов (Point, MultiPoint) возвращаемое значение всегда равно 0.
Простые примеры использования
Пример с геометрической линией (LINESTRING):
DECLARE @line geometry = geometry::STGeomFromText('LINESTRING(0 0, 3 4, 6 0)', 0);
SELECT @line.STLength() AS Length;Length 10
Пример с географической линией (GEOGRAPHY):
DECLARE @geo_line geography = geography::STGeomFromText('LINESTRING(37.61 55.74, 37.62 55.75)', 4326);
SELECT @geo_line.STLength() AS LengthMeters;LengthMeters 1415.35960949039
Пример с полигоном (периметр):
DECLARE @polygon geometry = geometry::STGeomFromText('POLYGON((0 0, 4 0, 4 3, 0 3, 0 0))', 0);
SELECT @polygon.STLength() AS Perimeter;Perimeter 14
Пример с пустой геометрией:
DECLARE @empty geometry = geometry::STGeomFromText('LINESTRING EMPTY', 0);
SELECT @empty.STLength() AS EmptyLength;EmptyLength 0
Похожие функции в MS SQL
STPerimeter() — вычисляет периметр полигонального объекта типа geometry. Для линейных объектов возвращает 0. Применяется, когда требуется получить именно длину внешней границы полигона. Функция STLength() для полигона возвращает тот же результат.
.Length — свойство экземпляров geometry и geography, которое является синонимом для метода STLength(). Использование свойства или метода даёт идентичный результат. Выбор между ними — вопрос стиля кодирования.
Предпочтение: STLength() является стандартным методом OGC, что обеспечивает лучшую читаемость кода. Свойство .Length может быть удобнее в коротких запросах.
Аналоги в других СУБД и языках
PostgreSQL/PostGIS: ST_Length(geometry). Для географических координат требуется приведение к geography или использование ST_Length(geography, use_spheroid).
SELECT ST_Length(ST_GeomFromText('LINESTRING(0 0, 3 4)'));5
MySQL: ST_Length(geom). До версии 8.0 возвращает результат в единицах системы координат, с 8.0 поддерживает географические вычисления.
SELECT ST_Length(ST_GeomFromText('LINESTRING(0 0, 3 4)'));5
Oracle: SDO_GEOM.SDO_LENGTH(geom, tol). Требует указания допуска (tolerance).
SELECT SDO_GEOM.SDO_LENGTH(SDO_GEOMETRY('LINESTRING(0 0, 3 4)', NULL), 0.005) FROM DUAL;5
SQLite с SpatiaLite: ST_Length(geom). Отличие: в SQLite функция может отсутствовать по умолчанию и требует загрузки расширения.
Типичные ошибки
1. Вызов для объекта нелинейного типа без учёта семантики. Для точки всегда возвращается 0, что может быть неочевидным.
DECLARE @point geometry = geometry::STPointFromText('POINT(10 20)', 0);
SELECT @point.STLength() AS PointLength;PointLength 0
2. Неучёт единиц измерения. Для geography результат всегда в метрах, для geometry — в единицах системы координат (например, градусах для WGS84). Использование разных SRID приводит к несопоставимым результатам.
DECLARE @line1 geometry = geometry::STGeomFromText('LINESTRING(0 0, 1 0)', 4326); -- градусы
DECLARE @line2 geometry = geometry::STGeomFromText('LINESTRING(0 0, 1 0)', 3857); -- метры
SELECT @line1.STLength() AS DegLength, @line2.STLength() AS MeterLength;DegLength MeterLength 1 1
Изменения в последних версиях
В SQL Server 2012 (11.x) и более поздних версиях функция STLength() для типа geography была обновлена для использования эллипсоидальной модели Земли (референц-эллипсоид WGS 84). В более ранних версиях (SQL Server 2008, 2008 R2) вычисления для geography выполнялись по сферической модели, что давало менее точные результаты, особенно для длинных отрезков. Изменение повысило точность расчётов расстояний между географическими координатами.
Расширенные примеры
Пример с составным объектом MultiLineString:
DECLARE @multi geometry = geometry::STGeomFromText('MULTILINESTRING((0 0, 5 0), (10 0, 10 5, 15 5))', 0);
SELECT @multi.STLength() AS TotalLength;TotalLength 15
Сравнение длины до и после применения буферизации:
DECLARE @road geometry = geometry::STGeomFromText('LINESTRING(0 0, 100 0)', 0);
DECLARE @road_buffer geometry = @road.STBuffer(5);
SELECT
@road.STLength() AS OriginalLineLength,
@road_buffer.STLength() AS BufferPerimeterLength;OriginalLineLength BufferPerimeterLength 100 220
Использование в запросе к таблице для фильтрации:
-- Предположим, существует таблица Rivers с полем geom типа geometry
SELECT Name, geom.STLength() AS RiverLength
FROM Rivers
WHERE geom.STLength() > 1000 -- Выбираем реки длиннее 1 км (в единицах SRID)
ORDER BY RiverLength DESC;Расчёт общей длины всех объектов в коллекции:
DECLARE @collection geometry = geometry::STGeomFromText('GEOMETRYCOLLECTION(
LINESTRING(0 0, 3 4),
POLYGON((5 5, 10 5, 10 10, 5 10, 5 5)),
LINESTRING(12 12, 12 18)
)', 0);
SELECT @collection.STLength() AS CollectionTotalLength;CollectionTotalLength 21
Пример с географическим типом и измерением расстояния между городами:
DECLARE @moscow_berlin geography = geography::STGeomFromText('LINESTRING(37.6173 55.7558, 13.4049 52.5200)', 4326);
SELECT ROUND(@moscow_berlin.STLength() / 1000, 0) AS Distance_KM;Distance_KM 1615