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
24
25
26
27
28
29
30
31
32
33 public class CategoryTag implements Serializable
34 {
35
36
37 private static final long serialVersionUID = 20180525L;
38
39
40 private GTUType gtuType;
41
42
43 private Route route;
44
45
46 private Lane lane;
47
48
49 Double factor;
50
51
52 private Category category;
53
54
55
56
57
58
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
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
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
151 parser.categories.put(name, tag);
152 }
153
154
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
172
173
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 }