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 public abstract class LaneBasedObjectIterable<H extends Headway, L extends LaneBasedObject>
27 extends AbstractPerceptionIterable<H, L, Boolean>
28 {
29
30
31 private static final Length MARGIN = Length.instantiateSI(1e-9);
32
33
34 private final Class<L> clazz;
35
36
37
38
39
40
41
42
43
44
45
46
47 public LaneBasedObjectIterable(final LaneBasedGtu perceivingGtu, final Class<L> clazz, final LaneRecordInterface<?> root,
48 final Length initialPosition, final boolean downstream, final Length maxDistance,
49 final RelativePosition relativePosition, final Route route)
50 {
51 super(perceivingGtu, root, initialPosition, downstream, maxDistance, relativePosition, route);
52 this.clazz = clazz;
53 }
54
55
56 @SuppressWarnings("unchecked")
57 @Override
58 protected Entry getNext(final LaneRecordInterface<?> record, final Length position, final Boolean counter)
59 {
60 List<LaneBasedObject> list;
61 if (isDownstream())
62 {
63 if (!record.isDownstreamBranch())
64 {
65 return null;
66 }
67 Length pos = position.eq0() && counter == null ? MARGIN.neg() : position;
68 list = record.getLane().getObjectAhead(pos);
69 }
70 else
71 {
72 Length pos = position.eq(record.getLane().getLength()) && counter == null
73 ? record.getLane().getLength().plus(MARGIN) : position;
74 list = record.getLane().getObjectBehind(pos);
75 }
76 while (list != null)
77 {
78 Set<L> set = new LinkedHashSet<>();
79 Length pos = list.get(0).getLongitudinalPosition();
80 for (LaneBasedObject object : list)
81 {
82 if (this.clazz.isAssignableFrom(object.getClass()))
83 {
84
85 set.add((L) object);
86 }
87 }
88 if (!set.isEmpty())
89 {
90 if (set.size() == 1)
91 {
92 return new Entry(set.iterator().next(), true, pos);
93 }
94 return new Entry(set, true, pos);
95 }
96 if (isDownstream())
97 {
98 list = record.getLane().getObjectAhead(pos);
99 }
100 else
101 {
102 list = record.getLane().getObjectBehind(pos);
103 }
104 }
105 return null;
106 }
107
108
109 @Override
110 protected final Length getDistance(final L object, final LaneRecordInterface<?> record, final Length position)
111 {
112 return isDownstream() ? record.getDistanceToPosition(position).minus(getDx())
113 : record.getDistanceToPosition(position).neg().plus(getDx());
114 }
115
116
117 @Override
118 public String toString()
119 {
120 return "LaneBasedObjectIterable [class=" + this.clazz + ", downstream=" + isDownstream() + "]";
121 }
122
123 }