View Javadoc
1   package org.opentrafficsim.road.network.factory.xml.demand;
2   
3   import java.io.Serializable;
4   import java.util.ArrayList;
5   import java.util.List;
6   
7   import org.opentrafficsim.core.gtu.GTUType;
8   import org.opentrafficsim.core.network.Link;
9   import org.opentrafficsim.core.network.route.Route;
10  import org.opentrafficsim.road.gtu.strategical.od.Categorization;
11  import org.opentrafficsim.road.gtu.strategical.od.Category;
12  import org.opentrafficsim.road.network.factory.xml.XMLParser;
13  import org.opentrafficsim.road.network.factory.xml.XmlParserException;
14  import org.opentrafficsim.road.network.lane.CrossSectionLink;
15  import org.opentrafficsim.road.network.lane.Lane;
16  import org.w3c.dom.NamedNodeMap;
17  import org.w3c.dom.Node;
18  import org.w3c.dom.NodeList;
19  
20  import nl.tudelft.simulation.language.Throw;
21  
22  /**
23   * Category.
24   * <p>
25   * Copyright (c) 2013-2018 Delft University of Technology, PO Box 5, 2600 AA, Delft, the Netherlands. All rights reserved. <br>
26   * BSD-style license. See <a href="http://opentrafficsim.org/node/13">OpenTrafficSim License</a>.
27   * <p>
28   * @version $Revision$, $LastChangedDate$, by $Author$, initial version 25 mei 2018 <br>
29   * @author <a href="http://www.tbm.tudelft.nl/averbraeck">Alexander Verbraeck</a>
30   * @author <a href="http://www.tudelft.nl/pknoppers">Peter Knoppers</a>
31   * @author <a href="http://www.transport.citg.tudelft.nl">Wouter Schakel</a>
32   */
33  public class CategoryTag implements Serializable
34  {
35  
36      /** */
37      private static final long serialVersionUID = 20180525L;
38  
39      /** GTU type. */
40      private GTUType gtuType;
41  
42      /** Route. */
43      private Route route;
44  
45      /** Lane. */
46      private Lane lane;
47  
48      /** FACTOR. */
49      Double factor;
50  
51      /** Created category. */
52      private Category category;
53  
54      /**
55       * Parse category nodes.
56       * @param nodeList NodeList; node list
57       * @param parser XmlOdParser; parser
58       * @throws XmlParserException if category cannot be parsed
59       */
60      static void parse(final NodeList nodeList, final XmlOdParser parser) throws XmlParserException
61      {
62          List<Class<?>> categorizationClasses = new ArrayList<>();
63          for (Node node : XMLParser.getNodesSorted(nodeList, "CATEGORY", "GTUTYPE", "ROUTE", "LANE"))
64          {
65              NamedNodeMap attributes = node.getAttributes();
66              CategoryTag tag = new CategoryTag();
67  
68              Node nameNode = attributes.getNamedItem("NAME");
69              Throw.when(nameNode == null, XmlParserException.class, "Missing NAME attribute in CATEGORY tag.");
70              String name = nameNode.getNodeValue().trim();
71  
72              Node gtuTypeNode = attributes.getNamedItem("GTUTYPE");
73              Throw.when(categorizationClasses.contains(GTUType.class) && gtuTypeNode == null, XmlParserException.class,
74                      "Missing GTUTYPE attribute in CATEGORY %s.", name);
75              Throw.when(
76                      !categorizationClasses.isEmpty() && !categorizationClasses.contains(GTUType.class) && gtuTypeNode != null,
77                      XmlParserException.class, "Missing GTUTYPE attribute in a CATEGORY prior to %s.", name);
78              if (gtuTypeNode != null)
79              {
80                  tag.gtuType = parser.getGTUType(gtuTypeNode.getNodeValue().trim());
81              }
82  
83              Node routeNode = attributes.getNamedItem("ROUTE");
84              Throw.when(categorizationClasses.contains(Route.class) && routeNode == null, XmlParserException.class,
85                      "Missing ROUTE attribute in CATEGORY %s.", name);
86              Throw.when(!categorizationClasses.isEmpty() && !categorizationClasses.contains(Route.class) && routeNode != null,
87                      XmlParserException.class, "Missing ROUTE attribute in a CATEGORY prior to %s.", name);
88              if (routeNode != null)
89              {
90                  String routeId = routeNode.getNodeValue().trim();
91                  tag.route = parser.network.getRoute(routeId);
92                  Throw.when(tag.route == null, XmlParserException.class, "Route %s is not available.", routeId);
93              }
94  
95              Node laneNode = attributes.getNamedItem("LANE");
96              Throw.when(categorizationClasses.contains(Lane.class) && laneNode == null, XmlParserException.class,
97                      "Missing LANE attribute in CATEGORY %s.", name);
98              Throw.when(!categorizationClasses.isEmpty() && !categorizationClasses.contains(Lane.class) && laneNode != null,
99                      XmlParserException.class, "Missing LANE attribute in a CATEGORY prior to %s.", name);
100             if (laneNode != null)
101             {
102                 String laneId = laneNode.getNodeValue().trim();
103                 // find lane
104                 for (Link link : parser.network.getLinkMap().values())
105                 {
106                     if (link instanceof CrossSectionLink)
107                     {
108                         for (Lane lane : ((CrossSectionLink) link).getLanes())
109                         {
110                             if (lane.getFullId().equals(laneId))
111                             {
112                                 tag.lane = lane;
113                                 break;
114                             }
115                         }
116                     }
117                     if (tag.lane != null)
118                     {
119                         break;
120                     }
121                 }
122                 Throw.when(tag.lane == null, XmlParserException.class,
123                         "Lane %s is not available. Make sure to use the full id 'LinkId.LaneId'.", laneId);
124             }
125 
126             Node factorNode = attributes.getNamedItem("FACTOR");
127             if (factorNode != null)
128             {
129                 tag.factor = DemandTag.parseFactor(factorNode.getNodeValue().trim());
130             }
131 
132             // define categorization classes
133             if (categorizationClasses.isEmpty())
134             {
135                 if (tag.gtuType != null)
136                 {
137                     categorizationClasses.add(GTUType.class);
138                 }
139                 if (tag.route != null)
140                 {
141                     categorizationClasses.add(Route.class);
142                 }
143                 if (tag.lane != null)
144                 {
145                     categorizationClasses.add(Lane.class);
146                 }
147                 Throw.when(categorizationClasses.isEmpty(), XmlParserException.class, "Category contains no objects.");
148             }
149 
150             // store category tag
151             parser.categories.put(name, tag);
152         }
153 
154         // create categorization
155         if (categorizationClasses.isEmpty())
156         {
157             parser.categorization = Categorization.UNCATEGORIZED;
158         }
159         else if (categorizationClasses.size() > 1)
160         {
161             parser.categorization = new Categorization("od categorization", categorizationClasses.get(0), categorizationClasses
162                     .subList(1, categorizationClasses.size()).toArray(new Class<?>[categorizationClasses.size() - 1]));
163         }
164         else
165         {
166             parser.categorization = new Categorization("od categorization", categorizationClasses.get(0));
167         }
168     }
169 
170     /**
171      * Returns the category.
172      * @param categorization Categorization; categorization
173      * @return Category; category
174      */
175     public Category getCategory(final Categorization categorization)
176     {
177         if (this.category == null)
178         {
179             int n = 0;
180             if (this.gtuType != null)
181             {
182                 n++;
183             }
184             if (this.route != null)
185             {
186                 n++;
187             }
188             if (this.lane != null)
189             {
190                 n++;
191             }
192             Object first = null;
193             Object[] objects = new Object[n - 1];
194             int i = 0;
195             if (this.gtuType != null)
196             {
197                 first = this.gtuType;
198             }
199             if (this.route != null)
200             {
201                 if (first == null)
202                 {
203                     first = this.gtuType;
204                 }
205                 else
206                 {
207                     objects[i] = this.route;
208                     i++;
209                 }
210             }
211             if (this.lane != null)
212             {
213                 if (first == null)
214                 {
215                     first = this.gtuType;
216                 }
217                 else
218                 {
219                     objects[i] = this.lane;
220                 }
221             }
222             this.category = new Category(categorization, first, objects);
223         }
224         return this.category;
225     }
226 
227 }