2012年11月28日水曜日

[Titanium奮闘記2回目]どっちのOSでも位置情報を連続取得! #TitaniumJP



○いきなりエラー

昨日のやつをAndroid実機で載せたらエラー吐いた。

Location:[47.22] find.js
Message:Uncaught ReferencError: cLocLat is not defined.

これはvarが抜けてたからでした。

ところでなんでgetCurrentPosition書いてるのか忘れてましたが、地図を拡大&スクロールさせるためでした。

それで思い出したけど、地図を拡大してほしいのに全く拡大してくれない謎エラーがあったっけ。
どうすればいいか分からなかったので、とりあえず昨日まで使ってたsetLocationを使わず、代わりにこのように書きました。

Ti.Geolocation.getCurrentPosition(
    function(e) {
        if (!e.success || e.error){
            alert('位置情報が取得できませんでした');
            return;
        }
       
          var cLocLat = e.coords.latitude;
          var cLocLong = e.coords.longitude;

        mapview.show(); // 地図を表示する

        mapview.region = {   // 現在地まで地図をスクロールする
            latitude:cLocLat,
            longitude:cLocLong,
            latitudeDelta:0.01,
            longitudeDelta:0.01
        }
    }
);
うん、なんとかうまく行った。
ただ、Android実機ではiPhoneのように現在地が出てこないので、出てくるように変更したいなぁ…。



○Androidで位置情報取得は難しい?

Androidではなぜか位置情報をうまく拾ってくれない。iPhone(エミュだけど)ではうまく取ってきてくれるのにね。
ここの部分は前からずっと調べてるんですが…この記事がその問題に該当しそうなんだけど…

基本的に裏でサービスが走って、衛星から電波が取れて、位置情報が取れたらアプリにイベントを返す仕組みになっていると思います。
アプリ側はサービスに対して、取得の頻度などを要求できますが、要求通りいくかどうかは、衛星の状態とか、端末のGPSの性能とか、いろいろな条件で変わってくると思われます。なので、不確定な要素があるんです。
http://ti.masuidrive.jp/topic.php?id=2499

マジですか…orz

位置情報の継続的な取得は、下記URLに掲載されているように、
Titanium.Geolocationのlocationイベントを利用すると良いのではないでしょうか。
http://docs.appcelerator.com/titanium/2.1/#!/guide/Tracking_Position_and_Heading-section-29004915_TrackingPositionandHeading-ContinuallymonitortheGPSpositionhttp://ti.masuidrive.jp/topic.php?id=2499

英語読めない…orz
つか、Ti.Geolocation.Androidとかあったのね(´・ω・`)

とりあえずドキュメントのサンプルコードを参考に書いてみた。

var win = Ti.UI.createWindow({
          backgroundColor:'#ffffff'
     });

var providerGps = Ti.Geolocation.Android.createLocationProvider({
    name: Ti.Geolocation.PROVIDER_GPS,
    minUpdateDistance: 0.0,
    minUpdateTime: 0
});

Ti.Geolocation.Android.addLocationProvider(providerGps);
Ti.Geolocation.Android.manualMode = true;

var labelPos = Ti.UI.createLabel({
     text: 'hogehoge',
     height: 70,
     top: 280
});

win.add(labelPos);

var locationCallback = function(e) {
    if (!e.success || e.error) {
          labelPos.text = 'error:' + JSON.stringify(e.error);
    }

     var cLocLat = e.coords.latitude;
     var cLocLong = e.coords.longitude;
     labelPos.text = cLocLat+'\n'+cLocLong ;
};

Titanium.Geolocation.addEventListener('location', locationCallback);

win.open();

これで念願のGPS情報を取り続ける部分が実現できました。


○OSで場合分けをするには

さて問題はiOSではこれは動かないというところ。
とりあえずOSで場合分けが出来たはずなのでやってみることに。

なぜかTi.Platform.modelではだめで、Ti.Platform.osnameだとうまく行きました。
うーん、KitchenSinkだとmodelでも行ってたのになぁ。へんなの。



○二点間の距離を出そう

コードには起こしていませんが、2点間の距離を取るには下のページが参考になりそうですね。

東西の距離(touzaiKyori)= 測定値(大阪)の緯度の半径 × 大阪東京の緯度の差(idoSa)
= コサインaIdo × 地球の半径(earth_r)× 大阪東京の緯度の差(idoSa)

南北の距離(nanbokuKyori)= 地球の半径(earth_r) × 大阪東京の経度の差(keidoSa)

この二つが求まればxの2乗 + yの2乗 = 求める距離の2乗となり、その平方根をもとめることで距離dが求まります。http://www.kiteretsu-so.com/archives/1183

現在地の緯度と経度を「cLocLat」「cLocLong」、仮に福岡タワーまでの距離を求めるとすると、JSではこうなるのか。
PHPで使えるdeg2radは関数にしちゃえ。

var earth_r = 6378.137;

var bLat = 33.593332; //福岡タワーの緯度
var bLong = 130.351408;//福岡タワーの経度
var latSa = deg2rad(bLat - cLat);
var longSa = deg2rad(bLong - cLong);

var nanboku = earth_r * latSa;
var touzai = Math.cos(deg2rad(cLat)) * earth_r * longSa;
var d = Math.sqrt(Math.pow(touzai,2) + Math.pow(nanboku,2));

function deg2rad(deg)
{
    return deg*Math.PI / 180;
}

元のサイトをほぼまねて作っただけでした。ごめんなさい。



○その他雑多メモ

Androidを動かすときにエラーが出たのでそれを覚え書き程度ですが書いときます。

[INSTALL_FAILED_MISSING_SHARED_LIBRARY]
多分直前にAndroidからGoogleAPIに変えたからかな。
これはTitaniumの「環境設定→AptanaStudio→Titanium」で設定したDefaultAndroidSDKと、プロジェクトの「プロパティ→Run/Debug Setting」で設定したAndroidAPIが違うと出るみたい。一緒にしときましょ。

[INSTALL_FAILED_INSUFFICIENT_STORAGE]
これは単純に容量が足りませんよーという意味でしょう。
実機のいらないファイルを消したら消えました。



○明日の予定

・距離がとれるかテスト
・closeを押したら位置情報取得をやめさせる方法(テスト版だし飛ばしてもいいかも
・データベース…(´・ω・`)
・addEventListenerのお勉強
・ドットインストールでGitの勉強をしよう

現段階でWPのインストールもろくに終わってないからすることたくさんだなぁ…(´・ω・`)

0 件のコメント:

コメントを投稿