MyWay
MyWay

Reputation: 1025

Zooming in/out some tiles not rendering - Osmdroid offline maps

I'm loading tiles from asstets, these is my code, which initialize map:

    mapView = (MapView)findViewById(R.id.offline_map_view); 
    mapView.setClickable(true);
    mapView.setBuiltInZoomControls(false);
    mapView.setMaxZoomLevel(macroZoomLevel);
    mapView.setMinZoomLevel(macroZoomLevel);
    mapView.getController().setZoom(macroZoomLevel); //set initial zoom-level, depends on your need
    mapView.setTileSource(new XYTileSource("MapQuest", 0, 18, 256, ".png",new String[] {"file:///android_asset/try/"} ));
    mapView.setUseDataConnection(false); //keeps the mapView from loading online tiles usi1ng network connection.
    mapView.getController().setCenter(new GeoPoint(54.370958, 18.589210));
    giveMarkersForActualLevel();

and everything is ok till I try to zoom in, there are part of maps which not rendering properly. Then I zoom out and then area which was on the beginning rendered properly is now having some gray tiles.

Firstly, I used osmdroid 4.3, added in this way:

 compile 'org.osmdroid:osmdroid-android:4.3'

Then I try with newest version of osmdroid, importing it by method which is described on the website compile 'org.osmdroid:osmdroid-android:5.1@aar'

Then I read here tu build from sources so I download newest sources, build it by gradle and added aar file osmdroid-android-release.aar. This doesn't fix my issue, too.

After zoom in and zoom out, I'm removing markers and adding another ones, so I tried to refresh map in this way.

((View)mapView.getParent()).invalidate();
mapView.invalidate();
mapView.postInvalidate();

Marker startMarker = new Marker(mapView);
startMarker.setPosition(new GeoPoint(54.337385, 18.662132));
setPropertiesForTopMarker(startMarker);
mapView.getOverlays().add(startMarker);

Marker startMarker1 = new Marker(mapView);
startMarker1.setPosition(new GeoPoint(54.332781, 18.587932));
setPropertiesForTopMarker(startMarker1);
mapView.getOverlays().add(startMarker1);

mapView.invalidate();
((View)mapView.getParent()).invalidate();
mapView.invalidate();
mapView.postInvalidate();

but it doesn't work too.

Have you got any ideas, how this issue can be resolved?

EDITED:

I tried to build osmdroid from sources to change this values mentioned by @spy. The debug from my logcat looks ok. Here are logs. I can't paste it here, because there are too many lines.

I tried with adding tiles providers in this way:

 final IRegisterReceiver registerReceiver = new SimpleRegisterReceiver(getApplicationContext());

        final ITileSource tileSource = new XYTileSource("MapQuest", 12, 14, 256, ".png",new String[] {"file:///android_asset/MapQuest/"} );

        final MapTileFilesystemProvider fileSystemProvider = new MapTileFilesystemProvider(
                registerReceiver, tileSource);

        final MapTileProviderArray tileProviderArray = new MapTileProviderArray(
                tileSource, registerReceiver, new MapTileModuleProviderBase[] {
                fileSystemProvider});

        mapView = new MapView(this, new DefaultResourceProxyImpl(this), tileProviderArray); 

or this way

 final IRegisterReceiver registerReceiver = new SimpleRegisterReceiver(getApplicationContext());

            final ITileSource tileSource = new XYTileSource("MapQuest", 12, 14, 256, ".png",new String[] {"file:///android_asset/MapQuest/"} );

            final MapTileFilesystemProvider fileSystemProvider = new MapTileFilesystemProvider(
                    registerReceiver, tileSource);

            final MapTileProviderArray tileProviderArray = new MapTileProviderArray(
                    tileSource, registerReceiver, new MapTileModuleProviderBase[] {
                    fileSystemProvider});

 TilesOverlay tilesOverlay =
                new TilesOverlay(tileProviderArray, getApplicationContext());

        mapView.getOverlays().add(tilesOverlay);

