tony gil
tony gil

Reputation: 9564

OSMDroid - zoom in without changing tiles, is it possible?

I am developing an android mobile mapping app using OSMDroid (v 4.3). I have established a basemap using arcgisonline as my tile server.

    String[] urlArray = {"http://server.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer/tile/"};
    mapView.setTileSource(new OnlineTileSourceBase("ArcGisOnline", null, 0, 16, 256, "",
            urlArray) {
            @Override
            public String getTileURLString(MapTile aTile) {
                String mImageFilenameEnding = ".png";
                return getBaseUrl() + aTile.getZoomLevel() + "/" + aTile.getY() + "/" + aTile.getX()
                        + mImageFilenameEnding;
            }
    });

Tile server works perfectly well. BUT when zooming in (level 14+), the tile set with satellite imagery has clouds that partially cover the ground, so i would like to know if it is possible to zoom in without changing tile set.

satellite imagery with cloud cover

REAL level 13

zoom13

FAKE zoom simulation (gimp) digital/fake zoom

NOTE: I would lose definition by "blowing up" tile imagery, that is a given. Since, I need to add markers (by tapping on screen) around some plots of land and it becomes too imprecise in zoom13 or impossible to determine correct edges in zoom 14+ with cloud coverage, pixelation in digital zoom is NOT an issue and is perfectly acceptable.

Upvotes: 3

Views: 1054

Answers (1)

M. Haché
M. Haché

Reputation: 354

No, there is no way of doing that without modifying the OSMdroid source code.

However, there is a way you could technically get one more zoom level for each tileset provided without going in the source code.

Instead of using the provided zoom buttons, you would need to create your own. Disable the default zoom buttons.

mapView.setBuiltInZoomControls(false);

Come back when you created you've done your new buttons.

With your new buttons, you would need to keep track of the zoom level you are in. When at a normal zoom level (in this case at the level before the clouds), set the "zoom in" button to do this instead.

mapView.setTilesScaledToDpi(true);

This will scale your map to Dots per inch, thus giving you the result you want. Here's an example.

When set to True. mapView.setTilesScaledToDpi(true);

When set to false. mapView.setTilesScaledToDpi(false);

Don't forget to set back to false when leaving this zoom level.

Downsides to this are, it only gives you one zoom level you can't decide the result, zoom resolution may vary by device, it was not intended to be used in that way and misuse of this could give messy result.

EDIT: You could also change the scaling of the tiles in the Tilesource like here. https://stackoverflow.com/a/25761055/6263209 BUT it would scale tiles on ALL zoom levels which I don't think is what you want.

EDIT 2: Allright since you said that setTilesScaledToDpi didn't work for you, I will try to explain another solution that would have the same effect than the previous ones.

Another solution you could try is having a function that would change the tileSource with a new one with every parameters the same except for the TileSizePixels parameter, which is the fifth one in the line below.

mapView.setTileSource(new OnlineTileSourceBase("ArcGisOnline", null, 0, 16, *Here*->256, "",
        urlArray)

What you could do is set a line in your app which the user could enter how much they want to zoom in on a tileset based on the size of tiles per pixels, and when they would confirm there choice you could call a function that would look like this:

public Void setNewTilesPixels(int tileSizePixels) {
    String[] urlArray = {"http://server.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer/tile/"};
    mapView.setTileSource(new OnlineTileSourceBase("ArcGisOnline", null, 0, 16, tileSizePixels, "",
        urlArray) {
            @Override
            public String getTileURLString(MapTile aTile) {
                String mImageFilenameEnding = ".png";
                return getBaseUrl() + aTile.getZoomLevel() + "/" + aTile.getY() + "/" + aTile.getX()
                    + mImageFilenameEnding;
        }
    });
}

Basically it would just let the user decide the size of the tiles on his screen by creating a new TileSource which is not the most efficient way but so were the previous answers. You can also hardcode the value yourself.

You should probably file an issue for your need on the official gitHub page because right now there are only workaround solutions which should not be the case.

Upvotes: 3

Related Questions