ユーザーID パスワード

技術情報

  • FAQ よくある質問
  • 個人ユーザー向けサービスのお手続きについて

コード&コラム

第10回
ARゲームを作ってみよう(2)


前へ 1 |2 |3 |4 |5 次へ

Step2 位置情報の取得とデータベースの作成

Step2ではGPSを用いた現在地の取得と、位置情報とテキストで構成されるARテキストのデータベースの作成を行います。また、位置情報を用いた方位の修正も実装します。

1.位置情報の取得
GPSARAppクラスに位置情報の変化によってメソッドを呼び出すため、LocationListenerインターフェースを実装します。また、位置情報を利用するため、LocationManagerとGeoPointの2つの変数と、方位の修正に使用するGeomagneticFieldを追加します。

public class GPSARApp extends Activity implements SensorEventListener, 
LocationListener{ private LocationManager locationManager; private GeoPoint geoPoint; private GeomagneticField geomagneticField;

LocationListenerを実装するとコードの左側に豆電球のアイコンが出現します。このアイコンをクリックし、「Add unimplemented methods」を選択するとeclipseの機能によって以下の4つのメソッドが追加します。各メソッドは位置情報の座標が変化したとき、位置情報が無効化された時、位置情報が有効になった時、位置情報の使用状況が変化した時に呼び出されます。

変化した位置情報の座標を取得するためにメソッドonLocationChangedを書き換えます。

    @Override
    public void onLocationChanged(Location arg0) {
    }

    @Override
    public void onProviderDisabled(String provider) {
    }

    @Override
    public void onProviderEnabled(String provider) {
    }

    @Override
    public void onStatusChanged(String provider, int status, Bundle extras) {
    }

以下のように記述することで位置情報の座標を取得と方位修正用のオブジェクトの作成を行います。

    @Override
    public void onLocationChanged(Location arg0) {
        geoPoint = new GeoPoint((int) (arg0.getLatitude() * 1E6),
                (int) (arg0.getLongitude() * 1E6));
    }
        geomagneticField = new GeomagneticField((float) arg0.getLatitude(),
                (float) arg0.getLongitude(), (float) arg0.getAltitude(),
                new Date().getTime());

    }

次に、位置情報を取得するためにロケーションマネージャの設定を行います。メソッドonResumeの内容を以下のように書き換えます。

    @Override
    public void onResume() {
        super.onResume();
        //追記:ロケーションマネージャの設定
        locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
        locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0,
                0, this);
        // センサー処理の登録
        sensorManager.registerListener(this,
                listMag.get(0), SensorManager.SENSOR_DELAY_NORMAL);
        sensorManager.registerListener(this,
                listAcc.get(0), SensorManager.SENSOR_DELAY_NORMAL);

    }

位置情報の取得にネットワークを用いたものとGPSを用いたものが存在します。ここではGPSを使用するように指定をしています。また、メソッドonStopの内容にセンサーの停止処理を記述します。

    @Override
    public void onStop() {
        super.onStop();
        locationManager.removeUpdates(this);
        sensorManager.unregisterListener(this);
    }

メソッドonLocationChangedで取得した位置情報geoPointはARテキストの描画で必要になります。そこで、描画処理を行うARViewのメソッドdrawScreenの引数として渡すことにします。
位置情報から求まる値を利用して方位の修正も行います。磁気センサーから得られる方位は、北極点と磁北の座標の違いから、東京で7度ほどのズレを生じます。これを、geomagneticFieldのメソッドを使用して修正します。

    @Override
    public void onSensorChanged(SensorEvent event) {

            ・・・(中略)・・・

            // 求まった方位角をラジアンから度に変換する
            float direction = (float) Math.toDegrees(actual_orientation[0])
                    + geomagneticField.getDeclination();
            arView.drawScreen(direction, geoPoint);

            ・・・(中略)・・・
    }

対応して、ARViewクラスの内容も変更します。

    public class ARView extends View {
    
    // 現在地を保持する変数
    int posx, posy;

    ・・・(中略)・・・
    public void drawScreen(float preDirection, GeoPoint geoPoint) {
        // センサーの値から端末の向きを計算する
        direction = (preDirection + 450) % 360;
        // 座標情報の取得
        if(geoPoint != null){
            posy = geoPoint.getLatitudeE6();
            posx = geoPoint.getLongitudeE6();
        }
        // onDrawを呼び出して再描画
        invalidate();
    }
}

以上で位置情報の取得とその利用の準備が整いました。それでは実際に表示するARテキストのデータベースを作成していきましょう。

