routing

PosGIS Routing

Pernah lihat ato nyoba aplikasi yahoo maps?
Saat kita mencari arah atau jalur terpendek dari satu lokasi ke lokasi lainnya, marker jalan muncul sebagai penunjuk arah jalur terpendek yang harus kita tempuh. Aplikasi ini menggunakan metoda Vertex Simplication dengan menghitung jarak terpendek. Sampai saat ini, untuk menangani datanya dari database postgresql yang kita simpan dipakai diprogram pgDIJKSTRA/pgRouting dari PostLBS. Ini sebenarnya hasil oprekan yang sudah cukup lama dan dilakukan di atas Windows menggunakan fungsi pgDijkstra, PostgreSQL 8.1.0 dan tidak berjalan pada PostgreSQL 8.0. Awalnya sih dari melihat dari dokumen yang dibawa oleh Pak Hadi, aku jadi tertarik kenapa ada error di function PostgreSQL-nya.
Kita coba menggunakan database roads dengan database username routing.

Baiklah, catatan yang pertama dimulai dari:

Pertama, pastikan pada database telah terinstall postgis. Bisa dengan installer yang disediakan pada windows atau sistem operasi lainnya.Untuk melihat apakah sudah terinstall, pada database ada table geometry_columns (registrasi data geometry tiap table) dan spatial_ref_sys sebagai projection table-nya.
*update : Bila menggunakan installer windows v8.2.x sudah terinstall otomatis dan sudah terdapat template postgis. Kita hanya membuat database berdasarkan template ini.
Bila belum terinstall ataupun terbuat templatenya, silahkan lihat postingan sebelumnya. Hanya saja secara default, kepimilikan fungsi dan kedua tabel oleh database postgres. Untuk merubahnya kita lakukan perintah:

C:PgSQL> psql -U postgres -d roads
       psql> ALTER TABLE geometry_columns OWNER TO routing;
       psql> ALTER TABLE spatial_ref_sys OWNER TO routing;

Kedua, masukkan data jalan anda. Misalkan jalanbandung.sql

C:PgSQL > psql -U routing -d roads -f jalanbandung.sql

Catatan: Pada beberapa type mapserver, dibutuhkan OID table yang mengandung data geometri sedangkan default postgresql 8.1 yang dicoba default-nya without oids. Ubah table Anda memakai OIDS dengan mengedit file SQL Anda pada bagian CREATE TABLE namatable ( ….) WITH OIDS;

Ketiga, masukkan fungsi dijkstra:

C:PgSQL> psql -U postgres -d roads -f dijkstra.sql
C:PgSQL> psql -U postgres -d roads -f dijkstra_postgis.sql

Catatan: Pada dijkstra.sql aku berhasil menemukan bug kecil terhadap fungsi create_graph_tables nantinya.
Oleh karena itu perlu diedit sedikit pada bagian :

"CREATE OR REPLACE FUNCTION create_graph_tables"
// temukan di bagian bawahnya yang bertuliskan:
EXECUTE 'CREATE TABLE ' || edges_table
                        || ' (id serial, source int, target int, '
                        || 'cost float8, reverse_cost float8,
                        UNIQUE (source, target))';

// ubah menjadi
EXECUTE 'CREATE TABLE ' || edges_table
                        || ' (id serial, source int, target int, '
                        || 'cost float8, reverse_cost float8) WITH OIDS';

Catatan: Belum dicoba pada fungsi yang terbaru

Keempat, buat satu table baru sebagai tempat hasil routing kita. Misalkan saja dengan nama table route. Caranya dengan membuat satu file sql baru route.sql dengan tabel isian berasal dari jalanbandung. File route.sql berisi:

CREATE TABLE route (gid int UNIQUE, source_id int, target_id int, edge_id int) WITH OIDS;
SELECT AddGeometryColumn('route', 'the_geom', -1, 'MULTILINESTRING', 2 );
INSERT INTO route (gid, the_geom) (SELECT gid, the_geom FROM jalanbandung);

atau bisa dilakukan tanpa membuat file route.sql dengan mengetikkan di konsol pgsql dengan mengetikkan terlebih dulu:

C:PgSQL> psql -U routing roads

dan untuk mengeksekusi route.sql kita berikan perintah:

C:PgSQL> psql -U postgres -d roads -f route.sql

Catatan: Tabel ini bertujuan untuk menempatkan data gid dan data geometri dari tabel kita yang sebenarnya identik tanpa mengikutkan informasi dari kolom lain.Kita tidak bereksperimen dengan tabel data melainkan pada tabel route ini. Bisa Anda lihat isi tabel ini terdiri dari kolom: || gid || source_id || target_id || the_geom || dengan source_id, target_id dan edge_id masih kosong. Di sinilah peran fungsi dijkstra yang kita install tadi akan bermain.

Kelima, kolom source_id dan target_id pada tabel route dengan mengetikkan perintah sql:

C:PgSQL> psql -U routing roads
       psql> SELECT assign_vertex_id('route', 1);

Script ini akan berjalan tergantung ketelitian verteks yang Anda inginkan (di atas menggunakan 0.000001 satuan) dan besarnya banyaknya data Anda. Semakin teliti (misalnya 0.01 satuan) maka script akan berlangsung semakin lama. Hasilnya akan disimpan pada kolom source_id dan target_id tabel route dengan membuat id dan data geometri pada tabel baru vertices_tmp.
Catatan: Berdasarkan hasil percobaan, prosedur ini hanya bisa dijalankan sekali.Apabila Anda merasa gagal melakukannya (source_id,target_id pada tabel route masih kosong begitu juga tabel vertices_tmp) Anda harus menghapus database Anda dan mengulangi dari awal.Ini disebabkan karena saat melakukan assignment antara tabel route dan vertices_tmp, fungsi mencatat oid tabel vertices_tmp yang pertama kali dibuat. Sedangkan apabila prosedur ini diulangi, oid tabel vertices_tmp tentu saja sudah berubah. Namun bila ada saran dan masukan yang lebih berguna, aku sih sangat berterima kasih ;)

Keenam, kolom edge_id pada tabel route masih kosong. Isikan dengan mengetikkan perintah sql:

C:PgSQL> psql -U routing roads
       psql> SELECT create_graph_tables('route', 'int4');
       // Script ini selain mengisi kolom edge_id,
       // juga akan membuat 2 tabel baru: route_edges dan route_vertices.
       // Sekarang lihat isi dari tabel route_edges. psql> SELECT * FROM route_edges LIMIT 3;

akan menghasilkan kira-kira seperti ini:

id  | source | target | cost | reverse_cost
---+-------+-------+------+--------------
1  |    1     |   2      |         |
2  |    3     |   3      |         |
4  |    2     |   2      |         |

(3 rows)

Untuk mengisi kolom cost sebagai hasil perhitungan besar jarak per path, gunakan perintah sql:

SELECT update_cost_from_distance('route');
SELECT * FROM route_edges LIMIT 3;

akan menghasilkan:

id  | source | target |            cost         | reverse_cost
---+-------+-------+-------------------+--------------
1   |     1   |    2     | 6857.46585793103 |
2   |     3   |    3     | 37349.9592156392 |
4   |     2   |    2     | 14040.5673116933 |

(3 rows)

Bersambung biar gak kepanjangan…

Related posts:

  1. PostGIS Sample
  2. Install PostGIS