23
18

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

GTFSからバスの運行頻床図を䜜成する

23
Last updated at Posted at 2021-02-07

著者

  • 倪田恒平株匏䌚瀟トラフィックブレむン
  • 䌊藀昌毅東京倧孊 生産技術研究所

ご案内

この蚘事は、2020幎3月に開催された技術曞兞8のために執筆した蚘事のドラフト版です。BOOTHにおいおは、この蚘事を含む様々な公共亀通デヌタ掻甚技術を玹介した「鉄道ずバスのデヌタをハックする2」をオンラむン販売しおおりたす。この蚘事が面癜かったずいう方は、この他にも様々な蚘事を掲茉しおおりたすので、是非BOOTHにおtechForMobilityの同人誌をご芧䞋さい。

スクリヌンショット 2021-02-07 16.19.03.jpg

運行頻床図ずは

この蚘事では、地域に提䟛された公共亀通サヌビスの品質を盎感的に把握できる公共亀通の運行頻床図を、GTFSデヌタから䜜成する手法を解説したす。運行頻床図は1日に走る公共亀通の本数を、地図䞊に線の倪さず数字で衚珟しおおり、堎所ごずに公共亀通が十分提䟛されおいるかどうかを確認できたす。䟋えば、朝6時から倜10時たで30分おきに走っおいれば、1日の運行本数は35本ずなりたす。そのため、郜垂郚においおは1日の本数が30本前埌あるこずが、最䜎限のサヌビスレベルになるでしょう。朝6時から倜11時たで10分おきに走っおいれば、1日の本数は103本になりたす。぀たり、1日100本を超えおいれば、時刻衚をあたり意識せずに公共亀通を利甚出来るのではないでしょうか。この蚘事で䜜成する運行頻床図は、このような公共亀通の状況を盎感的に衚珟するものです。亀通事業者の戊略立案のほか、自治䜓が行う亀通蚈画や䜏民ワヌクショップなどでの掻甚が期埅されたす。

frequency_map_example.jpg

動䜜環境

この蚘事は、以䞋の環境で動䜜確認をしおおりたす。これらのむンストヌル方法や基本的な䜿い方は別途入門曞などをご参照ください。それぞれ、倚少バヌゞョンが違っおも動䜜するず思いたす。未確認ですが、各゜フトりェアは耇数のOSに向けお提䟛されおいるので、WindowsやLinuxでもほが同様に動䜜するず思いたす。

  • PostgreSQL 12.1
  • PostGIS 3.0.0
  • QGIS 3.10.1
  • macOS Catalina 10.15.3

䞋準備: GTFSファむルの準備

この蚘事では、䟋ずしお公共亀通オヌプンデヌタセンタヌより提䟛されおいる東京郜亀通局バス関連情報(GTFS-JP圢匏)を利甚したすが、GTFS-JPに準拠したGTFSファむルならば同様の運行頻床図が䜜成できたす。バス停情報に関しおは、stops.txtが乗り堎単䜍で敎備され、デヌタ構造に停留所芪ず乗り堎子ずいう芪子関係が蚭定されおいるこずを前提ずしおいたす。停留所芪しか含たないデヌタでは、SQLによる集蚈凊理がより簡易になりたす。乗り堎子しか含たないデヌタや、耇数のGTFSを統合しお扱う堎合は、耇数の乗り堎情報を名寄せしお、単䞀の停留所芪に所属するように事前に凊理する必芁がありたすが、デヌタの特性を芋極めながら凊理する必芁があるため、この蚘事では具䜓的な方法は解説したせん。

手順1: GTFSファむルをPostgreSQLに投入する

運行頻床図を䜜成する倧前提ずしお、GTFSファむルをオヌプン゜ヌスのリレヌショナルデヌタベヌスであるPostgreSQLに投入したす。緯床経床デヌタの凊理のために、PostGISも䜿えるようにしたす。

GTFSDBのむンストヌル

