This tutorial will show you how to build a map application and retail store locator that filters and recommends nearby retail stores by travel time. This is going to be possible thanks to the TravelTime API, OpenStreetMap, and Leaflet.
By the end of the tutorial, your application will be able to perform the following actions:
- Set up a basic map application
- View potential store locations on a map and in a list
- View potential store locations with a travel time catchment area
- Rank stores from shortest to longest travel time
Let’s get started!
What problem are we solving?
If you’re looking for the nearest store out of a chain of stores, you’ll want to make sure that it is easy to get to. Today, we’ll be creating a store locator application that uses travel time, rather than distance, to display the store locations that are easiest for customers to reach.
Distance-based search often returns results that are too difficult or even impossible to reach, as it ignores the reality of available transport options and local geography.
To return more relevant results, we can use the TravelTime API to base our search results on the customer's journey time and transport preferences. This will result in more accurate results with the most relevant store locations showing first.
Often, people try to use Distance Matrix APIs to solve this problem. However, this isn’t a scalable solution since these APIs typically charge users per origin-destination pair. This means if you want to calculate times to 1,000 stores and rank shortest to longest, it gets expensive. The TravelTime API doesn’t charge you per element - 1 TravelTime credit includes times from 1 origin up to 2,000 destinations.
Step 1 — Creating your map application
We’ll start off by creating our map application. This map application will be the base on which we build our store locator.
Complete the following steps to add a basic map to your page:
- Include the Leaflet CSS file in the head section of your document.
- Create one div for your map, and another for your list of store locations that will appear on the map:
- Add the background image that will display on our map. This is known as the tile layer of the map. Please note that use of attribution is required to meet OpenStreetMap and copyright requirements:
Open your index.html file in your favourite browser or run your application. You should now see a space for our list of stores on the left, and our map on the right.
Now that we’ve added a simple map to the page, we can start adding features that will allow us to view potential store locations, both on the map and in our list.
Step 2 — Adding map markers for each location
Add the following snippet to your code:
This data will be crucial for most of the functionality we introduce later so make sure it has been added correctly.
Each object has an `id`, being the name of the Store, and a set of coordinates consisting of latitude and longitude. We can add map markers to our map using these coordinates.
Let’s add our first marker. Leaflet makes it simple to add a marker to your map, all you need to do is supply the latitude and longitude:
After you’ve added the code, refresh your marker to see the result:
Our location is clearly represented on the map with a blue marker, fantastic! Let’s keep going and add a marker for each store.
We’ll improve the appearance of our map application by making our store location markers green instead of blue. However, this is quite tricky in Leaflet. Add this block of code to create the green map marker that we will use for our store locations:
Now add the following code that iterates through our locations object, and uses the coordinates of each location to display a green map marker.
For each of the locations in our locations object, we’re grabbing the coordinates, and using those coordinates to place our marker. We’re also making sure to grab only the store coordinates by including this line of code:
This ensures we do not draw a second, unnecessary marker for our current location.
Relaunch your application to see the results of this code change:
Our application is starting to take shape. Next, all we have to do is display our stores in a list to the left side of our map, under the heading “Store Locations”. We’ll tackle this in the next section.
Step 3 — Displaying the stores in a list
We have dynamically added map markers to our list, based on the coordinates of the stores in our data. But how can we create a list in the same way? Let’s dive into it!
Remember we already have the following `div` to house our list:
This will act as our container for the list we are going to create. Add the following function to your code.
This method is designed to take in our list of locations, and add the `id` of our list. It also dynamically builds a HTML list depending on how many elements are inside of our `locations` variable, which contains our location data.
Add a call to our new method just below its declaration.
Run your application once again.
Great! Adding our list technically worked. However, it now looks out of place next to our map. Let’s add some basic CSS to address this. You can add style tags to your HTML page, or use an external stylesheet. Here’s the CSS code:
After applying these changes your application should look like the screenshot below:
That’s much better! Let’s take a break and review what we’ve built:
- We created a simple map and a container for a list of “Store Locations”
- We added data using a variable called `locations` that contains our coordinates and the coordinates of the stores.
- We added markers to the map based on the coordinates in our data.
- We created our list based on the different locations in our data.
So what’s next? Our data has been static so far, but what if it changed based on a number of different inputs?
Here is where the TravelTime API comes into play. We’re going to use the TravelTime API to improve our application and achieve the following:
- View potential store locations with a maximum travel time
- Rank stores by the shortest travel time
This will make our store locator more relevant to the user, only showing them the store locations that they can reach within a maximum travel time.
Step 4 — Showing store locations within a maximum travel time
Imagine the following scenario. We want to see markers on the map for each store that we can reach within 30 minutes using public transport. How can we modify our existing code to accomplish this?
Before we go any further, sign up for a free TravelTime API key if you have not already done so, it is required for this section. Now let’s get started!
In order to authenticate with the TravelTime API, add these variables to your code. Replace the strings below with your actual application id and API key.
Departure and travel time
The departure time is the time you start your journey. The departure time must be in ISO format. Create a variable to store the departure time like so:
The travel time is how long you would like to travel for. In this case, it is the time limit we are setting ourselves. The travel time is in seconds. We will create a variable for the travel time:
We will now send our request. We will be sending a request to the TravelTime Time Filter endpoint. This will allow us to get the distance between our current location (“My Location”) and the store locations (“Store 1, Store 2, etc.) in our data.
Note how our `departure_location_id` is set to “My Location”. The transport type is set to `public_transport`.
In the code above, we specified the properties we want to see in our response in our `properties` key. The `distance` is in metres and the `travel_time` is in seconds:
We’ve set up our request and it is ready to send!
Step 5 — Sending our API request
We’ve stored our API request as a variable. Now we have to write the code to send it to the endpoint: https://api.traveltimeapp.com/v4/time-filter. Add the following code to your project:
Relaunch your application, and hit the F12 key, or right-click and inspect the page. We have to verify that the sending of our request was a success.
In the Console of your browser tools, you should see the number 200. This is a result of the following code:
The 200 success status response code indicates that the request has succeeded!
You should also see an object called `results` that is printed by this line of code:
Click on this object to inspect it further. Keep iterating down through the list and you should eventually see a structure that resembles the following screenshot.
You can see that our response contains two arrays. The first is `locations`, which contains the stores that can be reached in 30 minutes or less by public transport.
The second is `unreachable` that contains the stores that cannot be reached by public transport in 30 minutes.
This information will be very useful! Remember, in our improved map we want to only show the map markers of the stores that are reachable. So how can we use the response from the time filter endpoint to implement this? We’ll have to make a few adjustments.
Step 6 — Displaying only the reachable store locations
To only show the map markers of the reachable stores we must make a few changes.
Complete the following changes to your codebase:
- First, remove the old method for drawing the map markers. This means deleting this block of code:
- Add the new method from drawing our map markers inside the event lister for our request. The final code for this function should look like the following snippet:
One important line of code to note is the following:
This code searches our original `locations` data for any stores that match the current iteration of the `locationsInRange` array.
For example, if “Store” 1 is determined to be in range and returned by the API response, the program will search the location’s object for “Store 1”. If a match is found, a green map marker is drawn.
This slight modification to our previous method should have the intended result. Relaunch the application to see if it was a success!
This is great, our map is only showing the stores we can reach within 30 minutes! You may have noticed that our list on the left side of the screen is out-of-date. It is still showing all of the stores. Let’s restrict this list to only show the stores within a 30-minute commute by public transit.
Step 7 — Showing a list of stores I can reach within a time limit
Thankfully we have done the bulk of the work already. We simply need to modify our existing code to incorporate the response times we have received from the travel time API. Each reachable location that gets returned has the following structure:
We will be showing both the `id` and the `travel_time` of each store that can be reached. Go back to the method `createLocationList` and make the following changes:
We also have to change which data we feed into this method. Previously we used this method on the locations variable that contains all of our stores. Now we want to use this method on only those stores that were determined to be reachable in 30 minutes. To accomplish this make the following change:
Relaunch your application. You should see an updated list that looks like the following screenshot:
Conclusion: A store locator page with accurate time-based search
You’ve reached the end of this tutorial. We’ve accomplished quite a lot: we were able to quickly get a map application up and running. We then introduced an accurate time-based search application with the TravelTime API, showing which stores the user could reach within their chosen travel time and preferred method of transport.
Why stop here? To learn more about what you can do with the TravelTime API, check out our documentation.
Keep expanding on this program, or use what you have learned here today to build a robust location-based application of your own!