两点之间的位置方位+地球曲率问题



我想实现三件事:

1)基于位置传感器实现指南针+获取当前坐标

2)定方位

3)一旦设置了方位,我想设置一个红色的罗盘针,无论手机旋转如何,它都将继续指向固定的方位。

到目前为止,我已经完成了1 + 2。至于3 -我已经设法将指针指向正确的方向,但随着手机旋转-指针也旋转,失去正确的方向。我试了很多方法,但就是不行。

还有一个问题:如果bearingTo()方法计算两个位置之间的度数-它是否考虑了地球曲率?如果不是,这只会对近距离准确…希望如此:-)

我很感激你的帮助。

这是我的代码-检查注释解释。提前感谢!

    @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
            tvCurrAzim = (TextView) findViewById(R.id.tvaz);
            tvCurrLat = (TextView) findViewById(R.id.tvlat);
            tvCurrLng = (TextView) findViewById(R.id.tvlng);
            tvBearing = (TextView) findViewById(R.id.tvbearing);
            tvIndicator = (TextView) findViewById(R.id.tvindicator);
            ivCompass = (ImageView) findViewById(R.id.imageView1); //compass ImageView
            ivArrow = (ImageView) findViewById(R.id.imageView2); //Red Needle ImageView
            // Get the location manager
            locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
            // Define the criteria how to select the location provider -> use
            // default
            Criteria criteria = new Criteria();
            provider = locationManager.getBestProvider(criteria, true);
            location = locationManager.getLastKnownLocation(provider);
            tvCurrLat.setText(String.valueOf(location.getLatitude()));
            tvCurrLng.setText(String.valueOf(location.getLongitude()));
            from = new Location(location); //creating new Location object
            to = new Location(location); //creating new Location object
    //setting lat,lng to destination Location
            to.setLatitude(newLat);
            to.setLongitude(newLng);
            mSensorManager = (SensorManager) getSystemService(SENSOR_SERVICE);
            mCompass = mSensorManager.getDefaultSensor(Sensor.TYPE_ORIENTATION);
        }
        // Compass Sensor Methods:
        @Override
        public void onAccuracyChanged(Sensor sensor, int accuracy) {
            // TODO Auto-generated method stub
        }
        @Override
        public void onSensorChanged(SensorEvent event) {
            // setting animation for compass
            azimuth = Math.round(event.values[0]);
            tvCurrAzim.setText(Float.toString(azimuth));
            // get the angle around the z-axis rotated
            // float degree = Math.round(event.values[0]);
            // create a rotation animation (reverse turn degree degrees)
            RotateAnimation ra = new RotateAnimation(currentDegree, -azimuth,
                    Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF,
                    0.5f);
            // how long the animation will take place
            ra.setDuration(210);
            // set the animation after the end of the reservation status
            ra.setFillAfter(true);
            // Start the animation
            ivCompass.startAnimation(ra);
            currentDegree = -azimuth;
            pointArrow();
        }
        // Location Manager Methods:
        public void setBearing() {
            from.setLatitude(location.getLatitude()); //setting lat,lng to origin Location
            from.setLongitude(location.getLongitude());
            bearing = Math.round(from.bearingTo(to));
            tvBearing.setText(String.valueOf(bearing));
            hasBearing = true;
            ivArrow.setVisibility(View.VISIBLE);
        }

        public void pointArrow() {
            if (hasBearing) { //once bearing is set
                // get the angle around the z-axis rotated
                float degree1 = Math.round(azimuth) - (float) bearing;
                // create a rotation animation (reverse turn degree degrees)
                RotateAnimation ra1 = new RotateAnimation(currentDegree1, -degree1,
                        Animation.RELATIVE_TO_SELF, 0.5f,
                        Animation.RELATIVE_TO_SELF, 0.5f);
                // how long the animation will take place
                ra1.setDuration(210);
                // set the animation after the end of the reservation status
                ra1.setFillAfter(true);
                // Start the animation
                ivArrow.startAnimation(ra1);
                currentDegree1 = -degree1;
//THIS METHOD WORKS TO POINT THE NEEDLE IN CORRECT DIRECTION, BUT AS PHONE ROTATES THE NEEDLE ROTATES TOO.
//I WANT IT TO KEEP POINTING IN FIXED DIRECTION REGARDLESS OF PHONE ROTATION
            } 
        }
        @Override
        public void onLocationChanged(Location location) {
            tvCurrLat.setText(String.valueOf(location.getLatitude()));
            tvCurrLng.setText(String.valueOf(location.getLongitude()));
            setBearing();
            locationManager.removeUpdates(this);
        }
        @Override
        public void onStatusChanged(String provider, int status, Bundle extras) {
        }
        @Override
        public void onProviderEnabled(String provider) {
        }
        @Override
        public void onProviderDisabled(String provider) {
        }
        @Override
        protected void onPause() {
            // Unregister the listener
            super.onPause();
            locationManager.removeUpdates(this);
            mSensorManager.unregisterListener(this);
            ivArrow.setVisibility(View.INVISIBLE);
        }
        @Override
        protected void onResume() {
            super.onResume();
            locationManager.requestLocationUpdates(provider, 1000, 1, this);
            mSensorManager.registerListener(this, mCompass,
                    SensorManager.SENSOR_DELAY_GAME);
        }

Android docs说bearingTo()使用WGS84椭球体,所以是的,它考虑了地球曲率。

要使你的指南针在设备旋转时稳定使用位置传感器是不够的,你还应该使用磁场传感器。大多数Android设备都有。

你需要SensorManager.getOrientation()看:http://developer.android.com/reference/android/hardware/SensorManager.html

相关内容

  • 没有找到相关文章

最新更新