GTFSは公共交通機関の時刻表や地理情報を公開するために標準化されたデータ形式です。
日本でもすでに複数の交通機関がGTFSフィードを公開していて、乗換案内などのサービスに利用できるようになっています。
今回はそのGTFSで登録されたデータを取得する簡単なSPARQLクエリーを紹介します。
まずは、バスの路線名とその路線を一意に示すIRIを取得するクエリーです。
下記クエリーを SPARQLコンソールに入力して検索を行うと、routeにIRIが、route_nameに路線名が入った結果が返ってきます。
PREFIX odp: <http://odp.jig.jp/odp/1.0#> PREFIX gtfs: <http://vocab.gtfs.org/terms#> SELECT * { ?route a gtfs:Route ; odp:refArea <http://statdb.nstac.go.jp/lod/sac/C18207> ; gtfs:routeType gtfs:Bus ; gtfs:longName ?route_name . } ORDER BY ?route LIMIT 100
次に、上のクエリーで取得した路線IRIから、路線の各便の情報を取得するクエリーです。
<http://odp.jig.jp/jp/fukui/sabae/bus_route/5> が路線IRIになります。
tripが便IRI、trip_nameが便名、headsignが行き先表示になります。
PREFIX gtfs: <http://vocab.gtfs.org/terms#> SELECT * { ?trip a gtfs:Trip ; gtfs:route <http://odp.jig.jp/jp/fukui/sabae/bus_route/5> ; gtfs:service ?service ; gtfs:shortName ?trip_name ; gtfs:headsign ?headsign . } ORDER BY ?trip ?service LIMIT 100
上記の便情報を取得するクエリーを実行してもらうと分かるのですが、同じ便名の便が複数返ってきます。
これは日によって運行するルートや時間が変わる場合で、実際にその便が運行する日程の情報は上記クエリーでserviceとして取得されたIRIに登録されています。
次はその情報を取得するクエリーです。
日程の情報はgtfs:CalendarRuleに曜日毎のデータが、gtfs:CalendarDateRuleに特別に運行・運休する日のデータが登録されています。
まず、gtfs:CalendarRuleを取得して曜日ごとの運行・運休を取得します。それぞれの曜日でtrueなら運行、falseなら運休です。
PREFIX gtfs: <http://vocab.gtfs.org/terms#> SELECT * { <http://odp.jig.jp/jp/fukui/sabae/bus_service/3> gtfs:serviceRule [ a gtfs:CalendarRule ; gtfs:monday ?monday ; gtfs:tuesday ?tuesday ; gtfs:wednesday ?wednesday ; gtfs:thursday ?thursday ; gtfs:friday ?friday ; gtfs:saturday ?saturday ; gtfs:sunday ?sunday ] . } LIMIT 100
次はgtfs:CalendarDateRuleを取得して、特別に運行・運休する日を取得します。
ここで取得された日付は上記の曜日の情報よりも優先されます。
additionがtrueならdateの日付が運行、falseなら運休になります。
PREFIX gtfs: <http://vocab.gtfs.org/terms#> PREFIX dcterms: <http://purl.org/dc/terms/> SELECT * { <http://odp.jig.jp/jp/fukui/sabae/bus_service/3> gtfs:serviceRule [ a gtfs:CalendarDateRule ; dcterms:date ?date ; gtfs:dateAddition ?addition ] . } LIMIT 100
もし、2017/09/06(水)に運行する便だけ取得するなら、下記のようなクエリーになるでしょう。
PREFIX gtfs: <http://vocab.gtfs.org/terms#> PREFIX dcterms: <http://purl.org/dc/terms/> PREFIX xsd: <http://www.w3.org/2001/XMLSchema#> SELECT * { ?trip a gtfs:Trip ; gtfs:route <http://odp.jig.jp/jp/fukui/sabae/bus_route/5> ; gtfs:service ?service ; gtfs:shortName ?trip_name ; gtfs:headsign ?headsign . ?service gtfs:serviceRule [ a gtfs:CalendarRule ; gtfs:wednesday ?day_of_week ] . OPTIONAL { ?service gtfs:serviceRule [ a gtfs:CalendarDateRule ; dcterms:date "2017-09-06"^^xsd:date ; gtfs:dateAddition ?addition ] } FILTER ( BOUND(?addition) && ?addtion || !BOUND(?addition) && ?day_of_week ) } ORDER BY ?trip ?service LIMIT 100
最後に時刻表の情報を取得してみます。
上記のクエリーで取得した便IRIを指定して、その便の各バス停名(stop_name)と到着時刻(arrival_time)と出発時刻(departure_time)を取得しています。
乗車タイプ(pickup_type)と降車タイプ(drop_off_type)はgtfs:Regularなら利用可能、gtfs:NotAvailableなら利用不能、gtfs:MustPhoneなら事前に電話連絡が必要で、gtfs:MustCoordinateWithDriverなら事前に運転手に連絡が必要になります。
arrival_timeとdeparture_timeはxsd:durationで登録されていますが、これは日付を跨いだ場合のためです。(xsd:timeは00:00から24:00までしか表現できません。)
PREFIX gtfs: <http://vocab.gtfs.org/terms#> PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#> SELECT * { ?stop_time a gtfs:StopTime ; gtfs:trip <http://odp.jig.jp/jp/fukui/sabae/bus_trip/29> ; gtfs:stop [ rdfs:label ?stop_name ] ; gtfs:stopSequence ?order ; gtfs:arrivalTime ?arrival_time ; gtfs:departureTime ?departure_time ; gtfs:pickupType ?pickup_type ; gtfs:dropOffType ?drop_off_type . } ORDER BY ?order LIMIT 100
GTFS関連の語彙についてはLinked GTFS specificationにまとめられているので、こちらも参考にしてみてください。