Offline maps, routing and geocoding in the CARTO Mobile SDK require
that you pre-download map data. For this we provide SDK internal API called
PackageManager - this manages offline data packages, which are downloaded from
CARTO server and used by the SDK for specific features.
So for offline mapping (geocoding or routing) you need to
Create and configure PackageManager instance
Download map data for the area what you need using the instance
Create a map layer (geocoding or routing service) by refering to the PackageManager instance
The packages that are once downloaded are kept persistently on the device
and can be updated or removed through the PackageManager as the app requires.
Create and configure Package Manager
1. Data Source ID
When creating PackageManager, you specify package contents by setting source parameter value as following:
carto.streets map data packages (vector tiles) for visual map layer.
routing:carto.streets - routing data packages for Valhalla routing engine
geocoding:carto.streets - geocoding/address search data packages
All these sources are based on OpenStreetMaps map data.
2. Define Folder
App has to decide to which folder the map files are stored. Typically you use standard file locations there, depending on platform. Note that each package source ID should be stored in a different folder, e.g. mappackages, routingpackages, geocodingpackages.
Package downloads for country packages cannot be started immediately, as the Mobile SDK needs to get latest definition of packages from CARTO online service. Once this list is received, PackageManagerListener’s onPackageListUpdated() is called.
Therefore you should write your own PackageManagerListener, and start package download using the onPackageListUpdated method, which ensures that the package metadata is downloaded.
You see that onPackageListUpdated() callback starts immediately download of some packages, as we are quite impatient here. Real download starts when initialization is done and PackageManager is started.
To have offline map data the PackageManager has to download some maps. Thre are two types of offline downloads: code sample above already includes downloading for country ID-s, and you can download also offline maps for any custom areas e.g. cities.
During any package download PackageManagerListener gets onPackageStatusChanged() call back events, this can be used to display progress bar UI.
Using country ID
Se list of available ID-s: https://github.com/CartoDB/mobile-sdk/wiki/List-of-Offline-map-packages
Start download of e.g. Estonia with this PackageManager use method: .startPackageDownload("EE");. Note that you must be sure that the PackageList is downloaded at least once: this is started with .startPackageListDownload() and confirmed in onPackageListUpdated() callback.
Bounding Box
CARTO Mobile SDK allows for the download of custom areas, called bounding boxes. It can be a city or national park for example. Note that there is size limit of about 50x50 km for the allowed areas here. For bigger areas you need to use several downloads, or country package.
A bounding box is constructed as bbox(west longitude,south latitude,east longitude,north latitude, so the bounding box of Berlin would be: bbox(13.2285,52.4698,13.5046,52.57477). There is no separate method for bounding box download start, just use same as string instead of instead of a country or county code, as package ID. So Berlin download would start with .startPackageDownload("bbox(13.2285,52.4698,13.5046,52.57477)");
Note that if you only download bounding box areas in your app, then PackageListDownload is not needed.
Consume PackageManager packages
Offline Map Layers
You should add CartoOfflineVectorTileLayer to the MapView, using PackageManager and map style for offline map layer as constructor parameters.
Warning - until map is downloaded, then this layer will have no map. So you may want to add another online tiled layer with same style, which will be replaced once offline map is downloaded
There is no special event or method to check package updates, so updates can be checked and controlled by application using following logic. You can call this logic as soon as you feel appropriate. Different packages can be updated in different point of time, and with different frequency.
Use packagemanager startPackageListDownload to get server packages
Wait for listener’s onPackageListUpdated event, now server packages were downloaded
Use packageManager getLocalPackages to get already downloaded packages (local packages)
Iterate list of local packages, check from metadata if server package list has newer version of some
If there is newer version, then this package is updated
Updated package download is like normal first download
During re-download of same package application shows old map until download is complete. So the update can run in background safely.
Additional notes
startPackageListDownload method does not need to be called every time when package list is required. In fact, once package list is successfully downloaded, it will remain locally available. But refreshing the contents once a day or perhaps once a week is recommended as some older packages may become available once newer versions are uploaded. getServerPackageListAge method can be used to check the age of the package list data.
Package manager keeps persistent task queue of all submitted requests. Even when it is stopped, downloads will automatically resume when it is started next time.
It is possible to pause downloads by setting task priority to -1. Downloads will resume once priority is set to non-negative number.
PackageInfo class provides two methods for human-readable package names: getName and getNames. getNames takes language argument and will return localized name of the package (assuming the language is supported, currently only major languages such as English, German, French are supported). getNames returns list of names, as some packages can be placed under multiple categories. So, using getNames should be preferred over getName.
Each package includes tile mask. Tile mask basically lists all tiles of the package up to a certain zoom level (currently 10). Tile mask can be used to quickly find a package corresponding to given tile coordinates or to find a package containing given tile.