SUMO - Simulation of Urban MObility
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
AGCity.cpp
Go to the documentation of this file.
1 /****************************************************************************/
10 // City class that contains all other objects of the city: in particular
11 // streets, households, bus lines, work positions and school
12 /****************************************************************************/
13 // SUMO, Simulation of Urban MObility; see http://sumo.sourceforge.net/
14 // Copyright (C) 2001-2012 DLR (http://www.dlr.de/) and contributors
15 // activitygen module
16 // Copyright 2010 TUM (Technische Universitaet Muenchen, http://www.tum.de/)
17 /****************************************************************************/
18 //
19 // This file is part of SUMO.
20 // SUMO is free software: you can redistribute it and/or modify
21 // it under the terms of the GNU General Public License as published by
22 // the Free Software Foundation, either version 3 of the License, or
23 // (at your option) any later version.
24 //
25 /****************************************************************************/
26 
27 
28 // ===========================================================================
29 // included modules
30 // ===========================================================================
31 #ifdef _MSC_VER
32 #include <windows_config.h>
33 #else
34 #include <config.h>
35 #endif
36 
37 #include <iostream>
38 #include <vector>
39 #include <string>
40 #include <map>
41 #include <iomanip>
43 #include <router/RONet.h>
44 #include <router/ROEdge.h>
45 #include "AGStreet.h"
46 #include "AGWorkPosition.h"
47 #include "AGCity.h"
48 //#define DRIVING_LICENSE_AGE 18
49 
50 
51 // ===========================================================================
52 // method definitions
53 // ===========================================================================
54 void
56  if (streetsCompleted) {
57  return;
58  } else {
59  streetsCompleted = true;
60  }
61 
62  NrStreets = 0;
63  int pop = 0, work = 0;
64  std::vector<AGStreet>::iterator it;
65 
66  for (it = streets.begin() ; it != streets.end() ; ++it) {
67  pop += (int)(it->getPopulation());
68  work += (int)(it->getWorkplaceNumber());
69  ++NrStreets;
70  }
72  //can be improved with other input data
73  SUMOReal neededWorkPositionsInCity = (1.0 - statData.unemployement)
76  + (float)statData.incomingTraffic;
77  // we generate 5% more work positions that really needed: to avoid any expensive research of random work positions
78  neededWorkPositionsInCity *= 1.05f;
79  statData.workPositions = (int)neededWorkPositionsInCity;
80  statData.factorWorkPositions = neededWorkPositionsInCity / (float) work;
81 
82  for (it = streets.begin() ; it != streets.end() ; ++it) {
83  it->setPopulation((int)(it->getPopulation() * statData.factorInhabitants));
84  it->setWorkplaceNumber((int)(it->getWorkplaceNumber() * statData.factorWorkPositions));
85  //it->print();
86  }
87 
88  //completing streets from edges of the network not handled/present in STAT file (no population no work position)
89  std::map<std::string, ROEdge*>::const_iterator itE;
90  std::vector<AGStreet>::iterator itS;
91 
92  for (itE = net->getEdgeMap().begin() ; itE != net->getEdgeMap().end() ; ++itE) {
93  for (itS = streets.begin() ; itS != streets.end() ; ++itS) {
94  if (itS->getName() == itE->second->getID()) {
95  break;
96  }
97  }
98  //if this edge isn't represented by a street
99  if (itS == streets.end()) {
100  streets.push_back(AGStreet(itE->second));
101  }
102  }
103 }
104 
105 void
107  std::vector<AGStreet>::iterator it;
108  int workPositionCounter = 0;
109 
110  try {
111  for (it = streets.begin() ; it != streets.end() ; ++it) {
112  //std::cout << "number of work positions in street: " << it->getWorkplaceNumber() << std::endl;
113  for (int i = 0 ; i < it->getWorkplaceNumber() ; ++i) {
114  workPositions.push_back(AGWorkPosition(*it, &statData));
115  ++workPositionCounter;
116  }
117  }
118  } catch (const std::bad_alloc& e) {
119  std::cout << "Number of work positions at bad_alloc exception: " << workPositionCounter << std::endl;
120  throw(e);
121  }
122  //std::cout << "Inner work positions done. " << workPositionCounter << " generated." << std::endl;
123 
124  // Work positions outside the city
126  std::cout << "--> work position: " << std::endl;
127  std::cout << " |-> in city: " << workPositionCounter << std::endl;
128  std::cout << " |-> out city: " << statData.workPositions - workPositionCounter << std::endl;
129  std::cout << " |-> in+out city: " << statData.workPositions << std::endl;
130 }
131 
132 void
134  // work positions outside the city
136  if (nbrWorkers <= 0) {
137  return;
138  }
139  nbrWorkers *= (1.0 - statData.unemployement);
143  int nbrOutWorkPositions = static_cast<int>(workPositions.size() * (static_cast<float>(statData.outgoingTraffic)) / (nbrWorkers - static_cast<float>(statData.outgoingTraffic)));
144 
145  if (cityGates.empty()) {
146  return;
147  }
148 
149  for (int i = 0 ; i < nbrOutWorkPositions ; ++i) {
151  workPositions.push_back(AGWorkPosition(cityGates[posi].getStreet(), cityGates[posi].getPosition(), &statData));
152  }
153  //cout << "outgoing traffic: " << statData.outgoingTraffic << std::endl;
154  //cout << "total number of workers in the city: " << nbrWorkers << std::endl;
155  //cout << "work positions out side the city: " << nbrOutWorkPositions << std::endl;
156  //cout << "work positions in and out of the city: " << workPositions.size() << std::endl;
157  statData.workPositions = static_cast<int>(workPositions.size());
158 }
159 
160 void
162  std::list<AGBusLine>::iterator it;
163  for (it = busLines.begin() ; it != busLines.end() ; ++it) {
164  //it->generateOpositDirection();
165  it->setBusNames();
166  }
167 }
168 
169 void
171  std::vector<AGStreet>::iterator it;
172  int people;
173  nbrCars = 0;
174  int idHouseholds = 0;
175 
176  for (it = streets.begin() ; it != streets.end() ; ++it) {
177  people = it->getPopulation();
178  while (people > 0) {
179  ++idHouseholds;
180  households.push_back(AGHousehold(&*it, this, idHouseholds));
181  households.back().generatePeople(); //&statData
182  //households.back().generateCars(statData.carRate);
183  people -= households.back().getPeopleNbr();
184  }
185  }
186 
187  //people from outside of the city generation:
189 
190  //TEST
191  int nbrSingle = 0;
192  int nbrCouple = 0;
193  int nbrChild = 0;
194  int nbrHH = 0;
195  int workingP = 0;
196  std::list<AGHousehold>::iterator itt;
197  for (itt = households.begin() ; itt != households.end() ; ++itt) {
198  if (itt->getAdultNbr() == 1) {
199  nbrSingle++;
200  if (itt->adults.front().isWorking()) {
201  workingP++;
202  }
203  }
204  if (itt->getAdultNbr() == 2) {
205  nbrCouple += 2;
206  if (itt->adults.front().isWorking()) {
207  workingP++;
208  }
209  if (itt->adults.back().isWorking()) {
210  workingP++;
211  }
212  }
213  nbrChild += itt->getPeopleNbr() - itt->getAdultNbr();
214  nbrHH++;
215  }
216  //cout << "number hh: " << nbrHH << std::endl;
217  //cout << "number single: " << nbrSingle << std::endl;
218  //cout << "number couple: " << nbrCouple << std::endl;
219  //cout << "number 3 or more: " << nbr3More << std::endl;
220  //cout << "number adults: " << nbrSingle + nbrCouple + nbr3More << std::endl;
221  //cout << "number children: " << nbrChild << std::endl;
222  //cout << "number people: " << nbrSingle + nbrCouple + nbr3More + nbrChild << std::endl;
223  //END TEST
224 
225  std::cout << "--> population: " << std::endl;
226  std::cout << " |-> city households: " << nbrHH << std::endl;
227  std::cout << " |-> city people: " << nbrSingle + nbrCouple + nbrChild << std::endl;
228  std::cout << " |-> city single: " << nbrSingle << " / (in) couple: " << nbrCouple << std::endl;
229  std::cout << " |-> city adults: " << nbrSingle + nbrCouple << std::endl;
230  std::cout << " |-> estimation: " << statData.getPeopleOlderThan(statData.limitAgeChildren) << std::endl;
231  std::cout << " |-> retired: " << statData.getPeopleOlderThan(statData.limitAgeRetirement) << std::endl;
232  std::cout << " |-> city children: " << nbrChild << std::endl;
233  std::cout << " |-> estimation: " << statData.getPeopleYoungerThan(statData.limitAgeChildren) << std::endl;
234 
235 }
236 
237 void
239  for (int i = 0 ; i < statData.incomingTraffic ; ++i) {
241  peopleIncoming.push_back(ad);
242  }
243 }
244 
245 void
247  std::list<AGHousehold>::iterator it;
248  bool shortage;
249  for (it = households.begin() ; it != households.end() ; ++it) {
250  shortage = !it->allocateChildrenSchool();
251  if (shortage) {
252  /*ofstream fichier("test.txt", ios::app); // ouverture en écriture avec effacement du fichier ouvert
253  if(fichier)
254  {
255  fichier << "===> WARNING: Not enough school places in the city for all children..." << std::endl;
256  fichier.close();
257  }
258  else
259  cerr << "Impossible d'ouvrir le fichier !" << std::endl;*/
260 
261  //std::cout << "===> WARNING: Not enough school places in the city for all children..." << std::endl;
262  }
263  }
264 }
265 
266 void
268  statData.AdultNbr = 0;
269  //end tests
273  std::list<AGHousehold>::iterator it;
274  bool shortage;
275 
276  for (it = households.begin() ; it != households.end() ; ++it) {
277  if (it->retiredHouseholders()) {
278  continue;
279  }
280  shortage = !it->allocateAdultsWork();
281  if (shortage) {
282  std::cout << "===> ERROR: Not enough work positions in the city for all working people..." << std::endl;
283  }
284  statData.AdultNbr += it->getAdultNbr(); //TESTING
285  }
286 
290  std::list<AGAdult>::iterator itA;
291  for (itA = peopleIncoming.begin() ; itA != peopleIncoming.end() ; ++itA) {
292  if (statData.workPositions > 0) {
293  itA->tryToWork(1, &workPositions);
294  } else {
295  //shouldn't happen
296  std::cout << "not enough work for incoming people..." << std::endl;
297  }
298  }
299 
300  //BEGIN TESTS
301  int workingP = 0;
302  std::list<AGHousehold>::iterator itt;
303  for (itt = households.begin() ; itt != households.end() ; ++itt) {
304  if (itt->getAdultNbr() == 1) {
305  if (itt->adults.front().isWorking()) {
306  workingP++;
307  }
308  }
309  if (itt->getAdultNbr() == 2) {
310  if (itt->adults.front().isWorking()) {
311  workingP++;
312  }
313  if (itt->adults.back().isWorking()) {
314  workingP++;
315  }
316  }
317  }
318  std::cout << " |-> working people: " << peopleIncoming.size() + workingP << std::endl;
319  std::cout << " |-> working people in city: " << workingP << std::endl;
320  std::cout << " |-> working people from outside: " << peopleIncoming.size() << std::endl;
321  //END TESTS
322 }
323 
324 void
326  statData.hhFarFromPT = 0;
327  nbrCars = 0;
328  std::list<AGHousehold>::iterator it;
329  for (it = households.begin() ; it != households.end() ; ++it) {
330  if (!it->isCloseFromPubTransport(&(statData.busStations))) {
332  nbrCars++;
333  it->addACar();
334  }
336  }
337  // new rate: the rate on the people that have'nt any car yet:
338  // nR = (R * Drivers - AlreadyCars) / (Drivers - AlreadyCars)
340  //std::cout << " - " << newRate << std::endl;
341  if (newRate < 0 || newRate >= 1) {
342  newRate = 0;
343  }
344 
345  nbrCars = 0;
346  int nbrAdults = 0;
347  for (it = households.begin() ; it != households.end() ; ++it) {
348  it->generateCars(newRate);
349  nbrCars += it->getCarNbr();
350  nbrAdults += it->getAdultNbr();
351  }
352  //TEST RESULTS
353  //std::cout << "number of cars: " << nbrCars << std::endl;
354  //std::cout << "number of adults: " << statData.getPeopleOlderThan(statData.limitAgeChildren) << std::endl;
355  //std::cout << "real number of adults: " << nbrAdults << std::endl;
356  //std::cout << "number of people far from public transport: " << statData.hhFarFromPT << std::endl;
357  //std::cout << "original rate: " << setprecision(4) << statData.carRate << std::endl;
358  //std::cout << "new rate: " << setprecision(4) << newRate << std::endl;
359  //std::cout << "real rate: " << setprecision(4) << (float)nbrCars / (float)statData.getPeopleOlderThan(statData.limitAgeChildren) << std::endl;
360  //END TEST RESULTS
361 }
362 
363 const AGStreet&
364 AGCity::getStreet(const std::string& edge) {
371  if (!streetsCompleted) {
373  completeStreets();
374  std::cout << "first completed in getStreet() of City: Consolidation of data not needed in ActivityGen any more" << std::endl;
375  }
376  //rest of the function
377  std::vector<AGStreet>::iterator it = streets.begin();
378  while (it != streets.end()) {
379  if (it->getName() == edge) {
380  return *it;
381  }
382  ++it;
383  }
384  std::cout << "===> ERROR: WRONG STREET EDGE (" << edge << ") given and not found in street set." << std::endl;
385  throw(std::runtime_error("Street not found with edge id " + edge));
386 }
387 
388 const AGStreet&
390  if (streets.empty()) {
391  throw(std::runtime_error("No street found in this city"));
392  }
393  return streets[RandHelper::rand(streets.size())];
394 }
395 
396 /****************************************************************************/