Yesterday I wrote an article about how to integrate the osmdroid library into an Eclipse project. You may have noticed I didn’t mention anything about actually creating an Activity that actually does something with the freshly installed library.
Let’s change that :-). Below you’ll find a heavily commented example on how to instantiate a MapView using an offline MBTiles map source. Since creating an mbtiles file is also a project on its own, I’ll see if I can write something up about that process soon.
Questions? Let me know!
package com.example.yourproject; import java.io.File; import org.osmdroid.DefaultResourceProxyImpl; import org.osmdroid.ResourceProxy; import org.osmdroid.tileprovider.MapTileProviderArray; import org.osmdroid.tileprovider.modules.IArchiveFile; import org.osmdroid.tileprovider.modules.MBTilesFileArchive; import org.osmdroid.tileprovider.modules.MapTileFileArchiveProvider; import org.osmdroid.tileprovider.modules.MapTileModuleProviderBase; import org.osmdroid.tileprovider.tilesource.XYTileSource; import org.osmdroid.tileprovider.util.SimpleRegisterReceiver; import org.osmdroid.views.MapController; import org.osmdroid.views.MapView; import android.app.Activity; import android.os.Bundle; import android.os.Environment; import android.view.Menu; public class RouteMapActivity extends Activity { @SuppressWarnings("unused") private static final String TAG = "RouteMapActivity"; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); /** * This whole thing revolves around instantiating a MapView class, way, * way below. And MapView requires a ResourceProxy. Who are we to deny * its needs? Let's create one! * * It would have been nice if this was taken care of in the MapView * constructor. Interestingly MapView *has* a constructor that creates a * new DefaultResourceProxyImpl but unfortunately that one doesn't allow * us to specify the parameters we *do* need to set ... */ DefaultResourceProxyImpl resProxy; resProxy = new DefaultResourceProxyImpl(this.getApplicationContext()); /** * A class that implements the ITileSource interface knows how to * convert an InputStream or a file path into a Drawable. It doesn't do * much more than that. The real 'sourcery' is performed by * MapTileFileArchiveProvider which will be introduced shortly. * * What we need is really a BitmapTileSourceBase instance, but this * class is defined as abstract. XYTileSource is not and comes closest * to what we want. * * Comment: I don't quite get why BitmapTileSource base is abstract; it * doesn't contain any abstract methods. */ XYTileSource tSource; tSource = new XYTileSource("mbtiles", ResourceProxy.string.offline_mode, 8, 15, 256, ".png", "http://who.cares/"); /** * Don't think the name SimpleRegisterReceiver is particularly well * chosen. SimpleReceiverRegistrar would have been better because the * only thing SimpleRegisterReceiver does, is wrap the methods * Context.registerReceiver(..) and Context.unregisterReceiver(..). Have * a look at the source if you don't believe me ;-). * * So why does it exist then?? Don't know, but it's quite possible to * just ignore this step and state the Activity implements * IRegisterReceiver and replace the 'simpleReceiver' variable with * 'this' further down (no additional implementation required). */ SimpleRegisterReceiver sr = new SimpleRegisterReceiver(this); /** * The following looks complicated, but really only creates an * iArchiveFile[]. Apparently Marc Kurtz and Nicolas Gramlich, the * authors of MapTileFileArchiveProvider, figured it might be useful to * support multiple files/sources. I guess that might make sense if * you're providing separate files for, for example, cities. * * They also provided quite a bit of logic in MapTileFileArchiveProvider * for handling SD Card inserts and ejects. Additionally, if files are * not explicitly specified they can be dynamically loaded from the * /mnt/sdcard/osmdroid directory, which is a nice feature. */ String packageDir = "/com.example.yourproject"; String p = Environment.getExternalStorageDirectory() + packageDir; File f = new File(p, "TileDatabase.mbtiles"); IArchiveFile[] files = { MBTilesFileArchive.getDatabaseFileArchive(f) }; MapTileModuleProviderBase moduleProvider; moduleProvider = new MapTileFileArchiveProvider(sr, tSource, files); /** * So at this point we have a MapTileModuleProvider that provides * MapTileModules: a MapTileModule looks at one or more sources, which * are *not* ITileSources but IArchiveFiles and provides MapTiles. What, * then, does MapTileProviderArray do? Well, it just adds another layer * to the complexity cake: this makes it possible to set multiple * MapTileModuleProviders, such as an on- and offline source. I'm sure * it's useful for someone, but for simple applications it's probably * too much. */ MapTileModuleProviderBase[] pBaseArray; pBaseArray = new MapTileModuleProviderBase[] { moduleProvider }; MapTileProviderArray provider; provider = new MapTileProviderArray(tSource, null, pBaseArray); /** * Are we there yet??? Create the MapView already! */ MapView mapView = new MapView(this, 256, resProxy, provider); mapView.setBuiltInZoomControls(true); // Zoom in and go to Amsterdam MapController controller = mapView.getController(); controller.setZoom(12); controller.animateTo(new LatLonPoint(52.373444, 4.892229)); // Set the MapView as the root View for this Activity; done! setContentView(mapView); } @Override public boolean onCreateOptionsMenu(Menu menu) { getMenuInflater().inflate(R.menu.activity_route_map, menu); return true; } }
Hi what kind of link should i put inside the tileSource to make it work with MapBox ?
(instead of the http://who.cares/)
the link looks like this : “http://a.tiles.mapbox.com/v3/myusername.map-f1rhoycw/page.html#3.00/0.00/0.00″
so, did you get the answer yet? I m curious as well
thank you
Very helpful, thanks.
Hi there.
Lines controller.animateTo(new LatLonPoint(52.373444, 4.892229)); and
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.activity_route_map, menu);
return true;
}
Give me errors. Some ideas? Thank you very much!!