#include <config.h>
#ifdef HAVE_VERSION_H
#include <version.h>
#endif
#include <iostream>
#include <string>
#include <limits.h>
#include <ctime>
#include <xercesc/sax/SAXException.hpp>
#include <xercesc/sax/SAXParseException.hpp>
#include <utils/common/StringUtils.h>
#include <utils/common/MsgHandler.h>
#include <utils/common/UtilExceptions.h>
#include <utils/common/SystemFrame.h>
#include <utils/common/ToString.h>
#include <utils/common/FileHelpers.h>
#include <utils/options/Option.h>
#include <utils/options/OptionsCont.h>
#include <utils/options/OptionsIO.h>
#include <utils/iodevices/OutputDevice.h>
#include <utils/xml/XMLSubSys.h>
#include <router/ROLoader.h>
#include <router/RONet.h>
#include "RODFEdgeBuilder.h"
#include "RODFFrame.h"
#include "RODFNet.h"
#include "RODFEdge.h"
#include "RODFDetector.h"
#include "RODFDetectorHandler.h"
#include "RODFRouteCont.h"
#include "RODFDetectorFlow.h"
#include "RODFDetFlowLoader.h"
void
readDetectors(RODFDetectorCon& detectors, OptionsCont& oc, RODFNet* optNet) {
if (!oc.isSet("detector-files")) {
throw ProcessError(TL("No detector file given (use --detector-files <FILE>)."));
}
std::vector<std::string> files = oc.getStringVector("detector-files");
for (std::vector<std::string>::const_iterator fileIt = files.begin(); fileIt != files.end(); ++fileIt) {
if (!FileHelpers::isReadable(*fileIt)) {
throw ProcessError(TLF("Could not open detector file '%'", *fileIt));
}
PROGRESS_BEGIN_MESSAGE("Loading detector definitions from '" + *fileIt + "'");
RODFDetectorHandler handler(optNet, oc.getBool("ignore-invalid-detectors"), detectors, *fileIt);
if (XMLSubSys::runParser(handler, *fileIt)) {
PROGRESS_DONE_MESSAGE();
} else {
PROGRESS_FAILED_MESSAGE();
throw ProcessError();
}
}
if (detectors.getDetectors().empty()) {
throw ProcessError(TL("No detectors found."));
}
}
void
readDetectorFlows(RODFDetectorFlows& flows, OptionsCont& oc, RODFDetectorCon& dc) {
if (!oc.isSet("measure-files")) {
return;
}
std::vector<std::string> files = oc.getStringVector("measure-files");
for (std::vector<std::string>::const_iterator fileIt = files.begin(); fileIt != files.end(); ++fileIt) {
if (!FileHelpers::isReadable(*fileIt)) {
throw ProcessError(TLF("The measure-file '%' can not be opened.", *fileIt));
}
PROGRESS_BEGIN_MESSAGE("Loading flows from '" + *fileIt + "'");
RODFDetFlowLoader dfl(dc, flows, string2time(oc.getString("begin")), string2time(oc.getString("end")),
string2time(oc.getString("time-offset")), string2time(oc.getString("time-factor")));
dfl.read(*fileIt);
PROGRESS_DONE_MESSAGE();
}
}
void
startComputation(RODFNet* optNet, RODFDetectorFlows& flows, RODFDetectorCon& detectors, OptionsCont& oc) {
if (oc.getBool("print-absolute-flows")) {
flows.printAbsolute();
}
if (oc.getBool("remove-empty-detectors")) {
PROGRESS_BEGIN_MESSAGE(TL("Removing empty detectors"));
optNet->removeEmptyDetectors(detectors, flows);
PROGRESS_DONE_MESSAGE();
} else if (oc.getBool("report-empty-detectors")) {
PROGRESS_BEGIN_MESSAGE(TL("Scanning for empty detectors"));
optNet->reportEmptyDetectors(detectors, flows);
PROGRESS_DONE_MESSAGE();
}
if (!detectors.detectorsHaveCompleteTypes() || oc.getBool("revalidate-detectors")) {
optNet->computeTypes(detectors, oc.getBool("strict-sources"));
}
std::vector<RODFDetector*>::const_iterator i = detectors.getDetectors().begin();
for (; i != detectors.getDetectors().end(); ++i) {
if ((*i)->getType() == SOURCE_DETECTOR) {
break;
}
}
if (i == detectors.getDetectors().end() && !oc.getBool("routes-for-all")) {
throw ProcessError(TL("No source detectors found."));
}
if (!detectors.detectorsHaveRoutes() || oc.getBool("revalidate-routes") || oc.getBool("guess-empty-flows")) {
PROGRESS_BEGIN_MESSAGE(TL("Computing routes"));
optNet->buildRoutes(detectors,
oc.getBool("keep-unfinished-routes"), oc.getBool("routes-for-all"),
!oc.getBool("keep-longer-routes"), oc.getInt("max-search-depth"));
PROGRESS_DONE_MESSAGE();
}
if (!detectors.detectorsHaveCompleteTypes()) {
throw ProcessError(TL("The detector types are not defined; use in combination with a network"));
}
if (!detectors.detectorsHaveRoutes()) {
throw ProcessError(TL("The emitters have no routes; use in combination with a network"));
}
if (oc.isSet("detector-output")) {
detectors.save(oc.getString("detector-output"));
}
if (oc.isSet("detectors-poi-output")) {
detectors.saveAsPOIs(oc.getString("detectors-poi-output"));
}
if (detectors.detectorsHaveRoutes() && oc.isSet("routes-output")) {
detectors.saveRoutes(oc.getString("routes-output"));
}
if (oc.getBool("guess-empty-flows")) {
optNet->buildDetectorDependencies(detectors);
detectors.guessEmptyFlows(flows);
}
const SUMOTime begin = string2time(oc.getString("begin"));
const SUMOTime end = string2time(oc.getString("end"));
const SUMOTime step = string2time(oc.getString("time-step"));
if (oc.isSet("emitters-output") || oc.isSet("emitters-poi-output")) {
optNet->buildEdgeFlowMap(flows, detectors, begin, end, step);
if (oc.getBool("revalidate-flows")) {
PROGRESS_BEGIN_MESSAGE(TL("Rechecking loaded flows"));
optNet->revalidateFlows(detectors, flows, begin, end, step);
PROGRESS_DONE_MESSAGE();
}
if (oc.isSet("emitters-output")) {
PROGRESS_BEGIN_MESSAGE(TL("Writing emitters"));
detectors.writeEmitters(oc.getString("emitters-output"), flows,
begin, end, step,
*optNet,
oc.getBool("calibrator-output"),
oc.getBool("include-unused-routes"),
oc.getFloat("scale"),
oc.getBool("emissions-only"));
PROGRESS_DONE_MESSAGE();
}
if (oc.isSet("emitters-poi-output")) {
PROGRESS_BEGIN_MESSAGE(TL("Writing emitter pois"));
detectors.writeEmitterPOIs(oc.getString("emitters-poi-output"), flows);
PROGRESS_DONE_MESSAGE();
}
}
if (oc.isSet("variable-speed-sign-output")) {
PROGRESS_BEGIN_MESSAGE(TL("Writing speed triggers"));
detectors.writeSpeedTrigger(optNet, oc.getString("variable-speed-sign-output"), flows,
begin, end, step);
PROGRESS_DONE_MESSAGE();
}
if (oc.isSet("validation-output")) {
PROGRESS_BEGIN_MESSAGE(TL("Writing validation detectors"));
detectors.writeValidationDetectors(oc.getString("validation-output"),
oc.getBool("validation-output.add-sources"), true, true);
PROGRESS_DONE_MESSAGE();
}
if (oc.isSet("end-reroute-output")) {
PROGRESS_BEGIN_MESSAGE(TL("Writing highway end rerouter"));
detectors.writeEndRerouterDetectors(oc.getString("end-reroute-output"));
PROGRESS_DONE_MESSAGE();
}
}
int
main(int argc, char** argv) {
OptionsCont& oc = OptionsCont::getOptions();
oc.setApplicationDescription(TL("Builds vehicle routes for SUMO using detector values."));
oc.setApplicationName("dfrouter", "Eclipse SUMO dfrouter " VERSION_STRING);
int ret = 0;
RODFNet* net = nullptr;
RODFDetectorCon* detectors = nullptr;
RODFDetectorFlows* flows = nullptr;
try {
XMLSubSys::init();
RODFFrame::fillOptions();
OptionsIO::setArgs(argc, argv);
OptionsIO::getOptions();
if (oc.processMetaOptions(argc < 2)) {
SystemFrame::close();
return 0;
}
SystemFrame::checkOptions(oc);
XMLSubSys::setValidation(oc.getString("xml-validation"), oc.getString("xml-validation.net"), "never");
MsgHandler::initOutputOptions();
if (!RODFFrame::checkOptions()) {
throw ProcessError();
}
RandHelper::initRandGlobal();
ROLoader loader(oc, false, !oc.getBool("no-step-log"));
net = new RODFNet(oc.getBool("highway-mode"));
RODFEdgeBuilder builder;
loader.loadNet(*net, builder);
net->buildApproachList();
detectors = new RODFDetectorCon();
readDetectors(*detectors, oc, net);
flows = new RODFDetectorFlows(string2time(oc.getString("begin")), string2time(oc.getString("end")),
string2time(oc.getString("time-step")));
readDetectorFlows(*flows, oc, *detectors);
startComputation(net, *flows, *detectors, oc);
} catch (const ProcessError& e) {
if (std::string(e.what()) != std::string("Process Error") && std::string(e.what()) != std::string("")) {
WRITE_ERROR(e.what());
}
MsgHandler::getErrorInstance()->inform("Quitting (on error).", false);
ret = 1;
#ifndef _DEBUG
} catch (const std::exception& e) {
if (std::string(e.what()) != std::string("")) {
WRITE_ERROR(e.what());
}
MsgHandler::getErrorInstance()->inform("Quitting (on error).", false);
ret = 1;
} catch (...) {
MsgHandler::getErrorInstance()->inform("Quitting (on unknown error).", false);
ret = 1;
#endif
}
delete net;
delete flows;
delete detectors;
SystemFrame::close();
if (ret == 0) {
std::cout << "Success." << std::endl;
}
return ret;
}