在 Android 中计算罗盘方位/航向位置

新手上路,请多包涵

我想在谷歌地图视图上的我的位置显示一个箭头,显示我相对于目的地位置(而不是北方)的方向。

a) 我使用磁力计和加速度计的传感器值计算了北方。我知道这是正确的,因为它与 Google 地图视图中使用的指南针对齐。

b) 我已经使用 myLocation.bearingTo(destLocation) 计算了从我的位置到目的地位置的初始方位;

我错过了最后一步;根据这两个值(a 和 b),我使用什么公式来获取手机相对于目标位置的指向方向?

感谢对头脑混乱的任何帮助!

原文由 Damian 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 1k
2 个回答

好的,我想通了。对于其他尝试这样做的人,您需要:

a) 航向:您从硬件罗盘获得的航向。这是在 北以东度数

b) 方位:从您所在位置到目的地位置的方位。这是 北以东的度数。

 myLocation.bearingTo(destLocation);

c) 偏角:真北和磁北之间的差异

从磁力计 + 加速度计返回的航向以真(磁)北(-180 到 +180)以东的度数为单位,因此您需要了解您所在位置的北和磁北之间的差异。这种差异是可变的,具体取决于您在地球上的位置。您可以使用 GeomagneticField 类获取。

 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)

原文由 Damian 发布,翻译遵循 CC BY-SA 2.5 许可协议

@Damian - 这个想法非常好,我同意答案,但是当我使用你的代码时我有错误的价值观,所以我自己写了这个(有人在你的评论中说了同样的话)。我认为用偏角计算航向很好,但后来我使用了类似的东西:

 heading = (bearing - heading) * -1;

而不是达米安的代码:

 heading = myBearing - (myBearing + heading);

并将 0 到 360 的 -180 更改为 180:

       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);
      }

其中 arrowViewImageView 带有箭头图片和100f参数 postRotate 是pivX和pivY。

我希望我能帮助别人。

原文由 CookieMonssster 发布,翻译遵循 CC BY-SA 3.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题