1 package org.opentrafficsim.editor.extensions.map;
2
3 import java.util.LinkedHashSet;
4 import java.util.Set;
5
6 import org.djunits.value.vdouble.scalar.Length;
7 import org.opentrafficsim.editor.XsdTreeNode;
8 import org.opentrafficsim.road.network.factory.xml.utils.StripeSynchronization.SynchronizableStripe;
9 import org.opentrafficsim.road.network.lane.Lane;
10 import org.opentrafficsim.road.network.lane.StripeData;
11 import org.opentrafficsim.road.network.lane.StripeData.StripePhaseSync;
12
13
14
15
16
17
18
19
20
21 public class SynchronizableMapStripe implements SynchronizableStripe<MapStripeData>
22 {
23
24 private final MapLinkData linkData;
25
26
27 private final MapStripeData data;
28
29
30 private final StripePhaseSync phaseSync;
31
32
33 private Double period = null;
34
35
36
37
38
39
40
41 public SynchronizableMapStripe(final MapLinkData linkData, final MapStripeData data, final StripePhaseSync phaseSync)
42 {
43 this.linkData = linkData;
44 this.data = data;
45 this.phaseSync = phaseSync;
46 }
47
48 @Override
49 public double getStartPhase()
50 {
51 if (getPeriod() < 0.0)
52 {
53 return 0.0;
54 }
55 return (this.data.getDashOffset().si % getPeriod()) / getPeriod();
56 }
57
58 @Override
59 public double getEndPhase()
60 {
61 if (getPeriod() < 0.0)
62 {
63 return 0.0;
64 }
65 return ((this.data.getCenterLine().getLength() + this.data.getDashOffset().si) % getPeriod()) / getPeriod();
66 }
67
68 @Override
69 public double getPeriod()
70 {
71 if (this.period == null)
72 {
73 this.period = StripeData.getPeriod(this.data.getElements());
74 }
75 return this.period;
76 }
77
78 @Override
79 public MapStripeData getObject()
80 {
81 return this.data;
82 }
83
84 @Override
85 public MapStripeData getUpstreamStripe()
86 {
87 XsdTreeNode fromNode = this.linkData.getNode().getCoupledKeyrefNodeAttribute("NodeStart");
88 if (fromNode == null)
89 {
90 return null;
91 }
92 for (XsdTreeNode networkChild : this.linkData.getNode().getParent().getChildren())
93 {
94 if (networkChild.getNodeName().equals("Link")
95 && fromNode.equals(networkChild.getCoupledKeyrefNodeAttribute("NodeEnd")))
96 {
97 MapLinkData otherLink = (MapLinkData) this.linkData.getMap().getData(networkChild);
98 if (otherLink == null)
99 {
100 return null;
101 }
102 for (MapStripeData otherStripe : otherLink.getStripeData())
103 {
104 if (otherStripe.getCenterLine().getLast().distance(this.data.getCenterLine().getFirst()) < Lane.MARGIN.si)
105 {
106 return otherStripe;
107 }
108 }
109 }
110 }
111 return null;
112 }
113
114 @Override
115 public MapStripeData getDownstreamStripe()
116 {
117 XsdTreeNode fromNode = this.linkData.getNode().getCoupledKeyrefNodeAttribute("NodeEnd");
118 if (fromNode == null)
119 {
120 return null;
121 }
122 for (XsdTreeNode networkChild : this.linkData.getNode().getParent().getChildren())
123 {
124 if (networkChild.getNodeName().equals("Link")
125 && fromNode.equals(networkChild.getCoupledKeyrefNodeAttribute("NodeStart")))
126 {
127 MapLinkData otherLink = (MapLinkData) this.linkData.getMap().getData(networkChild);
128 if (otherLink == null)
129 {
130 return null;
131 }
132 for (MapStripeData otherStripe : otherLink.getStripeData())
133 {
134 if (otherStripe.getCenterLine().getFirst().distance(this.data.getCenterLine().getLast()) < Lane.MARGIN.si)
135 {
136 return otherStripe;
137 }
138 }
139 }
140 }
141 return null;
142 }
143
144 @Override
145 public Set<MapStripeData> getCommonPhaseStripes()
146 {
147 Set<MapStripeData> out = new LinkedHashSet<>();
148 for (MapStripeData stripe : this.linkData.getStripeData())
149 {
150 SynchronizableMapStripe otherStripe = this.linkData.getMap().getSynchronizableStripes().get(stripe);
151 if (otherStripe != null && !otherStripe.equals(this))
152 {
153 boolean equalPhaseSync = getSynchronization().equals(otherStripe.getSynchronization());
154 boolean bothSyncUpOrDown = getSynchronization().isSync();
155 boolean samePeriod = getPeriod() == otherStripe.getPeriod();
156 boolean bothLatSyncToLink = this.data.getLateralSync().isLinkBased() && stripe.getLateralSync().isLinkBased();
157 if (equalPhaseSync && bothSyncUpOrDown && samePeriod && bothLatSyncToLink)
158 {
159 out.add(stripe);
160 }
161 }
162 }
163 return out;
164 }
165
166 @Override
167 public StripePhaseSync getSynchronization()
168 {
169 return this.phaseSync;
170 }
171
172 @Override
173 public void setStartPhase(final double phase)
174 {
175 this.data.setDashOffset(Length.instantiateSI(phase * getPeriod()));
176 }
177
178 @Override
179 public void setEndPhase(final double phase)
180 {
181 double len = getPeriod() - ((this.data.getCenterLine().getLength() - phase * getPeriod()) % getPeriod());
182 this.data.setDashOffset(Length.instantiateSI(len));
183 }
184
185 }