ブログトップ 記事一覧 ログイン 無料ブログ開設

大人になったら肺呼吸 RSSフィード Twitter

2011-03-23

PHPとJavaScriptで地震感知情報取得APIから地震情報を取得する

f:id:replication:20110323234303p:image

はじめに

関東東北震災以降、東北地方や茨城県などで強い余震が続いています。離れて暮らしていても、やっぱり怖いものです。緊急地震速報を見逃すまいと、NHKばかり見ている今日この頃です。というわけで、このエントリでは、PHPとJavaScriptを使って、EPSP(partA) 地震感知情報APIから地震の震源地やマグニチュードなどの情報を取得してみたいと思います。

これは、地震感知情報APIを用いた地震感知情報データの取得方法及び解析方法についてを提供するものです。

EPSP(partA) 地震感知情報APIにおける開発者向け情報 はてなブックマーク - EPSP(partA) 地震感知情報APIにおける開発者向け情報

地震感知情報APIの呼び出し

地震感知情報APIの呼び出しは、PHPで行います。JavaScriptからPHPを非同期で呼び出し、そこから地震感知情報APIにアクセスしています。関東東北震災以降、地震感知情報APIに大量のアクセスが来ているそうで、APIになるべく負荷をかけないようにするため、APC(Alternative PHP Cache)でキャッシュする処理が入っています。

APIによるデータ転送が、 p2pquake.ddo.jp 上り回線の90% を占める状態となり、地震情報以外の提供を中止させていただきました。

転送量軽減のため、従来通りの提供体制に復帰するために、キャッシュ(15秒〜1分程度で構いません)を取るなどの対応をお願いします。お手数をおかけします。

P2P地震情報 開発ログ: "地震感知情報API"をご利用のサービス提供者さまへお願い はてなブックマーク - P2P地震情報 開発ログ:

サーバサイド(PHP)

サーバサイドのPHPはこんな感じです。キャッシュヒットしない場合は、file_get_contentsでAPIを呼び出しにいきます。

<?PHP

date_default_timezone_set('Asia/Tokyo');

getEI();
function getEI() {
  header("Content-Type: text/html; charset=shift_JIS");
  $url = "http://p2pquake.ddo.jp/p2pquake/api_userquake.pl?";
  $url = $url . "date=" . date("m/d");
  try {
    // キャッシュから取り出し
    $html = apc_fetch($url);
    // キャッシュヒットしなかったら、file_get_contentsで取りに行く
    if ($html === false) {
      $html = file_get_contents($url, false, NULL);
      if($html != FALSE) {
        // 60秒間キャッシュする
        apc_store($url, $html, 60);
        echo $html;
      }
      else {
        echo "地震感知情報APIへの接続に失敗しました。(1)<br>";
      }
    }
    else {
    	// キャッシュヒットした場合
      echo $html;
    }
  } catch (Exception $e) {
    echo "地震感知情報APIへの接続に失敗しました。(2)<br>";
    echo $e->getMessage(); 
  }
  return true;
}
?>
クライアントサイド(JavaScript)

クライアントサイドでは、APIから返ってきたテキストデータを解析して、テーブルとして表示してやります。