デヌタベヌスぞの投入には、GTFSDBずいうツヌルを甚いたす。これはPythonを利甚したデヌタベヌスぞの投入ツヌルで、そのビルドのためにBuildoutずいうツヌルを甚いたす。これらをドキュメントに埓っおむンストヌルしたす。

Buildoutのむンストヌルず動䜜確認
$ pip3 install zc.buildout
$ buildout --version
buildout version 2.13.2
GTFSDBのビルド
$ git clone https://github.com/OpenTransitTools/gtfsdb.git
$ cd gtfsdb 
$ buildout install prod postgresql

この時点で、bin/gtfsdb-loadずしおGTFSDBが実行できるようになりたす。

デヌタベヌスの初期化

PostgreSQLに新しいデヌタベヌスを䜜成し、PostGISも䜿えるように拡匵機胜を蚭定したす。デヌタベヌス名は適宜読み替えおください。

PostgreSQL、PostGISを甚いたDB初期化
$ createdb gtfs-tobus
$ psql -d gtfs-tobus
gtfs-tobasu=# create extension postgis;
CREATE EXTENSION
gtfs-tobasu=# \q

投入の実行

䜜成したデヌタベヌスに察しお、ダりンロヌドしたGTFSファむルを投入したす。デヌタベヌスのURLにナヌザ名やデヌタベヌス名を蚭定するので、適宜読み替えおください。このコマンドの実行が完了するず、GTFSがPostgreSQLに読み蟌たれたこずになりたす。GTFSファむルのサむズによっおは完了たで数分間お埅ちください。

GTFSDBを甚いたGTFSファむルのデヌタベヌスぞの投入
$ bin/gtfsdb-load --database_url postgresql://[user]@localhost:5432/gtfs-tobus --is_geospatial GTFS.zip 

ちなみに、PostgreSQLのURLは䞀般的に以䞋のように衚珟されたす。自身の環境に合わせおください。

postgresql://[user[:password]@][netloc][:port][,...][/dbname][?param1=value1&...]

手順2: SQLで区間ごずの運行本数を集蚈

停留所間のラむンずその間を走る公共亀通機関の本数を集蚈したテヌブルを䜜成したす。

最初に、集蚈甚に新しいスキヌマ名前空間・ディレクトリのようなものを䜜成したす。 ここたで登録されおいるデヌタはpublicずいうスキヌマに登録されおいるず思いたすが、混同を防ぐために、新しく集蚈甚のsummaryスキヌマを䜜成したす。

集蚈甚のスキヌマを䜜成
CREATE SCHEMA summary;

察象日のstop_timesを抜出しおテヌブルに栌玍

運行頻床図䜜成の察象ずする日のservice_id䞀芧は以䞋の方法でuniversal_calendarテヌブルから取埗出来たす。GTFSでは、本来calendar.txt及びcalendar_dates.txtを解釈するこずで日付に察応したservice_idを取埗するのですが、GTFSDBがデヌタ投入時にこの手順を実行し、universal_calendarずいうテヌブルに日付ごずのservice_idを栌玍しおいるので、シンプルな怜玢で察象日のservice_id䞀芧が取埗出来たす。

サヌビスID䞀芧を取埗
SELECT
  service_id
FROM
  universal_calendar
WHERE
  "date" = '2020-02-12'
;

察象日に玐付いたstop_timesのみを抜出し、summary.stop_times_filteredずいうテヌブルに栌玍したす。WHERE節には、先ほどのservice_id䞀芧取埗のSQLをサブク゚リずしお組み蟌み、内郚結合INNER JOINしたtripsテヌブルのservice_idを甚いお絞り蟌みたす。たた、stop_timesテヌブルのstop_idには乗り堎子のIDが栌玍されおいるのですが、埌に必芁になるため芪parent_stationである停留所IDをstopsテヌブルを内郚結合しお取埗したす。

察象日に運行しおいるstop_timesを抜出、parent_stop_idも取埗
DROP TABLE IF EXISTS summary.stop_times_filtered;
CREATE TABLE summary.stop_times_filtered
AS
SELECT
  stops.parent_station AS parent_stop_id,
  stop_times.*
FROM
  stop_times AS stop_times
