Monday 10 April 2023

The longest line (part 2)

In my last blog piece I wrote about my attempt to find a longer straight line in Great Britain that doesn't cross a public road than the one identified by Ordnance Survey in their 2019 blog. I did this using their OS Open Roads dataset, and I excluded public roads because that's what I think makes most sense. I found a longer line in a different area, though I definitely wouldn't recommend trying to walk it but I would recommend watching this video. I wasn't quite satisfied that my previous line was the definitive single longest line possible so I spent a bit more time on it and now I'm back to report my results. All of this was done in QGIS, using open data from Ordnance Survey - and just a bit of curiosity. The original OS piece was in response to a question on Twitter but I also found it very interesting from a methods point of view. And now here's a map of the single longest straight line I think you can possibly find between roads in Great Britain. I'll say a bit more about the method below, for the nerds. Here's the web map of the new longest line. And here's the Scottish Outdoor Access Code.

What I now believe is the definitive 'longest line'

Was I wrong at first? Well, no, in the sense that I was still correct in stating that I'd found a longer line - in a different area - than the original OS line, but I didn't quite find the single longest line possible. The line I have found is roughly in the same location though and this is all just a mix of curiosity, mathematical geometry and fun so there's no big issue here. Look for longest-line-new in this folder (gpkg, shp and geojson formats) if you want to load up the line in your GIS software.

But I would strongly suggest that if anyone wants to walk this route they should be extremely careful and only attempt in good weather, and if they are very experienced in Highland terrain (e.g. thigh-deep heather, nasty, tussocky, holey land, murderous midgies, etc). I know myself how hard it can be to walk over this terrain and how much pain it can cause. Many difficult walks over the years have proven this, including a particularly bad decision in Knoydart a few years ago where it took us about an hour to walk 500 metres over what looked like flat ground!

In doing all this I also found a much longer line in England than the one identified in the original OS piece - over 35km vs 29km. This was the case even if I used the file that has the restricted roads in it. I also found a longer one for Wales too but in both these cases there is no right to roam so I don't want to encourage trespassing.

You can read about the method below, but here are a few images from my map adventures.

All areas > 100 sq km between roads

Generating sets of 'longest line' candidates

I got to about 35km straight line in England

Yes, I got carried away with myself again

What about the distance over terrain? Well, that's important so I did the same as last time. I took the longest line, plonked it on top of the OS Terrain 50 digital elevation model and then generated a distance for the line. Obviously if I had even more accurate terrain data (Terrain 5 for example) then the distance would be a bit more.

So, a nice wee 50 mile stroll

This was an interesting methodological challenge and I think I've found the definitive longest line you can travel along a straight line without crossing any public roads in the UK. See my original blog post on this for more on the background.

A revised web map - I think this is the final answer


The method - let me know if you have a better, super-quick method :)

In theory the task is easy. Just draw a straight line inside the biggest gap in the road network, defined using the OS Open Roads dataset. It's quite easy just to eyeball the biggest gaps in the road network and come to a pretty good answer but this is not sufficient if you want to be systematic and definitive. I didn't just eyeball it the first time, there was more to it than that, but also I wasn't completely exhaustive either. So, here's what I did this time, in brief. Note that the data is just for Great Britain but the longest line is the longest in the UK because there are no gaps in the road network in Northern Ireland anywhere near this big.

I'm reporting my method for non-restricted roads, but I also did it with the entire OS Open Roads dataset, including restricted roads - just for fun.

  1. Download the latest OS Open Roads dataset and add it to QGIS.
  2. I decided to polygonize the entire OS Open Roads dataset because of a suggestion by John Murray, and this was pretty useful. This was also pretty quick and simple on my computer.
  3. Then I decided to deal with the roads a bit differently, because they needed to be cut out of the 'between roads' polygons I made so that I could fit my lines entirely within the polygon geometry. But also because the OS Open Roads data is just centre lines and they have no thickness. So I approximated here and buffered the roads to 10 metre width, and dissolved the result. Then I ran a Difference on them to end up with a final set of polygons - lots of big 'no roads here' polygons. I only did this for areas of 100 sq km or more - for all road types this gave me 116 areas and when I removed restricted roads I ended up with 141 areas. 87 out of 141 are in Scotland.
  4. Then I needed a simple way to identify the longest line within polygons. This is in theory very easy but also you could waste a lot of time computing vertex-vertex distances here that you don't need to - you're only really interested in the furthest vertices from each other that can be connected with a line entirely within the polygon. So for this I used the Python console in QGIS and a little snippet I found on StackExchange (of course). I've copied this below in case it ever disappears from there. With thousands of vertices this can take a long time so try it one shape at a time if you are doing it yourself. You could just draw a set of lines to/from selected vertices but this is also a bit of a pain, particularly because it won't avoid the roads.
  5. How could I be sure which intra-road area contains the longest line? Well it's pretty easy to see visually but to be sure I created some minimum bounding circles and computed the radius and then the longest line was still clearly in my original Monadhliath Mountains area, so that was good. You can see a bit of this in one of the screenshots above.
  6. Then it was a case of doing some checks, double checks and then writing this short note.

import itertools

layer = iface.activeLayer() #Click layer in tree

#Create empty line layer
vl = QgsVectorLayer("LineString?crs={}&index=yes".format(layer.crs().authid()), "Longest_line", "memory")
provider = vl.dataProvider()

#For each polygon find the longest line that is within the polygon
for feat in layer.getFeatures():
    verts = [v for v in feat.geometry().vertices()] #List all vertices
    all_lines = []
    for p1,p2 in itertools.combinations(verts, 2): #For every combination of two vertices
        all_lines.append(QgsGeometry.fromPolyline([p1,p2])) #Create a line
    all_lines = [line for line in all_lines if line.within(feat.geometry())] #Check if line is within polygon
    if len(all_lines)>0:
        longest_line = max(all_lines, key=lambda x: x.length()) #Find longest line
        #Create a line feature from the longest line within polygon
        f = QgsFeature()
        f.setGeometry(longest_line)
        provider.addFeature(f)

QgsProject.instance().addMapLayer(vl)