Search code examples
androidgoogle-mapsosmdroid

osmdroid GoogleTilesOverlay smooth resize zoom


Following the Google Tile Wrapper example, I have implemented a google MapView with an osmdroid GoogleTilesOverlay.

    com.google.android.maps.MapView googleMapView;
    org.osmdroid.google.wrapper.MapView osmdMapView;
    org.osmdroid.google.overlay.GoogleTilesOverlay tiles;

    final MapView googleMapView = (com.google.android.maps.MapView.MapView) findViewById(R.id.plan_mapview);
    osmdMapView = new org.osmdroid.google.wrapper.MapView(gMapView);

    // snip Provider instantiation etc.

   overlayTiles = new GoogleTilesOverlay(provider, getApplicationContext());
   gMapView.getOverlays().add(overlayTiles);

At rest, the overlay tiles render fine however when zooming (pinch or via the controls) the underlying google tiles resize and are replaced smoothly however the osmd overlays aren't resizing.

The result: when zooming in the tiles that remain in view begin to overlap. Conversely when zooming out a gap becomes visible between each tile.

It looks to me like the first step is to sub-class GoogleTilesOverlay so that I can modify the draw() method. But then what?

I've googled hard and found a few pointers towards: a) short-circuiting out of the draw() method when in the middle of an animation b) using the Projector / Matrix classes to determine how to scale the overlay on the fly

Unfortunately I'm not an expert on the Android APIs so not sure which way to go... and then how to best implement a solution.


Solution

  • You need to do a slight modification on the draw method in GoogleTilesOverlay.

    As it is draws a rectangle of a constant size (x,y,x+tileSizePx,y+tileSizePx).

    Easy and rudimentary way to do it, just get two tiles (x,y and x+1,y+1) and Subtract the difference in pixels.

    Look below code:

                    final GeoPoint geoPointUL = new GeoPoint(
                            (int) (Mercator.tile2lat(y, zoomLevel) * 1E6),
                            (int) (Mercator.tile2lon(x, zoomLevel) * 1E6));                    
    
                    final GeoPoint geoPointLR = new GeoPoint(
                            (int) (Mercator.tile2lat(y+1, zoomLevel) * 1E6),
                            (int) (Mercator.tile2lon(x+1, zoomLevel) * 1E6));
    
                    Point pointUL=new Point(), pointLR=new Point();
                    pj.toPixels(geoPointUL, pointUL);
                    pj.toPixels(geoPointLR, pointLR);
                    tileSizePx = pointLR.x - pointUL.x;