Transit Index API

307 views
Skip to first unread message

Andrew Byrd

unread,
Feb 8, 2014, 10:02:14 AM2/8/14
to opentripp...@googlegroups.com
Hello dev list,

Probably more than any other part of OTP, the Transit Index API is the
result of the unorchestrated accumulation of patches. I've had various
reports that it "doesn't work right", some of the responses are
constructed in a convoluted manner, and overall the API is not as clean
and coherent as it should be.

As part of my work on profile routing (searching over a wide range of
times rather than a specific time) I needed a uniform notion of stop
patterns (JourneyPatterns) throughout OTP. This need is expressed in
ticket #1320, and work is progressing on branch 1320_patterns. With the
unified pattern concept in place, we obtain the "missing link" in the
GTFS data model and a coherent, nicely structured REST-ish transit index
falls into place. See
https://github.com/opentripplanner/OpenTripPlanner/blob/1320_patterns/otp-core/src/main/java/org/opentripplanner/index/IndexAPI.java

In summary, it looks like this:
/index/agencies
/index/agencies/{id}
/index/stops?lat=y&lon=x&radius=r
/index/stops/{id}
/index/stops/{id}/routes
/index/stops/{id}/patterns
/index/stops/{id}/stoptimes (not implemented yet, will be realtime!)
/index/routes
/index/routes/{id}
/index/routes/{id}/patterns
/index/routes/{id}/stops
/index/routes/{id}/trips
/index/trips (Results are too voluminous. Constrain with x/y/radius?)
/index/trips/{id}
/index/trips/{id}/stops
/index/trips/{id}/stoptimes
/index/patterns
/index/patterns/{id}
/index/patterns/{id}/trips
/index/patterns/{id}/stops
to be continued...

Besides the hierarchical naming of endpoints in accordance with GTFS
terms, another change is lazy-initializing the internal transit index
objects rather than requiring an additional graph builder module and
serializing the index into the Graph file. Building the index is not
particularly time consuming and can be done on demand.

As the patches making up the existing Transit Index were all created to
"scratch an itch", that set of endpoints does effectively tell us what
kind of supplemental information people need to fetch about transit
feeds. I will be extending the new index API to cover those same use
cases. Ideally this new layout will be the one included in OTP's 1.0
API, so if anyone has any suggestions on endpoints to include, or no
longer uses an endpoint they once added to the old transit index, please
let me know.

-Andrew

Andrew Byrd

unread,
Feb 8, 2014, 10:08:36 AM2/8/14
to opentripp...@googlegroups.com
On 02/08/2014 04:02 PM, Andrew Byrd wrote:
> In summary, it looks like this:
> /index/agencies
> /index/agencies/{id}
> /index/stops?lat=y&lon=x&radius=r
> /index/stops/{id}
> /index/stops/{id}/routes
> /index/stops/{id}/patterns
> /index/stops/{id}/stoptimes (not implemented yet, will be realtime!)

I imagine
/index/stops/{id}/routes/{id}/stoptimes/
and
/index/routes/{id}/stops/{id}/stoptimes/

would be pretty useful as well, and could be backed by the same method.

-Andrew

Matthias Hogerheijde

unread,
Feb 10, 2014, 4:03:35 AM2/10/14
to opentripp...@googlegroups.com
Would 


/index/stops/{id}/routes/{id}/stoptimes/ 
and 
/index/routes/{id}/stops/{id}/stoptimes/ 

by synonyms for 

/index/trips/{id}/stoptimes
and
/index/stops/{id}/stoptimes

Because I would vote against synonyms. Just link to the right location. So in order to go to the timetable from a stop listed in /index/routes/{id}/stops there should be a link to the specific stop /index/stops/{id}, from there you know how to retrieve the stoptimes: /index/stops/{id}/stoptimes.

The /index/stops?lat=y&lon=x&radius=r call now only contains a circle. But I would imagine the need/wish for a bounding box, or maybe even a ploygon.

The rest of it does get my vote ;)

Matthias

Matthias Hogerheijde

unread,
Feb 10, 2014, 4:45:31 AM2/10/14
to opentripp...@googlegroups.com

The /index/stops?lat=y&lon=x&radius=r call now only contains a circle. But I would imagine the need/wish for a bounding box, or maybe even a ploygon.

*polygon 

Andrew Byrd

unread,
Feb 10, 2014, 5:57:11 AM2/10/14
to opentripp...@googlegroups.com
Hello Matthias,

