Рассчитать компасный пеленг / направление к местоположению в Android

Я хочу отобразить стрелку в моем местоположении на карте Google, которая отображает мое направление относительно места назначения (вместо севера).

а) Я рассчитал север, используя значения датчиков магнитометра и акселерометра. Я знаю, что это правильно, потому что он совпадает с компасом, используемым в представлении Google Map.

б) Я рассчитал начальный пеленг от моего местоположения до места назначения с помощью myLocation.bearingTo (destLocation);

Мне не хватает последнего шага; из этих двух значений (a и b) какую формулу я использую, чтобы получить направление, в котором указывает телефон относительно места назначения?

Благодарим за любую помощь для тупого ума!


person Damian    schedule 29.11.2010    source источник
comment
Возможно, вы захотите проверить это сообщение в блоге о датчиках и ориентации экрана: android-developers.blogspot.com/2010/09/   -  person Cheryl Simon    schedule 30.11.2010
comment
Спасибо, я уже прочитал ту статью. К сожалению, это не решает проблему, поставленную в вопросе.   -  person Damian    schedule 30.11.2010
comment
Я нашел здесь решение, которое меня хорошо сработало stackoverflow.com/questions/7978618/   -  person dharan    schedule 17.09.2012


Ответы (11)


Хорошо, я понял это. Для всех, кто пытается это сделать, вам понадобятся:

a) заголовок: ваш курс по аппаратному компасу. Это в градусах к востоку от магнитного севера.

б) пеленг: пеленг от вашего местоположения до места назначения. Это в градусах к востоку от истинного севера.

myLocation.bearingTo(destLocation);

c) склонение: разница между истинным севером и магнитным севером.

Направление, возвращаемое магнитометром + акселерометром, выражается в градусах к востоку от истинного (магнитного) севера (от -180 до +180), поэтому вам нужно получить разницу между севером и магнитным севером для вашего местоположения. Эта разница варьируется в зависимости от того, где вы находитесь на Земле. Вы можете получить, используя класс Geom MagneticField.

GeomagneticField geoField;

private final LocationListener locationListener = new LocationListener() {
   public void onLocationChanged(Location location) {
      geoField = new GeomagneticField(
         Double.valueOf(location.getLatitude()).floatValue(),
         Double.valueOf(location.getLongitude()).floatValue(),
         Double.valueOf(location.getAltitude()).floatValue(),
         System.currentTimeMillis()
      );
      ...
   }
}

Вооружившись ими, вы рассчитываете угол стрелки, которую нужно нарисовать на карте, чтобы показать, где вы смотрите по отношению к объекту назначения, а не к истинному северу.

Сначала отрегулируйте направление по склонению:

heading += geoField.getDeclination();

Во-вторых, вам нужно сместить направление, в котором телефон смотрит (курс) от целевого пункта назначения, а не истинный север. Это та часть, на которой я застрял. Значение направления, возвращаемое компасом, дает вам значение, которое описывает, где находится магнитный север (в градусах к востоку от истинного севера) относительно того, куда указывает телефон. Так, например, Если значение равно -10, вы знаете, что магнитный север находится на 10 градусов слева от вас. Пеленг показывает угол вашего пункта назначения в градусах к востоку от истинного севера. Итак, после того, как вы скомпенсировали склонение, вы можете использовать формулу ниже, чтобы получить желаемый результат:

heading = myBearing - (myBearing + heading); 

Затем вы захотите преобразовать градусы к востоку от истинного севера (от -180 до +180) в нормальные градусы (от 0 до 360):

