Édité:
Je veux illustrer ma question. Supposons que vous soyez au "Point A" et que vous vouliez aller au "Point B". Ces points ne seraient pas dans la table "at_2po_4pgr" car les nœuds source / cible ne sont pas. Ensuite, je rechercherais le nœud le plus proche pour les points A et B (points verts). Après cela, je pourrais effectuer un appel shortest_path en utilisant des identifiants de points verts et j'obtiendrais un chemin "orange". Mais pour obtenir le coût réel du trajet (distance) dans le premier cas, il faudrait soustraire "offsetA" et dans le second cas ajouter de "offset B". Pour calculer la distance entre les points rouges et les points verts, j'exécute la requête suivante:
SELECT * FROM st_distance(
ST_GeomFromText('POINT(-3.6963314 42.3498066)',4326),
ST_GeomFromText('POINT(-3.6954276 42.3479634)',4326))
.
Comment puis-je savoir quand ajouter ou soustraire le décalage?
Désolé pour mon anglais!
Réponses:
Je ne pense pas que vous puissiez compter sur le sommet le plus proche. Imaginez que la source et la cible soient situées sur le même bord près du même sommet.
Vous préférez en considérer trois! différents cas:
la source
Vous pouvez trouver une telle fonction ici: https://github.com/pgRouting/pgrouting-contrib/blob/master/wrapper/routing_core_smart.sql#L69
Il recherche le lien le plus proche dans le réseau, ce qui donne généralement un meilleur résultat. Si vous utilisez Shooting Star, vous pouvez alors commencer le routage depuis / vers ce lien. Pour A * ou Dijkstra, vous sélectionnez soit le point de début ou de fin du lien, soit vous créez un nœud "virtuel" en divisant le lien en deux.
la source
Je vais expliquer la solution que j'ai trouvée (peut-être pas la meilleure).
Selon l'image du post, supposons que nous sommes au point A et que nous allons aller au point B . Comme je l'ai expliqué ci-dessus, ces points ne sont pas des sommets (source / cibles dans le tableau généré avec l'outil osm2po).
Pour cette raison, nous devons connaître la direction de marche / conduite. Si nous passons du sommet le plus proche au point A (point vert) par un chemin orange, nous devons soustraire le décalage entre le point A et le point vert (sommet le plus proche). Mais si nous devions traverser la rue Calle Almirante Bonifaz , alors nous devrions ajouter le décalage à la longueur de ce bord (du point vert à l'intersection entre la rue Almirante Bonifaz et la rue San Juan ).
J'exécute la requête suivante pour obtenir le chemin le plus court (vous avez besoin de l'extension pgRouting expliquée ici pgRouting - installation et exigences ici installation et exigences ):
Il en résulte un ensemble d'arêtes qui représente l'itinéraire complet. Par exemple, une sortie possible pour cette requête peut être:
Où le champ gid ( id dans la table générée par osm2po) représente l'identifiant de bord. Eh bien, nous devons vérifier les décalages au début et à la fin (points A / B).
Si nous vérifions le décalage de départ, il faut vérifier si le premier bord de l'ensemble des arêtes obtenues dans la requête ci - dessus est le même au plus proche chemin vers le point A . S'ils correspondent, nous soustraireons l'offset. S'ils ne correspondent pas, nous ajouterons le décalage. Pour obtenir le lien le plus proche d'un point, j'exécute la requête suivante:
Vous devez adapter cette fonction pour qu'elle renvoie le bord le plus proche. Vous devez d'abord modifier le type de point de liaison (ajouter le champ lien le plus proche ):
Vous devez également modifier le find_node_by_nearest_link_within_distance . Ajoutez simplement la dernière ligne (je ne montre qu'un extrait de la fonction):
Ensuite, vous devez savoir quelle est la distance entre le point ( point A / point B ) et l'arête la plus proche (décalage). À cet effet, je lance cette requête:
Où geom est le the_geom champ dans osm2po table générée.
À ce stade, nous aurions le décalage à ajouter ou à soustraire.
Enfin, vous devrez connaître la longueur de l'arête pour appliquer la valeur obtenue dans la requête ci-dessus et ajuster le réel (si vous travaillez avec le type de géométrie, vous devrez normaliser en mètres la valeur obtenue. Il suffit de multiplier 111000 par la longueur obtenue en la requête):
Si nous vérifions le décalage de fin, nous devons vérifier si le dernier chemin de l'ensemble de chemins obtenu dans la requête ci-dessus est le même que le chemin le plus proche du point de fin ( point B ) et nous ajouterons / soustraireons à de la même manière que précédemment.
Excuse mon anglais.
la source
En pgrouting, pgr_trsp - Turn Restriction Shortest Path (TRSP) fait exactement ce que vous recherchez.
Au lieu de spécifier les nœuds source et cible, vous pouvez spécifier les bords source et cible, ainsi que la fraction le long du bord où se trouvent votre origine et votre destination.
(Vous pouvez utiliser ST_Line_Locate_Point pour obtenir cette fraction de votre géométrie de point, en supposant que vous connaissez l'arête la plus proche.)
Voir http://docs.pgrouting.org/2.0/en/src/trsp/doc/index.html#trsp
la source