Skip to content

Instantly share code, notes, and snippets.

@deton
Last active October 26, 2025 07:57
Show Gist options
  • Save deton/3508b7a291b81d1f9bbedad8ea26dccf to your computer and use it in GitHub Desktop.
Save deton/3508b7a291b81d1f9bbedad8ea26dccf to your computer and use it in GitHub Desktop.
make_gtfsを使って仮のGTFS(時刻表)を生成する(神戸電鉄 有馬線の一部)

make_gtfsを使って仮のGTFS(時刻表)を生成する(神戸電鉄 有馬線の一部)

実際の発車時刻とは異なるが、1時間あたりの本数はなるべく合わせた時刻表。

駅の緯度経度や線路(ルート)形状の情報は、 国土数値情報 鉄道データを利用。

指定したbounding box内の駅のみを対象とする。

(withinbbox.pyとmidpoint.pyは https://gist.github.com/deton/ac80db5e4b464169a764b524d3377c96 と同じ)

shapes.geojson

uv run python withinbbox.py 134.963436,34.623885,135.170288,34.738791 N02-24_RailroadSection.shp
grep -e '有馬線' -e '神戸高速線.*神戸電鉄' N02-24_RailroadSection.134.963436,34.623885,135.170288,34.738791.geojson \
| sed -e 's/"N02_003": "[^"]*", //' | sort -u \
| sed -e '1i {"type":"FeatureCollection","features":[' -e '$s/,$/]}/' >arima.geojson
uv run python linemerge.py arima.geojson
sed -e '1i {"type":"Feature","properties":{"shape_id":"shp1"},"geometry":' -e '$a }' arima.linemerge.geojson >shapes.geojson

N02_003の値のみ異なる(有馬線と神戸高速線)、 同じ緯度経度のLineStringは1つだけにして、 1本のLineStringにマージしてshapes.geojsonを作成。

service_windows.csvとfrequencies.csv

NAVITIMEで駅の時刻表を見て(列車種別で絞り込みしつつ)、 各曜日・各時間帯・上り/下りの本数を調べて記入。

1時間あたりの本数が同じ時間が続く場合は1行にまとめられる。

(とりあえず、列車種別:普通、平日を対象に手作業)

stops.csv

駅のgeometryとして、midpointの緯度経度に変換

uv run python withinbbox.py 134.963436,34.623885,135.170288,34.738791 N02-24_Station.shp
uv run python midpoint.py N02-24_Station.134.963436,34.623885,135.170288,34.738791.geojson

とりあえず、重複するstop_idや駅名は手で削除。

grep -e '有馬線' -e '神戸高速線.*神戸電鉄' N02-24_Station.134.963436,34.623885,135.170288,34.738791.midpoint.geojson | sed -e 's/,$//' > stops.ndjson
vim stops.ndjson

(参考:同名駅のグループに属すものを検索。 緯度経度が同じなら、N02_005gの値をstop_idとして使う。)

grep -v 'N02_005c": "\([^"]*\)", "N02_005g": "\1"' N02-24_Station.134.963436,34.623885,135.170288,34.738791.midpoint.geojson
echo 'stop_id,stop_name,stop_lon,stop_lat' > stops.csv
jq -r '[.properties.N02_005c,.properties.N02_005,.geometry.coordinates[0],.geometry.coordinates[1]]|@csv' stops.ndjson >>stops.csv

make_gtfsを実行

uv run make_gtfs data/shintetsu_arima_local output/shintetsu_arima_local.zip

TimestampedGeoJsonに変換して表示してみる

https://gist.github.com/deton/8c4bd41faa4060dfa4a68066a5403be3#file-gtfsshape2timestampedgeojson-ipynb

https://deton.github.io/HeatMapWithTime/IconPositionWithTime.html?tripWidth=6&iconScale=0.7&zoom=12&pointRadius=2&lineWidth=1&latlon=34.67824,135.06856&jsonurl=https://gist.githubusercontent.com/deton/3508b7a291b81d1f9bbedad8ea26dccf/raw/75ed4860b79027f0f1407610421f87fc1f08abeb/zzGtfsTimestamped.geojson

route_short_name route_long_name route_type shape_id service_window_id frequency direction
ld 神戸電鉄有馬線 普通下り 2 shp1 wdd0506 4 1
ld 神戸電鉄有馬線 普通下り 2 shp1 wdd0607 5 1
ld 神戸電鉄有馬線 普通下り 2 shp1 wdd0708 8 1
ld 神戸電鉄有馬線 普通下り 2 shp1 wdd0809 7 1
ld 神戸電鉄有馬線 普通下り 2 shp1 wdd0917 4 1
ld 神戸電鉄有馬線 普通下り 2 shp1 wdd1719 5 1
ld 神戸電鉄有馬線 普通下り 2 shp1 wdd1923 4 1
ld 神戸電鉄有馬線 普通下り 2 shp1 wdd2324 3 1
lu 神戸電鉄有馬線 普通上り 2 shp1 wdu0506 5 0
lu 神戸電鉄有馬線 普通上り 2 shp1 wdu0607 4 0
lu 神戸電鉄有馬線 普通上り 2 shp1 wdu0708 7 0
lu 神戸電鉄有馬線 普通上り 2 shp1 wdu0809 6 0
lu 神戸電鉄有馬線 普通上り 2 shp1 wdu0917 4 0
lu 神戸電鉄有馬線 普通上り 2 shp1 wdu1718 5 0
lu 神戸電鉄有馬線 普通上り 2 shp1 wdu1819 6 0
lu 神戸電鉄有馬線 普通上り 2 shp1 wdu1920 5 0
lu 神戸電鉄有馬線 普通上り 2 shp1 wdu2024 4 0
import sys
import shapely
infile = sys.argv[1]
outfile = infile.replace('.geojson', '.linemerge.geojson')
with open(infile, encoding='utf-8') as f:
fc = shapely.from_geojson(f.read())
with open(outfile, 'w', encoding='utf-8') as f:
f.write(shapely.to_geojson(shapely.line_merge(fc)))
agency_name agency_url agency_timezone start_date end_date
神戸電鉄 https://www.shintetsu.co.jp Asia/Tokyo 20250101 20260101
service_window_id start_time end_time monday tuesday wednesday thursday friday saturday sunday
wdd0506 05:00:00 06:00:00 1 1 1 1 1 0 0
wdd0607 06:00:00 07:00:00 1 1 1 1 1 0 0
wdd0708 07:00:00 08:00:00 1 1 1 1 1 0 0
wdd0809 08:00:00 09:00:00 1 1 1 1 1 0 0
wdd0917 09:00:00 17:00:00 1 1 1 1 1 0 0
wdd1719 17:00:00 19:00:00 1 1 1 1 1 0 0
wdd1923 19:00:00 23:00:00 1 1 1 1 1 0 0
wdd2324 23:00:00 23:59:59 1 1 1 1 1 0 0
wdu0506 05:00:00 06:00:00 1 1 1 1 1 0 0
wdu0607 06:00:00 07:00:00 1 1 1 1 1 0 0
wdu0708 07:00:00 08:00:00 1 1 1 1 1 0 0
wdu0809 08:00:00 09:00:00 1 1 1 1 1 0 0
wdu0917 09:00:00 17:00:00 1 1 1 1 1 0 0
wdu1718 17:00:00 18:00:00 1 1 1 1 1 0 0
wdu1819 18:00:00 19:00:00 1 1 1 1 1 0 0
wdu1920 19:00:00 20:00:00 1 1 1 1 1 0 0
wdu2024 20:00:00 23:59:59 1 1 1 1 1 0 0
Display the source blob
Display the rendered blob
Raw
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
stop_id stop_name stop_lon stop_lat
007240 新開地 135.168970000874225 34.676620000281176
007221 湊川 135.166115001210528 34.679280000437686
007200 長田 135.149549999831436 34.681635000016762
007127 鵯越 135.142616410653289 34.692841880952678
006958 鈴蘭台 135.145880000275213 34.723635000027329
007169 丸山 135.143960000863643 34.685915000503826
Display the source blob
Display the rendered blob
Raw
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment