1   package org.opentrafficsim.road.gtu.lane.perception;
2   
3   import java.util.LinkedHashSet;
4   import java.util.List;
5   import java.util.Set;
6   
7   import org.djunits.value.vdouble.scalar.Length;
8   import org.opentrafficsim.core.gtu.RelativePosition;
9   import org.opentrafficsim.core.network.route.Route;
10  import org.opentrafficsim.road.gtu.lane.LaneBasedGTU;
11  import org.opentrafficsim.road.gtu.lane.perception.headway.Headway;
12  import org.opentrafficsim.road.network.lane.object.LaneBasedObject;
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  
23  
24  
25  
26  
27  public abstract class LaneBasedObjectIterable<H extends Headway, L extends LaneBasedObject>
28          extends AbstractPerceptionIterable<H, L, Void>
29  {
30  
31      
32      private final Class<L> clazz;
33  
34      
35  
36  
37  
38  
39  
40  
41  
42  
43  
44      public LaneBasedObjectIterable(final LaneBasedGTU perceivingGtu, final Class<L> clazz, final LaneRecord<?> root,
45              final Length initialPosition, final Length maxDistance, final RelativePosition relativePosition, final Route route)
46      {
47          super(perceivingGtu, root, initialPosition, true, maxDistance, relativePosition, route);
48          this.clazz = clazz;
49      }
50  
51      
52      @SuppressWarnings("unchecked")
53      @Override
54      protected Entry getNext(final LaneRecord<?> record, final Length position, final Void counter)
55      {
56          if (!record.isDownstreamBranch())
57          {
58              return null;
59          }
60          List<LaneBasedObject> list = record.getLane().getObjectAhead(position, record.getDirection());
61          while (list != null)
62          {
63              Set<L> set = new LinkedHashSet<>();
64              Length pos = list.get(0).getLongitudinalPosition();
65              for (LaneBasedObject object : list)
66              {
67                  if (this.clazz.isAssignableFrom(object.getClass()))
68                  {
69                      
70                      set.add((L) object);
71                  }
72              }
73              if (!set.isEmpty())
74              {
75                  if (set.size() == 1)
76                  {
77                      return new Entry(set.iterator().next(), null, pos);
78                  }
79                  return new Entry(set, null, pos);
80              }
81              list = record.getLane().getObjectAhead(pos, record.getDirection());
82          }
83          return null;
84      }
85  
86      
87      @Override
88      protected final Length getDistance(final L object, final LaneRecord<?> record, final Length position)
89      {
90          return record.getDistanceToPosition(position).minus(getDx());
91      }
92  
93      
94      @Override
95      public String toString()
96      {
97          return "LaneBasedObjectIterable [class=" + this.clazz + "]";
98      }
99  
100 }