Gosh. I’m going to do one of those academic blog posts where I self-promote by telling you that I’ve just published a paper and that you should go read it. I hate those. But, I had actually been meaning to make my thoughts into a blog post or two, and without the intervention of my academic advisor at the time, I would have; now the thing is a paper instead of a post, a full year after it would have been a post, and have I mentioned that you should read it? It’s about bike maps, and what I hate about bike maps and how I attempted to make them better as a genre, by example, and then by overly formal peer-reviewed explication.
For those of you who may have missed an earlier post, or who are finding this blog for the first time, please be advised that there may be but few updates coming. I have moved away from my exciting and bitter eight-year relationship with Cincinnati to the more expensive and diverse city of Toronto, Ontario.
Still seen as through a cell phone, darkly.
Though having been here for several days now, I feel I should send a letter home with some initial thoughts and relevant comparisons.
I don’t yet understand how bicycling works here. There seems to be much more bicycle infrastructure, and about a thousand times more cyclists, but I still find myself quite definitely on the vehicular cycling side of the debate. Cyclists here ride far to the right side of the road, and while car drivers seem very much more competent at driving near people, they can still pass extremely close to the cyclists, even while they are riding in the door-zone next to parked cars. In fact, that appears to be the norm. Perhaps people are also extremely cautious about opening their car doors? As a vehicular cyclist myself, this sort of riding absolutely terrifies me. Yet a couple times when I tried to take the lane for myself, the car behind me clearly indicated that this was not how it expected/wanted me to behave. There are also clear benefits to filtering forward on the right: cars can’t turn until the pedestrians clear the crosswalks, but bikes going straight can get ahead of the turning cars by moving with the pedestrians.
Streetcar tracks are not as bad for bike tires as I thought they would be or as the ones in Cincinnati are. I think the Toronto tracks have narrower grooves and are more flush with the road.
There is actual bicycle congestion here, exacerbated to be sure by the fact that cyclists generally stick to a narrow bike lane. Passing is constrained by the presence of cars on the left, so a slow rider can hold up a line of bikes for a while. Also, cyclists actually pile up at red lights! That’s not interesting so much as it is exciting, I guess.
Can it be possible that Cincinnati has a slightly more modern fare payment system than Toronto?? This agency still has tokens and accepts cash fares at the point of boarding, and does not have a stored-value card1!
Streetcars travel down the middle of many two lane streets and people board them by walking to the middle of the street across a lane of traffic. But the traffic is extremely well-trained and will not pass a stopped streetcar until all of the doors are closed.
What’s the deal with the new streetcar designs TTC is rolling out? Are they supposed to be sexier? Flashier? To get all the “choice riders”? Hell no. They are clearly being introduced because they are larger and the smaller streetcar vehicles can get insanely crowded. There is a line in the Spadina subway station to get on the streetcar and they have to cut it off when it’s packed full. A larger vehicle…
Streetcar bunching and breakdowns are a major problem as far as I can tell. TTC operates some very long routes, and since the vehicles can’t pass eachother or anything else that gets in their way, all of the cars have to turn back before the breakdown until the thing is cleared. Streetcars have their charm, but this would not be a problem with electric trolley buses.
So, I think the big lessons from the first week are that it’s possible to train car drivers to be more competent around the humans, bike lanes do NOT ever make me feel more safe, and streetcars are definitely less reliable than buses.
That’s what I got for today. Now back to working on that real-time app!
I said when I was working on the bike map that I would get around to publishing the ‘source code’, and now that I’m preparing to leave the city, I feel I ought to finally do that. So! The basic idea of this post will be a step by step instruction for how to make yourself (or your city) an updated Cincinnati Bike Map. Strictly speaking, this will work for other cities too, but please note that the map was designed for Cincinnati in 2014 and other cities in other times, with different (data) structures may simply not work well at all.
Let’s get started!
Step 1: Get the software you’ll need: QGIS, PostGIS(a PostgreSQL extension), osm2pgsql, osm2po, GRASS, PHP(for one of the scripts), and Inkscape and GIMP for the final layout. All are free and open source and run on Linux (but probably other things too).
Step 2:Update the data! A big and important step. The vector data is all from OpenStreetMap and the process of editing OSM is well documented elsewhere, so I needn’t go into it at all here.
Step 3: Go to OpenStreetMap and navigate to the area you want to download. Be generous and include at least ten extra miles on all sides of the map you’ll be making. Click the ‘export’ tab and use the ‘Overpass API’. It will prompt you to download a large .osm XML file to your computer.
Step 4: Import that data into a PostGIS database twice: once with osm2pgsql and once with osm2po. The first will bring in the OSM data as-is, with as many tags as you care to import. To do it the way I did it, you should use this osm2pgsql.style file. The second one, osm2po will slice the linear path data (the streets and stuff) into a table of routable nodes and edges. For that one, you may want to try this configuration file. If that doesn’t work, the real point of it is to include paths that bikes can use (paths, pedestrian streets, stairs, etc), which are not included by default, while leaving out the rest.
Step 5: Process the data from osm2pgsql using this SQL script. It does quite a few things, including setting (short) street labels, calculating speed in mph, setting default speeds and lane-counts for no-data streets, identifying landmark buildings, and pulling a number of features into a consistent format for better/easier rendering.
Step 6: Run this SQL script to merge the two tables you’ve imported into one table that is both routable and has all of the important attributes/tags from OSM.
Step 7: Run tarjan.php on the new/duplicate segments table. This script uses Tarjan’s Algorithm to identify edges that connected at both ends to the main street network, and those that are not, leaving the results in a boolean field on that table.
Step 8: Once the dangling edges are identified, run this SQL script to drop the minor paths that go nowhere. Major dead-ending streets will be kept. Things like driveways will be dropped.
Step 9: Get the elevation data. I used data from the USGS (use their national map tool to download). I found that of the two decent resolutions available, one was too course (I could see pixels) and the other was too fine (I could see buildings). I chose to smooth out the finer data, using a neighborhood average in GRASS. I suppose you could also go at that the other way though too, increasing the resolution and then smoothing. The point is to get an amount of detail that just looks right and doesn’t have any visible pixelation: use your gut!
Step 10: Now you have all the data ready to go in your PostGIS database, and you just need to drop it into QGIS and style it. I wish things were easy enough that I could share a simple stylesheet with you; the way QGIS does it, the style information is all bound up with information about the table. That means that if your table/database/column/everything names are different from the ones I used, you’re going to have trouble making this run smoothly. In the interest of giving something here though instead of nothing, I’ll link to the QGIS map files used to render the main and inset maps (hills, transit, and trails). These may not be directly useful, but you could look at them as XML files, and see precisely how things were styled including line widths, hex colors, etc. It may also be useful to sample colors directly from the digital version of the map using something like GIMP. Once ready, export these maps as 300+DPI rasters using the following templates: main map, 1/3 scale inset maps.
Step 11: Now we have the base maps, we’re finally ready for the layout! I did the layout in Inkscape SVG, linking to the exported raster maps which I placed in an adjacent directory. You’ll have to re-link those, but the frames should still be in the right position.
Step 12: Profit.
Well, that’s about the gist of it. … I don’t actually think that hardly covers it, but there’s not enough time in the world to document everything for an uncertain future that may or may well not contain good bike maps. And anyway, I don’t expect anyone to slavishly duplicate my approach. We’ll call it a limited edition ;-)
If someone does actually want a real update though, I’m always available to answer questions, or if you’re the type to cut right to the chase, for hire. Email me!
The map will be on the presses shortly and should be ready for distribution by the end of August. I had actually finished just before I left for Europe a couple weeks ago, but there was a little trouble with the folding that delayed things. I had to wait until my new (European) phone plan kicked in to let me call my partner who is now working with the printer for me.
That link up there goes to the folder where I’m keeping the most recent raster version of the map for the printer. It may yet be updated a teeny bit. PLEASE NOTE that the color is not optimised for RGB yet. I designed this for a specific printer/paper and, trust me, the colors look better on paper. You can get a bit closer to seeing the actual color of the map by looking at this image. Once I get back home and back to my desktop computer, I’ll be able to work on an RGB color-corrected PDF version for the web. I thought y’all might like something to look at in the meantime though :-)
Also note that there is a 1/3″ bleed included in those images which will be trimmed off. That too will change in the PDF/web version.
I can’t wait to see these little buggers finished! ^-^
931 miles that go nowhere, versus 2,761 that offer escape from either end.
For bikes at least, not that routing for other modes would change the figure much. Fun/disturbing fact of the day! Impress your friends with your amazing and mathematically informed knowledge of Cincinnati geography!
I talked about this geography of connectivity thing a little bit already, but since that post, I’ve switched to a better dead-end-finding algorithm. Where before I was looking for tree-like structures by recursing on nodes with only one edge, I’m now able to detect all nodes which could be removed from the graph‘s largest biconnected subcomponent by the elimination of just one edge. Or those which are already detached, of course.
In layman’s terms, this answers the question: “Where should we put no-exit signs?” Or for the purpose of defending our titular statement: “what portion of streets, measured by their length, would be behind such signs?”
Here is the PHP script I wrote to implement the algorithm. It connects to a PostgreSQL DB, and looks at a specified edge table with source and target fields. (These source and target fields are the IDs of the nodes on either end of the edges.) You can create an edge table, as I did, using OSM data processed with osm2po. Since I was routing for bikes, I excluded highways and most trunk roads. I also excluded dangling service roads from the measurement.
As the script runs through the graph, every time it isolates a subcomponent, it inserts the nodes of that subcomponent into a temporary table, along with a unique ID value for the component. Once all the nodes are in there(technically, they’re all part of some subcomponent), a GROUP BY statement gives us the ID of the biggest component. This component is the main street network itself. All edges that touch any node that is NOT part of this largest component are identified as dead-ending.
Before altogether too long, I’ll get around to doing some more interesting analysis and regional comparisons and mapping and stuff. But for now, I’m off to Europe with my little netbook, which is, to my honest delight, too puny for serious GIS.