Favorites ¶
In this guide you will learn how to insert a landmark into the favorites, and also how to remove a landmark from the favorites.
Setup ¶
First, get an API key token, see the Getting Started guide.
Download the Maps & Navigation SDK for Android archive file
Download the
Favourites
project
archive file or clone the project with Git
See the Configure Android Example guide.
Run the example ¶
In Android Studio, from the
File
menu, select
Sync
Project
with
Gradle
Files
|
|
The heart icon shows that the landmark is added to the favorites when it is filled, and not added to the favorites when it is just a contour.
How it works ¶

You can open the MainActivity.kt file to see how the a landmark is added to, or removed from, the favorites.
1private lateinit var store: LandmarkStore
2private val searchService = SearchService(
3 onStarted = {
4 progressBar.visibility = View.VISIBLE
5 showStatusMessage("Search service has started!")
6 },
7 onCompleted = { results, errorCode, _ ->
8 progressBar.visibility = View.GONE
9 showStatusMessage("Search service completed with error code: $errorCode")
10 when (errorCode)
11 {
12 GemError.NoError ->
13 {
14 if (results.isNotEmpty())
15 {
16 val landmark = results[0]
17 flyTo(landmark)
18 displayLocationInfo(landmark)
19 showStatusMessage("The search completed without errors.")
20 }
21 else
22 {
23 // The search completed without errors, but there were no results found.
24 showStatusMessage("The search completed without errors, but there were no results found.")
25 }
26 }
27 GemError.Cancel ->
28 {
29 // The search action was cancelled.
30 }
31 else ->
32 {
33 // There was a problem at computing the search operation.
34 showDialog("Search service error: ${GemError.getMessage(errorCode)}")
35 }
36 }
37 }
38)
class
MainActivity
:
AppCompatActivity()
,
an instance of each of the following is created:
var
store:
LandmarkStore
a landmark store, so the favorited landmark(s)
can be written into the data folder;
val
searchService
=
SearchService()
a search service, so that the id
of a result landmark can be obtained.
The search service implements the
onStarted
and
onCompleted
callbacks. When the search completes, if the result list is not empty,
then the first item in the result list (at index 0) is taken and the
camera flies to the location of that result:
val
landmark
=
results[0]
flyTo(landmark)
displayLocationInfo(landmark)
1private fun flyTo(landmark: Landmark) = SdkCall.execute {
2 landmark.geographicArea?.let { area ->
3 gemSurfaceView.mapView?.let { mainMapView ->
4 // Center the map on a specific area using the provided animation.
5 mainMapView.centerOnArea(area)
6 // Highlights a specific area on the map using the provided settings.
7 mainMapView.activateHighlightLandmarks(landmark)
8 }
9 }
10}
flyTo()
function is implemented using
mainMapView.centerOnArea(area)
1private fun displayLocationInfo(landmark: Landmark)
2{
3 // Display a view containing the necessary information about the landmark.
4 var name = ""
5 var coordinates = ""
6 SdkCall.execute {
7 name = landmark.name ?: "Unnamed Location"
8 landmark.coordinates?.apply { coordinates = "$latitude, $longitude" }
9 }
10 Util.postOnMain {
11 locationDetails.apply {
12 val nameView = findViewById<TextView>(R.id.name)
13 val coordinatesView = findViewById<TextView>(R.id.coordinates)
14 val imageView = findViewById<ImageView>(R.id.favourites_icon)
15 // Update the favourites icon based on the status of the landmark.
16 updateFavouritesIcon(imageView, getFavouriteId(landmark) != -1)
17 // Display the name and coordinates of the landmark.
18 nameView.text = name
19 coordinatesView.text = coordinates
20 // Treat favourites icon click event (Add/ Remove from favourites)
21 imageView.setOnClickListener {
22 val landmarkId = getFavouriteId(landmark)
23 if (landmarkId != -1)
24 {
25 deleteFromFavourites(landmarkId)
26 updateFavouritesIcon(imageView, false)
27 showStatusMessage("The landmark was deleted from favourites.")
28 }
29 else
30 {
31 addToFavourites(landmark)
32 updateFavouritesIcon(imageView, true)
33 showStatusMessage("The landmark was added to favourites.")
34 }
35 }
36 this.visibility = View.VISIBLE
37 }
38 }
39}
displayLocationInfo()
function is called when the search completes with
a non-empty result list. The function displays the name and coordinates of the
landmark on screen, as well as a red heart-shaped icon which is filled if the
landmark is set as a favorite and just an outline if it is not.
imageView.setOnClickListener
1private fun getFavouriteId(landmark: Landmark): Int = SdkCall.execute {
2 /*
3 Get the ID of the landmark saved in the store so we can use it to remove it
4 or to check if it's already a favourite.
5 */
6 val radius = 5.0 // meters
7 val area = landmark.coordinates?.let { RectangleGeographicArea(it, radius, radius) }
8 val landmarks = area?.let { store.getLandmarksByArea(it) } ?: return@execute -1
9 val threshold = 0.00001
10 landmarks.forEach {
11 val itCoordinates = it.coordinates
12 val landmarkCoordinates = landmark.coordinates
13 if (itCoordinates != null && landmarkCoordinates != null)
14 {
15 if ((itCoordinates.latitude - landmarkCoordinates.latitude < threshold) &&
16 (itCoordinates.longitude - landmarkCoordinates.longitude < threshold))
17 return@execute it.id
18 }
19 else
20 return@execute -1
21 }
22 -1
23} ?: -1
getFavouriteId()
function which does a linear search
through all landmarks in a specified set, and looks for coordinates that match
within a specified threshold.
1override fun onCreate(savedInstanceState: Bundle?)
2{
3 super.onCreate(savedInstanceState)
4 setContentView(R.layout.activity_main)
5 progressBar = findViewById(R.id.progressBar)
6 gemSurfaceView = findViewById(R.id.gem_surface)
7 locationDetails = findViewById(R.id.location_details)
8 statusText = findViewById(R.id.status_text)
9 SdkSettings.onMapDataReady = onMapDataReady@{ isReady ->
10 if (!isReady) return@onMapDataReady
11 // Defines an action that should be done after the world map is ready.
12 SdkCall.execute {
13 createStore()
14 val text = "Statue of Liberty New York"
15 val coordinates = Coordinates(40.68925476, -74.04456329)
16 searchService.searchByFilter(text, coordinates)
17 }
18 }
19 SdkSettings.onApiTokenRejected = {
20 showDialog("TOKEN REJECTED")
21 }
22 if (!Util.isInternetConnected(this))
23 {
24 showDialog("You must be connected to internet!")
25 }
26}
27 private fun createStore()
28 {
29 store = LandmarkStoreService().createLandmarkStore("Favourites")?.first!!
30 }
MainActivity
overrides the
onCreate()
function which checks
that internet access is available, then calls the
createStore()
function, which instantiates a Landmark store to for the favorites,
and then does a search for a hardcoded target:
createStore()
val
text
=
"Statue
of
Liberty
New
York"
val
coordinates
=
Coordinates(0.0,
0.0)
searchService.searchByFilter(text,
coordinates)