SHOEISHA iD

※旧SEメンバーシップ会員の方は、同じ登録情報(メールアドレス&パスワード)でログインいただけます

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

スマホアプリ開発の最新トレンド! ぜったい外せない位置情報活用術

OpenGLを使った地図描画エンジンの作り方(2)

スマホアプリ開発の最新トレンド! ぜったい外せない位置情報活用術 番外編

  • X ポスト
  • このエントリーをはてなブックマークに追加

 さて、XY座標を変えると地図を移動することができるのはお試しいただけたと思いますが、Z軸を変えても地図が拡大・縮小されないことにお気づきでしょうか。地図アプリであれば、ピンチ操作でZ軸を操作して地図を拡大・縮小するのが標準的ですが、現状のサンプルでは、Z軸の値を変えても地図が変化しないことが確認いただけると思います。これは、並行投影を使っているためです。平行投影は、オブジェクトがどの位置にあっても大きさが変化しない投影のため、Z軸を変化させても北海道の大きさが変化しません。では、拡大・縮小ができるように投影方法を変えてみましょう。

GL20MyRenderer
public void onSurfaceChanged(GL10 arg0, int width, int height) {

	//ビューポートの設定します。
	GLES20.glViewport(0,0,width,height);

	float fov = 45.0f; //画角
	float raito = (float) width/height;  //画面の縦横比
	float near = 1.0f; //視点から近平面までの距離
	float far = 100000000.0f; //視点から遠平面までの距離
	float top = near * (float)Math.tan(Math.toRadians(fov)); //画角から近平面のTOPを求める
	float bottom = -top;//近平面のbottom
	float left = bottom * raito; //近平面のleft
	float right = top * raito;  //近平面のright

	Matrix.frustumM(mProjMatrix, 0, left, right, bottom, top, near, far);

	GLES20.glUniformMatrix4fv(muProjMatrix, 1, false, mProjMatrix, 0);
}

 変更後の投影方法は、透視投影(参考:図4)です。Matrix.frustumMで設定されています。サンプルソースは、視点からの画角と画面の縦横比、近平面までの距離から値を求めています。いかがでしょうか。北海道がずいぶん小さく表示されたと思います。視点のZ軸値を変更することで、北海道が拡大・縮小されますのでお試しください。構成するデータの座標値が大きいため、視点やfarの数字が巨大になっているのは愛敬ということで。

図4(透視投影)
図4(透視投影)

 さて、ここで地図の拡大・縮小についてもう少し掘り下げて説明させていただきます。地図エンジンの挙動としては、視点を操作することで地図の拡大・縮小が行われることを理解いただけたと思いますが、Android版Yahoo!地図アプリでは、地図の拡大・縮小に伴って、地図上に表示されるデータの密度が変わります。Android版Yahoo!地図アプリをお試しいただくと、拡大した状態ではビルや歩道の形状まで表示されますが、縮小すると道路情報が主体になってくることがお分かりいただけると思います。

図5(詳細と広域の比較図)
図5(詳細と広域の比較図)

 これは、スケールによって最適な密度のデータを再ロードしているからです。初めに地図はXYで分割されていることを説明させていただきましたが、Z軸(スケール)によってもデータが分かれて構成されています。世界を縮小していく際に等間隔で最適な密度で投影されたデータを生成して、地図の美しさ・分かりやすさ・処理の高速化を追求しています。

図6(世界のZ軸の説明)
図6(世界のZ軸の説明)

 Android版Yahoo!地図アプリは少し変わった視点の取り扱いを行っています。データが等間隔に最適化・投影されるということは、オブジェクトの大きさも等倍で小さくなります。例えば1/2ごとにデータを切り替えたとすると、同じ建物を示すオブジェクトは、切り替わる際に1/2の大きさでデータ内に格納しています。このように処理するメリットとしては、同じ分割範囲により多くのオブジェクトを格納していくことができる点があげられます。

 一方で、単純に視点をそのままでデータを切り替えてしまうと不具合が生じてしまいます。データが1/2になる位置まで視点を引いた際に、1/2になっているデータをロードすると表示されるデータは1/4の状態です。これでは急に地図が小さくなった形で表示されて不自然なため、Android版Yahoo!地図アプリでは視点を初期化する処理を加えています。

図7(Y!地図アプリの視点移動)
図7(Y!地図アプリの視点移動)

 アプリケーション全体で管理されているスケール値とデータ間で管理されている実視点のスケール値の2種類で構成されているのは、Android版Yahoo!地図アプリの特徴の一つと言えるかもしれません。

まとめ

 今回は、内容が大変マニアックになってしまいましたが、興味を持っていただけましたでしょうか。指での操作部分を付けくわえたサンプルをGitHubにアップしましたので、ぜひ参考にしてください。シェーダまわりの話も付けくわえたかったのですが、内容がさらにマニアックになりそうなので次回にさせていただきたいと思います。次回はシェーダの基本部分と、それを利用した色の設定や破線などの描画を織り交ぜて説明したいと思います。

 本連載をきっかけに地図アプリに興味を持ってもらえると幸いです。

Yahoo!地図アプリ

この記事は参考になりましたか?

  • X ポスト
  • このエントリーをはてなブックマークに追加
スマホアプリ開発の最新トレンド! ぜったい外せない位置情報活用術連載記事一覧

もっと読む

この記事の著者

冨川 修広(ヤフー株式会社)(トミカワ ノブヒロ(ヤフーカブシキカイシャ))

2008年ヤフー入社。地図に関するシステム全般の設計・開発を担当。フルリニューアルしたAndroid版Yahoo!地図アプリでは、プロダクトマネージャとしてプロジェクト全体を統括。

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

この記事は参考になりましたか?

この記事をシェア

  • X ポスト
  • このエントリーをはてなブックマークに追加
CodeZine(コードジン)
https://codezine.jp/article/detail/7520 2013/12/11 14:00

おすすめ

アクセスランキング

アクセスランキング

イベント

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

新規会員登録無料のご案内

  • ・全ての過去記事が閲覧できます
  • ・会員限定メルマガを受信できます

メールバックナンバー

アクセスランキング

アクセスランキング