SUMO - Simulation of Urban MObility
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
ODMatrix.cpp
Go to the documentation of this file.
1 /****************************************************************************/
9 // An O/D (origin/destination) matrix
10 /****************************************************************************/
11 // SUMO, Simulation of Urban MObility; see http://sumo.sourceforge.net/
12 // Copyright (C) 2001-2012 DLR (http://www.dlr.de/) and contributors
13 /****************************************************************************/
14 //
15 // This file is part of SUMO.
16 // SUMO is free software: you can redistribute it and/or modify
17 // it under the terms of the GNU General Public License as published by
18 // the Free Software Foundation, either version 3 of the License, or
19 // (at your option) any later version.
20 //
21 /****************************************************************************/
22 
23 
24 // ===========================================================================
25 // included modules
26 // ===========================================================================
27 #ifdef _MSC_VER
28 #include <windows_config.h>
29 #else
30 #include <config.h>
31 #endif
32 
33 #include "ODMatrix.h"
35 #include <utils/common/StdDefs.h>
37 #include <utils/common/ToString.h>
38 #include <iostream>
39 #include <algorithm>
40 #include <list>
41 #include <iterator>
44 
45 #ifdef CHECK_MEMORY_LEAKS
46 #include <foreign/nvwa/debug_new.h>
47 #endif // CHECK_MEMORY_LEAKS
48 
49 
50 // ===========================================================================
51 // method definitions
52 // ===========================================================================
54  : myDistricts(dc), myNoLoaded(0), myNoWritten(0), myNoDiscarded(0) {}
55 
56 
58  for (std::vector<ODCell*>::iterator i = myContainer.begin(); i != myContainer.end(); ++i) {
59  delete *i;
60  }
61  myContainer.clear();
62 }
63 
64 
65 void
66 ODMatrix::add(SUMOReal vehicleNumber, SUMOTime begin,
67  SUMOTime end, const std::string& origin, const std::string& destination,
68  const std::string& vehicleType) {
69  myNoLoaded += vehicleNumber;
70  if (myDistricts.get(origin) == 0 && myDistricts.get(destination) == 0) {
71  WRITE_WARNING("Missing origin '" + origin + "' and destination '" + destination + "' (" + toString(vehicleNumber) + " vehicles).");
72  } else if (myDistricts.get(origin) == 0 && vehicleNumber > 0) {
73  WRITE_ERROR("Missing origin '" + origin + "' (" + toString(vehicleNumber) + " vehicles).");
74  myNoDiscarded += vehicleNumber;
75  } else if (myDistricts.get(destination) == 0 && vehicleNumber > 0) {
76  WRITE_ERROR("Missing destination '" + destination + "' (" + toString(vehicleNumber) + " vehicles).");
77  myNoDiscarded += vehicleNumber;
78  } else {
79  if (myDistricts.get(origin)->sourceNumber() == 0) {
80  WRITE_ERROR("District '" + origin + "' has no source.");
81  myNoDiscarded += vehicleNumber;
82  } else if (myDistricts.get(destination)->sinkNumber() == 0) {
83  WRITE_ERROR("District '" + destination + "' has no sink.");
84  myNoDiscarded += vehicleNumber;
85  } else {
86  ODCell* cell = new ODCell();
87  cell->begin = begin;
88  cell->end = end;
89  cell->origin = origin;
90  cell->destination = destination;
91  cell->vehicleType = vehicleType;
92  cell->vehicleNumber = vehicleNumber;
93  myContainer.push_back(cell);
94  }
95  }
96 }
97 
98 
101  size_t& vehName, std::vector<ODVehicle>& into,
102  bool uniform, const std::string& prefix) {
103  int vehicles2insert = (int) cell->vehicleNumber;
104  // compute whether the fraction forces an additional vehicle insertion
105  SUMOReal mprob = (SUMOReal) cell->vehicleNumber - (SUMOReal) vehicles2insert;
106  if (RandHelper::rand() < mprob) {
107  vehicles2insert++;
108  }
109 
110  const SUMOReal offset = (SUMOReal)(cell->end - cell->begin) / (SUMOReal) vehicles2insert / (SUMOReal) 2.;
111  for (int i = 0; i < vehicles2insert; ++i) {
112  ODVehicle veh;
113  veh.id = prefix + toString(vehName++);
114 
115  if (uniform) {
116  veh.depart = (SUMOTime)(offset + cell->begin + ((SUMOReal)(cell->end - cell->begin) * (SUMOReal) i / (SUMOReal) vehicles2insert));
117  } else {
118  veh.depart = (SUMOTime)RandHelper::rand(cell->begin, cell->end);
119  }
120 
123  veh.cell = cell;
124  into.push_back(veh);
125  }
126  return cell->vehicleNumber - vehicles2insert;
127 }
128 
129 
130 void
132  OutputDevice& dev, bool uniform, bool noVtype,
133  const std::string& prefix, bool stepLog) {
134  if (myContainer.size() == 0) {
135  return;
136  }
138  std::map<std::pair<std::string, std::string>, SUMOReal> fractionLeft;
139  size_t vehName = 0;
140  sort(myContainer.begin(), myContainer.end(), cell_by_begin_sorter());
141  // recheck begin time
142  begin = MAX2(begin, myContainer.front()->begin);
143  std::vector<ODCell*>::iterator next = myContainer.begin();
144  std::vector<ODVehicle> vehicles;
145  SUMOTime lastOut = -DELTA_T;
146  // go through the time steps
147  for (SUMOTime t = begin; t != end;) {
148  if (stepLog && t - lastOut >= DELTA_T) {
149  std::cout << "Parsing time " + time2string(t) << '\r';
150  lastOut = t;
151  }
152  // recheck whether a new cell got valid
153  bool changed = false;
154  while (next != myContainer.end() && (*next)->begin <= t && (*next)->end > t) {
155  std::pair<std::string, std::string> odID = std::make_pair((*next)->origin, (*next)->destination);
156  // check whether the current cell must be extended by the last fraction
157  if (fractionLeft.find(odID) != fractionLeft.end()) {
158  (*next)->vehicleNumber += fractionLeft[odID];
159  fractionLeft[odID] = 0;
160  }
161  // get the new departures (into tmp)
162  const size_t oldSize = vehicles.size();
163  const SUMOReal fraction = computeDeparts(*next, vehName, vehicles, uniform, prefix);
164  if (oldSize != vehicles.size()) {
165  changed = true;
166  }
167  if (fraction != 0) {
168  fractionLeft[odID] = fraction;
169  }
170  ++next;
171  }
172  if (changed) {
173  sort(vehicles.begin(), vehicles.end(), descending_departure_comperator());
174  }
175  for (std::vector<ODVehicle>::reverse_iterator i = vehicles.rbegin(); i != vehicles.rend() && (*i).depart == t; ++i) {
176  myNoWritten++;
178  if (!noVtype && (*i).cell->vehicleType.length() != 0) {
179  dev.writeAttr(SUMO_ATTR_TYPE, (*i).cell->vehicleType);
180  }
181  dev.writeAttr(SUMO_ATTR_FROM_TAZ, (*i).cell->origin).writeAttr(SUMO_ATTR_TO_TAZ, (*i).cell->destination);
182  if (oc.isSet("departlane") && oc.getString("departlane") != "default") {
183  dev.writeAttr(SUMO_ATTR_DEPARTLANE, oc.getString("departlane"));
184  }
185  if (oc.isSet("departpos")) {
186  dev.writeAttr(SUMO_ATTR_DEPARTPOS, oc.getString("departpos"));
187  }
188  if (oc.isSet("departspeed") && oc.getString("departspeed") != "default") {
189  dev.writeAttr(SUMO_ATTR_DEPARTSPEED, oc.getString("departspeed"));
190  }
191  if (oc.isSet("arrivallane")) {
192  dev.writeAttr(SUMO_ATTR_ARRIVALLANE, oc.getString("arrivallane"));
193  }
194  if (oc.isSet("arrivalpos")) {
195  dev.writeAttr(SUMO_ATTR_ARRIVALPOS, oc.getString("arrivalpos"));
196  }
197  if (oc.isSet("arrivalspeed")) {
198  dev.writeAttr(SUMO_ATTR_ARRIVALSPEED, oc.getString("arrivalspeed"));
199  }
200  dev.closeTag(true);
201  }
202  while (vehicles.size() != 0 && vehicles.back().depart == t) {
203  vehicles.pop_back();
204  }
205  if (!vehicles.empty()) {
206  t = vehicles.back().depart;
207  }
208  if (next != myContainer.end() && (t > (*next)->begin || vehicles.empty())) {
209  t = (*next)->begin;
210  }
211  if (next == myContainer.end() && vehicles.empty()) {
212  break;
213  }
214  }
215 }
216 
217 
218 SUMOReal
220  return myNoLoaded;
221 }
222 
223 
224 SUMOReal
226  return myNoWritten;
227 }
228 
229 
230 SUMOReal
232  return myNoDiscarded;
233 }
234 
235 
236 void
237 ODMatrix::applyCurve(const Distribution_Points& ps, ODCell* cell, std::vector<ODCell*>& newCells) {
238  for (size_t i = 0; i < ps.getAreaNo(); ++i) {
239  ODCell* ncell = new ODCell();
240  ncell->begin = TIME2STEPS(ps.getAreaBegin(i));
241  ncell->end = TIME2STEPS(ps.getAreaEnd(i));
242  ncell->origin = cell->origin;
243  ncell->destination = cell->destination;
244  ncell->vehicleType = cell->vehicleType;
245  ncell->vehicleNumber = cell->vehicleNumber * ps.getAreaPerc(i);
246  newCells.push_back(ncell);
247  }
248 }
249 
250 
251 void
253  std::vector<ODCell*> oldCells = myContainer;
254  myContainer.clear();
255  for (std::vector<ODCell*>::iterator i = oldCells.begin(); i != oldCells.end(); ++i) {
256  std::vector<ODCell*> newCells;
257  applyCurve(ps, *i, newCells);
258  copy(newCells.begin(), newCells.end(), back_inserter(myContainer));
259  delete *i;
260  }
261 }
262 
263 
264 
265 /****************************************************************************/
266