Ich habe einen Code für SQL2000 geschrieben, um dies zu tun. Er verwendet die "Winkel"-Methode zur Bestimmung, ob ein Punkt innerhalb eines Polygons liegt.
Erstens, die benutzerdefinierte Funktion 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))
Rückgabe Float Als Begin
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)
Ende
Als Nächstes nehme ich an, dass es eine Tabellenvariable mit Breiten-/Längenpaaren und einer Sequenznummer gibt (die die Reihenfolge angibt, in der die LAT/LONG-Paare das Polygon definieren). Es ist wichtig, dass der erste Punkt in dieser Tabelle mit dem letzten Punkt in der Tabelle identisch ist.
Außerdem habe ich mehrere Variablen für den minimalen und maximalen Breitengrad und Längengrad. Auf diese Weise wird ein Begrenzungsrahmen erstellt, so dass ich Punkte, die NICHT innerhalb eines rechteckigen Bereichs liegen, der das Polygon begrenzt, schnell ausschließen kann.
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