Google ストリートビュー APIのノウハウをいくつか ノウハウ(Tips)  

こんにちは ゲスト さん | ログイン | ヘルプ | okyuu.com Feed Feed

総合トップ / ノウハウ / インターネット ノウハウ / Web API ノウハウ / Google ストリートビュー APIのノウハウをいくつか

賛否両論のGoogle ストリートビューですが、自分が係わっているサイトのコンテンツに組み込む作業をしましたので、その過程で得たノウハウをいくつか紹介します。
本文
賛否両論のGoogle ストリートビューですが、自分が係わっているサイトのコンテンツに組み込む作業をしましたので、その過程で得たノウハウをいくつか紹介します。

まずは、実例をどうぞ。(#高度なことはやってません…)

→ カカクコムの本社付近のストリートビュー


■Googleマップにストリートビューのオーバーレイ(GStreetviewOverlay)を表示する。
例の青い道です。 #早く対応エリアが拡大されるといいですね。 JavaScriptコードの例
コピペする ブログに貼る
<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>
■ストリートビュー(GStreetviewPanorama)を表示する
ブラウザにFlashがインストールされている必要があります。 JavaScriptコードの例
コピペする ブログに貼る
function onLoad() {
     targetLatLng = new GLatLng(35.703554, 139.749495);
     stPanorama = new GStreetviewPanorama(document.getElementById("streetview"), 
                                         {latlng:targetLatLng });

}
HTMLコードの例
コピペする ブログに貼る
<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コードの例
コピペする ブログに貼る
    stPanorama = new GStreetviewPanorama(document.getElementById("streetview"));

    stClient = new GStreetviewClient();
    stClient.getNearestPanoramaLatLng(targetLatLng, function(latlng) {
            if (latlng == null) {
                return onError(600);
            }

            stPanorama.setLocationAndPOV(latlng);
        });
GStreetviewPanoramaのコンストラクタでは地点を指定せず(つまり表示せず)、目的に一番近い地点を非同期で受け取ってから、ストリートビューを表示する方法です。 ここで、現在地と目的地はズレがありますので、、、 ■現在地から目的地の方向(角度)を計算する
JavaScriptコードの例
コピペする ブログに貼る
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;
}
※9/5 1:30修正 最初の角度の算出式がちょっと間違っていましたので、修正しました。 以前の式でも答えは同じなのですが、理屈が合わないので。 0度はX軸上にないとおかしいですよね。 これまでのものを合わせて、、、 ■ストリートビュー内で移動した後に、目的地に向きを変える
JavaScriptコードの例
コピペする ブログに貼る
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);
}
Ajaxなコンテンツで、Lightbox(というかThickbox)を使う方法は別ノウハウにて。(予定)

  • コメント数 (6)
  • クリップ数 (4)
  • アクセス数 (8765)

  • コメント

唐突な質問ですみません
■現在地から目的地の方向(角度)を計算する 
この部分だけちょっと理解できなかったのですが(数学苦手mischievous)
これって何か公式とかあるのでしょうか?

smiopさん、こんにちわ。読んでいただきありがとうございます。
#私も数学はとっくに忘れてしまっているので、今回、試行錯誤で得た式です…ase01



GoogleのGPovにあるとおり、yawには0~360の範囲のを渡さなければなりません。
北が0度、東が90度、南が180度、西が270度です。



一方、現在地から目的地を見たときの方向は、数学の三角関数を用いて導き出すことができます。



Wikipediaの三角関数の項にある図で、頂点Aを現在地、頂点Bを目的地としてみたとき、∠Aが方向になります。



#実はこの辺、自分自身もすっきりしていないのが、、、sad
#0度ってどこを基準にしてるんでしょうhatena
#でもうまくいってるのでいいやってことでokattention



とにかく、


タンジェント(∠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になってしまうので、マイナス部分をなくすために、
コピペする ブログに貼る
if (yaw < 0) {
    yaw += 360;
}
としています。 #(yaw >= 360)は勢いで書いてしまいました。 だいたいこんな感じでわかりましたでしょうか? #いやいや、自分もわかってなんですけど。 とりあえず、ブラウザのURL入力欄に
javascript:alert(Math.atan2(1,0)*180/Math.PI);
などを入力してみるとよいかもです。。。

というか、こちらの方がわかりやすいかもase02

すみません、目的地の方向を求める式が間違っていたようですase01



原文部分も直しましたが、二つ上のの説明文が違っていますので、こちらのコメントで訂正させてください。(一人でなにやってるんだか…)



途中からですが、


∠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;
    }
