iOS/iPhone/iPad/watchOS/tvOS/MacOSX/Android プログラミング, Objective-C, Cocoa, Swiftなど
公共交通の標準データフォーマット General Transit Feed Specification (GTFS) を可視化してみます。
HomebrewでDuckDBをインストール。
$ brew install duckdb
岡山県の宇野バス(宇野自動車)のGTFSをダウンロード。
$ curl -L -o uno-GTFS.zip "https://api-public.odpt.org/api/v4/files/odpt/UnoBus/AllLines.zip?date=20231208"
ダウンロードしたファイルを解凍。
$ unzip uno-GTFS.zip -d uno-GTFS
内容を確認。
$ ls -l uno-GTFS
agency.txt 運行会社情報
calendar.txt 運行日情報
calendar_dates.txt 運行日付情報
fare_attributes.txt 運賃情報
fare_rules.txt 運賃ルール情報
feed_info.txt フィード情報
routes.txt 路線情報
shapes.txt 路線形状情報
stops.txt 停留所情報
stop_times.txt 時刻表情報
translations.txt
trips.txt 便情報
DuckDBを起動。
$ duckdb ViewGTFS.duckdb
v1.1.2 f680b7d08f
Enter ".help" for usage hints.
D
Spartial Spartial Extensionを有効にする。
D INSTALL spatial;
D LOAD spatial;
D
停留所情報と路線形状情報、便情報を取り込む。
D CREATE OR REPLACE TABLE stops AS SELECT * FROM read_csv('uno-GTFS/stops.txt');
D CREATE OR REPLACE TABLE shapes AS SELECT * FROM read_csv('uno-GTFS/shapes.txt');
D CREATE OR REPLACE TABLE trips AS SELECT * FROM read_csv('uno-GTFS/trips.txt');
D
内容を確認。
D SELECT * FROM stops LIMIT 5;
┌─────────┬───────────┬──────────────────────┬───────────┬──────────────────┬──────────────────┬─────────┬────────────────────────────────────────┬───────────────┬───────────────┬────────────────┐
│ stop_id │ stop_code │ stop_name │ stop_desc │ stop_lat │ stop_lon │ zone_id │ stop_url │ location_type │ platform_code │ parent_station │
│ varchar │ varchar │ varchar │ varchar │ double │ double │ varchar │ varchar │ int64 │ int64 │ varchar │
├─────────┼───────────┼──────────────────────┼───────────┼──────────────────┼──────────────────┼─────────┼────────────────────────────────────────┼───────────────┼───────────────┼────────────────┤
│ 2_01 │ │ 岡山駅 │ │ 34.6649511659916 │ 133.918614140014 │ 2_01 │ https://www.unobus.co.jp/bustei/2#2_01 │ 0 │ 11 │ │
│ 2_04 │ │ 岡山駅 │ │ 34.665088 │ 133.918707 │ 2_04 │ https://www.unobus.co.jp/bustei/2#2_04 │ 0 │ 12 │ │
│ 2_11 │ │ 岡山駅 │ │ 34.6656276536051 │ 133.918707018287 │ 2_11 │ https://www.unobus.co.jp/bustei/2#2_11 │ 0 │ 1 │ │
│ 3_03 │ │ 柳川西(北側)東岡山 │ │ 34.665708 │ 133.923902 │ 3_03 │ https://www.unobus.co.jp/bustei/3#3_03 │ 0 │ │ │
│ 4_01 │ │ 岡山駅前・ドレミの街 │ │ 34.665691 │ 133.921284 │ 4_01 │ https://www.unobus.co.jp/bustei/4#4_01 │ 0 │ 6 │ │
└─────────┴───────────┴──────────────────────┴───────────┴──────────────────┴──────────────────┴─────────┴────────────────────────────────────────┴───────────────┴───────────────┴────────────────┘
D SELECT * FROM shapes LIMIT 5;
┌──────────┬──────────────────┬──────────────────┬───────────────────┐
│ shape_id │ shape_pt_lat │ shape_pt_lon │ shape_pt_sequence │
│ int64 │ double │ double │ int64 │
├──────────┼──────────────────┼──────────────────┼───────────────────┤
│ 1041 │ 34.6649511659916 │ 133.918614140014 │ 1 │
│ 1041 │ 34.664688828413 │ 133.918397814614 │ 2 │
│ 1041 │ 34.6647661581233 │ 133.918196648608 │ 3 │
│ 1041 │ 34.6656285584571 │ 133.918808190945 │ 4 │
│ 1041 │ 34.665691 │ 133.921284 │ 5 │
└──────────┴──────────────────┴──────────────────┴───────────────────┘
D SELECT * FROM trips LIMIT 5;
┌────────────────┬────────────┬────────────────────────┬─────────────────────────┬──────────┬─────────────────┬──────────────┬──────────┐
│ route_id │ service_id │ trip_id │ trip_headsign │ block_id │ trip_short_name │ direction_id │ shape_id │
│ varchar │ varchar │ varchar │ varchar │ varchar │ varchar │ varchar │ int64 │
├────────────────┼────────────┼────────────────────────┼─────────────────────────┼──────────┼─────────────────┼──────────────┼──────────┤
│ ネオ瀬戸線_A │ 平日 │ 平日_05時40分_系統1642 │ 瀬戸駅(岡山駅 経由) │ │ │ │ 1642 │
│ 林野線_A │ 平日 │ 平日_06時00分_系統1332 │ 表町BC(新道河本 経由) │ │ │ │ 1332 │
│ 林野線_A │ 平日 │ 平日_06時00分_系統1182 │ 表町BC(新道河本 経由) │ │ │ │ 1182 │
│ ネオポリス線_A │ 平日 │ 平日_06時05分_系統1282 │ 表町BC(下市・中 経由) │ │ │ │ 1282 │
│ ネオポリス線_A │ 平日 │ 平日_06時10分_系統1632 │ 表町BC(下市・西 経由) │ │ │ │ 1632 │
└────────────────┴────────────┴────────────────────────┴─────────────────────────┴──────────┴─────────────────┴──────────────┴──────────┘
D
Kepler.gl向けのデータに変換する。
D COPY (
SELECT * FROM stops
) TO 'uno-GTFS_stops.csv' WITH (FORMAT CSV, HEADER);
D COPY (
SELECT * FROM trips
LEFT JOIN (
SELECT
shape_id,
{
"type": 'LineString',
"coordinates": list([shape_pt_lon,shape_pt_lat])
}::JSON AS "geometry"
FROM shapes GROUP BY shape_id
) AS shapes ON trips.shape_id = shapes.shape_id
) TO 'uno-GTFS_trips.csv' WITH (FORMAT CSV, HEADER);
D
https://kepler.gl/demo/ をWebブラウザで開く。
先ほど出力した uno-GTFS_stops.csv と uno-GTFS_trips.csvをDrag&Dropする。
停留所と路線形状が表示されましたが、地図が表示されていませんね。