読者です 読者をやめる 読者になる 読者になる

酢ろぐ!

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

C#で東京メトロオープンデータAPIを使って路線情報を取得する

C# 鉄道

前回からの続きです。タイトルでは路線情報を取得するとなっていますが、正しくはodpt:Railwayで指定する東京メトロ路線情報を取得するです。

東京メトロ路線情報を取得する

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

using Newtonsoft.Json;
using System;

namespace TokyoMetro.Apis
{
    public class Railway
    {
        [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; }

        [JsonProperty("dc:title")]
        public string Title { get; set; }

        [JsonProperty("odpt:stationOrder")]
        public StationOrder[] StationOrder { get; set; }

        [JsonProperty("odpt:travelTime")]
        public TravelTime[] TravelTime { get; set; }

        [JsonProperty("odpt:lineCode")]
        public string LineCode { get; set; }

        [JsonProperty("ug:region")]
        public string Region { get; set; }

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

        [JsonProperty("odpt:womenOnlyCar")]
        public WomenOnlyCar[][] WomenOnlyCar { get; set; }
    }

    /// <summary>
    /// 駅順
    /// </summary>
    public class StationOrder
    {
        [JsonProperty("odpt:station")]
        public string Station { get; set; }

        [JsonProperty("odpt:index")]
        public int Index { get; set; }
    }

    /// <summary>
    /// 駅間所用時間
    /// </summary>
    public class TravelTime
    {
        [JsonProperty("odpt:fromStation")]
        public string FromStation { get; set; }

        [JsonProperty("odpt:toStation")]
        public string ToStation { get; set; }

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

    /// <summary>
    /// 女性専用車両
    /// </summary>
    public class WomenOnlyCar
    {
        [JsonProperty("odpt:fromStation")]
        public string FromStation { get; set; }

        [JsonProperty("odpt:toStation")]
        public string ToStation { get; set; }

        [JsonProperty("odpt:operationDay")]
        public string OperationDay { get; set; }

        [JsonProperty("odpt:availableTimeFrom")]
        public string AvailableTimeFrom { get; set; }

        [JsonProperty("odpt:avalilableTimeUntil")]
        public string AvalilableTimeUntil { get; set; }

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

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

前回、東京メトロオープンデータを扱うためのTokyoMetroApiクラスを作っていたのでメソッドを追加してみましょう。前回実装済みのGetTrainInformationの中身については「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/";
        }

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

        public IEnumerable<Railway> GetRailway()
        {
            var parm = new Dictionary<string, string>();
            parm["rdf:type"] = "odpt:Railway";
            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<Railway[]>(json);
        }
    }
}

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

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

// 遅延時間を取得する(前回実装したやつ)
var trainInformation = api.GetTrainInformation();

// 路線情報を取得する
var railway = api.GetRailway();

下図のように東京メトロ路線情報が取得できます。路線情報クラスのSameAsプロパティはodpt.Railway:TokyoMetro.MarunouchiBranchのように路線を表すIDが格納されています。

f:id:ch3cooh393:20140922013838p:plain

路線情報と遅延時間情報を合わせてどの路線が遅延しているのか調べる

遅延時間情報クラスのRailwayプロパティと路線情報クラスのSameAsプロパティで連結させて、どの路線が遅延しているのか一覧を表示させてみましょう。IEnumable同士のデータの結合にはLINQのJoinメソッドを使います。

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

// 遅延時間を取得する(前回実装したやつ)
var trainInformation = api.GetTrainInformation();

// 路線情報を取得する
var railway = api.GetRailway();

// IDで連結させてみる
var q = railway.Join(trainInformation, 
    r => r.SameAs, t => t.Railway, 
    (r, t) => new
    {
        Id = r.Id,
        RailwayName = r.Title,
        InfomationText = t.TrainInformationText
    });

foreach (var item in q)
{
    Console.WriteLine("{0}線 - {1}", item.RailwayName, item.InfomationText);
}

さて、Visual Studioの出力ペインでどのような表示になったのか確認してみましょう。

銀座線 - 現在、平常どおり運転しています。
丸ノ内線 - 現在、平常どおり運転しています。
日比谷線 - 現在、平常どおり運転しています。
東西線 - 現在、平常どおり運転しています。
千代田線 - 現在、平常どおり運転しています。
有楽町線 - 現在、平常どおり運転しています。
半蔵門線 - 現在、平常どおり運転しています。
南北線 - 現在、平常どおり運転しています。
副都心線 - 現在、平常どおり運転しています。

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