が最終形になります。 #といいつつ、まだ実際にストリートビューに組み込んでいないので若干不安ですが、、、ase02

非常に詳細かつわかりやすい説明ありがとうございます。smileattention
コピペする ブログに貼る
    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)に変換するところがややこしいですね。

あなたの問題は解決しましたか?

okyuu.comはITエンジニアのための質問サイトです。あなたの質問に答えてくれるエンジニアがいるかもしれません。なんと回答率は89

はじめての方へ

カテゴリ

特集

okyuu.comポイント獲得を競って、話題の賞品をゲットしよう! okyuu.comポイント獲得を競って、話題の賞品をゲットしよう!
新しい評価指標「okyuu.comポイント」を多く獲得して、話題の賞品を手に入れよう!
ソフトウェアを公開するのが楽しい 岡野真也さん ソフトウェアを公開するのが楽しい 岡野真也さん
ソフトウェアを公開するのが面白くてたまらない。作っては公開というのが彼のやり方だが、若きエンジニアにとってはそれくらいがちょうどいいのかもしれない。
コンピュータは世界を広げる実験道具 西尾泰和さん コンピュータは世界を広げる実験道具 西尾泰和さん
プログラミング、サイエンス、デザイン マルチな彼にとって、コンピュータは未知の世界を広げるための道具であることに変わりはない。今後の展開が楽しみだ。
理想のOS開発に人生を賭ける 川合秀実さん 理想のOS開発に人生を賭ける 川合秀実さん
OSASK計画代表の川合さんは、人生の1秒を惜しみながら独自OSの開発にいそしむ。
「楽しむ」それが豊かなエンジニアになるコツ 坂井恵さん 「楽しむ」それが豊かなエンジニアになるコツ 坂井恵さん
日本MySQLユーザ会の副代表を務める坂井恵さん。技術の現場で会社運営に興味を持ち、独立起業の道を選んだエンジニアだ。
夢はエンジニアに強い影響を与える本を書くこと 松信嘉範さん 夢はエンジニアに強い影響を与える本を書くこと 松信嘉範さん
ソニーの情報シスから日本を代表するMySQLのコンサルタントに。彼が魅せられたオープンソースの世界とは?
お友達紹介機能をつかってポイントGET! お友達紹介機能をつかってポイントGET!
お友達を招待してみんなでokyuuポイントをGETしよう!
オープンソースの活動「すごく、いい」 前坂徹さん オープンソースの活動「すごく、いい」 前坂徹さん
オープンソースプロジェクトで活躍する若き新鋭。コミュニティ活動の感想を尋ねると「すごく、いい」と満面の笑み。
コンピュータは創造力を刺激する 奥一穂さん コンピュータは創造力を刺激する 奥一穂さん
天才エンジニアとしての国際的な評価も高い奥一穂さん。世間からのスマートだとの評価には「自分は広く浅くだから」とさらり。
25歳からプログラミング「泣きながら覚えた」 庄司嘉織さん 25歳からプログラミング「泣きながら覚えた」 庄司嘉織さん
25歳でプログラマーに転向した。いまやjava-jaを立ち上げるなど精力的なエンジニアだ。
Rails勉強会@東京は“キャスト”の気持ちで 諸橋恭介さん Rails勉強会@東京は“キャスト”の気持ちで 諸橋恭介さん
大学時代、偶然手にしたMacが諸橋さんにITエンジニアの道を開いた。
"シャイモード"機能を活用しよう! "シャイモード"機能を活用しよう!
こんな質問してもいいのかな?そんなときは"シャイモード"で投稿!
RX-7とサーバ運用の意外な共通点 並河祐貴さん RX-7とサーバ運用の意外な共通点 並河祐貴さん
Amazon EC2を巧みに使いこなすTIS/SonicGardenの並河さん。「腕一本で食べていきたい」とITエンジニアを目指した。
「ブラックボックスは不安でしょ」 ひろせまさあきさん 「ブラックボックスは不安でしょ」 ひろせまさあきさん
エンジニアが楽しくて仕方がない。オープンソースを組み合わせてシステムを作り上げるのが彼の矜持のようだ。
Perlの地位向上を胸に 牧大輔さん Perlの地位向上を胸に 牧大輔さん
endeworksの牧大輔さんは社団法人JPAを立ち上げ、Perlの企業利用を促進したいという。
偶然からCTOへ ライブドアCTO池邉智洋さん 偶然からCTOへ ライブドアCTO池邉智洋さん
池邉智洋さんはライブドアCTOの技術メンバーを先頭で率いる。「まずはやって見せることも大事」と語る。