GIS localizar pontos (longas lats) que estão contidos por um polígono expressa como uma coleção de longos lats

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

  •  16-09-2019
  •  | 
  •  

Pergunta

Eu estou tentando encontrar todos os itens de dados que têm long / lats que estão contidos por um polígono formado por uma série de longas lats poderia ser muitos pontos. Eu sei que você pode fazer este tipo de coisas com os novos tipos de dados geospacial no SQL 2008, mas eu estou usando SQL 2005 e C #. Será que isso é o melhor feito em no final DB ou em C #.

Graças.

Foi útil?

Solução

Eu tenho algum código escrito para SQL2000 para fazer isso. Ele usa o método 'ângulo' para determinar se um ponto está dentro de um polígono.

Em primeiro lugar, a função de usuário GetAngle definido:

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))

Retorna Float Como Comece

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)

Fim


Em seguida, assumir que existe uma variável de tabela de pares de latitude / longitude e um número de sequência (que indica a ordem em que os pares de latitude / longitude definir o polígono). É importante que o primeiro ponto nesta tabela é o mesmo que o último ponto na tabela.

Além disso, tenho várias variáveis ??para Min e Max Latitude e Longitude. Isso cria efetivamente uma caixa delimitadora para que eu possa eliminar rapidamente os pontos não dentro de uma região rectangular delimitadora do polígono.

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

Outras dicas

Parece algo que dá uma dor de cabeça se feito em T-SQL (que é mais ou menos tudo embora?). Claro que depende da complexidade dos polígonos e a forma como os itens de dados estão localizados, mas em geral a abordagem mais fácil e uma moderadamente eficiente poderia ser a de fazer alguns cálculos iniciais em C # que limita os itens de dados de uma maneira muito áspera. Portanto, algo como o seguinte.

  1. Calcular os limites ásperas do polígono em C #.
  2. Obter tudo dentro desses limites a partir do servidor SQL.
  3. Faça a filtragem precisos final em C #.

O desempenho do curso depende de quão bem você pode calcular os limites iniciais. Eu começaria com apenas um simples retângulo delimitador primeiro e ver se o desempenho é suficiente.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top