酢ろぐ!

カレーが嫌いなスマートフォンアプリプログラマのブログ。

C#で東京メトロオープンデータAPIを使って施設情報(駅施設情報)を取得する

おはようございます。今日もC#で東京メトロオープンデータAPIを使ってみましょうか。本記事では、odpt:StationFacilityを指定して、施設情報(駅施設情報)を取得します。

施設情報を取得する

東京メトロの施設情報は、JSON.NETを使って取得したJSON-LD形式のデータをパース(デシリアライズ)させます。その時、型を指定しますので事前に下記のようにStationFacilityクラスを定義しておきましょう。

今回は扱う情報が多いので定義が多くなっています。StationFacilityクラスは特定の駅の施設情報を全て持っており、StationFacilityクラスは、複数のバリアフリー施設情報を表すBarrierfreeFacilityクラスの配列、プラットフォームに車両が停車している時の、車両毎の最寄りの施設・出口等を表すPlatformInformationクラスの配列を持ちます。

using Newtonsoft.Json;
using System;

namespace TokyoMetro.Apis
{
    public class StationFacility
    {
        [JsonProperty("@context")]
        public string Context { get; set; }

        [JsonProperty("@id")]
        public string Id { get; set; }

        [JsonProperty("@type")]
        public string type { get; set; }

        [JsonProperty("owl:sameAs")]
        public string SameAs { get; set; }

        /// <summary>
        /// バリアフリー施設
        /// </summary>
        [JsonProperty("odpt:barrierfreeFacility")]
        public BarrierfreeFacility[] BarrierfreeFacility { get; set; }

        /// <summary>
        /// プラットフォームに車両が停車している時の、車両毎の最寄りの施設・出口等
        /// </summary>
        [JsonProperty("odpt:platformInformation")]
        public PlatformInformation[] PlatformInformation { get; set; }

        [JsonProperty("dc:date")]
        public DateTime Date { get; set; }
    }

    /// <summary>
    /// バリアフリー施設情報
    /// </summary>
    public class BarrierfreeFacility
    {
        [JsonProperty("@id")]
        public string Id { get; set; }

        [JsonProperty("@type")]
        public string type { get; set; }

        [JsonProperty("owl:sameAs")]
        public string SameAs { get; set; }

        [JsonProperty("ugsrv:categoryName")]
        public string CategoryName { get; set; }

        [JsonProperty("odpt:placeName")]
        public string PlaceName { get; set; }

        [JsonProperty("odpt:locatedAreaName")]
        public string LocatedAreaName { get; set; }

        /// <summary>
        /// 施設情報の詳細
        /// </summary>
        [JsonProperty("odpt:serviceDetail")]
        public ServiceDetail[] ServiceDetail { get; set; }

        [JsonProperty("spac:hasAssistant")]
        public string[] HasAssistant { get; set; }

        [JsonProperty("spac:isAvailableTo")]
        public string IsAvailableTo { get; set; }

        [JsonProperty("ugsrv:remark")]
        public string Remark { get; set; }
    }

    /// <summary>
    /// 施設情報の詳細
    /// </summary>
    public class ServiceDetail
    {
        /// <summary>
        /// 施設利用可能時間やエスカレータの方向が曜日によって変わる場合に、
        /// 次のいずれかを格納(曜日に依存しない場合は省略)
        /// </summary>
        [JsonProperty("odpt:operationDay")]
        public string OperationDay { get; set; }

        /// <summary>
        /// 施設の利用可能開始時間(いつでも利用できる場合は省略)
        /// </summary>
        [JsonProperty("ugsrv:serviceStartTime")]
        public string ServiceStartTime { get; set; }

        /// <summary>
        /// 施設の利用可能終了時間(いつでも利用できる場合は省略)
        /// </summary>
        [JsonProperty("ugsrv:serviceEndTime")]
        public string ServiceEndTime { get; set; }

        /// <summary>
        /// エスカレータの方向名(施設がエスカレータの場合
        /// に格納。上り、下り、上り・下りの3種類が存在)
        /// </summary>
        [JsonProperty("ugsrv:direction")]
        public string Direction { get; set; }
    }

    public class PlatformInformation
    {
        [JsonProperty("odpt:carComposition")]
        public int CarComposition { get; set; }

        [JsonProperty("odpt:carNumber")]
        public int CarNumber { get; set; }

        [JsonProperty("odpt:railDirection")]
        public string RailDirection { get; set; }

        [JsonProperty("odpt:surroundingArea")]
        public string[] SurroundingArea { get; set; }

        [JsonProperty("odpt:transferInformation")]
        public TransferInformation[] TransferInformation { get; set; }

        [JsonProperty("odpt:barrierfreeFacility")]
        public string[] BarrierfreeFacility { get; set; }
    }

    /// <summary>
    /// 最寄りの乗り換え可能な路線と所要時間
    /// </summary>
    public class TransferInformation
    {
        [JsonProperty("odpt:railway")]
        public string Railway { get; set; }

        [JsonProperty("odpt:necessaryTime")]
        public int NecessaryTime { get; set; }

        [JsonProperty("odpt:railDirection")]
        public string RailDirection { get; set; }
    }
}

第1回目の時に、東京メトロオープンデータを扱うためのTokyoMetroApiクラスを作っていたので興味のある方は読み返してくださいね。

このTokyoMetroApiクラスにメソッドを追加してみましょう。第4回目で紹介した駅情報を取得するGetPassengerSurveyメソッドの実装については「C#で東京メトロオープンデータAPIを使って駅情報(乗降人員数)を取得する - 酢ろぐ!」をご覧ください。

