ODMatrix.cpp
Go to the documentation of this file.00001
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #ifdef _MSC_VER
00025 #include <windows_config.h>
00026 #else
00027 #include <config.h>
00028 #endif
00029
00030 #include "ODMatrix.h"
00031 #include <utils/options/OptionsCont.h>
00032 #include <utils/common/StdDefs.h>
00033 #include <utils/common/MsgHandler.h>
00034 #include <utils/common/ToString.h>
00035 #include <iostream>
00036 #include <algorithm>
00037 #include <list>
00038 #include <utils/common/RandHelper.h>
00039 #include <utils/iodevices/OutputDevice.h>
00040
00041 #ifdef CHECK_MEMORY_LEAKS
00042 #include <foreign/nvwa/debug_new.h>
00043 #endif // CHECK_MEMORY_LEAKS
00044
00045
00046
00047
00048
00049 ODMatrix::ODMatrix(const ODDistrictCont &dc) throw()
00050 : myDistricts(dc), myNoLoaded(0), myNoWritten(0), myNoDiscarded(0) {}
00051
00052
00053 ODMatrix::~ODMatrix() throw() {
00054 for (CellVector::iterator i=myContainer.begin(); i!=myContainer.end(); ++i) {
00055 delete *i;
00056 }
00057 myContainer.clear();
00058 }
00059
00060
00061 void
00062 ODMatrix::add(SUMOReal vehicleNumber, SUMOTime begin,
00063 SUMOTime end, const std::string &origin, const std::string &destination,
00064 const std::string &vehicleType) throw() {
00065 myNoLoaded += vehicleNumber;
00066 if (myDistricts.get(origin)==0&&myDistricts.get(destination)==0) {
00067 MsgHandler::getWarningInstance()->inform("Missing origin '" + origin + "' and destination '" + destination + "' (" + toString(vehicleNumber) + " vehicles).");
00068 } else if (myDistricts.get(origin)==0&&vehicleNumber>0) {
00069 MsgHandler::getErrorInstance()->inform("Missing origin '" + origin + "' (" + toString(vehicleNumber) + " vehicles).");
00070 myNoDiscarded += vehicleNumber;
00071 } else if (myDistricts.get(destination)==0&&vehicleNumber>0) {
00072 MsgHandler::getErrorInstance()->inform("Missing destination '" + destination + "' (" + toString(vehicleNumber) + " vehicles).");
00073 myNoDiscarded += vehicleNumber;
00074 } else {
00075 if (myDistricts.get(origin)->sourceNumber()==0) {
00076 MsgHandler::getErrorInstance()->inform("District '" + origin + "' has no source.");
00077 myNoDiscarded += vehicleNumber;
00078 } else if (myDistricts.get(destination)->sinkNumber()==0) {
00079 MsgHandler::getErrorInstance()->inform("District '" + destination + "' has no sink.");
00080 myNoDiscarded += vehicleNumber;
00081 } else {
00082 ODCell *cell = new ODCell();
00083 cell->begin = begin;
00084 cell->end = end;
00085 cell->origin = origin;
00086 cell->destination = destination;
00087 cell->vehicleType = vehicleType;
00088 cell->vehicleNumber = vehicleNumber;
00089 myContainer.push_back(cell);
00090 }
00091 }
00092 }
00093
00094
00095 SUMOReal
00096 ODMatrix::computeEmissions(ODCell *cell,
00097 size_t &vehName, std::vector<ODVehicle> &into,
00098 bool uniform, const std::string &prefix) throw() {
00099 int vehicles2emit = (int) cell->vehicleNumber;
00100
00101 SUMOReal mrand = RandHelper::rand();
00102 SUMOReal mprob = (SUMOReal) cell->vehicleNumber - (SUMOReal) vehicles2emit;
00103 if (mrand<mprob) {
00104 vehicles2emit++;
00105 }
00106
00107 SUMOReal offset = (SUMOReal)(cell->end - cell->begin) / (SUMOReal) vehicles2emit / (SUMOReal) 2.;
00108 for (int i=0; i<vehicles2emit; ++i) {
00109 ODVehicle veh;
00110 veh.id = prefix + toString(vehName++);
00111
00112 if (uniform) {
00113 veh.depart = (unsigned int)(offset + cell->begin + ((SUMOReal)(cell->end - cell->begin) * (SUMOReal) i / (SUMOReal) vehicles2emit));
00114 } else {
00115 veh.depart = (unsigned int) RandHelper::rand((int) cell->begin, (int) cell->end);
00116 }
00117
00118 veh.from = myDistricts.getRandomSourceFromDistrict(cell->origin);
00119 veh.to = myDistricts.getRandomSinkFromDistrict(cell->destination);
00120 veh.cell = cell;
00121 into.push_back(veh);
00122 }
00123 return cell->vehicleNumber - vehicles2emit;
00124 }
00125
00126
00127 void
00128 ODMatrix::write(SUMOTime begin, SUMOTime end,
00129 OutputDevice &dev, bool uniform, bool noVtype,
00130 const std::string &prefix) throw() {
00131 if (myContainer.size()==0) {
00132 return;
00133 }
00134 OptionsCont &oc = OptionsCont::getOptions();
00135 std::map<std::pair<std::string, std::string>, SUMOReal> fractionLeft;
00136 size_t vehName = 0;
00137 sort(myContainer.begin(), myContainer.end(), cell_by_begin_sorter());
00138
00139 ODCell *first = *myContainer.begin();
00140 begin = MAX2(begin, first->begin);
00141 CellVector::iterator next = myContainer.begin();
00142 std::vector<ODVehicle> vehicles;
00143
00144 for (SUMOTime t=begin; t!=end; t++) {
00145 MsgHandler::getMessageInstance()->progressMsg("Parsing time " + toString(t));
00146
00147 bool changed = false;
00148 while (next!=myContainer.end()&&(*next)->begin<=t&&(*next)->end>t) {
00149 std::pair<std::string, std::string> odID = std::make_pair((*next)->origin, (*next)->destination);
00150
00151 if (fractionLeft.find(odID)!=fractionLeft.end()) {
00152 (*next)->vehicleNumber += fractionLeft[odID];
00153 fractionLeft[odID] = 0;
00154 }
00155
00156 std::vector<ODVehicle> tmp;
00157 SUMOReal fraction = computeEmissions(*next, vehName, tmp, uniform, prefix);
00158
00159 if (tmp.size()!=0) {
00160 copy(tmp.begin(), tmp.end(), back_inserter(vehicles));
00161 changed = true;
00162 }
00163
00164 if (fraction!=0) {
00165 if (fractionLeft.find(odID)==fractionLeft.end()) {
00166 fractionLeft[odID] = fraction;
00167 } else {
00168 fractionLeft[odID] += fraction;
00169 }
00170 }
00171
00172 ++next;
00173 }
00174 if (changed) {
00175 sort(vehicles.begin(), vehicles.end(), descending_departure_comperator());
00176 }
00177 std::vector<ODVehicle>::reverse_iterator i = vehicles.rbegin();
00178 for (; i!=vehicles.rend()&&(*i).depart==t; ++i) {
00179 myNoWritten++;
00180 dev.openTag("tripdef") << " id=\"" << (*i).id << "\" depart=\"" << t << ".00\" "
00181 << "from=\"" << (*i).from << "\" "
00182 << "to=\"" << (*i).to << "\"";
00183 if (!noVtype&&(*i).cell->vehicleType.length()!=0) {
00184 dev << " type=\"" << (*i).cell->vehicleType << "\"";
00185 }
00186 if (oc.getBool("with-taz")) {
00187 dev << " fromtaz=\"" << (*i).cell->origin << "\"";
00188 dev << " totaz=\"" << (*i).cell->destination << "\"";
00189 }
00190 if (oc.isSet("departlane") && oc.getString("departlane")!="default") {
00191 dev << " departlane=\"" << oc.getString("departlane") << "\"";
00192 }
00193 if (oc.isSet("departpos")) {
00194 dev << " departpos=\"" << oc.getString("departpos") << "\"";
00195 }
00196 if (oc.isSet("departspeed") && oc.getString("departspeed")!="default") {
00197 dev << " departspeed=\"" << oc.getString("departspeed") << "\"";
00198 }
00199 if (oc.isSet("arrivallane")) {
00200 dev << " arrivallane=\"" << oc.getString("arrivallane") << "\"";
00201 }
00202 if (oc.isSet("arrivalpos")) {
00203 dev << " arrivalpos=\"" << oc.getString("arrivalpos") << "\"";
00204 }
00205 if (oc.isSet("arrivalspeed")) {
00206 dev << " arrivalspeed=\"" << oc.getString("arrivalspeed") << "\"";
00207 }
00208 dev.closeTag(true);
00209 }
00210 while (vehicles.size()!=0&&(*vehicles.rbegin()).depart==t) {
00211 vehicles.pop_back();
00212 }
00213 }
00214 }
00215
00216
00217 SUMOReal
00218 ODMatrix::getNoLoaded() const throw() {
00219 return myNoLoaded;
00220 }
00221
00222
00223 SUMOReal
00224 ODMatrix::getNoWritten() const throw() {
00225 return myNoWritten;
00226 }
00227
00228
00229 SUMOReal
00230 ODMatrix::getNoDiscarded() const throw() {
00231 return myNoDiscarded;
00232 }
00233
00234
00235 void
00236 ODMatrix::applyCurve(const Distribution_Points &ps, ODCell *cell, CellVector &newCells) throw() {
00237 for (size_t i=0; i<ps.getAreaNo(); ++i) {
00238 ODCell *ncell = new ODCell();
00239 ncell->begin = (SUMOTime) ps.getAreaBegin(i);
00240 ncell->end = (SUMOTime) ps.getAreaEnd(i);
00241 ncell->origin = cell->origin;
00242 ncell->destination = cell->destination;
00243 ncell->vehicleType = cell->vehicleType;
00244 ncell->vehicleNumber = cell->vehicleNumber * ps.getAreaPerc(i);
00245 newCells.push_back(ncell);
00246 }
00247 }
00248
00249
00250 void
00251 ODMatrix::applyCurve(const Distribution_Points &ps) throw() {
00252 CellVector oldCells = myContainer;
00253 myContainer.clear();
00254 for (CellVector::iterator i=oldCells.begin(); i!=oldCells.end(); ++i) {
00255 CellVector newCells;
00256 applyCurve(ps, *i, newCells);
00257 copy(newCells.begin(), newCells.end(), back_inserter(myContainer));
00258 delete *i;
00259 }
00260 }
00261
00262
00263
00264
00265