Line data Source code
1 : /****************************************************************************/
2 : // Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo
3 : // Copyright (C) 2007-2024 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 428 : SAXWeightsHandler::ToRetrieveDefinition::ToRetrieveDefinition(const std::string& attributeName,
38 428 : bool edgeBased, EdgeFloatTimeLineRetriever& destination) :
39 428 : myAttributeName(attributeName),
40 428 : myAmEdgeBased(edgeBased),
41 428 : myDestination(destination),
42 428 : myAggValue(0),
43 428 : myNoLanes(0),
44 428 : myHadAttribute(0),
45 428 : myHadNonNumeric(false)
46 428 : { }
47 :
48 :
49 428 : SAXWeightsHandler::ToRetrieveDefinition::~ToRetrieveDefinition() {
50 428 : }
51 :
52 : // ---------------------------------------------------------------------------
53 : // SAXWeightsHandler methods
54 : // ---------------------------------------------------------------------------
55 :
56 418 : SAXWeightsHandler::SAXWeightsHandler(const std::vector<ToRetrieveDefinition*>& defs, const std::string& file) :
57 : SUMOSAXHandler(file),
58 418 : myDefinitions(defs),
59 418 : myCurrentTimeBeg(-1),
60 836 : myCurrentTimeEnd(-1) {
61 418 : }
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 418 : SAXWeightsHandler::~SAXWeightsHandler() {
73 846 : for (const auto& definition : myDefinitions) {
74 428 : delete definition;
75 : }
76 418 : }
77 :
78 :
79 : void
80 6374 : SAXWeightsHandler::myStartElement(int element, const SUMOSAXAttributes& attrs) {
81 6374 : switch (element) {
82 661 : case SUMO_TAG_INTERVAL: {
83 661 : bool ok = true;
84 661 : myCurrentID = attrs.getOpt<std::string>(SUMO_ATTR_ID, nullptr, ok, "");
85 661 : myCurrentTimeBeg = STEPS2TIME(attrs.getSUMOTimeReporting(SUMO_ATTR_BEGIN, nullptr, ok));
86 661 : myCurrentTimeEnd = STEPS2TIME(attrs.getSUMOTimeReporting(SUMO_ATTR_END, nullptr, ok));
87 661 : 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 661 : break;
93 5260 : case SUMO_TAG_EDGE: {
94 5260 : bool ok = true;
95 5260 : myCurrentEdgeID = attrs.getOpt<std::string>(SUMO_ATTR_ID, nullptr, ok, "");
96 5260 : tryParse(attrs, true);
97 : }
98 5260 : 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 : break;
108 24 : case SUMO_TAG_LANE: {
109 24 : tryParse(attrs, false);
110 : }
111 24 : break;
112 : default:
113 : break;
114 : }
115 6374 : }
116 :
117 :
118 : void
119 5284 : SAXWeightsHandler::tryParse(const SUMOSAXAttributes& attrs, bool isEdge) {
120 5284 : if (isEdge) {
121 : // process all that want values directly from the edge
122 10710 : for (const auto& definition : myDefinitions) {
123 5450 : if (definition->myAmEdgeBased) {
124 5430 : if (attrs.hasAttribute(definition->myAttributeName)) {
125 : try {
126 5420 : definition->myAggValue = attrs.getFloat(definition->myAttributeName);
127 5420 : definition->myNoLanes = 1;
128 5420 : definition->myHadAttribute = true;
129 0 : } catch (EmptyData&) {
130 0 : WRITE_ERRORF(TL("Missing value '%' in edge '%'."), definition->myAttributeName, myCurrentEdgeID);
131 0 : } catch (NumberFormatException&) {
132 0 : if (!definition->myHadNonNumeric) {
133 : // warn only once
134 0 : definition->myHadNonNumeric = true;
135 0 : WRITE_ERRORF(TL("The value '%' of attribute '%' should be numeric in edge '%' at time step %."),
136 : attrs.getStringSecure(definition->myAttributeName, ""), definition->myAttributeName,
137 : myCurrentEdgeID, time2string(TIME2STEPS(myCurrentTimeBeg)));
138 : }
139 0 : }
140 : } else {
141 10 : definition->myHadAttribute = false;
142 : }
143 : } else {
144 20 : definition->myAggValue = 0;
145 20 : definition->myNoLanes = 0;
146 : }
147 : }
148 : } else {
149 : // process the current lane values
150 48 : for (const auto& definition : myDefinitions) {
151 24 : if (!definition->myAmEdgeBased) {
152 : try {
153 24 : definition->myAggValue += attrs.getFloat(definition->myAttributeName);
154 24 : definition->myNoLanes++;
155 24 : definition->myHadAttribute = true;
156 0 : } catch (EmptyData&) {
157 0 : WRITE_ERRORF(TL("Missing value '%' in edge '%'."), definition->myAttributeName, myCurrentEdgeID);
158 0 : } catch (NumberFormatException&) {
159 0 : if (!definition->myHadNonNumeric) {
160 : // warn only once
161 0 : definition->myHadNonNumeric = true;
162 0 : WRITE_ERRORF(TL("The value '%' of attribute '%' should be numeric in edge '%' at time step %."),
163 : attrs.getStringSecure(definition->myAttributeName, ""), definition->myAttributeName,
164 : myCurrentEdgeID, time2string(TIME2STEPS(myCurrentTimeBeg)));
165 : }
166 0 : }
167 : }
168 : }
169 : }
170 5284 : }
171 :
172 :
173 : void
174 0 : SAXWeightsHandler::tryParseEdgeRel(const SUMOSAXAttributes& attrs) {
175 0 : if (attrs.hasAttribute(SUMO_ATTR_FROM) && attrs.hasAttribute(SUMO_ATTR_TO)) {
176 0 : bool ok = true;
177 0 : const std::string from = attrs.get<std::string>(SUMO_ATTR_FROM, nullptr, ok);
178 0 : const std::string to = attrs.get<std::string>(SUMO_ATTR_TO, nullptr, ok);
179 0 : for (ToRetrieveDefinition* ret : myDefinitions) {
180 0 : if (attrs.hasAttribute(ret->myAttributeName)) {
181 0 : ret->myDestination.addEdgeRelWeight(from, to,
182 0 : attrs.getFloat(ret->myAttributeName),
183 : myCurrentTimeBeg, myCurrentTimeEnd);
184 : }
185 : }
186 : }
187 0 : }
188 :
189 : void
190 7 : SAXWeightsHandler::tryParseTazRel(const SUMOSAXAttributes& attrs) {
191 7 : if (attrs.hasAttribute(SUMO_ATTR_FROM) && attrs.hasAttribute(SUMO_ATTR_TO)) {
192 7 : bool ok = true;
193 7 : const std::string from = attrs.get<std::string>(SUMO_ATTR_FROM, nullptr, ok);
194 7 : const std::string to = attrs.get<std::string>(SUMO_ATTR_TO, nullptr, ok);
195 14 : for (ToRetrieveDefinition* ret : myDefinitions) {
196 7 : if (attrs.hasAttribute(ret->myAttributeName)) {
197 14 : ret->myDestination.addTazRelWeight(myCurrentID, from, to,
198 7 : attrs.getFloat(ret->myAttributeName),
199 : myCurrentTimeBeg, myCurrentTimeEnd);
200 : }
201 : }
202 : }
203 7 : }
204 :
205 :
206 : void
207 6374 : SAXWeightsHandler::myEndElement(int element) {
208 6374 : if (element == SUMO_TAG_EDGE) {
209 10710 : for (const auto& definition : myDefinitions) {
210 5450 : if (definition->myHadAttribute) {
211 5440 : definition->myDestination.addEdgeWeight(myCurrentEdgeID,
212 5440 : definition->myAggValue / (double)definition->myNoLanes,
213 : myCurrentTimeBeg, myCurrentTimeEnd);
214 : }
215 : }
216 : }
217 6374 : }
218 :
219 :
220 : /****************************************************************************/
|