Line data Source code
1 : /****************************************************************************/
2 : // Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo
3 : // Copyright (C) 2007-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 SAXWeightsHandler.cpp
15 : /// @author Daniel Krajzewicz
16 : /// @author Jakob Erdmann
17 : /// @author Michael Behrisch
18 : /// @date Fri, 30 Mar 2007
19 : ///
20 : // An XML-handler for network weights
21 : /****************************************************************************/
22 : #include <config.h>
23 :
24 : #include <utils/common/MsgHandler.h>
25 :
26 : #include "SAXWeightsHandler.h"
27 :
28 :
29 : // ===========================================================================
30 : // method definitions
31 : // ===========================================================================
32 :
33 : // ---------------------------------------------------------------------------
34 : // SAXWeightsHandler::ToRetrieveDefinition methods
35 : // ---------------------------------------------------------------------------
36 :
37 451 : SAXWeightsHandler::ToRetrieveDefinition::ToRetrieveDefinition(const std::string& attributeName,
38 451 : bool edgeBased, EdgeFloatTimeLineRetriever& destination) :
39 451 : myAttributeName(attributeName),
40 451 : myAmEdgeBased(edgeBased),
41 451 : myDestination(destination),
42 451 : myAggValue(0),
43 451 : myNoLanes(0),
44 451 : myHadAttribute(0),
45 451 : myHadNonNumeric(false)
46 451 : { }
47 :
48 :
49 451 : SAXWeightsHandler::ToRetrieveDefinition::~ToRetrieveDefinition() {
50 451 : }
51 :
52 : // ---------------------------------------------------------------------------
53 : // SAXWeightsHandler methods
54 : // ---------------------------------------------------------------------------
55 :
56 441 : SAXWeightsHandler::SAXWeightsHandler(const std::vector<ToRetrieveDefinition*>& defs, const std::string& file) :
57 : SUMOSAXHandler(file),
58 441 : myDefinitions(defs),
59 441 : myCurrentTimeBeg(-1),
60 882 : myCurrentTimeEnd(-1) {
61 441 : }
62 :
63 :
64 0 : SAXWeightsHandler::SAXWeightsHandler(ToRetrieveDefinition* def, const std::string& file) :
65 : SUMOSAXHandler(file),
66 0 : myDefinitions({def}),
67 0 : myCurrentTimeBeg(-1),
68 0 : myCurrentTimeEnd(-1) {
69 0 : }
70 :
71 :
72 441 : SAXWeightsHandler::~SAXWeightsHandler() {
73 892 : for (const auto& definition : myDefinitions) {
74 451 : delete definition;
75 : }
76 441 : }
77 :
78 :
79 : void
80 6803 : SAXWeightsHandler::myStartElement(int element, const SUMOSAXAttributes& attrs) {
81 6803 : switch (element) {
82 683 : case SUMO_TAG_INTERVAL: {
83 683 : bool ok = true;
84 683 : myCurrentID = attrs.getOpt<std::string>(SUMO_ATTR_ID, nullptr, ok, "");
85 683 : myCurrentTimeBeg = STEPS2TIME(attrs.getSUMOTimeReporting(SUMO_ATTR_BEGIN, nullptr, ok));
86 683 : myCurrentTimeEnd = STEPS2TIME(attrs.getSUMOTimeReporting(SUMO_ATTR_END, nullptr, ok));
87 683 : if (myCurrentTimeEnd < myCurrentTimeBeg) {
88 0 : WRITE_ERROR("Interval end time " + toString(myCurrentTimeEnd) + " is lower than interval begin time " + toString(myCurrentTimeBeg));
89 0 : myCurrentTimeEnd = myCurrentTimeBeg;
90 : }
91 : }
92 683 : break;
93 5644 : case SUMO_TAG_EDGE: {
94 5644 : bool ok = true;
95 5644 : myCurrentEdgeID = attrs.getOpt<std::string>(SUMO_ATTR_ID, nullptr, ok, "");
96 5644 : tryParse(attrs, true);
97 : }
98 5644 : break;
99 0 : case SUMO_TAG_EDGEREL: {
100 0 : tryParseEdgeRel(attrs);
101 : }
102 0 : break;
103 7 : case SUMO_TAG_TAZREL: {
104 7 : tryParseTazRel(attrs);
105 : }
106 7 : break;
107 24 : case SUMO_TAG_LANE: {
108 24 : tryParse(attrs, false);
109 : }
110 24 : break;
111 : default:
112 : break;
113 : }
114 6803 : }
115 :
116 :
117 : void
118 5668 : SAXWeightsHandler::tryParse(const SUMOSAXAttributes& attrs, bool isEdge) {
119 5668 : if (isEdge) {
120 : // process all that want values directly from the edge
121 11478 : for (const auto& definition : myDefinitions) {
122 5834 : if (definition->myAmEdgeBased) {
123 5814 : if (attrs.hasAttribute(definition->myAttributeName)) {
124 : try {
125 5804 : definition->myAggValue = attrs.getFloat(definition->myAttributeName);
126 5804 : definition->myNoLanes = 1;
127 5804 : definition->myHadAttribute = true;
128 0 : } catch (EmptyData&) {
129 0 : WRITE_ERRORF(TL("Missing value '%' in edge '%'."), definition->myAttributeName, myCurrentEdgeID);
130 0 : } catch (NumberFormatException&) {
131 0 : if (!definition->myHadNonNumeric) {
132 : // warn only once
133 0 : definition->myHadNonNumeric = true;
134 0 : WRITE_ERRORF(TL("The value '%' of attribute '%' should be numeric in edge '%' at time step %."),
135 : attrs.getStringSecure(definition->myAttributeName, ""), definition->myAttributeName,
136 : myCurrentEdgeID, time2string(TIME2STEPS(myCurrentTimeBeg)));
137 : }
138 0 : }
139 : } else {
140 10 : definition->myHadAttribute = false;
141 : }
142 : } else {
143 20 : definition->myAggValue = 0;
144 20 : definition->myNoLanes = 0;
145 : }
146 : }
147 : } else {
148 : // process the current lane values
149 48 : for (const auto& definition : myDefinitions) {
150 24 : if (!definition->myAmEdgeBased) {
151 : try {
152 24 : definition->myAggValue += attrs.getFloat(definition->myAttributeName);
153 24 : definition->myNoLanes++;
154 24 : definition->myHadAttribute = true;
155 0 : } catch (EmptyData&) {
156 0 : WRITE_ERRORF(TL("Missing value '%' in edge '%'."), definition->myAttributeName, myCurrentEdgeID);
157 0 : } catch (NumberFormatException&) {
158 0 : if (!definition->myHadNonNumeric) {
159 : // warn only once
160 0 : definition->myHadNonNumeric = true;
161 0 : WRITE_ERRORF(TL("The value '%' of attribute '%' should be numeric in edge '%' at time step %."),
162 : attrs.getStringSecure(definition->myAttributeName, ""), definition->myAttributeName,
163 : myCurrentEdgeID, time2string(TIME2STEPS(myCurrentTimeBeg)));
164 : }
165 0 : }
166 : }
167 : }
168 : }
169 5668 : }
170 :
171 :
172 : void
173 0 : SAXWeightsHandler::tryParseEdgeRel(const SUMOSAXAttributes& attrs) {
174 0 : if (attrs.hasAttribute(SUMO_ATTR_FROM) && attrs.hasAttribute(SUMO_ATTR_TO)) {
175 0 : bool ok = true;
176 0 : const std::string from = attrs.get<std::string>(SUMO_ATTR_FROM, nullptr, ok);
177 0 : const std::string to = attrs.get<std::string>(SUMO_ATTR_TO, nullptr, ok);
178 0 : for (ToRetrieveDefinition* ret : myDefinitions) {
179 0 : if (attrs.hasAttribute(ret->myAttributeName)) {
180 0 : ret->myDestination.addEdgeRelWeight(from, to,
181 0 : attrs.getFloat(ret->myAttributeName),
182 : myCurrentTimeBeg, myCurrentTimeEnd);
183 : }
184 : }
185 : }
186 0 : }
187 :
188 : void
189 7 : SAXWeightsHandler::tryParseTazRel(const SUMOSAXAttributes& attrs) {
190 7 : if (attrs.hasAttribute(SUMO_ATTR_FROM) && attrs.hasAttribute(SUMO_ATTR_TO)) {
191 7 : bool ok = true;
192 7 : const std::string from = attrs.get<std::string>(SUMO_ATTR_FROM, nullptr, ok);
193 7 : const std::string to = attrs.get<std::string>(SUMO_ATTR_TO, nullptr, ok);
194 14 : for (ToRetrieveDefinition* ret : myDefinitions) {
195 7 : if (attrs.hasAttribute(ret->myAttributeName)) {
196 14 : ret->myDestination.addTazRelWeight(myCurrentID, from, to,
197 7 : attrs.getFloat(ret->myAttributeName),
198 : myCurrentTimeBeg, myCurrentTimeEnd);
199 : }
200 : }
201 : }
202 7 : }
203 :
204 :
205 : void
206 6803 : SAXWeightsHandler::myEndElement(int element) {
207 6803 : if (element == SUMO_TAG_EDGE) {
208 11478 : for (const auto& definition : myDefinitions) {
209 5834 : if (definition->myHadAttribute) {
210 5824 : definition->myDestination.addEdgeWeight(myCurrentEdgeID,
211 5824 : definition->myAggValue / (double)definition->myNoLanes,
212 : myCurrentTimeBeg, myCurrentTimeEnd);
213 : }
214 : }
215 : }
216 6803 : }
217 :
218 :
219 : /****************************************************************************/
|