Math.round(-heading / 360 + 180)
person Damian    schedule 30.11.2010
comment
это опечатка в твоей строке? заголовок + - geoField.getDeclination (); или что вы имеете в виду с + - ?? - person Henry; 03.02.2011
comment
когда вы говорите заголовок = myBearing - (myBearing + заголовок); там ошибка ?? Это как сказать заголовок = заголовок. - person ; 12.03.2011
comment
@Nikolas на самом деле это как сказать заголовок = -heading. - person Ilya Saunkin; 24.08.2011
comment
Извините, я не понимаю смысл вашего кода @Damien. Ваш начальный курс эквивалентен заданному азимуту от onOrientationChanged в градусах. Чтобы получить направление к вашему целевому местоположению, вы просто меняете азимут на * -1? Как это должно работать? - person dhesse; 03.09.2011
comment
Может кто-нибудь объяснить это, пожалуйста? Это работает? Потому что я всегда получаю курс на 180 градусов, используя этот метод. Кроме того, dhesse правильно, почему мы делаем это, когда это просто заголовок = -heading? Мне кажется, здесь что-то не так, но 14 человек это одобрили. - person datWooWoo; 28.06.2012
comment
@lespommes Вы в этом разобрались? Я также всегда получаю направление на 180 градусов, используя этот код: - /! - person Nick; 01.12.2012
comment
Ваша идея очень хороша, и она мне очень помогла, но я использовал другой код для подсчета значений для вращающейся стрелки. Мои коды ниже в моем ответе. - person CookieMonssster; 12.03.2013
comment
Как именно вы двигаетесь? Это то же самое, что и значение, полученное из location.getBearing ()? - person Price; 15.07.2014
comment
Этот код всегда возвращает только 180 градусов. Это не так. - person portfoliobuilder; 26.10.2016
comment
@Damian Это давно, но не могли бы вы ответить на комментарий выше. Как именно вы попадаете в курс? Это то же самое / приблизительное значение, которое было получено из location.getBearing () или oldLocation.bearingTo (newLocation)? - person NamNH; 16.02.2017

@Damian - Идея очень хорошая, и я согласен с ответом, но когда я использовал ваш код, у меня были неправильные значения, поэтому я написал это сам (кто-то сказал то же самое в ваших комментариях). Считать курс со склонением, я думаю, это хорошо, но позже я использовал что-то вроде этого:

heading = (bearing - heading) * -1;

вместо кода Дамиана:

heading = myBearing - (myBearing + heading); 

и изменив -180 на 180 для 0 до 360:

      private float normalizeDegree(float value){
          if(value >= 0.0f && value <= 180.0f){
              return value;
          }else{
              return 180 + (180 + value);
          }

а затем, когда вы хотите повернуть стрелку, вы можете использовать такой код:

      private void rotateArrow(float angle){

            Matrix matrix = new Matrix();
            arrowView.setScaleType(ScaleType.MATRIX);
            matrix.postRotate(angle, 100f, 100f);
            arrowView.setImageMatrix(matrix);
      }

где arrowView - это ImageView со стрелкой, а параметры 100f в postRotate - это pivX и pivY).

Надеюсь, я кому-нибудь помогу.

person CookieMonssster    schedule 12.03.2013
comment
Я не понимаю, почему вы используете * -1 при расчете заголовка - person edoardotognoni; 10.06.2013
comment
normalizeDegree излишне сложен. Вы можете сделать то же самое с return (value + 360) % 360 - person Alexander; 20.06.2014
comment
return 180 + (180 + value); - person brainmurphy1; 29.07.2014
comment
в чем разница между подшипником и моим подшипником? - person Wasim Ahmed; 27.02.2015
comment
почему заголовок = (подшипник - заголовок) * -1, а не просто заголовок - = подшипник - person WindRider; 18.03.2015
comment
Я сделал этот код два года назад и точно не могу вспомнить, почему я сделал это таким образом, но он работал правильно - person CookieMonssster; 22.03.2015
comment
Как мне получить начальное значение заголовка? Я не вижу этого по твоему или Дамиану. Могу ли я как-нибудь получить это из объекта geoField? - person Tim Cooper; 31.01.2018

Здесь стрелка на компасе показывает направление от вашего местоположения к Каабе (Место назначения).

вы можете просто использовать BearingTo таким образом. bearing to даст вам прямой угол от вашего местоположения до места назначения

  Location userLoc=new Location("service Provider");
    //get longitudeM Latitude and altitude of current location with gps class and  set in userLoc
    userLoc.setLongitude(longitude); 
    userLoc.setLatitude(latitude);
    userLoc.setAltitude(altitude);

   Location destinationLoc = new Location("service Provider");
  destinationLoc.setLatitude(21.422487); //kaaba latitude setting
  destinationLoc.setLongitude(39.826206); //kaaba longitude setting
  float bearTo=userLoc.bearingTo(destinationLoc);

BearTo даст вам диапазон от -180 до 180, что немного запутает. Нам нужно будет преобразовать это значение в диапазон от 0 до 360, чтобы получить правильное вращение.

Это таблица того, что мы действительно хотим, в сравнении с тем, что дает нам BearTo.

