我正在尝试查找所有数据项,这些数据项包含由长拉数组构成的多边形所包含的长/拉数可能是多个点。我知道你可以在SQL 2008中使用新的geospacial数据类型来做这种事情,但我使用的是SQL 2005和C#。这最好是在DB端还是在C#中完成。
感谢。
答案 0 :(得分:1)
如果在T-SQL中完成,这听起来像是令人头痛的事情(尽管这或多或少都是如此?)。当然,这取决于多边形的复杂性和数据项的定位方式,但通常最简单和适度有效的方法可能是在C#中进行一些初始计算,这会以非常粗略的方式限制数据项。如下所示。
当然,性能取决于您计算初始边界的程度。我首先从一个简单的边界矩形开始,看看性能是否足够。
答案 1 :(得分:1)
我为SQL2000编写了一些代码来执行此操作。它使用'angle'方法确定一个点是否位于多边形内。
首先,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))
返回Float 如 开始
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对定义多边形的顺序)。重要的是,此表中的第一个点与表中的最后一个点相同。
另外,我有几个变量用于Min和Max Latitude&经度。这有效地创建了一个边界框,这样我就可以快速消除不在多边形边界区域内的点。
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