Eksplorasi Peta Rute KRL Commuterline

12 May 2019
DataKepo - Peta

Di episode sebelumnya gue telah melakukan sedikit “kepo” terhadap data rute Transjakarta. Di episode DataKepo kali ini, gue akan melakukan “kepo” lebih mendalam terhadap moda transportasi publik lainnya yang ada di Jabodetabek yaitu KRL Commuterline.

Ada satu pertanyaan yang membuat gue penasaran yang pernah diajukan di episode kepo data Transjakarta sebelumnya yaitu bagaimana cara mengukur jarak antar halte (stasiun jika menggunakan KRL). Untuk mengukur jarak antar stasiun, gue harus memecah data rute satu trayek menjadi beberapa bagian dipisahkan berdasarkan koordinat stasiun yang dilewati trayek tersebut.

Visualisasi data KRL yang sudah dipisah per stasiun

Data Wrangling

Setelah berseluncur di Google dengan kata-kata pencarian split linestring based on point in R, split line by muiltple points, linestring to multiple line string in R sf, gue menemukan referensi yang mirip dengan permasalahan gue di split line by multiple points using sf package. Perbedaannya adalah kasus tersebut agak sedikit lebih panjang di proses awal karena data posisi yang diambil harus dicari terlebih dahulu ke data rute atau garis terdekat, sedangkan dalam kasus gue, data posisi stasiun sudah menempel dengan data rute trayek.

Selain menggunakan sf sebagai package utama yang gue gunakan untuk operasi data spasial, gue juga membutuhkan satu package tambahan yaitu lwgeom. Berikut ini langkah demi langkah yang mesti ditempuh, dan juga sudah tersaji dalam fungsi split_route yang bisa dicek secara lengkap di sini

  1. Menyiapkan data rute sebuah trayek KRL yang berupa linestring dan data posisi stasiun terkait trayek tersebut yang berupa point (sudah tersedia di nusantr dengan dataset bernama krl_route dan krl dengan beberapa pengolahan terlebih dahulu)

     route <- df_route %>% 
         filter(schedule_id == schedule_id_input,
                route_id == route_id_input)
     station <- df_station %>%
         unnest() %>% 
         filter(schedule_id == schedule_id_input)
    
  2. Mengubah data posisi stasiun yang berupa titik atau point menjadi polygon atau area yang sangat kecil menggunakan st_buffer

     buff <- st_combine(st_buffer(station, buffer_size))
    
  3. Memisahkan data rute trayek berdasarkan data posisi stasiun yang sudah menjadi area yang sangat kecil menggunakan fungsi st_split dari package lwgeom dan mengumpulkan pecahan-pecahan tersebut dalam bentuk linestring menggunakan st_collection_extract

     all <- st_collection_extract(st_split(route$geometry, buff), "LINESTRING")
    
  4. Mengubah data pecahan-pecahan linestring tersebut ke dalam bentuk sf data frame disertai id sebagai pengenal

     all <- st_as_sf(
         data.frame(
           order_id = 1:length(all),
           geometry = all
         )
       )
    
  5. Membuang pecahan-pecahan linestring yang tidak signifikan (dengan panjang garis threshold di bawah 250m yang merupakan sisa dari pecahan-pecahan area yang sangat kecil)

     all <- all %>% 
         mutate(d = as.numeric(st_length(geometry)) * 10^-3) %>% 
         filter(d > threshold)
    
  6. Mengubah pecahan-pecahan linestring ke bentuk titik atau point untuk mendapatkan titik awal/akhir dari tiap pecahan linestring

     point <- st_cast(all, "POINT") %>% 
         group_by(order_id) %>% 
         mutate(r = row_number()) %>% 
         arrange(desc(r)) %>% 
         mutate(r2 = row_number()) %>% 
         ungroup() %>% 
         arrange(order_id) %>% 
         filter(r == 1 | r2 == 1) %>% 
         select(-d)
    
  7. Melakukan spatial join dengan cara menggabungkan titik awal/akhir dengan data posisi stasiun berdasarkan titik terdekat untuk mendapatkan nama dan informasi stasiun

     all_name <- st_join(point, station, join = st_is_within_distance, dist = 200) %>% 
         arrange(order_id, r) %>% 
         as.data.frame() %>% 
         select(-geometry) %>% 
         group_by(order_id) %>% 
         summarise(line_name = paste0(station_name, collapse = " - ")) %>% 
         ungroup() %>% 
         separate(line_name, c("station_start", "station_end"), sep = " - ", remove = FALSE)
    
  8. Melakukan penggabungan data pecahan-pecahan linestring dengan data penggabungan spatial join berdasarkan id masing-masing untuk mendapatkan data yang benar-benar utuh

     final <- all_name %>% 
         left_join(all) 
    

Menggunakan langkah demi langkah di atas, data awal yang berupa linestring per trayek akan berubah menjadi linestring antar stasiun dalam sebuah trayek. Berikut ini salah satu contoh gambaran trayek sebelum dan sesudah data dipecah.

Data Exploration

Beberapa informasi umum yang didapatkan setelah melakukan kepo data rute KRL adalah:

  • 77 rute (9 rute di antaranya merupakan rute utama)
  • Total panjang rute utama: 358.5 km
  • Rata-rata panjang rute utama: 39.83 km
  • Total panjang rute utama (tanpa jalur duplikat): 276 km
  • Rata-rata jarak antar stasiun: 2.88 km

Panjang Rute Utama

Menggunakan data yang belum dipisah per stasiun, berikut ini adalah visualisasi 9 rute utama yang diurutkan berdasarkan rute terpanjang (72.84km) hingga rute terpendek (1.59km).

Jarak Antar Stasiun

Selanjutnya, gue akan memanfaatkan data yang sudah diolah dan dipisah per stasiun untuk mencari jarak antar stasiun pada tiap rute. Rute KRL bandara dan pengumpan (Jakarta Kota - Kampung Bandan) tidak akan dimasukkan dalam penghitungan karena jumlah stasiun yang sangat sedikit dibandingkan dengan rute lain.

Visualisasi di atas menunjukkan minimum jarak antar stasiun, rata-rata jarak antar stasiun dan maksimum jarak antar stasiun untuk tiap rute.

comments powered by Disqus