Join FlipAndroid.COM Telegram Group: https://t.me/joinchat/F_aqThGkhwcLzmI49vKAiw


Calcular el encabezado correcto correctamente en android

Mi requisito es llevar en Google maps apps en el modo de brújula (se puede ver la demostración cuando haga clic en el current location button twice ):

  • En este modo de compass , los mapas siempre giran en un ángulo de modo que la bluedot arrow siempre apunte a la pantalla superior.

Pero no sé cómo calcular el bearing correcto desde el azimuth, pitch, roll valores de azimuth, pitch, roll .

 public void onSensorChanged(SensorEvent sensorEvent) { switch (sensorEvent.sensor.getType()) { case Sensor.TYPE_ACCELEROMETER: System.arraycopy(sensorEvent.values, 0, mAccelerometers, 0, 3); break; case Sensor.TYPE_MAGNETIC_FIELD: System.arraycopy(sensorEvent.values, 0, mMagnetometers, 0, 3); break; default: break; } float[] rotationMatrix = new float[9]; boolean success = SensorManager.getRotationMatrix(rotationMatrix, null, mAccelerometers, mMagnetometers); if (success) { SensorManager.getOrientation(rotationMatrix, mOrientation); float azimuth = Math.toDegrees(mOrientation[0]); float pitch = Math.toDegrees(mOrientation[1]); float roll = Math.toDegrees(mOrientation[2]); } // cal to updateBearing(); } 

En iOS, CLHeading puede devolver exactamente el heading verdadero. ¿Hay alguna clase que tenga la misma función en android o cómo puedo calcularla?

  • Cómo obtener la ubicación GPS de Android
  • Android Google Maps: ¿Cómo obtener el área que se muestra actualmente en el dispositivo de pantalla?
  • Puntero nulo en la vista inflada al cargar por segunda vez un fragmento de mapa de google
  • Google Maps Android API v2 - detectar el toque en el mapa
  • TileProvider utilizando azulejos locales
  • Obtener el radio del mapa visible en Android
  • ¿Es posible eliminar la sombra de los iconos (elementos) en un googlemap?
  • Error al cargar el mapa. Error al contactar a los servidores de Google. Esto es probablemente un problema de autenticación
  • 3 Solutions collect form web for “Calcular el encabezado correcto correctamente en android”

    Compruebe debajo de Enlace para su problema teniendo-ejemplo

    Ejemplo de rodamiento

    También debajo de la respuesta es similor a su problema.

    ¿Cómo obtengo el cojinete correcto?

     package ymc.ch.bearingexample; import android.content.Context; import android.hardware.GeomagneticField; import android.hardware.Sensor; import android.hardware.SensorEvent; import android.hardware.SensorEventListener; import android.hardware.SensorManager; import android.location.Location; import android.location.LocationListener; import android.location.LocationManager; import android.os.Bundle; import android.util.Log; /** * Utility class that provides bearing values to true north. */ public class BearingToNorthProvider implements SensorEventListener, LocationListener { public static final String TAG = "BearingToNorthProvider"; /** * Interface definition for a callback to be invoked when the bearing changes. */ public static interface ChangeEventListener { /** * Callback method to be invoked when the bearing changes. * @param bearing the new bearing value */ void onBearingChanged(double bearing); } private final SensorManager mSensorManager; private final LocationManager mLocationManager; private final Sensor mSensorAccelerometer; private final Sensor mSensorMagneticField; // some arrays holding intermediate values read from the sensors, used to calculate our azimuth // value private float[] mValuesAccelerometer; private float[] mValuesMagneticField; private float[] mMatrixR; private float[] mMatrixI; private float[] mMatrixValues; /** * minimum change of bearing (degrees) to notify the change listener */ private final double mMinDiffForEvent; /** * minimum delay (millis) between notifications for the change listener */ private final double mThrottleTime; /** * the change event listener */ private ChangeEventListener mChangeEventListener; /** * angle to magnetic north */ private AverageAngle mAzimuthRadians; /** * smoothed angle to magnetic north */ private double mAzimuth = Double.NaN; /** * angle to true north */ private double mBearing = Double.NaN; /** * last notified angle to true north */ private double mLastBearing = Double.NaN; /** * Current GPS/WiFi location */ private Location mLocation; /** * when we last dispatched the change event */ private long mLastChangeDispatchedAt = -1; /** * Default constructor. * * @param context Application Context */ public BearingToNorthProvider(Context context) { this(context, 10, 0.5, 50); } /** * @param context Application Context * @param smoothing the number of measurements used to calculate a mean for the azimuth. Set * this to 1 for the smallest delay. Setting it to 5-10 to prevents the * needle from going crazy * @param minDiffForEvent minimum change of bearing (degrees) to notify the change listener * @param throttleTime minimum delay (millis) between notifications for the change listener */ public BearingToNorthProvider(Context context, int smoothing, double minDiffForEvent, int throttleTime) { mSensorManager = (SensorManager) context.getSystemService(Context.SENSOR_SERVICE); mSensorAccelerometer = mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER); mLocationManager = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE); mSensorMagneticField = mSensorManager.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD); mValuesAccelerometer = new float[3]; mValuesMagneticField = new float[3]; mMatrixR = new float[9]; mMatrixI = new float[9]; mMatrixValues = new float[3]; mMinDiffForEvent = minDiffForEvent; mThrottleTime = throttleTime; mAzimuthRadians = new AverageAngle(smoothing); } //============================================================================================== // Public API //============================================================================================== /** * Call this method to start bearing updates. */ public void start() { mSensorManager.registerListener(this, mSensorAccelerometer, SensorManager.SENSOR_DELAY_UI); mSensorManager.registerListener(this, mSensorMagneticField, SensorManager.SENSOR_DELAY_UI); for (final String provider : mLocationManager.getProviders(true)) { if (LocationManager.GPS_PROVIDER.equals(provider) || LocationManager.PASSIVE_PROVIDER.equals(provider) || LocationManager.NETWORK_PROVIDER.equals(provider)) { if (mLocation == null) { mLocation = mLocationManager.getLastKnownLocation(provider); } mLocationManager.requestLocationUpdates(provider, 0, 100.0f, this); } } } /** * call this method to stop bearing updates. */ public void stop() { mSensorManager.unregisterListener(this, mSensorAccelerometer); mSensorManager.unregisterListener(this, mSensorMagneticField); mLocationManager.removeUpdates(this); } /** * @return current bearing */ public double getBearing() { return mBearing; } /** * Returns the bearing event listener to which bearing events must be sent. * @return the bearing event listener */ public ChangeEventListener getChangeEventListener() { return mChangeEventListener; } /** * Specifies the bearing event listener to which bearing events must be sent. * @param changeEventListener the bearing event listener */ public void setChangeEventListener(ChangeEventListener changeEventListener) { this.mChangeEventListener = changeEventListener; } //============================================================================================== // SensorEventListener implementation //============================================================================================== @Override public void onSensorChanged(SensorEvent event) { switch (event.sensor.getType()) { case Sensor.TYPE_ACCELEROMETER: System.arraycopy(event.values, 0, mValuesAccelerometer, 0, 3); break; case Sensor.TYPE_MAGNETIC_FIELD: System.arraycopy(event.values, 0, mValuesMagneticField, 0, 3); break; } boolean success = SensorManager.getRotationMatrix(mMatrixR, mMatrixI, mValuesAccelerometer, mValuesMagneticField); // calculate a new smoothed azimuth value and store to mAzimuth if (success) { SensorManager.getOrientation(mMatrixR, mMatrixValues); mAzimuthRadians.putValue(mMatrixValues[0]); mAzimuth = Math.toDegrees(mAzimuthRadians.getAverage()); } // update mBearing updateBearing(); } @Override public void onAccuracyChanged(Sensor sensor, int i) { } //============================================================================================== // LocationListener implementation //============================================================================================== @Override public void onLocationChanged(Location location) { // set the new location this.mLocation = location; // update mBearing updateBearing(); } @Override public void onStatusChanged(String s, int i, Bundle bundle) { } @Override public void onProviderEnabled(String s) { } @Override public void onProviderDisabled(String s) { } //============================================================================================== // Private Utilities //============================================================================================== private void updateBearing() { if (!Double.isNaN(this.mAzimuth)) { if(this.mLocation == null) { Log.w(TAG, "Location is NULL bearing is not true north!"); mBearing = mAzimuth; } else { mBearing = getBearingForLocation(this.mLocation); } // Throttle dispatching based on mThrottleTime and minDiffForEvent if( System.currentTimeMillis() - mLastChangeDispatchedAt > mThrottleTime && (Double.isNaN(mLastBearing) || Math.abs(mLastBearing - mBearing) >= mMinDiffForEvent)) { mLastBearing = mBearing; if(mChangeEventListener != null) { mChangeEventListener.onBearingChanged(mBearing); } mLastChangeDispatchedAt = System.currentTimeMillis(); } } } private double getBearingForLocation(Location location) { return mAzimuth + getGeomagneticField(location).getDeclination(); } private GeomagneticField getGeomagneticField(Location location) { GeomagneticField geomagneticField = new GeomagneticField( (float)location.getLatitude(), (float)location.getLongitude(), (float)location.getAltitude(), System.currentTimeMillis()); return geomagneticField; } } 

    Azimut y ubicación son los únicos parámetros necesarios para calcular el encabezamiento.

    La convención para cálculos y transformaciones de ángulos es usarlos en este orden:
    1) Azimut
    2) Pitch
    3) Rodillo

    Para calcular un encabezado, sólo necesita el Azimut. Como se ha demostrado, son los values[0] devueltos desde la llamada a SensorManager.getOrientation

    Luego, convierta de radianes en grados, y asegúrese de que sea positivo:

     float current_measured_bearing = (float) (results[0] * 180 / Math.PI); if (current_measured_bearing < 0) current_measured_bearing += 360; 

    Más detalles en esta respuesta , que también considera el efecto de la orientación del dispositivo .

    FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.