本文摘抄自SQL 2008 帮助阅读笔记
有两种类型的空间数据。geometry 数据类型支持平面或欧几里得(平面球)数据。geometry 数据类型符合适用于 SQL 规范的开放地理空间联盟 (OGC) 简单特征 1.1.0 版。
另外,SQL Server 支持 geography 数据类型,该数据类型可存储诸如 GPS 纬度和经度坐标之类的椭圆体(圆球)数据。
geometry 和 geography 数据类型支持十一种空间数据对象或实例类型。但是,这些实例类型中只有七种“可实例化”;可以在数据库中创建并使用这些实例(或可对其进行实例化)。这些实例的某些属性由其父级数据类型派生而来,使其在 GeometryCollection 中区分为 Points、 LineStrings、Polygons 或多个 geometry 或 geography 实例。
下图描述了 geometry 和 geography 数据类型所基于的 geometry 层次结构。geometry 和 geography 的可实例化类型以蓝色表示。
如图所示,geometry 和 geography 数据类型的七种可实例化类型为 Point、MultiPoint、LineString、MultiLineString、Polygon、MultiPolygon 和 GeometryCollection。只要特定实例的格式正确,即使未显式定义该实例,geometry 和 geography 类型也可识别该实例。例如,如果您使用 STPointFromText() 方法显式定义了一个 Point 实例,只要方法输入的格式正确,geometry 和 geography 便将该实例识别为 Point。如果您使用 STGeomFromText()
方法定义了相同的实例,则 geometry 和 geography 数据类型都将该实例识别为 Point。
SRID (空间引用标识符)
每个空间实例都有一个空间引用标识符 (SRID)。
SRID 对应于基于特定椭圆体的空间引用系统,可用于平面球体映射或圆球映射。
空间列可包含具有不同 SRID 的对象。
然而,在使用 SQL Server 空间数据方法对数据执行操作时,仅可使用具有相同 SRID 的空间实例。
从两个空间数据实例派生的任何空间方法的结果仅在这两个实例具有相同的 SRID(该 SRID 基于相同的用于确定实例坐标的度量单位、数据和投影)时才有效。SRID 最常见的度量单位为米或平方米。
如果两个空间实例的 SRID 不相同,则对这两个实例使用 geometry 或 geography 数据类型方法后的结果将返回 NULL。例如,若要以下谓词返回非 NULL 结果,两个 geometry 实例(geometry1
和 geometry2
)必须具有相同的 SRID:
geometry1.STIntersects(geometry2) = 1
空间引用标识系统是由 European Petroleum Survey Group (EPSG) standard(欧洲石油测绘组 (EPSG) 标准)定义的,它是为绘图、测绘以及大地测量数据存储而开发的一组标准。该标准归石油天然气生产商 (OGP) 测绘和定位委员会所有。
几何图形实例默认 SRID 为零
SQL Server 中 geometry 实例的默认 SRID 为 0。利用 geometry 空间数据,执行计算是不需要空间实例的指定 SRID 的;因此,实例可驻留在未定义的平面空间。若要在 geometry 数据类型方法的计算中指明未定义的平面空间,SQL Server 数据库引擎 使用 SRID 0。
地域实例必须使用支持的 SRID
SQL Server 支持基于 EPSG 标准的 SRID。必须使用 geography 实例的支持,SQL Server 的 SRID 执行计算或将方法用于地域空间数据。
SRID 必须与 sys.spatial_reference_systems 目录视图中显示的 SRID 中的一个匹配。
如前所述,在使用 geography 数据类型对空间数据执行计算时,结果将取决于在创建数据时使用的是哪个椭圆体,因为为每个椭圆体都分配了一个特定空间引用标识符 (SRID)。
对 geography 实例使用方法时,SQL Server 使用等于 4326 的默认 SRID,它将映射到 WGS 84 空间引用系统。如果要使用 WGS 84(或 SRID 4326)之外的某个空间引用系统中的数据,您需要确定地域空间数据的特定 SRID。
点
在 SQL Server 空间数据中,Point 是表示单个位置的零维对象,可能包含 Z(仰角)和 M(度量)值。
下面的示例创建一个表示点 (3, 4) 的 geometry Point
实例,该实例的 SRID 为 0。
DECLARE @g geometry; SET @g = geometry::STGeomFromText('POINT (3 4)', 0);
下一个示例创建一个表示点 (3, 4) 的 geometry
Point
实例,该实例的 Z(仰角)值为 7,M(度量)值为 2.5,默认 SRID 为 0。
DECLARE @g geometry; SET @g = geometry::Parse('POINT(3 4 7 2.5)');
最后一个示例返回 geometry
Point
实例的 X、Y、Z 和 M 值。
SELECT @g.STX; SELECT @g.STY; SELECT @g.Z; SELECT @g.M;
Z 和 M 值可以显式指定为 NULL,如下例所示。
DECLARE @g geometry; SET @g = geometry::Parse('POINT(3 4 NULL NULL)');
C#
SqlGeometry centPoint = (SqlGeometry)dr.GetValue(1); // 中心点或点SQlGeometry类型 //实际上下面的代码执行一次就跳出了 // 随机取了第一个点为中心点 for (int j = 1; j <= centPoint.STNumPoints(); j++ ) { GeoPoint geoPoint = new GeoPoint (centPoint.STPointN(j).STX.Value, centPoint.STPointN(j).STY.Value); //面积中心点 spatialRes.GeoPolygon.CentPoint = geoPoint; //点 spatialRes.GeoPoint = geoPoint; break; }
MultiPoint
MultiPoint 是零个点或更多个点的集合。MultiPoint 实例的边界为空。
下面的示例创建一个 geometry MultiPoint
实例,该实例的 SRID 为 23 且包含两个点:一个点的坐标为 (2, 3),另一个点的坐标为 (7, 8),Z 值为 9.5。
DECLARE @g geometry; SET @g = geometry::STGeomFromText('MULTIPOINT((2 3), (7 8 9.5))', 23);
该 MultiPoint
实例也可使用 STMPointFromText()
表示,如下所示。
DECLARE @g geometry; SET @g = geometry::STMPointFromText('MULTIPOINT((2 3), (7 8 9.5))', 23);
下面的示例使用方法 STGeometryN()
来检索有关集合中第一个点的说明。
SELECT @g.STGeometryN(1).STAsText();
LineString
LineString 是一个一维对象,表示一系列点和连接这些点的线段。一个 LineString 实例必须由至少两个非重复点组成,也可以为空。
如图中所示:
- 图 1 显示的是一个简单、非闭合的 LineString 实例。
- 图 2 显示的是一个不简单、非闭合的 LineString 实例。
- 图 3 显示的是一个闭合、简单的 LineString 实例,因此是一个环。
- 图 4 显示的是一个闭合、不简单的 LineString 实例,因此不是一个环。
下面的示例说明如何创建一个包含三个点且 SRID 为 0 的 geometry
LineString
实例:
DECLARE @g geometry; SET @g = geometry::STGeomFromText('LINESTRING(1 1, 2 4, 3 9)', 0);
此 LineString
实例中的每个点都可以包含 Z(仰角)和 M(度量)值。下面这个示例向上例中创建的 LineString
实例添加了 M 值。M 和 Z 可以为 Null 值。
DECLARE @g geometry; SET @g = geometry::STGeomFromText('LINESTRING(1 1 NULL 0, 2 4 NULL 12.3, 3 9 NULL 24.5)', 0);
MultiLineString
MultiLineString 是零个或更多 geometry 或 geography LineString 实例的集合。
如图中所示:
- 图 1 显示的是一个简单的 MultiLineString 实例,其边界是其两个 LineString 元素的四个端点。
- 图 2 显示的是一个简单的 MultiLineString 实例,因为只有 LineString 元素的端点相交。边界是两个不重叠的端点。
- 图 3 显示的是一个不简单的 MultiLineString 实例,因为它的其中一个 LineString 元素的内部出现了相交。此 MultiLineString 实例的边界是四个端点。
- 图 4 显示的是一个不简单、非闭合的 MultiLineString 实例。
- 图 5 显示的是一个简单、非闭合的 MultiLineString。它没有闭合是因为它的 LineStrings 元素没有闭合。而其简单的原因在于,其任何 LineStrings 实例的内部都没有出现相交。
- 图 6 显示的是一个简单、闭合的 MultiLineString 实例。它为闭合的是因为它的所有元素都是闭合的。而其简单的原因在于,其所有元素都没有出现内部相交现象。
下面的示例创建了一个包含两个 LineString
元素且 SRID 为 0 的简单 geometry
MultiLineString
实例。
DECLARE @g geometry; SET @g = geometry::Parse('MULTILINESTRING((0 2, 1 1), (1 0, 1 1))');
若要使用不同的 SRID 实例化此实例,请使用 STGeomFromText()
或 STMLineStringFromText()
。也可以使用 Parse()
,然后修改 SRID,如下例所示。
DECLARE @g geometry; SET @g = geometry::Parse('MULTILINESTRING((0 2, 1 1), (1 0, 1 1))'); SET @g.STSrid = 13;
多边形
Polygon 是存储为一系列点的二维表面,这些点定义一个外部边界环和零个或多个内部环。可以从至少具有三个不同点的环中构建一个 Polygon 实例。Polygon 实例也可以为空。
Polygon 的外部环和任意内部环定义了其边界。环内部的空间定义了 Polygon 的内部。Polygon 的内部环在单个切点处既可与自身接触也可彼此接触,但如果 Polygon 的内部环交叉,则该实例无效。
如图中所示:
- 图 1 是由外部环定义其边界的 Polygon 实例。
- 图 2 是由外部环和两个内部环定义其边界的 Polygon 实例。内部环内的面积是 Polygon 实例的外部环的一部分。
- 图 3 是一个有效的 Polygon 实例,因为其内部环在单个切点处相交。
下例创建了一个带有孔和 SRID 为 10 的简单 geometry
Polygon
实例。
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);
可能输入无效的实例并转换为有效的 geometry
实例。在下列 Polygon
示例中,内部环和外部环重叠且该实例无效。
DECLARE @g geometry; SET @g = geometry::Parse('POLYGON((1 0, 0 1, 1 2, 2 1, 1 0), (2 0, 1 1, 2 2, 3 1, 2 0))');
在下例中,无效实例通过 MakeValid()
成为有效实例。
SET @g = @g.MakeValid(); SELECT @g.ToString();
以上示例中返回的 geometry
实例为 MultiPolygon
。
MULTIPOLYGON (((2 0, 3 1, 2 2, 1.5 1.5, 2 1, 1.5 0.5, 2 0)), ((1 0, 1.5 0.5, 1 1, 1.5 1.5, 1 2, 0 1, 1 0)))
MultiPolygon
MultiPolygon 实例是零个或更多个 Polygon 实例的集合。
如图中所示:
- 图 1 是一个包含两个 Polygon 元素的 MultiPolygon 实例。边界由两个外环和三个内环界定。
- 图 2 是一个包含两个 Polygon 元素的 MultiPolygon 实例。边界由两个外环和三个内环界定。这两个 Polygon 元素在切点处相交。
下面的示例演示如何创建 geometry
MultiPolygon
实例,并返回第二个组件的熟知文本 (WKT)。
DECLARE @g geometry; SET @g = geometry::Parse('MULTIPOLYGON(((0 0, 0 3, 3 3, 3 0, 0 0), (1 1, 1 2, 2 1, 1 1)), ((9 9, 9 10, 10 9, 9 9)))'); SELECT @g.STGeometryN(2).STAsText();
该示例实例化一个空的 MultiPolygon
实例。
DECLARE @g geometry; SET @g = geometry::Parse('MULTIPOLYGON EMPTY');
括号要注意一个()代表LineString (())代表面,((()))代表多面
GeometryCollection
GeometryCollection 是零个或更多个 geometry 或 geography 实例的集合。GeometryCollection 可以为空。
下面的示例实例化一个包含Point
实例和Polygon
实例的geometry
GeometryCollection
,它具有 Z 值,且 SRID 为 1。
DECLARE @g geometry; SET @g = geometry::STGeomCollFromText('GEOMETRYCOLLECTION(POINT(3 3 1), POLYGON((0 0 2, 1 10 3, 1 0 4, 0 0 2)))', 1);