Writing a custom OpenStreetMaps service with Docker

As a teenager, I loved maps, and for a long time I was convinced I wanted to become a cartographer. Earlier still, I fell in love with trains, and as a kid I was convinced I wanted to become a train driver. I ended up becoming a software engineer with a desire to travel as much by rail as possible.

Open source software for mapping trains. (Rendering: OpenRailwayMap, Map data © OpenStreetMap contributors)

In my bedroom, I had a map of the train system in The Netherlands, where I had marked individual track sections as I travelled them. Within 3 years, I had travelled all train tracks in my country. Now, having lived in England, Sweden and Germany, I wanted to come up with a new way of marking travelled sections of railroad.

I turned to OpenStreetMaps and the OpenRailwayMap, as they had done a majestic effort in mapping train tracks, and additionally, in laying out passenger train routes.

As it goes with side projects, my goal was not to succeed, rather to learn. I tossed a few hyped ingredients in the mix that I wanted to experiment with:

  1. writing and publishing this project as a composition of microservices through Docker;
  2. displaying the routes on a MapBox map through a React Native application

Too many unknowns for a new project? Possibly. But here goes.

Extracting OpenStreetMap data

As a base for processing railway data and drawings, I used the OpenRailwayMap software, specifically for importing their import.sh script. Their method of keeping the OSM file up to date is quite a bit more sophisticated, but for my proof of concept I just used a one-time import of data. I pre-processed the data to extract just railways and routes in the lines of func_filter.sh.

This is quite a bit to grok, but the main point here is creating the data structure in Postgres, then importing all using osm2pgsql. With all data in Postgres, I used a custom SQL query to dump everything to a CSV, and this mapped CSV to fill an ElasticSearch instance.

My thinking was that knowing end points of train routes would lead me to mark those, and highlight certain routes. Then, in a later to be decided data storage persist these tracks for individual users.

For mapping routes onto Mapbox, there are awesome tutorials, both beginner and advanced scenarios are well-described.

Then, I entered both ends of stations of a known route on a quick Javascript application, to verify whether this approach would actually work.

Great success! The red line is the train link from Rotterdam Centraal to Groningen. (© Mapbox © OpenStreetMap)

Next steps

So, instead of marking complete routes, my goal was to select segments that I travelled. This proved to be difficult, if not impossible, with my current approach. Thanks to some helpful individuals on the#osm-dev and #openrailwaymaps channels of irc.oftc.net, I was pointed to the routing engine OSRM, and the train implementation Raildar, which I am now exploring.

Having these images in Docker, I was curious about pushing them to a production-ready cloud system. I am familiar with Azure, but wanted to try Google App Engine and Kubernetes. I’ll save a write-up of my experience with getting these set-up for a next blog post.

Did I make any errors in my thinking? Is OSRM a good candidate or would there be better alternatives? Did I make some mistakes in my approach with Docker? Any feedback is welcome.