2005年07月14日
Movable Type用 位置プラグイン
Google Mapsが日本地図対応になった。しかも詳細。
いやー、すごいです。
というわけで、Google Maps APIなどの位置情報ツールとMovable Typeをつなぐプラグインを作成。エントリーに含まれる緯度経度を返します。
(2005-07-15 01:00 ちょっと変更)
locations.pl
(測地系変換にNowralさんのコードを使用させていただきました。ありがとうございます。)
インストール:
locations.plをpluginsディレクトリに置く
Image::Info
HTML::Parserに含まれるHTML::LinkExtor
が必要。HTML::Parserは多くのサーバに最初からインストールされているようだが、Image::Infoがない場合はここ参照
対応する位置情報:
・エントリー本文にimgタグとして記述され、同じサーバに置かれている画像のExif GPSタグ
・エントリー本文に含まれる地図サービスのURL ( walk.eznavi.jp / www.gpspowered.jp / mapfan.com / www.mapion.co.jp )
タグ記述例:
<MTEntries>
<MTLocations>
<$MTLocation coordinate="latitude" datum="1"$><br />
</MTLocations>
</MTEntries>
パラメータ:
coordinate 緯度か経度かの指定。無指定の場合「緯度,経度」とカンマで区切って返す
latitude 緯度
longitude 経度
datum 測地系。無指定の場合WGS84
0 WGS84
1 Tokyo97
format 緯度経度の表記方法。無指定で度単位。
dms 度.分.秒
実例:
その1-1:Individual Entry Archiveテンプレートに
<MTLocations>
<a href="http://maps.google.com/maps?q=<$MTLocation datum="1"$>+(HERE)&spn=0.004588,0.006136&hl=ja">Google Maps</a><br />
</MTLocations>
と記述すると、位置情報が含まれるエントリーの場合Google Mapsの該当する位置へのリンクが生成される。こんな感じ。
その1-2:Individual Entry Archiveテンプレートに
<MTLocations>
<a href="http://www.mapfan.com/index.cgi?MAP=E<$MTLocation coordinate="longitude" datum="1" format="dms"$>N<$MTLocation coordinate="latitude" datum="1" format="dms"$>&ZM=12">Mapfan</a><br />
</MTLocations>
と記述すると、位置情報が含まれるエントリーの場合Mapfanの該当する位置へのリンクが生成される
その1-3:たとえばこのようなCGIをMovable TypeのCGIと同じディレクトリに置き、Individual Entry Archiveテンプレートに
<MTLocations>
<a href="<$MTCGIPath$>red2map.cgi?ll=<$MTLocation$>&entry_id=<$MTEntryID$>">Map</a><br />
</MTLocations>
と書くと、地図サービスを選択してリンクすることができる。Google Mapsを選ぶとこんな感じ。
その2:data.xmlという出力ファイル名のインデックス・テンプレートを作る。中身は以下。
<markers>
<MTEntries lastn="100"><MTLocations>
<marker lat="<$MTLocation datum="1" coordinate="latitude"$>" lng="<$MTLocation datum="1" coordinate="longitude"$>" permalink="<$MTEntryPermalink$>"/>
</MTLocations></MTEntries>
</markers>
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" xmlns:v="urn:schemas-microsoft-com:vml">
<head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8"/>
<title>My Blog with Google Maps</title>
<style type="text/css">
v?:* {
behavior:url(#default#VML);
}
</style>
<script src="http://maps.google.com/maps?file=api&v=1&key=abcdefg" type="text/javascript"></script>
</head>
<body>
<div id="map" style="width: 640px; height: 640px"></div>
<script type="text/javascript">
//<![CDATA[
var map = new GMap(document.getElementById("map"));
map.addControl(new GSmallMapControl());
map.addControl(new GMapTypeControl());
map.centerAndZoom(new GPoint(139.741308333333,35.6553083333333), 4);
function createMarker(point, permalink) {
// Create a lettered icon for this point using our icon class from above
var icon = new GIcon();
icon.image = "http://labs.google.com/ridefinder/images/mm_20_red.png";
icon.shadow = "http://labs.google.com/ridefinder/images/mm_20_shadow.png";
icon.iconSize = new GSize(12, 20);
icon.shadowSize = new GSize(22, 20);
icon.iconAnchor = new GPoint(6, 20);
icon.infoWindowAnchor = new GPoint(5, 1);
var marker = new GMarker(point, icon);
var html = "<a href=?"" + permalink + "?">" + permalink + "</a>";
GEvent.addListener(marker, "click", function() {
marker.openInfoWindowHtml(html);
});
return marker;
}
var request = GXmlHttp.create();
request.open("GET", "data.xml", true);
request.onreadystatechange = function() {
if (request.readyState == 4) {
var xmlDoc = request.responseXML;
var markers = xmlDoc.documentElement.getElementsByTagName("marker");
for (var i = 0; i < markers.length; i++) {
var point = new GPoint(parseFloat(markers[i].getAttribute("lng")),
parseFloat(markers[i].getAttribute("lat")));
var marker = createMarker(point, markers[i].getAttribute("permalink"));
map.addOverlay(marker);
}
}
}
request.send(null);
//]]>
</script>
</body>
</html>
というhtmlを作ると、地図上に最近100件のエントリーの位置がマップされる。こんな感じ。