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")RのosrmパッケージからOSRMを使って、石川県の各市役所・町役場から最も近い駅を検索してみました。
準備
OSRMサーバーをDockerで立ち上げるところは、前回の記事と同じです。
sf, osrm, tibble, leafletの各パッケージを読み込み、OSRMの接続先を設定します。
データ
国土数値情報から以下のデータをダウンロードしました。いずれもライセンスは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 金沢市役所 七尾線 中津幡 0
## 2 七尾市役所 七尾線 和倉温泉 0
## 3 小松市役所 七尾線 中津幡 0
## 4 輪島市役所 七尾線 和倉温泉 0
## 5 珠洲市役所 七尾線 和倉温泉 0
## 6 加賀市役所 七尾線 中津幡 0
## 7 羽咋市役所 七尾線 能登部 0
## 8 かほく市役所 七尾線 能登部 0
## 9 白山市役所 七尾線 中津幡 0
## 10 能美市役所 七尾線 中津幡 0
## 11 野々市市役所 七尾線 中津幡 0
## 12 川北町役場 七尾線 中津幡 0
## 13 津幡町役場 七尾線 中津幡 0
## 14 内灘町役場 七尾線 中津幡 0
## 15 志賀町役場 七尾線 能登部 0
## 16 宝達志水町役場 七尾線 能登部 0
## 17 中能登町役場 七尾線 能登部 0
## 18 穴水町役場 七尾線 和倉温泉 0
## 19 能登町役場 七尾線 和倉温泉 0輪島市役所や珠洲市役所からの最寄り駅は穴水駅ということになってしまいます。
また、意外なことに、能美市役所から徒歩ルートで最も近い駅は、市内にある能美根上駅ではなく、となりの小松市にある明峰駅でした。
ルートを入れた地図も作成します。
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"))
【追加】QGISでの描画
結果のルートをGeoJSONで出力して、QGISで読み込み、地理院タイル(白地図)と国土数値情報/鉄道路線に重ねて表示しました。
