Line data Source code
1 : /****************************************************************************/
2 : // Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo
3 : // Copyright (C) 2010-2024 German Aerospace Center (DLR) and others.
4 : // activitygen module
5 : // Copyright 2010 TUM (Technische Universitaet Muenchen, http://www.tum.de/)
6 : // This program and the accompanying materials are made available under the
7 : // terms of the Eclipse Public License 2.0 which is available at
8 : // https://www.eclipse.org/legal/epl-2.0/
9 : // This Source Code may also be made available under the following Secondary
10 : // Licenses when the conditions for such availability set forth in the Eclipse
11 : // Public License 2.0 are satisfied: GNU General Public License, version 2
12 : // or later which is available at
13 : // https://www.gnu.org/licenses/old-licenses/gpl-2.0-standalone.html
14 : // SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later
15 : /****************************************************************************/
16 : /// @file AGActivityGen.cpp
17 : /// @author Piotr Woznica
18 : /// @author Daniel Krajzewicz
19 : /// @author Walter Bamberger
20 : /// @author Michael Behrisch
21 : /// @date July 2010
22 : ///
23 : // Main class that handles City, Activities and Trips
24 : /****************************************************************************/
25 : #include <config.h>
26 :
27 : #include <iostream>
28 : #include <utils/xml/XMLSubSys.h>
29 : #include <utils/common/MsgHandler.h>
30 : #include <utils/common/RandHelper.h>
31 : #include <sstream>
32 : #include "AGActivityGen.h"
33 : #include "AGActivityGenHandler.h"
34 : #include "city/AGPosition.h"
35 : #include "activities/AGActivities.h"
36 : #include "AGActivityTripWriter.h"
37 : #include "city/AGTime.h"
38 :
39 :
40 : // ===========================================================================
41 : // method definitions
42 : // ===========================================================================
43 : void
44 10 : AGActivityGen::importInfoCity() {
45 10 : AGActivityGenHandler handler(city, net);
46 20 : PROGRESS_BEGIN_MESSAGE(TL("Reading input"));
47 10 : if (!XMLSubSys::runParser(handler, inputFile)) {
48 1 : PROGRESS_FAILED_MESSAGE();
49 1 : throw ProcessError();
50 : } else {
51 9 : PROGRESS_DONE_MESSAGE();
52 : }
53 :
54 18 : PROGRESS_BEGIN_MESSAGE(TL("Consolidating statistics"));
55 9 : city.statData.consolidateStat(); //some maps are still not
56 9 : PROGRESS_DONE_MESSAGE();
57 :
58 18 : PROGRESS_BEGIN_MESSAGE(TL("Building street representation"));
59 9 : city.completeStreets();
60 9 : PROGRESS_DONE_MESSAGE();
61 :
62 18 : PROGRESS_BEGIN_MESSAGE(TL("Generating work positions"));
63 9 : city.generateWorkPositions();
64 9 : PROGRESS_DONE_MESSAGE();
65 :
66 18 : PROGRESS_BEGIN_MESSAGE(TL("Building bus lines"));
67 9 : city.completeBusLines();
68 9 : PROGRESS_DONE_MESSAGE();
69 :
70 :
71 18 : PROGRESS_BEGIN_MESSAGE(TL("Generating population"));
72 9 : city.generatePopulation();
73 9 : PROGRESS_DONE_MESSAGE();
74 :
75 18 : PROGRESS_BEGIN_MESSAGE(TL("Allocating schools"));
76 9 : city.schoolAllocation();
77 9 : PROGRESS_DONE_MESSAGE();
78 :
79 18 : PROGRESS_BEGIN_MESSAGE(TL("Allocating work places"));
80 9 : city.workAllocation();
81 9 : PROGRESS_DONE_MESSAGE();
82 :
83 18 : PROGRESS_BEGIN_MESSAGE(TL("Allocating car places"));
84 9 : city.carAllocation();
85 9 : PROGRESS_DONE_MESSAGE();
86 10 : }
87 :
88 : bool
89 7665 : AGActivityGen::timeTripValidation(const AGTrip& trip) const {
90 7665 : if (trip.getDay() > durationInDays + 1) {
91 : return false;
92 : }
93 7624 : if (trip.getDay() == 1) { //first day
94 3814 : if (trip.getTime() < beginTime) {
95 : return false;
96 : }
97 3814 : if (durationInDays == 0 && trip.getTime() > endTime) {
98 : return false;
99 : }
100 : }
101 7624 : if (trip.getDay() == durationInDays + 1) { //last day
102 3810 : if (trip.getTime() > endTime) {
103 : return false;
104 : }
105 0 : if (durationInDays == 0 && trip.getTime() < beginTime) {
106 : return false;
107 : }
108 : }
109 : return true;
110 : }
111 :
112 : void
113 7665 : AGActivityGen::varDepTime(AGTrip& trip) const {
114 7665 : if (trip.getType() != "default") {
115 3049 : return;
116 : }
117 : //buses are on time and random are already spread
118 4616 : int variation = (int)RandHelper::randNorm(0, city.statData.departureVariation);
119 4616 : AGTime depTime(trip.getDay(), 0, 0, trip.getTime());
120 4616 : depTime += variation;
121 4616 : if (depTime.getDay() > 0) {
122 4616 : trip.setDay(depTime.getDay());
123 4616 : trip.setDepTime(depTime.getSecondsInCurrentDay());
124 : } else {
125 0 : trip.setDay(1);
126 0 : trip.setDepTime(0);
127 : }
128 : }
129 :
130 :
131 : void
132 8 : AGActivityGen::generateOutputFile(std::list<AGTrip>& trips) {
133 8 : AGActivityTripWriter atw(outputFile);
134 8 : if (trips.size() != 0) {
135 : std::list<AGTrip>::iterator it;
136 : //variables for TESTS:
137 7 : int firstTrip = trips.front().getTime() + trips.front().getDay() * 86400;
138 7 : int lastTrip = trips.front().getTime() + trips.front().getDay() * 86400;
139 : std::map<int, int> histogram;
140 707 : for (int i = 0; i < 100; ++i) {
141 700 : histogram[i] = 0;
142 : }
143 : //END var TESTS
144 3821 : for (it = trips.begin(); it != trips.end(); ++it) {
145 3814 : atw.addTrip(*it);
146 : //TEST
147 3814 : if (it->getTime() + 86400 * it->getDay() > lastTrip) {
148 3198 : lastTrip = it->getTime() + 86400 * it->getDay();
149 : }
150 3814 : if (it->getTime() + 86400 * it->getDay() < firstTrip) {
151 0 : firstTrip = it->getTime() + 86400 * it->getDay();
152 : }
153 : //++histogram[((it->getDay()-1)*86400 + it->getTime())/3600];
154 3814 : ++histogram[(it->getTime()) / 3600];
155 : //END TEST
156 : }
157 : //PRINT TEST
158 : AGTime first(firstTrip);
159 : AGTime last(lastTrip);
160 28 : std::cout << "first real trip: " << first.getDay() << ", " << first.getHour() << ":" << first.getMinute() << ":" << first.getSecond() << std::endl;
161 28 : std::cout << "last real trip: " << last.getDay() << ", " << last.getHour() << ":" << last.getMinute() << ":" << last.getSecond() << std::endl;
162 707 : for (int i = 0; i < 100; ++i) {
163 700 : if (histogram[i] > 0) {
164 166 : std::cout << "histogram[ hour " << i << " ] = " << histogram[i] << std::endl;
165 : }
166 : }
167 : } else {
168 : std::cout << "No real trips were generated" << std::endl;
169 : }
170 8 : }
171 :
172 : void
173 9 : AGActivityGen::makeActivityTrips(int days, int beginSec, int endSec) {
174 9 : durationInDays = days;
175 9 : beginTime = beginSec;
176 9 : endTime = endSec;
177 : /**
178 : * making the activity trips
179 : */
180 9 : AGActivities acts(&city, durationInDays + 1);
181 9 : acts.generateActivityTrips();
182 :
183 : /**
184 : * validating the trips with the simulation's time limits
185 : */
186 : //list<Trip>* trips = &(acts.trips);
187 : std::list<AGTrip> expTrips;
188 : std::map<std::string, int> carUsed;
189 : std::list<AGTrip>::iterator it;
190 : //multiplication of days
191 4929 : for (it = acts.trips.begin(); it != acts.trips.end(); ++it) {
192 4921 : if (it->isDaily()) {
193 8232 : for (int currday = 1; currday < durationInDays + 2; ++currday) {
194 10976 : AGTrip tr(it->getDep(), it->getArr(), it->getVehicleName(), it->getTime(), currday);
195 10976 : tr.setType(it->getType());
196 5488 : if (carUsed.find(tr.getVehicleName()) != carUsed.end()) {
197 4469 : ++carUsed.find(tr.getVehicleName())->second;
198 : } else {
199 1019 : carUsed[tr.getVehicleName()] = 1;
200 : }
201 5488 : std::ostringstream os;
202 10976 : os << tr.getVehicleName() << ":" << carUsed.find(tr.getVehicleName())->second;
203 5488 : tr.setVehicleName(os.str());
204 5488 : tr.addLayOverWithoutDestination(*it); //intermediate destinations are taken in account too
205 5488 : varDepTime(tr); //slight variation on each "default" car
206 5488 : if (timeTripValidation(tr)) {
207 : expTrips.push_back(tr);
208 : }
209 : //else
210 : //std::cout << "trop tard 1 pour " << tr.getVehicleName() << " " << tr.getTime() << " day: " << tr.getDay() << std::endl;
211 5488 : }
212 : } else {
213 4354 : AGTrip tr(it->getDep(), it->getArr(), it->getVehicleName(), it->getTime(), it->getDay());
214 4354 : tr.setType(it->getType());
215 2177 : if (carUsed.find(tr.getVehicleName()) != carUsed.end()) {
216 500 : ++carUsed.find(tr.getVehicleName())->second;
217 : } else {
218 1677 : carUsed[tr.getVehicleName()] = 1;
219 : }
220 2177 : std::ostringstream os;
221 4354 : os << tr.getVehicleName() << ":" << carUsed.find(tr.getVehicleName())->second;
222 2177 : tr.setVehicleName(os.str());
223 2177 : tr.addLayOverWithoutDestination(*it); //intermediate destinations are taken in account too
224 2177 : varDepTime(tr); //slight variation on each "default" car
225 2177 : if (timeTripValidation(tr)) {
226 : expTrips.push_back(tr);
227 : }
228 : //else
229 : //std::cout << "trop tard 2 pour " << tr.getVehicleName() << " " << tr.getTime() << " day: " << tr.getDay() << std::endl;
230 2177 : }
231 : }
232 :
233 : std::cout << "total trips generated: " << acts.trips.size() << std::endl;
234 : std::cout << "total trips finally taken: " << expTrips.size() << std::endl;
235 :
236 : /**
237 : * re-ordering of trips: SUMO needs routes ordered by departure time.
238 : */
239 8 : expTrips.sort(); //natural order of trips
240 : std::cout << "...sorted by departure time.\n" << std::endl;
241 :
242 : /**
243 : * trip file generation
244 : */
245 8 : generateOutputFile(expTrips);
246 8 : }
247 :
248 :
249 : /****************************************************************************/
|