View Javadoc
1   package org.opentrafficsim.road.network.factory.xml.old;
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.lane.changing.LaneKeepingPolicy;
15  import org.opentrafficsim.road.network.lane.changing.OvertakingConditions;
16  import org.w3c.dom.NamedNodeMap;
17  import org.w3c.dom.Node;
18  import org.w3c.dom.NodeList;
19  import org.xml.sax.SAXException;
20  
21  /**
22   * ROADTYPE Tag.
23   * 
24   * <pre>
25   * {@code
26    <xsd:element name="LANETYPE">
27      <xsd:complexType>
28        <xsd:sequence>
29          <xsd:element name="SPEEDLIMIT" minOccurs="1" maxOccurs="unbounded">
30            <xsd:complexType>
31              <xsd:attribute name="GTUTYPE" type="xsd:string" use="required" />
32              <xsd:attribute name="LEGALSPEEDLIMIT" type="SPEEDTYPE" use="optional" />
33            </xsd:complexType>
34          </xsd:element>
35        </xsd:sequence>
36        <xsd:attribute name="NAME" type="xsd:string" use="required" />
37        <xsd:attribute name="DEFAULTLANEWIDTH" type="LENGTHTYPE" use="optional" />
38        <xsd:attribute name="DEFAULTLANEKEEPING" type="LANEKEEPINGTYPE" use="optional" />
39        <xsd:attribute ref="xml:base" />
40      </xsd:complexType>
41    </xsd:element>
42   * }
43   * </pre>
44   * <p>
45   * Copyright (c) 2013-2019 Delft University of Technology, PO Box 5, 2600 AA, Delft, the Netherlands. All rights reserved. <br>
46   * BSD-style license. See <a href="http://opentrafficsim.org/docs/license.html">OpenTrafficSim License</a>.
47   * <p>
48   * $LastChangedDate: 2015-07-24 02:58:59 +0200 (Fri, 24 Jul 2015) $, @version $Revision: 1147 $, by $Author: averbraeck $,
49   * initial version Jul 23, 2015 <br>
50   * @author <a href="http://www.tbm.tudelft.nl/averbraeck">Alexander Verbraeck</a>
51   */
52  class RoadTypeTag implements Serializable
53  {
54      /** */
55      private static final long serialVersionUID = 20150723L;
56  
57      /** Name. */
58      @SuppressWarnings("checkstyle:visibilitymodifier")
59      String name = null;
60  
61      /** Speed limits. */
62      @SuppressWarnings("checkstyle:visibilitymodifier")
63      Map<GTUType, Speed> legalSpeedLimits = new LinkedHashMap<>();
64  
65      /** Default lane width. */
66      @SuppressWarnings("checkstyle:visibilitymodifier")
67      Length defaultLaneWidth = null;
68  
69      /** The lane keeping policy, i.e., keep left, keep right or keep lane. */
70      @SuppressWarnings("checkstyle:visibilitymodifier")
71      LaneKeepingPolicy defaultLaneKeepingPolicy = null;
72  
73      /** The overtaking conditions for the lanes of this road type. */
74      @SuppressWarnings("checkstyle:visibilitymodifier")
75      OvertakingConditions defaultOvertakingConditions = null;
76  
77      /**
78       * Parse the ROADTYPE tags. Delegates to a separate method because the RoadTypeTag can also occur inside a LINK tag. In the
79       * latter case, it should not be stored in the central map. When this parseRoadTypes method is called, the tags <b>are</b>
80       * stored in the central map in the parser class.
81       * @param nodeList NodeList; nodeList the top-level nodes of the XML-file
82       * @param parser XmlNetworkLaneParserOld; the parser with the lists of information
83       * @throws SAXException when parsing of the tag fails
84       * @throws NetworkException when parsing of the tag fails
85       */
86      @SuppressWarnings("checkstyle:needbraces")
87      static void parseRoadTypes(final NodeList nodeList, final XmlNetworkLaneParserOld parser)
88              throws SAXException, NetworkException
89      {
90          for (Node node : XMLParser.getNodes(nodeList, "ROADTYPE"))
91          {
92              RoadTypeTag roadTypeTag = parseRoadType(node, parser);
93              parser.roadTypeTags.put(roadTypeTag.name, roadTypeTag);
94          }
95      }
96  
97      /**
98       * Parse the ROADTYPE tags.
99       * @param node Node; the ROADTYPE nodes of the XML-file
100      * @param parser XmlNetworkLaneParserOld; the parser with the lists of information
101      * @return the parsed RoadTypeTag
102      * @throws SAXException when parsing of the tag fails
103      * @throws NetworkException when parsing of the tag fails
104      */
105     @SuppressWarnings("checkstyle:needbraces")
106     static RoadTypeTag parseRoadType(final Node node, final XmlNetworkLaneParserOld parser)
107             throws SAXException, NetworkException
108     {
109         NamedNodeMap attributes = node.getAttributes();
110         RoadTypeTag roadTypeTag = new RoadTypeTag();
111 
112         Node name = attributes.getNamedItem("NAME");
113         if (name == null)
114             throw new SAXException("ROADTYPE: missing attribute NAME");
115         roadTypeTag.name = name.getNodeValue().trim();
116         if (parser.roadTypeTags.keySet().contains(roadTypeTag.name))
117             throw new SAXException("ROADTYPE: NAME " + roadTypeTag.name + " defined twice");
118 
119         Node width = attributes.getNamedItem("DEFAULTLANEWIDTH");
120         if (width != null)
121             roadTypeTag.defaultLaneWidth = LengthUnits.parseLength(width.getNodeValue());
122 
123         Node lkp = attributes.getNamedItem("DEFAULTLANEKEEPING");
124         if (lkp != null)
125             roadTypeTag.defaultLaneKeepingPolicy = LaneAttributes.parseLaneKeepingPolicy(lkp.getNodeValue().trim());
126 
127         Node oc = attributes.getNamedItem("DEFAULTOVERTAKING");
128         if (oc != null)
129             roadTypeTag.defaultOvertakingConditions =
130                     LaneAttributes.parseOvertakingConditions(oc.getNodeValue().trim(), parser);
131 
132         List<Node> speedLimitList = XMLParser.getNodes(node.getChildNodes(), "SPEEDLIMIT");
133         if (speedLimitList.size() == 0)
134             throw new SAXException("ROADTYPE: missing tag SPEEDLIMIT");
135         for (Node speedLimitNode : speedLimitList)
136         {
137             NamedNodeMap speedLimitAttributes = speedLimitNode.getAttributes();
138 
139             Node gtuTypeName = speedLimitAttributes.getNamedItem("GTUTYPE");
140             if (gtuTypeName == null)
141                 throw new NetworkException("ROADTYPE: No GTUTYPE defined");
142             if (!parser.gtuTypes.containsKey(gtuTypeName.getNodeValue().trim()))
143                 throw new NetworkException(
144                         "ROADTYPE: " + roadTypeTag.name + " GTUTYPE " + gtuTypeName.getNodeValue().trim() + " not defined");
145             GTUType gtuType = parser.gtuTypes.get(gtuTypeName.getNodeValue().trim());
146 
147             Node speedNode = speedLimitAttributes.getNamedItem("LEGALSPEEDLIMIT");
148             if (speedNode == null)
149                 throw new NetworkException(
150                         "ROADTYPE: " + roadTypeTag.name + " GTUTYPE " + gtuType.getId() + ": LEGALSPEEDLIMIT not defined");
151             Speed speed = SpeedUnits.parseSpeed(speedNode.getNodeValue().trim());
152 
153             roadTypeTag.legalSpeedLimits.put(gtuType, speed);
154         }
155 
156         return roadTypeTag;
157     }
158 
159     /** {@inheritDoc} */
160     @Override
161     public String toString()
162     {
163         return "RoadTypeTag [name=" + this.name + ", legalSpeedLimits=" + this.legalSpeedLimits + ", defaultLaneWidth="
164                 + this.defaultLaneWidth + ", defaultLaneKeepingPolicy=" + this.defaultLaneKeepingPolicy
165                 + ", defaultOvertakingConditions=" + this.defaultOvertakingConditions + "]";
166     }
167 
168 }