1 package org.opentrafficsim.road.network.factory.vissim;
2
3 import java.io.Serializable;
4 import java.util.LinkedHashMap;
5 import java.util.List;
6 import java.util.Map;
7
8 import org.djunits.value.vdouble.scalar.Length;
9 import org.djunits.value.vdouble.scalar.Speed;
10 import org.opentrafficsim.core.gtu.GTUType;
11 import org.opentrafficsim.core.network.NetworkException;
12 import org.opentrafficsim.core.network.factory.xml.units.LengthUnits;
13 import org.opentrafficsim.core.network.factory.xml.units.SpeedUnits;
14 import org.opentrafficsim.road.network.factory.vissim.units.LaneAttributes;
15 import org.opentrafficsim.road.network.lane.changing.LaneKeepingPolicy;
16 import org.opentrafficsim.road.network.lane.changing.OvertakingConditions;
17 import org.w3c.dom.NamedNodeMap;
18 import org.w3c.dom.Node;
19 import org.w3c.dom.NodeList;
20 import org.xml.sax.SAXException;
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108 class RoadLayoutTag implements Serializable
109 {
110
111 private static final long serialVersionUID = 20150723L;
112
113
114 @SuppressWarnings("checkstyle:visibilitymodifier")
115 String name = null;
116
117
118 @SuppressWarnings("checkstyle:visibilitymodifier")
119 RoadTypeTag roadTypeTag = null;
120
121
122 @SuppressWarnings("checkstyle:visibilitymodifier")
123 Map<GTUType, Speed> legalSpeedLimits = null;
124
125
126 @SuppressWarnings("checkstyle:visibilitymodifier")
127 LaneKeepingPolicy laneKeepingPolicy = null;
128
129
130 @SuppressWarnings("checkstyle:visibilitymodifier")
131 OvertakingConditions overtakingConditions = null;
132
133
134 @SuppressWarnings("checkstyle:visibilitymodifier")
135 Length defaultLaneWidth = null;
136
137
138 @SuppressWarnings("checkstyle:visibilitymodifier")
139 Map<String, CrossSectionElementTag> cseTags = new LinkedHashMap<>();
140
141
142
143
144
145
146
147
148
149
150 @SuppressWarnings("checkstyle:needbraces")
151 static void parseRoadTypes(final NodeList nodeList, final VissimNetworkLaneParser parser)
152 throws SAXException, NetworkException
153 {
154 for (Node node : XMLParser.getNodes(nodeList, "ROADLAYOUT"))
155 {
156 RoadLayoutTag roadLayoutTag = parseRoadType(node, parser);
157 parser.getRoadLayoutTags().put(roadLayoutTag.name, roadLayoutTag);
158 }
159 }
160
161
162
163
164
165
166
167
168
169 @SuppressWarnings("checkstyle:needbraces")
170 static RoadLayoutTag parseRoadType(final Node node, final VissimNetworkLaneParser parser)
171 throws SAXException, NetworkException
172 {
173 NamedNodeMap attributes = node.getAttributes();
174 RoadLayoutTag roadLayoutTag = new RoadLayoutTag();
175
176 Node name = attributes.getNamedItem("NAME");
177 if (name == null)
178 {
179 throw new SAXException("ROADLAYOUT: missing attribute NAME");
180 }
181 roadLayoutTag.name = name.getNodeValue().trim();
182 if (parser.getRoadLayoutTags().keySet().contains(roadLayoutTag.name))
183 {
184 throw new SAXException("ROADLAYOUT: NAME " + roadLayoutTag.name + " defined twice");
185 }
186
187 Node roadType = attributes.getNamedItem("ROADTYPE");
188 if (roadType == null)
189 {
190 throw new SAXException("ROADLAYOUT: missing attribute ROADTYPE");
191 }
192 if (!parser.getRoadTypeTags().containsKey(roadType.getNodeValue().trim()))
193 {
194 throw new SAXException("ROADLAYOUT: ROADTYPE " + roadType.getNodeValue().trim() + " not defined");
195 }
196 roadLayoutTag.roadTypeTag = parser.getRoadTypeTags().get(roadType.getNodeValue().trim());
197
198 Node width = attributes.getNamedItem("WIDTH");
199 if (width != null)
200 {
201 roadLayoutTag.defaultLaneWidth = LengthUnits.parseLength(width.getNodeValue());
202 }
203
204 Node lkp = attributes.getNamedItem("LANEKEEPING");
205 if (lkp != null)
206 {
207 roadLayoutTag.laneKeepingPolicy = LaneAttributes.parseLaneKeepingPolicy(lkp.getNodeValue().trim());
208 }
209
210 Node oc = attributes.getNamedItem("OVERTAKING");
211 if (oc != null)
212 {
213 roadLayoutTag.overtakingConditions = LaneAttributes.parseOvertakingConditions(oc.getNodeValue().trim(), parser);
214 }
215
216 List<Node> speedLimitList = XMLParser.getNodes(node.getChildNodes(), "SPEEDLIMIT");
217 if (speedLimitList.size() > 0)
218 {
219 roadLayoutTag.legalSpeedLimits = new LinkedHashMap<>();
220 }
221 for (Node speedLimitNode : speedLimitList)
222 {
223 NamedNodeMap speedLimitAttributes = speedLimitNode.getAttributes();
224
225 Node gtuTypeName = speedLimitAttributes.getNamedItem("GTUTYPE");
226 if (gtuTypeName == null)
227 {
228 throw new NetworkException("ROADLAYOUT.SPEEDLIMIT: No GTUTYPE defined");
229 }
230 if (!parser.getGtuTypes().containsKey(gtuTypeName.getNodeValue().trim()))
231 {
232 throw new NetworkException("ROADLAYOUT.SPEEDLIMIT: " + roadLayoutTag.name + " GTUTYPE "
233 + gtuTypeName.getNodeValue().trim() + " not defined");
234 }
235 GTUType gtuType = parser.getGtuTypes().get(gtuTypeName.getNodeValue().trim());
236
237 Node speedNode = speedLimitAttributes.getNamedItem("LEGALSPEEDLIMIT");
238 if (speedNode == null)
239 {
240 throw new NetworkException("ROADLAYOUT.SPEEDLIMIT: " + roadLayoutTag.name + " GTUTYPE " + gtuType.getId()
241 + ": LEGALSPEEDLIMIT not defined");
242 }
243 Speed speed = SpeedUnits.parseSpeed(speedNode.getNodeValue().trim());
244
245 roadLayoutTag.legalSpeedLimits.put(gtuType, speed);
246 }
247
248 int cseCount = 0;
249
250 for (Node laneNode : XMLParser.getNodes(node.getChildNodes(), "LANE"))
251 {
252 CrossSectionElementTag.parseLane(laneNode, parser, roadLayoutTag);
253 cseCount++;
254 }
255
256 for (Node ntlNode : XMLParser.getNodes(node.getChildNodes(), "NOTRAFFICLANE"))
257 {
258 CrossSectionElementTag.parseNoTrafficLane(ntlNode, parser, roadLayoutTag);
259 cseCount++;
260 }
261
262 for (Node stripeNode : XMLParser.getNodes(node.getChildNodes(), "STRIPE"))
263 {
264 CrossSectionElementTag.parseStripe(stripeNode, parser, roadLayoutTag);
265 cseCount++;
266 }
267
268 for (Node shoulderNode : XMLParser.getNodes(node.getChildNodes(), "SHOULDER"))
269 {
270 CrossSectionElementTag.parseShoulder(shoulderNode, parser, roadLayoutTag);
271 cseCount++;
272 }
273
274 if (cseCount == 0)
275 {
276 throw new NetworkException("ROADLAYOUT: No elements defined for road type " + roadLayoutTag.name);
277 }
278
279 return roadLayoutTag;
280 }
281
282
283 @Override
284 public String toString()
285 {
286 return "RoadLayoutTag [name=" + this.name + ", roadTypeTag=" + this.roadTypeTag + ", legalSpeedLimits="
287 + this.legalSpeedLimits + ", laneKeepingPolicy=" + this.laneKeepingPolicy + ", overtakingConditions="
288 + this.overtakingConditions + ", defaultLaneWidth=" + this.defaultLaneWidth + ", cseTags=" + this.cseTags + "]";
289 }
290
291 }