石川県の各市役所・町役場から最も近い駅を検索する

R
作者

伊東宏樹

公開

2025年5月17日

RのosrmパッケージからOSRMを使って、石川県の各市役所・町役場から最も近い駅を検索してみました。

準備

OSRMサーバーをDockerで立ち上げるところは、前回の記事と同じです。

sf, osrm, tibble, leafletの各パッケージを読み込み、OSRMの接続先を設定します。

library(sf)
## Linking to GEOS 3.13.0, GDAL 3.8.5, PROJ 9.5.1; sf_use_s2() is TRUE
library(osrm)
## Data: (c) OpenStreetMap contributors, ODbL 1.0 - http://www.openstreetmap.org/copyright
## Routing: OSRM - http://project-osrm.org/
library(tibble)
library(leaflet)

options(osrm.server = "http://192.168.1.62:5000/",
        osrm.profile = "foot")

データ

国土数値情報から以下のデータをダウンロードしました。いずれもライセンスはCC-BY4.0です。

  • 行政区域(石川県分)
  • 鉄道データ
  • 市町村役場等及び公的集会施設データ(石川県分)
data_dir <- "data"
station_file <- "N02-20_Station.geojson"
pref_file <- "N03-20240101_17.geojson"
office_file <- "P05-22_17.geojson"

各データを読み込みます。

# 駅データ
station <- st_read(file.path(data_dir, station_file)) |>
  dplyr::rename(Railway_class = N02_001,
                Institution_type = N02_002,
                Line_name = N02_003,
                Company_name = N02_004,
                Station_name = N02_005) |>
  st_transform(crs = 4326) # WGS84に変換
## Reading layer `N02-20_Station' from data source 
##   `/Users/hiroki/Sites/www/posts/2025-05-17-city-office-to-station/data/N02-20_Station.geojson' 
##   using driver `GeoJSON'
## Simple feature collection with 10267 features and 5 fields
## Geometry type: MULTILINESTRING
## Dimension:     XY
## Bounding box:  xmin: 127.6523 ymin: 26.19319 xmax: 145.5974 ymax: 45.41688
## Geodetic CRS:  JGD2011

# 行政区域データ
# 石川県全体でまとめる
pref <- st_read(file.path(data_dir, pref_file)) |>
  st_union()
## Reading layer `N03-20240101_17' from data source 
##   `/Users/hiroki/Sites/www/posts/2025-05-17-city-office-to-station/data/N03-20240101_17.geojson' 
##   using driver `GeoJSON'
## Simple feature collection with 1710 features and 6 fields
## Geometry type: POLYGON
## Dimension:     XY
## Bounding box:  xmin: 136.242 ymin: 36.06723 xmax: 137.3653 ymax: 37.85791
## Geodetic CRS:  WGS 84

# 市町村役場データ
office <- st_read(file.path(data_dir, office_file)) |>
   # 本庁(市役所、区役所、町役場、村役場)を抽出
  dplyr::filter(P05_002 == 1) |>
  st_transform(crs = 4326) # WGS84に変換
## Reading layer `P05-22_17' from data source 
##   `/Users/hiroki/Sites/www/posts/2025-05-17-city-office-to-station/data/P05-22_17.geojson' 
##   using driver `GeoJSON'
## Simple feature collection with 975 features and 4 fields
## Geometry type: POINT
## Dimension:     XY
## Bounding box:  xmin: 136.253 ymin: 36.17436 xmax: 137.3432 ymax: 37.52599
## Geodetic CRS:  JGD2011

# 市町村役場名を抽出する
office_name <- office |>
  as_tibble() |>
  dplyr::rename(Office_name = P05_003) |>
  dplyr::select(Office_name)

# 市町村役場の数
n_office <- nrow(office_name)

# 駅データを石川県内に絞り込む
# 点データに変換
station_pref <- st_intersection(station, pref) |>
  st_cast("POINT")
## Warning: attribute variables are assumed to be spatially constant throughout
## all geometries
## Warning in st_cast.sf(st_intersection(station, pref), "POINT"): repeating
## attributes for all sub-geometries for which they may not be constant

検索の実行と結果の整形

最も近い駅を検索

各市役所・町役場から徒歩ルートで最も近い駅を検索して、結果をresultに格納します。

result <- osrmTable(src = office,
                    dst = station_pref,
                    measure = "distance")

結果の整形

各市役所・町役場について最も近い駅を抽出します。

nearest <- purrr::map_dbl(seq_len(n_office),
                          \(i) which.min(result$distances[i, ]))

最も近い駅の路線名・駅名を抽出します。

nearest_name <- station_pref |>
  as_tibble() |>
  dplyr::slice(nearest) |>
  dplyr::select(Line_name, Station_name)

最も近い駅までの距離を抽出します。

nearest_dist <- purrr::map2_dbl(seq_len(n_office), nearest,
                                \(i, j) result$distances[i, j])

市町村役場名と路線名・駅名・距離を結合します。

result_tbl <- office_name |>
  dplyr::bind_cols(nearest_name) |>
  dplyr::mutate(Distance = nearest_dist)

経路の検索

各市役所・町役場について最も近い駅までの経路を検索します。

route <- purrr::map(seq_len(n_office),
                    \(i) osrmRoute(src = office[i, ],
                                   dst = station_pref[nearest[i], ]))

結果の表示

市役所・町役場と、そこから最も近い駅の路線名・駅名、距離(m)を表示します。

print(result_tbl)
## # A tibble: 19 × 4
##    Office_name    Line_name Station_name Distance
##    <chr>          <chr>     <chr>           <dbl>
##  1 金沢市役所     石川線    野町             1857
##  2 七尾市役所     七尾線    七尾              394
##  3 小松市役所     北陸線    小松             1069
##  4 輪島市役所     七尾線    穴水            21233
##  5 珠洲市役所     七尾線    穴水            46503
##  6 加賀市役所     北陸線    大聖寺            395
##  7 羽咋市役所     七尾線    羽咋             1068
##  8 かほく市役所   七尾線    宇野気            583
##  9 白山市役所     北陸線    松任             1673
## 10 能美市役所     北陸線    明峰             3581
## 11 野々市市役所   石川線    額住宅前         1064
## 12 川北町役場     北陸線    加賀笠間         5079
## 13 津幡町役場     七尾線    本津幡           1076
## 14 内灘町役場     浅野川線  内灘             2796
## 15 志賀町役場     七尾線    千路            10262
## 16 宝達志水町役場 七尾線    南羽咋           2477
## 17 中能登町役場   七尾線    良川             1878
## 18 穴水町役場     七尾線    穴水             1161
## 19 能登町役場     七尾線    穴水            29673

輪島市役所や珠洲市役所からの最寄り駅は穴水駅ということになってしまいます。

また、意外なことに、能美市役所から徒歩ルートで最も近い駅は、市内にある能美根上駅ではなく、となりの小松市にある明峰駅でした。

ルートを入れた地図も作成します。

center <- st_centroid(pref)
m <- leaflet() |>
  addTiles() |>
  setView(unlist(center)[1], unlist(center)[2],
          zoom = 9)
for (i in seq_len(n_office)) {
  m <- m |>
    addPolylines(data = route[[i]])
}
mapview::mapshot(m, file = file.path("figures", "route.png"))