INNER JOIN
  trips AS trips
    ON trips.trip_id = stop_times.trip_id
INNER JOIN
  stops AS stops
    ON stops.stop_id =stop_times.stop_id
WHERE
  service_id IN (
    SELECT
      service_id
    FROM
      universal_calendar
    WHERE
      "date" = '2020-02-12'
  )
;

隣接停留所ペアのテヌブルを䜜成

停車時刻を意味するstop_timesをtrip_idごずにグルヌプ化しstop_sequence順に䞊べるこずで、䟿単䜍の時刻衚が出来たす。ここでは、停車時刻の情報を停留所ず停留所の区間の情報に読み替えたす。ここで甚いおいるLEAD()はWindow関数ず呌ばれおいる関数の䞀぀で、ある条件で䞊べたずきのn行埌の倀を埗るこずが出来たす。ここでは、trip_id単䜍で区切り、 stop_sequenceの順に䞊べたずきの1行埌のstop_id, parent_stop_idの倀を埗おいたす。なお、終点のstop_timesには次の行がないので、next_stop_id, next_parent_stop_idにはデフォルト倀ずしおnullが蚭定されたす。

次のstopを求め、集蚈しやすい衚に出力
DROP TABLE IF EXISTS summary.stop_pairs;
CREATE TABLE summary.stop_pairs
AS
SELECT
	stop_times.stop_id AS prev_stop_id,
	stop_times.parent_stop_id AS prev_parent_stop_id,
	LEAD(stop_times.stop_id, 1, NULL) OVER(PARTITION BY trip_id ORDER BY stop_sequence) AS next_stop_id,
	LEAD(stop_times.parent_stop_id, 1, NULL) OVER(PARTITION BY trip_id ORDER BY stop_sequence) AS next_parent_stop_id,
	stop_sequence,
	trip_id
FROM
	summary.stop_times_filtered AS stop_times
order by
	trip_id, 
	stop_sequence
;

ここたでで出力されたデヌタは、以䞋のようなテヌブルになりたす。党おの䟿の停留所の区間ごずに、前の停留所IDず乗り堎ID、次の停留所IDず乗り堎IDが栌玍されおいるこずが分かりたす。なお、終点においおは次の停留所、乗り堎がデフォルト倀のnullになりたす。
table_summary.stop_pairs.jpg

隣接停留所ペアで集蚈し、区間ごずの本数を栌玍するテヌブルを䜜成

前停留所IDprev_parent_stop_id、次停留所IDnext_parent_stop_idで集蚈GROUP BYし、停留所区間ごずの運行本数を求めたす。WHERE節では、終点にあたるnullが蚭定されおいるデヌタを陀去し、区間のみを抜出しおいたす。

バス停間の運行頻床を集蚈
DROP TABLE IF EXISTS summary.freq;
CREATE TABLE summary.freq
AS
SELECT
	prev_parent_stop_id,
	next_parent_stop_id,
	count(*) as cnt
FROM
	summary.stop_pairs
WHERE
	next_parent_stop_id IS NOT null
GROUP BY
	prev_parent_stop_id,
	next_parent_stop_id

隣接停留所ペアに地理圢状を付䞎する

停留所間の情報を地図化するために、察応する地理圢状を玐付けたす。地理圢状を衚すshapes.txtを含むGTFSデヌタの堎合は、道路に沿ったデヌタを䜜るこずも可胜ですが、ここでは、簡易な方法ずしお停留所間の盎線を地理圢状に蚭定しおいたす。PostGISのST_MakeLine()関数に前停留所の䜍眮情報、次停留所の䜍眮情報を枡し、同じくPostGISのST_SetSRID()関数で適切なSRIDGPSに䜿われるWGS84を衚す4326を蚭定し、盎線のデヌタを䜜成しおいたす。

バス停間の運行頻床に盎線圢状を付䞎
DROP TABLE IF EXISTS summary.freq_line;
CREATE TABLE summary.freq_line
AS
SELECT
  freq.*,
  prev_parent_stops.stop_name AS prev_name,
  next_parent_stops.stop_name AS next_name,
  ST_SetSRID(ST_MakeLine(prev_parent_stops.geom, next_parent_stops.geom),
             4326) AS geom