I agree that we should avoid adding a level of API endpoints
hierarchically underneath another unless it somehow refines or restricts
the results of the higher level.

The two endpoints
/index/stops/{id}/routes/{id}/stoptimes/ and
/index/routes/{id}/stops/{id}/stoptimes/

would fetch the stoptimes at the given stop for the trips on the given
route, so each level restricts the information a bit more. The use case
would be retrieving next departure times for only one route passing
through a station with many routes, e.g. for providing user-specific
information on a smartphone application. I suppose it's better to choose
one or the other as the canonical ordering to keep things clear and simple.

/index/trips/{id}/stoptimes
Would fetch the stoptimes for every stop on that trip.

/index/stops/{id}/stoptimes
would fetch the stoptimes at the given stop for every trip passing
through the stop (possibly grouped by route), like so:

[ {
route: A,
times: [
{
trip: A001,
arrival: {
scheduled: 12:00:00,
predicted: 12:00:42
},
departure: {
scheduled: 12:02:00,
predicted: 12:02:00
}
},
{
trip: A002,
arrival: {
scheduled: 12:30:00,
predicted: null
},
departure: {
scheduled: 12:32:00,
predicted: null
}
}]
},
{
route: B,
times: [
...
]

So each level of the API can be thought of as "slicing" a
multidimensional table (stop, route, time) along one axis.

Of course this would benefit from being restricted to a time window,
which I suppose will be indicated by "now" and ISO-datetime
sub-resources or query parameters.


-Andrew
> --
> You received this message because you are subscribed to the Google
> Groups "OpenTripPlanner Developers" group.
> To unsubscribe from this group and stop receiving emails from it, send
> an email to opentripplanner...@googlegroups.com.
> For more options, visit https://groups.google.com/groups/opt_out.

Andrew Byrd

unread,
Feb 10, 2014, 6:04:54 AM2/10/14
to opentripp...@googlegroups.com
Agreed, a bounding box option is essential because people will be
fetching stops for display in rectangular windows.

I could implement this as
/index/stops?bbox=minLat,minLon,maxLat,maxLon

or
/index/stops?minLat=y0&minLon=x0&maxLat=y1&maxLon=x1

since the latter removes the confusion of positional arguments.

-Andrew

Matthias Hogerheijde

unread,
Feb 10, 2014, 8:58:34 AM2/10/14
to opentripp...@googlegroups.com
Agreed, i was to quick in my conclusion that is was synonymous.

Matthias Hogerheijde

unread,
Feb 10, 2014, 9:05:30 AM2/10/14
to opentripp...@googlegroups.com
I guess you would like to be able to do both a circle and a bounding box. Don't know what the best option is to name the agruments. Positional is confusing indeed, but if you want to have multiple types you could do something like

?circle=<centerX>,<centerY>,<radius>
?bbox=<upperLeftX>,<upperLeftY>,<lowerRightX>,<lowerRightY>
?poly=<x1>,<y1>;<x2>,<y2>;<x3>,<y3>;....

which looks nice I think. When new options become available, you can add them easily as well.

Another question I might ponder is: Might one want to filter stops by parent_station? E.g. all platforms within a railway station.

Andrew Byrd

unread,
Feb 10, 2014, 9:18:30 AM2/10/14
to opentripp...@googlegroups.com
On 02/10/2014 03:05 PM, Matthias Hogerheijde wrote:
> ?circle=<centerX>,<centerY>,<radius>
> ?bbox=<upperLeftX>,<upperLeftY>,<lowerRightX>,<lowerRightY>
> ?poly=<x1>,<y1>;<x2>,<y2>;<x3>,<y3>;....

Yes, the positional forms are not that bad. It's somewhat simpler to
explain, document, and parse because only one query parameter is allowed
at a time.

When would someone actually need to filter by a polygon on the server
side? I'm trying to avoid adding endpoints to the API purely for
completeness.

These points are somewhat minor, but:
1. to be consistent should it also be allowed to separate the coordinate
pairs in bbox with a semicolon?
2. Is there any reason why you choose upper left and lower right? I
generally like lower left and upper right, as this groups the minimum
and maximum coordinates together.

> Another question I might ponder is: Might one want to filter stops by
> parent_station? E.g. all platforms within a railway station.

I guess that could be done with:
/index/stations/{parent_station_id}

-Andrew
Reply all
Reply to author
Forward
0 new messages