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 <cassert>
00031 #include <string>
00032 #include <algorithm>
00033 #include <utils/options/OptionsCont.h>
00034 #include <utils/common/UtilExceptions.h>
00035 #include <utils/common/StringTokenizer.h>
00036 #include <utils/common/MsgHandler.h>
00037 #include <utils/common/ToString.h>
00038 #include <utils/common/RandHelper.h>
00039 #include <utils/common/StringUtils.h>
00040 #include "RORouteDef.h"
00041 #include "RONet.h"
00042 #include "RORouteDef_OrigDest.h"
00043 #include "RORDGenerator_ODAmounts.h"
00044 #include "ROVehicle.h"
00045 #include "RORouteDef_Complete.h"
00046 #include "ROAbstractRouteDefLoader.h"
00047 #include <utils/xml/SUMOVehicleParserHelper.h>
00048
00049 #ifdef CHECK_MEMORY_LEAKS
00050 #include <foreign/nvwa/debug_new.h>
00051 #endif // CHECK_MEMORY_LEAKS
00052
00053
00054
00055
00056
00057
00058
00059
00060 RORDGenerator_ODAmounts::FlowDef::FlowDef(ROVehicle *vehicle,
00061 SUMOVTypeParameter *type,
00062 RORouteDef *route,
00063 SUMOTime intBegin,
00064 SUMOTime intEnd,
00065 unsigned int vehicles2Emit,
00066 bool randomize)
00067 : myVehicle(vehicle), myVehicleType(type), myRoute(route),
00068 myIntervalBegin(intBegin), myIntervalEnd(intEnd),
00069 myVehicle2EmitNumber(vehicles2Emit), myEmitted(0), myRandom(randomize) {
00070 assert(myIntervalBegin<myIntervalEnd);
00071 if (myRandom) {
00072 SUMOTime period = myIntervalEnd - myIntervalBegin;
00073 myDepartures.reserve(myVehicle2EmitNumber);
00074 for (size_t i=0; i<myVehicle2EmitNumber; ++i) {
00075 SUMOTime departure = ((int)(RandHelper::rand(period) / DELTA_T)) * DELTA_T;
00076 myDepartures.push_back(departure);
00077 }
00078 sort(myDepartures.begin(), myDepartures.end());
00079 reverse(myDepartures.begin(), myDepartures.end());
00080 }
00081 }
00082
00083
00084 RORDGenerator_ODAmounts::FlowDef::~FlowDef() {
00085 delete myVehicle;
00086 }
00087
00088
00089 bool
00090 RORDGenerator_ODAmounts::FlowDef::applicableForTime(SUMOTime t) const {
00091 return myIntervalBegin<=t&&myIntervalEnd>t;
00092 }
00093
00094
00095 void
00096 RORDGenerator_ODAmounts::FlowDef::addRoutes(RONet &net, SUMOTime t) {
00097 assert(myIntervalBegin<=t&&myIntervalEnd>=t);
00098
00099 if (!myRandom) {
00100 unsigned int absPerEachStep = myVehicle2EmitNumber / ((myIntervalEnd-myIntervalBegin) / DELTA_T);
00101 for (unsigned int i=0; i<absPerEachStep; i++) {
00102 addSingleRoute(net, t);
00103 }
00104
00105 SUMOReal toEmit = (SUMOReal) myVehicle2EmitNumber / (SUMOReal)(myIntervalEnd-myIntervalBegin) * (SUMOReal)(t-myIntervalBegin+(SUMOReal)DELTA_T/2.);
00106 if (toEmit>myEmitted) {
00107 addSingleRoute(net, t);
00108 }
00109 } else {
00110 while (myDepartures.size()>0&&*(myDepartures.end()-1)<t+DELTA_T) {
00111 addSingleRoute(net, t);
00112 myDepartures.pop_back();
00113 }
00114 }
00115 }
00116
00117
00118 void
00119 RORDGenerator_ODAmounts::FlowDef::addSingleRoute(RONet &net, SUMOTime t) {
00120 std::string id = myVehicle->getID() + "_" + toString<unsigned int>(myEmitted);
00121 RORouteDef *rd = myRoute->copy(id);
00122 net.addRouteDef(rd);
00123 ROVehicle *veh = myVehicle->copy(id, t, rd);
00124 net.addVehicle(id, veh);
00125 myEmitted++;
00126 }
00127
00128
00129 SUMOTime
00130 RORDGenerator_ODAmounts::FlowDef::getIntervalEnd() const {
00131 return myIntervalEnd;
00132 }
00133
00134
00135
00136
00137
00138 RORDGenerator_ODAmounts::RORDGenerator_ODAmounts(RONet &net,
00139 SUMOTime begin,
00140 SUMOTime end,
00141 bool emptyDestinationsAllowed,
00142 bool randomize,
00143 const std::string &fileName) throw(ProcessError)
00144 : RORDLoader_TripDefs(net, begin, end, emptyDestinationsAllowed, false, fileName),
00145 myRandom(randomize) {
00146
00147 myParser->parseReset(myToken);
00148 myParser->parse(getFileName().c_str());
00149 myDepartureTime = myBegin;
00150 }
00151
00152
00153 RORDGenerator_ODAmounts::~RORDGenerator_ODAmounts() throw() {
00154 for (FlowDefV::const_iterator i=myFlows.begin(); i!=myFlows.end(); i++) {
00155 delete(*i);
00156 }
00157 }
00158
00159
00160 bool
00161 RORDGenerator_ODAmounts::readRoutesAtLeastUntil(SUMOTime until, bool skipping) throw(ProcessError) {
00162
00163 if (until<myBegin) {
00164 myDepartureTime = until;
00165 return true;
00166 }
00167
00168 buildRoutes(until);
00169 return true;
00170 }
00171
00172
00173 void
00174 RORDGenerator_ODAmounts::buildRoutes(SUMOTime until) throw() {
00175 SUMOTime t;
00176 for (t=myDepartureTime; t<until+1; t+=DELTA_T) {
00177 buildForTimeStep(t);
00178 }
00179 myDepartureTime = t;
00180 }
00181
00182
00183 void
00184 RORDGenerator_ODAmounts::buildForTimeStep(SUMOTime time) throw() {
00185 if (time<myBegin||time>=myEnd) {
00186 return;
00187 }
00188 myEnded = true;
00189 for (FlowDefV::const_iterator i=myFlows.begin(); i!=myFlows.end(); i++) {
00190 FlowDef *fd = *i;
00191
00192 if (fd->applicableForTime(time)) {
00193 fd->addRoutes(myNet, time);
00194 }
00195
00196 if (fd->getIntervalEnd()>time) {
00197 myEnded = false;
00198 }
00199 }
00200 }
00201
00202
00203 void
00204 RORDGenerator_ODAmounts::myStartElement(SumoXMLTag element,
00205 const SUMOSAXAttributes &attrs) throw(ProcessError) {
00206 RORDLoader_TripDefs::myStartElement(element, attrs);
00207 if (element == SUMO_TAG_FLOW) {
00208 parseFlowAmountDef(attrs);
00209 } else if (element == SUMO_TAG_INTERVAL) {
00210 parseInterval(attrs);
00211 }
00212 }
00213
00214
00215 void
00216 RORDGenerator_ODAmounts::parseFlowAmountDef(const SUMOSAXAttributes &attrs) throw(ProcessError) {
00217
00218
00219 std::string id = getVehicleID(attrs);
00220 if (myKnownIDs.find(id)!=myKnownIDs.end()) {
00221 throw ProcessError("The id '" + id + "' appears twice within the flow descriptions.'");
00222 }
00223 myKnownIDs.insert(id);
00224 myBeginEdge = getEdge(attrs, "origin", SUMO_ATTR_FROM, id, false);
00225 myEndEdge = getEdge(attrs, "destination",
00226 SUMO_ATTR_TO, id, myEmptyDestinationsAllowed);
00227 try {
00228 myParameter = SUMOVehicleParserHelper::parseVehicleAttributes(attrs, true, true);
00229 } catch (ProcessError &e) {
00230 throw ProcessError(StringUtils::replace(e.what(), "''", id.c_str()));
00231 }
00232 myParameter->id = id;
00233 bool ok = true;
00234 myIntervalBegin = attrs.getOptSUMOTimeReporting(SUMO_ATTR_BEGIN, "flow", id.c_str(), ok, myUpperIntervalBegin);
00235 myIntervalEnd = attrs.getOptSUMOTimeReporting(SUMO_ATTR_END, "flow", id.c_str(), ok, myUpperIntervalEnd);
00236 myVehicle2EmitNumber = attrs.getIntReporting(SUMO_ATTR_NO, "flow", id.c_str(), ok);
00237 if (!ok) {
00238 throw ProcessError();
00239 }
00240 if (myIntervalEnd<=myIntervalBegin) {
00241 throw ProcessError("The interval must be larger than 0.\n The current values are: begin=" + toString<unsigned int>(myIntervalBegin) + " end=" + toString<unsigned int>(myIntervalEnd));
00242 }
00243 }
00244
00245
00246 void
00247 RORDGenerator_ODAmounts::parseInterval(const SUMOSAXAttributes &attrs) {
00248 bool ok = true;
00249 myUpperIntervalBegin = attrs.getOptSUMOTimeReporting(SUMO_ATTR_BEGIN, "interval", 0, ok, -1);
00250 myUpperIntervalEnd = attrs.getOptSUMOTimeReporting(SUMO_ATTR_END, "interval", 0, ok, -1);
00251 }
00252
00253
00254 void
00255 RORDGenerator_ODAmounts::myEndElement(SumoXMLTag element) throw(ProcessError) {
00256 RORDLoader_TripDefs::myEndElement(element);
00257 if (element == SUMO_TAG_FLOW) {
00258 myEndFlowAmountDef();
00259 } else if (element == SUMO_TAG_INTERVAL) {
00260 myEndInterval();
00261 }
00262 }
00263
00264
00265 void
00266 RORDGenerator_ODAmounts::myEndInterval() {
00267 myUpperIntervalBegin = 0;
00268 myUpperIntervalEnd = 0;
00269 }
00270
00271
00272 void
00273 RORDGenerator_ODAmounts::myEndFlowAmountDef() {
00274 if (!MsgHandler::getErrorInstance()->wasInformed()) {
00275
00276 if (myIntervalEnd<myBegin) {
00277 return;
00278 }
00279
00280 RGBColor *col = myParameter->wasSet(VEHPARS_COLOR_SET) ? new RGBColor(myParameter->color) : 0;
00281 RORouteDef *route = new RORouteDef_OrigDest(myParameter->id, col, myBeginEdge, myEndEdge);
00282 SUMOVTypeParameter *type = myNet.getVehicleTypeSecure(myParameter->vtypeid);
00283
00284 if (MsgHandler::getErrorInstance()->wasInformed()) {
00285 return;
00286 }
00287
00288 myNet.addRouteDef(route);
00289 myNextRouteRead = true;
00290 ROVehicle *vehicle = new ROVehicle(*myParameter, route, type);
00291
00292 FlowDef *fd = new FlowDef(vehicle, type, route, myIntervalBegin, myIntervalEnd, myVehicle2EmitNumber, myRandom);
00293 myFlows.push_back(fd);
00294 delete myParameter;
00295 myParameter = 0;
00296 }
00297 }
00298
00299
00300
00301