Ich werde die Lösung erklären, die ich gefunden habe (vielleicht nicht die beste).
Nach Angaben der Post Bild, nehmen wir an , dass wir in sind Punkt A und wir jetzt gehen Punkt B . Wie ich oben erklärt habe, sind diese Punkte kein Eckpunkt (Quelle / Ziele in der Tabelle, die mit dem osm2po-Tool generiert wurde).
Aus diesem Grund müssen wir die Lauf- / Fahrtrichtung kennen. Wenn wir vom nächsten Scheitelpunkt zum Punkt A (Punkt Grün) über einen orangefarbenen Pfad gehen, müssen wir den Versatz zwischen Punkt A und Punkt Grün (nächster Scheitelpunkt) abziehen . Wenn wir jedoch die Straße Calle Almirante Bonifaz durchfahren müssen , müssen wir den Versatz zur Länge dieser Kante addieren (vom grünen Punkt bis zur Kreuzung zwischen Calle Almirante Bonifaz und Calle San Juan ).
Ich führe die folgende Abfrage aus, um den kürzesten Pfad zu ermitteln (Sie benötigen die hier erläuterte Erweiterung pgRouting pgRouting - Installation und Anforderungen hier Installation und Anforderungen ):
SELECT gid, cost, st_astext(the_geom) as the_geom FROM dijkstra_sp_delta('xx_2po_4pgr', source_vertex, target_vertex, 0.1);
Dies führt zu einer Reihe von Kanten, die die gesamte Route darstellen. Eine mögliche Ausgabe für diese Abfrage könnte beispielsweise sein:
Wobei die Feld- GID ( ID in der von osm2po generierten Tabelle) die Kanten- ID darstellt. Nun, wir müssen die Offsets am Anfang und am Ende überprüfen (Punkte A / B).
Wenn wir den Startversatz prüfen, müssen wir prüfen, ob die erste Kante der in der obigen Abfrage erhaltenen Menge von Kanten mit dem Pfad übereinstimmt, der dem Punkt A am nächsten liegt . Stimmen sie überein, werden wir den Offset abziehen. Wenn sie nicht übereinstimmen, addieren wir den Offset. Um den nächsten Link zu einem Punkt zu erhalten, führe ich die folgende Abfrage aus:
SELECT * FROM find_node_by_nearest_link_within_distance(point, 0.1, 'xx_2po_4pgr') as id;
Sie müssen diese Funktion anpassen, damit sie die nächste Kante zurückgibt. Zuerst müssen Sie den link_point- Typ ändern ( next_link- Feld hinzufügen ):
CREATE TYPE link_point AS
(id integer,
name character varying,
nearest_link integer);
ALTER TYPE link_point
OWNER TO postgres;
Sie müssen auch den find_node_by_nearest_link_within_distance ändern . Füge einfach die letzte Zeile hinzu (ich zeige nur einen Auszug aus der Funktion):
-- 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;
Dann müssen Sie wissen, wie groß der Abstand zwischen Punkt ( Punkt A / Punkt B ) und der nächsten Kante (Versatz) ist. Zu diesem Zweck führe ich diese Abfrage aus:
SELECT ST_Line_Locate_Point(geom , point)as offset;
Wo geom ist das the_geom Feld in osm2po erzeugten Tabelle.
Zu diesem Zeitpunkt hätten wir den Offset, um zu addieren oder zu subtrahieren.
Schließlich müssen Sie die Kantenlänge kennen, um den in der obigen Abfrage erhaltenen Wert anzuwenden und den Realwert anzupassen (wenn Sie mit dem Geometrietyp arbeiten, müssen Sie den erhaltenen Wert auf Meter normieren. Multiplizieren Sie einfach 111000 mit der in erhaltenen Länge die Abfrage):
select st_length(the_geom) from (select ST_ASTEXT(the_geom) as the_geom FROM dr_2po_4pgr WHERE id= edge_identifier)t";
Wenn wir den Endversatz prüfen würden, müssten wir prüfen, ob der letzte Pfad der in der obigen Abfrage erhaltenen Menge von Pfaden mit dem nächsten Pfad zum Endpunkt ( Punkt B ) identisch ist, und wir würden bei addieren / subtrahieren genauso wie zuvor.
Entschuldige mein Englisch.