云数据库技术

SQL Server 空间类型介绍

SQL Server功能非常强大,它对空间类型也有着非常强的支持。本文用较为简短的篇幅概述其空间类型的基本使用与原理。可以帮助读者了解空间类型的整体框架,如需了解更多细节,可以继续阅读其文档获取更多详情。 另外,本文内容比较“干”,看客需要自备矿泉水解渴。

01、概述

  • ‍ 官方介绍
SQL Server的空间类型主要有两种,分别是空间几何类型(Geometry)和空间地理类型(Geography)。其中, Geometry 类型表示欧几里得(平面)坐标系中的数据,Geography 类型表示圆形地球坐标系中的数据,如 GPS 经纬度坐标数据。
  • 通俗介绍
Geometry是平面空间数据类型,通过该类型可以保存平面坐标系(也就是X、Y平面坐标系)上的点(单点、多点)、线(弧线、折线)、多边形(多边形内嵌)。G eography是立体空间数据类型,主要是用于记录地球的经纬度。
空间几何和空间地理数据类型支持 16 种空间数据对象或实例类型,分为Point(点)、Curve (线) 、Surface (面) 、GeomCollection (集合)四大类。 这些实例类型中只有 11 种是可实例化的,分别为 Point、LineString、CircularString、CompundCurve、Polygon、CurvePolygon、MultiPolygon、MultiLineString、MultiPoint 和 GeomCollection。图1显示16种数据类型所基于的几何层次结构,其中11种可实例化类型以蓝色表示。

图1
只要实例的格式正确,即使未显式定义该实例,Geometry 和 Geography 类型也可识别该实例。例如,如果您使用 STPointFromText() 方法显式定义了一个 Point 实例,只要方法输入的格式正确,Geometry 和 Geography 便将该实例识别为 Point。如果您使用 STGeomFromText() 方法定义了相同的实例,则 Geometry 和 Geography 数据类型都将该实例识别为 Point。 另外,空间几何类型有SRID(Spatial Reference Identifiers)概念。因为 地球并不是理想化的平面,也不是理想的圆形,而是一个非标准的椭圆球体。因此,在不同的经纬度位置,计算两点的距离没有一个完美的公式。所以坐标系应运而生,SRID是指数据的坐标系,不同坐标系数据不具有比较的意义。SQL Server的Geometry类型默认的SRID是0, Geography类型默认的是4326。 空间几何的数据类型也是支持create Spatial index,此类型的索引结构是B-tree, 前提是 该表必须有主键 ,详细的空间索引类型可以参考官方介绍。
  • 示例
该示例表示创建包含一个自增列、一个Geography类型列名为GeogCol1的表,第三列使用 Geography中的 STAsText()方法的计算列。 然后插入三行数据,分别是含Point、LineString 和Polygon类型的实例。
DROP TABLE if EXISTS SpatialTable;   CREATE TABLE SpatialTable       ( id int IDENTITY (1,1),      GeogCol1 geography,       GeogCol2 AS GeogCol1.STAsText() );  GO  INSERT INTO SpatialTable (GeogCol1)  VALUES (geography::STGeomFromText('POINT(-122.360 47.656)', 4326));  INSERT INTO SpatialTable (GeogCol1)  VALUES (geography::STGeomFromText('LINESTRING(-122.360 47.656, -122.343 47.656 )', 4326));  INSERT INTO SpatialTable (GeogCol1)  VALUES (geography::STGeomFromText('POLYGON((-122.358 47.653 , -122.348 47.649, -122.348 47.658, -122.358 47.658, -122.358 47.653))', 4326));  GO
下面分别从点、线、面和集合四大类别中各抽取一个可实例化对象为例,简单介绍SQL Server空间数据类型是如何使用的。

02、点:Point

在SQL Server数据中,Point 是表示单个位置的 0 维对象,可能包含 Z (标高) 和 M (度量) 值。
  • Geography 类型

在Geography 数据类型中Point表示单个位置,其中 Long 表示经度(前一位),Lat 表示纬度(后一位), 维度和经度值以度数进行衡量。其中纬度值始终处于间隔 [-90, 90] 内,如果输入的值超出此范围,将引发异常。而经度值始终处于间隔 (-180, 180] 内,如果输入的值超出此范围,并不会直接报错,而是先对对值进行回绕以便适合此范围。例 如,如果为经度值输入 190,则该值将被回绕到值 -170。 但是经度值必须在 -15069 和 15069 度之间,否则也会报错。 SRID 表示您希望返回的 geometry 实例的空间引用 ID,默认是4326。


  • Geometry类型

在Geometry 数据类型中Point 类型表示单个位置,其中 X 表示要生成的点的 X 坐标, Y 表示要生成的点的 Y 坐标。SRID 表示您希望返回的 geometry 实例的空间引用 ID ,默认是0。
  • 示例
下面的示例创建一个 geometry类型 表示点 (3, 4) 的几何点实例,它的 SRID 为 0。
DECLARE @g geometry;  SET @g = geometry::STGeomFromText('POINT (3 4)', 0);

下面的示例创建一个 geometry类型 表示点 (3, 4) 的几何点实例,它的 Z(高程)值为 7、M(度量)值为 2.5 且默认 SRID 为 0。

DECLARE @g geometry;  SET @g = geometry::STGeomFromText('POINT(3 4 7 2.5)');

03、线:LineString

