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