Comment ajouter des décalages à l'itinéraire?

13

Édité:

échantillon

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!

Iñigo
la source
1
Bienvenue sur gis.stackexchange. Il s'agit d'un site de questions / réponses où chaque fil doit contenir exactement une question et ses réponses. Veuillez ouvrir un fil distinct pour la question # 3. # 2 est répondu dans gis.stackexchange.com/questions/33471/…
underdark
1
J'ai le même problème. avez-vous trouvé une solution? Merci beaucoup
Robert
1
Veuillez poster votre solution dans la section des réponses. Ensuite, il peut être voté.
underdark

Réponses:

2

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:

  1. un sommet est le point le plus proche.
  2. un nœud de forme du bord est le bon
  3. la ligne de bord elle-même est plus proche. (orthogonal)
Carsten
la source
Désolé mais ce n'est pas la bonne réponse. pgr_trsp - Le plus court chemin de restriction de virage (TRSP) s'est décalé comme indiqué pour la réponse @amball.
Juan Carlos Oropeza
7

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.

dkastl
la source
1

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 ):

SELECT gid, cost, st_astext(the_geom) as the_geom FROM dijkstra_sp_delta('xx_2po_4pgr', source_vertex, target_vertex, 0.1);

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:

sortie possible

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:

SELECT * FROM find_node_by_nearest_link_within_distance(point, 0.1, 'xx_2po_4pgr') as id;

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 ):

CREATE TYPE link_point AS
   (id integer,
    name character varying,
    nearest_link integer);
ALTER TYPE link_point
  OWNER TO postgres;

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):

-- Searching for a nearest link

    FOR row in EXECUTE 'select id from find_nearest_link_within_distance('''||point||''', '||distance||', '''||tbl||''') as id'
    LOOP
    END LOOP;
    IF row.id is null THEN
        res.id = -1;
        RETURN res;
    END IF;
    link:=row.id;
    res.nearest_link:=link;

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:

SELECT ST_Line_Locate_Point(geom , point)as offset; 

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):

select st_length(the_geom) from (select ST_ASTEXT(the_geom) as the_geom FROM dr_2po_4pgr WHERE id= edge_identifier)t";

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.

Iñigo
la source
1

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

amball
la source