This map shows the first few Km of the recently re-opened Borders Railway which runs between Edinburgh and Galashiels. This was created using data from OpenStreetMap (OSM), data copyright OpenStreetMap contributors.
To save space, the main railway line has been straightened, and the space around it has been distorted.. Strip Maps like this are nothing new; centuries ago, they were used to illustrate stagecoach routes and roads between towns.
"Up" in this map changes direction as you read from left to right; it goes from N in Edinburgh, to NE in the middle, and E at the right.
Preparing the data
In QGIS, I fetched the OSM relation for the Borders railway using QuickOSM. This was buffered by 1km, and the buffer was used to clip the OSM road network. Nodes were extracted (using Extract Nodes) and all of these were loaded into Postgres using shp2pgsql.
Warping the map
The points were warped/reprojected using PostGIS. The basic methodology is shown in the diagram below.
- The shortest line between each point and the railway is drawn (L)
- Where that line meets the railway, we measure the cumulative distance from the start of the railway (A). This is the x coordinate.
- The y coordinate is the length of L.
- The azimuth (bearing) of L is computed. For certain ranges of angles, we negate the Y coordinate. This has to be done, otherwise all points end up on one side of the railway!
These are fairly easy to compute in PostGIS, using ST_ShortestLine() and ST_LineLocatePoint().
Problems Encountered - OSM and Geometry
One of the things that took longest was trying to get it to work with the existing OSM route.
Eventually I took a pragmatic approach, and traced over the OSM route manually using QGIS.
The reason? OSM and geometry.
This is not a criticism of OSM mappers, or of OSM. OSM data often needs processing to make it amenable to coded approaches like this one.
I mention this as it's tripped me up a few times before. But there are always ways around it. Here were the hurdles I had to overcome...
- There were gaps (mostly caused by tunnels), which meant the route was broken into segments.
- These segments were not always aligned head-to-tail, and varied in direction. This made it difficult to create a single, unified linestring.
- This railway has been under construction for a few years now, so it will have been mapped incrementally. OSM tends to reflect "the truth on the ground".
There are no rules in OSM about geometry. Mappers don't need to worry about whether they draw a line from North to South, or from South to North. They're free to draw a polygon clockwise or anti-clockwise. That's not their concern, nor should it be.
In the end, I used the pragmatic approach, and traced a single line over the OSM route using QGIS. This made a single line segment with consistent direction. There are QGIS Plugins ("Join Lines", "QChainage") which I've used in the past to fix such problems.
Finally, thank you to the OSM mappers who made this map possible, and in such a timely manner - the route was mapped by the time the line was opened.
Uses data copyright OpenStreetMap contributors.
Font used is "Transport Heavy" by Nathaniel Porter, based on the UK Road Sign font (free for non-commercial use)
See a larger version
You can see/download a larger version on my flickr stream.