I keep coming back to this because it is really awkward to use. Maybe we took a wrong turn there, and should consider recitifying it.
The current problem is that we have
The consequence is that we cannot put an Id<TransitStopFacility> there. But that is what we would need, since we have an access walk to that stop facility, a drt interaction activity at the stop facility, and then a drt trip from there.
The problem, evidently, is that
I am also unable to find an alternative; e.g. a signature
I can see two alternatives:
(A) a common facility ID space. I have argued for that many times; I want to make my argument again.
The change would be
and fix the fallout.
One issue with that is that facility IDs then would need to be unique across several containers (ActivityFacilities, TransitStopFacilities, ...). This is, however, something that would be necessary anyways if the activity wants to point to, say, a transit stop.
The mechanism to get there is clear, since for Vehicle we have the same thing: There is CarrierVehicle, DrtVehicle, plain Vehicle, TransitVehicle. The mobsim reads all of them, and complains when an ID is repeated.
(B) move Id from generics to inheritance. I think in retrospect that that would have been the better option. There are two reasons:
(I) With that, Id inheritance would have the same properties as object inheritance. E.g. if
Which would mean that the Ids could follow the same inheritance scheme as the object, no longer causing problems every time we switch from Objects to the Ids (which we always do when we reference between containers).
(II) Another advantage of using Id inheritance would be that there is no type erasure: Once the Id is generated with the correct type, that type can always be recovered. That is, we would need to make sure that createPersonId, createVehicleId, etc. generate the correct type in the first place, and everything that follows is less critical.
Quite possibly, given the state of the project, alternative (B) is too much heavy lifting, and the concrete benefits are unclear.
But I am convinced we should do (A). And it would go along with a decision to have "flat" ID spaces in all matsim containers even if they use inheritance. I.e. if at some point we inherit from Person, the id should still be Id<Person>. Or if we want to introduce IDs for Activity, the signature would have to be Id<PlanElement>.
BTW, in branch knFacilityIdInActivity I have changed the core to Id<Facility> as a proposal; it was not very hard to do.
(4) Not sure if "referring to a facility" instead of "inheriting from facility" makes a difference here. The problem comes from the fact that our base data structures refer to IDs as soon as the material they want to point to is in a different container. If Activity would point to Facility instead of Id<??>, there would not be a problem. – I haven't thought into that direction.
Just to prevent misunderstanding: With “transit stops refer to a facility” I meant they refer to a (Facility)Id. I did not mean that they should point to the facility object in memory.
The idea was that if transit stops are not facilities (they do not inherit from Facility), but they just point to one using the facility’s Id, then it would be clear that for each transit stop there must be a Facility in the facilities file, like there must be the corresponding links in the network for the transit routes. It would basically enforce that there is only one facilities container, and not multiple.
Thanks. I guess that this could be considered. However, we would get another hashmap lookup every time we would need the coordinate of a transit stop.
Let me backtrack to the original problem. Currently, we have
Now it is possible to perform pt interaction activities at transit stop facilities, but with the above signature I cannot do
As a starting point for an alternative, one could consider
This would, in general, work. However, we would put in, say, Id<TransitStopFacility>, and get back Id<? extends Facility>. In consequence, the lookup
would be marked (at least by IntelliJ) as a possible problem. Although it would work. (Since, as we know, Id is internally backed by a string, and the strings are always the same no matter what the id type.) This is currently in branch knFacilityIdInActivityAlt.
To avoid the warning, I could do
Maybe this is a possiblity. It clarifies that when we get the facility ID back from the activity, we don't know of which type it is. (#)
(#) This is where typed IDs would help ... the original type would still be available as runtime. However, Marcel's observation from above becomes clearly visible here: When reading the population file, we would not know the necessary ID type. Which somewhat clarifies that moving to an inherited Id would be a lot of effort, and cause other problems.
I am sorry, but at need to come back to this. It is clear that agents can perform activities at facilities with IDs that are not of type ActivityFacility. So the smallest adaptation would be, as stated above, to return Id<? extends Facility>. I would then afterwards need to find that facility, with lookups in various containers.
In order for this to work, I still need unique IDs across facilities: If I have a transit stop and an activity facility with the same ID, I might retrieve the wrong one. As stated, I think that I can enforce ID uniqueness as with vehicles, where the code checks this when they are inserted into the mobsim.
If nobody chips in with additional comments, I think this is what I will do. Under protest , since I think that once we assume ID uniqueness across all facility types, we could as well admit it and use Id<Facility>. It would have the additional benefit of being of the same design as with vehicles (where we also have one Id<Vehicle>, but several contains in which vehicles reside.