Make a Web Mapping App with Routing and Place Search
Tags: gis, webdev, tutorial, beginners
Published: 2019-12-06 21:09:35

![Alt Text](https://thepracticaldev.s3.amazonaws.com/i/1tihrnw5o45gfxqigz29.png)

“We’ve got a long way to go and a short time to get there”; an excerpt from Jerry Reed’s classic record “Eastbound and Down”. Within those lyrics resides a deeper story of managing time and distance across the roads of America. There were no data hubs in Jerry’s days of trucking and fleet management. There were no ways of saving time beyond those that could be thought up on a whim.

The infrastructure now is much different of course. In today’s world, knowing the road that lies ahead is essential for business efficiency across several industries. Fleet management; retail logistics; sales teams that move around the country; local governments; and road maintenance crews are just a few examples of organizations who benefit from tightly managing their travels.

ThinkGeo Cloud Routing is a great way to inject that much-needed data into your own apps, as it offers really fast route calculation for North America (U.S., Canada and Mexico) plus much of Central America. So, let’s see how we can use the ThinkGeo Cloud to build a routing web app that lets us discover the world around our route, and gives us access to important point-of-interest data that can fuel our trips.

Before we get started with the code, let’s grab a ThinkGeo Cloud API key, which we’ll use to authenticate our requests to the ThinkGeo Cloud API. To get your own API key, you’ll need to sign up for a free ThinkGeo Cloud account at https://cloud.thinkgeo.com which takes just a few seconds. If you get stuck here, ThinkGeo has a handy tutorial video that can get you jump-started.

Now let’s do this.

**1. Setting up the background map**

Before we can display routes, we need a base map to provide context, and it’s pretty easy to set one up with ThinkGeo Cloud Maps. The first thing you’ll want to do in your web app is reference the ThinkGeo Cloud JavaScript libraries and CSS from their CDN. (These packages are also available on NPM if you prefer.)

https://cdn.thinkgeo.com/vectormap-js/3.0.0/vectormap.js
https://cdn.thinkgeo.com/vectormap-js/3.0.0/vectormap.css
https://cdn.thinkgeo.com/vectormap-icons/3.0.0/webfontloader.js
https://cdn.thinkgeo.com/cloudclient-js/1.0.8/thinkgeocloudclient.js

In your HTML page, add an element for the map to live in. We’ve just inlined some CSS here to make the map fill the screen.

<div id=”map” style=”position:relative; width:100%; height:100%;”></div>

Now we can create our map using ThinkGeo’s VectorMap.JS library. The map’s base layer will use the ThinkGeo Cloud Maps Vector Tile service to display a detailed street map using modern vector-based map data.

{% gist https://gist.github.com/GitHubAdmin-ThinkGeo/53c32dd664157587879a7d9c02b7e5ac %}

Next, let’s define a default view for the map when it starts up. We’ll zoom in to Dallas, TX as an example.

{% gist https://gist.github.com/GitHubAdmin-ThinkGeo/32086cbcca8a79999c0dbafa1fdf4aa0 %}

The next method will actually create and initialize our interactive map.

{% gist https://gist.github.com/GitHubAdmin-ThinkGeo/61babf9a1f82d80c2a51741e816c1007 %}


Finally, we’ll load a custom set of point-of-interest icons for our base map. The icon loader has an event that fires when loading is complete, and we’ll have this event call our initializeMap method when it does.

{% gist https://gist.github.com/GitHubAdmin-ThinkGeo/666044ee3c7b651ea5e81e49d9b58a63 %}


Now let’s take a look at our base map. So far so good, right?

![Alt Text](https://thepracticaldev.s3.amazonaws.com/i/gisqf8iayazge481eqn2.png)


**2. Calculating a route from A to B**

Since this is a routing app we’re building, next we’re going to add a start and end point to the map, and have the ThinkGeo Cloud calculate the shortest route between them. For brevity, we’ll use a hard-coded start and end point in the Dallas area, but you can use any latitude and longitude coordinates you wish (or gather them from map interaction).

First we need to define what our A and B points will look like. You can use any icon image you want instead of the sample ones from ThinkGeo’s servers.

{% gist https://gist.github.com/GitHubAdmin-ThinkGeo/9cd885feafb90951828d5b60aebb864b %}

Now to set the coordinates for these points and turn them into vector features for our map:

{% gist https://gist.github.com/GitHubAdmin-ThinkGeo/286d2f9721ab63be3b37ccced814d3cd %}


You might have noticed that we defined a vectorSource variable but didn’t use it yet. Go back to your initializeMap method and insert the following snippet at the end of it:

{% gist https://gist.github.com/GitHubAdmin-ThinkGeo/484eebea690f94a9f22113bc3d56a4ad %}

Finally, let’s find a route from A to B, using the ThinkGeo Cloud routing client. Add the following code to your JavaScript:

{% gist https://gist.github.com/GitHubAdmin-ThinkGeo/666a46d2251a7a86429a542bcaf73f6f %}

And finally, to kick off the process automatically on page load, call the performRouting method at the end of your initializeMap routine:


performRouting();

Refresh your browser now, and you’ll see a blue line connecting point A to B along the shortest available route!


![Alt Text](https://thepracticaldev.s3.amazonaws.com/i/vgtot031ucur0m7fms1g.png)

**3. Finding points of interest along your route**

Knowing the fastest way to get from place to place is great, but what if you want to know what you might encounter along your way? Maybe you’re looking for hotels to stop at, restaurants to grab a bite to eat, or gas stations to keep your car’s tank topped up. We can easily add that extra dimension to our app by using the ThinkGeo Cloud Reverse Geocoding service. Reverse geocoding is the process of taking a set of spatial coordinates and converting them into the nearest address or point of interest.

We’ll start by setting up a menu that lets the user choose what type of places they want to search for — hotels, restaurants, or gas stations. While we’re at it, let’s add a button that will regenerate the results when clicked. We can place this new markup in our HTML page after our map container element:


{% gist https://gist.github.com/GitHubAdmin-ThinkGeo/81a822e3c416e5b843e3c3d48b0ddee5 %}

Next, add the following code to your JavaScript. The searchPlaces method takes the route we received from the ThinkGeo Cloud and submits it as a reverse geocode query. The ThinkGeo Cloud Reverse Geocoding service will find and return all places of the types we specify within a certain proximity to our drive (200 meters, in this example).

{% gist https://gist.github.com/GitHubAdmin-ThinkGeo/a3e6f3774926a61358c87f6465192a38 %}


Below this, we’re going to add a method called showPlaces that will take the response from the ThinkGeo Cloud Reverse Geocoder and use it to create points on the map. Each point will have a pin icon with a symbol that represents its type; for example, a bed icon for hotels.


{% gist https://gist.github.com/GitHubAdmin-ThinkGeo/b47478b247048283d5becd28f2301d00 %}

Lastly, back in our initializeMap method, we need to add the layer that will hold our points of interest. Do this between the calls to showRouteEndpoints() and performRouting().

{% gist https://gist.github.com/GitHubAdmin-ThinkGeo/bb56159cf0c6569bbada140363bab869 %}

And voila…if we reload our map now, we’ll see all the restaurants within 200 meters of our route! This is great.


![Alt Text](https://thepracticaldev.s3.amazonaws.com/i/2cygkd6yokvz578uzawo.png)



**4. Displaying place details in a popup bubble**

One last thing to make this really useful: we need a way to show the user the details for each place along their route, such as its name and address. The features we added to our map have this information already embedded, we just need to display it. One way to do that would be to show it in a popup bubble when you click on one of the points, so let’s implement that now.

To make the popups work, we first need to insert a new HTML element inside of the map container on our web page, like this:

{% gist https://gist.github.com/GitHubAdmin-ThinkGeo/536985e555780fa787322cbc9d0cdc48 %}


To make this look right, we’ll need to add the following CSS. These styles will make the popup look like a speech balloon, and give it an “X” button that can be clicked to make it disappear.

{% gist https://gist.github.com/GitHubAdmin-ThinkGeo/e9e1ccea3758af427f5fdc964d13b88c %}


Finally, we need to add some JavaScript to our initializeMap method that makes these popups work. Before the call to performRouting(), we’ll create a map overlay for our popup and hook up the events to show and hide it.

{% gist https://gist.github.com/GitHubAdmin-ThinkGeo/0b86de255663e9c5714200d4b7f8a6c7 %}


And that’s all there is to it. Now, if you click on a point of interest on your map, a popup bubble will open and display the name and address of that point. (If the ThinkGeo Cloud service doesn’t know the name of the place, it will show its type instead.) Here’s how it looks:

![Alt Text](https://thepracticaldev.s3.amazonaws.com/i/eaeaws6vnwgvd0svjk27.png)


Go ahead and experiment with the finished product below.

{% codepen https://codepen.io/thinkgeocodepen/pen/oNNrvda %}