MATSIM
TransitRouterWrapper.java
Go to the documentation of this file.
1 /* *********************************************************************** *
2  * project: org.matsim.*
3  * TransitRouterWrapper.java
4  * *
5  * *********************************************************************** *
6  * *
7  * copyright : (C) 2012 by the members listed in the COPYING, *
8  * LICENSE and WARRANTY file. *
9  * email : info at matsim dot org *
10  * *
11  * *********************************************************************** *
12  * *
13  * This program is free software; you can redistribute it and/or modify *
14  * it under the terms of the GNU General Public License as published by *
15  * the Free Software Foundation; either version 2 of the License, or *
16  * (at your option) any later version. *
17  * See also COPYING, LICENSE and WARRANTY file *
18  * *
19  * *********************************************************************** */
20 package org.matsim.core.router;
21 
22 import java.util.ArrayList;
23 import java.util.List;
24 
25 import org.matsim.api.core.v01.Coord;
40 
46 public class TransitRouterWrapper implements RoutingModule {
47  private final TransitRouter router;
48  private final RoutingModule walkRouter;
50  private final Network network;
51 
52 
54  final TransitRouter router,
55  final TransitSchedule transitSchedule,
56  Network network, final RoutingModule walkRouter) {
57  if (router == null) {
58  throw new NullPointerException("The router object is null, but is required later.");
59  }
60  this.router = router;
61  this.transitSchedule = transitSchedule;
62  this.network = network;
63  if (walkRouter == null) {
64  throw new NullPointerException("The walkRouter object is null, but is required later.");
65  }
66  this.walkRouter = walkRouter;
67  }
68 
74  @Override
75  public List<? extends PlanElement> calcRoute(RoutingRequest request) {
76  List<? extends PlanElement> baseTrip = router.calcRoute(request);
77 
78  // the previous approach was to return null when no trip was found and
79  // not to replace the trip if so.
80  // However, this makes the output of routing modules more tricky to handle.
81  // Thus, every module should return a valid trip. When available, the "main
82  // mode" flag should be put to the mode of the routing module.
83  return baseTrip != null ?
84  fillWithActivities(baseTrip, request) :
85  null;
86  }
87 
92  private List<PlanElement> fillWithActivities(
93  final List<? extends PlanElement> baseTrip, RoutingRequest request) {
94  final Facility fromFacility = request.getFromFacility();
95  final Facility toFacility = request.getToFacility();
96  final double departureTime = request.getDepartureTime();
97  final Person person = request.getPerson();
98 
99  List<PlanElement> trip = new ArrayList<>();
100  Coord nextCoord = null;
101  int i = 0;
102  for (PlanElement pe : baseTrip) {
103  Leg leg = (Leg)pe;
104  if (i == 0) {
105  // (access leg)
106  Facility firstToFacility;
107  if (baseTrip.size() > 1) { // at least one pt leg available
108  TransitPassengerRoute tRoute = (TransitPassengerRoute) ((Leg)baseTrip.get(1)).getRoute();
109  firstToFacility = this.transitSchedule.getFacilities().get(tRoute.getAccessStopId());
110  } else {
111  firstToFacility = toFacility;
112  }
113  // (*)
114  Route route = createWalkRoute(fromFacility, departureTime, person,
115  leg.getTravelTime().seconds(), firstToFacility, request.getAttributes());
116  leg.setRoute(route);
117  } else {
118  if (leg.getRoute() instanceof TransitPassengerRoute) {
120  tRoute.setTravelTime(leg.getTravelTime().seconds());
121  tRoute.setDistance(RouteUtils.calcDistance(tRoute, transitSchedule, network));
123  trip.add(act);
124  nextCoord = this.transitSchedule.getFacilities().get(tRoute.getEgressStopId()).getCoord();
125  } else {
126  // it is not an instance of an ExperimentalTransitRoute so it must be a (transit) walk leg.
127 
128  // walk legs don't have a coord, use the coord from the last egress point. yyyy But I don't understand why in one case we take "nextCoord", while in the
129  // other case we retrieve the facility from the previous route.
130 
131  if (i == baseTrip.size() - 1) {
132  // if this is the last leg, we don't believe the leg from the TransitRouter. Why?
133 
134  TransitPassengerRoute tRoute = (TransitPassengerRoute) ((Leg)baseTrip.get(baseTrip.size() - 2)).getRoute();
135  Facility lastFromFacility = this.transitSchedule.getFacilities().get(tRoute.getEgressStopId());
136 
137  Route route = createWalkRoute(lastFromFacility, departureTime, person,
138  leg.getTravelTime().seconds(), toFacility, request.getAttributes());
139  leg.setRoute(route);
140  }
142  trip.add(act);
143  }
144  }
145  trip.add(leg);
146  i++;
147  }
148  return trip;
149  }
150 
151  private Route createWalkRoute(final Facility fromFacility, double departureTime, Person person, double travelTime, Facility firstToFacility, Attributes routingAttributes) {
152  // yyyy I extracted this method to make a bit more transparent that it is used twice. But I don't know why it is done in this way
153  // (take distance from newly computed walk leg, but take travelTime from elsewhere). Possibly, the problem is that the TransitRouter
154  // historically just does not compute the distances. kai, may'17
155 
156  Route route = RouteUtils.createGenericRouteImpl(fromFacility.getLinkId(), firstToFacility.getLinkId());
157  final List<? extends PlanElement> walkRoute = walkRouter.calcRoute(DefaultRoutingRequest.of(fromFacility, firstToFacility, departureTime, person, routingAttributes));
158  route.setDistance(((Leg) walkRoute.get(0)).getRoute().getDistance());
159  route.setTravelTime(travelTime);
160  return route;
161  }
162 
163 }
void setDistance(final double distance)
static RoutingRequest of(Facility fromFacility, Facility toFacility, double departureTime, Person person, Attributes attributes)
Map< Id< TransitStopFacility >, TransitStopFacility > getFacilities()
List< PlanElement > fillWithActivities(final List<? extends PlanElement > baseTrip, RoutingRequest request)
static Route createGenericRouteImpl(Id< Link > startLinkId, Id< Link > endLinkId)
Route createWalkRoute(final Facility fromFacility, double departureTime, Person person, double travelTime, Facility firstToFacility, Attributes routingAttributes)
TransitRouterWrapper(final TransitRouter router, final TransitSchedule transitSchedule, Network network, final RoutingModule walkRouter)
Id< TransitStopFacility > getEgressStopId()
List<? extends PlanElement > calcRoute(RoutingRequest request)
static double calcDistance(final NetworkRoute networkRoute, final double relPosOnDepartureLink, final double relPosOnArrivalLink, final Network network)
List<? extends PlanElement > calcRoute(RoutingRequest request)
static Activity createStageActivityFromCoordLinkIdAndModePrefix(final Coord interactionCoord, final Id< Link > interactionLink, String modePrefix)
Id< TransitStopFacility > getAccessStopId()
List<? extends PlanElement > calcRoute(RoutingRequest request)
void setTravelTime(final double travelTime)