STAsText: примеры (SQL)
STAsText: nvarchar(max)Функция STAsText в MS SQL Server
Функция STAsText является методом для экземпляров пространственных данных (geometry и geography) в SQL Server. Она возвращает представление экземпляра в формате WKT (Well-Known Text) открытого геопространционного консорциума (OGC).
Функция используется, когда необходимо получить текстовое, читаемое человеком описание геометрического объекта для отладки, логирования или передачи в системы, поддерживающие формат WKT.
Синтаксис и аргументы
Синтаксис метода: .STAsText ( )
Метод не принимает аргументов. Он вызывается для конкретного экземпляра пространственного типа данных (geometry или geography).
Возвращаемое значение
Тип возвращаемого значения: nvarchar(max)
Метод возвращает текстовое описание объекта. Для пустого экземпляра возвращается строка 'EMPTY'. Для экземпляра, не инициализированного с помощью метода STGeomFromText, может возвращаться NULL.
Формат WKT:
- Точка: POINT (X Y)
- Линия: LINESTRING (X1 Y1, X2 Y2, ...)
- Полигон: POLYGON ((X1 Y1, X2 Y2, ..., X1 Y1))
- Мультиточка: MULTIPOINT ((X1 Y1), (X2 Y2))
- Мультилиния: MULTILINESTRING ((...), (...))
- Мультиполигон: MULTIPOLYGON (((...)), ((...)))
- Коллекция: GEOMETRYCOLLECTION (POINT(...), LINESTRING(...))
Простые примеры использования STAsText
Пример 1: Точка (Point)
DECLARE @g geometry = geometry::STGeomFromText('POINT (10 20)', 0);
SELECT @g.STAsText() AS WKT_Result;WKT_Result POINT (10 20)
Пример 2: Линия (LineString)
DECLARE @g geometry;
SET @g = geometry::STGeomFromText('LINESTRING (0 0, 10 10, 20 5)', 4326);
SELECT @g.STAsText() AS LineString_WKT;LineString_WKT LINESTRING (0 0, 10 10, 20 5)
Пример 3: Полигон (Polygon)
DECLARE @g geometry = geometry::Parse('POLYGON ((0 0, 10 0, 10 10, 0 10, 0 0))');
SELECT @g.STAsText() AS Polygon_WKT;Polygon_WKT POLYGON ((0 0, 10 0, 10 10, 0 10, 0 0))
Пример 4: Пустой объект (Empty)
DECLARE @g geometry = geometry::STGeomFromText('POINT EMPTY', 0);
SELECT @g.STAsText() AS Empty_WKT;Empty_WKT EMPTY
Пример 5: Тип geography
DECLARE @g geography = geography::STGeomFromText('POINT(-122.359 47.651)', 4326);
SELECT @g.STAsText() AS Geog_WKT;Geog_WKT POINT (-122.359 47.651)
Похожие функции в MS SQL Server
ToString()
Метод .ToString() возвращает то же текстовое представление, что и STAsText(), но в формате, совместимом с более ранними версиями SQL Server. Функционально аналогичен для вывода WKT. Использование предпочтительно в сценариях обратной совместимости.
DECLARE @g geometry = geometry::STPointFromText('POINT(5 7)', 0);
SELECT @g.ToString() AS StringResult;StringResult POINT (5 7)
STGeometryType()
Метод .STGeometryType() возвращает не координаты, а имя типа геометрического объекта (например, 'Point', 'LineString'). Полезен для определения типа объекта перед его обработкой.
DECLARE @g geometry = geometry::STGeomFromText('LINESTRING(0 0, 1 1)', 0);
SELECT @g.STGeometryType() AS GeoType;GeoType LineString
AsTextZM()
Метод .AsTextZM() возвращает представление в формате WKT с учетом значений Z (высота) и M (мера), если они присутствуют в данных. STAsText() эти значения игнорирует. Использование предпочтительно для объектов с 3D или 4D координатами.
DECLARE @g geometry = geometry::Parse('POINT(1 2 3 4)');
SELECT @g.AsTextZM() AS ZM_Text,
@g.STAsText() AS Standard_Text;ZM_Text Standard_Text POINT (1 2 3 4) POINT (1 2)
Аналоги функции в других СУБД и языках
PostgreSQL/PostGIS
Функция ST_AsText(geometry) возвращает WKT представление. Аналогична SQL Server. Используется с типом данных GEOMETRY.
SELECT ST_AsText(ST_GeomFromText('POINT(10 20)'));st_astext POINT(10 20)
MySQL
Функция ST_AsText(g) возвращает WKT строку. Для spatial типов, таких как Point, LineString.
SELECT ST_AsText(ST_GeomFromText('POINT(15 30)'));ST_AsText(ST_GeomFromText('POINT(15 30)'))
POINT(15 30)Oracle Spatial
Метод SDO_UTIL.TO_WKTGEOMETRY(sdo_geometry) возвращает WKT. В более новых версиях также используется GET_WKT(). Отличается более сложной моделью данных SDO_GEOMETRY.
SELECT SDO_UTIL.TO_WKTGEOMETRY(SDO_GEOMETRY(2001, NULL, SDO_POINT_TYPE(10, 20, NULL), NULL, NULL)) AS WKT FROM DUAL;WKT POINT (10.0 20.0)
SQLite с расширением SpatiaLite
Функция AsText(geometry) возвращает WKT представление.
SELECT AsText(MakePoint(10, 20));AsText(MakePoint(10, 20)) POINT(10 20)
Python (библиотека Shapely)
Свойство .wkt объекта геометрии возвращает WKT строку.
from shapely.geometry import Point
p = Point(10, 20)
print(p.wkt)POINT (10 20)
Типичные ошибки при использовании STAsText
Вызов для NULL экземпляра
Если переменная пространственного типа равна NULL, вызов метода STAsText() вернет NULL, а не ошибку.
DECLARE @g geometry;
SELECT @g.STAsText() AS Result;Result NULL
Неправильный формат исходных данных
Ошибка возникает на этапе создания объекта, а не при вызове STAsText(). Метод требует валидный геометрический объект.
DECLARE @g geometry;
SET @g = geometry::STGeomFromText('NOTAGEOMETRY (10 20)', 0); -- Ошибка парсинга
SELECT @g.STAsText();Сообщение 6522, уровень 16... Неправильный тип данных geometry...
Путаница между geometry и geography
Метод работает для обоих типов, но важно понимать разницу в семантике координат (плоскость vs сфера).
DECLARE @geo geography = geography::Point(47.651, -122.359, 4326);
SELECT @geo.STAsText() AS WKT; -- Координаты в порядке долгота/широтаWKT POINT (-122.359 47.651)
Изменения в функции
Функция STAsText была введена в SQL Server 2008 вместе с поддержкой пространственных данных. С тех пор ее основная функциональность не претерпела значительных изменений.
В SQL Server 2012 и более поздних версиях улучшена общая производительность пространственных типов данных, что косвенно могло повлиять и на скорость работы этого метода.
Важное уточнение: начиная с SQL Server 2012, для получения WKT-представления с координатами Z и M рекомендуется использовать метод AsTextZM(), так как STAsText() продолжает возвращать только двумерные координаты (X, Y), игнорируя дополнительные измерения, если они есть.
Расширенные примеры использования
Пример 1: Работа с коллекцией объектов
DECLARE @col geometry = geometry::STGeomFromText('GEOMETRYCOLLECTION(POINT(1 2), LINESTRING(3 4, 5 6))', 0);
SELECT @col.STAsText() AS Collection_WKT,
@col.STNumGeometries() AS Num_Geoms;Collection_WKT GEOMETRYCOLLECTION (POINT (1 2), LINESTRING (3 4, 5 6)) Num_Geoms 2
Пример 2: Извлечение и анализ отдельных частей мультиполигона
DECLARE @mp geometry = geometry::STGeomFromText('MULTIPOLYGON (((0 0, 5 0, 5 5, 0 5, 0 0)), ((10 10, 15 10, 15 15, 10 15, 10 10)))', 0);
SELECT @mp.STGeometryN(1).STAsText() AS First_Polygon,
@mp.STGeometryN(2).STAsText() AS Second_Polygon,
@mp.STArea() AS Total_Area;First_Polygon POLYGON ((0 0, 5 0, 5 5, 0 5, 0 0)) Second_Polygon POLYGON ((10 10, 15 10, 15 15, 10 15, 10 10)) Total_Area 50
Пример 3: Преобразование между типами geometry и geography с сохранением WKT
DECLARE @g_geom geometry = geometry::STGeomFromText('POINT(10 20)', 4326);
DECLARE @g_geog geography = geography::STGeomFromText(@g_geom.STAsText(), 4326);
SELECT @g_geom.STAsText() AS Geom_WKT,
@g_geog.STAsText() AS Geog_WKT,
@g_geog.Lat AS Latitude,
@g_geog.Long AS Longitude;Geom_WKT POINT (10 20) Geog_WKT POINT (10 20) Latitude 20 Longitude 10
Пример 4: Использование в табличном запросе для сериализации
CREATE TABLE #SpatialData (id INT, geom geometry);
INSERT INTO #SpatialData VALUES
(1, geometry::Point(0, 0, 0)),
(2, geometry::STGeomFromText('LINESTRING(1 1, 2 2)', 0)),
(3, geometry::Parse('POLYGON((0 0, 3 0, 3 3, 0 3, 0 0))'));
SELECT id, geom.STAsText() AS WKT_Representation
FROM #SpatialData
ORDER BY id;
DROP TABLE #SpatialData;id WKT_Representation 1 POINT (0 0) 2 LINESTRING (1 1, 2 2) 3 POLYGON ((0 0, 3 0, 3 3, 0 3, 0 0))
Пример 5: Сравнение объектов через их текстовое представление
DECLARE @g1 geometry = geometry::STGeomFromText('POINT(5 5)', 0);
DECLARE @g2 geometry = geometry::Point(5, 5, 0);
DECLARE @g3 geometry = geometry::STGeomFromText('POINT(5 6)', 0);
SELECT @g1.STAsText() AS g1_WKT,
@g2.STAsText() AS g2_WKT,
CASE WHEN @g1.STEquals(@g2) = 1 THEN 'Equal' ELSE 'Not Equal' END AS Compare_1_2,
@g3.STAsText() AS g3_WKT,
CASE WHEN @g1.STEquals(@g3) = 1 THEN 'Equal' ELSE 'Not Equal' END AS Compare_1_3;g1_WKT g2_WKT Compare_1_2 g3_WKT Compare_1_3 POINT (5 5) POINT (5 5) Equal POINT (5 6) Not Equal