MATSIM
TransitQLink.java
Go to the documentation of this file.
1 /* *********************************************************************** *
2  * project: org.matsim.*
3  * TransitQLink
4  * *
5  * *********************************************************************** *
6  * *
7  * copyright : (C) 2014 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.mobsim.qsim.qnetsimengine;
21 
22 import java.io.Serializable;
23 import java.util.Comparator;
24 import java.util.LinkedList;
25 import java.util.List;
26 import java.util.ListIterator;
27 import java.util.PriorityQueue;
28 import java.util.Queue;
29 
30 import org.matsim.api.core.v01.Id;
36 
37 
44 final class TransitQLink {
49  private final Queue<QVehicle> transitVehicleStopQueue = new PriorityQueue<>(5, VEHICLE_EXIT_COMPARATOR);
50  private final QLaneI road;
51 
52  private static final Comparator<QVehicle> VEHICLE_EXIT_COMPARATOR = new QVehicleEarliestLinkExitTimeComparator();
53 
54 
55  TransitQLink(QLaneI road){
56  this.road = road;
57  }
58 
59  Queue<QVehicle> getTransitVehicleStopQueue(){
60  return this.transitVehicleStopQueue;
61  }
62 
63  final boolean addTransitToStopQueue(final double now, final QVehicle veh, final Id<Link> linkId) {
64  if (veh.getDriver() instanceof TransitDriverAgent) {
65  TransitDriverAgent driver = (TransitDriverAgent) veh.getDriver();
66  while (true) {
67  TransitStopFacility stop = driver.getNextTransitStop();
68  if ((stop != null) && (stop.getLinkId().equals(linkId))) {
69  double delay = driver.handleTransitStop(stop, now);
70  if (delay > 0.0) {
71  // yy removing this condition makes at least one test fail. I still think we could discuss doing this. kai, jun'13
72 
73  veh.setEarliestLinkExitTime(now + delay);
74  // add it to the stop queue: vehicle that is not yet on the road will never block
75  transitVehicleStopQueue.add(veh);
76  return true;
77  }
78  } else {
79  return false;
80  }
81  }
82  }
83  return false;
84  }
85 
86 
92  void handleTransitVehiclesInStopQueue(final double now) {
93  QVehicle veh;
94  // handle transit traffic in stop queue
95  List<QVehicle> departingTransitVehicles = null;
96  while ((veh = transitVehicleStopQueue.peek()) != null) {
97  // there is a transit vehicle.
98  if (veh.getEarliestLinkExitTime() > now) {
99  break;
100  }
101  if (departingTransitVehicles == null) {
102  departingTransitVehicles = new LinkedList<>();
103  }
104  departingTransitVehicles.add(transitVehicleStopQueue.poll());
105  }
106  if (departingTransitVehicles != null) {
107  // add all departing transit vehicles at the front of the vehQueue
108  ListIterator<QVehicle> iter = departingTransitVehicles.listIterator(departingTransitVehicles.size());
109  while (iter.hasPrevious()) {
110  this.road.addTransitSlightlyUpstreamOfStop(iter.previous()) ;
111  }
112  }
113  }
114 
115  HandleTransitStopResult handleTransitStop(final double now, final QVehicle veh,
116  final TransitDriverAgent transitDriver, Id<Link> linkId) {
117  TransitStopFacility stop = transitDriver.getNextTransitStop();
118  if ((stop != null) && (stop.getLinkId().equals(linkId))) {
119  double delay = transitDriver.handleTransitStop(stop, now);
120  if (delay > 0.0) {
121  veh.setEarliestLinkExitTime(now + delay);
122  // (if the vehicle is not removed from the queue in the following lines, then this will effectively block the lane
123  if (!stop.getIsBlockingLane()) {
124  transitVehicleStopQueue.add(veh);
125  // transit vehicle which is removed to the transit stop space
126  return HandleTransitStopResult.accepted;
127  } else {
128  // transit vehicle which blocks its lane by getting its exit time increased
129  return HandleTransitStopResult.rehandle;
130  }
131  } else {
132  // transit vehicle which instantaneously delivered passangers
133  return HandleTransitStopResult.rehandle;
134  }
135  } else {
136  // transit vehicle which either arrives or continues driving
137  return HandleTransitStopResult.continue_driving;
138  }
139  }
140 
147  static class QVehicleEarliestLinkExitTimeComparator implements Comparator<QVehicle>,
148  Serializable, MatsimComparator {
149 
150  private static final long serialVersionUID = 1L;
151 
152  @Override
153  public int compare(final QVehicle veh1, final QVehicle veh2) {
154  if (veh1.getEarliestLinkExitTime() > veh2.getEarliestLinkExitTime()) {
155  return 1;
156  }
157  if (veh1.getEarliestLinkExitTime() < veh2.getEarliestLinkExitTime()) {
158  return -1;
159  }
160 
161  // Both depart at the same time -> let the one with the larger id be first
162  return veh2.getId().compareTo(veh1.getId());
163  }
164  }
165 }