Skip to content

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
    }
})