У меня есть код, написанный для 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))
Возвращает 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 определяют многоугольник). Важно, чтобы первая точка в этой таблице совпадала с последней точкой в таблице.
Кроме того, у меня есть несколько переменных для минимальной и максимальной широты и долготы. Это эффективно создает ограничивающий прямоугольник, так что я могу быстро устранить точки НЕ в прямоугольной области, ограничивающей многоугольник.
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