using Newtonsoft.Json;
using System.Collections.Generic;
using System.Linq;
using System.Net;

namespace TokyoMetro.Apis
{
    public class TokyoMetroApi
    {
        public string ConsumerKey { get; private set; }

        public string EndPointUrl { get; private set; }

        public TokyoMetroApi(string consumerKey)
        {
            ConsumerKey = consumerKey;
            EndPointUrl = "https://api.tokyometroapp.jp/api/v2/datapoints/";
        }

        public IEnumerable<TrainInformation> GetTrainInformation()
        {
            // 第1回の記事を参照してください
        }

        public IEnumerable<Railway> GetRailway()
        {
            // 第2回の記事を参照してください
        }

        public IEnumerable<Station> GetStations()
        {
            // 第3回の記事を参照してください
        }

        public IEnumerable<PassengerSurvey> GetPassengerSurvey()
        {
            // 第4回の記事を参照してください
        }

        public IEnumerable<StationFacility> GetStationFacility()
        {
            var parm = new Dictionary<string, string>();
            parm["rdf:type"] = "odpt:StationFacility";
            parm["acl:consumerKey"] = ConsumerKey;

            var url = string.Format("{0}?{1}", EndPointUrl,
                string.Join("&", parm.Select(p => string.Format("{0}={1}", p.Key, p.Value))));

            // JSON-DLを取得する
            var client = new WebClient()
            {
                Encoding = System.Text.Encoding.UTF8
            };
            var json = client.DownloadString(url);

            return JsonConvert.DeserializeObject<StationFacility[]>(json);
        }
   }
}

さて、実際に使う際には下記のようにコンシューマキーを指定して、TokyoMetroApiクラスのインスタンスを生成してGetStationFacilityメソッドを実行します。

var consumerKey = "XXXXXXXXXXXXXXXXXXXXXXXXXX";
var api = new TokyoMetroApi(consumerKey);

var passengerSurvey = api.GetStationFacility();

下図のように駅情報(乗降人員数)が取得できます。今までのデータで最大級かもしれません。

f:id:ch3cooh393:20140925114732p:plain

具体的にどのような情報が得られるのか以下のサンプルコードを使って確認してみましょう*1

var consumerKey = "XXXXXXXXXXXXXXXXXXXXXXXXXX";
var api = new TokyoMetroApi(consumerKey);

var stationFacility = api.GetStationFacility();

// 1番目の要素を取り出す(虎ノ門駅でした)
var facility = stationFacility.First();

// バリアフリー施設の一覧
foreach (var f in facility.BarrierfreeFacility)
{
    Console.WriteLine("・{0} 場所:{1}", f.CategoryName, f.PlaceName);
}

// 電車がプラットフォームにいるときの乗り換え情報や改札外情報
foreach (var p in facility.PlatformInformation)
{
    Console.WriteLine("・車両編成数:{0} 号車番号:{1} {2}", p.CarComposition, p.CarNumber, p.RailDirection);

    // 改札外の最寄り施設(存在しない場合はnull)
    if (p.SurroundingArea != null)
    {
        foreach (var a in p.SurroundingArea)
        {
            Console.WriteLine(" ・{0}", a);
        }
    }
}

このサンプルコードを実行すると以下のような出力を得ることができます。まずはバリアフリー施設情報の方です。エレベータやエスカレーターなどの設備と場所が分かります。

・エレベーター 場所:1番線ホーム、虎ノ門交差点方面改札~3番出入口
・エレベーター 場所:2番線ホーム、西新橋方面改札~10番出入口(虎ノ門実業会館)
・エレベーター 場所:2番線ホーム、虎ノ門交差点方面改札~11番出入口
・エスカレーター 場所:2番線ホーム、虎ノ門交差点方面改札~11番出入口
・階段昇降機 場所:2番線ホーム~虎ノ門交差点方面改札

次に電車がプラットフォームにいるときの乗り換え情報や改札外情報です。分かりにくいのですが、車両が6両で1号車の場合に乗っていた場合に浅草線に乗り換える場合の所要時間や、そのまま改札の外に出たときに何があるのかが分かります。

・車両編成数:6 号車番号:1 odpt.RailDirection:TokyoMetro.Asakusa
 ・ホテルオークラ
 ・虎ノ門病院
・車両編成数:6 号車番号:2 odpt.RailDirection:TokyoMetro.Asakusa
・車両編成数:6 号車番号:3 odpt.RailDirection:TokyoMetro.Asakusa
・車両編成数:6 号車番号:4 odpt.RailDirection:TokyoMetro.Asakusa
・車両編成数:6 号車番号:5 odpt.RailDirection:TokyoMetro.Asakusa
 ・愛宕山東急イン
・車両編成数:6 号車番号:6 odpt.RailDirection:TokyoMetro.Asakusa
・車両編成数:6 号車番号:1 odpt.RailDirection:TokyoMetro.Shibuya
 ・ホテルオークラ
 ・虎の門病院
・車両編成数:6 号車番号:2 odpt.RailDirection:TokyoMetro.Shibuya
・車両編成数:6 号車番号:3 odpt.RailDirection:TokyoMetro.Shibuya
・車両編成数:6 号車番号:4 odpt.RailDirection:TokyoMetro.Shibuya
・車両編成数:6 号車番号:5 odpt.RailDirection:TokyoMetro.Shibuya
 ・愛宕山東急イン
・車両編成数:6 号車番号:6 odpt.RailDirection:TokyoMetro.Shibuya

関連記事:C#で扱う東京メトロオープンデータAPI

*1:PlatformInformationに関してはどのような見せ方が適切なのか思いつかなかったのでとりあえず羅列させています