Come aggiungere offset alla rotta?


13

Modificato:

campione

Voglio illustrare la mia domanda. Supponiamo di essere nel "Punto A" e di voler andare al "Punto B". Questi punti non sarebbero nella tabella "at_2po_4pgr" perché non sono nodi di origine / destinazione. Quindi, vorrei cercare il nodo più vicino per i punti A e B (punti verdi). Dopo questo, potrei eseguire una chiamata shortest_path usando id di punti verdi e otterrei un percorso "arancione". Ma per ottenere il costo del percorso reale (distanza) nel primo caso dovrei sottrarre "offsetA" e nel secondo caso aggiungere de "offset B". Per calcolare la distanza tra punti rossi e punti verdi, eseguo la seguente query:

SELECT * FROM st_distance( ST_GeomFromText('POINT(-3.6963314 42.3498066)',4326), ST_GeomFromText('POINT(-3.6954276 42.3479634)',4326)).

Come faccio a sapere quando aggiungere o sottrarre l'offset?

Mi scusi per il mio inglese!


1
Benvenuto in gis.stackexchange. Questo è un sito di domande e risposte in cui ogni thread dovrebbe contenere esattamente una domanda e le relative risposte. Si prega di aprire una discussione separata per la domanda n. 3. 2 # venga risolta gis.stackexchange.com/questions/33471/...
Sottosuolo

1
Ho lo stesso problema. hai trovato qualche soluzione? Grazie mille
Robert,

1
Pubblica la tua soluzione nella sezione delle risposte. Quindi può essere votato.
underdark

Risposte:


2

Non penso che tu possa fare affidamento sul vertice più vicino. Immagina che sorgente e target si trovino sullo stesso bordo vicino allo stesso vertice.

Preferiresti considerarne tre! diversi casi:

  1. un vertice è il punto più vicino.
  2. un nodo forma del bordo è quello giusto
  3. la linea di demarcazione stessa è più vicina. (ortogonale)

Ci dispiace ma questa non è la risposta corretta. pgr_trsp - Il percorso più breve di restrizione (TRSP) è sfalsato come mostra per la risposta di @amball.
Juan Carlos Oropeza,


1

Spiegherò la soluzione che ho trovato (forse non essere il migliore).

Secondo l'immagine appena catturata, supponiamo che siamo in punto A e faremo andare a Point B . Come ho spiegato sopra, questi punti non sono vertici (sorgente / target nella tabella generata con lo strumento osm2po).

Per questo motivo, dobbiamo conoscere la direzione di marcia / guida. Se passiamo dal vertice più vicino al punto A (punto verde) attraverso il percorso arancione dovremmo sottrarre l'offset tra il punto A e il punto verde (vertice più vicino). Ma se dovessimo attraversare Calle Almirante Bonifaz , dovremmo aggiungere l'offset alla lunghezza di questo bordo (dal punto verde all'intersezione tra Calle Almirante Bonifaz e Calle San Juan ).

Eseguo la seguente query per ottenere il percorso più breve (è necessaria l'estensione pgRouting spiegata qui pgRouting - installazione e requisiti qui installazione e requisiti ):

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

Ciò si traduce in un insieme di spigoli che rappresenta il percorso completo. Ad esempio, un possibile output per questa query potrebbe essere:

uscita possibile

Dove il campo gid ( id nella tabella generata osm2po) rappresenta l'identificatore del bordo. Bene, dobbiamo controllare gli offset all'inizio e alla fine (punti A / B).

Se controlliamo compensato dall'inizio, dobbiamo controllare se il primo bordo del set di spigoli ottenuti nella query precedente è uguale al percorso più vicino al punto A . Se corrispondono, sottrarremo l'offset. Se non corrispondono, aggiungeremo l'offset. Per ottenere il collegamento più vicino a un punto, eseguo la seguente query:

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

È necessario adattare questa funzione in modo che restituisca il bordo più vicino. In primo luogo è necessario modificare il link_point tipo (aggiungere nearest_link campo):

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

È inoltre necessario modificare find_node_by_nearest_link_within_distance . Basta aggiungere l'ultima riga (mostro solo un estratto della funzione):

-- 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;

Quindi è necessario sapere qual è la distanza tra il punto ( Punto A / Punto B ) e il bordo più vicino (offset). A tale scopo eseguo questa query:

SELECT ST_Line_Locate_Point(geom , point)as offset; 

Dove geom è il the_geom campo in osm2po tabella generata.

A questo punto, avremmo l'offset da aggiungere o sottrarre.

Infine, dovresti conoscere la legenda del bordo per applicare il valore ottenuto nella query sopra e regolare il reale (se lavori con il tipo di geometria, dovrai normalizzare a metri il valore ottenuto. Basta moltiplicare 111000 per la lunghezza ottenuta in la query):

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

Se dovessimo controllare l'offset finale, dovremmo verificare se l'ultimo percorso dell'insieme di percorsi ottenuto nella query sopra è lo stesso del percorso più vicino al punto finale ( Punto B ) e aggiungeremmo / sottrai a allo stesso modo di prima.

Scusa il mio inglese.


1

In pgrouting, pgr_trsp - Turn Restriction Shortest Path (TRSP) fa esattamente quello che stai cercando.

Invece di specificare i nodi di origine e di destinazione, è possibile specificare i bordi di origine e di destinazione e la frazione lungo il bordo in cui si trovano l'origine e la destinazione.

(Puoi utilizzare ST_Line_Locate_Point per ottenere quella frazione dalla geometria del tuo punto, supponendo che tu conosca il bordo più vicino.)

Vedi http://docs.pgrouting.org/2.0/en/src/trsp/doc/index.html#trsp

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.