52 : myDistricts(dc), myNumLoaded(0), myNumWritten(0), myNumDiscarded(0) {}
65 SUMOTime end,
const std::string& origin,
const std::string& destination,
66 const std::string& vehicleType,
const bool originIsEdge,
const bool destinationIsEdge) {
69 WRITE_WARNING(
"Missing origin '" + origin +
"' and destination '" + destination +
"' (" +
toString(vehicleNumber) +
" vehicles).");
74 }
else if (!originIsEdge &&
myDistricts.
get(origin) == 0 && vehicleNumber > 0) {
79 }
else if (!destinationIsEdge &&
myDistricts.
get(destination) == 0 && vehicleNumber > 0) {
80 WRITE_ERROR(
"Missing destination '" + destination +
"' (" +
toString(vehicleNumber) +
" vehicles).");
86 WRITE_ERROR(
"District '" + origin +
"' has no source.");
90 WRITE_ERROR(
"District '" + destination +
"' has no sink.");
110 const std::string& fromTaz,
const std::string& toTaz,
111 const std::string& vehicleType,
const bool originIsEdge,
const bool destinationIsEdge) {
118 std::vector<ODCell*>& odList =
myShortCut[std::make_pair(fromTaz, toTaz)];
120 for (std::vector<ODCell*>::const_reverse_iterator c = odList.rbegin(); c != odList.rend(); ++c) {
121 if ((*c)->begin <= depart && (*c)->end > depart && (*c)->vehicleType == vehicleType) {
126 if (cell ==
nullptr) {
128 const int intervalIdx = (int)(depart / interval);
129 if (
add(1., intervalIdx * interval, (intervalIdx + 1) * interval, fromTaz, toTaz, vehicleType, originIsEdge, destinationIsEdge)) {
131 odList.push_back(cell);
146 int& vehName, std::vector<ODVehicle>& into,
147 const bool uniform,
const bool differSourceSink,
148 const std::string& prefix) {
154 if (vehicles2insert == 0) {
158 const double offset = (double)(cell->
end - cell->
begin) / (double) vehicles2insert / (
double) 2.;
159 for (
int i = 0; i < vehicles2insert; ++i) {
172 }
while (canDiffer && differSourceSink && (veh.
to == veh.
from));
173 if (!canDiffer && differSourceSink && (veh.
to == veh.
from)) {
185 const ODCell*
const cell) {
191 if (oc.
isSet(
"departlane") && oc.
getString(
"departlane") !=
"default") {
194 if (oc.
isSet(
"departpos")) {
197 if (oc.
isSet(
"departspeed") && oc.
getString(
"departspeed") !=
"default") {
200 if (oc.
isSet(
"arrivallane")) {
203 if (oc.
isSet(
"arrivalpos")) {
206 if (oc.
isSet(
"arrivalspeed")) {
215 const bool differSourceSink,
const bool noVtype,
216 const std::string& prefix,
const bool stepLog,
217 bool pedestrians,
bool persontrips) {
221 std::map<std::pair<std::string, std::string>,
double> fractionLeft;
226 std::vector<ODCell*>::iterator next =
myContainer.begin();
227 std::vector<ODVehicle> vehicles;
230 for (
SUMOTime t = begin; t < end;) {
231 if (stepLog && t - lastOut >=
DELTA_T) {
232 std::cout <<
"Parsing time " +
time2string(t) <<
'\r';
236 bool changed =
false;
237 while (next !=
myContainer.end() && (*next)->begin <= t && (*next)->end > t) {
238 std::pair<std::string, std::string> odID = std::make_pair((*next)->origin, (*next)->destination);
240 if (fractionLeft.find(odID) != fractionLeft.end()) {
241 (*next)->vehicleNumber += fractionLeft[odID];
242 fractionLeft[odID] = 0;
245 const int oldSize = (int)vehicles.size();
246 const double fraction =
computeDeparts(*next, vehName, vehicles, uniform, differSourceSink, prefix);
247 if (oldSize != (
int)vehicles.size()) {
251 fractionLeft[odID] = fraction;
258 for (std::vector<ODVehicle>::reverse_iterator i = vehicles.rbegin(); i != vehicles.rend() && (*i).depart == t; ++i) {
269 }
else if (persontrips) {
285 while (vehicles.size() != 0 && vehicles.back().depart == t) {
288 if (!vehicles.empty()) {
289 t = vehicles.back().depart;
291 if (next !=
myContainer.end() && (t > (*next)->begin || vehicles.empty())) {
294 if (next ==
myContainer.end() && vehicles.empty()) {
304 const std::string& prefix,
305 bool asProbability,
bool pedestrians,
bool persontrips) {
313 const ODCell*
const c = *i;
314 if (c->
end > begin && c->
begin < end) {
316 if (probability <= 0) {
323 if (!asProbability) {
326 if (probability > 1) {
327 WRITE_WARNING(
"Flow density of " +
toString(probability) +
" vehicles per second, cannot be represented with a simple probability. Falling back to even spacing.");
340 }
else if (persontrips) {
343 if (!asProbability) {
346 if (probability > 1) {
347 WRITE_WARNING(
"Flow density of " +
toString(probability) +
" vehicles per second, cannot be represented with a simple probability. Falling back to even spacing.");
366 if (!asProbability) {
369 if (probability > 1) {
370 WRITE_WARNING(
"Flow density of " +
toString(probability) +
" vehicles per second, cannot be represented with a simple probability. Falling back to even spacing.");
389 const std::string line = lr.
readLine();
390 if (line[0] !=
'*') {
400 if (time.find(
'.') == std::string::npos) {
403 std::string hours = time.substr(0, time.find(
'.'));
404 std::string minutes = time.substr(time.find(
'.') + 1);
409 std::pair<SUMOTime, SUMOTime>
417 throw ProcessError(
"Begin time is larger than end time.");
419 return std::make_pair(begin, end);
421 throw ProcessError(
"Broken period definition '" + line +
"'.");
423 throw ProcessError(
"Broken period definition '" + line +
"'.");
442 std::string vehType,
bool matrixHasVehType) {
446 if (matrixHasVehType) {
454 std::pair<SUMOTime, SUMOTime> times =
readTime(lr);
465 std::vector<std::string> names;
466 while ((
int)names.size() != numDistricts) {
470 names.push_back(st2.
next());
475 for (std::vector<std::string>::iterator si = names.begin(); si != names.end(); ++si) {
476 std::vector<std::string>::iterator di = names.begin();
480 if (line.length() == 0) {
486 assert(di != names.end());
488 if (vehNumber != 0) {
489 add(vehNumber, begin, end, *si, *di, vehType);
491 if (di == names.end()) {
492 throw ProcessError(
"More entries than districts found.");
497 throw ProcessError(
"Not numeric vehicle number in line '" + line +
"'.");
502 }
while (di != names.end());
510 std::string vehType,
bool matrixHasVehType) {
514 if (matrixHasVehType) {
523 std::pair<SUMOTime, SUMOTime> times =
readTime(lr);
533 if (line.length() == 0) {
537 if (st2.
size() == 0) {
541 std::string sourceD = st2.
next();
542 std::string destD = st2.
next();
544 if (vehNumber != 0) {
545 add(vehNumber, begin, end, sourceD, destD, vehType);
548 throw ProcessError(
"Missing at least one information in line '" + line +
"'.");
550 throw ProcessError(
"Not numeric vehicle number in line '" + line +
"'.");
578 const std::vector<double>& times = ps.
getVals();
579 for (
int i = 0; i < (int)times.size() - 1; ++i) {
587 newCells.push_back(ncell);
596 for (std::vector<ODCell*>::iterator i = oldCells.begin(); i != oldCells.end(); ++i) {
597 std::vector<ODCell*> newCells;
599 copy(newCells.begin(), newCells.end(), back_inserter(
myContainer));
607 std::vector<std::string> files = oc.
getStringVector(
"od-matrix-files");
608 for (std::vector<std::string>::iterator i = files.begin(); i != files.end(); ++i) {
615 if (type.find(
';') != std::string::npos) {
616 type = type.substr(0, type.find(
';'));
619 if (type.length() > 1 && type[1] ==
'V') {
621 if (type.find(
'N') != std::string::npos) {
622 throw ProcessError(
"'" + *i +
"' does not contain the needed information about the time described.");
625 }
else if (type.length() > 1 && type[1] ==
'O') {
627 if (type.find(
'N') != std::string::npos) {
628 throw ProcessError(
"'" + *i +
"' does not contain the needed information about the time described.");
632 throw ProcessError(
"'" + *i +
"' uses an unknown matrix type '" + type +
"'.");
635 std::vector<std::string> amitranFiles = oc.
getStringVector(
"od-amitran-files");
636 for (std::vector<std::string>::iterator i = amitranFiles.begin(); i != amitranFiles.end(); ++i) {
638 throw ProcessError(
"Could not access matrix file '" + *i +
"' to load.");
653 std::vector<std::string> routeFiles = oc.
getStringVector(
"route-files");
654 for (std::vector<std::string>::iterator i = routeFiles.begin(); i != routeFiles.end(); ++i) {
656 throw ProcessError(
"Could not access route file '" + *i +
"' to load.");
671 if (timelineDayInHours) {
672 if (def.size() != 24) {
673 throw ProcessError(
"Assuming 24 entries for a day timeline, but got " +
toString(def.size()) +
".");
675 for (
int chour = 0; chour < 24; ++chour) {
678 result.
add(24 * 3600., 0.);
680 for (
int i = 0; i < (int)def.size(); i++) {
682 if (st2.
size() != 2) {
683 throw ProcessError(
"Broken time line definition: missing a value in '" + def[i] +
"'.");
void write(SUMOTime begin, const SUMOTime end, OutputDevice &dev, const bool uniform, const bool differSourceSink, const bool noVtype, const std::string &prefix, const bool stepLog, bool pedestrians, bool persontrips)
Writes the vehicles stored in the matrix assigning the sources and sinks.
void writeDefaultAttrs(OutputDevice &dev, const bool noVtype, const ODCell *const cell)
Helper function for flow and trip output writing the depart and arrival attributes.
OutputDevice & writeAttr(const SumoXMLAttr attr, const T &val)
writes a named attribute
Used for sorting the cells by the begin time they describe.
std::string next()
returns the next substring when it exists. Otherwise the behaviour is undefined
static bool isReadable(std::string path)
Checks whether the given file is readable.
a flow definitio nusing a from-to edges instead of a route (used by router)
bool readLine(LineHandler &lh)
Reads a single (the next) line from the file and reports it to the given LineHandler.
static const int WHITECHARS
identifier for splitting the given string at all whitespace characters
std::string getFileName() const
Returns the name of the used file.
Retrieves a file linewise and reports the lines to a handler.
std::string getRandomSinkFromDistrict(const std::string &name) const
Returns the id of a random sink from the named district.
const ODDistrictCont & myDistricts
The districts to retrieve sources/sinks from.
T get(const std::string &id) const
Retrieves an item.
bool good() const
Returns the information whether the stream is readable.
static double rand(std::mt19937 *rng=0)
Returns a random real number in [0, 1)
An internal representation of a single vehicle.
int sourceNumber() const
Returns the number of sources.
std::string time2string(SUMOTime t)
weights: time range begin
void setPrecision(int precision=gPrecision)
Sets the precison or resets it to default.
const std::vector< T > & getVals() const
Returns the members of the distribution.
bool hasNext()
returns the information whether further substrings exist
SAX-handler base for SUMO-files.
std::string from
The edge the vehicles shall start at.
static bool runParser(GenericSAXHandler &handler, const std::string &file, const bool isNet=false)
Runs the given handler on the given file; returns if everything's ok.
SUMOTime parseSingleTime(const std::string &time)
double vehicleNumber
The number of vehicles.
#define WRITE_WARNING(msg)
static OptionsCont & getOptions()
Retrieves the options.
void loadMatrix(OptionsCont &oc)
read a matrix in one of several formats
double computeDeparts(ODCell *cell, int &vehName, std::vector< ODVehicle > &into, const bool uniform, const bool differSourceSink, const std::string &prefix)
Computes the vehicle departs stored in the given cell and saves them in "into".
#define PROGRESS_FAILED_MESSAGE()
bool isSet(const std::string &name, bool failOnNonExistant=true) const
Returns the information whether the named option is set.
double myNumDiscarded
Number of discarded vehicles.
A single O/D-matrix cell.
int size() const
returns the number of existing substrings
double myNumWritten
Number of written vehicles.
std::string toString(const T &t, std::streamsize accuracy=gPrecision)
const std::vector< double > & getProbs() const
Returns the probabilities assigned to the members of the distribution.
std::string origin
Name of the origin district.
static double toDouble(const std::string &sData)
converts a string into the double value described by it by calling the char-type converter ...
bool destinationIsEdge
the destination "district" is an edge id
std::string getString(const std::string &name) const
Returns the string-value of the named option (only for Option_String)
bool add(double vehicleNumber, SUMOTime begin, SUMOTime end, const std::string &origin, const std::string &destination, const std::string &vehicleType, const bool originIsEdge=false, const bool destinationIsEdge=false)
Builds a single cell from the given values, verifying them.
ODCell * cell
The cell of the ODMatrix which generated the vehicle.
void loadRoutes(OptionsCont &oc, SUMOSAXHandler &handler)
read SUMO routes
SUMOTime string2time(const std::string &r)
A container for districts.
std::vector< std::string > getStringVector(const std::string &name) const
Returns the list of string-vector-value of the named option (only for Option_String) ...
#define PROGRESS_BEGIN_MESSAGE(msg)
Used for sorting vehicles by their departure (latest first)
double readFactor(LineReader &lr, double scale)
std::map< SUMOTime, std::vector< std::string > > departures
mapping of departure times to departing vehicles, if already fixed
std::map< const std::pair< const std::string, const std::string >, std::vector< ODCell * > > myShortCut
The loaded cells indexed by origin and destination.
static int toInt(const std::string &sData)
converts a string into the integer value described by it by calling the char-type converter...
std::string getRandomSourceFromDistrict(const std::string &name) const
Returns the id of a random source from the named district.
std::vector< ODCell * > myContainer
The loaded cells.
SUMOTime begin
The begin time this cell describes.
double getFloat(const std::string &name) const
Returns the double-value of the named option (only for Option_Float)
double getNumLoaded() const
Returns the number of loaded vehicles.
double getNumWritten() const
Returns the number of written vehicles.
std::pair< SUMOTime, SUMOTime > readTime(LineReader &lr)
std::string getNextNonCommentLine(LineReader &lr)
SUMOTime depart
The departure time of the vehicle.
bool originIsEdge
the origin "district" is an edge id
static std::string prune(const std::string &str)
Removes trailing and leading whitechars.
bool hasMore() const
Returns whether another line may be read (the file was not read completely)
A storage for options typed value containers)
An XML-Handler for districts.
void applyCurve(const Distribution_Points &ps)
Splits the stored cells dividing them on the given time line.
double getOverallProb() const
Return the sum of the probabilites assigned to the members.
void readV(LineReader &lr, double scale, std::string vehType, bool matrixHasVehType)
read a VISUM-matrix with the V Format
std::string vehicleType
Name of the vehicle type.
void readO(LineReader &lr, double scale, std::string vehType, bool matrixHasVehType)
read a VISUM-matrix with the O Format
Static storage of an output device and its base (abstract) implementation.
bool closeTag(const std::string &comment="")
Closes the most recently opened tag and optionally adds a comment.
std::string destination
Name of the destination district.
double getNumDiscarded() const
Returns the number of discarded vehicles.
a single trip definition (used by router)
SUMOTime end
The end time this cell describes.
#define PROGRESS_DONE_MESSAGE()
std::string to
The edge the vehicles shall end at.
bool add(T val, double prob, bool checkDuplicates=true)
Adds a value with an assigned probability to the distribution.
ODMatrix(const ODDistrictCont &dc)
Constructor.
std::set< std::string > myMissingDistricts
The missing districts already warned about.
std::string id
The id of the vehicle.
OutputDevice & openTag(const std::string &xmlElement)
Opens an XML tag.
double myNumLoaded
Number of loaded vehicles.
int sinkNumber() const
Returns the number of sinks.
void writeFlows(const SUMOTime begin, const SUMOTime end, OutputDevice &dev, const bool noVtype, const std::string &prefix, bool asProbability=false, bool pedestrians=false, bool persontrips=false)
Writes the flows stored in the matrix.
Distribution_Points parseTimeLine(const std::vector< std::string > &def, bool timelineDayInHours)
split the given timeline