Tôi sẽ giải thích giải pháp mà tôi đã tìm thấy (có lẽ không phải là tốt nhất).
Theo hình ảnh bưu điện, chúng ta hãy giả sử rằng chúng ta đang ở điểm A và chúng tôi sẽ đi đến điểm B . Như tôi đã giải thích ở trên, điểm này không phải là đỉnh (nguồn / mục tiêu trong bảng được tạo bằng công cụ osm2po).
Do đó, chúng ta cần biết hướng đi / lái xe. Nếu chúng ta đi từ đỉnh gần nhất đến Điểm A (điểm xanh lục) qua đường màu cam, chúng ta sẽ phải trừ phần bù giữa Điểm A và điểm xanh lục (đỉnh gần nhất). Nhưng nếu chúng ta phải đi qua đường Calle Almirante Bonifaz , thì chúng ta nên thêm phần bù vào chiều dài của cạnh này (từ điểm xanh đến điểm giao giữa Calle Almirante Bonifaz và Calle San Juan ).
Tôi chạy truy vấn sau để có được đường dẫn ngắn nhất (bạn cần phần mở rộng pgRouting được giải thích ở đây pgRouting - cài đặt và các yêu cầu ở đây cài đặt & yêu cầu ):
SELECT gid, cost, st_astext(the_geom) as the_geom FROM dijkstra_sp_delta('xx_2po_4pgr', source_vertex, target_vertex, 0.1);
Điều này dẫn đến một tập hợp các cạnh thể hiện tuyến đường hoàn chỉnh. Ví dụ: một đầu ra có thể cho truy vấn này có thể là:
Trong đó trường gid ( id trong bảng được tạo osm2po) đại diện cho mã định danh cạnh. Chà, chúng ta phải kiểm tra độ lệch ở đầu và cuối (Điểm A / B).
Nếu chúng ta kiểm tra phần bù bắt đầu, chúng ta phải kiểm tra xem cạnh đầu tiên của tập hợp các cạnh thu được trong truy vấn trên có giống với đường dẫn gần nhất đến Điểm A không . Nếu chúng khớp, thì chúng ta sẽ trừ phần bù. Nếu chúng không khớp, chúng tôi sẽ thêm phần bù. Để có được liên kết gần nhất đến một điểm, tôi chạy truy vấn sau:
SELECT * FROM find_node_by_nearest_link_within_distance(point, 0.1, 'xx_2po_4pgr') as id;
Bạn phải điều chỉnh chức năng này để nó trả về cạnh gần nhất. Trước tiên, bạn phải sửa đổi loại link_point (thêm trường Recent_link ):
CREATE TYPE link_point AS
(id integer,
name character varying,
nearest_link integer);
ALTER TYPE link_point
OWNER TO postgres;
Bạn cũng phải sửa đổi find_node_by_nearest_link_within_distance . Chỉ cần thêm dòng cuối cùng (tôi chỉ hiển thị một trích xuất từ hàm):
-- 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;
Sau đó, bạn cần biết khoảng cách giữa điểm ( Điểm A / Điểm B ) và cạnh gần nhất (bù). Đối với mục đích này, tôi chạy truy vấn này:
SELECT ST_Line_Locate_Point(geom , point)as offset;
Trong đó geom là trường_geom trong bảng osm2po được tạo.
Tại thời điểm này, chúng tôi sẽ có phần bù để thêm hoặc trừ.
Cuối cùng, bạn sẽ cần phải biết phần chân cạnh để áp dụng giá trị thu được trong truy vấn ở trên và điều chỉnh giá trị thực (nếu bạn làm việc với loại hình học, bạn sẽ phải chuẩn hóa thành mét giá trị thu được. Chỉ cần nhân 111000 với độ dài thu được trong truy vấn):
select st_length(the_geom) from (select ST_ASTEXT(the_geom) as the_geom FROM dr_2po_4pgr WHERE id= edge_identifier)t";
Nếu chúng ta kiểm tra phần bù cuối, thì chúng ta sẽ phải kiểm tra xem đường dẫn cuối cùng của tập hợp các đường dẫn thu được trong truy vấn trên có giống với đường dẫn gần nhất đến điểm kết thúc ( Điểm B ) không và chúng ta sẽ thêm / trừ cách tương tự như trước đây.
Xin lỗi tiếng anh của tôi