Saya akan menjelaskan solusi yang saya temukan (mungkin tidak menjadi yang terbaik).
Menurut gambar postingan, misalkan kita berada di Point A dan kita akan pergi ke Point B . Seperti yang saya jelaskan di atas, ini bukan titik (sumber / target dalam tabel yang dihasilkan dengan alat osm2po).
Karena itu, kita perlu mengetahui arah berjalan / mengemudi. Jika kita pergi dari titik terdekat ke titik A (titik hijau) melalui jalur oranye kita harus mengurangi offset antara titik A dan titik hijau (titik terdekat). Tetapi jika kita harus melalui jalan Calle Almirante Bonifaz , maka kita harus menambahkan offset ke panjang tepi ini (dari titik hijau ke persimpangan antara Calle Almirante Bonifaz dan Calle San Juan ).
Saya menjalankan kueri berikut untuk mendapatkan jalur terpendek (Anda memerlukan ekstensi pgRouting dijelaskan di sini pgRouting - instalasi dan persyaratan di sini instalasi & persyaratan ):
SELECT gid, cost, st_astext(the_geom) as the_geom FROM dijkstra_sp_delta('xx_2po_4pgr', source_vertex, target_vertex, 0.1);
Ini menghasilkan seperangkat tepi yang mewakili rute lengkap. Misalnya, satu kemungkinan keluaran untuk kueri ini mungkin:
Di mana gid bidang ( id dalam tabel yang dihasilkan osm2po) mewakili pengidentifikasi tepi. Nah, kita harus memeriksa offset di awal dan di akhir (Poin A / B).
Jika kita memeriksa awal offset, kita harus memeriksa apakah tepi pertama set dari tepi diperoleh di query di atas adalah sama untuk jalan terdekat ke Point A . Jika cocok, maka kami akan mengurangi offset. Jika tidak cocok, kami akan menambahkan offset. Untuk mendapatkan tautan terdekat ke suatu titik, saya menjalankan kueri berikut:
SELECT * FROM find_node_by_nearest_link_within_distance(point, 0.1, 'xx_2po_4pgr') as id;
Anda harus menyesuaikan fungsi ini sehingga mengembalikan tepi terdekat. Pertama, Anda harus mengubah link_point jenis (add nearest_link lapangan):
CREATE TYPE link_point AS
(id integer,
name character varying,
nearest_link integer);
ALTER TYPE link_point
OWNER TO postgres;
Anda juga harus memodifikasi find_node_by_nearest_link_within_distance . Cukup tambahkan baris terakhir (saya hanya menunjukkan ekstrak dari fungsi):
-- 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;
Maka Anda perlu tahu berapa jarak antara titik ( Titik A / Titik B ) dan tepi terdekat (offset). Untuk tujuan ini saya menjalankan kueri ini:
SELECT ST_Line_Locate_Point(geom , point)as offset;
Dimana GEOM adalah the_geom lapangan di osm2po tabel yang dihasilkan.
Pada titik ini, kita memiliki offset untuk ditambahkan atau dikurangi.
Terakhir, Anda perlu mengetahui leg edge untuk menerapkan nilai yang diperoleh dalam kueri di atas dan menyesuaikan real (jika Anda bekerja dengan tipe geometri, Anda harus menormalkan ke meter nilai yang diperoleh. Cukup kalikan 111000 dengan panjang yang diperoleh dalam kueri):
select st_length(the_geom) from (select ST_ASTEXT(the_geom) as the_geom FROM dr_2po_4pgr WHERE id= edge_identifier)t";
Jika kita akan memeriksa end offset, maka kita harus memeriksa apakah path terakhir dari set path yang diperoleh dalam query di atas sama dengan path terdekat ke titik akhir ( Point B ) dan kita akan menambahkan / mengurangi pada dengan cara yang sama seperti sebelumnya.
Maafkan bahasa Inggris saya.