Puntos de encontrar (SIG largos dorsales) que están incluidos en un polígono expresan como una colección de dorsales largas
-
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.
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.
- Calcular los límites aproximados del polígono en C #.
- Obtener todo dentro de estos límites desde el servidor SQL.
- 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.