【问题标题】:Why is this SQL Server geometry query returning no geometry?为什么此 SQL Server 几何查询不返回几何?
【发布时间】:2021-12-24 03:26:03
【问题描述】:

我正在 SQL Server 2017 中查询几何线上最接近给定点的点。以下内容适用于某些数据,而不适用于其他数据。我无法理解这种不一致。

declare @line geometry = 'LINESTRING(0 0, 10 10)' 
declare @p1 geometry = 'POINT(3 2)'
declare @p2 geometry = 'POINT(3 1)'

select @p1.STBuffer(@p1.STDistance(@line)).STIntersection(@line).ToString()
select @p2.STBuffer(@p2.STDistance(@line)).STIntersection(@line).ToString()

p1 的结果是POINT (2.500000 2.499999),正如预期的那样。 p2 的结果是GEOMETRYCOLLECTION EMPTY,我想知道为什么。这些点并没有什么不同。

【问题讨论】:

  • 我不是几何人,但我发现有趣的是 (3 0.9)(3 1.1)(3 1.000000000001) 也会产生结果,但 (3 1.0000000000001)(1 3) 失败。一定有一些关于 1(或接近 1)的东西?
  • LINESTRING 扩展到30 30,您将再次获得结果。我不提供这个作为解释。 :P

标签: sql-server spatial


【解决方案1】:

空间类型坐标和距离计算的结果都是浮点数,不是精确的实数。因此,在进行比较时,您必须在浮点精度的限制下测试舍入和截断差异的一些容差。

因此,如果您以较小的容差进行缓冲,则效果很好:

declare @line geometry = 'LINESTRING(0 0, 10 10)' 
declare @p1 geometry = 'POINT(3 2)'
declare @p2 geometry = 'POINT(3 1)'

select @p1.STBuffer(1.0000000001*@p1.STDistance(@line)).STIntersection(@line).ToString()
select @p2.STBuffer(1.0000000001*@p2.STDistance(@line)).STIntersection(@line).ToString()

这与

基本相同
select 'true' where 2 = power(sqrt(2),2)

几何点的标准距离是sqrt((x1-x2)^2+(y1-x2)^2)

【讨论】:

  • 但这似乎仍然是一个晦涩难懂的部落知识,也许方法应该解释这一点并且正确?必须将每个输入值乘以 1.0000000001 很尴尬,如果这实际上将一个值(如 0.9999)推入一个抵消容差并再次失败的值怎么办?
  • 这只是普通浮点计算和比较的二维模拟,可能会很痛苦。
  • 这是一个特别清晰简洁的答案。谢谢大卫。
猜你喜欢
  • 2014-01-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-10-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-01-13
相关资源
最近更新 更多