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-2024 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://github.com/wjschakel">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.     /** Bus type. */
  40.     private final GtuType busType;

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

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

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

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

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

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

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

  170. }