BusStop.java

  1. package org.opentrafficsim.road.network.lane.object;

  2. import java.util.LinkedHashSet;
  3. import java.util.List;
  4. import java.util.Set;

  5. import org.djunits.value.vdouble.scalar.Length;
  6. import org.djutils.immutablecollections.Immutable;
  7. import org.djutils.immutablecollections.ImmutableHashSet;
  8. import org.djutils.immutablecollections.ImmutableSet;
  9. import org.opentrafficsim.core.dsol.OtsSimulatorInterface;
  10. import org.opentrafficsim.core.gtu.GtuType;
  11. import org.opentrafficsim.core.network.NetworkException;
  12. import org.opentrafficsim.road.network.lane.Lane;
  13. import org.opentrafficsim.road.network.lane.conflict.BusStopConflictRule;
  14. import org.opentrafficsim.road.network.lane.conflict.Conflict;

  15. /**
  16.  * A bus stop is a location on a lane. The stop has a name, and a set of lines. At a single stop in reality, there may be
  17.  * different locations where busses stop for different lines. A {@code BusStop} pertains to only one such location. The bus stop
  18.  * in reality is represented by a shared name over a few {@code BusStop}'s, with different lines. As lines may also be set
  19.  * dynamically, the name and lines are insufficient to identify a specific {@code BusStop}. Hence there is a fixed unique id per
  20.  * {@code BusStop}.
  21.  * <p>
  22.  * Copyright (c) 2013-2023 Delft University of Technology, PO Box 5, 2600 AA, Delft, the Netherlands. All rights reserved. <br>
  23.  * BSD-style license. See <a href="https://opentrafficsim.org/docs/license.html">OpenTrafficSim License</a>.
  24.  * </p>
  25.  * @author <a href="https://github.com/averbraeck">Alexander Verbraeck</a>
  26.  * @author <a href="https://tudelft.nl/staff/p.knoppers-1">Peter Knoppers</a>
  27.  * @author <a href="https://dittlab.tudelft.nl">Wouter Schakel</a>
  28.  */
  29. public class BusStop extends AbstractLaneBasedObject
  30. {

  31.     /** */
  32.     private static final long serialVersionUID = 20170124L;

  33.     /** Line numbers. */
  34.     private final Set<String> lines = new LinkedHashSet<>();

  35.     /** Stop name. */
  36.     private final String name;

  37.     /** Stored conflicts downstream. */
  38.     private Set<Conflict> conflicts = null;
  39.    
  40.     /** Bus type. */
  41.     private final GtuType busType;

  42.     /**
  43.      * @param id String; id
  44.      * @param lane Lane; lane
  45.      * @param longitudinalPosition Length; position
  46.      * @param name String; name of stop
  47.      * @param simulator OtsSimulatorInterface; the simulator to schedule on
  48.      * @param busType GtuType; bus type.
  49.      * @throws NetworkException when the position on the lane is out of bounds
  50.      */
  51.     public BusStop(final String id, final Lane lane, final Length longitudinalPosition, final String name,
  52.             final OtsSimulatorInterface simulator, final GtuType busType) throws NetworkException
  53.     {
  54.         super(id, lane, longitudinalPosition, LaneBasedObject.makeGeometry(lane, longitudinalPosition), Length.ZERO);
  55.         this.name = name;
  56.         this.busType = busType;
  57.         init();
  58.     }

  59.     /**
  60.      * Sets the lines.
  61.      * @param lines Set&lt;String&gt;; lines that stop at this location
  62.      */
  63.     public final void setLines(final Set<String> lines)
  64.     {
  65.         this.lines.clear();
  66.         this.lines.addAll(lines);
  67.     }

  68.     /**
  69.      * Returns the lines set.
  70.      * @return whether the lines belongs to this stop
  71.      */
  72.     public final ImmutableSet<String> getLines()
  73.     {
  74.         return new ImmutableHashSet<>(this.lines, Immutable.COPY);
  75.     }

  76.     /**
  77.      * Returns the downstream conflicts of the bus stop. Search is only performed over links with BUS_STOP priority.
  78.      * @return downstream conflicts of the given conflict
  79.      */
  80.     public final Set<Conflict> getConflicts()
  81.     {
  82.         if (this.conflicts == null)
  83.         {
  84.             this.conflicts = new LinkedHashSet<>();
  85.             Lane lane = getLane();
  86.             // conflict forces only plus or minus as direction
  87.             Length position = getLongitudinalPosition();
  88.             while (lane != null)
  89.             {
  90.                 List<LaneBasedObject> objects = lane.getObjectAhead(position);
  91.                 while (objects != null)
  92.                 {
  93.                     for (LaneBasedObject object : objects)
  94.                     {
  95.                         if (object instanceof Conflict)
  96.                         {
  97.                             Conflict conflict = (Conflict) object;
  98.                             if (conflict.getConflictRule() instanceof BusStopConflictRule)
  99.                             {
  100.                                 this.conflicts.add(conflict);
  101.                             }
  102.                         }
  103.                     }
  104.                     objects = lane.getObjectAhead(objects.get(0).getLongitudinalPosition());
  105.                 }
  106.                 //
  107.                 Set<Lane> downstreamLanes = lane.nextLanes(this.busType);
  108.                 int numLanes = 0;
  109.                 for (Lane nextLane : downstreamLanes)
  110.                 {
  111.                     if (nextLane.getParentLink().getPriority().isBusStop())
  112.                     {
  113.                         numLanes++;
  114.                         lane = nextLane;
  115.                         position = Length.ZERO;
  116.                     }
  117.                 }
  118.                 if (numLanes != 1)
  119.                 {
  120.                     lane = null;
  121.                 }
  122.             }
  123.         }
  124.         return this.conflicts;
  125.     }

  126.     /** {@inheritDoc} */
  127.     @Override
  128.     public final int hashCode()
  129.     {
  130.         final int prime = 31;
  131.         int result = 1;
  132.         result = prime * result + this.getId().hashCode();
  133.         return result;
  134.     }

  135.     /** {@inheritDoc} */
  136.     @Override
  137.     public final boolean equals(final Object obj)
  138.     {
  139.         if (this == obj)
  140.         {
  141.             return true;
  142.         }
  143.         if (obj == null)
  144.         {
  145.             return false;
  146.         }
  147.         if (getClass() != obj.getClass())
  148.         {
  149.             return false;
  150.         }
  151.         BusStop other = (BusStop) obj;
  152.         if (!this.getId().equals(other.getId()))
  153.         {
  154.             return false;
  155.         }
  156.         return true;
  157.     }

  158.     /** {@inheritDoc} */
  159.     @Override
  160.     public final String toString()
  161.     {
  162.         String out = "BusStop [id=" + getId() + ", lines=";
  163.         String delim = "";
  164.         for (String line : this.lines)
  165.         {
  166.             out = out + delim + line;
  167.             delim = "/";
  168.         }
  169.         return out + "]";
  170.     }

  171. }