新潟県燕市のコミュニティバスと燕市周辺の越後交通の路線バスの1日の動きを可視化してみた

# 1. はじめに

前回の記事（[新潟県燕市のコミュニティバスの1日の動きを shapeデータを作成して可視化してみた](https://qiita.com/bebebefu/items/fff066673c0b9b58ad9f)）では、燕市が公開しているGTFSデータをもとに、バスの運行ルートをMobmapで可視化する方法を紹介しました。

その後、新潟県燕市内にも路線バスを運行している越後交通のGTFSリアルタイム（GTFS-RT）データも取得できましたので、前回の記事で可視化した新潟県燕市のコミュニティバスの1日の動きと合わせて新潟県燕市とその周辺のバスの動きを可視化してみたいと思います。なお、前回で対象にしようとしてました三条市のコミュニティバスについてはまだ準備が整っていないのでこの記事では対象外にしています。

可視化の方法や構成は、前回と同じくPythonとMobmapを使ったシンプルな構成です。GTFS-RTのデータをCSVに変換し、Mobmap形式に整形していくプロセスを紹介します。

# 2. 使用データと使用ツール
- **燕市のコミュニティバスのデータについて**
    - GTFSデータ：
燕市の公式サイトから取得しました。[ここからダウンロードしました(2025/3/14)](https://www.city.tsubame.niigata.jp/soshiki/toshi_seibi/3/6/11802.html)

    - 西沢ツール GTFS形状データ作成ツール（v4.22）：  
  [ここからダウンロードしました（2025/3/14）](https://gtfs-gis.jp/gtfs/)
    - 西沢ツールの使用方法で参考にした資料：
   兵庫県が公開している[GTFS経路形状作成ツール演習](https://web.pref.hyogo.lg.jp/ks05/documents/20221128-text3.pdf)


- **越後交通の路線バスのデータ**
    - GTFSリアルタイム（GTFS-RT）データ：
    2024年3月21日に取得した、越後交通のGTFS-RTデータ（vehicle_positions）。 なお、以下のサイトから５分毎にデータを取得しました

https://bus-vision.jp/nagaoka/view/opendataNagaoka.html


- **Mobmap Web:**
可視化ツールとして[Mobmap Web](https://mobmap.locationmind.com/)を使いました。（作成2025/3/29）

# 3. Pythonでのデータ整形

越後交通のGTFSリアルタイム（GTFS-RT）データは[新潟のバス2社のGTFS Realtimeデータを可視化してみる](https://qiita.com/bebebefu/items/9d0be6bfcd1e86a21ac4)で作成した以下のコードをそのまま使いました。
（**注：以下のコードでは、識別子となる`id`が重複しないように、ダウンロードしたGTFS-RTデータのファイル名の先頭文字を基に'id'に工夫を加えています。しかし、将来的に新潟交通の路線バスのデータを重ねる場合、さらに工夫が必要になるかもしれません。** これは、今回のGTFS-RTデータのファイル名が nagaoka_vpos_update_v2_○○.bin という形式であり、先頭の「n」の文字が新潟交通を加えた場合に重複する可能性があるためです。）

```python:GTFSリアルタイム（GTFS-RT）データの処理コード
import os
import pandas as pd
import pytz
from google.transit import gtfs_realtime_pb2

def read_bin_file(file_path, initial_letter):
    # GTFS Realtimeデータの読み込み
    feed = gtfs_realtime_pb2.FeedMessage()
    with open(file_path, 'rb') as file:
        feed.ParseFromString(file.read())

    # データの抽出
    data_list = []
    for entity in feed.entity:
        if entity.HasField('vehicle'):
            vehicle = entity.vehicle
            # 頭文字に基づいた数値を追加
            if initial_letter == 'e':
                id_suffix = 50
            if initial_letter == 'n':
                id_suffix = 130
            
            vehicle_id = id_suffix + int(vehicle.vehicle.id)  # 頭文字を追加

            data_list.append({
                'id': vehicle_id,
                'timestamp': vehicle.timestamp,
                'latitude': vehicle.position.latitude,
                'longitude': vehicle.position.longitude
            })
    
    return data_list

def main():
    directory_path = '.'  # ファイルが存在するディレクトリのパス
    bin_files = [f for f in os.listdir(directory_path) if f.endswith('.bin')]
    # ファイル名に基づいて時系列順にソート
    bin_files.sort()

    all_data = []
    for file in bin_files:
        file_path = os.path.join(directory_path, file)
        initial_letter = file[0]  # ファイル名の頭文字を取得
        file_data = read_bin_file(file_path, initial_letter)
        all_data.extend(file_data)

    # DataFrameに変換
    df = pd.DataFrame(all_data)

    # UNIXtimestampを日時に変換
    japan_timezone = pytz.timezone('Asia/Tokyo')
    df['timestamp'] = pd.to_datetime(df['timestamp'], unit='s').dt.tz_localize(pytz.utc).dt.tz_convert(japan_timezone)

    # 時系列順にソート
    df.sort_values('timestamp', inplace=True)

    # CSVファイルに保存（既存のデータに追加）
    df.to_csv('gtfs_realtime_data.csv', mode='a', header=False, index=False)

if __name__ == "__main__":
    main()
```

一方、燕市のコミュニティバスのデータについては、[前回の記事](https://qiita.com/bebebefu/items/fff066673c0b9b58ad9f)）で整形・補間処理したデータをそのまま使用しています。


# 4. Mobmap Web用データの作成
Mobmap Webでの可視化には、先ほど作成した越後交通のGTFS-RTデータと、前回の記事で作成済みの燕市コミュニティバスのデータを一つのCSVにまとめて使用しました。

それぞれのデータが異なるバス事業者のデータであることを明示するため、燕市のコミュニティバスのデータには`route_id`を`0`とし、越後交通のデータにはすべて`route_id`を`1`とすることで、事業者間の識別をできるようにしています。

最終的なCSVファイルは以下のような形式になっています。

```csvs:
id,timestamp,latitude,longitude,route_id
10658301001,2025-03-21 06:58:00+09:00,37.66339075,138.8242534,0
...
49928,2025-03-21 15:39:52+09:00,37.4430275,138.8474426,1
```

# 5. アニメーション化した結果
燕市周辺のバスの1日の動きをパーティクルで表した動画を以下に示します。
燕市のコミュニティバスは時刻表通りに動いたらという前提の動きになっています。そして越後交通の路線バスは2025/3/21のGTFS-RTデータを処理した動きになっています。なお、可視化した動きは朝7時からの動きです。始発のバスはその前から動いていますが、私の環境ではなぜかデータ取得がうまくいきませんでしたので、本動画では対象外
とさせていただきました。

なお、対象にしたバス路線は以下になります。各事業者ごとにパーティクルの色を分けています。

- 越後交通の路線バス：赤色
- 燕市コミュニティバス：青色

<iframe width="560" height="315" src="https://www.youtube.com/embed/OFSj575d5Uk?si=FcI0fsrhNP4MBFfe" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen></iframe>

# 6. まとめ
今回は、GTFSデータとGTFS-RT（リアルタイム）データを用いて、越後交通と燕市のコミュニティバスを組み合わせた1日の運行状況を可視化しました。これにより、燕市とその周辺のバス路線では、一部の路線が重複しているものの、おおむね越後交通と燕市のコミュニティバスのすみ分けができていることが分かりました。一方で、燕市内のバスの本数は思った以上に少ないという印象も受けました。
（動画には含まれていませんが）燕市の南側にある長岡市周辺の路線バスと比較すると、燕市のバスの本数の少なさがより際立ちます。長岡市周辺では、バスの運行が活発で、本数も圧倒的に多い印象を受けました。
　また、越後交通の路線バスですが、[バスルート](https://bus-routes.net/)で確認するとすべての路線がこのGTFS-RT（リアルタイム）に反映されているわけではないようでしたので、さらに調査が必要だと感じました。

今後は、三条市のコミュニティバスのデータ整備も進め、それらを統合することで、新潟県の県央地域におけるバスの運行状況をより詳細に可視化していきたいと考えています。
また、今回取得した越後交通のGTFS-RT（リアルタイム）データには、長岡市を中心とした運行情報も含まれているため、可視化の対象地域をさらに拡大していくことも検討しています。

## 注：
この記事は、以下の著作物を改変して利用しています。
- 燕市コミュニティバスのGTFSデータ:https://www.city.tsubame.niigata.jp/soshiki/toshi_seibi/3/6/11802.html)

- 越後交通（http://www.echigo-kotsu.co.jp/) のGTFS-RTデータ
　Bus-Vision ながおかバスi　https://bus-vision.jp/nagaoka/view/opendataNagaoka.html
　
 クリエイティブ・コモンズ・ライセンス表示4.0 国際 [https://creativecommons.org/licenses/by/4.0/legalcode.ja](https://creativecommons.org/licenses/by/4.0/legalcode.ja)