This post was written in the winter of 2014, but for some reason I got distracted and never posted it. Now I’m cleaning house, and here it is! In case you were wondering why it’s about winter weather…
About twice a week, I find myself waiting for the #17 at 13th and Main, heading up to UC for the day. The #17 works well for me since the geography department is on the west side of campus anyway, though in the winter more often than not I find myself wishing for a bus, any bus, for the love of god, when is the bus coming? My hands are freezing! I find myself here almost every day, but about twice a week, like I say, I find myself in a particular situation: passed up by a bus that’s going the same place I’m going, its clean, brightly lit, warm interior mocking me through it’s big windows. I don’t care it’s it’s going to the other side of campus. I just want on.
The M+ has just passed by. My inclination is to run for it’s next stop, but my position on 13th street denies me the option.
Once I see the M+ coming up Main, it’s too late to run south to the courthouse stop, too far and still too late to run up to it’s next stop at Findlay market. This is why the M+ is marginally faster than the other buses. It doesn’t stop for people like me, people of course, not at it’s limited and clearly signed set of stops.
The 13th Street stop is the one closest to my house and it’s always my starting place when catching transit up to campus. I always look south when I get there, and if I don’t see anything coming, sometimes I’ll sneak toward the courthouse, stop by stop, never getting too far away in case a bus pops out of nowhere. (Sometimes I creep north, constantly looking back…do I have time to grab a baguette?!? I pay for it, already half-way out the door.) The courthouse stop, see, has better frequency toward campus since it works for both the #17 and the M+, two high-frequency lines going where I want to go. Since they don’t usually arrive at exactly the same time, their headways compound and we get some constructive interference.
But it’s more complicated than this. Because the schedules for the #17 and M+ don’t work together, aren’t coordinated, reliably interrelated, I never know which to catch, which will actually get me to Braunstein Hall first. Both are frequent enough that I wouldn’t bother looking at a schedule if I wanted either, and both are so often just a little late or early that it wouldn’t do me much good if I did. In the absence of real-time-location information…you know what? Let’s let this derailment happen. Why not?
Where the h*ll is that real-time data, SORTA? What’s the deal here? This is getting really frustrating, now that the real-time info is posted at half a dozen stops. You’ve missed at least three of your own deadlines for releasing it. Stop making excuses and get your shit together!!!! RAAAGHAHG!!!1
*Phew* OK. Back on track. Without that real-time data, I’m essentially looking to ascertain the quantum state of the buses. Buses here are both a wave and a particle. Clearly working in a regular pattern, they still come in discrete chunks which can be discovered only by measurement and then never exactly predicted.
What’s a boy to do?
Stop fussing and wait an extra minute perhaps. That would be too simple though.
A big part of my problem here is that the schedules aren’t coordinated, meaning that they overlap and interact with each other in unpredictable ways. If they were coordinated, I could decide now which stop is usually the better one and stick to that decision.
In this particular situation, there’s not a good case to be made that these ones should be coordinated since they split off from each other once they get to the hill, but my dilemma illustrates a broader problem with the way SORTA has conceived of BRT: as a fast express line mostly redundant to a slow local service. Schedule coordination is impossible where lines are running at different speeds.
And this same problem becomes more dramatic when I consider other destinations. Lets say I want to get to Norwood, or once there, even further out to Kenwood. In the first case, I would have to take a bigger risk in walking toward the courthouse stop. The #4 turns east around the corner from the courthouse stop, meaning that I can’t even see it coming.
The best choice would necessarily be based on expected waiting times and expected travel times. A better-than-probabilistic decision can’t realistically be made during higher-frequency hours since the normal(in the non-statistical sense at least) delays, disrupt shorter and more-frequent trips more, relatively speaking. In the later case, I would most likely be presented with the same optimizing tactic that finds me sneaking south on Main Street. That is: walk to the nearest stop on Montgomery Road and once there, inch toward the closest higher-frequency stop, taking in any case whichever bus comes first. Once I know the position of one bus, the one having just arrived, I won’t typically wait around for the next since it’s position is unknown and possibly very distant. Assuming both came at once, and were both stopping, the choice would be easy: the faster one.
The problem here is one of lost potential. It’s not a bad situation by any stretch(I have two reasonably frequent-transit options! Yay!) but it could be better. Rather than having two transit lines in the same corridor running at ten-minute headways, one dramatically faster than other, we could have one line, significantly faster than what we have now, running more consistently, more frequently, and importantly: more simply.
Express lines, as SORTA have conceived them, split the baby.
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.
All data is from current(April 2014) public GTFS feeds listed here. I calculated the straight-line distance, in feet, using the appropriate US state-plane projections, from each and every stop on each line to the next scheduled stop in that line. I then weighted each segment distance thus created by the number of times the agency traverses that segment each week. Weekday trips count 5 times Saturday-only trips, etc. That should give us something like the average person’s experience of the distance to the next stop, if people are evenly distributed across vehicles. The chart was plotted in R using the density() function, output to SVG, and then tweaked and reoriented in Inkscape.
Draw your own conclusions!
EDIT: Some useful SQL code using the basic table structure from GTFS; I simply imported the calendar.txt, trips.txt, stop_times.txt & stops.txt from each agency’s feed into a POSTGIS DB and ran a spatial query on that. Here’s the basic procedure for Muni:
--create the whole table, even though we only need a few things
--it's easier than editing the CSV
CREATE TABLE sfmta_calendar (
CREATE TABLE sfmta_trips (
CREATE TABLE sfmta_stop_times (
CREATE TABLE sfmta_stops (
-- bring in the data
-- mind you get rid of the headers first
COPY sfmta_calendar FROM '/home/nate/calendar.txt' DELIMITER ',' CSV;
COPY sfmta_trips FROM '/home/nate/trips.txt' DELIMITER ',' CSV;
COPY sfmta_stop_times FROM '/home/nate/stop_times.txt' DELIMITER ',' CSV;
COPY sfmta_stops FROM '/home/nate/stops.txt' DELIMITER ',' CSV;
-- add a geometry column
ALTER TABLE sfmta_stops ADD COLUMN the_geom geometry(POINT,3494);
UPDATE sfmta_stops SET the_geom =
ST_GeomFromText('POINT('|| stop_lon ||' '|| stop_lat ||')', 4326)
--add columns which we'll update with the values we're actually interested in
ALTER TABLE sfmta_stop_times
ADD COLUMN weight integer,
ADD COLUMN next_stop real;
--run the spatial query
--first get each stop paired up with the next one down the line.
--this should return the total number of records in the stop_times
-- table minus the number of records in the trips table
--(each trip has one final stop)
WITH temp AS (
FROM sfmta_trips AS t
JOIN sfmta_stop_times AS st ON t.trip_id = st.trip_id
JOIN sfmta_stops AS s ON st.stop_id = s.stop_id),
--now get a table of weights
--most agencies use the same schedule for all week days and
--we don't want to over-emphasize weekend-only services
--each day column simply has a true/false binary value, which we've treated as an integer
weights AS (
(monday+tuesday+wednesday+thursday+friday+saturday+sunday) AS weight
--join all that shit and calculate the distance from each stop to the next
UPDATE sfmta_stop_times SET
next_stop = t1.the_geom <-> t2.the_geom,
weight = weights.weight
FROM temp AS t1
JOIN temp AS t2 ON
t1.stop_sequence = t2.stop_sequence + 1
AND t1.trip_id = t2.trip_id
AND t1.route_id = t2.route_id
JOIN weights ON weights.service_id = t1.service_id
t1.trip_id = sfmta_stop_times.trip_id AND
t1.stop_sequence = sfmta_stop_times.stop_sequence;
-- and export the data
WHERE next_stop > 0
) TO '/home/nate/sfmta.csv' DELIMITER ',' CSV HEADER;
Apologies for the slow posting here lately…grad school has been swallowing an outrageous amount of my time the last couple of weeks. I do have some interesting things in the works though, so I’ll just whet your appetites until they’re ready to fruit before leaving you with some methodological musings.
My first semester as a geography grad student is finally over! I haven’t picked a thesis topic yet, though I do have a feeling it’s going to have a lot to do with cartography and transportation when it comes. I’ll be TA-ing Human Geography next semester, and using some (formal, advised) independent study time to further develop a bicycle map concept.
So, about that bike map… after three or four months of teaming with Queen City Bike, they still hadn’t pulled together enough money to make me feel confident that the project was going to happen. $500 in four months is not a great start when I was shooting for $5,000 in the first! I’m currently, slowly looking into grants and doing everything I can to avoid having to do all the fundraising personally. As much as I enjoy talking with each and every one of you and asking for money, I learned from the transit map project that doing that puts too much of the burden of keeping the project alive on me. I’d really like to make this next big map project into something that keeps going for more than a couple printings and if that’s going to happen, I need someone else to seriously invest in it and care about it’s continuing success.
I’m presenting at the first poster session of the Transportation Research Board annual meeting in DC this January! This is exciting for three reasons: My topic(next bullet), it’s a mostly-free trip to a city, and I’ll get to print my poster at 8’x4′. Yes, that is eight feet by four feet! My poster will be bigger than me which is pretty cool, especially if the resolution on the printer is any good :-)
My poster topic, and the biggest devourer of my recent time, is a quantitative analysis of total access in several stop-spacing and service frequency scenarios. It’s my intention to prove(or disprove) that people, at least in the short term, would have better ‘access’ if SORTA abandoned their ‘BRT’ plans and simply added service to existing lines and got rid of some low-ridership stops. You’ll hear more about this here when it’s ready.
But I may also blame the slow posting on a rapidly developing understanding of my approach to such problems as the ones I’m trying to address through this blog. My rational side says I need to be positive and empirical, adding nuance and evidence to the general discussion of transit in Cincinnati, but the less rational sides of me want prankishness and a negative reproach to the nonsense I see going on all around me, particularly about ‘the streetcar’. As much as I want to tear down the populist John Schneiders and John Cranleys I want to take the high road and pretend that I might thereby climb high enough to avoid them. But would I then still be able to see the ground to which I must ultimately return for food and shelter? I’m torn. I wonder if a positive approach which strives for intellectual rigor first is more than an acknowledgement that practical political change in Cincinnati is hopeless (in the short term at least) and that my personal prospects lie in a different context with different values. Am I seeking validation from a group of elite critics and experts, popularly ignored, or actually trying to change a system largely run by demagogues and their uninterested employees? Is a synthesis possible?
Access is a pretty vague word. I don’t think I could succinctly define it and I suspect no one else could either as it regards discussions about transit and transportation. Still, we can imagine a transit line that makes no stops at all and say that it would provide no access whatsoever. It would be useless. Similarly, a line with infinite stops where the bus moves infinitesimally after each stop before stopping again also has an access value of 0; it would also be useless.1
Somewhere in the middle is the Goldilocks stop spacing arrangement. Where does the m+ fall on this spectrum? Where do the other lines in the system? Might there be an ideal middle ground or are both either too crowded or sparse? Is there room for …lets call it ‘schedule diversity’ within a corridor? What effect does that have on effective frequency and average wait times at the skipped-over stops?
I’d like to hear SORTA’s and TANK’s official positions, or perhaps not positions but perspectives, on these questions as they move forward with their discussions of adding more rapid-transit-like lines to their systems. It’s not evident to me as an outsider that they’ve weighed the issue at all, at least publicly. Transit planners? Can you weigh in please? I’ve made my opinion clear in the above chart but I’m curious how SORTA and TANK would re-draw it and what they might add to it.
Though my line tapers off here without hitting 0 because the driver has some agency in stopping and doesn’t have to stop at an empty stop. Infinite stops might be more comparable to dial-a-ride or flexible schedule or no-stop services. ↩
I decided a couple weeks ago, after returning from a long vacation on the east coast, that I was going to break out of my normal routine. Every morning pre-vacation I would wake up, grab my computer, and head out from my apartment in Pendelton to one of about 5 coffee shops within walking distance. I was in a rut. I was sick of the coffee, the people, and even the walk to get there. I’d been in Manhattan just a touch too long to be satisfied confining my perambulations to Over-the-Rhine alone!
I often have this realization and make promises to myself, too easily broken, that I’m going to shatter my routine. My pledge this time: I’m going to every single coffee shop in the metro area at least once and never to the same one twice until I completely exhaust my options. In an effort to hold myself accountable, I’ve decided to make a project of my commitment to diverse experience: I’m going to document every trip to every coffee shop including:
Mode used to get there(walk, transit, bike, helicopter, etc.)
Path taken(on the way there)
Review of the coffee shop building and it’s surroundings
Whether there was on-site parking
Type of people seen there(mostly students? Business meetings? )
How fun the trip was
How long it took me to get there
Time/Date of visit
or more precisely:
CREATE TABLE public.coffee_runs
gid integer NOT NULL DEFAULT nextval('coffee_runs_gid_seq'::regclass),
shop_name character varying,
"time" timestamp without time zone DEFAULT now(),
type_of_folk text, -- What kind of people are here?
trip_fun_value integer, -- FUN: rated from 1 to 5, 5 being the most fun
mode character varying, -- bike, walk, transit, etc
The end result should be an interesting and esoteric map of coffee quality, trip types, and travel times from Downtown(ish). I’m extremely curious how the degree of trip-fun correlates with various areas of the city and modes of travel. A guess: The further out, the less fun. Hopefully there will be surprises!
Starbucks, Downtown, second floor atrium, near Main and 6th. I have never been here before. (no statistically significant results just yet)