Papervision 3D と Adobe Flex を使ったジオコーディング
Mark Walters
今月号の記事
最近、地球上に正確な地理的ロケーション(位置情報)を表示するというジオコーディングが話題となっています。 Google、MapQuest、Yahoo! など、すべての地図サービスプロバイダーは、地図上のアドレスをジオコードしているので、特定のロケーションを見たり、複数のロケーション間の道順を調べたりすることが簡単にできます。このような地図サービスではパブリック API を公開しており、誰でも地図上にさまざまなタイプのデータ(写真、映像、RSS フィードなど)を表示したマッシュアップを作成し、地理的ロケーションとデータをリンクさせることができます。
地理的にデータを連動させることが容易になったため、Web 上での新たな情報ビジュアライゼーション領域が開かれました。たとえば、RSS フィードは、単に世界中からのニュースを提供してくれるだけでなく、そのニュースがどこから発信されているのかを正確に表示することも可能となります。他にも、バケーションの旅行先で撮影した写真を投稿し、訪れた都市とタグ付けしておけば、家族や友達にも旅行を疑似体験してもらうことができます。ジオコーディングにより、情報ビジュアライゼーションの可能性が大きく広がったといえます。
こうした地図サービスを使った情報ビジュアライゼーションとしてよくあるのが、地図上に 2D でポイントを配置する方法です。しかし、オープンソースの 3D ライブラリ「Papervision 3D」を使った Flash コンテンツであれば、3D の地球上にジオデータを表示することが可能です。
Papervision 3D は、オープンソースの Flash 用リアルタイム 3D エンジンです。このライブラリを使えば、素早く手軽にインタラクティブ 3D 環境を構築できます。この記事では、Papervision 3D と Yahoo! の地図サービス API を使って、入力したロケーションが 3D 地球上にマーカーでマッピングされるというコンテンツの作り方を解説します。
では、実際のコンテンツを「GeoGlobe」で見てみましょう。
準備作業
まずはサンプルファイル「geoglobe.zip 360 KB」をダウンロードしてください。サンプルのコードをなぞりながら、あるいは自分で書いたコードと比較しながら読み進めていきましょう。次に必要なライブラリをダウンロードします。Papervision 3D は、Google Code からダウンロードできます。現在のバージョンは1.5ですが、Subversion レポジトリではバージョン 2.0 のベータ版を利用することができます。この記事では、2.0 ベータ版を使います(このベータ版は、Papervision 3D 開発チームによって「GreatWhite」と名付けられています)。また、地球を回転させるために使用する Tweener ライブラリ もダウンロードします。Tweener ライブラリは、「as3」ディレクトリのライブラリを使用します。
注:Subversion についての詳細は、「Subversive」、または「Subclipse」をご覧ください。どちらも Eclipse のプラグインで、Adobe Flex Builder で利用でき、SVN を使った作業に役立ちます。Subversive は Eclipse 傘下になり、Eclipse の SVN クライアントとして使えるようになりました。
Flex ライブラリプロジェクトとしてレポジトリを Flex Builder にチェックアウトしたら、新規 Flex プロジェクトを作成して「GeoGlobe」と名前を付けます。そして、GeoGlobe プロジェクトのライブラリパスに先ほどの2つのライブラリを追加します。ライブラリを使用するには、GeoGlobe プロジェクトを右クリックして「プロパティ」を選びます。「Flex ビルドパス」を選び、さらに「ライブラリ」タブをクリックします。それから「プロジェクトの追加」ボタンをクリックして、2つのライブラリを選びます。以上で、準備が整いました。
3D による地球の作成
Papervision 3D を使用するには、準備が必要です。まず、レンダラー、シーン、カメラ、ビューポイントを作成します。以前のバージョンでは、レンダラーなどの作成は単調な繰り返し作業で時間がかかるものでした。しかし、2.0 ベータ版では、BasicView クラスが新たに用意され、すべての設定を行ってくれるようになっています。このクラスを拡張して、自分の 3D ジオメトリに追加するだけでいいのです。
では、org.papervision3d.view.BasicViewを拡張した GlobeView クラスを作成します。このクラスは、地球と地理的ロケーションを示すマーカーを作成するために使います。
マーカーよりも、地球の方が重要な要素です。org.papervision3d.objects.primitives.Sphereを拡張した新規クラスを作成します。このクラスでは、球体の半径、セグメント、素材を設定します。たとえば、「半径を 320、セグメントの幅を 24、セグメントの高さを 20」というように設定します。セグメント数が多くなればなるほど、球体が滑らかになりますが、マシンにかかる負荷も大きくなります。作成するアプリケーションの目的に合わせて、バランスよくセグメント数を設定してください。
最後に設定するのは球体の素材です。指定する緯度経度にマーカーを正確に配置させたり、見た目のゆがみをなくしたりするために、メルカトル図法の世界地図を使用します。メルカトル図法は、シリンダー状の地図図法で、球体の周りをシームレスに覆うことができます。この記事のサンプルファイルには、 メルカトル図法の世界地図画像を1枚使用していますが、違う見た目にしたい場合は好きな素材画像を使ってください。
次に Marker クラスを作成します。マーカーは、地図上での地理的ロケーションを示します。このサンプルではシンプルなキューブをマーカーとして使用していますが、好きな3Dオブジェクトを使ってください。Marker クラスは、 org.papervision3d.objects.DisplayObject3Dを拡張したクラスです。もう1つの 3D オブジェクトのコンテナであり、実際の 3D オブジェクトを拡張しているわけではありません。こうすることで、コンテナ内で 3D オブジェクトを Z 方向に移動させ、コンテナの軸に沿ってオブジェクトを配置できるようになるのです。結果として、3D オブジェクトを地球の中ではなく表面に配置することができます。サンプルではキューブを使用していますが、みなさんが好きな 3D オブジェクトに置き換えてください。
GlobeView クラス用に、地球の作成とカメラの初期化を行う必要があります。
//コピーするためのカメラ用 null オブジェクトを作成 cameraTarget = new DisplayObject3D(); scene.addChild( cameraTarget ); //カメラがアメリカを向くようにカメラターゲットを回転させる cameraTarget.yaw( 180 ); //地球の作成 globe = new Globe(); scene.addChild( globe ); //カメラのフォーカスとズームを設定 camera.focus = 1100; camera.zoom = 1;
上記のコードでは、カメラターゲットを作成し、カメラのフォーカスとズームを設定しています。このカメラターゲットは、単なる空の 3D ディスプレイオブジェクトで、カメラを回転させる際の擬似軸として利用します。 Papervision 3D では、特定の 3D オブジェクトの位置や変換設定をコピーして、他の 3D オブジェクトの位置や変換設定に使用することができます。このサンプルでは、カメラの変換設定をカメラターゲットの変換設定に使用し、シーンがレンダリングされるたびにある一定の距離だけカメラを後ろに引いています。このようにカメラを地球から離れたところにおくことで、地球を見ることができるようにしているのです。もし、カメラを後ろに引かなければ、カメラはカメラターゲットと一緒に地球の中に配置された状態になってしまいます。
緯度と経度
地球上にマーカーを正確に配置するには、テキストフィールドに入力された地理的ロケーションの緯度と経度の情報を取得する方法が必要となります。地図サービスの API を使うと、簡単に緯度と経度の情報を取得することができます。
Google、 MapQuest、Yahoo! の地図サービスでは、ジオコーディング用 API を公開しています。このサンプルでは、Yahoo! の API を利用しています。理由は、Yahoo! の API では、地理的ロケーションのテキスト情報を渡すだけで緯度と経度の情報を戻してくれる URL を提供しているからです。地理的ロケーションには、都市名、州名、都市名+州名、国名、郵便番号を使うことができます。Yahoo! の API が提供する URL にリクエストを送れば、特定のロケーションの詳細情報が XML ファイル形式で戻ってきます。その XML ファイル内のノードに緯度と経度の情報が含まれています。
この URL を利用するには、Yahoo! に登録して、アプリケーション ID を取得する必要があります。URL には2つのクエリパラメータが必要で、1つはジオコードしたいロケーション、もう1つはアプリケーション ID です。
注:Yahoo! のアプリケーション ID を取得したら、ソースコード内の Geocoder クラス内に入力してください。
マーカーの配置
地理的ロケーションの緯度経度情報を取得するのは簡単ですが、それを元に正確な位置にマーカーを配置させるにはちょっと工夫が必要です。では、手元にどんな材料があって、このタスクを達成するために何をすればいいのかを考えてみましょう。手元にはメルカトル図法の世界地図をマッピングした 3D 球体と、地球上のあるロケーションの緯度経度情報があります。そこで必要となるのは、地理的ロケーションの緯度経度情報を地球上の xyz ポイントに変換するアルゴリズムです。
こうしたアルゴリズムはすでに存在しています。以下は、球座標をデカルト座標に変換するアルゴリズムです。
x = r sin θ cos φ y = r sin θ sin φ z = r cos θ
r は半径、θ(シータ)は緯度、φ(ファイ)は経度です。
なぜこのような数式になるのかを深く考える必要はありません。こういうものだと思えばいいのです。ただ、みなさんに知っておいてほしいのは、y と z はアルゴリズム内で交換されなければならないということです。理由は、アルゴリズムで想定しているzの方向と Papervision 3D が想定している方向が異なるためです。他の注意点としては、地球上の地図の配置によっては、緯度経度を調整する必要があることです。このサンプルでは、緯度を90度、経度を15度移動させています。
繰り返しますが、このアルゴリズムはサンプルのキモとなる部分ですが、深く考え込まずに、そういうものだと受け入れてください。
仕上げのタスク
では、残りのタスクをフローに沿ってまとめてみましょう。テキストフィールドに入力されたテキスト情報を Yahoo! の API に渡してロケーションの緯度経度情報を取得し、緯度経度と地球の半径の情報をアルゴリズムに渡します。アルゴリズムからロケーションのxyz座標が算出されるので、それを元に地球上にマーカーを配置します。
まとめ
以上で、3D 地球上に正確な緯度経度でマーカーを配置する Flex アプリケーションの完成です。かなり複雑な課題でしたが、ここまで成し遂げ、GeoGlobe クラスを作成したり研究したりしたのであれば、もうみなさんは素晴らしいアプリケーションを作り始めたも同然です。ここからさらに写真やビデオを追加したり、世界中を放浪している友達を追跡したりするように発展させてみてはいかがでしょうか。Papervision 3D や地図サービス API は他にもいろいろな機能を提供しているので、もっと研究してみてください。両方とも、1つの記事ではカバーしきれないくらいの可能性を持っています。
この記事とソースコードのレビューをしてくれた Papervision 3D のチーム、Carlos Ulloa、John Grden、Ralph Hauwert に感謝しています。特に Carlos Ulloa は、記事中のアルゴリズムに関する用途や説明を検証してくれて、本当に助かりました。また、Cheyenne Throckmorton は、その素晴らしいテクニカル洞察力で細かくレビューしてくれました。最後に、素敵な地球テクスチャマップを使わせてくれた、Planetary Pixel Emporium の James Hastings-Trew に感謝を述べたいと思います。