2.ARテキストのデータベースの作成
ARテキストのデータベースには表示内容となるテキストと緯度経度で構成される位置情報を保存します。Androidで使用されるデータベースSQLiteを使用するため、SQLiteOpenHelperを継承したクラスSQLiteOpenHelperExをGPSARApp内に作成します。

    public class GPSARApp extends Activity implements SensorEventListener, 
LocationListener{ // データベースで使用する変数 private final static String DB_NAME = "gps_data.db"; private final static String DB_TABLE = "gps_data"; private final static int DB_VERSION = 1; private SQLiteDatabase db; ・・・(中略)・・・ public class SQLiteOpenHelperEx extends SQLiteOpenHelper { // コンストラクタ public SQLiteOpenHelperEx(Context context) { super(context, DB_NAME, null, DB_VERSION); } @Override public void onCreate(SQLiteDatabase db) { // テーブルの作成 String sql = "create table if not exists " + DB_TABLE + "(info text, latitude numeric, longitude numeric)"; db.execSQL(sql); } @Override public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { // データベースのアップグレード // ここでは、テーブルを作り直しをしています db.execSQL("drop table if exists " + DB_TABLE); onCreate(db); } } }

String sqlの内容には実行したいSQL文が記述されています。 db.execSQL(sql)により、sqlに記述されたSQL文を実行します。ここでは、DB_TABLEが存在しない場合、文字列、緯度、経度の3つの項目を持つテーブルを作成します。

作成したSQLiteOpenHelperExを使用してデータベースの準備を行うメソッドinitDataとテーブルの初期内容を準備するメソッドpresetTableを以下のように作成します。

    public void initData() {
        // SQLiteOpenHelperを継承したクラスを使用してデータベースを作成します
        SQLiteOpenHelperEx helper = new SQLiteOpenHelperEx(this);
        db = helper.getWritableDatabase();

        cursor = db.query(DB_TABLE, new String[] { "info", "latitude",
                "longitude" }, null, null, null, null, null);
        // テーブルが空の時内容をセットする
        if (cursor.getCount() < 1) {
            presetTable();
            cursor = db.query(DB_TABLE, new String[] { "info", "latitude",
                    "longitude" }, null, null, null, null, null);
        }
    }
    
    private void presetTable() {
        // テーブルの内容が空の時以下の内容をセットする
        ContentValues values = new ContentValues();
        values.put("info", "安田講堂");
        values.put("latitude", 35713433);
        values.put("longitude", 139762594);
        db.insert(DB_TABLE, "", values);
        values.put("info", "東京ドーム");
        values.put("latitude", 35705593);
        values.put("longitude", 139752252);
        db.insert(DB_TABLE, "", values);
        values.put("info", "東京スカイツリー");
        values.put("latitude", 35710036);
        values.put("longitude", 139811046);
        db.insert(DB_TABLE, "", values);
        values.put("info", "明治神宮");
        values.put("latitude", 35676402);
        values.put("longitude", 139700174);
        db.insert(DB_TABLE, "", values);
        values.put("info", "国会議事堂");
        values.put("latitude", 35675844);
        values.put("longitude", 139745578);
        db.insert(DB_TABLE, "", values);
    }

作成したinitTableはonCreateメソッドで呼び出します。

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        // データベースの用意
        initData();
        ・・・(中略)・・・

これでアクティビティの生成と同時にデータベースの使用準備が出来ました。それでは実際にデータベースの内容を読み込んでARテキストを表示する処理を作成しましょう。


第10回 ARゲームを作ってみよう(2)
 Step1 カメラ画像へのオーバーレイと方位センサー情報の取得
 Step2 位置情報の取得とデータベースの作成
 Step3 可視判定とテキストの表示
 Step4 現在位置の登録

サンプルコード

第1回 リファレンスコード(文字列編)

第2回 リファレンスコード2(グラフィックス編)

第3回 リファレンスコード3(タッチイベント編)

第4回 リファレンスコード4(チェックボックス/ラジオグループ編)

第5回 リファレンスコード5(スピナー編)

第6回 リファレンスコード6(サウンド/ムービー編)

第7回 リファレンスコード7(トースト編)

第8回 リファレンスコード8(Google Maps API利用編)

第9回 リファレンスコード9(SQLite編)

第10回 リファレンスコード10(音声認識編)

第11回 リファレンスコード11(日付/時刻ダイアログ編)

第12回 リファレンスコード12(Bluetooth編)