Online and Offline maps¶
Online maps¶
The fastest and most easy way to display a map is to turn on the online maps. They are downloaded dynamically depending on the camera position and are cached once downloaded. There are several ways on how to enable online maps. If you want to use online maps directly after the initialization, enable it through the JSON configuration.
val config = SygicEngine.JsonConfigBuilder()
config.mapReaderSettings().startupOnlineMapsEnabled(true)
To turn the online maps on and off dynamically, use the OnlineManager
's enableOnlineMapStreaming()
.
OnlineManagerProvider.getInstance().get().enableOnlineMapStreaming(object : OnlineManager.MapStreamingListener {
override fun onSuccess() {
}
override fun onError(errorCode: OnlineManager.MapStreamingError?) {
}
})
OnlineManagerProvider.getInstance().get().disableOnlineMapStreaming(object : OnlineManager.MapStreamingListener {
override fun onSuccess() {
}
override fun onError(errorCode: OnlineManager.MapStreamingError?) {
}
})
Note
Please note that offline routing can not be executed on cached online maps. Downloaded offline maps are necessary.
If you download an offline map of a country and load it, the online map of that country won't be downloaded.
Offline Maps¶
Applications developed with the Sygic Maps SDK for Android have the ability to pre-load map data, allowing the use of maps, search, routing, and other features without an active data connection. Let's dive right in.
We will work with an instance of MapInstaller
.
You can get the MapInstaller
just like any other instance - via the MapInstallerProvider
.
The available maps are now requested using one call, only (no more Regions -> Countries). The first parameter signifies whether you want to get the maps that are installed in your device already or the ones that are available online. false - online request, true - downloaded maps. The response is cached for 2 hours after the first available maps request and the next requests are therefore almost instantaneous.
If you would like to get the CountryDetails (such as continentName
- using which you can sort the countries
into continents, name
, regions
- if it's a country split map, it will have regions which can be downloaded
separately according to their ISO codes, totalSize
), the usage is shown in the brief sample below.
Again, you can choose whether you would like to explore an online or an already downloaded country.
Attention
Remember that each map needs to be loaded after being downloaded.
Please always use the ISO codes that you get from the MapInstaller
as it's not guaranteed that the MapInstaller
always operates with the ISO 3166 alpha-2 standard.
Order of installation¶
The map installer keeps track of maps that were requested to be installed. It keeps a queue with all the requests and downloads them over time. The order of downloads is given by the queue. The request to install a map is asynchronous, so if the install map function is called in a for loop for example, the requests will be added to the download queue in no particular order.
Info
Currently there is no way to ensure a specific download order via the API.
What happens when SDK is destroyed¶
Map installer supports concurrent downloads. If for any reason the SDK is destroyed (the app that uses the SDK is closed or has crashed), the running and queued map downloads are persistently stored and can be restored on a subsequent initialization of the SDK.
To restore them, the resume pending installations function must be called, which will start the download and installation of the previously persisted map downloads. The restored downloads have priority over new downloads. Learn how to resume pending installations.
In case of a network failure (Internet connection not available, disconnected Wi-Fi, etc.), the download will end with an install error and must be requested again by calling the install map function.
How to install a country¶
var mapInstaller: MapInstaller? = null
MapInstallerProvider.getInstance(object :
CoreInitCallback<MapInstaller> {
override fun onInstance(instance: MapInstaller) {
mapInstaller = instance
}
override fun onError(error: CoreInitException) {}
})
val mapResultListener = object : MapResultListener {
override fun onMapResult(mapIso: String, result: MapInstaller.LoadResult) {
//load the map (mapInstaller?.loadMap(mapIso))
}
}
mapInstaller?.getAvailableCountries(false, object : MapListResultListener {
override fun onMapListResult(mapIsos: List<String>, result: MapInstaller.LoadResult) {
// you receive all of the iso codes of the maps that are available for download
if (mapIsos.isNotEmpty() && result == MapInstaller.LoadResult.Success) {
// if you need to get their full names, just call .getCountryDetails for the specific iso code
mapInstaller?.getCountryDetails(mapIsos.first(), false, object : MapCountryDetailsListener {
override fun onCountryDetails(details: CountryDetails) {
// your code
}
override fun onCountryDetailsError(result: MapInstaller.LoadResult) {}
})
// install a map using an iso code and use the listener that we created above
mapInstaller?.installMap(mapIsos.first(), mapResultListener)
} else {
// error
}
}
})
How to detect the actual country¶
Since the version 17, there's a new functionality - you can now detect a country of where you're located using your IP address and get its ISO code by passing an empty string. If you pass a region ISO code, you will get the ISO code of the country.
mapInstaller.detectCurrentCountry("", object : MapResultListener {
override fun onMapResult(mapIso: String, result: MapInstaller.LoadResult) {
//here you can just call the mapInstaller.installMap(mapIso) to install it directly
}
})
How to restrict downloads to WiFi only¶
If you need to limit the download to Wi-Fi connection only or use specific network options, you can
create a NetworkSettings
object and pass it to the specific download.
val networkSettings = NetworkSettings()
networkSettings.allowRoaming = false
networkSettings.allowMetered = false
MapInstallerProvider.getInstance().get().installMap(
"iso",
networkSettings,
object: MapResultListener{}
)
Resuming pending installations¶
You can add an install progress listener or resume the pending installations like this:
mapInstaller?.addMapProgressInstallListener(object : MapInstallProgressListener {
override fun onMapInstallProgress(mapIso: String, downloadedBytes: Long, totalSize: Long) {
// your code
}
})
mapInstaller?.resumePendingInstallations(object : MapInstallerResumeInfoListener {
override fun onInfoProvided(resumedInstalls: List<ResumedMapInstallerOperation>, resumedUpdates:
List<ResumedMapInstallerOperation>, result: MapInstaller.LoadResult) {
// your code
}
})
Do not forget to remove the listener once you don't need it anymore.
How to cancel a download¶
The installMap
operation is a MapInstaller
task, therefore:
val task = mapInstaller?.installMap("iso", mapResultListener)
task?.cancel()
How to check for updates and update the maps¶
Here's an example of how to check for updates and update the map. Please bear in mind that it serves just as an example and will probably be much more complex in your app.
mapInstaller.checkForUpdates(object : MapListResultListener {
override fun onMapListResult(
mapIsos: List<String>,
result: MapInstaller.LoadResult
) {
if (result == MapInstaller.LoadResult.Success) {
for (mapIso in mapIsos) {
// if the map is a split map, you will get all of the regions along with the
// base map e.g. "de", "de-02", "de-04" - it is enough to call the
// update for "de" and it will update all of the installed regions
mapInstaller.updateMap(mapIso, object: MapResultListener{
override fun onMapResult(
mapIso: String,
result: MapInstaller.LoadResult
) {
if (result == MapInstaller.LoadResult.Success) {
mapInstaller.loadMap(mapIso, object: MapResultListener{
override fun onMapResult(
mapIso: String,
result: MapInstaller.LoadResult
) {
}
})
}
}
})
}
}
}
})
Clearing the cache¶
If you would need to clear the cache of MapInstaller
for any reason, you can do it like this :
mapInstaller.clearCache(object: ResultListener {
override fun onResult(result: MapInstaller.LoadResult) {
// your code
}
})
Changing the language of the names received via getCountryDetails¶
To avoid the necessity of translating the names of countries received via the getCountryDetails()
call,
you can set the locale of the MapInstaller
first. Note that this creates a new request just like requesting
all of the available maps - the whole map list gets cached in the language that is set.
The language tag has to be in the BCP 47 format.
mapInstaller.setLocale("en-US", object: ResultListener {
override fun onResult(result: MapInstaller.LoadResult) {
// your code
}
})