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