テスターですが何か?

ホビープログラマ略してHPです

東京電力「電力の使用状況グラフ」を解析して前年相当データを抽出するプログラムを作成しました

leave a comment »

長いタイトルです。「東京電力 節電効果計測サービス」で外部のAPIから前年相当データを取得していたのですが、APIからデータが取得できなくなってしまったので自力でグラフ画像から色データやらピクセルのXY座標などをごにゃごにゃして前年相当データを抽出するプログラムを作成しました。

画像とはこの画像です。この青色の折れ線グラフの点部分から、毎時の前年相当データを抽出することにします。

juyo-j_0410

 

早速ですが、ソースはここに公開します。(4/10時点の画像データでは正しく動作しますが、東京電力がグラフ画像の仕様を変更した場合、正しく動作しない可能性があります)

ざっくりとソースの解説をします。

画像の読み込み

  • URLから画像を読み込む
  • ピクセル単位で座標と色情報の組み合わせデータを作成

// 東京電力のサイトから「電力の使用状況グラフ」画像を読み込む
string url = "
http://www.tepco.co.jp.cache.yimg.jp/forecast/html/images/juyo-j.gif";
WebClient wc = new WebClient();
Stream stream = wc.OpenRead(url);
Bitmap Bitmap = new Bitmap(stream);
stream.Close();

// 画像をピクセルごとに色情報を取得してデータ化する
PixelList = new List<PixelData>();
PixelData d = null;
Color PixelColor;

for (var y = 0; y < Bitmap.Height; y++)
{
    for (var x = 0; x < Bitmap.Width; x++)
    {
        PixelColor = Bitmap.GetPixel(x, y);
        d = new PixelData();
        d.x = x;
        d.y = y;
        d.ColorName = ColorTranslator.ToHtml(PixelColor);   // 色は分かりやすくするため、HTMLの色情報に変換
        PixelList.Add(d);
    }
}

前日相当日データのグラフXY座標リストを作成

折れ線グラフの点部分のXYピクセル座標リストを作ります、24時間分なので24セットの座標リストを作ります。

image

ピクセルデータのリストからLinq, Linq, Liq投げまくりです。

private static Dictionary<int, int> MakePixelList(string ColorName)
       {
           // 色名称でピクセルデータをフィルタ
           var ColorFilter = from c in PixelList
                                where c.ColorName == ColorName
                                orderby c.x, c.y
                                select c;

           // 該当の色が6回登場するXピクセル座標を抽出
           // 6回色情報が登場するときが、折れ線グラフの点部分になる
           // また、1つの点に対してXピクセル座標は3回連続する
           var GraphXPositionList = from c in ColorFilter
                                     group c by c.x into g
                                     where g.Count() == 6
                                     select new { x = g.Key };

           // XYピクセル座標の組み合わせリストを作成
           int XPosition = 0;
           int YPosition = 0;
           var PositionList = new Dictionary<int, int>();

           Console.WriteLine("XYピクセル座標の組み合わせリスト");

           // 24回(24時間)ループ
           for (var i = 0; i < 24; i++)
           {
               // Xピクセル座標は3回連続するので、中点をXピクセル座標として採用する
               XPosition = GraphXPositionList.Take(i * 3 + 2).Last().x;

               // Xピクセル座標に対して、色情報が登場するY座標の最小値(画像では最上)を
               // Yピクセル座標に採用する
               YPosition = (from c in ColorFilter
                            where c.x == XPosition
                            select c.y).Min();

               Console.WriteLine(XPosition.ToString() + "," + YPosition.ToString());
               PositionList.Add(XPosition, YPosition);
           }

           return PositionList;
       }

消費電力量を算出

コメントに書いてある通りです、グラフのY軸(高さ)から、使用電力量を算出しています。高さから直接算出できないので、前日実績とのレシオからさんしゅつしていることと、グラフの0位置が1000万KWであることがポイントです。

            // 前年相当日データ部分のグラフ座標情報
            var PreviousYearPixelXYList = MakePixelList("#0000FF");

            // 折れ線グラフの0(実際は1000)のピクセルY座標
            var ZeroYPosition = PixelList.Where(p => p.ColorName == "#40FFFF").Max(p => p.y);

            // グラフ上の1ピクセルに対する、使用電力量(万KW)レシオ
            // 本来は、グラフの前日実績のピクセルXY座標と、CSVの使用電力量から求めるべきだが
            // 前年相当と先日実績がほぼ同じだと、前年相当が全面に表示され
            // グラフの前日実績のピクセルXY座標が正しく取得できないため、固定値として設定
            int Ratio = 14;

            int Hour = 0; // 時刻
            var PreviousYearUsageList = new List<int>();
            int PreviousYearUsage = 0;
           
            foreach (var PreviousYearValue in PreviousYearPixelXYList)
            {
                // 折れ線グラフの点部分ピクセルY座標から、消費電力量を算出する
                // 0位置からの距離とレシオから算出
                // グラフの0位置は1000万KWだが、なぜか1100万KWの方がグラフと整合性が取れる
                PreviousYearUsage = (ZeroYPosition – PreviousYearValue.Value) * Ratio + 1100;
                Console.WriteLine(Hour.ToString() + "時台の前年相当電力使用量" + PreviousYearUsage.ToString() + "万KW");
                Hour++;

                PreviousYearUsageList.Add(PreviousYearUsage);
            }

以上、簡単な解説でした、この処理を「東京電力 節電効果計測サービス」に組み込んでリリースする予定です。

今回のエントリは以上です。

Written by david9142

2011年4月10日 @ 4:16 PM

カテゴリー: LightElectricity

Tagged with , ,

コメントを残す

以下に詳細を記入するか、アイコンをクリックしてログインしてください。

WordPress.com ロゴ

WordPress.com アカウントを使ってコメントしています。 ログアウト / 変更 )

Twitter 画像

Twitter アカウントを使ってコメントしています。 ログアウト / 変更 )

Facebook の写真

Facebook アカウントを使ってコメントしています。 ログアウト / 変更 )

Google+ フォト

Google+ アカウントを使ってコメントしています。 ログアウト / 変更 )

%s と連携中

%d人のブロガーが「いいね」をつけました。