【问题标题】:Geometry error on one server but not the other with same data一台服务器上的几何错误,但另一台服务器上的数据相同
【发布时间】:2017-08-07 16:59:57
【问题描述】:

我有一个包含大约 400 行地理数据的表,我正在使用 STWithin 方法来确定一个点是否存在于这些行的边界内。

在我的测试服务器上它工作正常。但是,对于最新版本的数据集,查询在实时服务器上对这些数据行之一失败。如果我从查询中排除该行,则它会成功。

错误是:

消息 6522,第 16 级,状态 1,第 3 行

执行用户定义的过程中发生 .NET Framework 错误 例程或聚合“几何”:System.ArgumentException:24144: 此操作无法完成,因为实例无效。 使用 MakeValid 将实例转换为有效实例。请注意,MakeValid 可能会导致几何实例的点发生轻微偏移。

查询的简化版本是:

DECLARE @Point GEOMETRY = GEOMETRY::Point(416420, 345058, 0)

SELECT  *
FROM    PolygonData
WHERE   @Point.STWithin(GeoField) = 1

测试服务器是 SQL Server 2012 (11.0.2100.60),实时服务器是 SQL Server 2012 (11.0.6544.0)。

我不明白为什么相同的数据会在一台服务器上成功而在另一台服务器上失败?非常感谢任何帮助,谢谢。

【问题讨论】:

  • 你能提供“坏”实例的 WKT 吗?此外,代码异味是您使用几何数据类型(而不是地理)来存储地理数据。
  • 当然,我已经在这里gist.github.com/dannyshisler/66da21b345038d4238be92e925490aa5 发布了 WKT 数据,谢谢。数据是使用 SharpGIS 的 shape2sql.exe 工具从 Shapefile (.shp) 导入的,这就是数据采用其格式的原因。我还没有找到另一种将 .shp 数据导入 SQL Server 的方法。
  • 我知道为什么它不是一个有效的地理实例(地理假设坐标是纬度/经度,而这些不是)。但至于你的实际问题,当我将它加载到我的本地实例中时,我有一个奇怪的行为。如果我做了declare @g geometry = geometry::STGeomFromText(«your WKT», 0); select @g; 一切正常。但是,如果我尝试在 @g(如 STNumGeometries())上调用一个方法,它就会抱怨。打电话给MakeValid() 一切正常。我怀疑你有一个内环方向问题。也就是说,第一个多边形中有定义的“洞”……
  • ... 我认为其中一个孔的定义方向错误(例如,如果“父”多边形定义为逆时针方向,则为顺时针方向)。
  • 这很奇怪。我仍然不明白为什么它可以在一台服务器上运行而不是在另一台服务器上运行?无论如何,将MakeValid() 添加到我的查询中确实可以运行:SELECT * FROM PolygonData WHERE @Point.STWithin(GeoField.MakeValid()) = 1 感谢您的帮助。

标签: sql-server tsql sqlgeometry


【解决方案1】:

原来表中有无效数据。添加这个作为答案,同时也添加了一种方法来修复表中的数据。

update t
set g = g.MakeValid()
from dbo.yourTable as t
where t.g.STIsValid() = 0;

(将yourTableg 分别替换为实际表和列的名称)通过一次性操作更新坏数据,您不会产生在选择时调用MakeValid() 的开销(因为大概读取比写入更频繁)。您还可以为您执行的任何后续数据加载实施类似上述的方法。

【讨论】:

    猜你喜欢
    • 2013-12-10
    • 2020-04-04
    • 2013-08-24
    • 2013-10-24
    • 1970-01-01
    • 1970-01-01
    • 2010-12-30
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多