4

I have a working iOS prototype using the iOS tile-caching technique as shown below (Objective-C code):

RMTileCache  * tileCache = [[RMTileCache alloc] initWithExpiryPeriod:0]; 
[tileCache setBackgroundCacheDelegate:self]; 
RMMapboxSource * tileSource = [[RMMapboxSource alloc] initWithMapID:mapID]; 
[tileCache beginBackgroundCacheForTileSource:tileSource southWest:southWest northEast:northEasth minZoom:minZoom maxZoom:maxZoom];

What this basically does is download the map, cache the tiles permanently and make it possible for the app to run offline in the future. Since we're going through the official payed API, this is of course not violating any of the legal restrictions.

Now I'd like to achieve the same on Android. I have the SDK running in Android Studio and a working project with a remote map using the Map ID, basically this (Android Eclipse layout XML):

<com.mapbox.mapboxsdk.views.MapView
    android:id="@+id/mapview"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    mapid=“my_map_id" />

This works fine, but the solution has to be completely offline once the caching is done. My question is: is there a Java equivalent of the iOS source code above in the MapBox SDK? I attempted to look in the API, but could not find a solid reference to the tile caching system. And after some painful time trying to get it running based on the method names and code documentation, I gave up.

I'm running the latest GitHub distribution of MapBox along with the latest Android Studio, everything's up and running fine, but can't find the code to accomplish this. I don’t necessarily need an API reference, a few lines of code showing how it’s done would be enough.

Yasper
  • 501
  • 5
  • 23

3 Answers3

10

Offline Tile Caching support is now available in the Mapbox Android SDK as of version 0.5.1. It was released on 20-December-2014. Here's a basic example of how to get started:

OfflineMapDownloader offlineMapDownloader = OfflineMapDownloader.getOfflineMapDownloader(getActivity());
BoundingBox boundingBox = mapView.getBoundingBox();
CoordinateSpan span = new CoordinateSpan(boundingBox.getLatitudeSpan(), boundingBox.getLongitudeSpan());
CoordinateRegion coordinateRegion = new CoordinateRegion(mapView.getCenter(), span);
offlineMapDownloader.beginDownloadingMapID("MapboxMapID", coordinateRegion, (int) mapView.getZoomLevel(), (int) mapView.getZoomLevel());

To load a previously saved map:

ArrayList<OfflineMapDatabase> offlineMapDatabases = offlineMapDownloader.getMutableOfflineMapDatabases();
OfflineMapDatabase db = offlineMapDatabases.get(0);
OfflineMapTileProvider tp = new OfflineMapTileProvider(getActivity(), db);
offlineMapOverlay = new TilesOverlay(tp);
mapView.addOverlay(offlineMapOverlay);
Brad Leege
  • 481
  • 5
  • 7
  • How should one use this with the MapView? Does it check if there is an offline version automatically? Or do you have to specify in the mapview that you want to use a offline version. – Aegis Jan 27 '15 at 10:38
  • I just updated the answer with instructions on how to load it back. Hope this helps! – Brad Leege Jan 28 '15 at 16:33
  • I already figured it out from the source :) however I'm have a small issue with downloading the map. I think there is a bug in the SDK when converting the lat/lng numbers. I posted the issue on github [isssue #607](https://github.com/mapbox/mapbox-android-sdk/issues/607) – Aegis Jan 29 '15 at 09:05
  • @BradLeege I keep having out of memory exceptions, is there a proper documentation as to how to make those maps offline ? I am not using the mapview for bounds but using the data coming back from the webapi /v4/MAPID.json ... it seems like the bounds and min and max zoom just blow the memory when it generating all the tiles URLs and adding them to a list. Is it possible to get any help ? I'm using the latest stable version of the library (On Android off course). – TheYann Apr 20 '15 at 17:37
  • @TheYann Memory usage is all tied to the number of tiles being downloaded. The likely cause of this problem is too great a range in min and max zoom levels, as each zoom level has a larger number of tiles that the one above it. Try narrowing the range if possible. – Brad Leege Apr 22 '15 at 02:41
  • @BradLeege Well I tried a lot of things, narrowing the zoom range, as well as the bounds, but still my minimum requirements seems to be too much. I'll try to find a solution and maybe submit a pullrequest. – TheYann Apr 23 '15 at 05:53
2

I asked this question to the support team, here's the answer:

"We don't currently have a release date for the Android SDK or for this feature, because both are in very early stages of development.

-- Tom MacWright support@mapbox.com"

It's a very good product, I hope we can use it soon in Android.

emanukio
  • 21
  • 2
  • Yes, I just got the same answer. I'm with you, MapBox looks perfect on iOS and what is available on Droid looks just as promising. Unfortunately we can't pick it up without this portion. – Yasper Feb 24 '14 at 08:26
  • Does anyone have any idea on the progress of the support of this feature? – Mario Duarte Sep 08 '14 at 12:36
  • 1
    Good news: as of 2 days ago, this is being actively developed! https://github.com/mapbox/mapbox-android-sdk/issues/533 – ValarDohaeris Nov 11 '14 at 05:45
0

In your layout file there must be:

<com.mapbox.mapboxsdk.views.MapView
        android:id="@+id/yourMapViewId"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        />

In code where you want to initialize MapView:

File file = new File("your full path to tiles db");
MBTilesLayer mbTilesLayer = new MBTilesLayer(file);
MapView mapView = (MapView) findViewById(R.id.yourMapViewId);
mapView.setTileSource(mbTilesLayer);
Kevin Kopf
  • 13,327
  • 14
  • 49
  • 66
Žilvinas Rudžionis
  • 1,954
  • 20
  • 28