如何反转 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 【问题描述】:在varchar
列verticies
中,我存储了这个 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 中的环方向的主要内容,如果未能解决你的问题,请参考以下文章