ぐらめぬ・ぜぷつぇんのはてダ(2007 to 2011)

2007年~2011年ごろまで はてなダイアリー に書いてた記事を引っ越してきました。

Google AJAX API 経由で GoogleMaps APIを jQuery と併せて使う時のメモ。

最近はGoogleAJAX APIというのを使う事で、MapsとかSearchとかDataとか、統一されたロードAPIや区分けされた名前空間を使って利用する事ができるようになってるみたいです。

・「Google Maps API の概念」
http://code.google.com/intl/ja/apis/maps/documentation/index.html
の「Google AJAX API ローダーを使用」にも簡単な例がありますし、
http://code.google.com/intl/ja/apis/ajax/documentation/
AJAX APIの本家ドキュメントですが例が載ってます。

で、弄ってみたのですが幾つか嵌りどころがあったのでメモしておきます。あくまでも個人的なメモです。間違ってたら指摘してくれるとすごい嬉しいです。

"google.maps."名前空間は、素では使えないっぽい。

実験中に嵌りました。
google.setOnLoadCallback()あるいはgoogle.load()で"callback"経由で渡す関数の中でしか認識できないみたいです。多分、中で色々やってるんじゃないでしょうか。

↑に伴うGBrowserIsCompatible()やGUnload()の調整が必要。

今までは普通に、

<script...>
if (GBrowserIsCompatible()) { ... }
</script>

とか、

<body onunload="GUnload()">

とか、GUnload()をjQueryでやるならば

<script>
$(window).unload = GUnload();
</script>

とか、すっぴんの名前空間で動かせてたのですが。
これはそれぞれ、

google.maps.BrowserIsCompatible
google.maps.Unload

という名前空間になります。
・・・ということは、すっぴんの名前空間じゃ動かなくて、google.load()かgoogle.setOnLoadCallback()経由のcallbackの中で呼ぶしかないようです。

・「window.onunload = google.maps.Unload; gives error in IE」:ここが参考になりました。
http://groups.google.com/group/Google-Maps-API/browse_thread/thread/449182b23493de00

jQueryと抱き合わせたサンプル。

元々YakiBikiでのプラグイン化を意識してますので、一枚岩のHTMLに組み込むような書き方はできてない点に注意して下さい。
あと、HTTPヘッダーでcharset=UTF-8となるよう注意して下さい。あと動作保証無しです。一応WinXPIE7, FF2, Opera9で確認はしてますが・・・。

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
  <head>
    <meta http-equiv="content-type" content="text/html; charset=utf-8"/>
    <title>Google Maps JavaScript API Example</title>
<script src="./jquery-1.2.6.min.js" type="text/javascript" ></script>
<script type="text/javascript" src="http://www.google.com/jsapi?key=your_key"></script>
<script type="text/javascript">
<!--
$(function(){
	call_map1("map1", 37.4419, -122.1419, 13);
	call_map1("map2", 37.4419, 122.1419, 5);
	call_map1("map3", 37.4419, 122.1419, 5);
});
//-->
</script>
</head>
<body>
<script type="text/javascript">
<!--
function call_map1(element_id, lat, lng, zoom) {
	google.load("maps", "2", {"callback" : function() {
		if (!google.maps.BrowserIsCompatible()) {
			window.alert('Browser is not compatible for Google Maps');
			return;
		}
		var map_element = $("#" + element_id)[0];
		if (!map_element) {
			window.alert('Specified element[' + element_id + '] was not found.');
			return;
		}
		var map = new google.maps.Map2(map_element);
		map.setCenter(new google.maps.LatLng(lat, lng), zoom);
		$(window).unload = google.maps.Unload;
	}});
}
//-->
</script>
<div id="map1" style="width: 500px; height: 300px"></div>
<div id="map2" style="width: 600px; height: 200px"></div>
</body>
</html>

GoogleMapで、現在表示中のマップの中心緯度・経度を取得する為のカスタムコントロール


適当にGoogleMapのサンプルとかAPIドキュメント見ながらでっち上げたやつです。GoogleAJAX API経由でロードする方式に併せてます。あと、コードピースですので、実際に組み込む時は自己責任の上で、適宜足りない部分を想像等で補って下さい。

"WhereAmI?"カスタムコントロール

<script type="text/javascript">
<!--
function WhereAmIControl() {}

