2009年10月3日土曜日

Googleストリートビューの実装方法

下記の画像のようにMyClipにGoogleストリートビューの機能を盛り込んだので、その開発手順をここで紹介する。動作確認は実際にMyClip上で行って欲しい。今回の記事はストリートビューを使うにあたってすでにGoogle Maps APIのGMap2クラスに多少なりとも親しんでいるものとして話を進める。
APIの詳細はGoogle Maps API Referenceを参照してほしい。



-概要-
クリックされた地図上のストリートビューのデータ取得のためにGStreetviewPanorama.getNearestPanorama()を使用する。その際に問題になるのがクリックされた場所。そこが道路上ならば問題ないけれど建物上であればgetNearestPanorama()でデータを取得することができない。それなのでまず最初にGDirections.loadFromWaypoints()で最寄の道路座標データを取得する。

以下のコードは必要なところだけを抜き出した簡易版なので、手順だけでも大まかに掴んでもらえたらと思う。
(MyClip上ではストリートビュー関連の処理をクラスとしてまとめてあるので、thisはそのクラスを表すもの)

//マップの準備
this._map = new GMap2(
  document.getElementById("map"));
this._map.setUIToDefault();
this._map.setCenter(
  new GLatLng(lat, lng), 17);

//ビューの地図上の場所を表すアイコンの準備
this._guyIcon = new GIcon(G_DEFAULT_ICON);
this._guyIcon.image = 
  "http://maps.gstatic.com/mapfiles/cb/man_arrow-0.png";
this._guyIcon.transparent = 
  "http://maps.gstatic.com/mapfiles/cb/man-pick.png";
this._guyIcon.imageMap = [
  26, 13, 30, 14, 32, 28, 27, 28, 
  28, 36, 18, 35, 18, 27, 16, 26,
  16, 20, 16, 14, 19, 13, 22, 8];
this._guyIcon.iconSize = new GSize(49, 52);
this._guyIcon.iconAnchor = new GPoint(25, 35);

//ストリートビューのレイヤーをマップ上に載せる
this._svOverlay = new GStreetviewOverlay();
this._map.addOverlay(this._svOverlay);

//ストリートビューを準備
this._streetViewClient = new GStreetviewClient();
this._streetViewer = new GStreetviewPanorama(
  document.getElementById("stview"));

//最寄の道路座標を取得の準備
//loadFromWaypointsは非同期でデータ取得を行うので、callbackメソッドを設定する必要がある。ここではGEventにGDirectionsのloadイベントを登録している
this._direction = new GDirections();
GEvent.addListener(
 this._direction, "load", function() {
  //これで最寄のデータ取得完了
  var p = this._direction.getPolyline().getVertex(0); 
  var mystv = this;

  // 取得した道路上のストリートビューデータを取得
  this._streetViewClient.getNearestPanorama(p, 
   function(panoData) { mystv._showPanoData(panoData); });
});

// getNearestPanorama()のcallbackメソッド
_showPanoData: function (panoData) {
 this._streetViewer.setLocationAndPOV(
   panoData.location.latlng);
 if (!this._guyMarker) {
  this._guyMarker = 
   new GMarker(panoData.location.latlng, 
    { icon: this._guyIcon, draggable: true });
  this._map.addOverlay(this._guyMarker);
  var mystv = this;
  GEvent.addListener(this._guyMarker, "dragend", 
   function() { mystv._onDragEnd(); });
 }
 else {
  this._guyMarker.setLatLng(panoData.location.latlng);
 }
}

// 地図上の人型アイコンのドラッグ終了イベントハンドラ
_onDragEnd: function() {
 var latlng = this._guyMarker.getLatLng();
 this._direction.loadFromWaypoints(
  [latlng.toUrlValue(6), latlng.toUrlValue(6)], 
  { getPolyline:  true });
}

これで地図上にストリートビューのレイヤーと人型アイコンが表示され、人型アイコンをドラッグ&ドロップすれば最寄の道路上のストリートビューが表示される。

このほかにもGStreetviewPanoramaのinitialized, yawchangedイベントを実装すれば、ストリートビュー上のユーザーアクションが拾える。そうすれば地図からストリートビュー、またその逆へ、という双方向な挙動が実現できるのでよりユーザーフレンドリーな地図サービスが提供できる。デモを漁れば前述のイベント処理を実装したサンプルが見つかるので興味がある方はそちらへ。

0 件のコメント:

コメントを投稿