How to run a custom routing server with Node.js using OSM data
Programs required before you start are;
- PostgreSQL with Postgis and PgRouting extensions enabled
- Node.js
- Basic Node.js knowledge
- Optional: Postman (to test the routes)
In the past people used stars, sun or geographic signs to find their way from a place to another. Think of a captain on his way to America in 1800’s, he must use tools such as map, sextant, compass, chronometer etc. to accurately navigate his crew over the ocean. At night he must observe known stars using a start map and through the day he must adjust his ships direction by looking at the Sun. They have always looked away in order to navigate.

Nowadays our perception of navigation has changed. Smart phones, GPS and usefull mobile applications are making the navigation problem easy as a pie and accurate like it’s never before. All you have to do now is selecting the place you want to go! Internet brings traffic data, shortcut suggestions and even closed road warnings to you.

Mapbox, HERE, GraphHopper and Google Maps are providing high quality routing API’s to developers. You can integrate these API’s to take advantage of latest features such as human language directions. Of course they charge as you use the service. What if you want to build a routing API for free ?
OSM Data Download
We are going to use free OSM data in our routing backend server. OSM is an opensource and collaborative map of the world. There are various ways to download this data;
- You can directly go to OSM web site and use export button.
- Overpass Turbo API is another good solution because you can use filters to get only desired OSM data.
- You can write your own web application to download OSM data using provided API by OSM.
Use this link to download data that I used.
OSM data is downloaded in .osm format. It is an XML-formatted data form of nodes, ways and relations.
I prefer first option because osm2pgrouting program that we are going to use in the next step can clear the data and inserts only routing related data to Postgres. In the end you should have dowloaded a file with .osm extension for the desired area.
Transfer the downloaded data to PostgreSQL using osm2pgrouting
Now that we have our data we can insert the data into PostgreSQL using a special tool called osm2pgrouting. It inserts the OSM data into the database so that you don’t have to worry about the topology. Before using osm2pgrouting, you should create a database called routing_db (you can name your database anything but remember to change it accordingly in the next steps!). Now open pgAdmin or from the commandline run these two commands in order to activate the extensions;
CREATE EXTENSION postgis;
CREATE EXTENSION pgRouting;
Now open the command line (or terminal if you’re using Ubuntu or Mac) and navigate through the folder that PostgreSQL is installed. Inside the folder find the folder with the name bin.
Before running the command you should create a xml file that is going to interpret the OSM data when inserting database. That xml file is called mapconfig.xml. Default xml file can be found here; https://github.com/pgRouting/osm2pgrouting/blob/master/mapconfig.xml
After the download, copy the mapconfig.xml to bin folder.
Now run the command below;
osm2pgrouting -d routing_db -U postgres -h localhost -p 5432 -W your_password -f map1.osm -c “your\path\to\mapconfig.xml” — clean
Now you have the OSM data in your PostgreSQL database.
Testing the Routing Data Using SQL
Open a new query tab in pgAdmin and paste the query shown in the block;
SELECT ST_AsGeoJSON(ST_Union((the_geom))) FROM ways WHERE id in
(SELECT edge FROM pgr_dijkstra(
‘SELECT id,
source,
target,
length AS cost
FROM ways’,
(SELECT id FROM ways_vertices_pgr
ORDER BY the_geom <-> ST_SetSRID(ST_Point(32.824, 39.937), 4326) LIMIT 1),
(SELECT id FROM ways_vertices_pgr
ORDER BY the_geom <-> ST_SetSRID(ST_Point(32.823, 39.934), 4326) LIMIT 1),
directed := true) foo);
Query might seem a little confusing even if you familiar with SQL because there are three nested queries under the main query. In fact it is most simplistic query you can use in pgRouting. Basically it is taking two coordinates as input and returns a line that is connecting these two points as geojson.
Now when run this query it returns a geojson like the one below;
{“type”:”MultiLineString”,”coordinates”:[[[32.8236785,39.9328593],[32.8236427,39.9331657],[32.8235632,39.9338447]],[[32.8239203,39.9365802],[32.8242237,39.9362869],[32.824926,39.9355603],[32.8254992,39.9350228],[32.8258432,39.9347217]],[[32.824946,39.932861],[32.8247683,39.9328783],[32.8237783,39.9328717],[32.8236785,39.9328593]],[[32.8258432,39.9347217],[32.8256654,39.9346335],[32.8252273,39.9343465],[32.8250696,39.9339926],[32.8250301,39.9336153],[32.8250189,39.9335673],[32.8249706,39.9330756],[32.824946,39.932861]]]}
You can use a beautiful tool like geojson.io to validate this result. Just copy the query result and paste it to white area. You should see something like this;

Creating a Backend Server That Returns Routing Result
Now that we are sure that pgRouting is returning the desired results, we can set our backend server using Node.js. You can also download the code on Github.
Our folder structure is going the be like this;
server.js
node_modules
.env
package.json
package-lock.json
server
├── routes
│ ├── api.router.js
├── db
│ ├── index.js
├── controllers
│ ├── api.routing.controller.js
Let start with server.js. It is going to be the entry point for our Node.js application.


Make sure your PGUSER and PGPASSWORD values are true.



When all pieces are together, use node server command to run the server.
Testing the Server
I use Postman to test backend enpoints but you can use anything including Google Chrome. When you send a request to the server you should get the geojson result we have received from database in previous steps.

Thank you if you have followed the post this far. If you find this post usefull please share, if you see any errors please comment!