Eclipse SUMO - Simulation of Urban MObility
Loading...
Searching...
No Matches
ODMatrix.cpp
Go to the documentation of this file.
1/****************************************************************************/
2// Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo
3// Copyright (C) 2006-2023 German Aerospace Center (DLR) and others.
4// This program and the accompanying materials are made available under the
5// terms of the Eclipse Public License 2.0 which is available at
6// https://www.eclipse.org/legal/epl-2.0/
7// This Source Code may also be made available under the following Secondary
8// Licenses when the conditions for such availability set forth in the Eclipse
9// Public License 2.0 are satisfied: GNU General Public License, version 2
10// or later which is available at
11// https://www.gnu.org/licenses/old-licenses/gpl-2.0-standalone.html
12// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later
13/****************************************************************************/
21// An O/D (origin/destination) matrix
22/****************************************************************************/
23#include <config.h>
24
25#include <iostream>
26#include <algorithm>
27#include <list>
28#include <iterator>
42#include <utils/xml/XMLSubSys.h>
43#include <router/RORoute.h>
44#include "ODAmitranHandler.h"
45#include "ODMatrix.h"
46
47
48// ===========================================================================
49// method definitions
50// ===========================================================================
51ODMatrix::ODMatrix(const ODDistrictCont& dc, double scale) :
52 myDistricts(dc),
53 myNumLoaded(0),
54 myNumWritten(0),
55 myNumDiscarded(0),
56 myBegin(-1),
57 myEnd(-1),
58 myScale(scale)
59{}
60
61
63 for (ODCell* const cell : myContainer) {
64 for (RORoute* const r : cell->pathsVector) {
65 delete r;
66 }
67 delete cell;
68 }
69 myContainer.clear();
70}
71
72
73bool
74ODMatrix::add(double vehicleNumber, const std::pair<SUMOTime, SUMOTime>& beginEnd,
75 const std::string& origin, const std::string& destination,
76 const std::string& vehicleType, const bool originIsEdge, const bool destinationIsEdge,
77 bool noScaling) {
78 myNumLoaded += vehicleNumber;
79 if (!originIsEdge && !destinationIsEdge && myDistricts.get(origin) == nullptr && myDistricts.get(destination) == nullptr) {
80 WRITE_WARNINGF(TL("Missing origin '%' and destination '%' (% vehicles)."), origin, destination, toString(vehicleNumber));
81 myNumDiscarded += vehicleNumber;
82 myMissingDistricts.insert(origin);
83 myMissingDistricts.insert(destination);
84 return false;
85 } else if (!originIsEdge && myDistricts.get(origin) == 0 && vehicleNumber > 0) {
86 WRITE_ERRORF(TL("Missing origin '%' (% vehicles)."), origin, toString(vehicleNumber));
87 myNumDiscarded += vehicleNumber;
88 myMissingDistricts.insert(origin);
89 return false;
90 } else if (!destinationIsEdge && myDistricts.get(destination) == 0 && vehicleNumber > 0) {
91 WRITE_ERRORF(TL("Missing destination '%' (% vehicles)."), destination, toString(vehicleNumber));
92 myNumDiscarded += vehicleNumber;
93 myMissingDistricts.insert(destination);
94 return false;
95 }
96 if (!originIsEdge && myDistricts.get(origin)->sourceNumber() == 0) {
97 WRITE_ERRORF(TL("District '%' has no source."), origin);
98 myNumDiscarded += vehicleNumber;
99 return false;
100 } else if (!destinationIsEdge && myDistricts.get(destination)->sinkNumber() == 0) {
101 WRITE_ERRORF(TL("District '%' has no sink."), destination);
102 myNumDiscarded += vehicleNumber;
103 return false;
104 }
105 ODCell* cell = new ODCell();
106 cell->begin = beginEnd.first;
107 cell->end = beginEnd.second;
108 cell->origin = origin;
109 cell->destination = destination;
110 cell->vehicleType = vehicleType;
111 cell->vehicleNumber = vehicleNumber * (noScaling ? 1 : myScale);
112 cell->originIsEdge = originIsEdge;
113 cell->destinationIsEdge = destinationIsEdge;
114 myContainer.push_back(cell);
115 if (myBegin == -1 || cell->begin < myBegin) {
116 myBegin = cell->begin;
117 }
118 if (cell->end > myEnd) {
119 myEnd = cell->end;
120 }
121 return true;
122}
123
124
125bool
126ODMatrix::add(const std::string& id, const SUMOTime depart,
127 const std::string& fromTaz, const std::string& toTaz,
128 const std::string& vehicleType, const bool originIsEdge, const bool destinationIsEdge) {
129 if (myMissingDistricts.count(fromTaz) > 0 || myMissingDistricts.count(toTaz) > 0) {
130 myNumLoaded += 1.;
131 myNumDiscarded += 1.;
132 return false;
133 }
134 // we start looking from the end because there is a high probability that the input is sorted by time
135 std::vector<ODCell*>& odList = myShortCut[std::make_pair(fromTaz, toTaz)];
136 ODCell* cell = nullptr;
137 for (std::vector<ODCell*>::const_reverse_iterator c = odList.rbegin(); c != odList.rend(); ++c) {
138 if ((*c)->begin <= depart && (*c)->end > depart && (*c)->vehicleType == vehicleType) {
139 cell = *c;
140 break;
141 }
142 }
143 if (cell == nullptr) {
144 const SUMOTime interval = string2time(OptionsCont::getOptions().getString("aggregation-interval"));
145 const int intervalIdx = (int)(depart / interval);
146 // single vehicles are already scaled
147 if (add(1., std::make_pair(intervalIdx * interval, (intervalIdx + 1) * interval),
148 fromTaz, toTaz, vehicleType, originIsEdge, destinationIsEdge, true)) {
149 cell = myContainer.back();
150 odList.push_back(cell);
151 } else {
152 return false;
153 }
154 } else {
155 myNumLoaded += 1.;
156 cell->vehicleNumber += 1.;
157 }
158 cell->departures[depart].push_back(id);
159 return true;
160}
161
162
163double
165 int& vehName, std::vector<ODVehicle>& into,
166 const bool uniform, const bool differSourceSink,
167 const std::string& prefix) {
168 int vehicles2insert = (int) cell->vehicleNumber;
169 // compute whether the fraction forces an additional vehicle insertion
170 if (RandHelper::rand() < cell->vehicleNumber - (double)vehicles2insert) {
171 vehicles2insert++;
172 }
173 if (vehicles2insert == 0) {
174 return cell->vehicleNumber;
175 }
176
177 const double offset = (double)(cell->end - cell->begin) / (double) vehicles2insert / (double) 2.;
178 for (int i = 0; i < vehicles2insert; ++i) {
179 ODVehicle veh;
180 veh.id = prefix + toString(vehName++);
181
182 if (uniform) {
183 veh.depart = cell->begin + (SUMOTime)(offset + ((double)(cell->end - cell->begin) * (double) i / (double) vehicles2insert));
184 } else {
185 veh.depart = (SUMOTime)RandHelper::rand(cell->begin, cell->end);
186 }
187 const bool canDiffer = myDistricts.get(cell->origin)->sourceNumber() > 1 || myDistricts.get(cell->destination)->sinkNumber() > 1;
188 do {
191 } while (canDiffer && differSourceSink && (veh.to == veh.from));
192 if (!canDiffer && differSourceSink && (veh.to == veh.from)) {
193 WRITE_WARNINGF(TL("Cannot find different source and sink edge for origin '%' and destination '%'."), cell->origin, cell->destination);
194 }
195 veh.cell = cell;
196 into.push_back(veh);
197 }
198 return cell->vehicleNumber - vehicles2insert;
199}
200
201
202void
204 const ODCell* const cell) {
206 if (!noVtype && cell->vehicleType != "") {
208 }
210 if (oc.isSet("departlane") && oc.getString("departlane") != "default") {
211 dev.writeAttr(SUMO_ATTR_DEPARTLANE, oc.getString("departlane"));
212 }
213 if (oc.isSet("departpos")) {
214 dev.writeAttr(SUMO_ATTR_DEPARTPOS, oc.getString("departpos"));
215 }
216 if (oc.isSet("departspeed") && oc.getString("departspeed") != "default") {
217 dev.writeAttr(SUMO_ATTR_DEPARTSPEED, oc.getString("departspeed"));
218 }
219 if (oc.isSet("arrivallane")) {
220 dev.writeAttr(SUMO_ATTR_ARRIVALLANE, oc.getString("arrivallane"));
221 }
222 if (oc.isSet("arrivalpos")) {
223 dev.writeAttr(SUMO_ATTR_ARRIVALPOS, oc.getString("arrivalpos"));
224 }
225 if (oc.isSet("arrivalspeed")) {
226 dev.writeAttr(SUMO_ATTR_ARRIVALSPEED, oc.getString("arrivalspeed"));
227 }
228}
229
230
231void
233 OutputDevice& dev, const bool uniform,
234 const bool differSourceSink, const bool noVtype,
235 const std::string& prefix, const bool stepLog,
236 bool pedestrians, bool persontrips,
237 const std::string& modes) {
238 if (myContainer.size() == 0) {
239 return;
240 }
241 std::map<std::pair<std::string, std::string>, double> fractionLeft;
242 int vehName = 0;
244 // recheck begin time
245 begin = MAX2(begin, myContainer.front()->begin);
246 std::vector<ODCell*>::iterator next = myContainer.begin();
247 std::vector<ODVehicle> vehicles;
248 SUMOTime lastOut = -DELTA_T;
249
251 std::string personDepartPos = oc.isSet("departpos") ? oc.getString("departpos") : "random";
252 std::string personArrivalPos = oc.isSet("arrivalpos") ? oc.getString("arrivalpos") : "random";
253 SumoXMLAttr fromAttr = oc.getBool("junctions") ? SUMO_ATTR_FROMJUNCTION : SUMO_ATTR_FROM;
254 SumoXMLAttr toAttr = oc.getBool("junctions") ? SUMO_ATTR_TOJUNCTION : SUMO_ATTR_TO;
255
256 // go through the time steps
257 for (SUMOTime t = begin; t < end;) {
258 if (stepLog && t - lastOut >= DELTA_T) {
259 std::cout << "Parsing time " + time2string(t) << '\r';
260 lastOut = t;
261 }
262 // recheck whether a new cell got valid
263 bool changed = false;
264 while (next != myContainer.end() && (*next)->begin <= t && (*next)->end > t) {
265 std::pair<std::string, std::string> odID = std::make_pair((*next)->origin, (*next)->destination);
266 // check whether the current cell must be extended by the last fraction
267 if (fractionLeft.find(odID) != fractionLeft.end()) {
268 (*next)->vehicleNumber += fractionLeft[odID];
269 fractionLeft[odID] = 0;
270 }
271 // get the new departures (into tmp)
272 const int oldSize = (int)vehicles.size();
273 const double fraction = computeDeparts(*next, vehName, vehicles, uniform, differSourceSink, prefix);
274 if (oldSize != (int)vehicles.size()) {
275 changed = true;
276 }
277 if (fraction != 0) {
278 fractionLeft[odID] = fraction;
279 }
280 ++next;
281 }
282 if (changed) {
283 sort(vehicles.begin(), vehicles.end(), descending_departure_comperator());
284 }
285
286 for (std::vector<ODVehicle>::reverse_iterator i = vehicles.rbegin(); i != vehicles.rend() && (*i).depart == t; ++i) {
287 if (t >= begin) {
288 myNumWritten++;
289 if (pedestrians) {
291 dev.writeAttr(SUMO_ATTR_DEPARTPOS, personDepartPos);
293 dev.writeAttr(fromAttr, (*i).from);
294 dev.writeAttr(toAttr, (*i).to);
295 dev.writeAttr(SUMO_ATTR_FROM_TAZ, (*i).cell->origin).writeAttr(SUMO_ATTR_TO_TAZ, (*i).cell->destination);
296 dev.writeAttr(SUMO_ATTR_ARRIVALPOS, personArrivalPos);
297 dev.closeTag();
298 dev.closeTag();
299 } else if (persontrips) {
301 dev.writeAttr(SUMO_ATTR_DEPARTPOS, personDepartPos);
303 dev.writeAttr(fromAttr, (*i).from);
304 dev.writeAttr(toAttr, (*i).to);
305 dev.writeAttr(SUMO_ATTR_FROM_TAZ, (*i).cell->origin).writeAttr(SUMO_ATTR_TO_TAZ, (*i).cell->destination);
306 dev.writeAttr(SUMO_ATTR_ARRIVALPOS, personArrivalPos);
307 if (modes != "") {
308 dev.writeAttr(SUMO_ATTR_MODES, modes);
309 }
310 dev.closeTag();
311 dev.closeTag();
312 } else {
314 dev.writeAttr(fromAttr, (*i).from);
315 dev.writeAttr(toAttr, (*i).to);
316 writeDefaultAttrs(dev, noVtype, i->cell);
317 dev.closeTag();
318 }
319 }
320 }
321 while (vehicles.size() != 0 && vehicles.back().depart == t) {
322 vehicles.pop_back();
323 }
324 if (!vehicles.empty()) {
325 t = vehicles.back().depart;
326 }
327 if (next != myContainer.end() && (t > (*next)->begin || vehicles.empty())) {
328 t = (*next)->begin;
329 }
330 if (next == myContainer.end() && vehicles.empty()) {
331 break;
332 }
333 }
334}
335
336
337void
339 OutputDevice& dev, bool noVtype,
340 const std::string& prefix,
341 bool asProbability, bool pedestrians, bool persontrips,
342 const std::string& modes) {
343 if (myContainer.size() == 0) {
344 return;
345 }
346 int flowName = 0;
348 // recheck begin time
349 for (std::vector<ODCell*>::const_iterator i = myContainer.begin(); i != myContainer.end(); ++i) {
350 const ODCell* const c = *i;
351 if (c->end > begin && c->begin < end) {
352 const double probability = asProbability ? float(c->vehicleNumber) / STEPS2TIME(c->end - c->begin) : 1;
353 if (probability <= 0) {
354 continue;
355 }
356 //Person flows
357 if (pedestrians) {
358 dev.openTag(SUMO_TAG_PERSONFLOW).writeAttr(SUMO_ATTR_ID, prefix + toString(flowName++));
360 if (!asProbability) {
362 } else {
363 if (probability > 1) {
364 WRITE_WARNINGF(TL("Flow density of % vehicles per second, cannot be represented with a simple probability. Falling back to even spacing."), toString(probability));
366 } else {
367 dev.setPrecision(6);
368 dev.writeAttr(SUMO_ATTR_PROB, probability);
369 dev.setPrecision();
370 }
371 }
374 dev.writeAttr(SUMO_ATTR_ARRIVALPOS, "random");
375 dev.closeTag();
376 dev.closeTag();
377 } else if (persontrips) {
378 dev.openTag(SUMO_TAG_PERSONFLOW).writeAttr(SUMO_ATTR_ID, prefix + toString(flowName++));
380 if (!asProbability) {
382 } else {
383 if (probability > 1) {
384 WRITE_WARNINGF(TL("Flow density of % vehicles per second, cannot be represented with a simple probability. Falling back to even spacing."), toString(probability));
386 } else {
387 dev.setPrecision(6);
388 dev.writeAttr(SUMO_ATTR_PROB, probability);
389 dev.setPrecision();
390 }
391 }
394 dev.writeAttr(SUMO_ATTR_ARRIVALPOS, "random");
395 if (modes != "") {
396 dev.writeAttr(SUMO_ATTR_MODES, modes);
397 }
398 dev.closeTag();
399 dev.closeTag();
400 } else {
401 // Normal flow output
402 dev.openTag(SUMO_TAG_FLOW).writeAttr(SUMO_ATTR_ID, prefix + toString(flowName++));
405
406 if (!asProbability) {
408 } else {
409 if (probability > 1) {
410 WRITE_WARNINGF(TL("Flow density of % vehicles per second, cannot be represented with a simple probability. Falling back to even spacing."), toString(probability));
412 } else {
413 dev.setPrecision(6);
414 dev.writeAttr(SUMO_ATTR_PROB, probability);
415 dev.setPrecision();
416 }
417 }
418 writeDefaultAttrs(dev, noVtype, *i);
419 dev.closeTag();
420 }
421 }
422 }
423}
424
425
426std::string
428 while (lr.good() && lr.hasMore()) {
429 const std::string line = lr.readLine();
430 if (line[0] != '*') {
431 return StringUtils::prune(line);
432 }
433 }
434 throw ProcessError(TLF("End of file while reading %.", lr.getFileName()));
435}
436
437
439ODMatrix::parseSingleTime(const std::string& time) {
440 if (time.find('.') == std::string::npos) {
441 throw NumberFormatException("no separator");
442 }
443 const std::string hours = time.substr(0, time.find('.'));
444 const std::string minutes = time.substr(time.find('.') + 1);
445 return TIME2STEPS(StringUtils::toInt(hours) * 3600 + StringUtils::toInt(minutes) * 60);
446}
447
448
449std::pair<SUMOTime, SUMOTime>
451 std::string line = getNextNonCommentLine(lr);
452 try {
454 const SUMOTime begin = parseSingleTime(st.next());
455 const SUMOTime end = parseSingleTime(st.next());
456 if (begin >= end) {
457 throw ProcessError("Matrix begin time " + time2string(begin) + " is larger than end time " + time2string(end) + ".");
458 }
459 return std::make_pair(begin, end);
460 } catch (OutOfBoundsException&) {
461 throw ProcessError(TLF("Broken period definition '%'.", line));
462 } catch (NumberFormatException& e) {
463 throw ProcessError("Broken period definition '" + line + "' (" + e.what() + ").");
464 }
465}
466
467
468double
470 std::string line = getNextNonCommentLine(lr);
471 double factor = -1;
472 try {
473 factor = StringUtils::toDouble(line) * scale;
474 } catch (NumberFormatException&) {
475 throw ProcessError(TLF("Broken factor: '%'.", line));
476 }
477 return factor;
478}
479
480void
481ODMatrix::readV(LineReader& lr, double scale,
482 std::string vehType, bool matrixHasVehType) {
483 PROGRESS_BEGIN_MESSAGE("Reading matrix '" + lr.getFileName() + "' stored as VMR");
484 // parse first defs
485 std::string line;
486 if (matrixHasVehType) {
487 line = getNextNonCommentLine(lr);
488 if (vehType == "") {
489 vehType = StringUtils::prune(line);
490 }
491 }
492
493 const std::pair<SUMOTime, SUMOTime> beginEnd = readTime(lr);
494 const double factor = readFactor(lr, scale);
495
496 // districts
497 line = getNextNonCommentLine(lr);
498 const int numDistricts = StringUtils::toInt(StringUtils::prune(line));
499 // parse district names (normally ints)
500 std::vector<std::string> names;
501 while ((int)names.size() != numDistricts && lr.hasMore()) {
502 line = getNextNonCommentLine(lr);
504 while (st2.hasNext()) {
505 names.push_back(st2.next());
506 }
507 }
508 if (!lr.hasMore()) {
509 throw ProcessError(TLF("Missing line with % district names.", toString(numDistricts)));
510 }
511
512 // parse the cells
513 for (std::vector<std::string>::iterator si = names.begin(); si != names.end(); ++si) {
514 std::vector<std::string>::iterator di = names.begin();
515 do {
516 try {
517 line = getNextNonCommentLine(lr);
518 } catch (ProcessError&) {
519 throw ProcessError(TLF("Missing line for district %.", (*si)));
520 }
521 if (line.length() == 0) {
522 continue;
523 }
524 try {
526 while (st2.hasNext()) {
527 assert(di != names.end());
528 double vehNumber = StringUtils::toDouble(st2.next()) * factor;
529 if (vehNumber != 0) {
530 add(vehNumber, beginEnd, *si, *di, vehType);
531 }
532 if (di == names.end()) {
533 throw ProcessError(TL("More entries than districts found."));
534 }
535 ++di;
536 }
537 } catch (NumberFormatException&) {
538 throw ProcessError(TLF("Not numeric vehicle number in line '%'.", line));
539 }
540 if (!lr.hasMore()) {
541 break;
542 }
543 } while (di != names.end());
544 }
546}
547
548
549void
550ODMatrix::readO(LineReader& lr, double scale,
551 std::string vehType, bool matrixHasVehType) {
552 PROGRESS_BEGIN_MESSAGE("Reading matrix '" + lr.getFileName() + "' stored as OR");
553 // parse first defs
554 std::string line;
555 if (matrixHasVehType) {
556 line = getNextNonCommentLine(lr);
557 int type = StringUtils::toInt(StringUtils::prune(line));
558 if (vehType == "") {
559 vehType = toString(type);
560 }
561 }
562
563 const std::pair<SUMOTime, SUMOTime> beginEnd = readTime(lr);
564 const double factor = readFactor(lr, scale);
565
566 // parse the cells
567 while (lr.hasMore()) {
568 line = getNextNonCommentLine(lr);
569 if (line.length() == 0) {
570 continue;
571 }
573 if (st2.size() == 0) {
574 continue;
575 }
576 try {
577 std::string sourceD = st2.next();
578 std::string destD = st2.next();
579 double vehNumber = StringUtils::toDouble(st2.next()) * factor;
580 if (vehNumber != 0) {
581 add(vehNumber, beginEnd, sourceD, destD, vehType);
582 }
583 } catch (OutOfBoundsException&) {
584 throw ProcessError(TLF("Missing at least one information in line '%'.", line));
585 } catch (NumberFormatException&) {
586 throw ProcessError(TLF("Not numeric vehicle number in line '%'.", line));
587 }
588 }
590}
591
592
593
594double
596 return myNumLoaded;
597}
598
599
600double
602 return myNumWritten;
603}
604
605
606double
608 return myNumDiscarded;
609}
610
611
612void
613ODMatrix::applyCurve(const Distribution_Points& ps, ODCell* cell, std::vector<ODCell*>& newCells) {
614 const std::vector<double>& times = ps.getVals();
615 for (int i = 0; i < (int)times.size() - 1; ++i) {
616 ODCell* ncell = new ODCell();
617 ncell->begin = TIME2STEPS(times[i]);
618 ncell->end = TIME2STEPS(times[i + 1]);
619 ncell->origin = cell->origin;
620 ncell->destination = cell->destination;
621 ncell->vehicleType = cell->vehicleType;
622 ncell->vehicleNumber = cell->vehicleNumber * ps.getProbs()[i] / ps.getOverallProb();
623 newCells.push_back(ncell);
624 }
625}
626
627
628void
630 std::vector<ODCell*> oldCells = myContainer;
631 myContainer.clear();
632 for (std::vector<ODCell*>::iterator i = oldCells.begin(); i != oldCells.end(); ++i) {
633 std::vector<ODCell*> newCells;
634 applyCurve(ps, *i, newCells);
635 copy(newCells.begin(), newCells.end(), back_inserter(myContainer));
636 delete *i;
637 }
638}
639
640
641void
643 std::vector<std::string> files = oc.getStringVector("od-matrix-files");
644 for (std::vector<std::string>::iterator i = files.begin(); i != files.end(); ++i) {
645 LineReader lr(*i);
646 if (!lr.good()) {
647 throw ProcessError(TLF("Could not open '%'.", (*i)));
648 }
649 std::string type = lr.readLine();
650 // get the type only
651 if (type.find(';') != std::string::npos) {
652 type = type.substr(0, type.find(';'));
653 }
654 // parse type-dependant
655 if (type.length() > 1 && type[1] == 'V') {
656 // process ptv's 'V'-matrices
657 if (type.find('N') != std::string::npos) {
658 throw ProcessError(TLF("'%' does not contain the needed information about the time described.", *i));
659 }
660 readV(lr, 1, oc.getString("vtype"), type.find('M') != std::string::npos);
661 } else if (type.length() > 1 && type[1] == 'O') {
662 // process ptv's 'O'-matrices
663 if (type.find('N') != std::string::npos) {
664 throw ProcessError(TLF("'%' does not contain the needed information about the time described.", *i));
665 }
666 readO(lr, 1, oc.getString("vtype"), type.find('M') != std::string::npos);
667 } else {
668 throw ProcessError("'" + *i + "' uses an unknown matrix type '" + type + "'.");
669 }
670 }
671 std::vector<std::string> amitranFiles = oc.getStringVector("od-amitran-files");
672 for (std::vector<std::string>::iterator i = amitranFiles.begin(); i != amitranFiles.end(); ++i) {
673 if (!FileHelpers::isReadable(*i)) {
674 throw ProcessError(TLF("Could not access matrix file '%' to load.", *i));
675 }
676 PROGRESS_BEGIN_MESSAGE("Loading matrix in Amitran format from '" + *i + "'");
677 ODAmitranHandler handler(*this, *i);
678 if (!XMLSubSys::runParser(handler, *i)) {
680 } else {
682 }
683 }
684 myVType = oc.getString("vtype");
685 for (std::string file : oc.getStringVector("tazrelation-files")) {
686 if (!FileHelpers::isReadable(file)) {
687 throw ProcessError(TLF("Could not access matrix file '%' to load.", file));
688 }
689 PROGRESS_BEGIN_MESSAGE("Loading matrix in tazRelation format from '" + file + "'");
690
691 std::vector<SAXWeightsHandler::ToRetrieveDefinition*> retrieverDefs;
692 retrieverDefs.push_back(new SAXWeightsHandler::ToRetrieveDefinition(oc.getString("tazrelation-attribute"), true, *this));
693 SAXWeightsHandler handler(retrieverDefs, "");
694 if (!XMLSubSys::runParser(handler, file)) {
696 } else {
698 }
699 }
700}
701
702void
703ODMatrix::addTazRelWeight(const std::string intervalID, const std::string& from, const std::string& to,
704 double val, double beg, double end) {
705 add(val, std::make_pair(TIME2STEPS(beg), TIME2STEPS(end)), from, to, myVType == "" ? intervalID : myVType);
706}
707
708
709void
711 std::vector<std::string> routeFiles = oc.getStringVector("route-files");
712 for (std::vector<std::string>::iterator i = routeFiles.begin(); i != routeFiles.end(); ++i) {
713 if (!FileHelpers::isReadable(*i)) {
714 throw ProcessError(TLF("Could not access route file '%' to load.", *i));
715 }
716 PROGRESS_BEGIN_MESSAGE("Loading routes and trips from '" + *i + "'");
717 if (!XMLSubSys::runParser(handler, *i)) {
719 } else {
721 }
722 }
723}
724
725
727ODMatrix::parseTimeLine(const std::vector<std::string>& def, bool timelineDayInHours) {
728 Distribution_Points result("N/A");
729 if (timelineDayInHours) {
730 if (def.size() != 24) {
731 throw ProcessError(TLF("Assuming 24 entries for a day timeline, but got %.", toString(def.size())));
732 }
733 for (int chour = 0; chour < 24; ++chour) {
734 result.add(chour * 3600., StringUtils::toDouble(def[chour]));
735 }
736 result.add(24 * 3600., 0.); // dummy value to finish the last interval
737 } else {
738 for (int i = 0; i < (int)def.size(); i++) {
739 StringTokenizer st2(def[i], ":");
740 if (st2.size() != 2) {
741 throw ProcessError(TLF("Broken time line definition: missing a value in '%'.", def[i]));
742 }
743 const double time = StringUtils::toDouble(st2.next());
744 result.add(time, StringUtils::toDouble(st2.next()));
745 }
746 }
747 return result;
748}
749
750
751void
755
756
757/****************************************************************************/
long long int SUMOTime
Definition GUI.h:36
#define WRITE_WARNINGF(...)
Definition MsgHandler.h:271
#define WRITE_ERRORF(...)
Definition MsgHandler.h:280
#define TL(string)
Definition MsgHandler.h:287
#define PROGRESS_DONE_MESSAGE()
Definition MsgHandler.h:275
#define TLF(string,...)
Definition MsgHandler.h:288
#define PROGRESS_FAILED_MESSAGE()
Definition MsgHandler.h:278
#define PROGRESS_BEGIN_MESSAGE(msg)
Definition MsgHandler.h:274
SUMOTime DELTA_T
Definition SUMOTime.cpp:38
SUMOTime string2time(const std::string &r)
convert string to SUMOTime
Definition SUMOTime.cpp:46
std::string time2string(SUMOTime t, bool humanReadable)
convert SUMOTime to string (independently of global format setting)
Definition SUMOTime.cpp:69
#define STEPS2TIME(x)
Definition SUMOTime.h:55
#define TIME2STEPS(x)
Definition SUMOTime.h:57
@ SUMO_TAG_WALK
@ SUMO_TAG_FLOW
a flow definition using from and to edges or a route
@ SUMO_TAG_PERSON
@ SUMO_TAG_PERSONTRIP
@ SUMO_TAG_PERSONFLOW
@ SUMO_TAG_TRIP
a single trip definition (used by router)
SumoXMLAttr
Numbers representing SUMO-XML - attributes.
@ SUMO_ATTR_NUMBER
@ SUMO_ATTR_ARRIVALSPEED
@ SUMO_ATTR_ARRIVALLANE
@ SUMO_ATTR_DEPART
@ SUMO_ATTR_FROMJUNCTION
@ SUMO_ATTR_ARRIVALPOS
@ SUMO_ATTR_BEGIN
weights: time range begin
@ SUMO_ATTR_MODES
@ SUMO_ATTR_DEPARTPOS
@ SUMO_ATTR_TO_TAZ
@ SUMO_ATTR_DEPARTSPEED
@ SUMO_ATTR_TO
@ SUMO_ATTR_FROM
@ SUMO_ATTR_END
weights: time range end
@ SUMO_ATTR_FROM_TAZ
@ SUMO_ATTR_DEPARTLANE
@ SUMO_ATTR_PROB
@ SUMO_ATTR_TYPE
@ SUMO_ATTR_ID
@ SUMO_ATTR_TOJUNCTION
T MAX2(T a, T b)
Definition StdDefs.h:82
std::string toString(const T &t, std::streamsize accuracy=gPrecision)
Definition ToString.h:46
static bool isReadable(std::string path)
Checks whether the given file is readable.
Retrieves a file linewise and reports the lines to a handler.
Definition LineReader.h:48
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.
Definition ODMatrix.h:392
Used for sorting vehicles by their departure (latest first)
Definition ODMatrix.h:428
SUMOTime myEnd
Definition ODMatrix.h:380
double getNumLoaded() const
Returns the number of loaded vehicles.
Definition ODMatrix.cpp:595
void readV(LineReader &lr, double scale, std::string vehType, bool matrixHasVehType)
read a VISUM-matrix with the V Format
Definition ODMatrix.cpp:481
void sortByBeginTime()
Definition ODMatrix.cpp:752
double readFactor(LineReader &lr, double scale)
Definition ODMatrix.cpp:469
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".
Definition ODMatrix.cpp:164
void addTazRelWeight(const std::string intervalID, const std::string &from, const std::string &to, double val, double beg, double end)
Definition ODMatrix.cpp:703
SUMOTime myBegin
parsed time bounds
Definition ODMatrix.h:380
~ODMatrix()
Destructor.
Definition ODMatrix.cpp:62
SUMOTime parseSingleTime(const std::string &time)
Definition ODMatrix.cpp:439
double myScale
the scaling factor for traffic
Definition ODMatrix.h:386
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.
Definition ODMatrix.cpp:338
void applyCurve(const Distribution_Points &ps)
Splits the stored cells dividing them on the given time line.
Definition ODMatrix.cpp:629
std::map< const std::pair< const std::string, const std::string >, std::vector< ODCell * > > myShortCut
The loaded cells indexed by origin and destination.
Definition ODMatrix.h:362
std::pair< SUMOTime, SUMOTime > readTime(LineReader &lr)
Definition ODMatrix.cpp:450
void readO(LineReader &lr, double scale, std::string vehType, bool matrixHasVehType)
read a VISUM-matrix with the O Format
Definition ODMatrix.cpp:550
std::set< std::string > myMissingDistricts
The missing districts already warned about.
Definition ODMatrix.h:368
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.
Definition ODMatrix.cpp:232
const ODDistrictCont & myDistricts
The districts to retrieve sources/sinks from.
Definition ODMatrix.h:365
Distribution_Points parseTimeLine(const std::vector< std::string > &def, bool timelineDayInHours)
split the given timeline
Definition ODMatrix.cpp:727
ODMatrix(const ODDistrictCont &dc, double scale)
Constructor.
Definition ODMatrix.cpp:51
void writeDefaultAttrs(OutputDevice &dev, const bool noVtype, const ODCell *const cell)
Helper function for flow and trip output writing the depart and arrival attributes.
Definition ODMatrix.cpp:203
double myNumLoaded
Number of loaded vehicles.
Definition ODMatrix.h:371
double myNumWritten
Number of written vehicles.
Definition ODMatrix.h:374
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, bool noScaling=false)
Builds a single cell from the given values, verifying them.
Definition ODMatrix.cpp:74
void loadMatrix(OptionsCont &oc)
read a matrix in one of several formats
Definition ODMatrix.cpp:642
void loadRoutes(OptionsCont &oc, SUMOSAXHandler &handler)
read SUMO routes
Definition ODMatrix.cpp:710
double getNumWritten() const
Returns the number of written vehicles.
Definition ODMatrix.cpp:601
std::vector< ODCell * > myContainer
The loaded cells.
Definition ODMatrix.h:359
double myNumDiscarded
Number of discarded vehicles.
Definition ODMatrix.h:377
double getNumDiscarded() const
Returns the number of discarded vehicles.
Definition ODMatrix.cpp:607
std::string myVType
user-defined vType
Definition ODMatrix.h:383
std::string getNextNonCommentLine(LineReader &lr)
Definition ODMatrix.cpp:427
A storage for options typed value containers)
Definition OptionsCont.h:89
bool isSet(const std::string &name, bool failOnNonExistant=true) const
Returns the information whether the named option is set.
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 & writeAttr(const SumoXMLAttr attr, const T &val)
writes a named attribute
OutputDevice & openTag(const std::string &xmlElement)
Opens an XML tag.
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.
Definition RORoute.h:52
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.
bool add(T val, double prob, bool checkDuplicates=true)
Adds a value with an assigned probability to the distribution.
const std::vector< T > & getVals() const
Returns the members of the distribution.
const std::vector< double > & getProbs() const
Returns the probabilities assigned to the members of 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, const bool isExternal=false, const bool catchExceptions=true)
Runs the given handler on the given file; returns if everything's ok.
A single O/D-matrix cell.
Definition ODCell.h:48
std::string destination
Name of the destination district.
Definition ODCell.h:62
std::map< SUMOTime, std::vector< std::string > > departures
mapping of departure times to departing vehicles, if already fixed
Definition ODCell.h:71
std::string vehicleType
Name of the vehicle type.
Definition ODCell.h:65
std::string origin
Name of the origin district.
Definition ODCell.h:59
double vehicleNumber
The number of vehicles.
Definition ODCell.h:50
bool originIsEdge
the origin "district" is an edge id
Definition ODCell.h:74
SUMOTime end
The end time this cell describes.
Definition ODCell.h:56
SUMOTime begin
The begin time this cell describes.
Definition ODCell.h:53
bool destinationIsEdge
the destination "district" is an edge id
Definition ODCell.h:77
An internal representation of a single vehicle.
Definition ODMatrix.h:270
SUMOTime depart
The departure time of the vehicle.
Definition ODMatrix.h:274
std::string from
The edge the vehicles shall start at.
Definition ODMatrix.h:278
ODCell * cell
The cell of the ODMatrix which generated the vehicle.
Definition ODMatrix.h:276
std::string to
The edge the vehicles shall end at.
Definition ODMatrix.h:280
std::string id
The id of the vehicle.
Definition ODMatrix.h:272