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