How to Create Your own Map backend like Google Map…

Ashish Ranjan
6 min readOct 9, 2021

When I heard, first time about OSRM my reaction was “What the hell is OSRM 🤯”

OSRM in Open Source Routing Machine. In simple words, you can create your map application like Google Maps using OSRM (FOR FREE!!)

Why OSRM?

  • Powerful and efficient engine routing machine for solving shortest road tracks.
  • It’s fully open-source and you can host it on your computer without paying for a license

So say bye to google map and create your own map company by using OSRM

What Type of data you would get with OSRM:

  • Nearest: Snaps coordinates to the street network and returns the nearest matches
  • Route: Finds the fastest route between coordinates
  • Table: Computes the duration or distances of the fastest route between all pairs of supplied coordinates
  • Match: Snaps noisy GPS traces to the road network in the most plausible way
  • Trip: Solves the Traveling Salesman Problem using a greedy heuristic
  • Tile: Generates Mapbox Vector Tiles with internal routing metadata

There are two pre-processing pipelines available:

  • Contraction Hierarchies (CH)
  • Multi-Level Dijkstra (MLD)

we recommend using MLD by default except for special use-cases such as very large distance matrices where CH is still a better fit for the time being. In the following, we explain the MLD pipeline. If you want to use the CH pipeline instead replace osrm-partition and osrm-customize with a single osrm-contract and change the algorithm option for osrm-routed to --algorithm ch.

How to use OSRM project with the power of ECS Fargate:

Before going to use ECS Fargate lemme describe what is Fargate and why we’re going to use this for our deployment:

AWS Fargate
  1. AWS Container as a service ⇒ where you won’t have to manage underlying worker nodes(Ec2).
  2. You can increase the number of replicas based on your current workload
  3. You pay only for the vCPU and memory resources that your tasks are using, No provisioning cost 🤑

ECS Fargate Deployment Guide:

If you want to deploy OSRM on ECS first thing would be, a running docker container. DockerHub provides OSRM backend but for running that you would have some preprocessed data otherwise you won’t be able to use OSRM service.

Infra Architecture

AWS Infra Overview for ECS Fargate Deployment

AWS Infra Overview for ECS Fargate Deployment

We can divide our architecture into 2 steps:

  1. Create ECS infra along with VPC, Load Balancer, task definition, and service.
  2. Creating File system.

Create a File system:

we’re using EFS for our Network file system; because ECS Fargate is compatible with it.

  • Make sure of security inbound/outbound rules otherwise, you won’t be able to use EFS
Amazon EFS
  • For Processing OSRM data I used m5.2xlarge Ec2 machine ⇒ This could be based on your requirements. I was processing India region data that was around 1 GB. Make sure you would be using the proper Instance Type Based on your data size otherwise you'll get an error. for me, it took around 1 hour.
Screenshot: M5.2xlarge Ec2 system utilization while processing data
  • Commands that I used during this process
#mount efs on data folder   
sudo mount -t efs -o tls fs-123455:/ efs
or
sudo mount -t nfs4 -o nfsvers=4.1,rsize=1048576,wsize=1048576,hard,timeo=600,retrans=2,noresvport fs-12345.efs.ap-south-1.amazonaws.com:/ efs
#download osrm india region data wget http://download.geofabrik.de/asia/india-latest.osm.pbf #extract osrm data
docker run -t -v "${PWD}:/data" osrm/osrm-backend osrm-extract -p /opt/car.lua /data/india-latest.osm.pbf
#preprocessing osrm data
docker run -t -v "${PWD}:/data" osrm/osrm-backend osrm-partition /data/india-latest.osrm docker run -t -v "${PWD}:/data" osrm/osrm-backend osrm-customize /data/india-latest.osrm
#test your osrm conatiner
docker run -t -v "${PWD}:/data" osrm/osrm-backend osrm-extract -p /opt/car.lua /data/india-latest.osm.pbf
#check with curl
curl localhost:5000/route/v1/driving/13.388860,52.517037\;13.385983,52.496891\?steps\=true -k
  • The flag -v "${PWD}:/data" creates the directory /data inside the docker container and makes the current working directory "${PWD}" available there. The file /data/india-latest.osm.pbf inside the container is referring to "${PWD}/india-latest.osm.pbf" on the host.

