25
25
import org .matsim .core .utils .io .IOUtils ;
26
26
import org .matsim .pt .transitSchedule .api .*;
27
27
import org .matsim .pt .utils .CreatePseudoNetwork ;
28
+ import org .matsim .pt .utils .CreatePseudoNetworkWithLoopLinks ;
28
29
import org .matsim .pt .utils .TransitScheduleValidator ;
29
30
import org .matsim .vehicles .*;
30
31
import picocli .CommandLine ;
@@ -85,8 +86,8 @@ public class CreateTransitScheduleFromGtfs implements MATSimAppCommand {
85
86
@ CommandLine .Option (names = "--transform-schedule" , description = "Fully qualified class name to a Consumer<TransitSchedule> to be executed after the schedule was created" , arity = "0..*" , split = "," )
86
87
private List <Class <?>> transformSchedule ;
87
88
88
- @ CommandLine .Option (names = "--merge-stops" , description = "Whether stops should be merged by coordinate" )
89
- private boolean mergeStops ;
89
+ @ CommandLine .Option (names = "--merge-stops" , description = "Whether stops should be merged by coordinate" , defaultValue = "doNotMerge" )
90
+ private GtfsConverter . MergeGtfsStops mergeStops ;
90
91
91
92
@ CommandLine .Option (names = "--prefix" , description = "Prefixes to add to the gtfs ids. Required if multiple inputs are used and ids are not unique." , split = "," )
92
93
private List <String > prefixes = new ArrayList <>();
@@ -100,10 +101,29 @@ public class CreateTransitScheduleFromGtfs implements MATSimAppCommand {
100
101
@ CommandLine .Option (names = "--shp-crs" , description = "Overwrite coordinate system of the shape file" )
101
102
private String shpCrs ;
102
103
104
+ @ CommandLine .Option (names = "--pseudo-network" , description = "Define how the pseudo network should be created" , defaultValue = "singleLinkBetweenStops" )
105
+ private PseudoNetwork pseudoNetwork ;
106
+
107
+
103
108
public static void main (String [] args ) {
104
109
System .exit (new CommandLine (new CreateTransitScheduleFromGtfs ()).execute (args ));
105
110
}
106
111
112
+ private static void addHbefaMapping (VehicleType vehicleType , HbefaVehicleCategory category ) {
113
+ EngineInformation carEngineInformation = vehicleType .getEngineInformation ();
114
+ VehicleUtils .setHbefaVehicleCategory (carEngineInformation , String .valueOf (category ));
115
+ VehicleUtils .setHbefaTechnology (carEngineInformation , "average" );
116
+ VehicleUtils .setHbefaSizeClass (carEngineInformation , "average" );
117
+ VehicleUtils .setHbefaEmissionsConcept (carEngineInformation , "average" );
118
+ vehicleType .setNetworkMode (TransportMode .pt );
119
+ }
120
+
121
+ private static void increaseLinkFreespeedIfLower (Link link , double newFreespeed ) {
122
+ if (link .getFreespeed () < newFreespeed ) {
123
+ link .setFreespeed (newFreespeed );
124
+ }
125
+ }
126
+
107
127
@ Override
108
128
public Integer call () throws Exception {
109
129
@@ -183,6 +203,13 @@ public Integer call() throws Exception {
183
203
184
204
Scenario ptScenario = getScenarioWithPseudoPtNetworkAndTransitVehicles (network , scenario .getTransitSchedule (), "pt_" );
185
205
206
+ for (TransitLine line : new ArrayList <>(scenario .getTransitSchedule ().getTransitLines ().values ())) {
207
+ if (line .getRoutes ().isEmpty ()) {
208
+ log .warn ("Line {} with no routes removed." , line .getId ());
209
+ scenario .getTransitSchedule ().removeTransitLine (line );
210
+ }
211
+ }
212
+
186
213
if (validate ) {
187
214
//Check schedule and network
188
215
TransitScheduleValidator .ValidationResult checkResult = TransitScheduleValidator .validateAll (ptScenario .getTransitSchedule (), ptScenario .getNetwork ());
@@ -237,14 +264,19 @@ private Predicate<Stop> createFilter(int i) throws Exception {
237
264
/**
238
265
* Creates the pt scenario and network.
239
266
*/
240
- private static Scenario getScenarioWithPseudoPtNetworkAndTransitVehicles (Network network , TransitSchedule schedule , String ptNetworkIdentifier ) {
267
+ private Scenario getScenarioWithPseudoPtNetworkAndTransitVehicles (Network network , TransitSchedule schedule , String ptNetworkIdentifier ) {
241
268
ScenarioUtils .ScenarioBuilder builder = new ScenarioUtils .ScenarioBuilder (ConfigUtils .createConfig ());
242
269
builder .setNetwork (network );
243
270
builder .setTransitSchedule (schedule );
244
271
Scenario scenario = builder .build ();
245
272
246
273
// add pseudo network for pt
247
- new CreatePseudoNetwork (scenario .getTransitSchedule (), scenario .getNetwork (), ptNetworkIdentifier , 0.1 , 100000.0 ).createNetwork ();
274
+ switch (pseudoNetwork ) {
275
+ case singleLinkBetweenStops ->
276
+ new CreatePseudoNetwork (scenario .getTransitSchedule (), scenario .getNetwork (), ptNetworkIdentifier , 0.1 , 100000.0 ).createNetwork ();
277
+ case withLoopLinks ->
278
+ new CreatePseudoNetworkWithLoopLinks (scenario .getTransitSchedule (), scenario .getNetwork (), ptNetworkIdentifier , 0.1 , 100000.0 ).createNetwork ();
279
+ }
248
280
249
281
// create TransitVehicle types
250
282
// see https://svn.vsp.tu-berlin.de/repos/public-svn/publications/vspwp/2014/14-24/ for veh capacities
@@ -449,8 +481,12 @@ private static Scenario getScenarioWithPseudoPtNetworkAndTransitVehicles(Network
449
481
// so we need to add time for passengers to board and alight
450
482
double minStopTime = 30.0 ;
451
483
484
+ List <Id <Link >> routeIds = new LinkedList <>();
485
+ routeIds .add (route .getRoute ().getStartLinkId ());
486
+ routeIds .addAll (route .getRoute ().getLinkIds ());
487
+ routeIds .add (route .getRoute ().getEndLinkId ());
488
+
452
489
for (int i = 1 ; i < routeStops .size (); i ++) {
453
- // TODO cater for loop link at first stop? Seems to just work without.
454
490
TransitRouteStop routeStop = routeStops .get (i );
455
491
// if there is no departure offset set (or infinity), it is the last stop of the line,
456
492
// so we don't need to care about the stop duration
@@ -462,8 +498,23 @@ private static Scenario getScenarioWithPseudoPtNetworkAndTransitVehicles(Network
462
498
// Math.max to avoid negative values of travelTime
463
499
double travelTime = Math .max (1 , routeStop .getArrivalOffset ().seconds () - lastDepartureOffset - 1.0 -
464
500
(stopDuration >= minStopTime ? 0 : (minStopTime - stopDuration )));
465
- Link link = network .getLinks ().get (routeStop .getStopFacility ().getLinkId ());
466
- increaseLinkFreespeedIfLower (link , link .getLength () / travelTime );
501
+
502
+
503
+ Id <Link > stopLink = routeStop .getStopFacility ().getLinkId ();
504
+ List <Id <Link >> subRoute = new LinkedList <>();
505
+ do {
506
+ Id <Link > linkId = routeIds .removeFirst ();
507
+ subRoute .add (linkId );
508
+ } while (!subRoute .contains (stopLink ));
509
+
510
+ List <? extends Link > links = subRoute .stream ().map (scenario .getNetwork ().getLinks ()::get )
511
+ .toList ();
512
+
513
+ double length = links .stream ().mapToDouble (Link ::getLength ).sum ();
514
+
515
+ for (Link link : links ) {
516
+ increaseLinkFreespeedIfLower (link , length / travelTime );
517
+ }
467
518
lastDepartureOffset = routeStop .getDepartureOffset ().seconds ();
468
519
}
469
520
@@ -481,20 +532,15 @@ private static Scenario getScenarioWithPseudoPtNetworkAndTransitVehicles(Network
481
532
return scenario ;
482
533
}
483
534
484
- private static void addHbefaMapping (VehicleType vehicleType , HbefaVehicleCategory category ) {
485
- EngineInformation carEngineInformation = vehicleType .getEngineInformation ();
486
- VehicleUtils .setHbefaVehicleCategory (carEngineInformation , String .valueOf (category ));
487
- VehicleUtils .setHbefaTechnology (carEngineInformation , "average" );
488
- VehicleUtils .setHbefaSizeClass (carEngineInformation , "average" );
489
- VehicleUtils .setHbefaEmissionsConcept (carEngineInformation , "average" );
490
- vehicleType .setNetworkMode (TransportMode .pt );
491
- }
492
-
493
- private static void increaseLinkFreespeedIfLower (Link link , double newFreespeed ) {
494
- if (link .getFreespeed () < newFreespeed ) {
495
- link .setFreespeed (newFreespeed );
496
- }
535
+ public enum PseudoNetwork {
536
+ /**
537
+ * Create links between all stops and possibly duplicate stops.
538
+ */
539
+ singleLinkBetweenStops ,
540
+ /**
541
+ * Create a pseudo network with loop links at each stop.
542
+ */
543
+ withLoopLinks ,
497
544
}
498
545
499
-
500
546
}
0 commit comments