Wyjaśnię rozwiązanie, które znalazłem (być może nie będzie najlepsze).
Zgodnie z tym stanowiskiem obrazu, załóżmy, że jesteśmy w punkcie A i zamierzam iść do punktu B . Jak wyjaśniłem powyżej, punkty te nie są wierzchołkami (źródło / cele w tabeli generowane za pomocą narzędzia osm2po).
Z tego powodu musimy znać kierunek marszu / jazdy. Jeśli przejdziemy od najbliższego wierzchołka do punktu A (punkt zielony) przez pomarańczową ścieżkę, musielibyśmy odjąć przesunięcie między punktem A i punktem zielonym (najbliższy wierzchołek). Ale gdybyśmy musieli przejść ulicą Calle Almirante Bonifaz , powinniśmy dodać przesunięcie do długości tej krawędzi (od punktu zielonego do przecięcia między Calle Almirante Bonifaz i Calle San Juan ).
Uruchomiam następujące zapytanie, aby uzyskać najkrótszą ścieżkę (potrzebujesz wyjaśnienia rozszerzenia pgRouting tutaj pgRouting - instalacja i wymagania tutaj instalacja i wymagania ):
SELECT gid, cost, st_astext(the_geom) as the_geom FROM dijkstra_sp_delta('xx_2po_4pgr', source_vertex, target_vertex, 0.1);
W rezultacie powstaje zestaw krawędzi reprezentujących pełną trasę. Na przykład jednym z możliwych wyników tego zapytania może być:
Gdzie pole gid ( id w tabeli generowanej przez osm2po) reprezentuje identyfikator krawędzi. Cóż, musimy sprawdzić przesunięcia na początku i na końcu (punkty A / B).
Jeśli sprawdzimy początek offset, musimy sprawdzić, czy pierwsza krawędź zestawu krawędzi uzyskanych w powyższym zapytaniu jest taka sama do najbliższej drogi do punktu A . Jeśli się zgadzają, odejmiemy przesunięcie. Jeśli się nie zgadzają, dodamy przesunięcie. Aby uzyskać najbliższe łącze do punktu, uruchamiam następujące zapytanie:
SELECT * FROM find_node_by_nearest_link_within_distance(point, 0.1, 'xx_2po_4pgr') as id;
Musisz dostosować tę funkcję, aby zwracała najbliższą krawędź. Najpierw musisz zmodyfikować typ linku (dodaj pole najbliższego linku ):
CREATE TYPE link_point AS
(id integer,
name character varying,
nearest_link integer);
ALTER TYPE link_point
OWNER TO postgres;
Musisz także zmodyfikować find_node_by_nearest_link_with_distance . Wystarczy dodać ostatni wiersz (pokazuję tylko wyciąg z funkcji):
-- 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;
Następnie musisz wiedzieć, jaka jest odległość między punktem ( Punkt A / Punkt B ) a najbliższą krawędzią (odsunięcie). W tym celu uruchamiam to zapytanie:
SELECT ST_Line_Locate_Point(geom , point)as offset;
Gdzie geom jest the_geom pola w osm2po generowanej tabeli.
W tym momencie będziemy mieli przesunięcie do dodania lub odjęcia.
Na koniec musisz znać szerokość krawędzi, aby zastosować wartość uzyskaną w powyższym zapytaniu i dostosować wartość rzeczywistą (jeśli pracujesz z typem geometrii, będziesz musiał znormalizować do liczników uzyskaną wartość. Wystarczy pomnożyć 111000 przez długość uzyskaną w Zapytanie):
select st_length(the_geom) from (select ST_ASTEXT(the_geom) as the_geom FROM dr_2po_4pgr WHERE id= edge_identifier)t";
Gdybyśmy sprawdzili przesunięcie końcowe, musielibyśmy sprawdzić, czy ostatnia ścieżka zestawu ścieżek uzyskana w powyższym zapytaniu jest taka sama jak najbliższa ścieżka do punktu końcowego ( punkt B ) i dodalibyśmy / odejmowali w tak samo jak poprzednio.
Wybacz mój angielski.