utiliser STDistance dans le server SQL pour find le path le plus court dans le graphique

J'ai une table qui contient des informations sur les arêtes du graphe sous forme de geometry linessortingng de geometry linessortingng . Le résultat spatial de la requête select * from edge ressemble à ceci entrez la description de l'image ici CHAQUE linessortingng est toujours créée à partir de deux geometry points avec une instruction insert comme:

 INSERT INTO edge VALUES( geometry::Parse('LINESTRING(1 1 ,1 2)')) 

Afin de find le path le plus court entre deux points j'ai implémenté l'algorithm de Dijkstra selon Dijkstra en c # , cependant j'ai découvert la fonction STDistance () qui est de faire la même chose en exécutant une requête simple. Quelqu'un pourrait-il me donner un indice comment pourrais-je utiliser STDistance avec des objects créés comme je l'ai décrit? Chaque exemple que je trouve utilise des linessortingngs créées à partir de 3 points.

J'ai de la difficulté à utiliser l'exemple dans la situation que j'ai linessortingngs dire 3 linessortingngs comme ci-dessous:

 INSERT INTO edge VALUES( geometry::Parse('LINESTRING(1 1 ,1 2)')) INSERT INTO edge VALUES( geometry::Parse('LINESTRING(1 2 ,1 3)')) INSERT INTO edge VALUES( geometry::Parse('LINESTRING(1 3 ,1 4)')) 

et find le path le plus court de 1 1 à 1 4

Edit: J'ai réussi à combiner toutes les lignes en une forme en:

 SELECT geometry::UnionAggregate(linessortingng) FROM edge 

je reçois la forme:

Maintenant, j'utilise STDistance comme suit:

 SELECT (geometry::UnionAggregate(linessortingng)).STDistance(geometry::STGeomFromText('POINT(0 0)', 0)) FROM edge 

Cependant la valeur de return est sur la distance entre le point (0,0) et la forme présentée, quand mon intention est de countr la longueur des bords d'un point à l'autre, des indices?

Code Kata . Comme d'autres l'ont dit dans les commentaires, STDistance vous donnera la distance de ligne droite minimale entre deux objects de geometry, pas un path à travers un graphique. L'implémentation de Dijkstra dans Sql me dépasse, mais la méthode de la force brute est acceptable pour un petit nombre de nœuds tel que vous l'avez démontré. Ce code calcule tous les paths dans le graphique de A à B, puis sélectionne le plus court.

S'il vous plaît noter que ceci est seulement une preuve que cela peut être fait, pas une recommandation que cela devrait être fait. Votre code existant dans c # est probablement plus simple et plus rapide.

Merci de m'avoir donné l'opportunité d'apprendre les fonctions de geometry dans le server sql.

 -- Declare and set parameters. DECLARE @start geometry, @end geometry SET @start = geometry::STGeomFromText('POINT(-1 1)', 0); SET @end = geometry::STGeomFromText('POINT(1 3)', 0); -- Caching of ST function results and for reversibility. DECLARE @segments TABLE ( edge geometry, start_point geometry, end_point geometry, [weight] float ) INSERT @segments ( edge, start_point, end_point, [weight]) SELECT e, e.STStartPoint(), e.STEndPoint(), e.STLength() FROM edge UNION ALL -- Can traverse edges both ways unless we're in a directed graph? SELECT e, e.STEndPoint(), e.STStartPoint(), e.STLength() FROM edge -- We need to know number of edges for some bookkeeping later. DECLARE @total_edges INT SELECT @total_edges = COUNT(*) FROM edge; -- Meat of the procedure. Find all sensible paths from @start to @end allowed by the graph, using a recursive common table expression. WITH cte (path, start_point, end_point, [weight], segments_traversed) AS ( SELECT edge AS path, start_point, end_point, [weight] , 1 AS segments_traversed FROM @segments WHERE @start.STEquals(start_point) = 1 UNION ALL SELECT c.path.STUnion(s.edge) AS PATH, s.start_point, s.end_point, s.[weight] + c.[weight] AS weight, c.segments_traversed + 1 AS segments_traversed FROM cte c INNER JOIN @segments s ON -- next edge must start where this one ended. s.start_point.STEquals(c.end_point) = 1 AND -- terminate paths that hit the endpoint. c.start_point.STEquals(@end) = 0 AND -- if we traveled more than the number of edges there's surely a better path that doesn't loop! -- also acts as a guarantee of termination. c.segments_traversed < @total_edges ) SELECT TOP 1 path FROM cte c WHERE -- Ressortingct to paths ending at end point. c.end_point.STEquals(@end) = 1 ORDER BY weight ASC