2008-10-27

GMap2 と GStreetviewPanorama の位置情報を相互に連携する方法

Golazo MA4 team のなかじまんです。新機能のお知らせです。

Golazo MA4 で Google ストリートビューを使って、メモの位置の風景を確認できるようにしました。
Golazo MA4 でメモを表示するとき、そのメモの位置を表す Google マップに加え、Google ストリートビューを表示して、その位置の風景を確認できるようにしてみました。今回は、ココメモの "よく読む" のリンク先だけ対応しました。今後は、ココメモの追加や編集でも対応する予定です。
予定どおり、Golazo MA4 で、ココメモを追加するときと編集するときに、Google ストリートビューを表示して、その位置の風景を確認しながらメモできるようにしました。次のスクリーンショットのとおりです。



Google マップの移動に応じて、ストリートビューが連携します。また、ストリートビューの移動に応じて、Google マップが連携します。つまり、マップとストリートビューが相互に連携します。さらに、マップの地点で、ストリートビューのデータが存在しなときは、ストリートビューを非表示にします。

GMap2 と GStreetviewPanorama の移動イベントをハンドリングして、緯度経度を軸として、相互に連携するだけで簡単ジャンと思いきや、GStreetviewPanorama の不完全さ? により、実現にかなり苦労しました。

ので、ソースコードを抜粋して、ポイントを紹介しておきます。

// GStreetview
var pano = new GStreetviewPanorama(document.getElementById('pano'));
//pano.hide(); //BUG

GMap2 は生成してあるとします。まず、GStreetviewPanorama を生成します。このとき、オプションである初期の緯度経度は指定しません。

はじめは非表示とするため、hide メソッドを呼び出したいところですが、この時点で hide メソッドを使うと、show メソッドで表示できなくなってしまいました。バグっぽいです。

// GStreetviewClient
var client = new GStreetviewClient();
client.getNearestPanoramaLatLng(point, function(latlng) {
if (latlng) {
$('#pano').show();
if (pano.isHidden())
pano.show();
pano.setLocationAndPOV(point);
}
});

GStreetviewClient を使って、GMap2 の中心の緯度経度から、getNearestPanoramaLatLng メソッドを使って、ストリートビューのデータを探します。point が中心の緯度経度です。データが見つかったときは、GStreetviewPanorama を表示し、現在地として GMap2 の中心の緯度経度を指定しています。データが見つからないときは、非表示のままです。

var initialized = 0;

// GMap2.moveend
GEvent.addListener(map, 'moveend', function() {
client.getNearestPanoramaLatLng(map.getCenter(), function(latlng) {
if (latlng) {
$('#pano').show();
if (pano.isHidden())
pano.show();
if (initialized == 0)
pano.setLocationAndPOV(map.getCenter());
} else {
if (!pano.isHidden())
pano.hide();
$('#pano').hide();
}
if (initialized > 0)
initialized -= 1;
});
});

// GStreetview.initialized
GEvent.addListener(pano, 'initialized', function(location) {
initialized++;
map.setCenter(location.latlng);
});

GStreetviewPanorama の initialized イベントをハンドリングして、ストリートビューで移動したとき、GMap2 の中心がその緯度経度になるように指定しています。

GMap2 の moveend イベントをハンドリングして、マップを移動したとき、その移動先の緯度経度から、getNearestPanoramaLatLng メソッドを使って、ストリートビューのデータを探しています。データが見つかったときは、GStreetviewPanorama を表示し、現在地として GMap2 の中心の緯度経度を指定しています。データが見つからないときは、、GStreetviewPanorama を非表示としています。

ストリートビューで移動したとき、その移動先をマップの中心としていますが、このままだとマップが移動したことになり、さらに、ストリートビューを移動しようとします。つまり、意味のない連鎖のループが形成され、パラパラチラチラと、同じ緯度経度でのストリートビューの表示が繰り返されてしまいます。

ですので、initialized 変数を使って、ストリートビューの再表示が、ただ1回になるように工夫しています。何かもっと正規な方法がありそうな気がするのですが、今のところ見つかっていません。

主要ブラウザで動作確認しましたが、Opera 9.5 で、ストリートビューの現在地が更新されないという不都合を確認しています。それ以外のブラウザは大丈夫でした。原因は分からずじまいです。Opera 9.2 では期待どおりですので、Flash Player とかプラグインと関係がありそうな気もします。

0 件のコメント: