52 : myDistricts(dc), myNumLoaded(0), myNumWritten(0), myNumDiscarded(0), myBegin(-1), myEnd(-1) {}
57 for (
RORoute*
const r : cell->pathsVector) {
67 ODMatrix::add(
double vehicleNumber,
const std::pair<SUMOTime, SUMOTime>& beginEnd,
68 const std::string& origin,
const std::string& destination,
69 const std::string& vehicleType,
const bool originIsEdge,
const bool destinationIsEdge) {
72 WRITE_WARNING(
"Missing origin '" + origin +
"' and destination '" + destination +
"' (" +
toString(vehicleNumber) +
" vehicles).");
77 }
else if (!originIsEdge &&
myDistricts.
get(origin) == 0 && vehicleNumber > 0) {
82 }
else if (!destinationIsEdge &&
myDistricts.
get(destination) == 0 && vehicleNumber > 0) {
83 WRITE_ERROR(
"Missing destination '" + destination +
"' (" +
toString(vehicleNumber) +
" vehicles).");
89 WRITE_ERROR(
"District '" + origin +
"' has no source.");
93 WRITE_ERROR(
"District '" + destination +
"' has no sink.");
98 cell->
begin = beginEnd.first;
99 cell->
end = beginEnd.second;
119 const std::string& fromTaz,
const std::string& toTaz,
120 const std::string& vehicleType,
const bool originIsEdge,
const bool destinationIsEdge) {
127 std::vector<ODCell*>& odList =
myShortCut[std::make_pair(fromTaz, toTaz)];
129 for (std::vector<ODCell*>::const_reverse_iterator c = odList.rbegin(); c != odList.rend(); ++c) {
130 if ((*c)->begin <= depart && (*c)->end > depart && (*c)->vehicleType == vehicleType) {
135 if (cell ==
nullptr) {
137 const int intervalIdx = (int)(depart / interval);
138 if (
add(1., std::make_pair(intervalIdx * interval, (intervalIdx + 1) * interval),
139 fromTaz, toTaz, vehicleType, originIsEdge, destinationIsEdge)) {
141 odList.push_back(cell);
156 int& vehName, std::vector<ODVehicle>& into,
157 const bool uniform,
const bool differSourceSink,
158 const std::string& prefix) {
164 if (vehicles2insert == 0) {
168 const double offset = (double)(cell->
end - cell->
begin) / (double) vehicles2insert / (
double) 2.;
169 for (
int i = 0; i < vehicles2insert; ++i) {
182 }
while (canDiffer && differSourceSink && (veh.
to == veh.
from));
183 if (!canDiffer && differSourceSink && (veh.
to == veh.
from)) {
195 const ODCell*
const cell) {
201 if (oc.
isSet(
"departlane") && oc.
getString(
"departlane") !=
"default") {
204 if (oc.
isSet(
"departpos")) {
207 if (oc.
isSet(
"departspeed") && oc.
getString(
"departspeed") !=
"default") {
210 if (oc.
isSet(
"arrivallane")) {
213 if (oc.
isSet(
"arrivalpos")) {
216 if (oc.
isSet(
"arrivalspeed")) {
225 const bool differSourceSink,
const bool noVtype,
226 const std::string& prefix,
const bool stepLog,
227 bool pedestrians,
bool persontrips,
228 const std::string& modes) {
232 std::map<std::pair<std::string, std::string>,
double> fractionLeft;
237 std::vector<ODCell*>::iterator next =
myContainer.begin();
238 std::vector<ODVehicle> vehicles;
242 std::string personDepartPos = oc.
isSet(
"departpos") ? oc.
getString(
"departpos") :
"random";
243 std::string personArrivalPos = oc.
isSet(
"arrivalpos") ? oc.
getString(
"arrivalpos") :
"random";
248 for (
SUMOTime t = begin; t < end;) {
249 if (stepLog && t - lastOut >=
DELTA_T) {
250 std::cout <<
"Parsing time " +
time2string(t) <<
'\r';
254 bool changed =
false;
255 while (next !=
myContainer.end() && (*next)->begin <= t && (*next)->end > t) {
256 std::pair<std::string, std::string> odID = std::make_pair((*next)->origin, (*next)->destination);
258 if (fractionLeft.find(odID) != fractionLeft.end()) {
259 (*next)->vehicleNumber += fractionLeft[odID];
260 fractionLeft[odID] = 0;
263 const int oldSize = (int)vehicles.size();
264 const double fraction =
computeDeparts(*next, vehName, vehicles, uniform, differSourceSink, prefix);
265 if (oldSize != (
int)vehicles.size()) {
269 fractionLeft[odID] = fraction;
277 for (std::vector<ODVehicle>::reverse_iterator i = vehicles.rbegin(); i != vehicles.rend() && (*i).depart == t; ++i) {
290 }
else if (persontrips) {
312 while (vehicles.size() != 0 && vehicles.back().depart == t) {
315 if (!vehicles.empty()) {
316 t = vehicles.back().depart;
318 if (next !=
myContainer.end() && (t > (*next)->begin || vehicles.empty())) {
321 if (next ==
myContainer.end() && vehicles.empty()) {
331 const std::string& prefix,
332 bool asProbability,
bool pedestrians,
bool persontrips,
333 const std::string& modes) {
341 const ODCell*
const c = *i;
342 if (c->
end > begin && c->
begin < end) {
344 if (probability <= 0) {
351 if (!asProbability) {
354 if (probability > 1) {
355 WRITE_WARNING(
"Flow density of " +
toString(probability) +
" vehicles per second, cannot be represented with a simple probability. Falling back to even spacing.");
368 }
else if (persontrips) {
371 if (!asProbability) {
374 if (probability > 1) {
375 WRITE_WARNING(
"Flow density of " +
toString(probability) +
" vehicles per second, cannot be represented with a simple probability. Falling back to even spacing.");
397 if (!asProbability) {
400 if (probability > 1) {
401 WRITE_WARNING(
"Flow density of " +
toString(probability) +
" vehicles per second, cannot be represented with a simple probability. Falling back to even spacing.");
420 const std::string line = lr.
readLine();
421 if (line[0] !=
'*') {
431 if (time.find(
'.') == std::string::npos) {
434 const std::string hours = time.substr(0, time.find(
'.'));
435 const std::string minutes = time.substr(time.find(
'.') + 1);
440 std::pair<SUMOTime, SUMOTime>
450 return std::make_pair(begin, end);
452 throw ProcessError(
"Broken period definition '" + line +
"'.");
454 throw ProcessError(
"Broken period definition '" + line +
"' (" + e.what() +
").");
473 std::string vehType,
bool matrixHasVehType) {
477 if (matrixHasVehType) {
484 const std::pair<SUMOTime, SUMOTime> beginEnd =
readTime(lr);
491 std::vector<std::string> names;
492 while ((
int)names.size() != numDistricts && lr.
hasMore()) {
496 names.push_back(st2.
next());
504 for (std::vector<std::string>::iterator si = names.begin(); si != names.end(); ++si) {
505 std::vector<std::string>::iterator di = names.begin();
510 throw ProcessError(
"Missing line for district " + (*si) +
".");
512 if (line.length() == 0) {
518 assert(di != names.end());
520 if (vehNumber != 0) {
521 add(vehNumber, beginEnd, *si, *di, vehType);
523 if (di == names.end()) {
524 throw ProcessError(
"More entries than districts found.");
529 throw ProcessError(
"Not numeric vehicle number in line '" + line +
"'.");
534 }
while (di != names.end());
542 std::string vehType,
bool matrixHasVehType) {
546 if (matrixHasVehType) {
554 const std::pair<SUMOTime, SUMOTime> beginEnd =
readTime(lr);
560 if (line.length() == 0) {
564 if (st2.
size() == 0) {
568 std::string sourceD = st2.
next();
569 std::string destD = st2.
next();
571 if (vehNumber != 0) {
572 add(vehNumber, beginEnd, sourceD, destD, vehType);
575 throw ProcessError(
"Missing at least one information in line '" + line +
"'.");
577 throw ProcessError(
"Not numeric vehicle number in line '" + line +
"'.");
605 const std::vector<double>& times = ps.
getVals();
606 for (
int i = 0; i < (int)times.size() - 1; ++i) {
614 newCells.push_back(ncell);
623 for (std::vector<ODCell*>::iterator i = oldCells.begin(); i != oldCells.end(); ++i) {
624 std::vector<ODCell*> newCells;
626 copy(newCells.begin(), newCells.end(), back_inserter(
myContainer));
634 std::vector<std::string> files = oc.
getStringVector(
"od-matrix-files");
635 for (std::vector<std::string>::iterator i = files.begin(); i != files.end(); ++i) {
642 if (type.find(
';') != std::string::npos) {
643 type = type.substr(0, type.find(
';'));
646 if (type.length() > 1 && type[1] ==
'V') {
648 if (type.find(
'N') != std::string::npos) {
649 throw ProcessError(
"'" + *i +
"' does not contain the needed information about the time described.");
652 }
else if (type.length() > 1 && type[1] ==
'O') {
654 if (type.find(
'N') != std::string::npos) {
655 throw ProcessError(
"'" + *i +
"' does not contain the needed information about the time described.");
659 throw ProcessError(
"'" + *i +
"' uses an unknown matrix type '" + type +
"'.");
662 std::vector<std::string> amitranFiles = oc.
getStringVector(
"od-amitran-files");
663 for (std::vector<std::string>::iterator i = amitranFiles.begin(); i != amitranFiles.end(); ++i) {
665 throw ProcessError(
"Could not access matrix file '" + *i +
"' to load.");
678 throw ProcessError(
"Could not access matrix file '" + file +
"' to load.");
682 std::vector<SAXWeightsHandler::ToRetrieveDefinition*> retrieverDefs;
695 double val,
double beg,
double end) {
702 std::vector<std::string> routeFiles = oc.
getStringVector(
"route-files");
703 for (std::vector<std::string>::iterator i = routeFiles.begin(); i != routeFiles.end(); ++i) {
705 throw ProcessError(
"Could not access route file '" + *i +
"' to load.");
720 if (timelineDayInHours) {
721 if (def.size() != 24) {
722 throw ProcessError(
"Assuming 24 entries for a day timeline, but got " +
toString(def.size()) +
".");
724 for (
int chour = 0; chour < 24; ++chour) {
727 result.
add(24 * 3600., 0.);
729 for (
int i = 0; i < (int)def.size(); i++) {
731 if (st2.
size() != 2) {
732 throw ProcessError(
"Broken time line definition: missing a value in '" + def[i] +
"'.");
#define WRITE_WARNING(msg)
#define PROGRESS_DONE_MESSAGE()
#define PROGRESS_FAILED_MESSAGE()
#define PROGRESS_BEGIN_MESSAGE(msg)
std::string time2string(SUMOTime t)
convert SUMOTime to string
SUMOTime string2time(const std::string &r)
convert string to SUMOTime
@ SUMO_TAG_FLOW
a flow definitio nusing a from-to edges instead of a route (used by router)
@ SUMO_TAG_TRIP
a single trip definition (used by router)
SumoXMLAttr
Numbers representing SUMO-XML - attributes.
@ SUMO_ATTR_BEGIN
weights: time range begin
@ SUMO_ATTR_END
weights: time range end
std::string toString(const T &t, std::streamsize accuracy=gPrecision)
static bool isReadable(std::string path)
Checks whether the given file is readable.
Retrieves a file linewise and reports the lines to a handler.
bool good() const
Returns the information whether the stream is readable.
bool readLine(LineHandler &lh)
Reads a single (the next) line from the file and reports it to the given LineHandler.
bool hasMore() const
Returns whether another line may be read (the file was not read completely)
std::string getFileName() const
Returns the name of the used file.
T get(const std::string &id) const
Retrieves an item.
An XML-Handler for districts.
A container for districts.
std::string getRandomSourceFromDistrict(const std::string &name) const
Returns the id of a random source from the named district.
std::string getRandomSinkFromDistrict(const std::string &name) const
Returns the id of a random sink from the named district.
int sourceNumber() const
Returns the number of sources.
int sinkNumber() const
Returns the number of sinks.
Used for sorting the cells by the begin time they describe.
Used for sorting vehicles by their departure (latest first)
double getNumLoaded() const
Returns the number of loaded vehicles.
void readV(LineReader &lr, double scale, std::string vehType, bool matrixHasVehType)
read a VISUM-matrix with the V Format
bool add(double vehicleNumber, const std::pair< SUMOTime, SUMOTime > &beginEnd, 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.
double readFactor(LineReader &lr, double scale)
ODMatrix(const ODDistrictCont &dc)
Constructor.
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".
void addTazRelWeight(const std::string intervalID, const std::string &from, const std::string &to, double val, double beg, double end)
SUMOTime myBegin
parsed time bounds
SUMOTime parseSingleTime(const std::string &time)
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, const std::string &modes="")
Writes the flows stored in the matrix.
void applyCurve(const Distribution_Points &ps)
Splits the stored cells dividing them on the given time line.
std::map< const std::pair< const std::string, const std::string >, std::vector< ODCell * > > myShortCut
The loaded cells indexed by origin and destination.
std::pair< SUMOTime, SUMOTime > readTime(LineReader &lr)
void readO(LineReader &lr, double scale, std::string vehType, bool matrixHasVehType)
read a VISUM-matrix with the O Format
std::set< std::string > myMissingDistricts
The missing districts already warned about.
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, const std::string &modes)
Writes the vehicles stored in the matrix assigning the sources and sinks.
const ODDistrictCont & myDistricts
The districts to retrieve sources/sinks from.
Distribution_Points parseTimeLine(const std::vector< std::string > &def, bool timelineDayInHours)
split the given timeline
void writeDefaultAttrs(OutputDevice &dev, const bool noVtype, const ODCell *const cell)
Helper function for flow and trip output writing the depart and arrival attributes.
double myNumLoaded
Number of loaded vehicles.
double myNumWritten
Number of written vehicles.
void loadMatrix(OptionsCont &oc)
read a matrix in one of several formats
void loadRoutes(OptionsCont &oc, SUMOSAXHandler &handler)
read SUMO routes
double getNumWritten() const
Returns the number of written vehicles.
std::vector< ODCell * > myContainer
The loaded cells.
double myNumDiscarded
Number of discarded vehicles.
double getNumDiscarded() const
Returns the number of discarded vehicles.
std::string myVType
user-defined vType
std::string getNextNonCommentLine(LineReader &lr)
A storage for options typed value containers)
bool isSet(const std::string &name, bool failOnNonExistant=true) const
Returns the information whether the named option is set.
double getFloat(const std::string &name) const
Returns the double-value of the named option (only for Option_Float)
std::string getString(const std::string &name) const
Returns the string-value of the named option (only for Option_String)
bool getBool(const std::string &name) const
Returns the boolean-value of the named option (only for Option_Bool)
const StringVector & getStringVector(const std::string &name) const
Returns the list of string-value of the named option (only for Option_StringVector)
static OptionsCont & getOptions()
Retrieves the options.
Static storage of an output device and its base (abstract) implementation.
OutputDevice & openTag(const std::string &xmlElement)
Opens an XML tag.
OutputDevice & writeAttr(const SumoXMLAttr attr, const T &val)
writes a named attribute
bool closeTag(const std::string &comment="")
Closes the most recently opened tag and optionally adds a comment.
void setPrecision(int precision=gPrecision)
Sets the precision or resets it to default.
A complete router's route.
static double rand(SumoRNG *rng=nullptr)
Returns a random real number in [0, 1)
double getOverallProb() const
Return the sum of the probabilites assigned to the members.
const std::vector< double > & getProbs() const
Returns the probabilities assigned to the members of the distribution.
const std::vector< T > & getVals() const
Returns the members of the distribution.
bool add(T val, double prob, bool checkDuplicates=true)
Adds a value with an assigned probability to the distribution.
Complete definition about what shall be retrieved and where to store it.
An XML-handler for network weights.
SAX-handler base for SUMO-files.
int size() const
returns the number of existing substrings
static const int WHITECHARS
identifier for splitting the given string at all whitespace characters
bool hasNext()
returns the information whether further substrings exist
std::string next()
returns the next substring when it exists. Otherwise the behaviour is undefined
static double toDouble(const std::string &sData)
converts a string into the double value described by it by calling the char-type converter
static std::string prune(const std::string &str)
Removes trailing and leading whitechars.
static int toInt(const std::string &sData)
converts a string into the integer value described by it by calling the char-type converter,...
static bool runParser(GenericSAXHandler &handler, const std::string &file, const bool isNet=false, const bool isRoute=false)
Runs the given handler on the given file; returns if everything's ok.
A single O/D-matrix cell.
std::string destination
Name of the destination district.
std::map< SUMOTime, std::vector< std::string > > departures
mapping of departure times to departing vehicles, if already fixed
std::string vehicleType
Name of the vehicle type.
std::string origin
Name of the origin district.
double vehicleNumber
The number of vehicles.
bool originIsEdge
the origin "district" is an edge id
SUMOTime end
The end time this cell describes.
SUMOTime begin
The begin time this cell describes.
bool destinationIsEdge
the destination "district" is an edge id
An internal representation of a single vehicle.
SUMOTime depart
The departure time of the vehicle.
std::string from
The edge the vehicles shall start at.
ODCell * cell
The cell of the ODMatrix which generated the vehicle.
std::string to
The edge the vehicles shall end at.
std::string id
The id of the vehicle.