はじめに
https://gdal.org/drivers/vector/gtfs.html
GDAL/OGRがGTFSをサポートした。2023年5月リリース予定のv3.7から利用できるようになる。
リポジトリのupstreamには既にコードが反映されているので、どんな挙動か試してみる。
なお使ったのはおなじみ拓殖バスさんのGTFSデータ。
ogrinfo
apps/ogrinfo GTFS_regular_line.zip
INFO: Open of `GTFS_regular_line.zip'
using driver `GTFS' successful.
1: agency (None)
2: calendar (None)
3: calendar_dates (None)
4: fare_attributes (None)
5: fare_rules (None)
6: feed_info (None)
7: routes (None)
8: shapes (Point)
9: stops (Point)
10: stop_times (None)
11: translations (None)
12: trips (Line String)
13: shapes_geom (Line String)
v3.7ではogrinfoが-jsonオプションをサポートするのでやってみる。なるほど、layerという単位で情報を出力出来るのは便利そう。
apps/ogrinfo GTFS_regular_line.zip -json
{
"description": "GTFS_regular_line.zip",
"driverShortName": "GTFS",
"driverLongName": "General Transit Feed Specification",
"layers": [
//行数多すぎるので一部抜粋
{
"name": "stops",
"metadata": {},
"geometryFields": [
{
"name": "",
"type": "Point",
"nullable": true,
"extent": [
142.82196521759,
42.891557,
143.295466714286,
43.4601089766615
],
"coordinateSystem": null
}
],
"featureCount": 906,
"fields": [
{
"name": "stop_id",
"type": "String",
"nullable": true,
"uniqueConstraint": false
},
{
"name": "stop_code",
"type": "String",
"nullable": true,
"uniqueConstraint": false
},
{
"name": "stop_name",
"type": "String",
"nullable": true,
"uniqueConstraint": false
},
{
"name": "stop_desc",
"type": "String",
"nullable": true,
"uniqueConstraint": false
},
{
"name": "stop_lat",
"type": "Real",
"nullable": true,
"uniqueConstraint": false
},
{
"name": "stop_lon",
"type": "Real",
"nullable": true,
"uniqueConstraint": false
},
{
"name": "zone_id",
"type": "String",
"nullable": true,
"uniqueConstraint": false
},
{
"name": "stop_url",
"type": "String",
"nullable": true,
"uniqueConstraint": false
},
{
"name": "location_type",
"type": "Integer",
"nullable": true,
"uniqueConstraint": false
},
{
"name": "platform_code",
"type": "String",
"nullable": true,
"uniqueConstraint": false
},
{
"name": "parent_station",
"type": "String",
"nullable": true,
"uniqueConstraint": false
}
]
},
],
"metadata": {},
"domains": {},
"relationships": {}
}
ogr2ogr
ここからが本番。
apps/ogr2ogr output GTFS_regular_line.zip -lco ENCODING=UTF-8
とすると、outputフォルダ内に4種類のシェープファイルが生成される。
ls output
agency.dbf feed_info.dbf shapes_geom.dbf stops.shp trips.shx
calendar.dbf routes.dbf shapes_geom.shp stops.shx
calendar_dates.dbf shapes.dbf shapes_geom.shx translations.dbf
fare_attributes.dbf shapes.shp stop_times.dbf trips.dbf
fare_rules.dbf shapes.shx stops.dbf trips.shp
出力をディレクトリにすると、レイヤー別にシェープファイルが生成されるのはGTFSに限らない以前からある挙動。
なお、GeoPackageなどの形式で出力しようとするとエラーが発生した。まだリリース前の機能なので、単にバグだと思われる。
apps/ogr2ogr output.gpkg GTFS_regular_line.zip stops
Warning 3: Cannot find tms_NZTM2000.json (GDAL_DATA is not defined)
Segmentation fault: 11
上記のシェープファイルをQGISで表示してみる。
- stopsは単に停留所の位置と属性なので、わかりやすいデータ。
- tripsは、trip単位でラインが生成されるので、同じルートで複数のtripがあると、同じラインが重なることになる。また、このラインはstop同士を直線で繋いだ線分。
- shapesは座標で、shapes_geomはそれらを繋いだライン、意味のある属性はない。
終わりに
GDALがサポートしたので、じきにQGISにも反映されるでしょう。QGISがデフォルトでGTFSを読めていたら、GTFS-GOというプラグインを開発することはありませんでした。ようやく時代が追いついてきたな…!
基本機能が充実していくのは喜ばしいことですし、GTFS-GOもGDALの実装を参考に改善していくことができます(頻度集計機能もあるし)。