我试图找到所有具有长/纬度的数据项,这些数据项由由长纬度数组组成的多边形包含,可能有很多点。我知道您可以使用 SQL 2008 中的新地理空间数据类型执行此类操作,但我使用的是 SQL 2005 和 C#。这最好在数据库端还是在 C# 中完成。

谢谢。

有帮助吗?

解决方案

我有SQL2000为此写了一些代码。它使用用于确定“角度”的方法,如果一个点位于一个多边形内。

首先,用户GetAngle定义的函数:

ALTER Function [dbo].[GetAngle](
@Ax Decimal(8,5), 
@Ay Decimal(8,5), 
@Bx Decimal(8,5), 
@By Decimal(8,5), 
@Cx Decimal(8,5), 
@Cy Decimal(8,5))

返回浮法 如 开始

Declare @dot_product Float
Declare @cross_product Float

Declare @BAx Decimal(8,5)
Declare @BAy Decimal(8,5)
Declare @BCx Decimal(8,5)
Declare @BCy Decimal(8,5)

--' Get the vectors' coordinates.
Set @BAx = Sign(@Ax - @Bx) * dbo.CalculateDistance(@Ax, @Ay, @Bx, @Ay)
Set @BAy = Sign(@Ay - @By) * dbo.CalculateDistance(@Ax, @Ay, @Ax, @By)
Set @BCx = Sign(@Cx - @Bx) * dbo.CalculateDistance(@Cx, @Cy, @Bx, @Cy)
Set @BCy = Sign(@Cy - @By) * dbo.CalculateDistance(@Cx, @Cy, @Cx, @By)

--' Calculate the dot product.
Set @dot_product = @BAx * @BCx + @BAy * @BCy

--' Calculate the Z coordinate of the cross product.
Set @cross_product = @BAx * @BCy - @BAy * @BCx

--' Calculate the angle.
return ATn2(@cross_product, @dot_product)

结束


接下来,我假定有纬度/经度对表变量和一个序列号(指示在其中的LAT / LONG对定义多边形的顺序)。重要的是,此表中的第一点是一样的,在表中的最后一个点。

另外,我有对最小和最大经纬度几个变量。这有效地产生了边界框,这样我可以很快的矩形区域包围的多边形内的点消除NOT。

Select  Address.AddressId
From    @Temp As A
        Inner Join @Temp As B
            On A.SequenceNumber = B.SequenceNumber - 1
        Inner Join Address
            On Address.XCoord Between @MinLongitude And @MaxLongitude
            And Address.YCoord Between @MinLatitude And @MaxLatitude
Group By Address.AddressId
Having Abs(Sum(dbo.GetAngle(A.Longitude, A.Latitude, Address.XCoord, Address.YCoord, B.Longitude, B.Latitude))) > 3.14

其他提示

如果在 T-SQL 中完成,这听起来像是令人头疼的事情(但这或多或少是一切?)。当然,这取决于多边形的复杂性和数据项的定位方式,但一般来说,最简单且效率较高的方法可能是在 C# 中进行一些初始计算,这会以非常粗略的方式限制数据项。所以像下面这样。

  1. 在 C# 中计算多边形的粗略边界。
  2. 从 SQL Server 获取这些边界内的所有内容。
  3. 用C#做最后的精确过滤。

当然,性能取决于您计算初始边界的能力。我首先从一个简单的边界矩形开始,看看性能是否足够。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top