LineString 是一个一维对象,表示一系列点和连接这些点的线段。下图2显示了 LineString 实例的示例。

图2
图2中:
  • 1显示的是一个简单、非闭合的 LineString 实例。
  • 2显示的是一个不简单、非闭合的 LineString 实例。
  • 3显示的是一个闭合、简单的 LineString 实例,因此是一个环。
  • 4显示的是一个闭合、不简单的 LineString 实例,因此不是一个环。
LineString实例分为可接受的、有效的,其中有效实例表示必须有两个及以上不同的点组成或者实例为空,如果两个是 LineString实例是两个相同的点,则称之为可接受但无效实例,使用时会报 System.FormatException 异常。
  • 示例
有效实例,返回1。
DECLARE @g1 geometry= 'LINESTRING EMPTY';  DECLARE @g2 geometry= 'LINESTRING(1 1, 1 2)'; DECLARE @g3 geometry= 'LINESTRING(1 1, 3 3, 2 4, 2 0)';  SELECT @g1.STIsValid(), @g2.STIsValid(), @g3.STIsValid();
无效可接受实例,返回0。
DECLARE @g1 geometry= 'LINESTRING(1 1, 1 1)';SELECT @g1.STIsValid()



04、面:Polygon

Polygon 是存储为一系列点的二维表面,这些点定义一个外部边界环和零个或多个内部环。至少具有三个不同点的平面才可以构建一个 Polygon 实例。Polygon 实例也可以为空。下图3显示了 Polygon 实例的示例。

图3 图3中:
  • 1是由外部环定义其边界的 Polygon 实例。
  • 2是由外部环和两个内部环定义其边界的 Polygon 实例。内部环内的面积是 Polygon 实例的外部环的一部分。
  • 3是一个有效的 Polygon 实例,因为其内部环在单个切点处相交。

  • 示例
以下示例创建了一个带有孔且SRID为10的简单GeometryPolygon实例。
DECLARE @g geometry;SET @g=geometry::STPolyFromText('POLYGON((0 0, 0 3, 3 3, 3 0, 0 0), (1 1, 1 2, 2 1, 1 1))',10);

05、集合:GemetryCollection

GeometryCollection 是零个或更多个 geometry 或 geography 实例的集合,也就是该实例可以为空。 GeometryCollection实例中所有的实例都为有效时,该集合类型才为有效实例。
  • 示例
以下示例显示三个有效的 GeometryCollection 实例和一个g4无效的实例。
DECLARE @g1 geometry = 'GEOMETRYCOLLECTION EMPTY';  DECLARE @g2 geometry = 'GEOMETRYCOLLECTION(LINESTRING EMPTY,POLYGON((-1 -1, -1 -5, -5 -5, -5 -1, -1 -1)))';  DECLARE @g3 geometry = 'GEOMETRYCOLLECTION(LINESTRING(1 1, 3 5),POLYGON((-1 -1, -1 -5, -5 -5, -5 -1, -1 -1)))';  DECLARE @g4 geometry = 'GEOMETRYCOLLECTION(LINESTRING(1 1, 3 5),POLYGON((-1 -1, 1 -5, -5 5, -5 -1, -1 -1)))';  SELECT @g1.STIsValid(), @g2.STIsValid(), @g3.STIsValid(), @g4.STIsValid();

06、 数据类型常用函数使用

空间地理类型的实例提供了丰富的函数,例如将数据类型转换成字符串、判断实例几何图形类型等等函数。下面简单介绍几个常用的数据类型。
  • STAsText将几何图形转换成字符串

使用:Geometry实例.STAsText() 返回类型:nvarchar(max)

  • STBoundary查询几何图形的边界

使用:Geometry实例.STBoundary() 返回类型:geometry 当图形对象是Point时,查询其边界,返回的Geometry类型为空。

  • STGeometryType查询几何图形的类型

使用:Geometry实例.STGeometryType() 返回类型:nvarchar(4000)

  • 线段相关方法
STLength:计算线段长度 STStartPoint:返回Geometry实例第一个Point STEndPoint:返回Geometry实例最后一个Point STPointN:返回Geometry实例制定Point
  • 多边形相关方法
STArea:求多边形面积 STNRings:返回多边形中环的数量 STPerimeter:返回闭环的长度包括内环 STExteriorRing:以线串的形式返回多边形最外面的环 STInteriorRingN:以线串形式返回指定的内部环
  • 其他常用方法
STGeometryType:返回一个几何类型 更多的方法使用参考SQL Server官方文档。

07、总结

到此,我们对SQL Server的空间地理类型应该有了初步的认识。简单总结下,SQL Server空间地理类型分为空间几何类型(Geometry)和空间地理类型(Geography),其中Geometry用于平面几何图形,Geography用于空间地理。两种类型支持 16 种空间数据对象或实例类型,分为Point(点)、Curve(线)、Surface(面)、GeomCollection(集合)四大类,其中有 11 种可以实例化。另外,对于空间类型还有特有的SRID标识,一般我们用默认值即可。

08、参考

@SQL Server Spatial Data Type @SQL Server Spatial index @SQL Server Data types (Transact-SQL) @Wiki SCID 往期内容推荐:




SQL Server 2022公测:全面支持云服务的数据库
云厂商SQL Server 性能测试报告
云数据库技术行业动态@2022-06-24
云数据库技术行业动态@2022-06-10
云数据库技术行业动态 ‍ @ 2022-05-27 ‍