#include <config.h>
#include <utils/common/MsgHandler.h>
#include "SAXWeightsHandler.h"
SAXWeightsHandler::ToRetrieveDefinition::ToRetrieveDefinition(const std::string& attributeName,
bool edgeBased, EdgeFloatTimeLineRetriever& destination) :
myAttributeName(attributeName),
myAmEdgeBased(edgeBased),
myDestination(destination),
myAggValue(0),
myNoLanes(0),
myHadAttribute(0),
myHadNonNumeric(false)
{ }
SAXWeightsHandler::ToRetrieveDefinition::~ToRetrieveDefinition() {
}
SAXWeightsHandler::SAXWeightsHandler(const std::vector<ToRetrieveDefinition*>& defs, const std::string& file) :
SUMOSAXHandler(file),
myDefinitions(defs),
myCurrentTimeBeg(-1),
myCurrentTimeEnd(-1) {
}
SAXWeightsHandler::SAXWeightsHandler(ToRetrieveDefinition* def, const std::string& file) :
SUMOSAXHandler(file),
myDefinitions({def}),
myCurrentTimeBeg(-1),
myCurrentTimeEnd(-1) {
}
SAXWeightsHandler::~SAXWeightsHandler() {
for (const auto& definition : myDefinitions) {
delete definition;
}
}
void
SAXWeightsHandler::myStartElement(int element, const SUMOSAXAttributes& attrs) {
switch (element) {
case SUMO_TAG_INTERVAL: {
bool ok = true;
myCurrentID = attrs.getOpt<std::string>(SUMO_ATTR_ID, nullptr, ok, "");
myCurrentTimeBeg = STEPS2TIME(attrs.getSUMOTimeReporting(SUMO_ATTR_BEGIN, nullptr, ok));
myCurrentTimeEnd = STEPS2TIME(attrs.getSUMOTimeReporting(SUMO_ATTR_END, nullptr, ok));
if (myCurrentTimeEnd < myCurrentTimeBeg) {
WRITE_ERROR("Interval end time " + toString(myCurrentTimeEnd) + " is lower than interval begin time " + toString(myCurrentTimeBeg));
myCurrentTimeEnd = myCurrentTimeBeg;
}
}
break;
case SUMO_TAG_EDGE: {
bool ok = true;
myCurrentEdgeID = attrs.getOpt<std::string>(SUMO_ATTR_ID, nullptr, ok, "");
tryParse(attrs, true);
}
break;
case SUMO_TAG_EDGEREL: {
tryParseEdgeRel(attrs);
}
break;
case SUMO_TAG_TAZREL: {
tryParseTazRel(attrs);
}
break;
break;
case SUMO_TAG_LANE: {
tryParse(attrs, false);
}
break;
default:
break;
}
}
void
SAXWeightsHandler::tryParse(const SUMOSAXAttributes& attrs, bool isEdge) {
if (isEdge) {
for (const auto& definition : myDefinitions) {
if (definition->myAmEdgeBased) {
if (attrs.hasAttribute(definition->myAttributeName)) {
try {
definition->myAggValue = attrs.getFloat(definition->myAttributeName);
definition->myNoLanes = 1;
definition->myHadAttribute = true;
} catch (EmptyData&) {
WRITE_ERRORF(TL("Missing value '%' in edge '%'."), definition->myAttributeName, myCurrentEdgeID);
} catch (NumberFormatException&) {
if (!definition->myHadNonNumeric) {
definition->myHadNonNumeric = true;
WRITE_ERRORF(TL("The value '%' of attribute '%' should be numeric in edge '%' at time step %."),
attrs.getStringSecure(definition->myAttributeName, ""), definition->myAttributeName,
myCurrentEdgeID, time2string(TIME2STEPS(myCurrentTimeBeg)));
}
}
} else {
definition->myHadAttribute = false;
}
} else {
definition->myAggValue = 0;
definition->myNoLanes = 0;
}
}
} else {
for (const auto& definition : myDefinitions) {
if (!definition->myAmEdgeBased) {
try {
definition->myAggValue += attrs.getFloat(definition->myAttributeName);
definition->myNoLanes++;
definition->myHadAttribute = true;
} catch (EmptyData&) {
WRITE_ERRORF(TL("Missing value '%' in edge '%'."), definition->myAttributeName, myCurrentEdgeID);
} catch (NumberFormatException&) {
if (!definition->myHadNonNumeric) {
definition->myHadNonNumeric = true;
WRITE_ERRORF(TL("The value '%' of attribute '%' should be numeric in edge '%' at time step %."),
attrs.getStringSecure(definition->myAttributeName, ""), definition->myAttributeName,
myCurrentEdgeID, time2string(TIME2STEPS(myCurrentTimeBeg)));
}
}
}
}
}
}
void
SAXWeightsHandler::tryParseEdgeRel(const SUMOSAXAttributes& attrs) {
if (attrs.hasAttribute(SUMO_ATTR_FROM) && attrs.hasAttribute(SUMO_ATTR_TO)) {
bool ok = true;
const std::string from = attrs.get<std::string>(SUMO_ATTR_FROM, nullptr, ok);
const std::string to = attrs.get<std::string>(SUMO_ATTR_TO, nullptr, ok);
for (ToRetrieveDefinition* ret : myDefinitions) {
if (attrs.hasAttribute(ret->myAttributeName)) {
ret->myDestination.addEdgeRelWeight(from, to,
attrs.getFloat(ret->myAttributeName),
myCurrentTimeBeg, myCurrentTimeEnd);
}
}
}
}
void
SAXWeightsHandler::tryParseTazRel(const SUMOSAXAttributes& attrs) {
if (attrs.hasAttribute(SUMO_ATTR_FROM) && attrs.hasAttribute(SUMO_ATTR_TO)) {
bool ok = true;
const std::string from = attrs.get<std::string>(SUMO_ATTR_FROM, nullptr, ok);
const std::string to = attrs.get<std::string>(SUMO_ATTR_TO, nullptr, ok);
for (ToRetrieveDefinition* ret : myDefinitions) {
if (attrs.hasAttribute(ret->myAttributeName)) {
ret->myDestination.addTazRelWeight(myCurrentID, from, to,
attrs.getFloat(ret->myAttributeName),
myCurrentTimeBeg, myCurrentTimeEnd);
}
}
}
}
void
SAXWeightsHandler::myEndElement(int element) {
if (element == SUMO_TAG_EDGE) {
for (const auto& definition : myDefinitions) {
if (definition->myHadAttribute) {
definition->myDestination.addEdgeWeight(myCurrentEdgeID,
definition->myAggValue / (double)definition->myNoLanes,
myCurrentTimeBeg, myCurrentTimeEnd);
}
}
}
}