Create ECS Infra:

  • VPC with 2public-private subnets along with NAT gateway
  • ALB ⇒ private or public based on your requirements; I’ll describe later why we need to use ALB
  • ECS cluster
  • Task definition ⇒ While creating a Task definition you would need to take care of the below points
  1. port mapping: 5000
  2. Command: ["osrm-routed","--algorithm","mld","/data/india-latest.osrm"]
  3. Mount point: /data osrm-backend-stg
  4. Volumes: Volume type=>EFS File_system_ID=>fs-12345
  • Make sure you would assign proper resource for provisioning you farget container otherwise you would get OOM error
ECS Fargate OOM error
  • In my case, I used 8GiB of ram because it was throwing OOM issue. this is mainly for India region OSRM data. things would be different in your case How do i benchmark resource ⇒ I used an incremental increase from 1 GiB to my required state
  • After this step, your container would be in a running state but after some time you would realize that your container is creating, again and again, 😧 why so ⇒ because your container is not passing health check on Load balancer target groups. for OSRM they didn’t provide any HealthCheck API(as fas as a realize). If you check for DockerHub description, they’ll provide some curl URLs (/route/v1/driving/13.388860,52.517037...) but you can’t use this endpoint on the AWS Loadbalancer health check path. for resolving this issue I used custom status code for health check as 400
  • After following the above steps your service would be up and running.

How to access Endpoint:

After doing all this stuff your questions would be what to do next.

you would be able to access your Fargate service with your Loadbalacer Endpoint followed by below URIs

GET/{service}/{version}/{profile}/{coordinates}[.{format}]?option=value&option=value (Will explain you dont worry) orcurl "https://<LoadBalancerDNS>/route/v1/driving/13.388860,52.517037;13.385983,52.496891?steps=true"

Okay let me explain it HTTP requests

  • Service ⇒ Service has one of the following values: route , nearest , table , match , trip , tile
  • Version ⇒ The version of the protocol implemented by the service
  • Profile ⇒ Typically it is car , bike or foot
  • Coordinates ⇒ Just longitude and latitude in-service format which you needed
  • Nearest service ⇒ Where coordinates only support a single entry in {longitude}, {latitude}.

Response sample:

{
"code": "Ok",
"routes": [
{
"geometry": "yqliDixviL??",
"legs": [
{
"steps": [
{
"intersections": [
{
"out": 0,
"entry": [
true
],
"bearings": [
291
],
"location": [
69.917649,
27.922374
]
}
],
"driving_side": "right",
"geometry": "yqliDixviL??",
"mode": "driving",
"duration": 0,
"maneuver": {
"bearing_after": 291,
"location": [
69.917649,
27.922374
],
"bearing_before": 0,
"type": "depart"
},
"weight": 0,
"distance": 0,
"name": ""
},
{
"intersections": [
{
"in": 0,
"entry": [
true
],
"bearings": [
111
],
"location": [
69.917649,
27.922374
]
}
],
"driving_side": "right",
"geometry": "yqliDixviL",
"mode": "driving",
"duration": 0,
"maneuver": {
"bearing_after": 0,
"location": [
69.917649,
27.922374
],
"bearing_before": 291,
"type": "arrive"
},
"weight": 0,
"distance": 0,
"name": ""
}
],
"distance": 0,
"duration": 0,
"summary": "",
"weight": 0
}
],
"distance": 0,
"duration": 0,
"weight_name": "routability",
"weight": 0
}
],
"waypoints": [
{
"hint": "XVMlgFhcJYBtAAAAAAAAANhfAQAAAAAAQXHyQQAAAACtZ8NGAAAAADcAAAAAAAAA668AAAAAAAASSwCA0dsqBMYPqgE8TMwArVghA0IAPxLHlp4p",
"distance": 5532453.427398,
"name": "",
"location": [
69.917649,
27.922374
]
},
{
"hint": "XVMlgFhcJYBtAAAAAAAAANhfAQAAAAAAQXHyQQAAAACtZ8NGAAAAADcAAAAAAAAA668AAAAAAAASSwCA0dsqBMYPqgH_QMwA-wkhA0IAPxLHlp4p",
"distance": 5531562.577164,
"name": "",
"location": [
69.917649,
27.922374
]
}
]
}

Nothing more to see here….

By,
Ashish Ranjan

--

--

Ashish Ranjan

Building Highly scalable and reliable Infrastructure