Edytowane:
Chcę zilustrować moje pytanie. Załóżmy, że jesteś w „Punkcie A” i chcesz przejść do „Punktu B”. Te punkty nie byłyby w tabeli „at_2po_4pgr”, ponieważ nie są węzłami źródłowymi / docelowymi. Następnie szukałem najbliższego węzła dla punktów A i B (zielone punkty). Następnie mogę wykonać wywołanie shortest_path przy użyciu identyfikatorów zielonych punktów i uzyskać ścieżkę „pomarańczową”. Ale aby uzyskać rzeczywisty koszt ścieżki (odległość) w pierwszym przypadku musiałbym odjąć „offsetA”, a w drugim przypadku dodać de „offset B”. Aby obliczyć odległość między czerwonymi i zielonymi punktami, uruchamiam następujące zapytanie:
SELECT * FROM st_distance(
ST_GeomFromText('POINT(-3.6963314 42.3498066)',4326),
ST_GeomFromText('POINT(-3.6954276 42.3479634)',4326))
.
Skąd mam wiedzieć, czy dodać lub odjąć przesunięcie?
Przepraszam za mój angielski!
Odpowiedzi:
Nie sądzę, że można polegać na najbliższym wierzchołku. Wyobraź sobie, że źródło i cel znajdują się na tej samej krawędzi blisko tego samego wierzchołka.
Wolisz rozważyć trzy! różne przypadki:
źródło
Możesz znaleźć taką funkcję tutaj: https://github.com/pgRouting/pgrouting-contrib/blob/master/wrapper/routing_core_smart.sql#L69
Wyszukuje najbliższe łącze w sieci, co zwykle daje lepszy wynik. Jeśli używasz Shooting Star, możesz rozpocząć routing z / do tego łącza. W przypadku A * lub Dijkstra albo wybierasz punkt początkowy lub końcowy łącza, albo tworzysz „wirtualny” węzeł, dzieląc łącze na dwa.
źródło
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 ):
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:
Musisz dostosować tę funkcję, aby zwracała najbliższą krawędź. Najpierw musisz zmodyfikować typ linku (dodaj pole najbliższego linku ):
Musisz także zmodyfikować find_node_by_nearest_link_with_distance . Wystarczy dodać ostatni wiersz (pokazuję tylko wyciąg z funkcji):
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:
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):
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.
źródło
W pgrouting pgr_trsp - Najkrótsza ścieżka ograniczenia ruchu (TRSP) robi dokładnie to, czego szukasz.
Zamiast określać węzły źródłowy i docelowy, można określić krawędzie źródłowe i docelowe oraz ułamek wzdłuż krawędzi, w której znajduje się miejsce początkowe i docelowe.
(Możesz użyć ST_Line_Locate_Point, aby uzyskać ten ułamek z geometrii punktu, zakładając, że znasz najbliższą krawędź.)
Zobacz http://docs.pgrouting.org/2.0/en/src/trsp/doc/index.html#trsp
źródło