function getEI() {
  var xmlHttp = new XMLHttpRequest();
  xmlHttp.onreadystatechange = function() {
    if (xmlHttp.readyState == 4) {
      if (xmlHttp.status == 200) {
        // ロード完了したときの処理
        
        // ローディングインジケータを非表示
        document.getElementById("loadingImg").style.display = "none";
        // データの解析
        var record = xmlHttp.responseText.split("\n");
        for(var i=0, len=record.length; i<len; i++) {
          var arrCommaSep = record[i].split(",");
          // 地震情報データ(QUA)の場合だけ処理する
          if (arrCommaSep[1] === "QUA") {
            var arrTmp = arrCommaSep[2].split("/");
            var tr = document.createElement("tr");
            for(var j=0, len2=arrTmp.length; j<len2; j++) {
              var td = document.createElement("td");
              // 津波の有無
              if (j === 2) {
                td.innerHTML = getTsunami(arrTmp[j]);
              }
              // 地震情報種類
              else if(j === 3) {
                td.innerHTML = getEIClass(arrTmp[j]);
              }
              // 震度訂正
              else if(j === 7) {
                td.innerHTML = IntensityCorrection(arrTmp[j]);
              }
              else {
                td.innerHTML = arrTmp[j];
              }
              tr.appendChild(td);
            }
            document.getElementById("tbl").appendChild(tr);
          }
        }
      }
      else {
        // 通信失敗
        document.getElementById("loadingImg").style.display = "none";
        alert("通信中にエラー発生::" + xmlHttp.status);
      }
    }
    else {
      // ロード中
      document.getElementById("loadingImg").style.display = "inline";
    }
  }
  var url = "./getEI.php" 
  xmlHttp.open("GET", url, true); 
  xmlHttp.send(null);
}

// 津波の有無
function getTsunami(n) {
  switch(parseInt(n)) {
    case 0:
      return "なし";
      break;
  case 1:
      return "あり";
      break;
  case 2:
      return "調査中";
      break;
  case 3:
      return "不明";
      break;
  }
}

// 地震情報種類
function getEIClass(n) {
  switch(parseInt(n)) {
  case 1:
      return "震度速報";
      break;
  case 2:
      return "震源情報";
      break;
  case 3:
      return "震源・震度情報";
      break;
  case 4:
      return "震源・詳細震度情報";
      break;
  case 5:
      return "遠地地震情報";
      break;
  }
}

// 震度訂正
function IntensityCorrection(n) {
  switch(parseInt(n)) {
  case 0:
      return "いいえ";
      break;
  case 1:
      return "はい";
      break;
  }
}
デモアプリ

「地震情報をロードする」ボタンを押すと、地震感知情報APIから今日の地震情報を取得し、一覧表として表示します。Google Mapとの連携やソート機能などが実装できると良い感じになるかも。


関連エントリ

pyon-yonpyon-yon 2011/10/18 00:16 よく出来ていると思いますが、
IE(ここではie9)以外のブラウザでは、情報が取得できないようです。

pyon-yonpyon-yon 2011/10/18 09:10 昨日伝えした件ですが、別の事務所のPCで見たら、IE9以外のブラウザでも情報取得ができましたので報告します。失礼いたしました。でも、考えられる原因は何なのでしょうね。

replicationreplication 2011/10/18 23:18 pyon-yonさん
コメントありがとうございます。JavaScriptがONでないか、あるいは、地震情報が発生していないと何も表示されない可能性はありますが、原因はちょっとわかりません。

pyon-yonpyon-yon 2011/10/21 10:53 技術的にアドバイスいただければ有難いのですが、jqueryで、
jQuery.get(url,function (data) {
という形で処理しようとしているのですが、例示いただいている
var record = xmlHttp.responseText.split("\n");
の部分を、
var record = data.responseText.split("\n");
とすると、「data.responseText is undefined」となってしまいます。jQuery.getだと
戻り値がXMLHttpRequestオブジェクトとは違うのでしょうか?ちなみに、dataはXMLdocumentオブジェクトみたいです。
プログラミング初級者ですが、よろしくお願いします。

replicationreplication 2011/10/21 23:36 pyon-yonさん、こんにちわ。
質問の件ですが、以下のエントリに書いてみました。わかんないことがあれば、またコメントしてください。
http://d.hatena.ne.jp/replication/20111021

pyon-yonpyon-yon 2011/10/22 11:16 ありがとうございます。エントリーで新しく示していただいたサンプルコードを試しました。string,1,200,など3つのalertが出た後、「jQuery.getのサンプルページ」を表示して終了しますね。responseTextがundefinedだからでしょうか?undefinedとなるようにするためにはどうしたらよいのでしょう。var url = "地震情報.xml"を想定してデータを得たいと考えています。

投稿したコメントは管理者が承認するまで公開されません。

スパム対策のためのダミーです。もし見えても何も入力しないでください
ゲスト


画像認証