I am trying to make an application that relies on offline maps. Openstreet maps became my choice as OSMDroid seems to be used quite heavily. However when I tried it with the offline maps (MBTiles generated using Mobile Atlas creator) the "MapView" class does not display any map on my device. Here is the snippet that lives inside a fragment. I do not see logcat throwing any errors either
public void onActivityCreated(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onActivityCreated(savedInstanceState);
String [] url = {"http://example.org/"};
XYTileSource MBTILESRENDER = new XYTileSource("mbtiles",
ResourceProxy.string.offline_mode,
1, 20, 256,
".png",
url);
DefaultResourceProxyImpl mResourceProxy = new DefaultResourceProxyImpl(getActivity());
SimpleRegisterReceiver simpleReceiver = new SimpleRegisterReceiver(getActivity());
File f = new File(Environment.getExternalStorageDirectory(), "osmdroid/srMbTiles.mbtiles");
Log.e("File ", f.toString() + " PATH:" + f.getAbsolutePath());
if ( f.exists() ) {
Log.d("DEBUG", " #### FIle Exists");
}
IArchiveFile[] files = { MBTilesFileArchive.getDatabaseFileArchive(f) };
MapTileModuleProviderBase moduleProvider = new MapTileFileArchiveProvider(simpleReceiver, MBTILESRENDER, files);
MapTileProviderArray mProvider = new MapTileProviderArray(MBTILESRENDER, null, new MapTileModuleProviderBase[] { moduleProvider });
myOpenMapView = new MapView(getActivity(),
256,mResourceProxy, mProvider);
myOpenMapView.setBuiltInZoomControls(true);
myOpenMapView.setTileSource(MBTILESRENDER);
IMapController controller = (IMapController) myOpenMapView.getController();
controller.setZoom(12);
getActivity().setContentView(myOpenMapView);
}
Any help would be greatly appreciated. Thanks in advance
I had the same error and the problem was that specified zoom level didn't existed and no map was shown. Try to change zoom level to a function like max/min zoom level. Also my implementation differs from yours.
I followed this tutorial to implement Offline MBTiles maps, and in the main activity i've modified it this way:
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Create the mapView with an MBTileProvider
DefaultResourceProxyImpl resProxy;
resProxy = new DefaultResourceProxyImpl(this.getApplicationContext());
String path = Environment.getExternalStorageDirectory() + "/LocalPath/";
File file = new File(path, "file.mbtiles");
MBTileProvider provider = new MBTileProvider(this, file);
mapView = new MapView(this,
resProxy,
provider);
mapView.setScrollableAreaLimit(provider.getBoundingBox());
mapView.zoomToBoundingBox(provider.getBoundingBox());
// Set the MapView as the root View for this Activity; done!
setContentView(mapView);
mapView.setBuiltInZoomControls(true);
MapController controller = (MapController) mapView.getController();
//desired zoom level (here we use maximum)
controller.setZoom(provider.getTileSource().getMaximumZoomLevel());
}
Also, you are using a map with defined boundaries, so it's desirable to tell the map to attach to them. This is done with the instruction:
mapView.setScrollableAreaLimit(provider.getBoundingBox());
I've done this by modifying MBTileSource.java this way:
protected MBTileSource(int minZoom,
int maxZoom,
BoundingBoxE6 box,
int tileSizePixels,
File file,
SQLiteDatabase db) {
super("MBTiles", resourceId, minZoom, maxZoom, tileSizePixels, ".png");
this.bbox = box;
archive = file;
database = db;
}
public static MBTileSource createFromFile(File file) {
//original stuff
//added
// Get the MBTiles limits
Cursor box = db.rawQuery("SELECT value FROM metadata WHERE name='bounds' LIMIT 0,1",
new String[] {});
BoundingBoxE6 bbox = null;
if (box.moveToFirst())
{
String rawBox = box.getString(box.getColumnIndex("value"));
StringTokenizer tokens=new StringTokenizer(rawBox, ",");
double fourth = Double.parseDouble((String) tokens.nextElement());
double third = Double.parseDouble((String) tokens.nextElement());
double second = Double.parseDouble((String) tokens.nextElement());
double first = Double.parseDouble((String) tokens.nextElement());
bbox = new BoundingBoxE6(first,second,third,fourth);
}
box.close();
return new MBTileSource(minZoomLevel, maxZoomLevel, bbox, tileSize, file, db);
}
public BoundingBoxE6 getBoundingBox()
{
return this.bbox;
}