Line data Source code
1 : /****************************************************************************/
2 : // Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo
3 : // Copyright (C) 2001-2025 German Aerospace Center (DLR) and others.
4 : // This program and the accompanying materials are made available under the
5 : // terms of the Eclipse Public License 2.0 which is available at
6 : // https://www.eclipse.org/legal/epl-2.0/
7 : // This Source Code may also be made available under the following Secondary
8 : // Licenses when the conditions for such availability set forth in the Eclipse
9 : // Public License 2.0 are satisfied: GNU General Public License, version 2
10 : // or later which is available at
11 : // https://www.gnu.org/licenses/old-licenses/gpl-2.0-standalone.html
12 : // SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later
13 : /****************************************************************************/
14 : /// @file DataHandler.cpp
15 : /// @author Jakob Erdmann
16 : /// @date Jun 2021
17 : ///
18 : // The XML-Handler for data elements loading
19 : /****************************************************************************/
20 : #include <config.h>
21 :
22 : #include <utils/common/MsgHandler.h>
23 : #include <utils/common/StringUtils.h>
24 : #include <utils/xml/XMLSubSys.h>
25 :
26 : #include "DataHandler.h"
27 :
28 :
29 : // ===========================================================================
30 : // method definitions
31 : // ===========================================================================
32 :
33 0 : DataHandler::DataHandler(const std::string& filename) :
34 : CommonHandler(filename),
35 0 : SUMOSAXHandler(filename) {
36 0 : }
37 :
38 :
39 0 : DataHandler::~DataHandler() {}
40 :
41 :
42 : bool
43 0 : DataHandler::parse() {
44 : // run parser and return result
45 0 : return XMLSubSys::runParser(*this, getFileName());
46 : }
47 :
48 :
49 : void
50 0 : DataHandler::parseSumoBaseObject(CommonXMLStructure::SumoBaseObject* obj) {
51 : // check if loading was aborted
52 0 : if (!myAbortLoading) {
53 : // switch tag
54 0 : switch (obj->getTag()) {
55 : // Stopping Places
56 0 : case SUMO_TAG_INTERVAL:
57 0 : if (buildDataInterval(obj,
58 : obj->getStringAttribute(SUMO_ATTR_ID),
59 : obj->getDoubleAttribute(SUMO_ATTR_BEGIN),
60 : obj->getDoubleAttribute(SUMO_ATTR_END))) {
61 0 : obj->markAsCreated();
62 : }
63 : break;
64 0 : case SUMO_TAG_EDGE:
65 0 : if (buildEdgeData(obj,
66 : obj->getStringAttribute(SUMO_ATTR_ID),
67 0 : obj->getParameters())) {
68 0 : obj->markAsCreated();
69 : }
70 : break;
71 0 : case SUMO_TAG_EDGEREL:
72 0 : if (buildEdgeRelationData(obj,
73 : obj->getStringAttribute(SUMO_ATTR_FROM),
74 : obj->getStringAttribute(SUMO_ATTR_TO),
75 0 : obj->getParameters())) {
76 0 : obj->markAsCreated();
77 : }
78 : break;
79 0 : case SUMO_TAG_TAZREL:
80 0 : if (buildTAZRelationData(obj,
81 : obj->getStringAttribute(SUMO_ATTR_FROM),
82 : obj->getStringAttribute(SUMO_ATTR_TO),
83 0 : obj->getParameters())) {
84 0 : obj->markAsCreated();
85 : }
86 : break;
87 : default:
88 : break;
89 : }
90 : // now iterate over childrens
91 0 : for (const auto& child : obj->getSumoBaseObjectChildren()) {
92 : // call this function recursively
93 0 : parseSumoBaseObject(child);
94 : }
95 : }
96 0 : }
97 :
98 :
99 : void
100 0 : DataHandler::myStartElement(int element, const SUMOSAXAttributes& attrs) {
101 : // obtain tag
102 : const SumoXMLTag tag = (element == 0) ? SUMO_TAG_ROOTFILE : static_cast<SumoXMLTag>(element);
103 : // open SUMOBaseOBject
104 0 : myCommonXMLStructure.openSUMOBaseOBject();
105 : // check tag
106 : try {
107 0 : switch (tag) {
108 : // interval
109 0 : case SUMO_TAG_INTERVAL:
110 0 : parseInterval(attrs);
111 : break;
112 : // datas
113 0 : case SUMO_TAG_EDGE:
114 0 : parseEdgeData(attrs);
115 : break;
116 0 : case SUMO_TAG_EDGEREL:
117 0 : parseEdgeRelationData(attrs);
118 : break;
119 0 : case SUMO_TAG_TAZREL:
120 0 : parseTAZRelationData(attrs);
121 : break;
122 0 : case SUMO_TAG_PARAM:
123 0 : WRITE_WARNING(TL("Data elements cannot load attributes as params"));
124 0 : myCommonXMLStructure.abortSUMOBaseOBject();
125 : break;
126 0 : default:
127 : // tag cannot be parsed in routeHandler
128 0 : myCommonXMLStructure.abortSUMOBaseOBject();
129 : break;
130 : }
131 0 : } catch (InvalidArgument& e) {
132 0 : writeError(e.what());
133 0 : }
134 0 : }
135 :
136 :
137 : void
138 0 : DataHandler::myEndElement(int element) {
139 : // obtain tag
140 : const SumoXMLTag tag = static_cast<SumoXMLTag>(element);
141 : // get last inserted object
142 0 : CommonXMLStructure::SumoBaseObject* obj = myCommonXMLStructure.getCurrentSumoBaseObject();
143 : // close SUMOBaseOBject
144 0 : myCommonXMLStructure.closeSUMOBaseOBject();
145 0 : if (obj) {
146 : // check tag
147 0 : switch (tag) {
148 : // only interval
149 0 : case SUMO_TAG_INTERVAL:
150 : // parse object and all their childrens
151 0 : parseSumoBaseObject(obj);
152 : // delete object (and all of their childrens)
153 0 : delete obj;
154 : break;
155 : default:
156 : break;
157 : }
158 : }
159 0 : }
160 :
161 :
162 : void
163 0 : DataHandler::parseInterval(const SUMOSAXAttributes& attrs) {
164 : // declare Ok Flag
165 0 : bool parsedOk = true;
166 : // needed attributes
167 0 : const std::string id = attrs.get<std::string>(SUMO_ATTR_ID, "", parsedOk);
168 0 : const double begin = STEPS2TIME(attrs.getSUMOTimeReporting(SUMO_ATTR_BEGIN, "", parsedOk));
169 0 : const double end = STEPS2TIME(attrs.getSUMOTimeReporting(SUMO_ATTR_END, "", parsedOk));
170 : // continue if flag is ok
171 0 : if (parsedOk) {
172 : // set tag
173 0 : myCommonXMLStructure.getCurrentSumoBaseObject()->setTag(SUMO_TAG_INTERVAL);
174 : // add all attributes
175 0 : myCommonXMLStructure.getCurrentSumoBaseObject()->addStringAttribute(SUMO_ATTR_ID, id);
176 0 : myCommonXMLStructure.getCurrentSumoBaseObject()->addDoubleAttribute(SUMO_ATTR_BEGIN, begin);
177 0 : myCommonXMLStructure.getCurrentSumoBaseObject()->addDoubleAttribute(SUMO_ATTR_END, end);
178 : } else {
179 0 : myCommonXMLStructure.getCurrentSumoBaseObject()->setTag(SUMO_TAG_ERROR);
180 : }
181 0 : }
182 :
183 :
184 : void
185 0 : DataHandler::parseEdgeData(const SUMOSAXAttributes& attrs) {
186 : // declare Ok Flag
187 0 : bool parsedOk = true;
188 : // needed attributes
189 0 : const std::string id = attrs.get<std::string>(SUMO_ATTR_ID, "", parsedOk);
190 : // fill attributes
191 0 : getAttributes(attrs, {SUMO_ATTR_ID});
192 : // continue if flag is ok
193 0 : if (parsedOk) {
194 : // set tag
195 0 : myCommonXMLStructure.getCurrentSumoBaseObject()->setTag(SUMO_TAG_EDGE);
196 : // add all attributes
197 0 : myCommonXMLStructure.getCurrentSumoBaseObject()->addStringAttribute(SUMO_ATTR_ID, id);
198 : } else {
199 0 : myCommonXMLStructure.getCurrentSumoBaseObject()->setTag(SUMO_TAG_ERROR);
200 : }
201 0 : }
202 :
203 :
204 : void
205 0 : DataHandler::parseEdgeRelationData(const SUMOSAXAttributes& attrs) {
206 : // declare Ok Flag
207 0 : bool parsedOk = true;
208 : // needed attributes
209 0 : const std::string from = attrs.get<std::string>(SUMO_ATTR_FROM, "", parsedOk);
210 0 : const std::string to = attrs.get<std::string>(SUMO_ATTR_TO, "", parsedOk);
211 : // fill attributes
212 0 : getAttributes(attrs, {SUMO_ATTR_FROM, SUMO_ATTR_TO});
213 : // continue if flag is ok
214 0 : if (parsedOk) {
215 : // set tag
216 0 : myCommonXMLStructure.getCurrentSumoBaseObject()->setTag(SUMO_TAG_EDGEREL);
217 : // add all attributes
218 0 : myCommonXMLStructure.getCurrentSumoBaseObject()->addStringAttribute(SUMO_ATTR_FROM, from);
219 0 : myCommonXMLStructure.getCurrentSumoBaseObject()->addStringAttribute(SUMO_ATTR_TO, to);
220 : } else {
221 0 : myCommonXMLStructure.getCurrentSumoBaseObject()->setTag(SUMO_TAG_ERROR);
222 : }
223 0 : }
224 :
225 :
226 : void
227 0 : DataHandler::parseTAZRelationData(const SUMOSAXAttributes& attrs) {
228 : // declare Ok Flag
229 0 : bool parsedOk = true;
230 : // needed attributes
231 0 : const std::string from = attrs.get<std::string>(SUMO_ATTR_FROM, "", parsedOk);
232 0 : const std::string to = attrs.get<std::string>(SUMO_ATTR_TO, "", parsedOk);
233 : // fill attributes
234 0 : getAttributes(attrs, {SUMO_ATTR_FROM, SUMO_ATTR_TO});
235 : // continue if flag is ok
236 0 : if (parsedOk) {
237 : // set tag
238 0 : myCommonXMLStructure.getCurrentSumoBaseObject()->setTag(SUMO_TAG_TAZREL);
239 : // add all attributes
240 0 : myCommonXMLStructure.getCurrentSumoBaseObject()->addStringAttribute(SUMO_ATTR_FROM, from);
241 0 : myCommonXMLStructure.getCurrentSumoBaseObject()->addStringAttribute(SUMO_ATTR_TO, to);
242 : } else {
243 0 : myCommonXMLStructure.getCurrentSumoBaseObject()->setTag(SUMO_TAG_ERROR);
244 : }
245 0 : }
246 :
247 :
248 : void
249 0 : DataHandler::getAttributes(const SUMOSAXAttributes& attrs, const std::vector<SumoXMLAttr> avoidAttributes) const {
250 : // transform avoidAttributes to strings
251 : std::vector<std::string> avoidAttributesStr;
252 0 : for (const SumoXMLAttr& avoidAttribute : avoidAttributes) {
253 0 : avoidAttributesStr.push_back(toString(avoidAttribute));
254 : }
255 : // iterate over attributes and fill parameters map
256 0 : for (const std::string& attribute : attrs.getAttributeNames()) {
257 0 : if (std::find(avoidAttributesStr.begin(), avoidAttributesStr.end(), attribute) == avoidAttributesStr.end()) {
258 0 : myCommonXMLStructure.getCurrentSumoBaseObject()->addParameter(attribute, attrs.getStringSecure(attribute, ""));
259 : }
260 0 : }
261 0 : }
262 :
263 :
264 : void
265 0 : DataHandler::checkParent(const SumoXMLTag currentTag, const SumoXMLTag parentTag, bool& ok) {
266 : // check that parent SUMOBaseObject's tag is the parentTag
267 0 : if ((myCommonXMLStructure.getCurrentSumoBaseObject()->getParentSumoBaseObject() &&
268 0 : (myCommonXMLStructure.getCurrentSumoBaseObject()->getParentSumoBaseObject()->getTag() == parentTag)) == false) {
269 0 : writeError(toString(currentTag) + " must be defined within the definition of a " + toString(parentTag));
270 0 : ok = false;
271 : }
272 0 : }
273 :
274 : /****************************************************************************/
|