SQL Server - sql 空间数据
以geometry
为例,geography
类似
目录
基础功能
创建空间表
录入数据
计算面积
转WKB
转WKT
转地理标记语言 (GML)
创建geometry实例
获得集合中的实例
STPointN
获得类型
是否闭合
是否为空
STIsSimple
是否有效
计算长度
SRID
获得点的X、Y坐标
是否包含M值
是否包含Z值
类型是否相同
拓扑计算
计算交集
计算是否包含
查询是否相交
计算差集
计算余集
计算并集
计算二者是否相连
计算最短距离
STEquals
是否有重叠
是否接触
是否完全包含
集合操作
基础功能
创建空间表
GeogCol1
是几何图形geometry
,GeogCol2
是根据GeogCol1
计算表达式
CREATE TABLE SpatialTable
( id int IDENTITY (1,1),
GeomCol1 geometry,
GeomCol2 AS GeomCol1.STAsText() );
录入数据
INSERT INTO SpatialTable (GeomCol1)
VALUES (geometry::STGeomFromText('LINESTRING (100 100, 20 180, 180 180)', 0));
INSERT INTO SpatialTable (GeomCol1)
VALUES (geometry::STGeomFromText('POLYGON ((0 0, 150 0, 150 150, 0 150, 0 0))', 0));
--也可以带srid
INSERT INTO SpatialTable (GeomCol1)
VALUES (geometry::STGeomFromText('LINESTRING (100 100, 20 180, 180 180)', 4326));
INSERT INTO SpatialTable (GeomCol1)
VALUES (geometry::STGeomFromText('POLYGON ((0 0, 150 0, 150 150, 0 150, 0 0))', 4326));
OGC静态方法 STGeomFromText将WKT字符串转换为geometry实例
计算面积
DECLARE @g geometry;
SET @g = geometry::STGeomFromText('POLYGON((0 0, 3 0, 3 3, 0 3, 0 0),(2 2, 2 1, 1 1, 1 2, 2 2))', 0);
SELECT @g.STArea();
--查询数据库记录以计算面积
DECLARE @g geometry;
SELECT @g = GeomCol1 FROM SpatialTable WHERE id = 2;
SELECT @g.STArea();
转WKB
DECLARE @g geometry;
SET @g = geometry::STGeomFromText('LINESTRING(0 0, 2 3)', 0);
SELECT @g.STAsBinary(); --0x0102000000020000000000000000000000000000000000000000000000000000400000000000000840
STAsBinary(geometry 数据类型)
AsBinaryZM
转WKT
DECLARE @g geometry;
SET @g = geometry::STGeomFromText('LINESTRING(0 0, 2 3)', 0);
SELECT @g.STAsText(); --LINESTRING (0 0, 2 3)
其他方法
DECLARE @g geometry;
SET @g = geometry::STGeomFromText('LINESTRING(0 0, 0 1, 1 0)', 0);
SELECT @g.ToString();
转地理标记语言 (GML)
GML是Geography Markup Language
DECLARE @g geometry;
SET @g = geometry::STGeomFromText('LINESTRING(0 0, 0 1, 1 0)', 0)
SELECT @g.AsGml();
--结果如下:
--<LineString xmlns="http://www.opengis.net/gml">
-- <posList>0 0 0 1 1 0</posList>
--</LineString>
创建geometry实例
OGC 静态几何图形方法
包括如下方法:
STGeomFromText(geometry 数据类型)
STPointFromText(geometry 数据类型)
STLineFromText(geometry 数据类型)
STPolyFromText(geometry 数据类型)
STMPointFromText(geometry 数据类型)
STMLineFromText(geometry 数据类型)
STMPolyFromText(geometry 数据类型)
STGeomCollFromText(geometry 数据类型)
STGeomFromWKB(geometry 数据类型)
STPointFromWKB(geometry 数据类型)
STLineFromWKB(geometry 数据类型)
STPolyFromWKB(geometry 数据类型)
STMPointFromWKB(geometry 数据类型)
STMLineFromWKB(geometry 数据类型)
STMPolyFromWKB(geometry 数据类型)
STGeomCollFromWKB(geometry 数据类型)
还有:
GeomFromGml:根据地理标记语言 (GML) 的 子集中的给定表示形式构建 geometry 实例
Parse
Point
获得集合中的实例
获得几何图形集合中的指定几何图形,即集合中的geometry 实例
DECLARE @g geometry;
SET @g = geometry::STGeomFromText('MULTIPOINT(0 0, 13.5 2, 7 19)', 0);
SELECT @g.STGeometryN(1).ToString(); --POINT (0 0)
SELECT @g.STGeometryN(2).ToString(); --POINT (13.5 2)
SELECT @g.STGeometryN(3).ToString(); --POINT (7 19)
SELECT @g.STGeometryN(4).ToString(); --NULL
STPointN
获得实例内部的点
DECLARE @g geometry;
SET @g = geometry::STGeomFromText('LINESTRING(0 0, 2 2, 1 0)', 0);
SELECT @g.STPointN(2).ToString(); --POINT (2 2)
获得类型
DECLARE @g geometry;
SET @g = geometry::STGeomFromText('POLYGON((0 0, 3 0, 3 3, 0 3, 0 0))', 0);
SELECT @g.STGeometryType();
是否闭合
DECLARE @g geometry;
DECLARE @l geometry;
SET @g = geometry::STGeomFromText('LINESTRING(0 0, 2 2, 1 0)', 0);
SET @l = geometry::STGeomFromText('LINESTRING(0 0, 2 2, 1 0, 0 0)', 0);
SELECT @g.STIsClosed(); --0
SELECT @l.STIsClosed(); --1
是否为空
DECLARE @g geometry;
SET @g = geometry::STGeomFromText('POLYGON EMPTY', 0);
SELECT @g.STIsEmpty();
STIsSimple
geometry 实例是开放地理空间信息联盟 (OGC) 所定义的简单实例,则返回 1。 如果 geometry 实例不是简单实例,则返回 0。
DECLARE @g geometry;
SET @g = geometry::STGeomFromText('LINESTRING(0 0, 2 2, 0 2, 2 0)', 0);
SELECT @g.STIsSimple();
是否有效
DECLARE @g geometry;
SET @g = geometry::STGeomFromText('LINESTRING(0 0, 2 2, 1 0)', 0);
SELECT @g.STIsValid();
SQL Server 只生成有效的 geometry 实例,但允许存储和检索无效的实例。 可使用 MakeValid()
方法检索表示任何无效实例的相同点集的有效实例。
STIsValid
确定空间对象无效的问题
DECLARE @p GEOMETRY = 'Polygon((2 2, 4 4, 4 2, 2 4, 2 2))'
SELECT @p.IsValidDetailed()
--Returns: 24404: Not valid because polygon ring (1) intersects itself or some other ring.
MakeValid
将无效 geometry 实例转换为具有有效开放地理空间信息联盟 (OGC) 类型的 geometry 实例
MakeValid
计算长度
DECLARE @g geometry;
SET @g = geometry::STGeomFromText('LINESTRING(0 0, 2 2, 1 0)', 0);
SELECT @g.STLength();
SRID
--查询SRID
DECLARE @g geometry;
SET @g = geometry::STGeomFromText('POLYGON((0 0, 3 0, 3 3, 0 3, 0 0))', 13);
SELECT @g.STSrid;
--修改SRID
SET @g.STSrid = 23;
SELECT @g.STSrid;
获得点的X、Y坐标
DECLARE @g geometry;
SET @g = geometry::STGeomFromText('POINT(3 8)', 0);
SELECT @g.STX;
SELECT @g.STY;
是否包含M值
M是度量值, 度量值的语义是用户定义的。
DECLARE @p GEOMETRY = 'Point(1 1 1 1)'
SELECT @p.HasM
--Returns: 1 (true)
是否包含Z值
Z是标高值。 标高值的语义是用户定义的。
DECLARE @p GEOMETRY = 'Point(1 1 1 1)'
SELECT @p.HasZ
--Returns: 1 (true)
类型是否相同
测试 geometry 实例是否与指定的类型
相同。 如果 geometry 实例的类型与指定类型相同,则返回 1。 如果指定的类型是该实例类型的上级,此方法也返回 1。 否则,此方法返回 0。
--创建一个 MultiPoint 实例,并使用 InstanceOf() 查看该实例是否为 GeometryCollection
DECLARE @g geometry;
SET @g = geometry::STGeomFromText('MULTIPOINT(0 0, 13.5 2, 7 19)', 0);
SELECT @g.InstanceOf('GEOMETRYCOLLECTION');
拓扑计算
计算交集
DECLARE @geom1 geometry;
DECLARE @geom2 geometry;
DECLARE @result geometry;
SELECT @geom1 = GeomCol1 FROM SpatialTable WHERE id = 1;
SELECT @geom2 = GeomCol1 FROM SpatialTable WHERE id = 2;
SELECT @result = @geom1.STIntersection(@geom2);
SELECT @result.STAsText();
计算是否包含
DECLARE @g geometry;
DECLARE @h geometry;
DECLARE @p geometry;
SET @g = geometry::STGeomFromText('POLYGON((0 0, 2 0, 2 2, 0 2, 0 0))', 0);
SET @h = geometry::STGeomFromText('POINT(1 1)', 0);
SET @p = geometry::STGeomFromText('POINT(5 5)', 0);
SELECT @g.STContains(@h);
SELECT @g.STContains(@p);
查询是否相交
DECLARE @g geometry;
DECLARE @h geometry;
DECLARE @l geometry;
DECLARE @l2 geometry;
DECLARE @p geometry;
DECLARE @p2 geometry;
SET @g = geometry::STGeomFromText('LINESTRING(0 2, 2 0)', 0);
SET @h = geometry::STGeomFromText('LINESTRING(0 0, 2 2)', 0);
SET @l = geometry::STGeomFromText('LINESTRING(0 0, 1 1)', 0);
SET @l2 = geometry::STGeomFromText('LINESTRING(0 0, 1 1.5)', 0);
SET @p = geometry::STGeomFromText('POLYGON((0 0, 2 0, 2 2, 0 2, 0 0))', 0);
SET @p2 = geometry::STGeomFromText('POLYGON((0 0, 1 0, 1 1, 0 1, 0 0))', 0);
SELECT @g.STCrosses(@h); --1
SELECT @g.STCrosses(@l); --0
SELECT @g.STCrosses(@l2); --1
SELECT @h.STCrosses(@p); --0
SELECT @h.STCrosses(@p2); --1
其他方法
DECLARE @g geometry;
DECLARE @h geometry;
SET @g = geometry::STGeomFromText('LINESTRING(0 2, 2 0, 4 2)', 0);
SET @h = geometry::STGeomFromText('POINT(1 1)', 0);
SELECT @g.STIntersects(@h); --1
计算差集
DECLARE @g geometry;
DECLARE @h geometry;
SET @g = geometry::STGeomFromText('POLYGON((0 0, 0 2, 2 2, 2 0, 0 0))', 0);
SET @h = geometry::STGeomFromText('POLYGON((1 1, 3 1, 3 3, 1 3, 1 1))', 0);
SELECT @g.STDifference(@h).ToString(); --POLYGON ((0 0, 2 0, 2 1, 1 1, 1 2, 0 2, 0 0))
SELECT @h.STDifference(@g).ToString(); --POLYGON ((2 1, 3 1, 3 3, 1 3, 1 2, 2 2, 2 1))
计算余集
DECLARE @g geometry;
DECLARE @h geometry;
SET @g = geometry::STGeomFromText('POLYGON((0 0, 0 2, 2 2, 2 0, 0 0))', 0);
SET @h = geometry::STGeomFromText('POLYGON((1 1, 3 1, 3 3, 1 3, 1 1))', 0);
SELECT @g.STSymDifference(@h).ToString(); --MULTIPOLYGON (((2 1, 3 1, 3 3, 1 3, 1 2, 2 2, 2 1)), ((0 0, 2 0, 2 1, 1 1, 1 2, 0 2, 0 0)))
SELECT @h.STSymDifference(@g).ToString(); --MULTIPOLYGON (((2 1, 3 1, 3 3, 1 3, 1 2, 2 2, 2 1)), ((0 0, 2 0, 2 1, 1 1, 1 2, 0 2, 0 0)))
计算并集
DECLARE @g geometry;
DECLARE @h geometry;
SET @g = geometry::STGeomFromText('POLYGON((0 0, 0 2, 2 2, 2 0, 0 0))', 0);
SET @h = geometry::STGeomFromText('POLYGON((1 1, 3 1, 3 3, 1 3, 1 1))', 0);
SELECT @g.STUnion(@h).ToString(); --POLYGON ((0 0, 2 0, 2 1, 3 1, 3 3, 1 3, 1 2, 0 2, 0 0))
计算二者是否相连
DECLARE @g geometry;
DECLARE @h geometry;
SET @g = geometry::STGeomFromText('LINESTRING(0 2, 2 0, 4 2)', 0);
SET @h = geometry::STGeomFromText('POINT(1 1)', 0);
SELECT @g.STDisjoint(@h);
计算最短距离
DECLARE @g geometry;
DECLARE @h geometry;
SET @g = geometry::STGeomFromText('POLYGON((0 0, 2 0, 2 2, 0 2, 0 0))', 0);
SET @h = geometry::STGeomFromText('POINT(10 10)', 0);
SELECT @g.STDistance(@h);
STEquals
如果一个 geometry 实例表示的点集
与另一个 geometry 实例表示的点集
相同,则返回 1。 否则,返回 0。
DECLARE @g geometry
DECLARE @h geometry;
SET @g = geometry::STGeomFromText('LINESTRING(0 2, 2 0, 4 2)', 0);
SET @h = geometry::STGeomFromText('MULTILINESTRING((4 2, 2 0), (0 2, 2 0))', 0);
SELECT @g.STEquals(@h); --1
是否有重叠
DECLARE @g geometry;
DECLARE @h geometry;
SET @g = geometry::STGeomFromText('POLYGON((0 0, 2 0, 2 2, 0 2, 0 0))', 0);
SET @h = geometry::STGeomFromText('POLYGON((1 1, 3 1, 3 3, 1 3, 1 1))', 0);
SELECT @g.STOverlaps(@h); --1
是否接触
DECLARE @g geometry;
DECLARE @h geometry;
SET @g = geometry::STGeomFromText('LINESTRING(0 2, 2 0, 4 2)', 0);
SET @h = geometry::STGeomFromText('POINT(1 1)', 0);
SELECT @g.STTouches(@h);
是否完全包含
DECLARE @g geometry;
DECLARE @h geometry;
SET @g = geometry::STGeomFromText('POLYGON((0 0, 2 0, 2 2, 0 2, 0 0))', 0);
SET @h = geometry::STGeomFromText('POLYGON((1 1, 3 1, 3 3, 1 3, 1 1))', 0);
SELECT @g.STWithin(@h);
集合操作
CollectionAggregate:从一组 geometry 类型创建一个 GeometryCollection 实例 。
ConvexHullAggregate:为一组给定的 geometry 对象返回一个凸包。
EnvelopeAggregate:为一组给定的 geometry 对象返回一个边框。
UnionAggregate:对一组几何图形对象执行联合操作。
其他功能
名称 | 功能 | 链接 |
---|---|---|
STBoundary | 计算边界 | 链接 |
STBuffer | 计算缓冲区 | 链接 |
STCentroid | 查询几何中心 | 链接 |
STConvexHull | 获得凸包 | 链接 |
STCurveToLine | 获得圆弧线段的多边形近似值 | 链接 |
STEndpoint | 获得终点 | 链接 |
STEnvelope | 获得最小轴对齐边界矩形 | 链接 |
STExteriorRing | 获得多边形 geometry 实例的外环 | 链接 |
STInteriorRingN | 获得Polygongeometry 实例的指定内环 | 链接 |
STNumCurves | 一维空间数据类型获得曲线数 | 链接 |
STNumGeometries | 获得构成 geometry 实例的几何图形的数目 | 链接 |
STNumInteriorRing | 获得Polygongeometry 实例的内环数 | 链接 |
STNumPoints | 获得点数的总和 | 链接 |
STRelate | 判断两实例是否相关 | 链接 |
ShortestLineTo | 计算实例之间的最短距离,返回包含两个点的 LineString 实例 | 链接 |
以上并非全部方法,部分方法未列出
参考资料
学习技术最好的文档就是【官方文档】,没有之一。
还有学习资料【Microsoft Learn】、【CSharp Learn】、【My Note】。
如果,你认为阅读这篇博客让你有些收获,不妨点击一下右下角的【推荐】按钮。
如果,你希望更容易地发现我的新博客,不妨点击一下【关注】。