21 package org.matsim.core.mobsim.qsim.qnetsimengine;
25 import org.apache.logging.log4j.LogManager;
26 import org.apache.logging.log4j.Logger;
114 static final class Builder {
123 this.netsimEngine = netsimEngine;
127 this.linkSpeedCalculator = linkSpeedCalculator ;
134 AbstractQLink build(
Link link, QNodeI toNodeQ, List<ModelLane>
lanes ) {
135 Objects.requireNonNull( linkSpeedCalculator );
136 return new QLinkLanesImpl(link, toNodeQ, lanes, context, netsimEngine, linkSpeedCalculator, flowEfficiencyCalculator, vehicleHandler ) ;
163 private final List<ModelLane>
lanes;
180 super(link, toNodeQ, context, netsimEngine, linkSpeedCalculator, vehicleHandler);
182 this.toQueueNode = toNodeQ;
183 this.laneQueues =
new LinkedHashMap<>();
184 this.toNodeLaneQueues =
new ArrayList<>();
187 this.nextQueueToLinkCache =
new LinkedHashMap<>();
191 this.visdata = this.
new VisDataImpl();
192 this.setTransitQLink(
new TransitQLink(this.firstLaneQueue));
196 Stack<QLaneI> stack =
new Stack<>();
197 Map<Id<Lane>,
QLaneI> queueByIdMap =
new HashMap<>();
198 Map<Id<Lane>, Set<Id<Link>>> laneIdToLinksMap =
new HashMap<>();
200 Id<Lane> laneId = lane.getLaneData().getId();
206 QueueWithBuffer.Builder builder =
new QueueWithBuffer.Builder( context ) ;
208 builder.setLaneId(laneId);
209 builder.setLength(lane.getLength());
210 builder.setEffectiveNumberOfLanes(lane.getLaneData().getNumberOfRepresentedLanes());
211 builder.setFlowCapacity_s(lane.getLaneData().getCapacityVehiclesPerHour() / 3600.);
212 builder.setFlowEfficiencyCalculator(flowEfficiencyCalculator);
213 QLaneI queue = builder.createLane(
this);
215 queueByIdMap.put(laneId, queue);
216 firstLaneQueue = queue;
218 Set<Id<Link>> toLinkIds =
new HashSet<>();
220 if (lane.getToLanes() == null || lane.getToLanes().isEmpty()) {
222 this.toNodeLaneQueues.add(queue);
223 toLinkIds.addAll(lane.getLaneData().getToLinkIds());
224 laneIdToLinksMap.put(laneId, toLinkIds);
226 Map<Id<Link>, List<QLaneI>> toLinkIdDownstreamQueues =
new LinkedHashMap<>();
228 toLinkIdDownstreamQueues);
230 Set<Id<Link>> toLinks = laneIdToLinksMap.get(toLane.getLaneData().getId());
231 if (toLinks == null){
235 if (!laneIdToLinksMap.containsKey(laneId)) {
236 laneIdToLinksMap.put(laneId,
new HashSet<
Id<Link>>());
238 laneIdToLinksMap.get(laneId).addAll(toLinks);
240 List<QLaneI> downstreamQueues = toLinkIdDownstreamQueues.get(toLinkId);
241 if (downstreamQueues == null) {
242 downstreamQueues =
new ArrayList<>();
243 toLinkIdDownstreamQueues.put(toLinkId, downstreamQueues);
245 downstreamQueues.add(queueByIdMap.get(toLane.getLaneData().getId()));
253 while (!stack.isEmpty()) {
254 QLaneI queue = stack.pop();
255 this.laneQueues.put(queue.
getId(), queue);
266 super.clearVehicles();
267 for (
QLaneI lane : this.laneQueues.values()) {
268 lane.clearVehicles();
276 boolean lanesActive =
false;
277 boolean movedWaitToRoad =
false;
287 this.getTransitQLink().handleTransitVehiclesInStopQueue(now);
290 this.getTransitQLink().handleTransitVehiclesInStopQueue(now);
294 this.setActive(lanesActive || movedWaitToRoad || (!this.getWaitingList().isEmpty())
295 || !this.getTransitQLink().getTransitVehicleStopQueue().isEmpty());
296 return this.isActive();
300 boolean activeLane =
false;
301 for (
QLaneI lane : this.laneQueues.values()) {
305 if (!this.toNodeLaneQueues.contains(lane)) {
320 for (
QLaneI lane : this.laneQueues.values()) {
321 lane.initBeforeSimStep();
324 for (
QLaneI lane : this.laneQueues.values()) {
332 activeLane = activeLane || lane.isActive();
359 if (nextQueue != null) {
367 StringBuilder b =
new StringBuilder();
369 b.append(
" is on Lane Id ").append(qlane.
getId());
370 b.append(
" on Link Id ").append(this.
getLink().getId());
371 b.append(
" and wants to drive to Link Id ").append(toLinkId);
372 b.append(
" but there is no Lane leading to that Link!");
373 log.error(b.toString());
374 throw new IllegalStateException(b.toString());
380 List<QLaneI> toQueues = this.nextQueueToLinkCache.get(queue.
getId()).
get(toLinkId);
381 QLaneI retLane = toQueues.get(0);
382 if (toQueues.size() == 1) {
386 for (
int i = 1; i < toQueues.size(); i++) {
387 QLaneI toQueue = toQueues.get(i);
403 boolean movedWaitToRoad =
false;
404 while (!getWaitingList().isEmpty()) {
406 return movedWaitToRoad;
408 QVehicle veh = this.getWaitingList().poll();
410 movedWaitToRoad =
true;
415 if (this.getTransitQLink().addTransitToStopQueue(now, veh, this.
getLink().getId())) {
429 return movedWaitToRoad;
435 for (
QLaneI lane : this.toNodeLaneQueues) {
436 if (!lane.isNotOfferingVehicle()) {
447 for (
QLaneI lane : this.laneQueues.values()) {
451 lane.recalcTimeVariantAttributes();
461 for (
QVehicle veh : this.getWaitingList()) {
462 if (veh.getId().equals(vehicleId))
465 for (
QLaneI lane : this.laneQueues.values()) {
476 Collection<MobsimVehicle> ret =
new ArrayList<MobsimVehicle>(this.getWaitingList());
477 for (
QLaneI lane : this.laneQueues.values()) {
478 ret.addAll(lane.getAllVehicles());
487 double getSpaceCap() {
490 for (
QLaneI lane : this.laneQueues.values()) {
491 final double storageCapacity = lane.getStorageCapacity();
492 log.warn(
"storageCapacity=" + storageCapacity) ;
493 total += storageCapacity;
511 double getSimulatedFlowCapacity() {
527 QLaneI getOriginalLane() {
537 class VisDataImpl
implements VisData {
543 if (nodeOffset != 0.0) {
544 nodeOffset = nodeOffset + 2.0;
554 public Collection<AgentSnapshotInfo> addAgentSnapshotInfo(
555 final Collection<AgentSnapshotInfo> positions) {
560 if (visLink != null) {
563 ql.getId().toString());
564 ((QueueWithBuffer.VisDataImpl) ql.getVisData()).setVisInfo(
570 road.getVisData().addAgentSnapshotInfo(positions, now);
576 cnt2 = context.snapshotInfoBuilder.positionVehiclesFromTransitStop(positions,
getLink(),
577 getTransitQLink().getTransitVehicleStopQueue(), cnt2);
579 context.snapshotInfoBuilder.positionVehiclesFromWaitingList(positions,
582 context.snapshotInfoBuilder.positionAgentsInActivities(positions,
QLinkLanesImpl.this.getLink(),
QLaneI chooseNextLane(QLaneI queue, Id< Link > toLinkId)
QVehicle popFirstVehicle()
void moveBufferToNextLane(QLaneI qlane)
Map< String, VisLane > getLaneData()
QVehicle getVehicle(Id< Vehicle > vehicleId)
void addTransitSlightlyUpstreamOfStop(final QVehicle veh)
final Collection< MobsimVehicle > getAllNonParkedVehicles()
QVehicle getFirstVehicle()
LinkedHashMap< Id< Lane >, QLaneI > getQueueLanes()
final List< ModelLane > lanes
static< T > Id< T > create(final long key, final Class< T > type)
double getLoadIndicator()
void processEvent(final Event event)
final LinkedHashMap< Id< Lane >, QLaneI > laneQueues
QLaneI getAcceptingQLane()
boolean isNotOfferingVehicle()
final Map< Id< Lane >, Map< Id< Link >, List< QLaneI > > > nextQueueToLinkCache
List< QLaneI > getOfferingQLanes()
void addFromWait(final QVehicle veh)
List< ModelLane > getToLanes()
boolean isInsertingWaitingVehiclesBeforeDrivingVehicles()
boolean isAcceptingFromUpstream()
double getSimulatedFlowCapacityPerTimeStep()
boolean moveWaitToRoad(final double now)
boolean isWantingToArriveOnCurrentLink()
final FlowEfficiencyCalculator flowEfficiencyCalculator
boolean isNotOfferingVehicle()
QLinkLanesImpl(final Link link, final QNodeI toNodeQ, List< ModelLane > lanes, NetsimEngineContext context, NetsimInternalInterface netsimEngine, LinkSpeedCalculator linkSpeedCalculator, FlowEfficiencyCalculator flowEfficiencyCalculator, VehicleHandler vehicleHandler)
MobsimDriverAgent getDriver()
VisLinkWLanes createVisLinkLanes(CoordinateTransformation transform, VisLink link, double nodeOffsetMeter, List< ModelLane > lanes)
void recalcTimeVariantAttributes()
NetsimEngineContext context
void addFromUpstream(final QVehicle veh)
Id< Link > chooseNextLinkId()
boolean isAcceptingFromWait(QVehicle veh)
void recalculatePositions(VisLinkWLanes linkData, SnapshotLinkWidthCalculator linkWidthCalculator)
List< QLaneI > toNodeLaneQueues