2010-02-17 4 views
1

J'ai un ensemble d'objets ligne et polygone (type SqlGeometry) et un objet point (type SqlGeometry). Comment pouvons-nous trouver le point le plus proche sur chaque ligne de l'objet ponctuel donné? Y a-t-il une API pour faire cette opération?comment obtenir le point le plus proche sur un objet SqlGeometry à partir d'un autre objet SqlGeometry?

+0

BTW, cette question est sur API C#, mais la réponse acceptée utilise SQL Server. Très confus à tout lecteur qui cherche des questions et réponses similaires. Suggestion: obtenez la question/tags directement. – mloskot

Répondre

3

Je ne suis pas sûr si cela est possible directement dans SQL Server 2008:

http://social.msdn.microsoft.com/Forums/en/sqlspatial/thread/cb094fb8-07ba-4219-8d3d-572874c271b5

La solution proposée dans ce thread est:

declare @g geometry = 'LINESTRING(0 0, 10 10)' 
declare @h geometry = 'POINT(0 10)' 

select @h.STBuffer(@h.STDistance(@g)).STIntersection(@g).ToString() 

Sinon, vous auriez à écrire un script pour lire la géométrie de votre base de données et utiliser des bibliothèques spatiales séparées.

+0

pour l'objet de géographie, il était nécessaire d'ajouter un tampon supplémentaire de 0,1 mètre et prendre le premier point du résultat. Sinon, il produisait une collection de géométrie vide. @ h.STBuffer (@ h.STDistance (@g) + 0.1) .SInterection (@g) .STFirstPoint(). ToString() – malay

2

Si vous êtes réellement intéressé par la recherche du point le plus proche sur la ligne (autrement dit un nœud), vous pouvez transformer chaque ligne en un ensemble de points ayant la même ligne. Puis interrogez le plus proche et calculez la distance.

Si au contraire, vous essayez de calco la distance d'un point à la plus proche ligne - STDistance http://msdn.microsoft.com/en-us/library/bb933808.aspx Je suppose que le problème que les autres adresses de réponse est ce qu'il faut mettre dans votre clause where mais vous pouvez utiliser STDistance pour spécifier un distance au-dessus que vous ne vous inquiétez pas, comme

où pointGeom.stdistance (lineGeom) < « distance que vous aimez »

6

Voici un échantillon présentant des solutions possibles en utilisant SqlGeometry et C#, pas SQL Server est requise :

using System; 
using Microsoft.SqlServer.Types; 
namespace MySqlGeometryTest 
{ 
    class ReportNearestPointTest 
    { 
     static void ReportNearestPoint(string wktPoint, string wktGeom) 
     { 
      SqlGeometry point = SqlGeometry.Parse(wktPoint); 
      SqlGeometry geom = SqlGeometry.Parse(wktGeom); 
      double distance = point.STDistance(geom).Value; 
      SqlGeometry pointBuffer = point.STBuffer(distance); 
      SqlGeometry pointResult = pointBuffer.STIntersection(geom); 
      string wktResult = new string(pointResult.STAsText().Value); 
      Console.WriteLine(wktResult); 
     } 

     static void Main(string[] args) 
     { 
      ReportNearestPoint("POINT(10 10)", "MULTIPOINT (80 70, 20 20, 200 170, 140 120)"); 
      ReportNearestPoint("POINT(110 200)", "LINESTRING (90 80, 160 150, 300 150, 340 150, 340 240)"); 
      ReportNearestPoint("POINT(0 0)", "POLYGON((10 20, 10 10, 20 10, 20 20, 10 20))"); 
      ReportNearestPoint("POINT(70 170)", "POLYGON ((110 230, 80 160, 20 160, 20 20, 200 20, 200 160, 140 160, 110 230))"); 
     } 
    } 
} 

La sortie du programme:

POINT (20 20) 
POINT (160 150) 
POINT (10 10) 
POINT (70 160) 
+0

c'est la même chose que la réponse de geographika mais c'est le code C# – malay

+1

Oui, en effet, et je La réponse de geographika a bien sûr pris fin, mais a également décidé de fournir cette variante. – mloskot

Questions connexes