Reputation: 55
After each fresh install tiles in my MapView
only load after zooming out quite a bit. After that it works fine, but I can't figure out what causes this.
The debug logs are as follows:
D/OsmDroid: SqlCache - Tile doesn't exist: Mapnik/1/0/0
D/OsmDroid: Archives - Tile doesn't exist: /1/0/0
D/OsmDroid: SqlCache - Tile doesn't exist: Mapnik/3/1/3
D/OsmDroid: Archives - Tile doesn't exist: /3/1/3
D/OsmDroid: SqlCache - Tile doesn't exist: Mapnik/5/5/12
...
I have initialized my MapView in onViewCreated
like this:
map = requireView().findViewById(R.id.map);
map.setTileSource(TileSourceFactory.MAPNIK);
map.getZoomController().setVisibility(CustomZoomButtonsController.Visibility.NEVER);
map.setMultiTouchControls(true);
And once I obtained a location fix, the following is executed:
IMapController mapController = map.getController();
mapController.setZoom(10.0);
GeoPoint startingPoint = new GeoPoint(location.getLatitude(), location.getLongitude());
mapController.setCenter(startingPoint);
I have followed the osmdroid tutorial, set the user agent, added the necessary permissions to the manifest and so on. Please let me know, if you need further information.
Edit: I'm using version 6.1.11
Upvotes: 3
Views: 599
Reputation: 4000
Every time you zoom in/out, OsmDroid checks to see if there is a copy of the tile for every tile index within the map view's current boundary. If a copy exists, it will be copied from the tile cache and drawn on the map. If not, the tile will be downloaded from the online map tile database and drawn on the map. The downloaded tile will be saved in the tile cache for quick retrieval the next time those tile indices are in the view's boundary.
It does, however, involve a significant number of tile module provider objects that handle each event. They are saved in the MapTileModuleProviderBase
tile module provider array that is set in MapView.setTileProvider()
call. If the map tile download module provider is not included, it will not download any tiles from the Internet/network; instead, it will retrieve a copy from any attached tile module providers: cache tile module provider, assets tile module provider, file archive module provider, and so on. If any of those tile providers are missing from the tile module provider array, the tile for that tile index will not be drawn properly and you will see an empty grey "tile" square.
These tile module providers may refer to the OsmDroid default configuration instance, the DefaultConfigurationProvider
, for properties that control tile expiration rate, cache size, and so on. These properties affect the tile draw performance.
If you use OsmDroid-specific tile module provider API (MapsForge, GeoPackage, WMS, etc.) to load online/offline map databases which may change the current tile module provider array structure, follow these steps to properly reset to the MAPNIK database:
//load MAPNIK basemap updateable from Internet and cacheable
IFilesystemCache tileWriter = null;
INetworkAvailablityCheck networkAvailabilityCheck = new NetworkAvailabliltyCheck(getContext());
List<MapTileModuleProviderBase> defaultProviders = new ArrayList<>();
SimpleRegisterReceiver simpleRegisterReceiver = new SimpleRegisterReceiver(getContext());
if (Build.VERSION.SDK_INT < 10) {
tileWriter = new TileWriter();
} else {
tileWriter = new SqlTileWriter();
}
defaultProviders.add(new MapTileAssetsProvider(simpleRegisterReceiver, getContext().getAssets()));
final MapTileAssetsProvider assetsProvider = new MapTileAssetsProvider(
simpleRegisterReceiver, getContext().getAssets(), TileSourceFactory.MAPNIK);
defaultProviders.add(assetsProvider);
final MapTileFileStorageProviderBase cacheProvider =
MapTileProviderBasic.getMapTileFileStorageProviderBase(simpleRegisterReceiver, TileSourceFactory.MAPNIK, tileWriter);
defaultProviders.add(cacheProvider);
final MapTileFileArchiveProvider archiveProvider = new MapTileFileArchiveProvider(
simpleRegisterReceiver, TileSourceFactory.MAPNIK);
defaultProviders.add(archiveProvider);
final MapTileApproximater approximationProvider = new MapTileApproximater();
defaultProviders.add(approximationProvider);
approximationProvider.addProvider(assetsProvider);
approximationProvider.addProvider(cacheProvider);
approximationProvider.addProvider(archiveProvider);
final MapTileDownloader downloaderProvider = new MapTileDownloader(TileSourceFactory.MAPNIK, tileWriter, networkAvailabilityCheck);
defaultProviders.add(downloaderProvider);
MapTileModuleProviderBase[] providerArray = new MapTileModuleProviderBase[defaultProviders.size()];
for (int i = 0; i < defaultProviders.size(); i++) {
providerArray[i] = defaultProviders.get(i);
}
Log.i(IMapView.LOGTAG, String.format("reset MAPNIK: current tile module providers(%d) = %s",
providerArray.length,
Arrays.toString(providerArray)));
MapTileProviderArray obj = new MapTileProviderArray(TileSourceFactory.DEFAULT_TILE_SOURCE, simpleRegisterReceiver, providerArray);
mapView.setTileProvider(obj);
mapView.setTileSource(TileSourceFactory.MAPNIK);
Normally, we don't need to explicitly call MapView.invalidate()
(if called from a UI thread) or MapView.postInvalidate()
(if called from a non-UI thread) since this is handled by MapView for tile resources.
public void setTileProvider(final MapTileProviderBase base) {
this.mTileProvider.detach();
mTileProvider.clearTileCache();
this.mTileProvider = base;
mTileProvider.getTileRequestCompleteHandlers().add(mTileRequestCompleteHandler);
updateTileSizeForDensity(mTileProvider.getTileSource());
this.mMapOverlay = new TilesOverlay(mTileProvider, this.getContext(), horizontalMapRepetitionEnabled, verticalMapRepetitionEnabled);
mOverlayManager.setTilesOverlay(mMapOverlay);
invalidate();
}
If you change any of MapView's properties in a thread again, you must call the appropriate map view invalidation to force the redraw. Calling invalidation too frequently will have a negative impact on the app's performance.
Upvotes: 2
Reputation: 71
I had this exact problem. It seems that if you initially set any zoom level > 19, tiles are not rendered correctly.
As a workaround I set zoom level to 19 instead of 20. Then the user is able to set it as he likes
Upvotes: 3
Reputation: 81
Updated:
https://tile.openstreetmap.org/1/0/0.png
This would be the url the tilesource is trying to pull the image from. And as you can see the tile is there.
have you tried invalidating the map to force a redraw?
map.invalidate()
Upvotes: 1