読者です 読者をやめる 読者になる 読者になる

ストリートビューの画像が存在するかどうか調べる/インドアビューを除外する

JavaScript Webサイト設計

2016年9月1日更新:ストリートビュー画像の有無を API で取得できることが分かったので書き直しました

Google Maps JavaScript API v3 では次のようにして、指定した div 要素に任意の地点のストリートビューを表示することができる。

// ストリートビューを表示する HTML 要素
var panoramaDiv = document.getElementById("thePanorama");

// 目標物(建物等)の座標
var thePosition = new google.maps.LatLng(36.561839, 136.654176);

// ストリートビューを表示
var panorama = new google.maps.StreetViewPanorama(panoramaDiv, {
	position: thePosition
	, zoom: 1
});

この API を使う上で留意しておくべき点は、指定した場所のストリートビューの画像が存在しない場合に、エラーも何も出さずに画像を表示されないことだ。API では画像の有無を取得できない。

事前に画像の有無を調べる

StreetViewService クラスを使うとストリートビュー画像の有無を調べることができる。

// ストリートビューを表示する HTML 要素
var panoramaDiv = document.getElementById("thePanorama");

// 目標物(建物等)の座標
var thePosition = new google.maps.LatLng(36.561839, 136.654176);

// ストリートビューオブジェクト
var panorama;

// ストリートビュー画像があるかどうか調べる
var svs = new google.maps.StreetViewService;
svs.getPanorama({
	// 目標物の座標
	location: thePosition
	// 撮影地点の選択方式。最も近い地点を選ぶ NEAREST がデフォルト。
	// BEST なら Google が最も適切と判断した地点となる
	, preference: google.maps.StreetViewPreference.NEAREST
	// 指定座標からどれだけ離れた撮影地点までを選択するかメートル単位で設定。
	// デフォルトでは50
	, radius: 50
	// 画像の種類を選択する。OUTDOOR ならインドアビューを除外
	, source: google.maps.StreetViewSource.DEFAULT
	
}, function(panoramaData, status) {
	switch (status) {
	case google.maps.StreetViewStatus.OK:
		// 画像あり。ストリートビューを表示する
		panorama = new google.maps.StreetViewPanorama(panoramaDiv, {
			position: panoramaData.location.latLng
			, zoom: 1
		});
		// ストリートビューの表示が完了した後、カメラの向きを調整(後述)
		var didLoad = google.maps.event.addListener(panorama, "status_changed", function() {
			google.maps.event.removeListener(didLoad);
			adjustPanoramaPov();
		});
		break;
	case google.maps.StreetViewStatus.UNKNOWN_ERROR:
		// エラー時の処理
		break;
	case google.maps.StreetViewStatus.ZERO_RESULTS:
		// 画像が見つからないときの処理
		break;
	}
});

getPanorama() メソッドのオプションで、建物のの中を撮影したインドアビューを除外することができる。インドアビューの多い繁華街や観光地で、道路からの映像のみ表示したい場合に有効だ。

var svs = new google.maps.StreetViewService;
svs.getPanorama({
	location: thePosition
	// インドアビューを除外
	, source: google.maps.StreetViewSource.OUTDOOR
}, function(panoramaData, status) {
	...
});

標準ではインドアビューが表示されてしまう

カメラの向きを調整する

先のコードに出てくる adjustPanoramaPov() は、カメラの向きを指定した目標物に向けるものである。API では自動的にこの処理を行ってくれない。目標物とカメラ座標の位置関係から逆三角関数を用いて方角を求めている。

// カメラの位置に基づき、カメラの向きを修正する
function adjustPanoramaPov() {
	var posFrom, posTo, dlat, dlng, heading;
	
	posFrom = panorama.getPosition();
	posTo = thePosition;
	dlat = posTo.lat() - posFrom.lat();
	dlng = posTo.lng() - posFrom.lng();
	heading = Math.atan2(dlng, dlat) / Math.PI * 180;
	if (heading < 0) {
		heading += 360; // [-180, 180] に対して heading の値は [0, 360] なので修正する
	}

	// タイマーを入れないと表示が更新されない
	setTimeout(function() {
		panorama.setPov({ heading: heading, pitch: 0 });
	});
}