【问题标题】:TSQL Geography STGeomFromText Displaying Wrong ResultTSQL Geography STGeomFromText 显示错误的结果
【发布时间】:2014-08-06 16:23:35
【问题描述】:

我正在尝试编写一个代码来告诉我点是否在多边形内

DECLARE @Latitude varchar(20) = '41.694110'
DECLARE @Longitude varchar(20) = '44.833680'
DECLARE @g geography;
DECLARE @p geography;

DECLARE @PolygonString varchar(500) = 'POLYGON((41.711921 44.658505, 41.851703 44.773175, 41.763158 44.972302, 41.654421 44.843083, 41.711921 44.658505))'

SET @g = geography::STGeomFromText(@PolygonString, 4326);
SET @p = geography::Point(@Latitude, @Longitude, 4326)

SELECT @g.STIntersects(@p)

它总是返回 0。这是场景的可视化表示。

http://sbtutor.com/

知道我的代码有什么问题吗?

谢谢。

【问题讨论】:

  • 你的数据中有多边形吗?

标签: sql-server tsql geography


【解决方案1】:

mdisbio 的回答让我想到了参数的顺序,所以一旦我反转了每个参数的 long/lat 顺序以遵守左手规则,我不得不重新排序这些点,最后得出的结果是相交的。

DECLARE @Latitude varchar(20) = '41.694110'
DECLARE @Longitude varchar(20) = '44.833680'
DECLARE @g geography;
DECLARE @p geography;

DECLARE @PolygonString varchar(500) = 'POLYGON((44.658505 41.711921, 44.843083 41.654421, 44.972302 41.763158, 44.773175 41.851703, 44.658505 41.711921))'

SET @g = geography::STGeomFromText(@PolygonString, 4326);
SET @p = geography::Point(@Latitude, @Longitude, 4326)

SELECT @g.STIntersects(@p)
--1

所以对于Points,排序是纬度/经度,但似乎对于多边形,排序被解释为经度/纬度。记住这一点,这应该是轻而易举的事。

【讨论】:

  • 您能否详细说明“左手规则”,以便我更好地理解这一点? “逆时针”?或者是其他东西?我知道这些点必须是连续的......
  • 我的意思是顺时针逆时针。事实上,如果不应用此规则,地理对象(但不是几何对象)将无法创建。
  • 我尝试了完全相同的想法,几乎没有修改,我所做的是 SET @p = geography::Point(@Longitude, @Latitude, 4326) 但这没有任何意义。好吧,它起作用了,但没有合乎逻辑的解释为什么起作用:D
  • 如果你有 SSMS,你可以发出 SELECT @g UNION ALL SELECT @p 并获得你的多边形和点的可视化表示,以及它们是否相交...
【解决方案2】:

我不是地理空间类型方面的专家,但可以给你一些想法。 对于 WKT 字符串(用于制作多边形的字符串),对需要是 long/lat 而不是 lat/long。

也就是说,我仍然无法将您的多边形识别为有效的地理,因为我没有应用 Jaaz 稍后指出的逆时针规则。所以我使用了没有那么严格的几何类型,它工作正常。

使用几何作为多边形,POINT 也必须是几何。在这种情况下,geometry::POINT() 需要 X,Y 坐标 (lng/lat),而不是与 geography 类型一起使用的 lat/lng 对。

所以,这将在相交处产生 true:

DECLARE @Latitude float = 41.694110
DECLARE @Longitude float = 44.833680
DECLARE @g geometry = geometry::Point(@Longitude, @Latitude, 4326)
DECLARE @p geometry = geometry::STPolyFromText('POLYGON((44.658505 41.711921, 44.773175 41.851703, 44.972302 41.763158, 44.843083 41.654421, 44.658505 41.711921))', 4326);
SELECT @g.STIntersects(@p)

【讨论】:

  • Jaaz 更正它保持地理类型,所以这是正确的答案。
  • 你说得对,我虽然纬度是 X,经度是 Y,但我终于发现经度是 X,纬度是 Y。我已经将代码从地理更改为几何。现在一切都说得通了。谢谢!!!
  • 为了清楚起见,geography::POINT() 的参数是 LAT、LONG、SRID。但是geometry::POINT() 的参数是 X,Y,SRID。 x,y 平面可以是任何笛卡尔平面,而不仅仅是地图投影。但是如果您使用的是地图投影,那么它对应于 LONG,LAT(使用地理时的顺序相反)。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-10-31
  • 2017-08-14
  • 1970-01-01
  • 1970-01-01
  • 2020-04-25
  • 1970-01-01
相关资源
最近更新 更多