MATSIM
DefaultAnalysisMainModeIdentifier.java
Go to the documentation of this file.
1 
2 /* *********************************************************************** *
3  * project: org.matsim.*
4  * DefaultAnalysisMainModeIdentifier.java
5  * *
6  * *********************************************************************** *
7  * *
8  * copyright : (C) 2023 by the members listed in the COPYING, *
9  * LICENSE and WARRANTY file. *
10  * email : info at matsim dot org *
11  * *
12  * *********************************************************************** *
13  * *
14  * This program is free software; you can redistribute it and/or modify *
15  * it under the terms of the GNU General Public License as published by *
16  * the Free Software Foundation; either version 2 of the License, or *
17  * (at your option) any later version. *
18  * See also COPYING, LICENSE and WARRANTY file *
19  * *
20  * *********************************************************************** */
21 
22 package org.matsim.core.router;
23 
24 import org.apache.logging.log4j.LogManager;
25 import org.apache.logging.log4j.Logger;
29 
30 import java.util.ArrayList;
31 import java.util.List;
32 
42  // Please do not lightheartedly change this class, you are not the only user affected.
43 
44  private static final Logger log = LogManager.getLogger(DefaultAnalysisMainModeIdentifier.class);
45 
46  private final List<String> modeHierarchy = new ArrayList<>() ;
47 
49  // If you want to change the mode hierarchy, please create your own copy for that.
50  modeHierarchy.add( TransportMode.non_network_walk ) ;
51  modeHierarchy.add( "undefined" ) ;
52  modeHierarchy.add( TransportMode.transit_walk) ;
53  modeHierarchy.add( TransportMode.other ) ;
54  modeHierarchy.add( TransportMode.walk ) ;
55  modeHierarchy.add( TransportMode.bike ) ;
56  modeHierarchy.add( TransportMode.taxi ) ;
57  modeHierarchy.add( TransportMode.drt ) ;
58  modeHierarchy.add( TransportMode.ride ) ;
59  modeHierarchy.add( TransportMode.motorcycle ) ;
60  modeHierarchy.add( TransportMode.truck );
61  modeHierarchy.add( TransportMode.car ) ;
62  modeHierarchy.add( TransportMode.pt ) ;
63  modeHierarchy.add( TransportMode.train ) ;
64  modeHierarchy.add( TransportMode.ship ) ;
65  modeHierarchy.add( TransportMode.airplane ) ;
66 
67  modeHierarchy.add( "freight" ) ; // not clear where this should go since it is not passenger traffic, but it is used in many scenarios.
68 
69  // NOTE: This hierarchical stuff is not so great: is park-n-ride a car trip or a pt trip? Could weigh it by distance, or by time spent
70  // in respective mode. Or have combined modes as separate modes. In any case, can't do it at the leg level, since it does not
71  // make sense to have the system calibrate towards something where we have counted the car and the pt part of a multimodal
72  // trip as two separate trips. kai, sep'16
73  }
74 
75  @Override public String identifyMainMode( List<? extends PlanElement> planElements ) {
76  int mainModeIndex = -1 ;
77  String unknownMode = null;
78  for ( PlanElement pe : planElements ) {
79  if (pe instanceof Leg leg) {
80  int index = modeHierarchy.indexOf( leg.getMode() ) ;
81  if ( index < 0 ) {
82  /*
83  * The current leg mode is not included in the hierarchy above.
84  *
85  * If besides this unknown mode there are only (access/egress) non_network_walk and walk, we can assume that this unknown mode
86  * is the main mode. That assumption saves creating custom AnalysisMainModeIdentifier if new modes not included in the hierarchy
87  * above are used. However, with multiple modes besides walk and non_network_walk we need to know the hierarchy of those modes
88  * to determine which of those is the main mode.
89  */
90  if (unknownMode != null && !unknownMode.equals(leg.getMode())) {
91  log.error("Multiple unknown modes in one trip: " + leg.getMode() + " and " + unknownMode + ". The AnalysisMainModeIdentifier" +
92  " cannot determine which of those is the main mode because they are both unknown to it. Please bind your own " +
93  "AnalysisMainModeIdentifier that interprets all modes used in your scenario correctly.");
94  throw new IllegalStateException("unknown modes in AnalysisMainModeIdentifier: " + leg.getMode() + " and " + unknownMode ) ;
95  } else {
96  unknownMode = leg.getMode();
97  }
98  }
99  if ( index > mainModeIndex ) {
100  mainModeIndex = index ;
101  }
102  }
103  }
104 
105  if (unknownMode != null) {
106  if (mainModeIndex > modeHierarchy.indexOf( TransportMode.walk )) {
107  // another mode besides walk and our unknown mode was found before, we don't know which of them is the main mode
108  log.error("Unknown mode " + unknownMode + " and " + modeHierarchy.get( mainModeIndex ) + " found in the same trip. The " +
109  "AnalysisMainModeIdentifier cannot determine which of those is the main mode because they are both unknown to it. " +
110  "Please bind your own AnalysisMainModeIdentifier that interprets all modes used in your scenario correctly.");
111  throw new IllegalStateException("unknown mode in AnalysisMainModeIdentifier: " + unknownMode);
112  } else {
113  return unknownMode;
114  }
115  }
116 
117  return modeHierarchy.get( mainModeIndex ) ;
118  }
119 }
String identifyMainMode(List<? extends PlanElement > planElements)