openplans/OpenTripPlanner — Issue #564: Default agency ID used even if alternate is provided in GTFS
Author: chosak
Created: 2011-11-16 16:03:29+00:00
State: open

When I run API queries against a graph built from the [WMATA](http://www.wmata.com) GTFS file, which contains correct agency definitions, the returned data contains reference to the incorrect default agency ID ("TriMet").

I've modified my ```graph-builder.xml``` file to include:

```xml

```

Because the WMATA GTFS file actually contains data for two different agencies ("METRO" and "DC Circulator"), there isn't one appropriate default agency ID, so I've just left it as the default. I had assumed that because agency IDs are properly used in the GTFS dataset that this "TriMet" default agency ID would never be used.

Unfortunately, running a simple query shows that this isn't the case:

```
http://path.to.server:8080/opentripplanner-api-webapp/ws/plan? \
_dc=1321458174889&arriveBy=false&date=11%2F16%2F2011&time=10%3A42%20am&mode=TRANSIT%2CWALK \
&optimize=QUICK&maxWalkDistance=840&routerId=&toPlace=38.904201946181%2C-77.021589041702 \
&fromPlace=38.891376495065%2C-77.094373465526&intermediatePlaces=
```

The above query, run against the graph built from the WMATA GTFS, returns, in part:

```xml

2011-11-16T11:16:18-05:00
2011-11-16T11:33:00-05:00
8081.244773005155

CLARENDON METRORAIL STATION

TriMet
12648

-77.094987
38.887176

{"type": "Point", "coordinates": [-77.094987,38.887176]}

...
```

Here the leg has the correct agency ID of 2 ("METRO"), but the stop has a totally wrong agency ID! It should read "METRO" instead of "TriMet".

I've looked into the code and I have an idea for what could be causing this:

There appears to be a issue with the way that some of the models in the ```onebusaway-gtfs``` library refer to an agency ID where there isn't one specified in the GTFS specification. Model fields that should be defined to refer to a single ID are defined using the "AgencyAndID" data type when it seems like there isn't enough information to fill in that type.

Specifically, ```org.onebusaway.gtfs.model.Trip``` includes the following members:

```java
public final class Trip extends IdentityBean {
...
private AgencyAndId id;
private AgencyAndId serviceId;
private AgencyAndId shapeId;
...
}
```

and ```org.onebusaway.gtfs.model.ServiceCalendar``` includes:

```java
public final class ServiceCalendar extends IdentityBean {
...
private int id;
private AgencyAndId serviceId;
...
```

and ```org.onebusaway.gtfs.model.Stop``` includes:

```java
public final class Stop extends IdentityBean {
...
private AgencyAndId id;
...
```

According to [the GTFS spec](http://code.google.com/transit/spec/transit_feed_specification.html#trips_txt___Field_Definitions), none of these fields should refer to an agency, but should be a unique identifier of unspecified type. I'm not very familiar with the OneBusAway library, but it looks like the model loader is trying to be smart and associate an agency ID with each entity at load time, even though the files don't actually specify one. The only information it has to use at this point is the default agency ID, which is wrong.

The place where the agency ID actually gets set on the entities as they are loaded is the ```resolveAgencyId``` method in ```org.onebusaway.gtfs.serialization.mappings.DefaultAgencyIdFieldMappingFactory```. This always fills in those agency IDs with the default ID.

One possible solution for this would be to go back through the entities after they are loaded and fill in the proper agency ID by looking through the relationships between agencies, trips, stops, etc. But what happens if multiple agencies service the same stop? It seems that a stop shouldn't necessarily be linked to one particular agency. Rather, the route leg should be the place where the agency is specified. Ideally, this could contain both the agency ID as well as its name.