MATSIM
TripRouter.java
Go to the documentation of this file.
1 /* *********************************************************************** *
2  * project: org.matsim.*
3  * RoutingHandler.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.Collections;
24 import java.util.HashMap;
25 import java.util.LinkedHashMap;
26 import java.util.List;
27 import java.util.Map;
28 import java.util.Set;
29 
30 import jakarta.inject.Inject;
31 import jakarta.inject.Provider;
32 
33 import org.apache.logging.log4j.LogManager;
34 import org.apache.logging.log4j.Logger;
41 import org.matsim.core.config.Config;
42 import org.matsim.core.gbl.Gbl;
45 
60 public final class TripRouter implements MatsimExtensionPoint {
61  private static final Logger log = LogManager.getLogger(TripRouter.class );
62 
63  private final Map<String, RoutingModule> routingModules = new HashMap<>();
65 
66  private Config config;
67  // (I need the config in the PlanRouter to figure out activity end times. And since the PlanRouter is not
68  // injected, I cannot get it there directly. kai, oct'17)
69 
70  public static final class Builder {
71  private final Config config;
72  private FallbackRoutingModule fallbackRoutingModule = new FallbackRoutingModuleDefaultImpl() ;
73  private Map<String, Provider<RoutingModule>> routingModuleProviders = new LinkedHashMap<>() ;
74  public Builder( Config config ) {
75  this.config = config ;
76  }
77  public Builder setRoutingModule(String mainMode, RoutingModule routingModule ) {
78  // the initial API accepted routing modules. injection, however, takes routing module providers. (why?)
79  // trying to bring these two into line here. maybe some other approach would be preferred, don't know. kai, jun'18
80  this.routingModuleProviders.put( mainMode, new Provider<RoutingModule>(){
81  @Override public RoutingModule get() {
82  return routingModule ;
83  }
84  } ) ;
85  return this ;
86  }
87  public TripRouter build() {
88  return new TripRouter( routingModuleProviders, config, fallbackRoutingModule ) ;
89  }
90  }
91 
92 // @Deprecated // use the Builder instead. kai, oct'17
93 // public TripRouter() {}
94 // // yyyyyy I guess this is meant as a way to create the trip router without injection, and to set its internals afterwards. But
95 // // is it so sensible to have this in this way? The injection stuff states that the material is immutable after injection; here we introduce a
96 // // way to get around that again, and even to change the injected material later.
97 // // I would expect a Builder instead.
98 // // kai, sep'16
99 
100  @Inject
101  TripRouter( Map<String, Provider<RoutingModule>> routingModuleProviders, Config config,
102  FallbackRoutingModule fallbackRoutingModule ) {
103  this.fallbackRoutingModule = fallbackRoutingModule;
104 
105  for (Map.Entry<String, Provider<RoutingModule>> entry : routingModuleProviders.entrySet()) {
106  setRoutingModule(entry.getKey(), entry.getValue().get());
107  }
108  this.config = config ;
109  }
110 
111  // /////////////////////////////////////////////////////////////////////////
112  // constructors
113  // /////////////////////////////////////////////////////////////////////////
114 
115  // /////////////////////////////////////////////////////////////////////////
116  // setters / getters
117  // /////////////////////////////////////////////////////////////////////////
124  @Deprecated // use the Builder instead. kai, oct'17
125  /* package-private */ RoutingModule setRoutingModule(
126  final String mainMode,
127  final RoutingModule module) {
128  RoutingModule old = routingModules.put( mainMode , module );
129 
130  return old;
131  }
132 
133  public RoutingModule getRoutingModule(final String mainMode) {
134  return routingModules.get( mainMode );
135  }
136 
137  public Set<String> getRegisteredModes() {
138  return Collections.unmodifiableSet( routingModules.keySet() );
139  }
140 
141  // /////////////////////////////////////////////////////////////////////////
142  // Handling methods
143  // /////////////////////////////////////////////////////////////////////////
157  public synchronized List<? extends PlanElement> calcRoute(
158  final String mainMode,
159  final Facility fromFacility,
160  final Facility toFacility,
161  final double departureTime,
162  final Person person,
163  final Attributes routingAttributes) {
164  // I need this "synchronized" since I want mobsim agents to be able to call this during the mobsim. So when the
165  // mobsim is multi-threaded, multiple agents might call this here at the same time. kai, nov'17
166 
167  Gbl.assertNotNull( fromFacility );
168  Gbl.assertNotNull( toFacility );
169 
170  RoutingModule module = routingModules.get( mainMode );
171 
172  if (module == null) {
173  throw new UnknownModeException( "unregistered main mode |"+mainMode+"|: does not pertain to "+routingModules.keySet() );
174  }
176  fromFacility,
177  toFacility,
178  departureTime,
179  person,
180  routingAttributes);
181 
182  List<? extends PlanElement> trip = module.calcRoute(request);
183 
184  if ( trip == null ) {
185  trip = fallbackRoutingModule.calcRoute(request) ;
186  }
187  for (Leg leg: TripStructureUtils.getLegs(trip)) {
188  TripStructureUtils.setRoutingMode(leg, mainMode);
189  }
190  return trip;
191  }
192 
193  public static class UnknownModeException extends RuntimeException {
195  final String msg) {
196  super( msg );
197  }
198  }
199 
200  // /////////////////////////////////////////////////////////////////////////
201  // public static convenience methods.
202  // /////////////////////////////////////////////////////////////////////////
203 
218  public static List<PlanElement> insertTrip(
219  final Plan plan,
220  final Activity origin,
221  final List<? extends PlanElement> trip,
222  final Activity destination) {
223  return insertTrip(
224  plan.getPlanElements(),
225  origin,
226  trip,
227  destination);
228  }
229 
240  public static List<PlanElement> insertTrip(
241  final List<PlanElement> plan,
242  final Activity origin,
243  final List<? extends PlanElement> trip,
244  final Activity destination) {
245  int indexOfOrigin = -1;
246  int indexOfDestination = -1;
247 
248  // search the trip
249  int currentIndex = 0;
250  for (PlanElement pe : plan) {
251  if (pe == origin) {
252  indexOfOrigin = currentIndex;
253  }
254  if (pe == destination) {
255  indexOfDestination = currentIndex;
256  if (indexOfDestination < indexOfOrigin ) {
257  throw new RuntimeException(
258  "destination "+destination+" found before origin "+
259  origin+" in "+plan );
260  }
261  break;
262  }
263  currentIndex++;
264  }
265 
266  // check validity
267  if (indexOfOrigin < 0) {
268  throw new RuntimeException( "could not find origin "+origin+" in "+plan );
269  }
270  if (indexOfDestination < 0) {
271  throw new RuntimeException( "could not find destination "+destination+" in "+plan );
272  }
273 
274  // replace the trip and return the former one
275  List<PlanElement> seq = plan.subList( indexOfOrigin + 1 , indexOfDestination );
276  List<PlanElement> oldTrip = new ArrayList<>( seq );
277  seq.clear();
278  assert trip != null;
279  seq.addAll( trip );
280 
281  return oldTrip;
282  }
283 
284  public Config getConfig() {
285  return config;
286  }
287 
288  @Deprecated // #deleteBeforeRelease : only used to retrofit plans created since the merge of fallback routing module (sep'-dec'19)
289  public static String getFallbackMode(String transportMode) {
290  return transportMode + FallbackRoutingModuleDefaultImpl._fallback;
291  }
292 
293  @Deprecated // #deleteBeforeRelease : only used to retrofit plans created since the merge of fallback routing module (sep'-dec'19)
294  public static boolean isFallbackMode(String mode) {
295  return mode.endsWith(FallbackRoutingModuleDefaultImpl._fallback);
296  }
297 }
298 
synchronized List<? extends PlanElement > calcRoute(final String mainMode, final Facility fromFacility, final Facility toFacility, final double departureTime, final Person person, final Attributes routingAttributes)
final Map< String, RoutingModule > routingModules
Definition: TripRouter.java:63
static RoutingRequest of(Facility fromFacility, Facility toFacility, double departureTime, Person person, Attributes attributes)
Map< String, Provider< RoutingModule > > routingModuleProviders
Definition: TripRouter.java:73
Builder setRoutingModule(String mainMode, RoutingModule routingModule)
Definition: TripRouter.java:77
static boolean isFallbackMode(String mode)
static List< PlanElement > insertTrip(final Plan plan, final Activity origin, final List<? extends PlanElement > trip, final Activity destination)
static void setRoutingMode(Leg leg, String mode)
List<? extends PlanElement > calcRoute(RoutingRequest request)
List< PlanElement > getPlanElements()
static List< PlanElement > insertTrip(final List< PlanElement > plan, final Activity origin, final List<? extends PlanElement > trip, final Activity destination)
static void assertNotNull(Object obj)
Definition: Gbl.java:212
final FallbackRoutingModule fallbackRoutingModule
Definition: TripRouter.java:64
static String getFallbackMode(String transportMode)
FallbackRoutingModule fallbackRoutingModule
Definition: TripRouter.java:72
RoutingModule getRoutingModule(final String mainMode)
static List< Leg > getLegs(final Plan plan)