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