2009-04-25 3 views
2

J'essaie de trouver tous les éléments de données qui ont long/lats qui sont contenues par un polygone composé d'un tableau de longue lats pourrait être beaucoup de points. Je sais que vous pouvez faire ce genre de choses avec les nouveaux types de données geospacial dans SQL 2008 mais j'utilise SQL 2005 et C#. Est-ce que cela serait mieux fait à la fin de la DB ou en C#.SIG trouver des points (longs lats) qui sont contenues par un polygone exprimé comme une collection de longs lats

Merci.

Répondre

1

J'ai du code écrit pour que SQL2000 le fasse. Il utilise la méthode «angle» pour déterminer si un point se trouve dans un polygone.

Tout d'abord, la fonction définie par l'utilisateur 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)) 

Retours Float Comme 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) 

Fin


Ensuite, je suppose qu'il ya une variable de latitude de table/Longitude et un numéro de séquence (indica l'ordre dans lequel les paires LAT/LONG définissent le polygone). Il est important que le premier point de cette table soit le même que le dernier point du tableau.

De plus, j'ai plusieurs variables pour la longitude min et max & Longitude. Cela crée effectivement une boîte englobante de sorte que je puisse rapidement éliminer les points qui NE se trouvent PAS dans une région rectangulaire délimitant le polygone.

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 
+0

je suis tombé sur ce sujet et je suis intéressé, mais où est 'dbo.CalculateDistance' défini? – Lloyd

1

Cela ressemble à quelque chose qui donne mal à la tête si cela est fait en T-SQL (qui est plus ou moins tout si?). Bien sûr, cela dépend de la complexité des polygones et de la façon dont les éléments de données sont localisés, mais en général l'approche la plus simple et modérément efficace pourrait être de faire quelques calculs initiaux en C# qui limitent les données de manière très approximative. Donc quelque chose comme le suivant.

  1. Calculez les limites approximatives du polygone en C#.
  2. Récupérez tout ce qui se trouve à l'intérieur de ces limites à partir du serveur SQL.
  3. Faire le filtrage final précis en C#.

La performance dépend bien sûr de la façon dont vous pouvez calculer les limites initiales. Je commencerais par un simple rectangle de délimitation et je verrais si la performance est suffisante.

+0

+1 pour me sauver taper la même réponse :) –

Questions connexes