View Javadoc
1   package org.opentrafficsim.road.network.factory.xml;
2   
3   import java.io.Serializable;
4   import java.rmi.RemoteException;
5   import java.util.ArrayList;
6   import java.util.List;
7   
8   import javax.naming.NamingException;
9   
10  import org.djunits.value.vdouble.scalar.Angle;
11  import org.djunits.value.vdouble.scalar.Direction;
12  import org.opentrafficsim.core.geometry.OTSPoint3D;
13  import org.opentrafficsim.core.network.NetworkException;
14  import org.opentrafficsim.core.network.OTSNode;
15  import org.opentrafficsim.core.network.animation.NodeAnimation;
16  import org.opentrafficsim.core.network.factory.xml.units.AngleUnits;
17  import org.opentrafficsim.core.network.factory.xml.units.Coordinates;
18  import org.w3c.dom.NamedNodeMap;
19  import org.w3c.dom.Node;
20  import org.w3c.dom.NodeList;
21  import org.xml.sax.SAXException;
22  
23  import nl.tudelft.simulation.language.Throw;
24  
25  /**
26   * <p>
27   * Copyright (c) 2013-2018 Delft University of Technology, PO Box 5, 2600 AA, Delft, the Netherlands. All rights reserved. <br>
28   * BSD-style license. See <a href="http://opentrafficsim.org/docs/license.html">OpenTrafficSim License</a>.
29   * <p>
30   * $LastChangedDate: 2015-07-24 02:58:59 +0200 (Fri, 24 Jul 2015) $, @version $Revision: 1147 $, by $Author: averbraeck $,
31   * initial version Jul 23, 2015 <br>
32   * @author <a href="http://www.tbm.tudelft.nl/averbraeck">Alexander Verbraeck</a>
33   */
34  class NodeTag implements Serializable
35  {
36      /** */
37      private static final long serialVersionUID = 20150723L;
38  
39      /** Name. */
40      @SuppressWarnings("checkstyle:visibilitymodifier")
41      String name = null;
42  
43      /** Coordinate (null at first, can be calculated later when connected to a link. */
44      @SuppressWarnings("checkstyle:visibilitymodifier")
45      OTSPoint3D coordinate = null;
46  
47      /** Absolute angle of the node. 0 is "East", pi/2 = "North". */
48      @SuppressWarnings("checkstyle:visibilitymodifier")
49      Direction angle = null;
50  
51      /** TODO slope as an angle. */
52      @SuppressWarnings("checkstyle:visibilitymodifier")
53      Angle slope = null;
54  
55      /** The calculated Node, either through a coordinate or after calculation. */
56      @SuppressWarnings("checkstyle:visibilitymodifier")
57      OTSNode node = null;
58  
59      /**
60       * @param nodeList nodeList the top-level nodes of the XML-file
61       * @param parser the parser with the lists of information
62       * @throws SAXException when parsing of GTU tag fails
63       * @throws NetworkException when parsing of GTU tag fails
64       */
65      @SuppressWarnings("checkstyle:needbraces")
66      static void parseNodes(final NodeList nodeList, final XmlNetworkLaneParser parser) throws SAXException, NetworkException
67      {
68          for (Node node : XMLParser.getNodes(nodeList, "NODE"))
69          {
70              NamedNodeMap attributes = node.getAttributes();
71              NodeTag nodeTag = new NodeTag();
72  
73              Node name = attributes.getNamedItem("NAME");
74              if (name == null)
75                  throw new SAXException("NODE: missing attribute NAME");
76              nodeTag.name = name.getNodeValue().trim();
77              if (parser.nodeTags.keySet().contains(nodeTag.name))
78                  throw new SAXException("NODE: NAME " + nodeTag.name + " defined twice");
79  
80              if (attributes.getNamedItem("COORDINATE") != null)
81                  nodeTag.coordinate = Coordinates.parseCoordinate(attributes.getNamedItem("COORDINATE").getNodeValue());
82  
83              if (attributes.getNamedItem("ANGLE") != null)
84                  nodeTag.angle = AngleUnits.parseDirection(attributes.getNamedItem("ANGLE").getNodeValue());
85  
86              // TODO slope for the Node.
87  
88              parser.nodeTags.put(nodeTag.name, nodeTag);
89  
90              if (nodeTag.coordinate != null && nodeTag.angle != null)
91              {
92                  // only make a node if we know the coordinate and angle. Otherwise, wait till we can calculate it.
93                  try
94                  {
95                      makeOTSNode(nodeTag, parser);
96                  }
97                  catch (NamingException exception)
98                  {
99                      throw new NetworkException(exception);
100                 }
101             }
102         }
103     }
104 
105     /**
106      * Parse a list of Nodes, e.g. for a ROUTE.
107      * @param nodeNames the space separated String with the node names
108      * @param parser the parser with the lists of information
109      * @return a list of NodeTags
110      * @throws SAXException when parsing of the tag fails
111      * @throws NetworkException when parsing of the tag fails
112      */
113     static List<NodeTag> parseNodeList(final String nodeNames, final XmlNetworkLaneParser parser)
114             throws SAXException, NetworkException
115     {
116         List<NodeTag> nodeList = new ArrayList<>();
117         String[] ns = nodeNames.split("\\s");
118         for (String s : ns)
119         {
120             if (!parser.nodeTags.containsKey(s))
121             {
122                 throw new SAXException("Node " + s + " from node list [" + nodeNames + "] was not defined");
123             }
124             nodeList.add(parser.nodeTags.get(s));
125         }
126         return nodeList;
127 
128     }
129 
130     /**
131      * @param nodeTag the tag with the info for the node.
132      * @param parser the parser with the lists of information
133      * @return a constructed node
134      * @throws NetworkException when point cannot be instantiated
135      * @throws NamingException when animation context cannot be found.
136      */
137     static OTSNode makeOTSNode(final NodeTag nodeTag, final XmlNetworkLaneParser parser)
138             throws NetworkException, NamingException
139     {
140         Throw.whenNull(nodeTag.angle, "NodeTag: " + nodeTag.name + " angle == null");
141         String id = nodeTag.name;
142         Direction angle = nodeTag.angle;
143         Angle slope = nodeTag.slope == null ? Angle.ZERO : nodeTag.slope;
144         OTSNode node = new OTSNode(parser.network, id, nodeTag.coordinate, angle, slope);
145         nodeTag.node = node;
146 
147         try
148         {
149             new NodeAnimation(nodeTag.node, parser.simulator);
150         }
151         catch (RemoteException exception)
152         {
153             exception.printStackTrace();
154         }
155 
156         return node;
157     }
158 
159     /** {@inheritDoc} */
160     @Override
161     public String toString()
162     {
163         return "NodeTag [name=" + this.name + ", coordinate=" + this.coordinate + ", node=" + this.node + "]";
164     }
165 
166 }