Case study: Atlas app for truck drivers

Crowdsourced navigation app that enables truck drivers to help each other by updating real-time road info.

Solving a problem for truckers

You’ve been zipping along the highway for eight hours straight. It’s time to take a break. Theweather is getting worse. It’s pouring rain. You start looking for truck parking and rest areas. Examining your map, you note several rest stops. As you’re heading for the nearest stop you suddenly get held up in a line of slow-moving traffic caused by roadwork. You wait. Hopefully, you can still make it before dark.

Bad weather, road construction, and traffic jams: these are events truck drivers deal with on a daily basis. Planning rest stops and gas stations, comparing fuel prices, and checking ahead to see if a weigh station is open or closed are all parts of a driver’s regular routine.

With so many work-related challenges, truckers need a trip planning companion that can make their workdays safer and more convenient.

Project goals

The main goal of the project was to enable a community of drivers to update the real-time status of places on their route. To achieve this goal we needed to make the app:

Extremely user-friendly
Things like a name change to a road, or a bridge that is closed to traffic because of repair work can easily frustrate drivers. The app had to be highly informative and user-friendly so drivers could do their jobs more safely and efficiently.

Affordable for every driver
A lot of drivers use low-cost smartphones. We had to make the app work perfectly well on the majority of devices including those that cost less than $100.

Available in the offline mode
In Russia and Kazakhstan there are many regions where there is no mobile network coverage -or, if there is mobile coverage, it’s very unstable. One of the main requirements for the app was the integration of an offline mode so all the information could always be available — regardless of internet connection.

Client feedback

They were willing to help every step of the way and remained as transparent as possible throughout the process. They were always available and responsive even on the weekends. I knew exactly what they were doing in each sprint and I could clearly see their progress. It was very easy for them to move forward without needing additional assistance or guidance.They delivered within budget and on schedule, and they brilliantly solved any challenges that popped up. I admire MadAppGang’s ability to get on the same page in any matter. I’d be very happy to work with MadAppGang again.

MadAppGang helped one of the largest Russian transportation companies develop an app that improves driver’s quality of life by giving them access to real-time road information anytime and anywhere

Our solution

Atlas is a crowdsourced navigation app that lets truck drivers know the actual traffic and weather situation on the road. It makes it easy for truckers to find truck parking, rest areas, truck washes, hotels and restaurants, fuel and weigh stations, and more. The app helps truckers save time and fuel and reduces their daily frustrations.

MadAppGang developed a full stack service for Atlas which is easy to scale and develop. Using this service, drivers can access all the road information they need along the way, build routes, and leave comments. All the app’s functionality is available for any device, including the cheapest Android smartphones, and can be accessed in offline mode.

Existing geopoints can be moderated, complemented, and changed using a convenient admin panel. Our engineers also implemented a fast, scalable, and reliable backend for the system.

We used short two-week Scrum iterations in the process of development and completed the project on time and within budget. Our client was highly involved in the development process and our team did exactly what he requested.

Main
Routes
Filter

Technologies

Kotlin
Java
ReactJS
BeeGo
Infrastructure — Docker Swarm
Map — Leaflet.JS with OSM, Yandex and Google layers
Transport Security — HTTPS TLS1.2
Database — MongoDB
Backend architecture — Docker-composed microservices
Monitoring — cAdvisor+Grafana
Cache — Redis
Android app maps — MapBox

Engineering challenges

Clustering more than 200,000 points on a map

We had about 200,000 geopoints imported from the OpenStreetMap to our database. This huge volume of information is pretty hard to plot on a map. For example, to show Moscow alone we would’ve needed to add 40MB of data. Here is what Moscow could look like:

Cramming all these data on one screen makes the map impossible to use. And if a user had a weak internet connection, they wouldn't be able to access any of that info. We couldn't let that happen.

Mapbox solved the problem of displaying hundreds of thousands of points on a map by implementing clustering on the client-side.

But we decided to go with server-side clustering. While this solution is widely used in many other geolocation services, there is no ready-to-use library for implementing it.

1. Falling for Golang

Leaflet.clustering offers a great system that works on the client-side just like Mapbox' Supercluster. But creating a service in NodeJS only for clustering would've slowed down our system. When it comes to performance, Golang is far better than NodeJS.

We decided to develop our component for clustering geopoints in Golang.

2. Porting kdbush library for super fast spatial index for 2D points.

Clustering is based on spatial indexes. There is a number of open source solutions for storing and querying spatial data in the Go programming language. These solutions include geo.go, tile38 и rtreego. However, they didn't quite fit our purposes.

  • Geo.go solves the problem of projection in different coordinate systems. It uses dynamic index that slows down performance and consumes a large amount of memory.
  • Tile38 implements not only indexing, but also storing data with a tracking possibility. This additional business logic would've complicated our solution.
  • Rtreego is actually the right solution for our case. But this implementation handles general N-dimensional cases. It's not optimised for 2D points, which means it works slower than we needed and – again – consumes memory.