+-----------+--------------+
| bearingTo | Real bearing |
+-----------+--------------+
| 0         | 0            |
+-----------+--------------+
| 90        | 90           |
+-----------+--------------+
| 180       | 180          |
+-----------+--------------+
| -90       | 270          |
+-----------+--------------+
| -135      | 225          |
+-----------+--------------+
| -180      | 180          |
+-----------+--------------+

поэтому мы должны добавить этот код после BearTo

// If the bearTo is smaller than 0, add 360 to get the rotation clockwise.

  if (bearTo < 0) {
    bearTo = bearTo + 360;
    //bearTo = -100 + 360  = 260;
}

вам необходимо реализовать SensorEventListener и его функции (onSensorChanged, onAcurracyChabge) и написать весь код внутри onSensorChanged

Полный код компаса направления Киблы находится здесь

 public class QiblaDirectionCompass extends Service implements SensorEventListener{
 public static ImageView image,arrow;

// record the compass picture angle turned
private float currentDegree = 0f;
private float currentDegreeNeedle = 0f;
Context context;
Location userLoc=new Location("service Provider");
// device sensor manager
private static SensorManager mSensorManager ;
private Sensor sensor;
public static TextView tvHeading;
   public QiblaDirectionCompass(Context context, ImageView compass, ImageView needle,TextView heading, double longi,double lati,double alti ) {

    image = compass;
    arrow = needle;


    // TextView that will tell the user what degree is he heading
    tvHeading = heading;
    userLoc.setLongitude(longi);
    userLoc.setLatitude(lati);
    userLoc.setAltitude(alti);

  mSensorManager =  (SensorManager) context.getSystemService(SENSOR_SERVICE);
    sensor = mSensorManager.getDefaultSensor(Sensor.TYPE_ORIENTATION);
    if(sensor!=null) {
        // for the system's orientation sensor registered listeners
        mSensorManager.registerListener(this, sensor, SensorManager.SENSOR_DELAY_GAME);//SensorManager.SENSOR_DELAY_Fastest
    }else{
        Toast.makeText(context,"Not Supported", Toast.LENGTH_SHORT).show();
    }
    // initialize your android device sensor capabilities
this.context =context;
@Override
public void onCreate() {
    // TODO Auto-generated method stub
    Toast.makeText(context, "Started", Toast.LENGTH_SHORT).show();
    mSensorManager.registerListener(this, sensor, SensorManager.SENSOR_DELAY_GAME); //SensorManager.SENSOR_DELAY_Fastest
    super.onCreate();
}

@Override
public void onDestroy() {
    mSensorManager.unregisterListener(this);
Toast.makeText(context, "Destroy", Toast.LENGTH_SHORT).show();

    super.onDestroy();

}
@Override
public void onSensorChanged(SensorEvent sensorEvent) {


Location destinationLoc = new Location("service Provider");

destinationLoc.setLatitude(21.422487); //kaaba latitude setting
destinationLoc.setLongitude(39.826206); //kaaba longitude setting
float bearTo=userLoc.bearingTo(destinationLoc);

  //bearTo = The angle from true north to the destination location from the point we're your currently standing.(asal image k N se destination taak angle )

  //head = The angle that you've rotated your phone from true north. (jaise image lagi hai wo true north per hai ab phone jitne rotate yani jitna image ka n change hai us ka angle hai ye)



GeomagneticField geoField = new GeomagneticField( Double.valueOf( userLoc.getLatitude() ).floatValue(), Double
        .valueOf( userLoc.getLongitude() ).floatValue(),
        Double.valueOf( userLoc.getAltitude() ).floatValue(),
        System.currentTimeMillis() );
head -= geoField.getDeclination(); // converts magnetic north into true north

if (bearTo < 0) {
    bearTo = bearTo + 360;
    //bearTo = -100 + 360  = 260;
}

//This is where we choose to point it
float direction = bearTo - head;

// If the direction is smaller than 0, add 360 to get the rotation clockwise.
if (direction < 0) {
    direction = direction + 360;
}
 tvHeading.setText("Heading: " + Float.toString(degree) + " degrees" );

RotateAnimation raQibla = new RotateAnimation(currentDegreeNeedle, direction, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);
raQibla.setDuration(210);
raQibla.setFillAfter(true);

arrow.startAnimation(raQibla);

currentDegreeNeedle = direction;

// create a rotation animation (reverse turn degree degrees)
RotateAnimation ra = new RotateAnimation(currentDegree, -degree, 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
image.startAnimation(ra);

currentDegree = -degree;
}
@Override
public void onAccuracyChanged(Sensor sensor, int i) {

}
@Nullable
@Override
public IBinder onBind(Intent intent) {
    return null;
}

xml-код здесь

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@drawable/flag_pakistan">
<TextView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:id="@+id/heading"
    android:textColor="@color/colorAccent"
    android:layout_centerHorizontal="true"
    android:layout_marginBottom="100dp"
    android:layout_marginTop="20dp"
    android:text="Heading: 0.0" />
<RelativeLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@+id/heading"
android:scaleType="centerInside"
android:layout_centerVertical="true"
android:layout_centerHorizontal="true">

<ImageView
    android:id="@+id/imageCompass"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:scaleType="centerInside"
    android:layout_centerVertical="true"
    android:layout_centerHorizontal="true"
    android:src="@drawable/images_compass"/>

<ImageView
    android:id="@+id/needle"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_centerVertical="true"
    android:layout_centerHorizontal="true"
    android:scaleType="centerInside"
    android:src="@drawable/arrow2"/>
</RelativeLayout>
</RelativeLayout>
person Muhammad Kashif Arif    schedule 29.05.2017
comment
Спасибо за этот ответ, но в некоторых местах, например в Канаде или Аргентине, голова Киблы показывает неправильное направление. - person TheTallWitch; 05.04.2018
comment
Я нахожусь в Пакистане, и он работает нормально. Эмпирическую проверку во всем мире невозможно. Может вы что-то упустили. - person Muhammad Kashif Arif; 11.04.2018
comment
Я точно следовал вашему коду, и он отлично работает в Иране, и в большинстве мест, которые я проверил, я дал позицию в Канаде просто для проверки, и направление было неправильным. Я также проверил множество существующих доступных приложений Qibla Finder, у них также была эта проблема с некоторыми конкретными местоположениями. - person TheTallWitch; 12.04.2018
comment
Во встроенной функции будет ошибка, или вы могли допустить ошибку. если будет ошибка, то она будет исправлена ​​в последней версии. потому что это встроенная функция. - person Muhammad Kashif Arif; 09.06.2018
comment
Я не исследовал это полностью, но внимательно прочитал docs сообщает: возвращает приблизительное начальное азимут. Это что-то вроде направления, в котором вы должны начать идти, чтобы добраться до пункта назначения по кратчайшему пути через земной шар (то есть шар). - person ngmir; 24.06.2018
comment
См. объяснение здесь что такое начальный подшипник. Это может объяснить, почему вы получаете хорошие результаты в одном месте и не очень хорошие результаты в другом. bearingTo, вероятно, не то, что вы ищете, когда хотите иметь прямое направление на карте. - person ngmir; 24.06.2018
comment
где degree здесь tvHeading.setText("Heading: " + Float.toString(degree) + " degrees" ); и где вы его объявляете / назначаете ???????????????????????? - person sheko; 25.02.2020

Я не эксперт в чтении карт / навигации и т. Д., Но, конечно, «направления» абсолютны, а не относительны, или на самом деле они относительно N или S, которые сами по себе фиксированы / абсолютны.

Пример: предположим, что воображаемая линия, проведенная между вами и местом назначения, соответствует «абсолютной» ЮВ (азимут 135 градусов относительно магнитного N). Теперь предположим, что ваш телефон указывает на северо-запад - если вы проведете воображаемую линию от воображаемого объекта на горизонте до пункта назначения, он пройдет через ваше местоположение и будет иметь угол 180 градусов. Теперь 180 градусов в смысле компаса на самом деле относятся к S, но пункт назначения не является `` из-за S '' воображаемого объекта, на который указывает ваш телефон, и, более того, если вы отправитесь в эту воображаемую точку, ваш пункт назначения все равно будет SE от куда вы переехали.

На самом деле линия 180 градусов фактически говорит вам, что пункт назначения находится «позади вас» относительно того, как указывает телефон (и, предположительно, вы).

Сказав это, однако, если вы хотите вычислить угол линии от воображаемой точки до пункта назначения (проходящей через ваше местоположение), чтобы нарисовать указатель на пункт назначения ... просто вычтите (абсолютное) пеленг пункт назначения от абсолютного пеленга воображаемого объекта и игнорировать отрицание (если оно есть). например, NW - SE составляет 315-135 = 180, поэтому нарисуйте указатель так, чтобы он указывал в нижней части экрана, указывая «позади вас».

РЕДАКТИРОВАТЬ: Я немного ошибся в математике ... вычтите меньший из подшипников из большего, затем вычтите результат из 360, чтобы получить угол, под которым следует рисовать указатель на экране.

person Squonk    schedule 29.11.2010
comment
Спасибо за вашу помощь. Мне удалось понять это и дать ответ ниже для всех, кто сталкивается с той же проблемой. - person Damian; 30.11.2010
comment
Только 2 балла против 37, полученных за (неправильный) принятый ответ? Ну что ж, спасибо, что разместили Squonk, мне очень помогло. - person cjm; 20.01.2015

Если вы находитесь в одном часовом поясе

Конвертировать GPS в UTM

http://www.ibm.com/developerworks/java/library/j-coordconvert/ http://stackoverflow.com/questions/176137/java-convert-lat-lon-to-utm

Координаты UTM дают вам простой X Y 2D

Рассчитайте угол между обоими точками UTM

http://forums.groundspeak.com/GC/index.php?showtopic=146917

Это дает направление, как если бы вы смотрели на север

Итак, что бы вы ни вращали, на север просто вычтите этот угол.

Если обе точки имеют угол UTM 45 °, и вы находитесь на 5 ° к востоку от севера, ваша стрелка будет указывать на 40 ° от севера.

person Pedro    schedule 30.06.2011

Вот как я это сделал:

Canvas g = new Canvas( compass );
Paint p = new Paint( Paint.ANTI_ALIAS_FLAG );

float rotation = display.getOrientation() * 90;

g.translate( -box.left, -box.top );
g.rotate( -bearing - rotation, box.exactCenterX(), box.exactCenterY() );
drawCompass( g, p );
drawNeedle( g, p );
person Sileria    schedule 11.09.2011

Я знаю, что это немного старовато, но ради людей вроде меня из Google, которые не нашли здесь полного ответа. Вот несколько отрывков из моего приложения, в которых стрелки помещаются в настраиваемый список ....

Location loc;   //Will hold lastknown location
Location wptLoc = new Location("");    // Waypoint location 
float dist = -1;
float bearing = 0;
float heading = 0;
float arrow_rotation = 0;

LocationManager lm = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
loc = lm.getLastKnownLocation(LocationManager.GPS_PROVIDER);

if(loc == null) {   //No recent GPS fix
    Criteria criteria = new Criteria();
    criteria.setAccuracy(Criteria.ACCURACY_FINE);
    criteria.setAltitudeRequired(false);
    criteria.setBearingRequired(true);
    criteria.setCostAllowed(true);
    criteria.setSpeedRequired(false);
    loc = lm.getLastKnownLocation(lm.getBestProvider(criteria, true));
}

if(loc != null) {
    wptLoc.setLongitude(cursor.getFloat(2));    //Cursor is from SimpleCursorAdapter
    wptLoc.setLatitude(cursor.getFloat(3));
    dist = loc.distanceTo(wptLoc);
    bearing = loc.bearingTo(wptLoc);    // -180 to 180
    heading = loc.getBearing();         // 0 to 360
    // *** Code to calculate where the arrow should point ***
    arrow_rotation = (360+((bearing + 360) % 360)-heading) % 360;
}

Готов поспорить, что это можно упростить, но это работает! LastKnownLocation использовался, поскольку этот код был взят из нового SimpleCursorAdapter.ViewBinder ()

onLocationChanged содержит вызов notifyDataSetChanged ();

код также из нового SimpleCursorAdapter.ViewBinder () для установки цвета поворота изображения и списка (применяется только в одном столбцеIndex, заметьте) ...

LinearLayout ll = ((LinearLayout)view.getParent());
ll.setBackgroundColor(bc); 
int childcount = ll.getChildCount();
for (int i=0; i < childcount; i++){
    View v = ll.getChildAt(i);
    if(v instanceof TextView) ((TextView)v).setTextColor(fc);
    if(v instanceof ImageView) {
        ImageView img = (ImageView)v;
        img.setImageResource(R.drawable.ic_arrow);
        Matrix matrix = new Matrix();
        img.setScaleType(ScaleType.MATRIX);
        matrix.postRotate(arrow_rotation, img.getWidth()/2, img.getHeight()/2);
        img.setImageMatrix(matrix); 
}

Если вам интересно, что я покончил с драмами о магнитных датчиках, в моем случае это не стоило хлопот. Я надеюсь, что кто-то сочтет это таким же полезным, как и я, когда Google приводит меня в stackoverflow!

person dno    schedule 09.11.2014

Я сейчас пытаюсь понять это, но кажется, что математика зависит от того, где вы и ваша цель находитесь на Земле относительно истинного и магнитного Севера. Например:

float thetaMeThem = 0.0;
if (myLocation.bearingTo(targetLocation) > myLocation.getBearing()){ 
     thetaMeThem = myLocation.bearingTo(targetLocation) - azimuth + declination;} 

См. Азимут в Sensor.TYPE_ORIENTATION.

См. GetDeclination () для определения склонения.

Предполагается, что склонение отрицательное (к западу от истинного севера) и их подшипник> ваш.

Если склонение положительное и yourBearing> theirBearing другой вариант:

float thetaMeThem = 0.0;
if (myLocation.bearingTo(targetLocation) < myLocation.getBearing()){ 
     thetaMeThem = azimuth - (myLocation.bearingTo(targetLocation) - declination);} 

Я не тестировал это полностью, но игра с углами на бумаге привела меня к этому.

person tricknology    schedule 17.08.2012

Это лучший способ определить пеленг по объекту местоположения на карте Google: ->

 float targetBearing=90;

      Location endingLocation=new Location("ending point"); 

      Location
       startingLocation=new Location("starting point");
       startingLocation.setLatitude(mGoogleMap.getCameraPosition().target.latitude);
       startingLocation.setLongitude(mGoogleMap.getCameraPosition().target.longitude);
       endingLocation.setLatitude(mLatLng.latitude);
       endingLocation.setLongitude(mLatLng.longitude);
      targetBearing =
       startingLocation.bearingTo(endingLocation);

person Ramkailash    schedule 13.06.2016

Формула даст азимут с использованием координат начальной точки до конечной точки см.

Следующий код даст вам азимут (угол от 0 до 360).

private double bearing(Location startPoint, Location endPoint) {
    double longitude1 = startPoint.getLongitude();
    double latitude1 = Math.toRadians(startPoint.getLatitude());

    double longitude2 = endPoint.getLongitude();        
    double latitude2 = Math.toRadians(endPoint.getLatitude());

    double longDiff = Math.toRadians(longitude2 - longitude1);

    double y = Math.sin(longDiff) * Math.cos(latitude2);
    double x = Math.cos(latitude1) * Math.sin(latitude2) - Math.sin(latitude1) * Math.cos(latitude2) * Math.cos(longDiff);

    return Math.toDegrees(Math.atan2(y, x));

}

Это работает для меня, надеюсь, что это сработает и для других

person K K    schedule 29.09.2016

Терминология: Разница между ИСТИННЫМ севером и Магнитным Севером известна как «вариация», а не склонение. Разница между показаниями компаса и магнитным курсом называется «отклонением» и зависит от направления. Поворот компаса определяет ошибки устройства и позволяет вносить исправления, если устройство имеет встроенную коррекцию. Магнитный компас будет иметь карту отклонения, которая описывает ошибку устройства на любом направлении.

Склонение: термин, используемый в астронавигации: склонение похоже на широту. Он сообщает, как далеко звезда находится от небесного экватора. Чтобы определить склонение звезды, проследите часовой круг «прямо вниз» от звезды до небесного экватора. Угол от звезды к небесному экватору по часовому кругу - это склонение звезды.

person Simon    schedule 08.08.2012
comment
Если оставить в стороне терминологию, метод Android getDeclination () возвращает: Отклонение горизонтальной составляющей магнитного поля от истинного севера в градусах (т.е. положительное значение означает, что магнитное поле повернуто на восток так же сильно, как и истинный север). - person tricknology; 18.08.2012
comment
Извините, но магнитное склонение - правильный термин. Проверьте ngdc.noaa.gov/geomagmodels/Declination.jsp. Или ребята из NOAA тоже ошибаются? - person Mister Smith; 20.11.2012