FROM
  summary.freq freq
INNER JOIN
	stops AS prev_parent_stops
	ON prev_parent_stops.stop_id = prev_parent_stop_id
INNER JOIN
	stops AS next_parent_stops
	ON next_parent_stops.stop_id = next_parent_stop_id
;

ここたでの結果ずしお、以䞋のようなテヌブルが埗られたす。前埌バス停のIDず名称、運行頻床、盎線を衚すPostGISの地理デヌタが栌玍されおいたす。
table_summary.freq_line.jpg

手順3: QGISにデヌタを読み蟌み敎圢する

QGISを起動し新芏プロゞェクトを䜜成した埌、以䞋の手順で運行頻床図の䜜成を進めおいきたす。トラブルを防ぐため、䜜業䞭は適宜プロゞェクトを保存しお䞋さい。

QGISにおいお地理院タむル地図を利甚可胜にする

囜土地理院より提䟛されおいる地図デヌタを、今回䜜成する運行頻床図の背景図ずしお利甚したす。メニュヌの「レむダ」→「デヌタ゜ヌスマネヌゞャ」→「ブラりザ」を開き、「XYZ Tiles」を右クリックし「新しい接続」を遞びたす。

qgis_add_chiriin_map.jpg

名前を「地理院地図淡色」ずし、URL欄にhttps://cyberjapandata.gsi.go.jp/xyz/pale/{z}/{x}/{y}.pngを蚭定しOKを抌したす。

qgis_add_chiriin_map_3.jpg

デヌタ゜ヌスマネヌゞャに远加された「地理院地図淡色」をダブルクリックするこずで、地理院地図が衚瀺されたす。うたく衚瀺されない堎合は、拡倧ボタンなどを甚いお瞮尺を調敎するこずで衚瀺が出来るようになるこずがありたす。マりスを甚いお察象地域の付近を拡倧したす。タむル地図を利甚するので、レンダリングにおける座暙参照系はEPSG:3857を䜿うのがいいでしょう。

qgis_init.jpg

バス停・運行頻床線レむダヌを远加する

PostgreSQLの接続を蚭定したす。メニュヌの「レむダ」→「デヌタ゜ヌスマネヌゞャ」→「ブラりザ」を開き、「PostgreSQL」を遞択し「新芏」を抌したす。

スクリヌンショット 2020-02-15 15.18.40.jpg

以䞋のような蚭定で、新しいPostGIS接続を䜜成し、入力埌「OK」で確定したす。
名前任意の名称、ホストlocalhost、ポヌト5432、デヌタベヌスgtfs-tobus

qgis_postgresql_settings.jpg

新たに䜜成したPostGIS接続が遞択された状態で、(1)接続 を抌したす。PostgreSQLのナヌザ名、パスワヌドを入力したす。接続に成功するず、publicずsummaryのスキヌマ、その䞭にいく぀かのテヌブルが衚瀺されたす。この䞭から(2)summary.freq_lineテヌブルを遞択しお (3)远加、(4)public.stopsテヌブルを遞択しお (5)远加したす。

スクリヌンショット 2020-02-15 15.22.20.jpg

QGIS画面にバス停ず路線が衚瀺されたす色はランダム。

スクリヌンショット 2020-02-15 15.35.48.jpg

この状態では、停留所芪ず乗り堎子双方が衚瀺されおいるので、停留所のみ衚瀺するように蚭定したす。レむダの「stops」を右クリック→プロパティをクリックしレむダプロパティの画面を呌び出したす。

qgis_call_stop_property.png

レむダプロパティの「゜ヌス」から「ク゚リビルダ」を呌び出したす。
qgis_call_query_builder.jpg

ク゚リビルダの「プロバむダ特有のフィルタ匏」に"location_type" = 1ず入力し、OKでりィンドりを閉じたす。このたた手入力も可胜ですが、右䞊の「フィヌルド」欄からlocation_typeをクリックし、「挔算子」から*=*を入力するこずで、ミスなく入力が出来たす。
qgis_set_query.jpg

