SQL WKT 可以很好地绘制几何图形,但不能绘制地理数据类型

Posted

技术标签:

【中文标题】SQL WKT 可以很好地绘制几何图形,但不能绘制地理数据类型【英文标题】:SQL WKT draws well with geometry, but not with geography data type 【发布时间】:2018-07-24 08:23:26 【问题描述】:

我有一段代码

DECLARE @g geometry;
DECLARE @borders geography;   
SET @g = geometry::STGeomFromText('SOME WKT', 0); 
SET @borders = GEOGRAPHY::STGeomFromText(@g.MakeValid().STAsText(),4326)
SELECT @g;
SELECT @borders;

由于太长贴在这里,WKT可以点这个链接:https://justpaste.it/6qw0a

谁能给我解释一下,为什么当我将它绘制为几何图形时它显示得很好,但是当我尝试将它绘制为地理时,它显示的是整个世界而不是一小群岛屿。

截图如下:

【问题讨论】:

【参考方案1】:

您的戒指方向有问题。对于地理形状,在边界上指定点的顺序很重要。也就是说,想象一个有角 A、B、C 和 D 的正方形。(A、B、C、D、A)与(A、D、C、B、A)不同。其中一个指定了您的想法,而另一个定义了世界其他地方,其中有一个方形孔!但不要难过,这是一个很常见的“陷阱”!在地理数据中。

您的数据在定义点的方式上不一致。也就是说,有些将岛屿边界指定为顺时针方向,而另一些则指定为逆时针方向。一切都没有丢失。使用您的 WKT,我相信我能够恢复所需的形状。

DECLARE @wkt varchar(max) = '«your wkt here»';
DECLARE @borders geography;   
SET @borders = GEOGRAPHY::STGeomFromText(@wkt, 4326);

select geography::UnionAggregate(b2.g)
from Util.dbo.Numbers as n
cross apply (
    select @borders.STGeometryN(n.n) as g1,
        @borders.STGeometryN(n.n).ReorientObject() as g2
) as b
cross apply (
    select case when g1.EnvelopeAngle() > 90 then g2 else g1 end as g
) as b2
where n.n <= @borders.STNumGeometries();

作为解释,我通过索引从几何集合中挑选出每个单独的几何,指定它,并通过交叉应用重新定向版本,然后使用启发式“如果包络角地理大于 90°,选择(可能是)正确的可能是错误的方向。从那里,我将它们全部放入一个 UnionAggregate 中,以将它们全部塞回一个地理实例中。

最后,如果不是很明显,Numbers 只是一个整数表,我在诸如此类的情况下使用它。

【讨论】:

您能否再解释一下 Util.Numbers 表?这张表中有哪些数字,在什么范围内? 它们只是从1开始的计数。至于多少,我通常以10,000左右为种子。如果我觉得这还不够,我会添加更多。我使用这个 (itprotoday.com/microsoft-sql-server/…) 的变体来填充表格。【参考方案2】:
DECLARE @geom GEOMETRY = 'POLYGON ((0 0, 10 0, 10 10, 0 10, 0 0))';
DECLARE @geog GEOGRAPHY = @geom.MakeValid().STUnion(@geom.STStartPoint()).STAsText()

Thistopic 已经回答了我的问题

【讨论】:

以上是关于SQL WKT 可以很好地绘制几何图形,但不能绘制地理数据类型的主要内容,如果未能解决你的问题,请参考以下文章

(lat, lon) WKT 坐标不能用 st_transform 很好地重新投影

基于openlayers的wkt绘制展示功能

基于openlayers的wkt绘制展示功能

使用 PyGraphviz 绘制有关图形\节点的更多信息

在图像右上角绘制文本

绘制聚类热图(带树状图)/Python