Поделиться через


Основные сведения о типах пространственных данных

Существует два типа пространственных данных. Тип данных 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, PolygonsCurvePolygons или как несколько 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 см. в одном из следующих источников:

Сегменты дуги

Три типа, допускающих создание экземпляров, могут принимать сегменты дуги: 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)