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 (CellVector::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 mrand = RandHelper::rand();
106  SUMOReal mprob = (SUMOReal) cell->vehicleNumber - (SUMOReal) vehicles2insert;
107  if (mrand < mprob) {
108  vehicles2insert++;
109  }
110 
111  SUMOReal offset = (SUMOReal)(cell->end - cell->begin) / (SUMOReal) vehicles2insert / (SUMOReal) 2.;
112  for (int i = 0; i < vehicles2insert; ++i) {
113  ODVehicle veh;
114  veh.id = prefix + toString(vehName++);
115 
116  if (uniform) {
117  veh.depart = (unsigned int)(offset + cell->begin + ((SUMOReal)(cell->end - cell->begin) * (SUMOReal) i / (SUMOReal) vehicles2insert));
118  } else {
119  veh.depart = (unsigned int) RandHelper::rand((int) cell->begin, (int) cell->end);
120  }
121 
124  veh.cell = cell;
125  into.push_back(veh);
126  }
127  return cell->vehicleNumber - vehicles2insert;
128 }
129 
130 
131 void
133  OutputDevice& dev, bool uniform, bool noVtype,
134  const std::string& prefix, bool stepLog) {
135  if (myContainer.size() == 0) {
136  return;
137  }
139  std::map<std::pair<std::string, std::string>, SUMOReal> fractionLeft;
140  size_t vehName = 0;
141  sort(myContainer.begin(), myContainer.end(), cell_by_begin_sorter());
142  // recheck begin time
143  ODCell* first = *myContainer.begin();
144  begin = MAX2(begin, first->begin);
145  CellVector::iterator next = myContainer.begin();
146  std::vector<ODVehicle> vehicles;
147  // go through the time steps
148  for (SUMOTime t = begin; t != end; t++) {
149  if (stepLog) {
150  std::cout << "Parsing time " + toString(t) << '\r';
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  std::vector<ODVehicle> tmp;
163  SUMOReal fraction = computeDeparts(*next, vehName, tmp, uniform, prefix);
164  // copy new departures if any
165  if (tmp.size() != 0) {
166  copy(tmp.begin(), tmp.end(), back_inserter(vehicles));
167  changed = true;
168  }
169  // save the fraction
170  if (fraction != 0) {
171  if (fractionLeft.find(odID) == fractionLeft.end()) {
172  fractionLeft[odID] = fraction;
173  } else {
174  fractionLeft[odID] += fraction;
175  }
176  }
177  //
178  ++next;
179  }
180  if (changed) {
181  sort(vehicles.begin(), vehicles.end(), descending_departure_comperator());
182  }
183  std::vector<ODVehicle>::reverse_iterator i = vehicles.rbegin();
184  for (; i != vehicles.rend() && (*i).depart == t; ++i) {
185  myNoWritten++;
186  dev.openTag("trip") << " id=\"" << (*i).id << "\" depart=\"" << t << ".00\" "
187  << "from=\"" << (*i).from << "\" "
188  << "to=\"" << (*i).to << "\"";
189  if (!noVtype && (*i).cell->vehicleType.length() != 0) {
190  dev << " type=\"" << (*i).cell->vehicleType << "\"";
191  }
192  dev << " fromTaz=\"" << (*i).cell->origin << "\"";
193  dev << " toTaz=\"" << (*i).cell->destination << "\"";
194  if (oc.isSet("departlane") && oc.getString("departlane") != "default") {
195  dev << " departLane=\"" << oc.getString("departlane") << "\"";
196  }
197  if (oc.isSet("departpos")) {
198  dev << " departPos=\"" << oc.getString("departpos") << "\"";
199  }
200  if (oc.isSet("departspeed") && oc.getString("departspeed") != "default") {
201  dev << " departSpeed=\"" << oc.getString("departspeed") << "\"";
202  }
203  if (oc.isSet("arrivallane")) {
204  dev << " arrivalLane=\"" << oc.getString("arrivallane") << "\"";
205  }
206  if (oc.isSet("arrivalpos")) {
207  dev << " arrivalPos=\"" << oc.getString("arrivalpos") << "\"";
208  }
209  if (oc.isSet("arrivalspeed")) {
210  dev << " arrivalSpeed=\"" << oc.getString("arrivalspeed") << "\"";
211  }
212  dev.closeTag(true);
213  }
214  while (vehicles.size() != 0 && (*vehicles.rbegin()).depart == t) {
215  vehicles.pop_back();
216  }
217  }
218 }
219 
220 
221 SUMOReal
223  return myNoLoaded;
224 }
225 
226 
227 SUMOReal
229  return myNoWritten;
230 }
231 
232 
233 SUMOReal
235  return myNoDiscarded;
236 }
237 
238 
239 void
241  for (size_t i = 0; i < ps.getAreaNo(); ++i) {
242  ODCell* ncell = new ODCell();
243  ncell->begin = (SUMOTime) ps.getAreaBegin(i);
244  ncell->end = (SUMOTime) ps.getAreaEnd(i);
245  ncell->origin = cell->origin;
246  ncell->destination = cell->destination;
247  ncell->vehicleType = cell->vehicleType;
248  ncell->vehicleNumber = cell->vehicleNumber * ps.getAreaPerc(i);
249  newCells.push_back(ncell);
250  }
251 }
252 
253 
254 void
256  CellVector oldCells = myContainer;
257  myContainer.clear();
258  for (CellVector::iterator i = oldCells.begin(); i != oldCells.end(); ++i) {
259  CellVector newCells;
260  applyCurve(ps, *i, newCells);
261  copy(newCells.begin(), newCells.end(), back_inserter(myContainer));
262  delete *i;
263  }
264 }
265 
266 
267 
268 /****************************************************************************/
269