1 package org.opentrafficsim.road.network.factory.xml.old;
2
3 import java.io.Serializable;
4 import java.util.HashMap;
5 import java.util.List;
6 import java.util.Map;
7
8 import org.djunits.unit.LengthUnit;
9 import org.djunits.value.vdouble.scalar.Angle;
10 import org.djunits.value.vdouble.scalar.Length;
11 import org.opentrafficsim.core.network.NetworkException;
12 import org.opentrafficsim.core.network.factory.xml.units.AngleUnits;
13 import org.opentrafficsim.core.network.factory.xml.units.LengthUnits;
14 import org.opentrafficsim.road.network.lane.CrossSectionElement;
15 import org.opentrafficsim.road.network.lane.CrossSectionLink;
16 import org.opentrafficsim.road.network.lane.CrossSectionLink.Priority;
17 import org.opentrafficsim.road.network.lane.Lane;
18 import org.opentrafficsim.road.network.lane.changing.LaneKeepingPolicy;
19 import org.w3c.dom.NamedNodeMap;
20 import org.w3c.dom.Node;
21 import org.w3c.dom.NodeList;
22 import org.xml.sax.SAXException;
23
24
25
26
27
28
29
30
31
32
33 final class LinkTag implements Serializable
34 {
35
36 private static final long serialVersionUID = 20150723L;
37
38
39 @SuppressWarnings("checkstyle:visibilitymodifier")
40 String name = null;
41
42
43 @SuppressWarnings("checkstyle:visibilitymodifier")
44 NodeTag nodeStartTag = null;
45
46
47 @SuppressWarnings("checkstyle:visibilitymodifier")
48 NodeTag nodeEndTag = null;
49
50
51 @SuppressWarnings("checkstyle:visibilitymodifier")
52 RoadLayoutTag roadLayoutTag = null;
53
54
55 @SuppressWarnings("checkstyle:visibilitymodifier")
56 Length offsetStart = null;
57
58
59 @SuppressWarnings("checkstyle:visibilitymodifier")
60 Length offsetEnd = null;
61
62
63 @SuppressWarnings("checkstyle:visibilitymodifier")
64 Angle rotationStart = null;
65
66
67 @SuppressWarnings("checkstyle:visibilitymodifier")
68 Angle rotationEnd = null;
69
70
71 @SuppressWarnings("checkstyle:visibilitymodifier")
72 StraightTag straightTag = null;
73
74
75 @SuppressWarnings("checkstyle:visibilitymodifier")
76 PolyLineTag polyLineTag = null;
77
78
79 @SuppressWarnings("checkstyle:visibilitymodifier")
80 ArcTag arcTag = null;
81
82
83 @SuppressWarnings("checkstyle:visibilitymodifier")
84 BezierTag bezierTag = null;
85
86
87 @SuppressWarnings("checkstyle:visibilitymodifier")
88 Map<String, LaneOverrideTag> laneOverrideTags = new HashMap<>();
89
90
91 @SuppressWarnings("checkstyle:visibilitymodifier")
92 Map<String, GeneratorTag> generatorTags = new HashMap<>();
93
94
95 @SuppressWarnings("checkstyle:visibilitymodifier")
96 Map<String, ListGeneratorTag> listGeneratorTags = new HashMap<>();
97
98
99 @SuppressWarnings("checkstyle:visibilitymodifier")
100 Map<String, List<SensorTag>> sensorTags = new HashMap<>();
101
102
103 @SuppressWarnings("checkstyle:visibilitymodifier")
104 Map<String, List<TrafficLightTag>> trafficLightTags = new HashMap<>();
105
106
107 @SuppressWarnings("checkstyle:visibilitymodifier")
108 Map<String, FillTag> fillTags = new HashMap<>();
109
110
111 @SuppressWarnings("checkstyle:visibilitymodifier")
112 Map<String, SinkTag> sinkTags = new HashMap<>();
113
114
115 @SuppressWarnings("checkstyle:visibilitymodifier")
116 Map<String, Lane> lanes = new HashMap<>();
117
118
119 @SuppressWarnings("checkstyle:visibilitymodifier")
120 CrossSectionLink link = null;
121
122
123 @SuppressWarnings("checkstyle:visibilitymodifier")
124 LaneKeepingPolicy laneKeepingPolicy = null;
125
126
127 Priority priority = null;
128
129
130
131
132
133
134
135
136 @SuppressWarnings("checkstyle:needbraces")
137 static void parseLinks(final NodeList nodeList, final XmlNetworkLaneParserOld parser) throws SAXException, NetworkException
138 {
139 for (Node node : XMLParser.getNodes(nodeList, "LINK"))
140 {
141 NamedNodeMap attributes = node.getAttributes();
142 LinkTag linkTag = new LinkTag();
143
144 if (attributes.getNamedItem("NAME") == null)
145 throw new SAXException("LINK: missing attribute NAME");
146 linkTag.name = attributes.getNamedItem("NAME").getNodeValue().trim();
147 if (parser.connectorTags.keySet().contains(linkTag.name) || parser.linkTags.keySet().contains(linkTag.name))
148 throw new SAXException("LINK: NAME " + linkTag.name + " defined twice");
149
150 if (attributes.getNamedItem("ROADLAYOUT") == null)
151 throw new SAXException("LINK: missing attribute ROADLAYOUT for link " + linkTag.name);
152 String roadTypeName = attributes.getNamedItem("ROADLAYOUT").getNodeValue().trim();
153 if (!parser.roadLayoutTags.containsKey(roadTypeName))
154 throw new SAXException("LINK: ROADLAYOUT " + roadTypeName + " not found for link " + linkTag.name);
155 linkTag.roadLayoutTag = parser.roadLayoutTags.get(roadTypeName);
156
157 if (attributes.getNamedItem("NODESTART") == null)
158 throw new SAXException("LINK: missing attribute NODESTART for link " + linkTag.name);
159 String fromNodeStr = attributes.getNamedItem("NODESTART").getNodeValue().trim();
160 linkTag.nodeStartTag = parser.nodeTags.get(fromNodeStr);
161 if (linkTag.nodeStartTag == null)
162 throw new SAXException("LINK: NODESTART node " + fromNodeStr + " for link " + linkTag.name + " not defined");
163
164 if (attributes.getNamedItem("NODEEND") == null)
165 throw new SAXException("LINK: missing attribute NODEEND for link " + linkTag.name);
166 String toNodeStr = attributes.getNamedItem("NODEEND").getNodeValue().trim();
167 linkTag.nodeEndTag = parser.nodeTags.get(toNodeStr);
168 if (linkTag.nodeEndTag == null)
169 throw new SAXException("LINK: NODEEND node " + toNodeStr + " for link " + linkTag.name + " not defined");
170
171 if (attributes.getNamedItem("OFFSETSTART") != null)
172 linkTag.offsetStart = LengthUnits.parseLength(attributes.getNamedItem("OFFSETSTART").getNodeValue());
173
174 if (attributes.getNamedItem("OFFSETEND") != null)
175 linkTag.offsetEnd = LengthUnits.parseLength(attributes.getNamedItem("OFFSETEND").getNodeValue());
176
177 if (attributes.getNamedItem("ROTATIONSTART") != null)
178 linkTag.rotationStart = AngleUnits.parseAngle(attributes.getNamedItem("ROTATIONSTART").getNodeValue());
179
180 if (attributes.getNamedItem("ROTATIONEND") != null)
181 linkTag.rotationEnd = AngleUnits.parseAngle(attributes.getNamedItem("ROTATIONEND").getNodeValue());
182
183 if (attributes.getNamedItem("PRIORITY") != null)
184 linkTag.priority = LaneAttributes.parsePriority(attributes.getNamedItem("PRIORITY").getNodeValue());
185
186 Node lkp = attributes.getNamedItem("LANEKEEPING");
187 if (lkp != null)
188 linkTag.laneKeepingPolicy = LaneAttributes.parseLaneKeepingPolicy(lkp.getNodeValue().trim());
189 else if (linkTag.roadLayoutTag.laneKeepingPolicy != null)
190 linkTag.laneKeepingPolicy = linkTag.roadLayoutTag.laneKeepingPolicy;
191 else if (linkTag.roadLayoutTag.roadTypeTag.defaultLaneKeepingPolicy != null)
192 linkTag.laneKeepingPolicy = linkTag.roadLayoutTag.roadTypeTag.defaultLaneKeepingPolicy;
193 else
194 throw new SAXException("LINK: cannot determine LANEKEEPING for lane: " + linkTag.name);
195
196 List<Node> straightNodes = XMLParser.getNodes(node.getChildNodes(), "STRAIGHT");
197 List<Node> polyLineNodes = XMLParser.getNodes(node.getChildNodes(), "POLYLINE");
198 List<Node> arcNodes = XMLParser.getNodes(node.getChildNodes(), "ARC");
199 List<Node> bezierNodes = XMLParser.getNodes(node.getChildNodes(), "BEZIER");
200 if (straightNodes.size() > 1)
201 throw new SAXException("LINK: more than one STRAIGHT tag for link " + linkTag.name);
202 if (polyLineNodes.size() > 1)
203 throw new SAXException("LINK: more than one POLYLINE tag for link " + linkTag.name);
204 if (bezierNodes.size() > 1)
205 throw new SAXException("LINK: more than one BEZIER tag for link " + linkTag.name);
206 if (arcNodes.size() > 1)
207 throw new SAXException("LINK: more than one ARC tag for link " + linkTag.name);
208 if (straightNodes.size() + polyLineNodes.size() + arcNodes.size() + bezierNodes.size() > 1)
209 throw new SAXException("LINK: multiple tags (STRAIGHT, POLYLINE, ARC, BEZIER) for link " + linkTag.name);
210 if (straightNodes.size() + polyLineNodes.size() + arcNodes.size() + bezierNodes.size() == 0)
211 throw new SAXException("LINK: no tags (STRAIGHT, POLYLINE, ARC, BEZIER) for link " + linkTag.name);
212
213
214 if (straightNodes.size() == 1)
215 StraightTag.parseStraight(straightNodes.get(0), parser, linkTag);
216
217
218 if (polyLineNodes.size() == 1)
219 PolyLineTag.parsePolyLine(polyLineNodes.get(0), parser, linkTag);
220
221
222 if (arcNodes.size() == 1)
223 ArcTag.parseArc(arcNodes.get(0), parser, linkTag);
224
225
226 if (bezierNodes.size() == 1)
227 BezierTag.parseBezier(bezierNodes.get(0), parser, linkTag);
228
229 parser.linkTags.put(linkTag.name, linkTag);
230
231
232 for (Node loNode : XMLParser.getNodes(node.getChildNodes(), "LANEOVERRIDE"))
233 {
234 LaneOverrideTag.parseLaneOverride(loNode, parser, linkTag);
235 }
236
237
238 for (Node genNode : XMLParser.getNodes(node.getChildNodes(), "GENERATOR"))
239 {
240 GeneratorTag.parseGenerator(genNode, parser, linkTag);
241 }
242
243
244 for (Node listGenNode : XMLParser.getNodes(node.getChildNodes(), "LISTGENERATOR"))
245 {
246 ListGeneratorTag.parseListGenerator(listGenNode, parser, linkTag);
247 }
248
249
250 for (Node sensorNode : XMLParser.getNodes(node.getChildNodes(), "SENSOR"))
251 {
252 SensorTag.parseSensor(sensorNode, parser, linkTag);
253 }
254
255
256 for (Node trafficLightNode : XMLParser.getNodes(node.getChildNodes(), "TRAFFICLIGHT"))
257 {
258 TrafficLightTag.parseTrafficLight(trafficLightNode, parser, linkTag);
259 }
260
261
262 for (Node sinkNode : XMLParser.getNodes(node.getChildNodes(), "SINK"))
263 {
264 SinkTag.parseSink(sinkNode, parser, linkTag);
265 }
266
267
268 for (Node fillNode : XMLParser.getNodes(node.getChildNodes(), "FILL"))
269 {
270 FillTag.parseFill(fillNode, parser, linkTag);
271 }
272
273 }
274 }
275
276
277
278
279
280
281
282
283
284 static Length parseBeginEndPosition(final String posStr, final CrossSectionElement cse) throws NetworkException
285 {
286 if (posStr.trim().equals("BEGIN"))
287 {
288 return new Length(0.0, LengthUnit.METER);
289 }
290
291 double length = cse.getCenterLine().getLengthSI();
292
293 if (posStr.trim().equals("END"))
294 {
295 return new Length(length, LengthUnit.METER);
296 }
297
298 if (posStr.endsWith("%"))
299 {
300 String s = posStr.substring(0, posStr.length() - 1).trim();
301 try
302 {
303 double fraction = Double.parseDouble(s) / 100.0;
304 if (fraction < 0.0 || fraction > 1.0)
305 {
306 throw new NetworkException("parseBeginEndPosition: attribute POSITION with value " + posStr
307 + " invalid for lane " + cse.toString() + ", should be a percentage between 0 and 100%");
308 }
309 return new Length(length * fraction, LengthUnit.METER);
310 }
311 catch (NumberFormatException nfe)
312 {
313 throw new NetworkException("parseBeginEndPosition: attribute POSITION with value " + posStr
314 + " invalid for lane " + cse.toString() + ", should be a percentage between 0 and 100%", nfe);
315 }
316 }
317
318 if (posStr.trim().startsWith("END-"))
319 {
320 String s = posStr.substring(4).trim();
321 double offset = LengthUnits.parseLength(s).getSI();
322 if (offset > length)
323 {
324 throw new NetworkException("parseBeginEndPosition - attribute POSITION with value " + posStr
325 + " invalid for lane " + cse.toString() + ": provided negative offset greater than than link length");
326 }
327 return new Length(length - offset, LengthUnit.METER);
328 }
329
330 Length offset = LengthUnits.parseLength(posStr);
331 if (offset.getSI() > length)
332 {
333 throw new NetworkException("parseBeginEndPosition - attribute POSITION with value " + posStr + " invalid for lane "
334 + cse.toString() + ": provided offset greater than than link length");
335 }
336 return offset;
337 }
338
339
340 @Override
341 public String toString()
342 {
343 return "LinkTag [name=" + this.name + ", nodeStartTag=" + this.nodeStartTag + ", nodeEndTag=" + this.nodeEndTag + "]";
344 }
345
346 }