Puntos de encontrar (SIG largos dorsales) que están incluidos en un polígono expresan como una colección de dorsales largas

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

  •  16-09-2019
  •  | 
  •  

Pregunta

Estoy tratando de encontrar todos los elementos de datos que tienen largas / dorsales que están incluidos en un polígono formado por una serie de dorsales largas podría haber muchos puntos. Sé que usted puede hacer este tipo de cosas con los nuevos tipos de datos geoespaciales en SQL 2008, pero estoy usando SQL 2005 y C #. ¿Esto se realiza mejor en en el extremo DB o en C #.

Gracias.

¿Fue útil?

Solución

Tengo algo de código escrito para SQL2000 para hacer esto. Se utiliza el método de 'ángulo' para determinar si un punto se encuentra dentro de un polígono.

En primer lugar, la función GetAngle definido por el usuario:

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

Las devoluciones Flotador Como Comience

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)

Fin


Siguiente I suponga que hay una variable de tabla de pares de latitud / longitud y un número de secuencia (que indica el orden en que la LAT / LONG pares definen el polígono). Es importante que el primer punto de esta tabla es el mismo que el último punto de la tabla.

Además, tengo varias variables para Min y Max latitud y longitud. Esto crea un cuadro delimitador para que pueda eliminar rápidamente los puntos no dentro de una región rectangular que delimita el 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

Otros consejos

Suena como algo que da un dolor de cabeza si se hace de T-SQL (que es más o menos todo lo que sin embargo?). Por supuesto, depende de la complejidad de los polígonos y la forma en que los elementos de datos se encuentran pero en general el método más sencillo y una moderadamente eficaz podría ser la de hacer algunos cálculos iniciales en C # que limita los elementos de datos de una manera muy aproximada. Así que algo como lo siguiente.

  1. Calcular los límites aproximados del polígono en C #.
  2. Obtener todo dentro de estos límites desde el servidor SQL.
  3. Haga el filtrado de precisión final en C #.

El rendimiento por supuesto depende de qué tan bien puede calcular los límites iniciales. Me gustaría empezar con un simple rectángulo delimitador primero y ver si el rendimiento es suficiente.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top