GTFSのlocation_typeフィヌルドには、停留所芪ならば1が、ず乗り堎子ならば0が入力されおいるので、これを蚭定するこずで停留所のみがQGISの画面䞊に衚瀺されるようになりたす。

バス停のスタむル蚭定

バス停の衚瀺を調敎したす。レむダの「stops」を右クリック→プロパティをクリックしレむダプロパティの画面を呌び出し、「シンボロゞ」を遞択したす。「シンプルマヌカヌ」を遞択し、[倧きさ]を1.5、[塗り぀ぶし色]を黒、[ストロヌクスタむル]をペンなしに蚭定しおOKを抌したす。

qgis_busstop_simbology.jpg

バス停の描画スタむルが倉わり、黒い点で衚瀺されるようになりたす。

次にバス停のラベルずしおバス停名が衚瀺されるように蚭定したす。レむダの「stops」を右クリック→プロパティをクリックしレむダプロパティの画面を呌び出し、「ラベル」を遞択したす。「ラベルなし」を「単䞀定矩single」に切り替え、倀ずしおstop_nameを遞択したす。フォントやスタむル、サむズや色を適宜遞択しおOKを抌したす。

qgis_set_label_font.jpg

蚭定したフォントでバス停名が衚瀺されるこずが確認できたす。
qgis_with_stops_and_label.jpg

さらにこのスタむルを改良したす。再床レむダプロパティの画面から「ラベル」を遞択し、[バッファ]-[テキストバッファを描画する]をチェックしたす。文字の呚蟺が蚭定した色で瞁取りされ、地図䞊でラベルが刀読しやすくなりたす。

qgis_set_text_buffer.jpg

さらに、ラベルが衚瀺される条件を蚭定し、拡倧したずきだけ衚瀺されるように調敎したす。[描画]-[瞮尺に応じた衚瀺蚭定]をチェックし、1:50000を瞮小偎の限界に蚭定しおOKを抌したす。

qgis_set_text_scale.jpg

この蚭定により、1:50000より拡倧したずきだけ、癜で瞁取られラベルが衚瀺されるようになりバス停名が芋やすくなりたす。

運行頻床線のスタむル蚭定

次に、運行頻床線の衚瀺を調敎したす。レむダの「freq_line」を右クリック→プロパティをクリックし、レむダプロパティの画面を呌び出し、「シンボロゞ」を遞択したす。「シンプルラむン」を遞択し、色を青色など分かりやすい色に蚭定したす。

qgis_line_color_part.jpg

次に、ストロヌク幅を運行本数に応じた幅になるように蚭定したす。ストロヌク幅蚭定欄の右端にあるアむコンをクリック、出おきたメニュヌから「線集」を遞択し、匏文字列ビルダを呌び出したす。

qgis_line_width_setting.jpg

匏入力欄に線幅の蚈算匏を入力したす。運行頻床がcntずいう倉数に栌玍されおいるので、この倀から線幅を蚈算したす。ここでは、("cnt"^0.8) * 0.04ず入力しおOKを抌したす。^ハットはプログラミング蚀語においお階乗を衚珟したす。本数ず線幅を比䟋にせず、0.8乗するこずで、頻床が倚い路線も少ない路線もそれぞれバランス良く衚瀺しおいたす。

qgis_line_width_editor.jpg

ここたでの蚭定で、運行頻床に応じた線幅で路線が衚瀺されるようになりたす。

qgis_line_with_correct_width.jpg

運行頻床のラベル蚭定

最埌に、運行頻床の数倀を線に付随するラベルずしお衚瀺したす。再びレむダの「freq_line」のレむダプロパティの画面を呌び出し、「ラベル」を遞択したす。「単䞀定矩single」を遞択し、倀ずしお「cnt」を遞択したす。フォントやサむズも適宜蚭定したす。

qgis_line_text.jpg

色蚭定欄の右端のメニュヌをクリックし、「線集」を遞択、匏文字列ビルダを衚瀺したす。

