Основные сведения о типах пространственных данных
Существует два типа пространственных данных. Тип данных geometry
поддерживает планарные или эвклидовы данные (система координат для плоской Земли). Тип данных geometry
соответствует спецификации «Simple Features for SQL» консорциума OGC версии 1.1.0 и стандарту SQL MM (стандарт ISO).
Кроме того, SQL Server поддерживает geography
тип данных, в котором хранятся эллипсоидальные (круглоземные) данные, такие как координаты широты и долготы GPS.
Важно!
Подробное описание и примеры пространственных функций, представленных в SQL Server 2012 г., включая усовершенствования типов пространственных данных, см. в техническом документе Новые пространственные функции в SQL Server Code-Named "Денали".
Объекты пространственных данных
Типы данных geometry
и geography
поддерживают шестнадцать объектов пространственных данных или типов экземпляров. Однако только одиннадцать из этих типов экземпляров являются материализуемыми. Такие экземпляры можно создавать в базе данных и работать с ними. Эти экземпляры наследуют определенные свойства от родительских типов данных, которые различают их как Points
, LineStrings, CircularStrings, CompoundCurves
, Polygons
CurvePolygons
или как несколько geometry
экземпляров или geography
в GeometryCollection
. Тип Geography
имеет дополнительный тип экземпляра FullGlobe
.
На рисунке ниже изображена иерархия geometry
, на которой основаны типы данных geometry
и geography
. Типы экземпляров geometry
и geography
обозначены синим цветом.
Как показано на рисунке, 10 geometry
типов данных и geography
: Point
, MultiPoint
, LineString
, CircularString
, MultiLineString
, CompoundCurve
, , Polygon
, CurvePolygon
, , MultiPolygon
и GeometryCollection
. Есть один дополнительный тип, допускающий создание экземпляров, для типа данных geography: FullGlobe
. geometry
Типы и geography
могут распознавать конкретный экземпляр, если он является экземпляром правильного формата, даже если экземпляр не определен явным образом. Например, если вы явно определяете Point
экземпляр с помощью метода STPointFromText() и geography
распознаете экземпляр как Point
, при условии, geometry
что входные данные метода правильно сформированы. Если определить такой же экземпляр с помощью метода STGeomFromText()
, то оба типа данных geometry
и geography
будут распознавать экземпляр как Point
.
Подтипы для типов geometry и geography делятся на простые типы и типы-коллекции. Некоторые методы, например STNumCurves()
, работают только с простыми типами.
Простые типы:
Типы-коллекции:
Различия между типами данных geometry и geography
Два типа пространственных данных часто демонстрируют одинаковое поведение, однако у них имеется ряд ключевых различий в способе хранения и управления данными.
Определение границ соединения
Определяющими данными для типов LineString
и Polygon
могут быть только вершины. Границей соединения между двумя вершинами в типе geometry является прямая линия. Однако границей соединения между двумя вершинами в типе geography является короткая большая эллиптическая кривая, проложенная между вершинами. Большой эллипс представляет собой пересечение эллипсоида с плоскостью, проходящей через его центр, а большая эллиптическая кривая представляет собой сегмент кривой на большом эллипсе.
Определение сегментов дуги
Сегменты дуги для типов geometry определяются на декартовой координатной плоскости XY (значения Z не учитываются). Сегменты дуги для типов geography определяются сегментами кривой на эталонной сфере. Любую параллель на эталонной сфере можно определить двумя взаимодополняющими дугами, где точки для обеих дуг имеют постоянный угол широты.
Измерения в пространственных типах данных
В планарной модели (или модели плоской Земли) измерение расстояний и площадей проводятся в таких же единицах измерения, в каких представляются координаты. При использовании типа данных geometry
расстояние между точками (2, 2) и (5, 6) составляет 5 единиц, независимо от используемых единиц.
В эллиптической модели, или модели круглой Земли, координаты указываются в градусах долготы и широты. Однако длины и площади обычно измеряются в метрах и квадратных метрах, хотя измерения могут зависеть от идентификатора пространственной ссылки (SRID) экземпляра geography
. Самой распространенной единицей измерения типа данных geography
является метр.
Ориентация пространственных данных
В планарной системе ориентация кольца многоугольника является несущественным фактором. Например, многоугольник ((0, 0), (10, 0), (0, 20), (0, 0)) идентичен многоугольнику ((0, 0), (0, 20), (10, 0), (0, 0)). Спецификация простых функций OGC для SQL не диктует порядок кругов, а SQL Server не применяет упорядочение кругов.
В эллиптической модели без указания ориентации многоугольник не определен или является неоднозначным. Например, описывает ли кольцо вокруг экватора северное или южное полушарие? При использовании типа данных geography
для хранения пространственного экземпляра необходимо указать ориентацию кольца и точно описать расположение экземпляра. Внутренняя часть многоугольника в эллиптической модели определяется правилом левой руки.
Если уровень совместимости 100 или ниже в SQL Server 2019 (15.x), тип geography
данных имеет следующие ограничения:
Любой экземпляр
geography
должен лежать в пределах одного полушария. Не допускается сохранение пространственных объектов больше размера полушария.Любой экземпляр
geography
в представлении консорциума OGC Well-Known Text (WKT) или Well-Known Binary (WKB), порождающий объект больше полушария, приводит к возникновению исключенияArgumentException
.Методы
geography
типа данных, требующие ввода двухgeography
экземпляров, таких как STIntersection(), STUnion(), STDifference() и STSymDifference(), возвращают значение NULL, если результаты методов не помещаются в одно полушарие. Метод STBuffer() также возвращает значение NULL, если выходные данные выходят за пределы одного полушария.
В SQL Server 2019 (15.x) FullGlobe
— это особый тип многоугольника, охватывающий весь земной шар. Объект FullGlobe
имеет площадь, но не имеет границ и вершин.
Для типа данных geography внешнее и внутреннее кольца не важны.
В спецификации простых функций OGC для SQL рассматриваются внешние и внутренние кольца, но это различие не имеет смысла для типа данных SQL Servergeography
. Любое кольцо многоугольника может быть принято как внешнее кольцо.
Дополнительные сведения о спецификациях OGC см. в одном из следующих источников:
Спецификации OGC, простой доступ к функциям, часть 1 — общая архитектура
Спецификации OGC, простой доступ к функциям, часть 2 — параметры SQL
Сегменты дуги
Три типа, допускающих создание экземпляров, могут принимать сегменты дуги: CircularString
, CompoundCurve
и CurvePolygon
. Сегмент дуги определяется тремя точками на двумерной плоскости, при этом третья точка не может совпадать с первой.
Фигуры A и B являются типичными сегментами дуги. Обратите внимание, что каждая из трех точек лежит на периметре круга.
Фигуры C и D демонстрируют, как можно определить сегмент линии с помощью сегмента дуги. Обратите внимание, что для определения сегмента дуги по-прежнему требуются три точки, тогда как обычный сегмент линии можно определить с помощью двух точек.
Методы, работающие с типами сегментов дуги, для приближения дуги используют сегменты прямой линии. Количество сегментов, используемых для приближения дуги, зависит от длины и кривизны дуги. Значения Z можно сохранять для каждого типа сегмента дуги. Однако методы не используют значения Z в своих вычислениях.
Примечание
Если для сегментов дуги даются значения Z, они должны совпадать для всех точек сегмента дуги. Только в этом случае они могут быть приняты в качестве ввода. Например: CIRCULARSTRING(0 0 1, 2 2 1, 4 0 1)
принимается, но CIRCULARSTRING(0 0 1, 2 2 2, 4 0 1)
не принимается.
Сравнение типов LineString и CircularString
На следующей диаграмме показаны одинаковые равнобедренные треугольники (треугольник A для определения треугольника использует сегменты линии, а треугольник B — сегменты дуги).
В следующем примере показано, как сохранить эти равнобедренные треугольники с помощью экземпляра LineString
и экземпляра CircularString
:
DECLARE @g1 geometry;
DECLARE @g2 geometry;
SET @g1 = geometry::STGeomFromText('LINESTRING(1 1, 5 1, 3 5, 1 1)', 0);
SET @g2 = geometry::STGeomFromText('CIRCULARSTRING(1 1, 3 1, 5 1, 4 3, 3 5, 2 3, 1 1)', 0);
IF @g1.STIsValid() = 1 AND @g2.STIsValid() = 1
BEGIN
SELECT @g1.ToString(), @g2.ToString()
SELECT @g1.STLength() AS [LS Length], @g2.STLength() AS [CS Length]
END
Обратите внимание, что экземпляру CircularString
требуется семь точек для определения треугольника, тогда как экземпляру LineString
для этого достаточно всего четырех точек. Причиной этого является то, что экземпляр CircularString
хранит сегменты дуги, а не сегменты линии. Поэтому сторонами треугольника, хранящегося в экземпляре CircularString
, являются ABC, CDE и EFA, а сторонами треугольника, хранящегося в экземпляре LineString
, — AC, CE и EA.
Рассмотрим следующий фрагмент кода:
SET @g1 = geometry::STGeomFromText('LINESTRING(0 0, 2 2, 4 0)', 0);
SET @g2 = geometry::STGeomFromText('CIRCULARSTRING(0 0, 2 2, 4 0)', 0);
SELECT @g1.STLength() AS [LS Length], @g2.STLength() AS [CS Length];
Этот фрагмент выдаст следующие результаты:
LS LengthCS Length
5.65685...6.28318...
На следующем рисунке показано, как хранится каждый тип (красная линия — , LineString``@g1
синяя линия — ):CircularString``@g2
Как показано на рисунке выше, объекты CircularString
используют меньшее число точек для хранения границ кривой и обеспечивают большую точность, чем объекты LineString
. Объекты CircularString
полезны для хранения круговых границ, например область поиска радиусом в двадцать миль от указанной точки. Объекты LineString
хорошо подходят для хранения линейных границ, например городского квартала.
Сравнение типов LineString и CompoundCurve
В следующем примере кода показано, как одна и та же фигура сохраняется с помощью экземпляров LineString
и CompoundCurve
:
SET @g = geometry::Parse('LINESTRING(2 2, 4 2, 4 4, 2 4, 2 2)');
SET @g = geometry::Parse('COMPOUNDCURVE((2 2, 4 2), (4 2, 4 4), (4 4, 2 4), (2 4, 2 2))');
SET @g = geometry::Parse('COMPOUNDCURVE((2 2, 4 2, 4 4, 2 4, 2 2))');
или
В этих примерах фигура может храниться как экземпляр LineString
или как экземпляр CompoundCurve
. В следующем примере тип CompoundCurve
используется для хранения среза круговой диаграммы:
SET @g = geometry::Parse('COMPOUNDCURVE(CIRCULARSTRING(2 2, 1 3, 0 2),(0 2, 1 0, 2 2))');
Экземпляр CompoundCurve
может хранить сегмент дуги (2 2, 1 3, 0 2) непосредственно, в то время как экземпляру LineString
пришлось бы преобразовать кривую в несколько сегментов строки меньшего размера.
Сравнение типов CircularString и CompoundCurve
В следующем примере кода показано, как можно сохранить срезы круговой диаграммы в экземпляре CircularString
:
DECLARE @g geometry;
SET @g = geometry::Parse('CIRCULARSTRING( 0 0, 1 2.1082, 3 6.3246, 0 7, -3 6.3246, -1 2.1082, 0 0)');
SELECT @g.ToString(), @g.STLength();
Для хранения среза круговой диаграммы с помощью экземпляра CircularString
требуется три точки для каждого сегмента линии. Если промежуточная точка неизвестна, необходимо либо вычислить ее, либо сдублировать конечную точку сегмента линии, как показано в следующем фрагменте кода:
SET @g = geometry::Parse('CIRCULARSTRING( 0 0, 3 6.3246, 3 6.3246, 0 7, -3 6.3246, 0 0, 0 0)');
CompoundCurve
экземпляры разрешают оба LineString
компонента и CircularString
, поэтому необходимо знать только две точки на сегменты линий кругового среза. В этом примере кода показано, как использовать тип CompoundCurve
для хранения той же фигуры:
DECLARE @g geometry;
SET @g = geometry::Parse('COMPOUNDCURVE(CIRCULARSTRING( 3 6.3246, 0 7, -3 6.3246), (-3 6.3246, 0 0, 3 6.3246))');
SELECT @g.ToString(), @g.STLength();
Сравнение типов Polygon и CurvePolygon
Экземпляры CurvePolygon
могут использовать экземпляры CircularString
и CompoundCurve
для определения внешних и внутренних колец. Экземпляры Polygon
не могут использовать типы сегментов дуги: CircularString
и CompoundCurve
.
См. также:
Пространственные данные (SQL Server)geometry Data Type Method Referencegeography Data Type Method ReferenceSTNumCurves (geometry Data Type)STNumCurves (geography Data Type)STGeomFromText (geometry Data Type)STGeomFromText (geography Data Type)