Search code examples
androidmapsofflineosmdroidmbtiles

MBTiles maps not working in OSMDroid


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


Solution

  • 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;
        }