#include <config.h>
#include <string>
#include <utility>
#include <iostream>
#include <utils/common/UtilExceptions.h>
#include <utils/common/MsgHandler.h>
#include <utils/common/ToString.h>
#include <utils/xml/SUMOSAXHandler.h>
#include <utils/xml/SUMOXMLDefinitions.h>
#include "ODDistrict.h"
#include "ODDistrictCont.h"
#include "ODDistrictHandler.h"
ODDistrictHandler::ODDistrictHandler(ODDistrictCont& cont,
const std::string& file)
: SUMOSAXHandler(file), myContainer(cont), myCurrentDistrict(nullptr) {}
ODDistrictHandler::~ODDistrictHandler() {}
void
ODDistrictHandler::myStartElement(int element,
const SUMOSAXAttributes& attrs) {
switch (element) {
case SUMO_TAG_TAZ:
openDistrict(attrs);
break;
case SUMO_TAG_TAZSOURCE:
addSource(attrs);
break;
case SUMO_TAG_TAZSINK:
addSink(attrs);
break;
default:
break;
}
}
void
ODDistrictHandler::myEndElement(int element) {
if (element == SUMO_TAG_TAZ) {
closeDistrict();
}
}
void
ODDistrictHandler::openDistrict(const SUMOSAXAttributes& attrs) {
myCurrentDistrict = nullptr;
bool ok = true;
std::string id = attrs.get<std::string>(SUMO_ATTR_ID, nullptr, ok);
if (!ok) {
return;
}
myCurrentDistrict = new ODDistrict(id);
if (attrs.hasAttribute(SUMO_ATTR_EDGES)) {
const std::vector<std::string>& desc = attrs.get<std::vector<std::string> >(SUMO_ATTR_EDGES, id.c_str(), ok);
for (const std::string& eID : desc) {
myCurrentDistrict->addSource(eID, 1.);
myCurrentDistrict->addSink(eID, 1.);
}
}
}
void
ODDistrictHandler::addSource(const SUMOSAXAttributes& attrs) {
std::pair<std::string, double> vals = parseTAZ(attrs);
if (vals.second >= 0) {
myCurrentDistrict->addSource(vals.first, vals.second);
}
}
void
ODDistrictHandler::addSink(const SUMOSAXAttributes& attrs) {
std::pair<std::string, double> vals = parseTAZ(attrs);
if (vals.second >= 0) {
myCurrentDistrict->addSink(vals.first, vals.second);
}
}
std::pair<std::string, double>
ODDistrictHandler::parseTAZ(const SUMOSAXAttributes& attrs) {
if (myCurrentDistrict == nullptr) {
return std::pair<std::string, double>("", -1);
}
bool ok = true;
std::string id = attrs.get<std::string>(SUMO_ATTR_ID, nullptr, ok);
if (!ok) {
return std::pair<std::string, double>("", -1);
}
double weight = attrs.get<double>(SUMO_ATTR_WEIGHT, id.c_str(), ok);
if (ok) {
if (weight < 0) {
WRITE_ERRORF(TL("'probability' must be positive (in definition of % '%')."), attrs.getObjectType(), id);
} else {
return std::pair<std::string, double>(id, weight);
}
}
return std::pair<std::string, double>("", -1);
}
void
ODDistrictHandler::closeDistrict() {
if (myCurrentDistrict != nullptr) {
myContainer.add(myCurrentDistrict->getID(), myCurrentDistrict);
}
}