Search code examples
androidopenstreetmaposmdroid

Overlays in osmdroid-android-3.0.3.jar


I'd previously managed to incorporate OpenStreetMaps into my application using osmdroid-android-3.0.1.jar with the great assistance of the answer to my question

Porting a Google Maps app to Osmdroid - problem with overlay

I've now upgraded to using the 3.0.3 jar and can't get my overlay to display.

My app can switch display from Google Maps to OSM and display the same overlay consisting of lines and texts on top of either. The alternative displays each run in their own activity for now, as the classes are similar but do not have absolutely identical methods, or at least they didn't have in 3.0.1. (Ultimately I'd like to use the Osmdroid wrapper jar to combine them in one activity and reduce the duplicate code, but that's a question for a later date) Right now I'd like to get the same functionality as I had with the now deprecated 3.0.1 jar using the new 3.0.3 version.

With the new jar, I still get the mapview displayed OK but the overlay has disappeared. I've had to make some changes to the code, as the 3.0.1 onDraw() method has now been replaced with draw() (just like Google) in the MapOverlay extends org.osmdroid.views.overlay.Overlay class.

All the code in the previous onDraw() (now draw) method has been copied verbatim from the answer to the question referred to above, It worked fine, although I confess to not fully understanding the concepts of worldsize, bounding boxes and the transformation described.

I notice that the method

final Point upperLeft = org.osmdroid.views.util.Mercator
            .projectGeoPoint(boundingBox.getLatNorthE6(), boundingBox.getLonWestE6(),
            zoomLevel + tileZoom, null);

is now deprecated, and I had to remove tileZoom and

final int tileZoom = projection.getTileMapZoom();

to get it to compile.

When I get to the code in the draw() method, I can see in the debugger that all the data necessary to draw the overlay is still present and correct. The drawing is done by lines such as canvas.drawLine(....) and canvas.drawText(....). I've not used the extra parameter to the function (boolean shadow) at all.

My redrawOverlay() method remains as:

private void redrawOverlay() {

    mGpt = mMapVw.getMapCenter();

    if (mmapOverlay == null)
        mmapOverlay = new MapOverlay(this);
    mmapOverlay.setEnabled(true);
    List<Overlay> listOfOverlays = mMapVw.getOverlays();
    int ovlSize = listOfOverlays.size();
    if (ovlSize > 1)
        listOfOverlays.remove(1);
    listOfOverlays.add(mmapOverlay);
    mMapVw.invalidate();
}

(The Google listofOverlays.clear() shouldn't be used as osmdroid 3.0.1 had element 0 as the map itself - hence the remove(1))

I'm wondering what I have to do to modify the existing 3.0.1 code to work with 3.0.3? I'm hoping that one of the authors of might read this question.

Update

By adapting the Minimap overaly as suggested in the answer to the question referred to above, the draw() method for drawing an overlay from top left to bottom right, now becomes:

    @Override
    protected void draw(Canvas pC,  MapView pOsmv, boolean shadow) {
        if(shadow)
            return;

        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);
        // Calculate the half-world size
          final Rect viewportRect = new Rect();
          final Projection projection = pOsmv.getProjection();
          final int zoomLevel = projection.getZoomLevel();
          int mWorldSize_2 = TileSystem.MapSize(zoomLevel) / 2;

          // Save the Mercator coordinates of what is on the screen
          viewportRect.set(projection.getScreenRect());
          // DON'T set offset with either of below
          //viewportRect.offset(-mWorldSize_2, -mWorldSize_2);
          //viewportRect.offset(mWorldSize_2, mWorldSize_2);

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

This works OK


Solution

  • Let me try to suggest a few things:

    1. In the new jar build, calling getOverlays().clear() will no longer remove the map tile overlay. Calling remove(1) may be incorrect now since the map tile overlay is no longer in position 0.

    2. The projection has a method that will get you the screen coordinate rectangle of what is currently on the screen. You can check the coordinates you use to draw your lines with against this rectangle to make sure they intercept it.

    3. Take a look at the new TileSystem class. Anything that was deprecated can be recreated using these functions.