We looked further and eventually found the kdbush library. We ported it and optimized for our purposes. This index allowed us to build Gocluster, a very fast Golang library for geospatial point clustering.

Results

We compared our Gocluster solution with Mapbox Supercluster with the same dataset on the same machine. For the test we built clusters for 21 map layers with 1 000 000 points. And we got amazing results:

Choosing a powerful online map service

1. An ultimate map for Russia
To display a detailed map of the territory of the Russian Federation and Kazakhstan we needed a suitable map service. Unfortunately, Google Maps isn't the best option for this part of the world. Yandex Maps are much better but they aren't available as a native component on Android.

We chose Mapbox. This library provides a greater set of functionality than Google and is used in many popular mobile applications. For example, Strava uses Mapbox to show map with a custom style and beautifully coloured routes in their running application.

2. Offline mode
With the help of Mapbox we could upload a region in the phone memory so users could use maps when there is no internet connection. With Mapbox' offline functionality and our point caching solution almost all the app's features can be available in the offline mode.

3. Navigation
Mapbox offers step-by-step navigation features. This functionality isn't included to the current app version. But we're planning to roll out navigation in the next release.

Solving user authorization problems

1. When email and social sign-up won't work.
Less than half of our users – truck drivers – have a profile on social networks. Only 10% of them are registered on Facebook. And there is a large number of drivers – about 30% – who don't even have email.

Those who have email don't use it often. So if a driver forgot his password, he would need to go through three-level password recovery procedure (click password reset button > get the letter > click on the link in the letter > get a new password) which might actually seem harder than driving an 18 wheeler truck.

Social or email sign-ups weren't the options we could choose to authorize users.
But registering with a mobile phone number (ala WhatsApp), on the other hand, is much easier for our users. To confirm registration, we send users an SMS with a verification code that they don't even have to enter manually. The app recognizes the needed SMS and enters the code automatically.

2. When Twilio won't work either.
To verify phone using SMS we intended to use Twilio, one of the most popular communication platforms. But during testing we discovered that only 1 in 4 messages being sent reaches the recipients. This problem stems from Russian telecom operators who integrate services like Twilio using a so called "gray" scheme that reduces the cost of sending messages and, well, doesn't work properly.

We decided to find a local provider who had direct agreements with all Russian telecom operators. And we found one. But they didn't have a web API for sending messages. Together we developed a specification for our interface and the local provider implemented it in the shortest terms.

Getting lucky with Docker for server infrastructure

Many cloud services, such as AWS or Google Cloud provide a range of possibilities to create scalable architecture, for example AWS Elastic Beanstalk. Unfortunately, we couldn't use them because all the data had to be stored on the territory of the Russian Federation, according to the law. Also, to provide faster access to data it was advisable to place the server in Russia too.

We didn't know a reliable solution in the Russian Federation and didn't want to rely on advertising promises either. That's why an excellent way out was to use a provider-independent scalable system.

Docker is gaining immense popularity today. Despite being new, it's already widely used by a large number of companies, such as Google, Amazon, Microsoft, and IBM.

A big advantage of this technology is that it's open source and written in Golang. If necessary, we could customize this solution for our needs.

Another advantage of Docker is that it has a vibrant community that is constantly enhancing this technology. Also, Docker is Secure by Default.

Docker allowed us to deploy applications and services quickly and easily. The deployment is completely independent from the hosting service.

Our solution turned out to be lightweight and reliable. It took us 15 minutes to migrate from the test servers on DigitalOcean to Russian VScale servers.

We are happy to be part of the Docker community and contribute to the development of this next-generation virtualization project.

Taking care of other devs with comprehensive API documentation

Well-written documentation for a web service is a very important element of the infrastructure. We pay a lot of attention to API design. We normally use Stoplight to model our APIs, but this service uses a proprietary format, which means we can't use our APIs outside of the platform.

Instead, we created our own documentation in the Swagger 2 format. A new open standard OpenAPI is based on this format.

We created developer-friendly documentation with the help of SwaggerUI and a convenient tool for editing, Swagger Editor. Any third-party developer can make his or her own application based on our service.

Mad team

Sergii Chaban
Lead Android developer
Jack Rudenko
CTO, Backend development
Denis Provodnikov
Frontend
Sergii Kostantian
Android developer
Denis Ivanov
Backend, Frontend

Our products

SmartRun is a personal running coach that improves your cardiovascular system with heart rate based trainings.

Check it out