6

AS3 AIR for Android アプリケーションに取り組んでいます。「私の問題は次のとおりです。GPS の位置を指定して、移動方向 (北、北西、西、南西、南、南東、東、北東) を取得したい」

2 つの異なる GPS 測定値を使用して進行方向を推測する方法のコードが必要です。次に、そのデータを 360 度使用したいと思います。

北、南、東、西などの一般的な方向を取得する方法を理解していると思います。私は2つの別々のGPS測定値を取得し、そのようなものを比較します...

1 回目または 2 回目の GPS 測定値で X が大きいかどうかを確認します。1 回目または 2 回目の GPS 測定値で Y が大きいかどうかを確認します。これで大まかな方向性が見えてくるはずです。X1 と X2 の違いと Y1 と Y2 の違いを比較します。次に、ユーザーが最も向かった方向を確認できます。次に、方向を表示します。

データを取得して、コンパスのような 360 度の解釈に使用する方法がわかりません... 誰か助けてくれませんか?

作業コード------------------------------------------------ -------------------------------

package 

{
import flash.display.Sprite;
// Geolocation sensor stuff
import flash.sensors.Geolocation; 
import flash.events.GeolocationEvent;
//Timer setup stuff for setting frequesncy of GPS Update
import flash.utils.Timer;
import flash.events.TimerEvent;

// Sprite and Textfield display
import flash.display.Sprite;
import flash.text.TextField;
import flash.text.TextFieldAutoSize;
import flash.text.TextFormat;


    public class FlashTest extends Sprite 

    {
        //Variable to check if current or prior Geolocation Event fired
        private var gpsCheck:int = 1;
        public var dLon:Number


        //latitude and longitude in degrees (RAW info from Geolocation)
        public var gpsLat1:Number
        public var gpsLon1:Number
        private var gpsLat2:Number
        private var gpsLon2:Number
        public var bearing:Number


        // Latitude and longitude in radians converted from Degrees
        public var gpsLat1R:Number
        public var gpsLon1R:Number
        private var gpsLat2R:Number
        private var gpsLon2R:Number     
        private var yy:Number  
        private var xx:Number          


        public function FlashTest() 

        {
            // Text box for displaying results
            var my_txt:TextField = new TextField();
                my_txt.wordWrap=true; 
                my_txt.width = 300;
                my_txt.height = 300;
                 addChild(my_txt);

            /*
            //If GPS is on device create Geolocation object named "my_geo"
            //Request updates from my_geo every 2000 milliseconds. Run onGeoUpdate function
            //when Event is triggered. After that create the text box for displaying data.
            if (Geolocation.isSupported)
            {
                var my_geo:Geolocation = new Geolocation();
                my_geo.setRequestedUpdateInterval(2000);                
                my_geo.addEventListener(GeolocationEvent.UPDATE, onGeoUpdate);
                var my_txt:TextField = new TextField();
                my_txt.wordWrap=true; 
                my_txt.width = 300;
                my_txt.height = 300;
                addChild(my_txt);
            } 
            // If GPS is not supported on device display "No GPS Signal" 
            else
            {
                addChild(my_txt);
                my_txt.wordWrap=true; 
                my_txt.width = 300;
                my_txt.height = 300;
                addChild(my_txt);
                my_txt.text = "No GPS Signal ";
            }
            */


            // False GPS reading being passed for testing 
            //COMMENT THESE LINES OUT STARTING HERE---
                gpsLat1 =  42.1234584;
                gpsLon1 = -83.1234577;
                gpsLat2 =  42.1234583;
                gpsLon2 = -83.1234577;
           // END OF WHAT SHOULD BE COMMENTED OUT---

           // Equations to convert all RAW Geolocation information over to radians 
                gpsLat1R = gpsLat1 * Math.PI / 180;
                gpsLon1R = gpsLon1 * Math.PI / 180;
                gpsLat2R = gpsLat2 * Math.PI / 180;
                gpsLon2R = gpsLon2 * Math.PI / 180;
          // The rest of the math     
                dLon = gpsLon1 - gpsLon2;
                yy = Math.sin(dLon) * Math.cos(gpsLat2R);
                xx = Math.cos(gpsLat1R) * Math.sin(gpsLat2R) - Math.sin(gpsLat1R) * Math.cos(gpsLat2R) * Math.cos(dLon);
                bearing = Math.atan2(yy, xx) * 180 / Math.PI;
         // Run The Geoupdate function                
            onGeoUpdate();


        // onGeoUpdate basically displays the information that was collected and converted.
        // This is where you will put what you want the code to do with the results
            function onGeoUpdate():void
            {
            my_txt.text = "My Latitude is "+gpsLat1+ " and my Longitude is "+gpsLon1+ 
            "My 2nd Latitude is "+gpsLat2+" and my 2nd Longitude is "+gpsLon2+ 
            " Bearing is " +bearing;

            }            
        }
    }
}
4

3 に答える 3

6

必要な式 ( 2 点のlon1lon2経度、およびlat1lat2緯度) は、多くの場所 (たとえば、http://www.movable-type.co.uk/scripts/latlong.html ) で提供されています。計算は次のようになります (好きな言語に変換してください...):

dLon = lon2 - lon1;
y = sin(dLon) * cos(lat2);
x = cos(lat1) * sin(lat2) - sin(lat1) * cos(lat2) *cos(dLon);
bearing = atan2(y, x) * 180 / Pi;

:atan2結果を [-pi, pi] の間の値に減らします。数値を掛けた後180/piは [-180,180] の間になります。0 から 360 の間の値を取得するには、次のようにします。

if (bearing < 0) bearing += 360;

この作業を行うために必要なその他の詳細を記入していただければ幸いです。

EDIT私はあなたが与えた数字を使って少しのコードを書きました:これはMatlabですが、かなり読みやすいはずです:

% bearings
lat1 = 42.1234584;
lat2 = 42.1234583;
lon1 = -83.1234577;
lon2 = -83.1234510;

% convert to radians:
g2r = pi/180;
lat1r = lat1 * g2r;
lat2r = lat2 * g2r;
lon1r = lon1 * g2r;
lon2r = lon2 * g2r;
dlonr = lon2r - lon1r;
y = sin(dlonr) * cos(lat2r);
x = cos(lat1r)*sin(lat2r) - sin(lat1r) * cos(lat2r)*cos(dlonr);

% compute bearning and convert back to degrees:
bearing = atan2(y, x) / g2r;

fprintf(1,'x: %+.3e\ny: %+.3e\nbearing: %.3f\n', x, y, bearing);

これにより、次の出力が得られます。

x: -1.745e-09
y: +8.673e-08
bearing: 91.153

ご覧のとおり、x小さいyですが、移動した「地球の円周の一部」を表しています (真東に約 3.5 メートルのようです...)。これらの数値を使用して実装をデバッグできるはずです。

ちなみに、GPS の「絶対」精度は低い (この場合、100 m を超える不確実性) 場合がありますが、「相対」精度は良好です (100 m よりもはるかに優れた 2 つの位置の差を測定します)。

于 2013-08-29T20:55:09.510 に答える
2

Location API を使用している場合、場所が変更されるとコールバックが返され、0 ~ 360 度の移動方向を取得できるLocationオブジェクトが返されます。bearing

于 2013-08-29T20:47:07.483 に答える