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.gtu.GtuType;
  10. import org.opentrafficsim.core.network.NetworkException;
  11. import org.opentrafficsim.road.network.lane.Lane;
  12. import org.opentrafficsim.road.network.lane.conflict.BusStopConflictRule;
  13. import org.opentrafficsim.road.network.lane.conflict.Conflict;

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

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

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

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

  36.     /** Stored conflicts downstream. */
  37.     private Set<Conflict> conflicts = null;

  38.     /** Bus type. */
  39.     private final GtuType busType;

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

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

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

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

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

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

  153.     @Override
  154.     public final String toString()
  155.     {
  156.         String out = "BusStop [id=" + getId() + ", lines=";
  157.         String delim = "";
  158.         for (String line : this.lines)
  159.         {
  160.             out = out + delim + line;
  161.             delim = "/";
  162.         }
  163.         return out + "]";
  164.     }

  165. }