如何反转 JSON 多边形顺序以调整 SQL Server 中的环方向

Posted

技术标签:

【中文标题】如何反转 JSON 多边形顺序以调整 SQL Server 中的环方向【英文标题】:How to reverse a JSON polygon order to adjust for ring orientation in SQL Server 【发布时间】:2017-09-06 03:32:18 【问题描述】:

varcharverticies 中,我存储了这个 JSON:

["lng":-82.82312393275788,"lat":27.982508364801642,
 "lng":-82.8065586098819,"lat":27.984479050536944,
 "lng":-82.808017731586,"lat":27.9704560800863,
 "lng":-82.82166481105378,"lat":27.975004270258353,
 "lng":-82.8230381020694,"lat":27.980537643052056,
 "lng":-82.82312393275788,"lat":27.982508364801642]

这是保存为来自 Google 地图多边形的字符串。我的意图是将其保存为 geography 数据类型,并将其存储到 [geo] 列中。

我的问题是当我尝试使用时:

geography::STGeomFromText('POLYGON(' + replace(replace(replace(replace(replace(vertices,'"lng":',''),',"lat":',' '),'[','('),']',')'),'','') + ')', 4326)

我收到地理错误:

24205:指定的输入不代表有效的地理实例,因为它超出了单个半球。每个地理实例必须适合单个半球。此错误的一个常见原因是多边形的环方向错误。要创建大于半球的地理实例,请升级 SQL Server 版本并将数据库兼容级别更改为至少 110。

查看其他堆栈溢出答案,我被告知这是一个环方向问题,我需要反转 Json。据我了解,第一个点和最后一个点是起点/终点,它们很好,我需要颠倒所有其他点的顺序。

我的问题:有没有办法使用 SQL Server 中的函数来做到这一点?

【问题讨论】:

您使用的是哪个版本的 SQL Server? SQL Server 2016 SQL Server 2016 (IIRC)SQL 2012 中的“超过一个半球”错误消失了。JSON 仍然不能代表您感兴趣的事物(即很可能整个世界都有事物大小的洞),但这可以通过调用 .ReorientObject() 方法调用来修复。但回到根本问题,我认为您使用的是 SQL 2008(或在其兼容模式设置为此类的数据库中)。 好的。让我仔细检查一下版本。但是我应该将.ReorientObject() 放在geography::STGeomFromText() 调用的末尾吗? 【参考方案1】:

如果您使用的是 SQL Server 2014+ 和几何类型;您的代码应该可以完美运行:

declare @g geometry, @json nvarchar(400) = '["lng":-82.82312393275788,"lat":27.982508364801642,
 "lng":-82.8065586098819,"lat":27.984479050536944,
 "lng":-82.808017731586,"lat":27.9704560800863,
 "lng":-82.82166481105378,"lat":27.975004270258353,
 "lng":-82.8230381020694,"lat":27.980537643052056,
 "lng":-82.82312393275788,"lat":27.982508364801642]';

 set @g = geometry::STPolyFromText('POLYGON(' + replace(replace(replace(replace(replace(@json,'"lng":',''),',"lat":',' '),'[','('),']',')'),'','') + ')', 4326);  
SELECT @g.ToString(); 

[SQL Fiddle Demo]


但如果您的问题是关于创建标量函数,代码可以是这样的:

create function dbo.GetPolygon 
(
    @inputJson nvarchar(max),
    @sid int
)
returns geometry
as
begin
    declare @g geometry, @json nvarchar(max) = @inputJson;
    
    set @g = geometry::STPolyFromText('POLYGON(' + replace(replace(replace(replace(replace(@json,'"lng":',''),',"lat":',' '),'[','('),']',')'),'','') + ')', @sid);  

    return @g;
end
go

然后像这样使用它:

select dbo.GetPolygon(@json, 4326).ToString();

但是如果您使用的是地理类型:您不能简单地绘制多边形,它还应该涵盖其他一些条件:

注意:地理类型比几何类型更严格一些。它不能跨越不同的半球并且外环必须逆时针绘制[1]

GEOGRAPHY 用于陆地空间数据(即地球弯曲表面上的数据)[2]

更多地理信息请查看:What are the pros and cons of PostGIS geography and geometry types?

SELECT @g.ToString(), @g.STIsValid(); 
-- To test that geography is valid

顺便说一句;此代码也可以正常工作并且有效:[SQL Fiddle Demo]

【讨论】:

非常感谢,但我需要地理,而不是几何。谢谢! 好的。这里的问题是我无法区分你所说的和我所说的。这确实是精神错乱的定义。为什么我的会导致错误,而你的不会。我没有留下任何东西。顺便说一句,SQL Server 2016。谢谢。 好的!,我很快就会在本地 SQL Server 2016 中检查它 -HTH ;)。

以上是关于如何反转 JSON 多边形顺序以调整 SQL Server 中的环方向的主要内容,如果未能解决你的问题,请参考以下文章

如何反转 SQL Server 中的 OPENJSON() 函数?

具有堆栈结构的 JSON 反序列化反转顺序 [重复]

如何反转TreeView的顺序?

如何自动缩放mapView以显示覆盖

反转SQLite中结果集的顺序

如何反转Daru :: DataFrame的行?