移植谷歌地图应用到Osmdroid-叠加的问题[英] Porting a Google Maps app to Osmdroid - problem with overlay

本文是小编为大家收集整理的关于移植谷歌地图应用到Osmdroid-叠加的问题的处理/解决方法,可以参考本文帮助大家快速定位并解决问题,中文翻译不准确的可切换到English标签页查看源文。

问题描述

我正在将基于Google Maps的项目移植到OSMdroid才能使用OpenStreetMaps.除了添加我的叠加层之外,端口正常运行确定,该叠加由许多直线和一些文本组成.在两个项目中,我通过定时器线程和处理程序调用RedraWoverlay来添加叠加层.

在OSM项目中,我的叠加只是一个完全隐藏地图的灰色广场.如果我删除了redrawoveraly的调用,则显示OSM块.我在下面的代码样本中将覆盖代码减少到单个对角线的最小值.它在Google App中工作正常,覆盖地图瓷砖. com.google.android.maps.overlay有一个绘制方法,OSM有一个OnDraw,所以我在OSM版本中有:

   private MapView mv;
   private MapOverlay mmapOverlay = null;

   private void redrawOverlay() {

   gPt = mv.getMapCenter();
   if (mmapOverlay == null)
      mmapOverlay = new MapOverlay(getApplicationContext());
      List<Overlay> listOfOverlays = mv.getOverlays();
      listOfOverlays.clear();
      listOfOverlays.add(mmapOverlay);
      mv.invalidate();
   }

   public class MapOverlay extends org.osmdroid.views.overlay.Overlay {

   public MapOverlay(Context ctx) {
      super(ctx);
      // TODO Auto-generated constructor stub
   }

      @Override
      public void onDraw(Canvas canvas, MapView mapView) {

      Paint lp3;
      lp3 = new Paint();
      lp3.setColor(Color.RED);
      lp3.setAntiAlias(true);
      lp3.setStyle(Style.STROKE);
      lp3.setStrokeWidth(1);
      lp3.setTextAlign(Paint.Align.LEFT);
      lp3.setTextSize(12);
      canvas.drawLine(10, 10, 150, 150, lp3);
   }

虽然在谷歌地图中,​​我有等同的:

  public class MapOverlay extends com.google.android.maps.Overlay {


   @Override
   public boolean draw(Canvas canvas, MapView mapView, boolean shadow,
   long when) {
      super.draw(canvas, mapView, shadow);
      Paint lp3;
      lp3 = new Paint();
      .....etc.

除了覆盖的实例只是:

之外,redrawoverlay是相同的
mmapOverlay = new MapOverlay();

所有建议都将被贪心地收到

kurtzmarc的更新问题:

谢谢你到目前为止,我看到你是Osmdroid的作者之一.到目前为止,我喜欢它的表现.我想抑制"跳转到",您可以在双击双击.我想这根本不做什么.我认为它可能会在你的来源中击中这一点并做Zoominfixing:

private class MapViewDoubleClickListener implements GestureDetector.OnDoubleTapListener {
   @Override
   public boolean onDoubleTap(final MotionEvent e) {
   for (int i = mOverlays.size() - 1; i >= 0; i--)
      if (mOverlays.get(i).onDoubleTapUp(e, MapView.this))
         return true;

      final GeoPoint center = getProjection().fromPixels(e.getX(), e.getY());
      return zoomInFixing(center);
  }

似乎我可以覆盖它.我正在使用3.0.1 jar和关联的javadocs.我想知道MapView的SettouchDelegate方法是否有帮助,但在Javadocs中没有引用它.请问你有什么建议吗?

推荐答案

我不确定您正在调用redrawoverlay()的位置,但如果您查看最小overlay,则将看到在屏幕上的固定位置绘制的示例.换句话说,您在屏幕坐标中绘制不在地图坐标.

示例:

@Override
protected void onDraw(final Canvas pC, final MapView pOsmv) {
  // Calculate the half-world size
  final Rect viewportRect = new Rect();
  final Projection projection = pOsmv.getProjection();
  final int zoomLevel = projection.getZoomLevel();
  final int tileZoom = projection.getTileMapZoom();
  mWorldSize_2 = 1 << (zoomLevel + tileZoom - 1);

  // Find what's on the screen
  final BoundingBoxE6 boundingBox = projection.getBoundingBox();
  final Point upperLeft = org.osmdroid.views.util.Mercator
            .projectGeoPoint(boundingBox.getLatNorthE6(), boundingBox.getLonWestE6(),
            zoomLevel + tileZoom, null);
  final Point lowerRight = org.osmdroid.views.util.Mercator
     .projectGeoPoint(boundingBox.getLatSouthE6(), boundingBox.getLonEastE6(), zoomLevel
     + tileZoom, null);

  // Save the Mercator coordinates of what is on the screen
  viewportRect.set(upperLeft.x, upperLeft.y, lowerRight.x, lowerRight.y);

  // Offset into OSM coordinates
  viewportRect.offset(-mWorldSize_2, -mWorldSize_2);

  // Draw a line from one corner to the other
  canvas.drawLine(viewportRect.left, viewportRect.top, viewportRect.right, viewportRect.bottom);

从此,viewportrect表示屏幕左下角的左上角.您可以使用它在屏幕上的任何固定点绘制.

更新:

要回答您的第二个问题 - 您需要做的是覆盖覆盖中的ondoubletap并返回"true".返回"true"表示您"消耗"事件的基类,并且不会发生进一步处理.查看Minimap覆盖代码以获得一个很好的例子:

http://code.google.com/p/osmdroid/source/browse/trunk/osmdroid-android/src/org/osmdroid/views/overlay/minimapoverlay.java

我们是在改革叠加层的中间,因此其中一些将在不久的将来处理一点.例如,getoverlays().清除()错误您还在其他地方报告,我们自修复了它.

本文地址:https://www.itbaoku.cn/post/102445.html

问题描述

I'm porting a Google Maps based project to Osmdroid in order to use OpenStreetMaps. The port is working OK apart from adding my overlay which consists of a number of straight lines and some text. In both projects I add the Overlay by means of a timer thread and handler calling redrawOverlay.

In the OSM project my overlay is just a grey square completely hiding the map. If I remove the call to redrawOveraly, the OSM tiles are shown OK. I've reduced the overlay code to the bare minimum of a single diagonal line in the code samples below. It works fine in the Google app, overlaying the map tile. The com.google.android.maps.Overlay has a draw method, the OSM has an onDraw, so I have in the OSM version:

   private MapView mv;
   private MapOverlay mmapOverlay = null;

   private void redrawOverlay() {

   gPt = mv.getMapCenter();
   if (mmapOverlay == null)
      mmapOverlay = new MapOverlay(getApplicationContext());
      List<Overlay> listOfOverlays = mv.getOverlays();
      listOfOverlays.clear();
      listOfOverlays.add(mmapOverlay);
      mv.invalidate();
   }

   public class MapOverlay extends org.osmdroid.views.overlay.Overlay {

   public MapOverlay(Context ctx) {
      super(ctx);
      // TODO Auto-generated constructor stub
   }

      @Override
      public void onDraw(Canvas canvas, MapView mapView) {

      Paint lp3;
      lp3 = new Paint();
      lp3.setColor(Color.RED);
      lp3.setAntiAlias(true);
      lp3.setStyle(Style.STROKE);
      lp3.setStrokeWidth(1);
      lp3.setTextAlign(Paint.Align.LEFT);
      lp3.setTextSize(12);
      canvas.drawLine(10, 10, 150, 150, lp3);
   }

Whilst in the Google maps original I have the equivalent :

  public class MapOverlay extends com.google.android.maps.Overlay {


   @Override
   public boolean draw(Canvas canvas, MapView mapView, boolean shadow,
   long when) {
      super.draw(canvas, mapView, shadow);
      Paint lp3;
      lp3 = new Paint();
      .....etc.

redrawOverlay is the same except the instantiation of the overlay is just:

mmapOverlay = new MapOverlay();

All suggestions will be gratefully received

UPDATE Question for kurtzmarc:

Thanks for you help so far, I see that you are one of the authors of Osmdroid. I like what it's doing so far. I would like to suppress the 'jump to and zoom in' that you get on double tap. I'd like it to do nothing at all. I think it's probably hitting this bit in your source and doing the zoomInFixing:

private class MapViewDoubleClickListener implements GestureDetector.OnDoubleTapListener {
   @Override
   public boolean onDoubleTap(final MotionEvent e) {
   for (int i = mOverlays.size() - 1; i >= 0; i--)
      if (mOverlays.get(i).onDoubleTapUp(e, MapView.this))
         return true;

      final GeoPoint center = getProjection().fromPixels(e.getX(), e.getY());
      return zoomInFixing(center);
  }

It doesn't seem that I can override it. I'm using the 3.0.1 jar and the associated javadocs. I'm wondering if the Mapview's setTouchDelegate method would help, but there is no reference to it in the javadocs. Have you any suggestions please?

推荐答案

I'm not sure where you are calling redrawOverlay() from, but if you look at the MinimapOverlay you will see an example where something is drawn at a fixed location on the screen. In other words, you are drawing in screen coordinates not in map coordinates.

Example:

@Override
protected void onDraw(final Canvas pC, final MapView pOsmv) {
  // Calculate the half-world size
  final Rect viewportRect = new Rect();
  final Projection projection = pOsmv.getProjection();
  final int zoomLevel = projection.getZoomLevel();
  final int tileZoom = projection.getTileMapZoom();
  mWorldSize_2 = 1 << (zoomLevel + tileZoom - 1);

  // Find what's on the screen
  final BoundingBoxE6 boundingBox = projection.getBoundingBox();
  final Point upperLeft = org.osmdroid.views.util.Mercator
            .projectGeoPoint(boundingBox.getLatNorthE6(), boundingBox.getLonWestE6(),
            zoomLevel + tileZoom, null);
  final Point lowerRight = org.osmdroid.views.util.Mercator
     .projectGeoPoint(boundingBox.getLatSouthE6(), boundingBox.getLonEastE6(), zoomLevel
     + tileZoom, null);

  // Save the Mercator coordinates of what is on the screen
  viewportRect.set(upperLeft.x, upperLeft.y, lowerRight.x, lowerRight.y);

  // Offset into OSM coordinates
  viewportRect.offset(-mWorldSize_2, -mWorldSize_2);

  // Draw a line from one corner to the other
  canvas.drawLine(viewportRect.left, viewportRect.top, viewportRect.right, viewportRect.bottom);

From here viewportRect represents the upper left to the lower right of the screen. You can use this to draw at any fixed points on the screen.

UPDATE:

To answer your second question - what you need to do is override onDoubleTap in your Overlay and return "true". Returning "true" indicates to the base class that you "consumed" the event and no further processing should take place. Take a look at the minimap overlay code for a good example:

http://code.google.com/p/osmdroid/source/browse/trunk/osmdroid-android/src/org/osmdroid/views/overlay/MinimapOverlay.java

We are right in the middle of overhauling the Overlays, so some of this will be handled a little better in the near future. For example, the getOverlays().clear() bug you ran into has also been reported elsewhere and we've since fixed it.