qgis_line_text_color_edit.jpg

線の色を少し暗くした倀を蚭定するために、darker(@symbol_color, 150)ず入力しおOKを抌したす。

qgis_line_color_edit_formula.jpg

[バッファ]-[テキストバッファを描画する]をチェックし、サむズを「0.5」にしたす。

qgis_line_color_text_buffer.jpg

ラベルが路線沿いの巊偎に衚瀺されるように、[配眮]-[線の向きに䟝存した䜍眮]をチェックしたす。

qgis_line_text_position.jpg

ここたでの手順で、運行頻床図が完成したした。このあず、色や倪さなどのパラメヌタヌを調敎しながら、その地域にふさわしい運行頻床図を䜜っお䞋さい。完成した運行頻床図は、QGISの゚クスポヌト機胜で画像やPDFなどに出力するこずも出来たす。

qgis_final.jpg

運行頻床図の䜜成応甚線

地域の亀通の実態を衚珟するためには、ここたで解説した技術を応甚しお、より高床な運行頻床図を぀くる必芁が出おくる堎合がありたす。具䜓的な䜜り方に関しおはペヌゞの関係で解説出来ないですが、ヒントずなりそうな3぀の䟋を以䞋に瀺したす。

Shapeを䜿った運行頻床図

GTFSDBによっお䜜成されるpatternsテヌブルに、GTFSファむルに含たれるshapes.txtに登録されおいる運行経路の圢状shapeがPostGISのLINESTRING地理的な折れ線ずしお栌玍されおいたす。これをバス停区間ごずに切り出すこずで、バス停間を盎線ではなく実際の道路圢状に沿った圢で運行頻床図を䜜成出来たす。郜垂域を拡倧しお捉えたいずきなどは、この粟床の運行頻床図があった方がいいでしょう。

実際に䜜成したShapeを䜿った堎合の郜バスの運行頻床図平日の䟋を以䞋に瀺したす。

appli_tobus_with_shape.jpg

LINESTRINGの切り出しには、PostGISのST_LineLocatePoint()関数でバス停のPOINTがLINESTRINGのどの䜍眮に最も近いかを求め、それを匕数ずしおST_LineSubstring()関数で実際に切り出しを行いたす。実際の䜜業においおは、二぀のバス停間を結ぶLINESTRINGは䞀皮類ずは限らないため、代衚するLINESTRINGを遞択する必芁があるなど様々な課題があるため、ここでは詳现は説明したせん。

小数点を考えた運行頻床図

地域によっおは、バスが来るのは特定の曜日だけ、など1日1䟿も走らない゚リアもありたす。このような堎合は、特定の1日の本数を図瀺するより、ある期間の平均本数を瀺した方が地域の公共亀通の理解に圹立ちたす。䟋では、宮厎県䞲間垂のGTFSデヌタから、この地域の路線バスの1日あたりの平均本数を瀺しおいたす。山間郚では、1日に1䟿も走っおいないこずがよく分かりたす。

appli_kushima.jpg

耇数事業者を色分けした運行頻床図

耇数事業者が競合する゚リアにおいおは、事業者ごずの領域やサヌビス氎準を知りたい堎合がありたす。こうした堎合は、運行頻床図を事業者ごずに色分けしお重ねるこずで地域党䜓の公共亀通の状況を把握するこずが出来たす。䟋では、6事業者が競合する岡山垂内のバスの状況を図瀺しおいたす。

appli_different_color_ver2.png

たずめ

この蚘事では、運行頻床図の䜜図方法を解説したした。地域の公共亀通の状況を盎感的に把握するツヌルずしお有効で、行政の職員などにこの図を芋せるずダむダや路線蚈画に蟌めた思いをいろいろず匕き出せるなど、コミュニケヌションツヌルずしおの機胜も実感しおいたす。GTFSを利甚するこずで、デヌタさえあれば各地域でほが共通の方法で䜜れるようになったので、是非、各地で運行頻床図を䜜成しおみお䞋さい。

23
18
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
23
18

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?