如何在osmdroid中根据地图调整指南针



如何将指南针的方向捕捉到地图的方向?

我在MapView中添加了一个指南针,并启用了这样的地图旋转:

MapView mapView = findViewById(R.id.mapView);
// Enable & add compass
CompassOverlay compassOverlay = new CompassOverlay(this, mapView);
compassOverlay.enableCompass();
mapView.getOverlays().add(compassOverlay);
// Enable map rotation with gestures
mapView.getOverlays().add(new RotationGestureOverlay(mapView));

现在,当地图没有旋转,所以向上是北,向右是东等,指南针工作正常。但当我用手势旋转地图时,指南针不会相应地移动。因此,当设备面向北方,地图处于默认旋转时,指南针会根据地图显示北方,这是正确的。但是,当我将地图顺时针旋转90°时,指南针仍然指向上方,而不是顺时针转动90°。

我试着使用compassOverlay.setPointerMode(true);,但这只是改变了指南针的外观。

在深入研究并考虑Peter的答案时,我找到了一个简单的解决方案(Kotlin(:

  1. 创建一个新的CompassOverlay实例并重写draw()方法
val mapNorthCompassOverlay = object: CompassOverlay(context, mapView) {
override fun draw(c: Canvas?, pProjection: Projection?) {
drawCompass(c, -mapView.mapOrientation, pProjection?.screenRect)
}
}
  1. 将覆盖添加到mapView的实例覆盖列表中:
mapView.overlays.add(mapNorthCompassOverlay)

就是这样。

说明:drawCompass()是一种受保护的方法,但我们可以覆盖使用前一种方法获取手机磁力计数据以获得方位的公共draw()。由于drawCompass()反转方位数据以打印在地图上,这不是我们预期的行为,因此在这种情况下,我们将-mapView.mapOrientation作为参数传递,因为它包含地图北部的信息。此外,此CompassOverlay不需要您使用enableCompass(),这是一种开始侦听传感器方向变化的方法,因此您不需要创建伪OrientationProvider来避免手机浪费资源。

我编辑了之前的答案:指南针似乎只在实际硬件上工作。

请参见:添加指南针以旋转MapView

编辑-使用Raul的解决方案-只将此答案作为历史工件


本帖https://github.com/osmdroid/osmdroid/issues/1647有解决方案。从那里复制,使用灯光编辑。。。

  1. 创建一个新类:MapAlignedCompassOverlay.java,它只是类CompassOverlay.java的复制/重命名,更改包名以匹配您的包,并将类名更改为MapAlignedCompassOverlay

  2. 将函数drawCompass()中的一行从mCompassMatrix.setRotate(-bearing, mCompassRoseCenterX, mCompassRoseCenterY);mCompassMatrix.setRotate(proj.getOrientation(), mCompassRoseCenterX, mCompassRoseCenterY);

  3. 在设置代码中(例如onCreate,如果您在活动中(,使用MapAlignedCompassOverlay替换我的应用程序中的CompassOverlay,只需给它一个假的OrientationProvider就可以了。例如(Kotlin(:

val fakeOrientationProvider = object: IOrientationProvider{
override fun startOrientationProvider(orientationConsumer: IOrientationConsumer?) = true
override fun stopOrientationProvider() = Unit
override fun getLastKnownOrientation(): Float = 0f
override fun destroy() = Unit
}
mapView.overlays.add(MapAlignedCompassOverlay(context, fakeOrientationProvider, mapView).apply {
enableCompass()
onOrientationChanged(0f, fakeOrientationProvider)  // Magically makes it show up.
})

现在你有了一个与地图匹配的指南针。注意,为了证明这一点,您可以启用";"捏转";带有

mapView.overlays.add(RotationGestureOverlay(mapView))

旋转时,请注意指南针始终指向(正北(。

最新更新