How to show an offline mapsforge map initially/immediately when the app starts?
See original GitHub issueIssue Type
[x] Question [x] Bug [ ] Improvement [ ] Build system related [ ] Performance [x] Documentation
Description and/or steps/code to reproduce the problem
Download the attached zip file “OsmDroidMapsforge_problem_showing_map_initially.zip” (680 kb) with a small Android project, including three small mapsforge maps (.map files) in an assets folder which should become copied into the tablet when running the app. Unzip it and open it with Android Studio and run the app in a USB connected Android device.
Environment
Android Studio 3.3.1. I have tested the app in the attached zip file with two tablets (Android 4.4 and 7.1). The below described behaviour is the same for both those tablets.
If it’s a bug, version(s) of android this affects:
All versions probably (at least 4.4 and 7.1 which I have tested)
Version of osmdroid the issue relates to:
osmdroid 6.0.3 and mapsforge 0.8.0
Problem
The problem is: How can you show a map with mapsforge files immediately when the app starts (i.e. without delaying with any further interaction such as e.g. clicking a button)? It seems necessary with some kind of delay, for example triggering a dialog when the user can select a map file. (while some things need to finish in the background I suppose?)
In the attached example code, it does not work when trying to show the map immediately, but there is also a workaround with some delay in a thread, and when that code is used then it works. See the comments below at the end of the onCreate method.
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
MapsForgeTileSource.createInstance(this.getApplication());
Context ctx = getApplicationContext();
Configuration.getInstance().load(ctx, PreferenceManager.getDefaultSharedPreferences(ctx));
setContentView(R.layout.activity_main);
mMapView = (MapView) findViewById(R.id.map);
// Here is the relevant part:
//showOfflineMaps(); // this does NOT work
// However, the following works, but WHY ?
showMapsforgeMapsDelayed(); // this method invokes the above method "showOfflineMaps" from a thread
}
private void showOfflineMaps() {
final File[] maps = assetsFileHelper.getAllMapsforgeFilesInOsmDroidDirectory();
XmlRenderTheme theme = null;
MapsForgeTileSource fromFiles = MapsForgeTileSource.createFromFiles(maps, theme, "rendertheme-v4");
MapsForgeTileProvider forge = new MapsForgeTileProvider(
new SimpleRegisterReceiver(getApplicationContext()),
fromFiles, null);
mMapView.setTileProvider(forge);
mMapView.getController().setZoom(fromFiles.getMinimumZoomLevel());
mMapView.zoomToBoundingBox(fromFiles.getBoundsOsmdroid(), true);
}
private void showMapsforgeMapsDelayed() {
final int milliseconds = 100; // 100 milliseconds seems to be enough for the maps to become displayed without having to click the GUI button
final FragmentActivity activity = this;
final Thread thread = new Thread(new Runnable() {
public void run() {
try {
Thread.sleep(milliseconds);
} catch (InterruptedException e) {
e.printStackTrace();
}
activity.runOnUiThread(new Runnable(){
@Override
public void run() {
showOfflineMaps();
}
});
}
});
thread.start();
}
The following page has a section “Code setup”: https://github.com/osmdroid/osmdroid/wiki/Mapsforge
I suspect that some of that setup code is triggering something in the background but it will not have finished soon enough when the activity is created. Maybe something is missing in that documentation? Maybe there is some callback method that should be implemented to do something when everything needed has really finished in the background, rather than adding a delay as I did in the attached code example? OsmDroidMapsforge_problem_showing_map_initially.zip
Issue Analytics
- State:
- Created 5 years ago
- Comments:5
@TomasJohansson Fair enough, I’ve just fixed the osmdroid vs. Mapsforge doc too.
I understand that the
View.post
syntax can be a bit annoying, but I’m not 100% convinced by your suggestion as there are other map set up cases (e.g. centering the map) that would need the same “AfterLayoutHasCompleted” additional methods.The best we can do I guess is to be more explicit in the doc and in the code samples.
Okay, so it is not specific for Mapsforge only, but it is applicable for Mapsforge code. Therefore, IMHO, the documentation code example for mapsforge could also be more clear about this, since it is currently written as if it is okay to invoke the methods in sequence. (with “mMapView.getController()…” and then “mMapView.zoomToBoundingBox…” directly after)
I suppose it is a very common situation that you want to zoom automatically to the bounding box. (or is it not?) If so, would it not be desirable to make the setup code easier i.e. with less verbose code, so that you can invoke those methods in sequence in an onReady method? I mean, the osmdroid developers might add a convenience methods to be able to do something like this:
Okay I can close the issue since there is a solution i.e. use the post method. Thank you.