function build_whereami() {
	WhereAmIControl.prototype = new google.maps.Control();

	WhereAmIControl.prototype.initialize = function(map) {
		var container = document.createElement("div");
		var mainDiv = document.createElement("div");
		mainDiv.style.textDecoration = "underline";
		mainDiv.style.color = "#0000cc";
		mainDiv.style.backgroundColor = "white";
		mainDiv.style.font = "small Arial";
		mainDiv.style.border = "1px solid black";
		mainDiv.style.padding = "2px";
		mainDiv.style.marginBottom = "3px";
		mainDiv.style.textAlign = "center";
		mainDiv.style.width = "6em";
		mainDiv.style.cursor = "pointer";
		container.appendChild(mainDiv);
		mainDiv.appendChild(document.createTextNode("WhereAmI?"));
		google.maps.Event.addDomListener(mainDiv, "click", function() {
			var latlng = map.getCenter();
			void(window.prompt('latitude, longitude', latlng.toUrlValue()));
		});

		map.getContainer().appendChild(container);
		return container;
	}

	WhereAmIControl.prototype.getDefaultPosition = function() {
		return new GControlPosition(G_ANCHOR_BOTTOM_RIGHT, new GSize(7, 20));
	}
}
//-->
</script>

以上のJSコードを適当な箇所に挿入し、google.load()で呼び出しておきます。

// 適当にonloadなイベントに組み込んで下さい。
google.load("maps", "2", {"callback" : build_whereami });

GMap2のコントロールに貼り付けるには、普通にaddControlでOKです。右下から20px程上、著作権表示と被らない辺りに"WhereAmI?"リンクボックスが表示されるようにしてます。リンクをクリックすると、地図の中心座標を「緯度, 経度」の順でpromptで表示しますので、そのままコピペしちゃえます。

google.load("maps", "2", {"callback" : function() {
	if (!google.maps.BrowserIsCompatible()) {
		return;
	}
	var map = new google.maps.Map2(document.getElementById('エレメントのID'));
	map.setCenter(new google.maps.LatLng(lat, lng), zoom);
	map.addControl(new WhereAmIControl());
}});

JavaScript名前空間とかスコープ、めちゃあやふやな頭で書いてますので、注意して下さい。一応WinXPのFirefox2, IE7, Opera9で確認はしてますが・・・。

GoogleMap用のHTMLプラグイン、出来た。

MapTypeControlが、見慣れた文字列の四角い枠の表示・・・じゃなくて、何か潰れた線みたいになってる。
ちょっと気になるけど、後回しにしても問題無さそうな感覚があるので、とりあえず引き続きWikiプラグイン(HTMLプラグインへのラッパー)を作ってみよう。

ちなみに、なんでWikiプラグインだけにしなかったのかというと。
HTMLフォーマットは直にHTMLとかJavaScriptが書けるといっても、やっぱり面倒くさい。
またWikiプラグインでとめているとどうしてもキャッシュの問題が出てくる。動的な所はなるべくキャッシュしておきたくないので(まぁoutlineプラグインとかで結構悩んではいるけど)、HTMLプラグインまで落とし込んで、都度生成させた方が良いでしょうという感じです。

あと、GoogleMapsのAPIの鍵だけど・・・どうも、localhostで動かす分には別サイトのキーでも動くのだけれど。ちゃんとしたドメイン(たとえばhostsファイルでの実験用ドメイン名)にした途端に、「サイトが違いますよー、ちゃんと申請したホスト名で使って下さいよー」みたいな(いい加減ですみません)メッセージが出て使えない。これはしゃーないので取得した。

あと・・・HTTPSとかで公開する場合とかどうなるのかな〜とか、YakiBiki自体をLAN内で封じ込める場合(外部サイトは閲覧できる)とかはGoogleMapの利用規約上大丈夫なのかな?とか。ここら辺は完全に使う側の問題なのだけれど、ちょっと気になった。

GoogleMap用のWikiプラグイン、出来た。あとsetup.php周り直した。

検索一覧画面での複数表示も上手く行った。
HTML/Wikiプラグインのヘルプページにも追記した。

結局、丸一日かかっちゃったなぁ・・・。

途中、子安武人アイマス実況中継MADで2時間ほど笑い転げていたのもあるけど。

あとsetup.phpで、初期データがおかしかったりした部分があったので直しました。SandBoxページも、ちょうどWiki書式の確認のために作っていたページがあったのでそれを手直しして入れ込みました。SideBarのリンクも整理。
他に、templateから新規作成するときに、画像と添付ファイルの場合にtemplateの日時置換が行われていなかったのも直しました。なんか、タイトルの初期値にデフォルトで{$upload_filename}を上書き設定してた・・・。空の場合のみ上書き設定するよう修正。

ほかは・・・今後、ちゃんとsetupする場面も出てくると思いますので、何かsetup絡みで出てきたら都度対処したいと思います。