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