-
- _tt
- 562ポイント
- 投稿時間:2008/09/03 20:30
賛否両論のGoogle ストリートビューですが、自分が係わっているサイトのコンテンツに組み込む作業をしましたので、その過程で得たノウハウをいくつか紹介します。
本文
賛否両論のGoogle ストリートビューですが、自分が係わっているサイトのコンテンツに組み込む作業をしましたので、その過程で得たノウハウをいくつか紹介します。 まずは、実例をどうぞ。(#高度なことはやってません…) → カカクコムの本社付近のストリートビュー ■Googleマップにストリートビューのオーバーレイ(GStreetviewOverlay)を表示する。
例の青い道です。 #早く対応エリアが拡大されるといいですね。 JavaScriptコードの例■ストリートビュー(GStreetviewPanorama)を表示するコピペする ブログに貼る<script src="http://maps.google.com/maps?file=api&v=2&key=APIキー" type="text/javascript"></script> <script type="text/javascript"> <!-- map = new GMap2(document.getElementById("map")); streetview = new GStreetviewOverlay(); map.addOverlay(streetview); // --> </script>
ブラウザにFlashがインストールされている必要があります。 JavaScriptコードの例HTMLコードの例コピペする ブログに貼るfunction onLoad() { targetLatLng = new GLatLng(35.703554, 139.749495); stPanorama = new GStreetviewPanorama(document.getElementById("streetview"), {latlng:targetLatLng }); }※ここで注意!コピペする ブログに貼る<body onload="onLoad()" onunload="GUnload()"> <div id="streetview" style="width:600px; height:400px;"> </div> </body>Note that the last two methods are inexact: the Street View service does not require (and generally does not receive) exact latitudes and longitudes in these cases, but rather searches for the existence of panorama data "near" a given GLatLng.ということなので、実際に表示された地点は指定したものとは異なる。 また、近い地点データがない場合、エラーコード600でerrorイベントで発生する。 ■エラー処理を行う(GStreetviewPanorama.ErrorValues)
JavaScriptコードの例■ストリートビューの移動後、現在地点を取得するコピペする ブログに貼るGEvent.addListener(stPanorama, "error", onError); function onError(errorCode) { if (errorCode == 600) { document.getElementById("streetview").innerHTML = '<p>ストリートビュー未対応エリアです。</p>'; return; } else if (errorCode == 603) { document.getElementById("streetview").innerHTML = '<p>ブラウザがFlash未対応です。</p>'; return; } }
JavaScriptコードの例※ここで注意!コピペする ブログに貼るGEvent.addListener(stPanorama, "initialized", onInitialized); function onInitialized(location) { alert("(" + location.latlng.lat() + "," + location.latlng.lng() + ")"); }This event is fired when the panorama is initialized after moving to a new location. The location is a GStreetviewLocation object. Note: the initialized event is not sent when the panorama is first rendered; this is a known issue and we plan to fix this in a future release. (Since 2.104)つまり、一番最初に表示されたとき、今はinitializedイベントは発生しないが、(これは不具合なので、)将来直そうと思っていますとのこと。 実はこれ、結構深刻な問題だったりします。 なぜなら、GStreetviewPanoramaにはgetLocation()的なメソッドがないので、とにかくinitializedイベントが発生しないと、今どこの地点を表示しているかわかりません。 ですが、Noteにあるとおり、一番最初の表示ではinitializedイベントが発生しないため、一番最初の地点がわからないのです。(コンストラクタで指定した緯度経度の一番近くが表示されたというだけなので、正確な緯度経度がわからない) 結局、どうしたかというと、、、 ■目的地の一番近くのストリートビューデータがある地点を表示する
素直にGStreetviewClientを使います。 JavaScriptコードの例GStreetviewPanoramaのコンストラクタでは地点を指定せず(つまり表示せず)、目的に一番近い地点を非同期で受け取ってから、ストリートビューを表示する方法です。 ここで、現在地と目的地はズレがありますので、、、 ■現在地から目的地の方向(角度)を計算するコピペする ブログに貼るstPanorama = new GStreetviewPanorama(document.getElementById("streetview")); stClient = new GStreetviewClient(); stClient.getNearestPanoramaLatLng(targetLatLng, function(latlng) { if (latlng == null) { return onError(600); } stPanorama.setLocationAndPOV(latlng); });
JavaScriptコードの例※9/5 1:30修正 最初の角度の算出式がちょっと間違っていましたので、修正しました。 以前の式でも答えは同じなのですが、理屈が合わないので。 0度はX軸上にないとおかしいですよね。 これまでのものを合わせて、、、 ■ストリートビュー内で移動した後に、目的地に向きを変えるコピペする ブログに貼るfunction calcYaw(fromLatLng, toLatLng) { if (fromLatLng.equals(toLatLng)) { return -1; } var lat_f = fromLatLng.lat(); var lng_f = fromLatLng.lng(); var lat_t = toLatLng.lat(); var lng_t = toLatLng.lng(); var yaw = 90 - Math.atan2(lat_t - lat_f, lng_t - lng_f) * 180 / Math.PI; if (yaw < 0) { yaw += 360; } return yaw; }
JavaScriptコードの例Ajaxなコンテンツで、Lightbox(というかThickbox)を使う方法は別ノウハウにて。(予定)コピペする ブログに貼るfunction onInitialized(location) { var yaw = calcYaw(location.latlng, targetLatLng); if (yaw < 0) return; var pov = { yaw: yaw, pitch: location.pov.pitch, zoom: location.pov.zoom }; stPanorama.panTo(pov); }
- コメント数 (6)
- クリップ数 (4)
- アクセス数 (8765)
- コメント
唐突な質問ですみません ■現在地から目的地の方向(角度)を計算する この部分だけちょっと理解できなかったのですが(数学苦手) これって何か公式とかあるのでしょうか?
smiopさん、こんにちわ。読んでいただきありがとうございます。 #私も数学はとっくに忘れてしまっているので、今回、試行錯誤で得た式です…GoogleのGPovにあるとおり、yawには0~360の範囲の度を渡さなければなりません。 北が0度、東が90度、南が180度、西が270度です。 一方、現在地から目的地を見たときの方向は、数学の三角関数を用いて導き出すことができます。 Wikipediaの三角関数の項にある図で、頂点Aを現在地、頂点Bを目的地としてみたとき、∠Aが方向になります。 #実はこの辺、自分自身もすっきりしていないのが、、、
#0度ってどこを基準にしてるんでしょう
#でもうまくいってるのでいいやってことで
とにかく、
タンジェント(∠A) = a / bですので、∠A = アークタンジェント(a / b)で角度が求められます。 これをJavaScriptで書くと、r = Math.atan2(b, a)になります。 ただし、ここで得られる r は -π~+π(-3.14~+3.14) のラジアン単位の値ですので、これを度に変換するのが、ラジアン←→度のあたりの式です。d = Math.atan2(b, a) * 180 / Math.PIで、このままだと-180~+180になってしまうので、マイナス部分をなくすために、としています。 #(yaw >= 360)は勢いで書いてしまいました。 だいたいこんな感じでわかりましたでしょうか? #いやいや、自分もわかってなんですけど。 とりあえず、ブラウザのURL入力欄にコピペする ブログに貼るif (yaw < 0) { yaw += 360; }javascript:alert(Math.atan2(1,0)*180/Math.PI);などを入力してみるとよいかもです。。。
すみません、目的地の方向を求める式が間違っていたようです原文部分も直しましたが、二つ上のの説明文が違っていますので、こちらのコメントで訂正させてください。(一人でなにやってるんだか…) 途中からですが、
∠A = アークタンジェント(a / b)はJavaScriptのatan2を使うと、r = Math.atan2(a, b)です。第一引数がY軸、第二引数がX軸が正しいです。 (逆になってました。。。) したがって、d = Math.atan2(a, b) * 180 / Math.PIで∠Aの角度が求まります。 しかし、いま必要なのは北方向(正のY軸)を0度として統計回りにプラスとなるGPovのyawの値です。 数学における∠Aは、東方向(正のX軸)を0度とする反時計回りにプラスとなるものですので、ストリートビューのGPovで使う為には、yaw = 90 - Math.atan2(a, b) * 180 / Math.PIとしなければなりません。 結局、が最終形になります。 #といいつつ、まだ実際にストリートビューに組み込んでいないので若干不安ですが、、、コピペする ブログに貼るvar yaw = 90 - Math.atan2(lat_t - lat_f, lng_t - lng_f) * 180 / Math.PI; if (yaw < 0) { yaw += 360; }![]()
非常に詳細かつわかりやすい説明ありがとうございます。
これはいったん南を向いて反時計回りに対象物方向へ向かわせるイメージですよね なんとか理解できました ありがとうございますコピペする ブログに貼るvar yaw = 90 - Math.atan2(lat_t - lat_f, lng_t - lng_f) * 180 / Math.PI; if (yaw < 0) { yaw += 360; }
smiopさんへこちらこそ自分の理解不足とモヤモヤを解消するチャンスをいただいてありがとうございました。 おかげ様で、コードを修正し、気分をすっきりさせることができました。 数学の座標系(x,y,θ)をGoogleマップの座標系(lat,lng,yaw)に変換するところがややこしいですね。
3
コメント
(2008/09/03 21:01)
by _tt
- 0クリップ
- 6074アクセス
- プログラミング / 開発言語 / JavaScript
5
コメント
0
コメント
(2008/12/21 15:52)
by kidman
0
コメント
0
コメント
(2008/08/20 17:29)
by kiske
- 0クリップ
- 1624アクセス
- プログラミング / 開発言語 / JavaScript
3
コメント
(2008/08/21 18:26)
by zegenvs
- 0クリップ
- 1159アクセス
- プログラミング / 開発言語 / JavaScript
0
コメント
0
コメント
(2008/10/27 13:17)
by kiske
0
コメント
0
コメント
(2008/10/01 12:37)
by moppo