but both methods didn't show me any map. Source of this code.

Upvotes: 2

Views: 2071

Answers (2)

MyWay
MyWay

Reputation: 1025

Ok, finally I solve my issue by using Providers.

I made few modification of code taken from this answer, so right now it looks like this.

        mapView.setClickable(true);
        mapView.setBuiltInZoomControls(false);

        mapView.setMaxZoomLevel(macroZoomLevel);
        mapView.setMinZoomLevel(macroZoomLevel);
        mapView.getController().setZoom(macroZoomLevel); //set initial zoom-level, depends on your need

        mapView.setUseDataConnection(false); //keeps the mapView from loading online tiles usi1ng network connection.
        mapView.getController().setCenter(new GeoPoint(54.370958, 18.589210));

        // save zip to sd
        AssetManager assetManager = this.getAssets();
        InputStream is;
        String fileName = "map.zip";    // the zip file lies in assets root
        String path = this.getExternalFilesDir(null) + File.separator + fileName; // the path I save SD to

        File tileFile = new File(path);
        if(!tileFile.exists()) {
            try {
                is = assetManager.open(fileName);

                FileOutputStream fo = new FileOutputStream(path);

                byte[] b = new byte[1024];
                int length;
                while((length = is.read(b)) != -1) {
                    fo.write(b, 0, length);
                }

                fo.flush();
                fo.close();
                is.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

        IArchiveFile[] archives = new IArchiveFile[1];
        archives[0] = ArchiveFileFactory.getArchiveFile(tileFile);

        // Simple implementation that extends BitmapTileSourceBase and nothing else
        CustomTileSource customTiles = new CustomTileSource("MapQuest", null, 10, 14, 256, ".png");  // Maverik is the name of the folder inside the zip (so zip is map.zip and inside it is a folder called Maverik)

        MapTileModuleProviderBase[] providers = new MapTileModuleProviderBase[1];
        providers[0] = new MapTileFileArchiveProvider(new SimpleRegisterReceiver(this.getApplicationContext()), customTiles, archives);    // this one is for local tiles (zip etc.)



        MapTileProviderArray tileProvider = new MapTileProviderArray(customTiles,
                new SimpleRegisterReceiver(this.getApplicationContext()), providers);
        tilesOverlay = new TilesOverlay(tileProvider, this.getApplicationContext());
        tilesOverlay.setLoadingBackgroundColor(Color.TRANSPARENT);  // this makes sure that the invisble tiles of local tiles are transparent so we can see tiles from web, transparent have a minor performance decline.

        mapView.getOverlays().add(tilesOverlay);

CustomTileSource looks like this:

public class CustomTileSource extends BitmapTileSourceBase {

    public CustomTileSource(String aName, ResourceProxy.string aResourceId, int aZoomMinLevel, int aZoomMaxLevel, int aTileSizePixels, String aImageFilenameEnding) {
        super(aName, aResourceId, aZoomMinLevel, aZoomMaxLevel, aTileSizePixels, aImageFilenameEnding);
    }
}

so this is just subclass of BitmapTileSourceBase without any additional method.

I have in assets zip type file, which name is map.zip, structure of this directory looks like this:

map.zip/MapQuest/[lvlOfZoom]/[x]/[y.png]

And now it works ok, I only zooming when I click on my marker, the user by gesture can't do that.

If you have some problems with implementing approach descripted by me or something isn't clear for you, I will try to help you in comments.

Upvotes: 0

spy
spy

Reputation: 3258

Something worth trying...

If you only want asset loading, then use a custom tile provider array that only includes the asserts loader. In the above config, it will still is the online mechanisms (okhttp or whatever's on the device) to try and download the file from file:/// which may behave strangely with file urls.

Also try turning on tile debugging via OpenStreetMapTileProviderConstants.DEBUGMODE and DEBUG_TILE_PROVIDERS. It may reveal the root cause

Upvotes: 1

Related Questions