Google mapsに天気アイコンをつけてみる
Livedoor Weather Hacksを使って何をしようか考えましたが、真っ先に思いついたのがGoogle mapsの地図に貼り付けてみることでした。 ということで、やってみました。
実は結構大変だった
最初は「GXmlHttpを使ってRSS情報をそのまま読んで解析すればいいや〜」と軽く考えていましたが、実は結構大変でした。 というのも、GXmlHttpはGoogle maps api用スクリプトが置いてある場所以外からはXMLを取って来れないからです。 これはセキュリティ上の制限で、Google maps apiが悪いというよりも、下位にあるJavascriptの制限でした。
でも、やっぱりGoogle mapsに表示したかったのでかなり強引な方法を使いました。 自サイトにLivedoor Weather Hacks専用転送スクリプトを書いて無理やり同一サイトからRSSを取っている形にしてしまいました。
サンプル
札幌の明日の天気を表示してみました。 出力結果はこんな感じです。 firefoxとIEで試しました。
ソースコード(google maps api)
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<script src="http://maps.google.com/maps?file=api&v=1&key=YOUR_GOOGLE_MAPS_KEY"
type="text/javascript" charset="UTF-8"></script>
<script type="text/javascript">
//<![CDATA[
var map;
function onLoad() {
map = new GMap(document.getElementById("map"));
var point = new GPoint(141.36, 43.05);
map.centerAndZoom(point, 11);
map.setMapType(G_SATELLITE_TYPE);
var request = GXmlHttp.create();
// use custom mirror since GXmlHttp can only get
// data from the same host.
// (there might be a better way...)
request.open("GET", "./mirror-weatherhacks.php", true);
request.onreadystatechange = function() {
if (request.readyState == 4) {
var rssitem = request.responseXML.getElementsByTagName("item");
for (var i=0; i < rssitem.length; i++) {
var cat = rssitem[i].getElementsByTagName("category");
if (cat[0].childNodes[0].nodeValue == "PR") {
// skip ad
continue;
}
// get url of OTENKI icon
var urlobj = rssitem[i].getElementsByTagName("url");
var url = urlobj[0].childNodes[0].nodeValue;
// get width of OTENKI icon
var widthobj = rssitem[i].getElementsByTagName("width");
var width = widthobj[0].childNodes[0].nodeValue;
// get height of OTENKI icon
var heightobj = rssitem[i].getElementsByTagName("height");
var height = heightobj[0].childNodes[0].nodeValue;
// create a marker with OTENKI icon
var icon = new GIcon();
icon.image = url;
icon.iconSize = new GSize(width, height);
icon.iconAnchor = new GPoint(0, 0);
var marker = new GMarker(point, icon);
map.addOverlay(marker);
break;
}
}
}
request.send(null);
}
//]]>
</script>
</head>
<body onload="onLoad()" style="margin:0px; padding:0px;">
<div id="map" style="width:450px; height:400px; padding:0px; margin:0px;"></div>
</body>
</html>
ソースコード(RSS転送)
mirror-weatherhacks.phpというファイル名で使いました。
<?php
$host = "weather.livedoor.com";
$path = "/forecast/rss/1b/4.xml";
$content_type = "";
$fp = fsockopen($host, 80, $errno, $errstr, 30);
if (!$fp) {
echo "<ERROR>$errstr ($errno)</ERROR>";
} else {
$httpreq = "GET $path HTTP/1.0\r\n";
$httpreq .= "Connection: Close\r\n";
$httpreq .= "\r\n";
fwrite($fp, $httpreq);
# get http status line
$statusline = fgets($fp, 2048);
# get http header
while (!feof($fp)) {
$header = fgets($fp, 2048);
if (strncasecmp($header, "Content-Type:", 13) == 0) {
$content_type = $header;
} else if ($header == "\r\n" || $header == "\r" || $header == "\n") {
break;
}
}
$content = "";
while (!feof($fp)) {
$content .= fgets($fp, 8196);
}
fclose($fp);
if ($content_type != "") {
header($content_type);
}
echo $content;
}
?>