Search along a route
This tutorial shows how to use the TomTom Maps SDK for iOS to create an application that helps a user find points of interest along a planned route. The application is written in Objective-C and Swift language. If you are interested in another example, please check the Time to leave tutorial.
It shows how to use:
- The TomTom Map SDK module to display a map, including markers with custom icons and balloons.
- The TomTom Routing SDK module to plan routes with and without waypoints.
- The TomTom Search SDK module to search for points of interest (POIs) and to geocode map positions.
An end user can start interacting with the application by planning a route with departure and destination points:
- One long press on the map sets a departure point.
- A second long press sets a destination point and draws a route between those two points on the map.
When the route is visible on the map, the user can type a POI name or category into a search field or click on any of the predefined POI category buttons (gas station, restaurant, ATM). The map displays markers for POIs that match the user's request. The user can add one of the displayed POIs to their planned route by tapping the marker on the map and choosing the "Add to my route" button inside the marker balloon that is then displayed. The route is recalculated and redrawn to include the selected point.
- Make sure that the CocoaPods dependency manager is installed on your computer: https://cocoapods.org.
- Create a new App project named SearchAlongARoute.. Choose either Objective-C or Swift and make sure that Storyboard is selected.
- Go to the console and create a pod file by executing a
- Copy and paste SDK module dependencies into the newly created Podfile:Install the SDK modules by typing1pod 'TomTomOnlineSDKMaps', ‘2.4.713’2pod 'TomTomOnlineSDKSearch', ‘2.4.713’3pod 'TomTomOnlineSDKRouting', ‘2.4.713’4pod 'TomTomOnlineSDKMapsUIExtensions', ‘2.4.713’
pod installfrom the console. After this is finished close your project and open *.xcworkspace file with XCode. For more details about this step, please see the downloads section.
- If you don't have an API key visit a How to get a TomTom API key site and create one. The key will be used later in the code.
To initialize a TomTom map, import the TomTomOnlineSDKMaps module into your project file and add a
placeholder for the new API key. Paste your key in the
Now, add a
TTMapView property into a ViewController interface.
Next, add a following lines of code into the
Run your application. You should see a map.
The TomTom map handles zooming, panning, rotating and double tapping gestures. In this application you need to add additional map interactions including location handling, long map press events, drawing routes and markers.
import statements inside the ViewController file:
ViewController class must conform to the protocols:
initTomTomServices method to the
ViewController class where the Map Display API modules
are initialized. At the same time, add an
initUIViews method where User Interface (UI) elements
are initialized. Move the map initialization code in the
initTomTomServices method. Once the map
view is ready to be used the
onMapReady method is called, in which you need to enable showing user
current location and enable clustering annotations.
Drawing a route on the map requires that the following additional properties be defined in the ViewController interface:
- TTAlongRouteSearch – used in later part of this tutorial
- Departure coordinates
- Destination coordinates
- Waypoint coordinates
Initialize required fields and services inside the
initTomTomServices method. Your
ViewController class is used here as a delegate receiving an event notification from the TomTom
Map, Routing and Search services.
Initialize an icon for a departure map annotation inside the
initUIViews method.You also need to
add an icon named ic_map_route_departure to the Assets.xcassets directory.
You need a
clearMap function, where all the markers and the route are removed from the map.
Now add an implementation to the method
didLongPress that handles long press events on the map.
didLongPress function calls a reverseGeocoder's
reverseGeocoderWithQuery method. This method
checks if a road can be found in the place where a long press is registered on the map.
If the reverse geocoding call is successful and contains valid results, the effect of the long press depends on context:
- The first long press on the map sets the
- A second long press sets the
destinationPositionobject and draws a route on the map.
- A third long press removes any destination and departure markers and the route from the map.
Next add functions to send a route request to the Routing API and to draw a route from the response on the map.
createRouteQuery method returns a routeQuery object:
- With additional waypoints (if the
wayPointfield is a valid 2D coordinate).
- Without additional waypoints (if the
wayPointfield is not a valid 2D coordinate).
drawRouteWithDeparture method calls the Routing API. If the response is successful, an active
route is drawn on the map.
createAndDisplayMarkerAtPosition method to display a departure position marker if the
destination position is not set:
Now add dictionary property where you can store coordinates with a balloon text to display when any map marker is tapped.
Make sure that you initialize the dictionary inside the
Now you can draw the route on the map by using long presses in chosen locations.
Modify the Main.storyboard file by adding a SearchBar control. Add constraints to the SearchBar control to make sure that it will be displayed correctly on all of the devices.
Now add constraints to the
initTomTomMapConstraints function inside
In the next step you need to make sure that the SearchBar which you just added is always above a keyboard when it is visible.
First add two constant fields above the interface declaration in the ViewController file:
and two properties inside the ViewController class:
bottomConstraint property is adjusted with the size of the keyboard shown on the phone screen
when the user starts typing inside the SearchBar. A
keyboardShown property is used to store
information if keyboard is currently visible.
Make sure that the
bottomConstraint property field is connected with a SearchBar bottom constraint
from the Main.storyboard file.
Next add an
initKeyboardNotificationEvents method where keyboard events are assigned to methods
executed whenever a specific event is triggered.
initKeyboardNotificationEvents inside the
Add required methods:
keyboardDidHide are used to set the
keyboardShown field with a
Boolean value holding information about a current keyboard state. Inside a
keyboardWillHide methods, the keyboard height is adjusted with the value of a keyboard frame
Optionally implement a single tap on the map event, where you can hide keyboard if it is visible:
Add a UISearchBarDelegate protocol declaration to the ViewController inside the ViewController.m file and a SearchBar outlet as property inside. Connect your outlet property with the SearchBar from the Main.storyboard file.
Designate a current ViewController object as a delegate for the newly added
searchBar property by
adding this line inside the
This will allow you to receive and react to the
searchBar event notifications. Implement a
method searchBarSearchButtonClicked to be executed whenever a search bar search button is pressed.
In the next step add implementation of the method executed whenever the search bar button is clicked.
searchAlongTheRoute function in this object executes a search query for the provided search
term along the route visible on the map.
completedWithResponse method executed when a response is received from the TomTom search
module. Make sure to declare that your ViewController class conforms to the
createAndDisplayMarkerAtPosition method then adds a map marker in the position returned by the
search query, including the name and address of the POI.
Add a new User Interface View file named CustomAnnotationView. Open the newly added CustomAnnotationView.xib file and configure the size of the View component inside this file.
Add labels where a point of interest name and an address can be displayed. Additionally add a button to include point of interest marker to the route displayed on map.
Select all views and add a layout constraints to align items.
Now create a new Cocoa Touch Class file named CustomAnnotationView as a subclass of UIView . Make sure that your CustomAnnotationView conforms to a TTCalloutView protocol by modifying a CustomAnnotationView file.
Configure a custom class for the main View component in the CustomViewController.xib file.
Inside the CustomAnnotationView file add a WayPointAddedDelegate protocol with a
method defined inside. The class implementing this protocol receives notifications from a button
click inside the marker balloon. Additionally define properties and methods inside the
Connect outlets with previously added labels and the
addWayPointmethod for the Touch up inside
action performed on the add waypoint button.
Now add an implementation of the CustomAnnotationView class inside the CustomAnnotationView.m file
When a class implements the WayPointAddedDelegate protocol it must define a
which is executed whenever a button inside marker balloon is clicked.
Import CustomAnnotationView.h inside the ViewController.m file.
Add the WayPointAddedDelegate protocol declaration to the ViewController class and implement
In the last step overwrite default behavior of the
viewForSelectedAnnotation method where custom
annotation is created for each point of interest along a route.
createCustomAnnotation method a
CustomAnnotationView object is created, and labels
for this object are populated with the information about a found point of interest. Next this
annotation is displayed for each marker visible on the map.
Now you should have a fully working application where you can:
- Display a map.
- Create a route between 2 points.
- Display points of interest.
- Add a single POI to your route.
The additional styling, shortcut buttons, and help screen in the application screenshots are not a part of this tutorial. You can find them, along with all the icons and images used in this tutorial, in the application posted on Github.
This tutorial explained how to create a sample application that searches for and displays points of interest(POIs) along a route, then recalculates the route to include one of those POIs.
This application can be extended with other TomTom Maps SDK functions, such as displaying information about traffic and travel distances.
The full application, including additional layout changes and improvements, is visible below. At the bottom of the screen there are three optional buttons that can be used for quick searches for gas stations, restaurants, and ATMs. There is also a help button in the top right corner along with a clear button to remove the route and any markers from the map.