ГИС находит точки (длинные латы), которые содержатся в полигоне, выраженном в виде набора длинных лат

StackOverflow https://stackoverflow.com/questions/788469

  •  16-09-2019
  •  | 
  •  

Вопрос

Я пытаюсь найти все элементы данных, которые имеют длину / lats, которые содержатся в полигоне, состоящем из массива длинных lats, может быть много точек.Я знаю, что вы можете делать подобные вещи с новыми геопространственными типами данных в 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))

Возвращает значение Float Как 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)

Конец


Далее я предполагаю, что существует табличная переменная пар Широта / Долгота и порядковый номер (указывающий порядок, в котором пары ШИРОТА / длина определяют многоугольник).Важно, чтобы первый пункт в этой таблице совпадал с последним пунктом в таблице.

Кроме того, у меня есть несколько переменных для минимальной и максимальной широты и долготы.Это эффективно создает ограничивающую рамку, так что я могу быстро удалять точки, НЕ входящие в прямоугольную область, ограничивающую многоугольник.

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-сервера.
  3. Выполните окончательную точную фильтрацию на C#.

Производительность, конечно, зависит от того, насколько хорошо вы сможете рассчитать начальные границы.Я бы сначала начал с простого ограничивающего прямоугольника и посмотрел, достаточна ли производительность.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top