Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
eclipse
GitHub Repository: eclipse/sumo
Path: blob/main/src/netedit/elements/demand/GNERouteHandler.cpp
185790 views
1
/****************************************************************************/
2
// Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo
3
// Copyright (C) 2001-2025 German Aerospace Center (DLR) and others.
4
// This program and the accompanying materials are made available under the
5
// terms of the Eclipse Public License 2.0 which is available at
6
// https://www.eclipse.org/legal/epl-2.0/
7
// This Source Code may also be made available under the following Secondary
8
// Licenses when the conditions for such availability set forth in the Eclipse
9
// Public License 2.0 are satisfied: GNU General Public License, version 2
10
// or later which is available at
11
// https://www.gnu.org/licenses/old-licenses/gpl-2.0-standalone.html
12
// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later
13
/****************************************************************************/
14
/// @file GNERouteHandler.cpp
15
/// @author Pablo Alvarez Lopez
16
/// @date Jan 2019
17
///
18
// Builds demand objects for netedit
19
/****************************************************************************/
20
21
#include <netedit/changes/GNEChange_DemandElement.h>
22
#include <netedit/dialogs/basic/GNEOverwriteElement.h>
23
#include <netedit/dialogs/basic/GNEWarningBasicDialog.h>
24
#include <netedit/frames/common/GNEInspectorFrame.h>
25
#include <netedit/frames/GNEAttributesEditor.h>
26
#include <netedit/GNEApplicationWindow.h>
27
#include <netedit/GNENet.h>
28
#include <netedit/GNEUndoList.h>
29
#include <netedit/GNEViewParent.h>
30
#include <utils/xml/NamespaceIDs.h>
31
32
#include "GNEContainer.h"
33
#include "GNEPerson.h"
34
#include "GNEPersonTrip.h"
35
#include "GNERide.h"
36
#include "GNERoute.h"
37
#include "GNERouteRef.h"
38
#include "GNERouteDistribution.h"
39
#include "GNERouteHandler.h"
40
#include "GNEStop.h"
41
#include "GNEStopPlan.h"
42
#include "GNETranship.h"
43
#include "GNETransport.h"
44
#include "GNEVType.h"
45
#include "GNEVTypeRef.h"
46
#include "GNEVTypeDistribution.h"
47
#include "GNEVehicle.h"
48
#include "GNEWalk.h"
49
50
51
// ===========================================================================
52
// member method definitions
53
// ===========================================================================
54
55
GNERouteHandler::GNERouteHandler(GNENet* net, FileBucket* bucket, const bool allowUndoRedo, const bool removeEmptyPersons) :
56
RouteHandler(bucket, false),
57
myNet(net),
58
myPlanObject(new CommonXMLStructure::SumoBaseObject(nullptr)),
59
myAllowUndoRedo(allowUndoRedo),
60
myRemoveEmptyPersons(removeEmptyPersons) {
61
}
62
63
64
GNERouteHandler::~GNERouteHandler() {
65
// check if clear all parent plan elements without children
66
if (myRemoveEmptyPersons) {
67
for (const auto& parentPlanElement : myParentPlanElements) {
68
if (parentPlanElement->getChildDemandElements().empty()) {
69
if (myAllowUndoRedo) {
70
myNet->getUndoList()->begin(parentPlanElement, TLF("delete % '%'", parentPlanElement->getTagStr(), parentPlanElement->getID()));
71
myNet->getUndoList()->add(new GNEChange_DemandElement(parentPlanElement, false), true);
72
myNet->getUndoList()->end();
73
} else {
74
parentPlanElement->decRef("postParserTasks");
75
myNet->getAttributeCarriers()->deleteDemandElement(parentPlanElement, false);
76
}
77
}
78
}
79
}
80
// update options based in current buckets
81
myNet->getGNEApplicationWindow()->getFileBucketHandler()->updateOptions();
82
// delete plan object
83
delete myPlanObject;
84
}
85
86
bool
87
GNERouteHandler::buildVType(const CommonXMLStructure::SumoBaseObject* sumoBaseObject, const SUMOVTypeParameter& vTypeParameter) {
88
// check if loaded type is a default type
89
if (DEFAULT_VTYPES.count(vTypeParameter.id) > 0) {
90
// overwrite default vehicle type
91
return GNEVType::overwriteVType(myNet->getAttributeCarriers()->retrieveDemandElement(SUMO_TAG_VTYPE, vTypeParameter.id, false), vTypeParameter, myNet->getUndoList());
92
} else {
93
const auto element = retrieveDemandElement(NamespaceIDs::types, vTypeParameter.id);
94
if (!checkElement(SUMO_TAG_VTYPE, element)) {
95
return false;
96
} else if (!checkValidDemandElementID(SUMO_TAG_VTYPE, vTypeParameter.id)) {
97
return false;
98
} else {
99
// create vType/pType using myCurrentVType
100
GNEDemandElement* vType = new GNEVType(myNet, myFileBucket, vTypeParameter);
101
// if this vType was created within a vType distribution, we have to create an extra vTypeRef
102
GNEDemandElement* vTypeRef = nullptr;
103
GNEDemandElement* distributionParent = nullptr;
104
if (sumoBaseObject && sumoBaseObject->getParentSumoBaseObject() && (sumoBaseObject->getParentSumoBaseObject()->getTag() == SUMO_TAG_VTYPE_DISTRIBUTION)) {
105
const auto& vTypeDistributionID = sumoBaseObject->getParentSumoBaseObject()->getStringAttribute(SUMO_ATTR_ID);
106
distributionParent = myNet->getAttributeCarriers()->retrieveDemandElement(SUMO_TAG_VTYPE_DISTRIBUTION, vTypeDistributionID, false);
107
if (distributionParent) {
108
// create vType reference without probability
109
vTypeRef = new GNEVTypeRef(distributionParent, vType);
110
} else {
111
WRITE_WARNING(TLF("VType '%' with probability % cannot be referenced with distribution '%'", vTypeParameter.id, toString(vTypeParameter.defaultProbability), vTypeDistributionID));
112
}
113
}
114
if (myAllowUndoRedo) {
115
myNet->getUndoList()->begin(vType, TLF("add % '%'", vType->getTagStr(), vTypeParameter.id));
116
myNet->getUndoList()->add(new GNEChange_DemandElement(vType, true), true);
117
if (vTypeRef) {
118
myNet->getUndoList()->add(new GNEChange_DemandElement(vTypeRef, true), true);
119
}
120
myNet->getUndoList()->end();
121
} else {
122
myNet->getAttributeCarriers()->insertDemandElement(vType);
123
if (vTypeRef) {
124
distributionParent->addChildElement(vTypeRef);
125
vType->addChildElement(vTypeRef);
126
}
127
vType->incRef("buildVType");
128
}
129
return true;
130
}
131
}
132
}
133
134
135
bool
136
GNERouteHandler::buildVTypeRef(const CommonXMLStructure::SumoBaseObject* sumoBaseObject, const std::string& vTypeID, const double probability) {
137
const auto distribution = getVTypeDistributionParent(sumoBaseObject);
138
// the referenced element can be either a vType or a vTypeDistribution
139
const auto refElement = myNet->getAttributeCarriers()->retrieveDemandElements({SUMO_TAG_VTYPE, SUMO_TAG_VTYPE_DISTRIBUTION}, vTypeID, false);
140
// check distributions
141
if (distribution == nullptr) {
142
return writeErrorInvalidParent(GNE_TAG_VTYPEREF, {SUMO_TAG_VTYPE_DISTRIBUTION});
143
} else if (refElement) {
144
// create distributions
145
GNEDemandElement* vTypeRef = new GNEVTypeRef(distribution, refElement, probability);
146
if (myAllowUndoRedo) {
147
myNet->getUndoList()->begin(vTypeRef, TLF("add % '%'", vTypeRef->getTagStr(), distribution->getID()));
148
myNet->getUndoList()->add(new GNEChange_DemandElement(vTypeRef, true), true);
149
myNet->getUndoList()->end();
150
} else {
151
myNet->getAttributeCarriers()->insertDemandElement(vTypeRef);
152
distribution->addChildElement(vTypeRef);
153
refElement->addChildElement(vTypeRef);
154
vTypeRef->incRef("buildVTypeRef");
155
}
156
return true;
157
} else {
158
return writeErrorInvalidParent(GNE_TAG_VTYPEREF, {SUMO_TAG_VTYPE, SUMO_TAG_VTYPE_DISTRIBUTION}, vTypeID);
159
}
160
}
161
162
163
bool
164
GNERouteHandler::buildVTypeDistribution(const CommonXMLStructure::SumoBaseObject* /*sumoBaseObject*/, const std::string& id, const int deterministic) {
165
// check conditions
166
const auto element = retrieveDemandElement(NamespaceIDs::types, id);
167
if (!checkElement(SUMO_TAG_VTYPE_DISTRIBUTION, element)) {
168
return false;
169
} else if (!checkValidDemandElementID(SUMO_TAG_VTYPE_DISTRIBUTION, id)) {
170
return false;
171
} else {
172
// create distributions
173
GNEVTypeDistribution* vTypeDistribution = new GNEVTypeDistribution(id, myNet, myFileBucket, deterministic);
174
if (myAllowUndoRedo) {
175
myNet->getUndoList()->begin(vTypeDistribution, TLF("add % '%'", vTypeDistribution->getTagStr(), id));
176
myNet->getUndoList()->add(new GNEChange_DemandElement(vTypeDistribution, true), true);
177
myNet->getUndoList()->end();
178
} else {
179
myNet->getAttributeCarriers()->insertDemandElement(vTypeDistribution);
180
vTypeDistribution->incRef("buildVTypeDistribution");
181
}
182
return true;
183
}
184
}
185
186
187
bool
188
GNERouteHandler::buildRoute(const CommonXMLStructure::SumoBaseObject* sumoBaseObject, const std::string& id, SUMOVehicleClass vClass,
189
const std::vector<std::string>& edgeIDs, const RGBColor& color, const int repeat, const SUMOTime cycleTime,
190
const double probability, const Parameterised::Map& routeParameters) {
191
// check conditions
192
const auto element = retrieveDemandElement(NamespaceIDs::routes, id);
193
if (!checkElement(SUMO_TAG_ROUTE, element)) {
194
return false;
195
} else if (!checkValidDemandElementID(SUMO_TAG_ROUTE, id)) {
196
return false;
197
} else if (!checkNegative(SUMO_TAG_ROUTE, id, SUMO_ATTR_REPEAT, repeat, true)) {
198
return false;
199
} else {
200
// parse edges
201
const auto edges = parseEdges(SUMO_TAG_ROUTE, id, edgeIDs);
202
// check edges
203
const auto validEdges = GNERoute::isRouteValid(edges);
204
// continue depending if route is valid
205
if (validEdges.size() > 0) {
206
return writeError(TLF("Could not build % with ID '%' in netedit; %.", toString(SUMO_TAG_ROUTE), id, validEdges));
207
} else {
208
// create GNERoute
209
GNEDemandElement* route = new GNERoute(id, myNet, myFileBucket, vClass, edges, color, repeat, cycleTime, probability, routeParameters);
210
// if this route was created within a route distribution, we have to create an extra routeRef
211
GNEDemandElement* routeRef = nullptr;
212
GNEDemandElement* distributionParent = nullptr;
213
if (sumoBaseObject && sumoBaseObject->getParentSumoBaseObject() && (sumoBaseObject->getParentSumoBaseObject()->getTag() == SUMO_TAG_ROUTE_DISTRIBUTION)) {
214
const auto& routeDistributionID = sumoBaseObject->getParentSumoBaseObject()->getStringAttribute(SUMO_ATTR_ID);
215
distributionParent = myNet->getAttributeCarriers()->retrieveDemandElement(SUMO_TAG_ROUTE_DISTRIBUTION, routeDistributionID, false);
216
if (distributionParent) {
217
// create route reference without probability
218
routeRef = new GNERouteRef(distributionParent, route);
219
} else {
220
WRITE_WARNING(TLF("Route '%' with probability % cannot be referenced with distribution '%'", id, toString(probability), routeDistributionID));
221
}
222
}
223
if (myAllowUndoRedo) {
224
myNet->getUndoList()->begin(route, TLF("add % '%'", route->getTagStr(), id));
225
myNet->getUndoList()->add(new GNEChange_DemandElement(route, true), true);
226
if (routeRef) {
227
myNet->getUndoList()->add(new GNEChange_DemandElement(routeRef, true), true);
228
}
229
myNet->getUndoList()->end();
230
} else {
231
myNet->getAttributeCarriers()->insertDemandElement(route);
232
for (const auto& edge : edges) {
233
edge->addChildElement(route);
234
}
235
if (routeRef) {
236
distributionParent->addChildElement(routeRef);
237
route->addChildElement(routeRef);
238
}
239
route->incRef("buildRoute");
240
}
241
return true;
242
}
243
}
244
245
}
246
247
248
bool
249
GNERouteHandler::buildRouteRef(const CommonXMLStructure::SumoBaseObject* sumoBaseObject, const std::string& routeID, const double probability) {
250
const auto distribution = getRouteDistributionParent(sumoBaseObject);
251
// the referenced element can be either a route or a routeDistribution
252
const auto refElement = myNet->getAttributeCarriers()->retrieveDemandElements({SUMO_TAG_ROUTE, SUMO_TAG_ROUTE_DISTRIBUTION}, routeID, false);
253
// check distributions
254
if (distribution == nullptr) {
255
return writeErrorInvalidParent(GNE_TAG_ROUTEREF, {SUMO_TAG_ROUTE_DISTRIBUTION});
256
} else if (refElement) {
257
// create distributions
258
GNEDemandElement* routeRef = new GNERouteRef(distribution, refElement, probability);
259
if (myAllowUndoRedo) {
260
myNet->getUndoList()->begin(routeRef, TLF("add % in '%'", routeRef->getTagStr(), distribution->getID()));
261
myNet->getUndoList()->add(new GNEChange_DemandElement(routeRef, true), true);
262
myNet->getUndoList()->end();
263
} else {
264
myNet->getAttributeCarriers()->insertDemandElement(routeRef);
265
distribution->addChildElement(routeRef);
266
refElement->addChildElement(routeRef);
267
routeRef->incRef("buildRouteRef");
268
}
269
return true;
270
} else {
271
return writeErrorInvalidParent(GNE_TAG_ROUTEREF, {SUMO_TAG_ROUTE, SUMO_TAG_ROUTE_DISTRIBUTION}, routeID);
272
}
273
}
274
275
276
bool
277
GNERouteHandler::buildRouteDistribution(const CommonXMLStructure::SumoBaseObject* /*sumoBaseObject*/, const std::string& id) {
278
// check conditions
279
const auto element = retrieveDemandElement(NamespaceIDs::routes, id);
280
if (!checkElement(SUMO_TAG_ROUTE_DISTRIBUTION, element)) {
281
return false;
282
} else if (!checkValidDemandElementID(SUMO_TAG_ROUTE_DISTRIBUTION, id)) {
283
return false;
284
} else {
285
// create distributions
286
GNERouteDistribution* routeDistribution = new GNERouteDistribution(id, myNet, myFileBucket);
287
if (myAllowUndoRedo) {
288
myNet->getUndoList()->begin(routeDistribution, TLF("add % '%'", routeDistribution->getTagStr(), id));
289
myNet->getUndoList()->add(new GNEChange_DemandElement(routeDistribution, true), true);
290
myNet->getUndoList()->end();
291
} else {
292
myNet->getAttributeCarriers()->insertDemandElement(routeDistribution);
293
routeDistribution->incRef("buildRouteDistribution");
294
}
295
return true;
296
}
297
}
298
299
300
bool
301
GNERouteHandler::buildVehicleOverRoute(const CommonXMLStructure::SumoBaseObject* /*sumoBaseObject*/, const SUMOVehicleParameter& vehicleParameters) {
302
// check conditions
303
const auto element = retrieveDemandElement(NamespaceIDs::vehicles, vehicleParameters.id);
304
if (!checkElement(SUMO_TAG_VEHICLE, element)) {
305
return false;
306
} else if (!checkValidDemandElementID(SUMO_TAG_VEHICLE, vehicleParameters.id)) {
307
return false;
308
} else {
309
// obtain routes and vtypes
310
GNEDemandElement* type = getType(vehicleParameters.vtypeid);
311
GNEDemandElement* route = getRoute(vehicleParameters.routeid);
312
if (type == nullptr) {
313
return writeErrorInvalidParent(SUMO_TAG_VEHICLE, vehicleParameters.id, {SUMO_TAG_VTYPE, SUMO_TAG_VTYPE_DISTRIBUTION}, vehicleParameters.vtypeid);
314
} else if (route == nullptr) {
315
return writeErrorInvalidParent(SUMO_TAG_VEHICLE, vehicleParameters.id, {SUMO_TAG_ROUTE, SUMO_TAG_ROUTE_DISTRIBUTION}, vehicleParameters.routeid);
316
} else if (vehicleParameters.wasSet(VEHPARS_DEPARTLANE_SET) && (vehicleParameters.departLaneProcedure == DepartLaneDefinition::GIVEN) && ((int)route->getParentEdges().front()->getChildLanes().size() < vehicleParameters.departLane)) {
317
return writeError(TLF("Invalid % used in % '%'. % is greater than number of lanes", toString(SUMO_ATTR_DEPARTLANE), toString(vehicleParameters.tag), vehicleParameters.id, toString(vehicleParameters.departLane)));
318
} else if (vehicleParameters.wasSet(VEHPARS_DEPARTSPEED_SET) && (vehicleParameters.departSpeedProcedure == DepartSpeedDefinition::GIVEN) && (type->getAttributeDouble(SUMO_ATTR_MAXSPEED) < vehicleParameters.departSpeed)) {
319
return writeError(TLF("Invalid % used in % '%'. % is greater than type %", toString(SUMO_ATTR_DEPARTSPEED), toString(vehicleParameters.tag), vehicleParameters.id, toString(vehicleParameters.departSpeed), toString(SUMO_ATTR_MAXSPEED)));
320
} else {
321
// create vehicle using vehicleParameters
322
GNEDemandElement* vehicle = new GNEVehicle(SUMO_TAG_VEHICLE, myNet, myFileBucket, type, route, vehicleParameters);
323
if (myAllowUndoRedo) {
324
myNet->getUndoList()->begin(vehicle, TLF("add % '%'", vehicle->getTagStr(), vehicleParameters.id));
325
myNet->getUndoList()->add(new GNEChange_DemandElement(vehicle, true), true);
326
myNet->getUndoList()->end();
327
} else {
328
myNet->getAttributeCarriers()->insertDemandElement(vehicle);
329
// set vehicle as child of type and Route
330
type->addChildElement(vehicle);
331
route->addChildElement(vehicle);
332
vehicle->incRef("buildVehicleOverRoute");
333
}
334
return true;
335
}
336
}
337
}
338
339
340
bool
341
GNERouteHandler::buildVehicleEmbeddedRoute(const CommonXMLStructure::SumoBaseObject* /*sumoBaseObject*/, const SUMOVehicleParameter& vehicleParameters,
342
const std::vector<std::string>& edgeIDs, const RGBColor& color, const int repeat, const SUMOTime cycleTime,
343
const Parameterised::Map& routeParameters) {
344
// check conditions
345
const auto element = retrieveDemandElement(NamespaceIDs::vehicles, vehicleParameters.id);
346
if (!checkElement(GNE_TAG_VEHICLE_WITHROUTE, element)) {
347
return false;
348
} else if (!checkValidDemandElementID(GNE_TAG_VEHICLE_WITHROUTE, vehicleParameters.id)) {
349
return false;
350
} else {
351
// parse route edges
352
const auto edges = parseEdges(GNE_TAG_ROUTE_EMBEDDED, vehicleParameters.id, edgeIDs);
353
// check edges
354
const auto validEdges = GNERoute::isRouteValid(edges);
355
// continue depending if route is valid
356
if (validEdges.size() > 0) {
357
return writeError(TLF("Could not build % with ID '%' in netedit; %.", toString(GNE_TAG_VEHICLE_WITHROUTE), vehicleParameters.id, validEdges));
358
} else {
359
// obtain type
360
GNEDemandElement* type = getType(vehicleParameters.vtypeid);
361
if (type == nullptr) {
362
return writeErrorInvalidParent(GNE_TAG_VEHICLE_WITHROUTE, vehicleParameters.id, {SUMO_TAG_VTYPE, SUMO_TAG_VTYPE_DISTRIBUTION}, vehicleParameters.vtypeid);
363
} else if (vehicleParameters.wasSet(VEHPARS_DEPARTLANE_SET) && (vehicleParameters.departLaneProcedure == DepartLaneDefinition::GIVEN) && ((int)edges.front()->getChildLanes().size() < vehicleParameters.departLane)) {
364
return writeError(TLF("Invalid % used in % '%'. % is greater than number of lanes", toString(SUMO_ATTR_DEPARTLANE), toString(vehicleParameters.tag), vehicleParameters.id, toString(vehicleParameters.departLane)));
365
} else if (vehicleParameters.wasSet(VEHPARS_DEPARTSPEED_SET) && (vehicleParameters.departSpeedProcedure == DepartSpeedDefinition::GIVEN) && (type->getAttributeDouble(SUMO_ATTR_MAXSPEED) < vehicleParameters.departSpeed)) {
366
return writeError(TLF("Invalid % used in % '%'. % is greater than type %", toString(SUMO_ATTR_DEPARTSPEED), toString(vehicleParameters.tag), vehicleParameters.id, toString(vehicleParameters.departSpeed), toString(SUMO_ATTR_MAXSPEED)));
367
} else {
368
// create vehicle using vehicleParameters
369
GNEDemandElement* vehicle = new GNEVehicle(GNE_TAG_VEHICLE_WITHROUTE, myNet, myFileBucket, type, vehicleParameters);
370
// create embedded route
371
GNEDemandElement* route = new GNERoute(vehicle, edges, color, repeat, cycleTime, routeParameters);
372
if (myAllowUndoRedo) {
373
myNet->getUndoList()->begin(vehicle, TLF("add % '%'", vehicle->getTagStr(), vehicleParameters.id));
374
myNet->getUndoList()->add(new GNEChange_DemandElement(vehicle, true), true);
375
myNet->getUndoList()->add(new GNEChange_DemandElement(route, true), true);
376
myNet->getUndoList()->end();
377
} else {
378
myNet->getAttributeCarriers()->insertDemandElement(vehicle);
379
myNet->getAttributeCarriers()->insertDemandElement(route);
380
type->addChildElement(vehicle);
381
vehicle->addChildElement(route);
382
for (const auto& edge : edges) {
383
edge->addChildElement(route);
384
}
385
vehicle->incRef("buildVehicleEmbeddedRoute");
386
route->incRef("buildVehicleEmbeddedRoute");
387
}
388
return true;
389
}
390
}
391
}
392
}
393
394
395
bool
396
GNERouteHandler::buildFlowOverRoute(const CommonXMLStructure::SumoBaseObject* /*sumoBaseObject*/, const SUMOVehicleParameter& vehicleParameters) {
397
// check conditions
398
const auto element = retrieveDemandElement(NamespaceIDs::vehicles, vehicleParameters.id);
399
if (!checkElement(GNE_TAG_FLOW_ROUTE, element)) {
400
return false;
401
} else if (!checkValidDemandElementID(GNE_TAG_FLOW_ROUTE, vehicleParameters.id)) {
402
return false;
403
} else {
404
// obtain routes and vtypes
405
GNEDemandElement* type = getType(vehicleParameters.vtypeid);
406
GNEDemandElement* route = getRoute(vehicleParameters.routeid);
407
if (type == nullptr) {
408
return writeErrorInvalidParent(SUMO_TAG_VEHICLE, vehicleParameters.id, {SUMO_TAG_VTYPE, SUMO_TAG_VTYPE_DISTRIBUTION}, vehicleParameters.vtypeid);
409
} else if (route == nullptr) {
410
return writeErrorInvalidParent(SUMO_TAG_VEHICLE, vehicleParameters.id, {SUMO_TAG_ROUTE, SUMO_TAG_ROUTE_DISTRIBUTION}, vehicleParameters.routeid);
411
} else if (vehicleParameters.wasSet(VEHPARS_DEPARTLANE_SET) && (vehicleParameters.departLaneProcedure == DepartLaneDefinition::GIVEN) && ((int)route->getParentEdges().front()->getChildLanes().size() < vehicleParameters.departLane)) {
412
return writeError(TLF("Invalid % used in % '%'. % is greater than number of lanes", toString(SUMO_ATTR_DEPARTLANE), toString(vehicleParameters.tag), vehicleParameters.id, toString(vehicleParameters.departLane)));
413
} else if (vehicleParameters.wasSet(VEHPARS_DEPARTSPEED_SET) && (vehicleParameters.departSpeedProcedure == DepartSpeedDefinition::GIVEN) && (type->getAttributeDouble(SUMO_ATTR_MAXSPEED) < vehicleParameters.departSpeed)) {
414
return writeError(TLF("Invalid % used in % '%'. % is greater than type %", toString(SUMO_ATTR_DEPARTSPEED), toString(vehicleParameters.tag), vehicleParameters.id, toString(vehicleParameters.departSpeed), toString(SUMO_ATTR_MAXSPEED)));
415
} else {
416
// create flow or trips using vehicleParameters
417
GNEDemandElement* flow = new GNEVehicle(GNE_TAG_FLOW_ROUTE, myNet, myFileBucket, type, route, vehicleParameters);
418
if (myAllowUndoRedo) {
419
myNet->getUndoList()->begin(flow, TLF("add % '%'", flow->getTagStr(), vehicleParameters.id));
420
myNet->getUndoList()->add(new GNEChange_DemandElement(flow, true), true);
421
myNet->getUndoList()->end();
422
} else {
423
myNet->getAttributeCarriers()->insertDemandElement(flow);
424
// set flow as child of type and Route
425
type->addChildElement(flow);
426
route->addChildElement(flow);
427
flow->incRef("buildFlowOverRoute");
428
}
429
return true;
430
}
431
}
432
}
433
434
435
bool
436
GNERouteHandler::buildFlowEmbeddedRoute(const CommonXMLStructure::SumoBaseObject* /*sumoBaseObject*/, const SUMOVehicleParameter& vehicleParameters,
437
const std::vector<std::string>& edgeIDs, const RGBColor& color, const int repeat, const SUMOTime cycleTime,
438
const Parameterised::Map& routeParameters) {
439
// check conditions
440
const auto element = retrieveDemandElement(NamespaceIDs::vehicles, vehicleParameters.id);
441
if (!checkElement(GNE_TAG_FLOW_WITHROUTE, element)) {
442
return false;
443
} else if (!checkValidDemandElementID(GNE_TAG_FLOW_WITHROUTE, vehicleParameters.id)) {
444
return false;
445
} else {
446
// parse route edges
447
const auto edges = parseEdges(GNE_TAG_FLOW_WITHROUTE, vehicleParameters.id, edgeIDs);
448
// check edges
449
const auto validEdges = GNERoute::isRouteValid(edges);
450
// continue depending if route is valid
451
if (validEdges.size() > 0) {
452
return writeError(TLF("Could not build % with ID '%' in netedit; %.", toString(GNE_TAG_FLOW_WITHROUTE), vehicleParameters.id, validEdges));
453
} else {
454
// obtain type
455
GNEDemandElement* type = getType(vehicleParameters.vtypeid);
456
if (type == nullptr) {
457
return writeErrorInvalidParent(GNE_TAG_FLOW_WITHROUTE, vehicleParameters.id, {SUMO_TAG_VTYPE, SUMO_TAG_VTYPE_DISTRIBUTION}, vehicleParameters.vtypeid);
458
} else if (vehicleParameters.wasSet(VEHPARS_DEPARTLANE_SET) && (vehicleParameters.departLaneProcedure == DepartLaneDefinition::GIVEN) && ((int)edges.front()->getChildLanes().size() < vehicleParameters.departLane)) {
459
return writeError(TLF("Invalid % used in % '%'. % is greater than number of lanes", toString(SUMO_ATTR_DEPARTLANE), toString(vehicleParameters.tag), vehicleParameters.id, toString(vehicleParameters.departLane)));
460
} else if (vehicleParameters.wasSet(VEHPARS_DEPARTSPEED_SET) && (vehicleParameters.departSpeedProcedure == DepartSpeedDefinition::GIVEN) && (type->getAttributeDouble(SUMO_ATTR_MAXSPEED) < vehicleParameters.departSpeed)) {
461
return writeError(TLF("Invalid % used in % '%'. % is greater than type %", toString(SUMO_ATTR_DEPARTSPEED), toString(vehicleParameters.tag), vehicleParameters.id, toString(vehicleParameters.departSpeed), toString(SUMO_ATTR_MAXSPEED)));
462
} else {
463
// create vehicle using vehicleParameters
464
GNEDemandElement* vehicle = new GNEVehicle(GNE_TAG_FLOW_WITHROUTE, myNet, myFileBucket, type, vehicleParameters);
465
// create embedded route
466
GNEDemandElement* route = new GNERoute(vehicle, edges, color, repeat, cycleTime, routeParameters);
467
if (myAllowUndoRedo) {
468
myNet->getUndoList()->begin(vehicle, TLF("add % '%'", vehicle->getTagStr(), vehicleParameters.id));
469
myNet->getUndoList()->add(new GNEChange_DemandElement(vehicle, true), true);
470
myNet->getUndoList()->add(new GNEChange_DemandElement(route, true), true);
471
myNet->getUndoList()->end();
472
} else {
473
myNet->getAttributeCarriers()->insertDemandElement(vehicle);
474
myNet->getAttributeCarriers()->insertDemandElement(route);
475
type->addChildElement(vehicle);
476
vehicle->addChildElement(route);
477
for (const auto& edge : edges) {
478
edge->addChildElement(route);
479
}
480
vehicle->incRef("buildFlowEmbeddedRoute");
481
route->incRef("buildFlowEmbeddedRoute");
482
}
483
return true;
484
}
485
}
486
}
487
}
488
489
490
bool
491
GNERouteHandler::buildTrip(const CommonXMLStructure::SumoBaseObject* sumoBaseObject, const SUMOVehicleParameter& vehicleParameters,
492
const std::string& fromEdgeID, const std::string& toEdgeID) {
493
// check conditions
494
const auto element = retrieveDemandElement(NamespaceIDs::vehicles, vehicleParameters.id);
495
if (!checkElement(SUMO_TAG_TRIP, element)) {
496
return false;
497
} else if (!checkValidDemandElementID(SUMO_TAG_TRIP, vehicleParameters.id)) {
498
return false;
499
} else {
500
// set via attribute
501
if (sumoBaseObject && sumoBaseObject->hasStringListAttribute(SUMO_ATTR_VIA)) {
502
vehicleParameters.via = sumoBaseObject->getStringListAttribute(SUMO_ATTR_VIA);
503
}
504
// parse edges
505
const auto fromEdge = parseEdge(SUMO_TAG_TRIP, vehicleParameters.id, fromEdgeID, sumoBaseObject, true);
506
const auto toEdge = parseEdge(SUMO_TAG_TRIP, vehicleParameters.id, toEdgeID, sumoBaseObject, false);
507
if (!fromEdge || !toEdge) {
508
return false;
509
} else {
510
// obtain type
511
GNEDemandElement* type = getType(vehicleParameters.vtypeid);
512
if (type == nullptr) {
513
return writeErrorInvalidParent(SUMO_TAG_TRIP, vehicleParameters.id, {SUMO_TAG_VTYPE, SUMO_TAG_VTYPE_DISTRIBUTION}, vehicleParameters.vtypeid);
514
} else if (vehicleParameters.wasSet(VEHPARS_DEPARTLANE_SET) && ((vehicleParameters.departLaneProcedure == DepartLaneDefinition::GIVEN)) && ((int)fromEdge->getChildLanes().size() < vehicleParameters.departLane)) {
515
return writeError(TLF("Invalid % used in % '%'. % is greater than number of lanes", toString(SUMO_ATTR_DEPARTLANE), toString(vehicleParameters.tag), vehicleParameters.id, toString(vehicleParameters.departLane)));
516
} else if (vehicleParameters.wasSet(VEHPARS_DEPARTSPEED_SET) && (vehicleParameters.departSpeedProcedure == DepartSpeedDefinition::GIVEN) && (type->getAttributeDouble(SUMO_ATTR_MAXSPEED) < vehicleParameters.departSpeed)) {
517
return writeError(TLF("Invalid % used in % '%'. % is greater than type %", toString(SUMO_ATTR_DEPARTSPEED), toString(vehicleParameters.tag), vehicleParameters.id, toString(vehicleParameters.departSpeed), toString(SUMO_ATTR_MAXSPEED)));
518
} else if (!checkViaAttribute(SUMO_TAG_TRIP, vehicleParameters.id, vehicleParameters.via)) {
519
return false;
520
} else {
521
// create trip or flow using tripParameters
522
GNEDemandElement* trip = new GNEVehicle(SUMO_TAG_TRIP, myNet, myFileBucket, type, fromEdge, toEdge, vehicleParameters);
523
if (myAllowUndoRedo) {
524
myNet->getUndoList()->begin(trip, TLF("add % '%'", trip->getTagStr(), vehicleParameters.id));
525
myNet->getUndoList()->add(new GNEChange_DemandElement(trip, true), true);
526
myNet->getUndoList()->end();
527
} else {
528
myNet->getAttributeCarriers()->insertDemandElement(trip);
529
// set vehicle as child of type
530
type->addChildElement(trip);
531
trip->incRef("buildTrip");
532
// add reference in all edges
533
fromEdge->addChildElement(trip);
534
toEdge->addChildElement(trip);
535
}
536
return true;
537
}
538
}
539
}
540
}
541
542
543
bool
544
GNERouteHandler::buildTripJunctions(const CommonXMLStructure::SumoBaseObject* /*sumoBaseObject*/, const SUMOVehicleParameter& vehicleParameters,
545
const std::string& fromJunctionID, const std::string& toJunctionID) {
546
// check conditions
547
const auto element = retrieveDemandElement(NamespaceIDs::vehicles, vehicleParameters.id);
548
if (!checkElement(GNE_TAG_TRIP_JUNCTIONS, element)) {
549
return false;
550
} else if (!checkValidDemandElementID(GNE_TAG_TRIP_JUNCTIONS, vehicleParameters.id)) {
551
return false;
552
} else {
553
// parse junctions
554
const auto fromJunction = parseJunction(GNE_TAG_TRIP_JUNCTIONS, vehicleParameters.id, fromJunctionID);
555
const auto toJunction = parseJunction(GNE_TAG_TRIP_JUNCTIONS, vehicleParameters.id, toJunctionID);
556
if (!fromJunction || !toJunction) {
557
return false;
558
} else {
559
// obtain type
560
GNEDemandElement* type = getType(vehicleParameters.vtypeid);
561
if (type == nullptr) {
562
return writeErrorInvalidParent(GNE_TAG_TRIP_JUNCTIONS, vehicleParameters.id, {SUMO_TAG_VTYPE, SUMO_TAG_VTYPE_DISTRIBUTION}, vehicleParameters.vtypeid);
563
} else if (vehicleParameters.wasSet(VEHPARS_DEPARTLANE_SET) && ((vehicleParameters.departLaneProcedure == DepartLaneDefinition::GIVEN)) && (vehicleParameters.departLane > 0)) {
564
return writeError(TLF("Invalid % used in % '%'. % is greater than number of lanes", toString(SUMO_ATTR_DEPARTLANE), toString(vehicleParameters.tag), vehicleParameters.id, toString(vehicleParameters.departLane)));
565
} else if (vehicleParameters.wasSet(VEHPARS_DEPARTSPEED_SET) && (vehicleParameters.departSpeedProcedure == DepartSpeedDefinition::GIVEN) && (type->getAttributeDouble(SUMO_ATTR_MAXSPEED) < vehicleParameters.departSpeed)) {
566
return writeError(TLF("Invalid % used in % '%'. % is greater than type %", toString(SUMO_ATTR_DEPARTSPEED), toString(vehicleParameters.tag), vehicleParameters.id, toString(vehicleParameters.departSpeed), toString(SUMO_ATTR_MAXSPEED)));
567
} else {
568
// create trip using vehicleParameters
569
GNEDemandElement* flow = new GNEVehicle(GNE_TAG_TRIP_JUNCTIONS, myNet, myFileBucket, type, fromJunction, toJunction, vehicleParameters);
570
if (myAllowUndoRedo) {
571
myNet->getUndoList()->begin(flow, TLF("add % '%'", flow->getTagStr(), vehicleParameters.id));
572
myNet->getUndoList()->add(new GNEChange_DemandElement(flow, true), true);
573
myNet->getUndoList()->end();
574
} else {
575
myNet->getAttributeCarriers()->insertDemandElement(flow);
576
// set vehicle as child of type
577
type->addChildElement(flow);
578
flow->incRef("buildFlow");
579
// add reference in all junctions
580
fromJunction->addChildElement(flow);
581
toJunction->addChildElement(flow);
582
}
583
return true;
584
}
585
}
586
}
587
}
588
589
590
bool
591
GNERouteHandler::buildTripTAZs(const CommonXMLStructure::SumoBaseObject* /*sumoBaseObject*/, const SUMOVehicleParameter& vehicleParameters,
592
const std::string& fromTAZID, const std::string& toTAZID) {
593
// check conditions
594
const auto element = retrieveDemandElement(NamespaceIDs::vehicles, vehicleParameters.id);
595
if (!checkElement(GNE_TAG_TRIP_TAZS, element)) {
596
return false;
597
} else if (!checkValidDemandElementID(GNE_TAG_TRIP_TAZS, vehicleParameters.id)) {
598
return false;
599
} else {
600
// parse TAZs
601
const auto fromTAZ = parseTAZ(GNE_TAG_TRIP_TAZS, vehicleParameters.id, fromTAZID);
602
const auto toTAZ = parseTAZ(GNE_TAG_TRIP_TAZS, vehicleParameters.id, toTAZID);
603
if (!fromTAZ || !toTAZ) {
604
return false;
605
} else {
606
// obtain type
607
GNEDemandElement* type = getType(vehicleParameters.vtypeid);
608
if (type == nullptr) {
609
return writeErrorInvalidParent(GNE_TAG_TRIP_TAZS, vehicleParameters.id, {SUMO_TAG_VTYPE, SUMO_TAG_VTYPE_DISTRIBUTION}, vehicleParameters.vtypeid);
610
} else if (vehicleParameters.wasSet(VEHPARS_DEPARTLANE_SET) && ((vehicleParameters.departLaneProcedure == DepartLaneDefinition::GIVEN)) && (vehicleParameters.departLane > 0)) {
611
return writeError(TLF("Invalid % used in % '%'. % is greater than number of lanes", toString(SUMO_ATTR_DEPARTLANE), toString(vehicleParameters.tag), vehicleParameters.id, toString(vehicleParameters.departLane)));
612
} else if (vehicleParameters.wasSet(VEHPARS_DEPARTSPEED_SET) && (vehicleParameters.departSpeedProcedure == DepartSpeedDefinition::GIVEN) && (type->getAttributeDouble(SUMO_ATTR_MAXSPEED) < vehicleParameters.departSpeed)) {
613
return writeError(TLF("Invalid % used in % '%'. % is greater than type %", toString(SUMO_ATTR_DEPARTSPEED), toString(vehicleParameters.tag), vehicleParameters.id, toString(vehicleParameters.departSpeed), toString(SUMO_ATTR_MAXSPEED)));
614
} else {
615
// create trip using vehicleParameters
616
GNEDemandElement* flow = new GNEVehicle(GNE_TAG_TRIP_TAZS, myNet, myFileBucket, type, fromTAZ, toTAZ, vehicleParameters);
617
if (myAllowUndoRedo) {
618
myNet->getUndoList()->begin(flow, TLF("add % '%'", flow->getTagStr(), vehicleParameters.id));
619
myNet->getUndoList()->add(new GNEChange_DemandElement(flow, true), true);
620
myNet->getUndoList()->end();
621
} else {
622
myNet->getAttributeCarriers()->insertDemandElement(flow);
623
// set vehicle as child of type
624
type->addChildElement(flow);
625
flow->incRef("buildFlow");
626
// add reference in all TAZs
627
fromTAZ->addChildElement(flow);
628
toTAZ->addChildElement(flow);
629
}
630
return true;
631
}
632
}
633
}
634
}
635
636
637
bool
638
GNERouteHandler::buildFlow(const CommonXMLStructure::SumoBaseObject* sumoBaseObject, const SUMOVehicleParameter& vehicleParameters,
639
const std::string& fromEdgeID, const std::string& toEdgeID) {
640
// check conditions
641
const auto element = retrieveDemandElement(NamespaceIDs::vehicles, vehicleParameters.id);
642
if (!checkElement(SUMO_TAG_FLOW, element)) {
643
return false;
644
} else if (!checkValidDemandElementID(SUMO_TAG_FLOW, vehicleParameters.id)) {
645
return false;
646
} else {
647
// set via attribute
648
if (sumoBaseObject && sumoBaseObject->hasStringListAttribute(SUMO_ATTR_VIA)) {
649
vehicleParameters.via = sumoBaseObject->getStringListAttribute(SUMO_ATTR_VIA);
650
}
651
// parse edges
652
const auto fromEdge = parseEdge(SUMO_TAG_FLOW, vehicleParameters.id, fromEdgeID, sumoBaseObject, true);
653
const auto toEdge = parseEdge(SUMO_TAG_FLOW, vehicleParameters.id, toEdgeID, sumoBaseObject, false);
654
if (!fromEdge || !toEdge) {
655
return false;
656
} else {
657
// obtain type
658
GNEDemandElement* type = getType(vehicleParameters.vtypeid);
659
if (type == nullptr) {
660
return writeErrorInvalidParent(SUMO_TAG_FLOW, vehicleParameters.id, {SUMO_TAG_VTYPE, SUMO_TAG_VTYPE_DISTRIBUTION}, vehicleParameters.vtypeid);
661
} else if (vehicleParameters.wasSet(VEHPARS_DEPARTLANE_SET) && (vehicleParameters.departLaneProcedure == DepartLaneDefinition::GIVEN) && ((int)fromEdge->getChildLanes().size() < vehicleParameters.departLane)) {
662
return writeError(TLF("Invalid % used in % '%'. % is greater than number of lanes", toString(SUMO_ATTR_DEPARTLANE), toString(vehicleParameters.tag), vehicleParameters.id, toString(vehicleParameters.departLane)));
663
} else if (vehicleParameters.wasSet(VEHPARS_DEPARTSPEED_SET) && (vehicleParameters.departSpeedProcedure == DepartSpeedDefinition::GIVEN) && (type->getAttributeDouble(SUMO_ATTR_MAXSPEED) < vehicleParameters.departSpeed)) {
664
return writeError(TLF("Invalid % used in % '%'. % is greater than type %", toString(SUMO_ATTR_DEPARTSPEED), toString(vehicleParameters.tag), vehicleParameters.id, toString(vehicleParameters.departSpeed), toString(SUMO_ATTR_MAXSPEED)));
665
} else if (!checkViaAttribute(SUMO_TAG_FLOW, vehicleParameters.id, vehicleParameters.via)) {
666
return false;
667
} else {
668
// create trip or flow using tripParameters
669
GNEDemandElement* flow = new GNEVehicle(SUMO_TAG_FLOW, myNet, myFileBucket, type, fromEdge, toEdge, vehicleParameters);
670
if (myAllowUndoRedo) {
671
myNet->getUndoList()->begin(flow, TLF("add % '%'", flow->getTagStr(), vehicleParameters.id));
672
myNet->getUndoList()->add(new GNEChange_DemandElement(flow, true), true);
673
myNet->getUndoList()->end();
674
} else {
675
myNet->getAttributeCarriers()->insertDemandElement(flow);
676
// set vehicle as child of type
677
type->addChildElement(flow);
678
flow->incRef("buildFlow");
679
// add reference in all edges
680
fromEdge->addChildElement(flow);
681
toEdge->addChildElement(flow);
682
}
683
return true;
684
}
685
}
686
}
687
}
688
689
690
bool
691
GNERouteHandler::buildFlowJunctions(const CommonXMLStructure::SumoBaseObject* /*sumoBaseObject*/, const SUMOVehicleParameter& vehicleParameters,
692
const std::string& fromJunctionID, const std::string& toJunctionID) {
693
// check conditions
694
const auto element = retrieveDemandElement(NamespaceIDs::vehicles, vehicleParameters.id);
695
if (!checkElement(GNE_TAG_FLOW_JUNCTIONS, element)) {
696
return false;
697
} else if (!checkValidDemandElementID(GNE_TAG_FLOW_JUNCTIONS, vehicleParameters.id)) {
698
return false;
699
} else {
700
// parse junctions
701
const auto fromJunction = parseJunction(GNE_TAG_FLOW_JUNCTIONS, vehicleParameters.id, fromJunctionID);
702
const auto toJunction = parseJunction(GNE_TAG_FLOW_JUNCTIONS, vehicleParameters.id, toJunctionID);
703
if (!fromJunction || !toJunction) {
704
return false;
705
} else {
706
// obtain type
707
GNEDemandElement* type = getType(vehicleParameters.vtypeid);
708
if (type == nullptr) {
709
return writeErrorInvalidParent(GNE_TAG_FLOW_JUNCTIONS, vehicleParameters.id, {SUMO_TAG_VTYPE, SUMO_TAG_VTYPE_DISTRIBUTION}, vehicleParameters.vtypeid);
710
} else if (vehicleParameters.wasSet(VEHPARS_DEPARTLANE_SET) && ((vehicleParameters.departLaneProcedure == DepartLaneDefinition::GIVEN)) && (vehicleParameters.departLane > 0)) {
711
return writeError(TLF("Invalid % used in % '%'. % is greater than number of lanes", toString(SUMO_ATTR_DEPARTLANE), toString(vehicleParameters.tag), vehicleParameters.id, toString(vehicleParameters.departLane)));
712
} else if (vehicleParameters.wasSet(VEHPARS_DEPARTSPEED_SET) && (vehicleParameters.departSpeedProcedure == DepartSpeedDefinition::GIVEN) && (type->getAttributeDouble(SUMO_ATTR_MAXSPEED) < vehicleParameters.departSpeed)) {
713
return writeError(TLF("Invalid % used in % '%'. % is greater than type %", toString(SUMO_ATTR_DEPARTSPEED), toString(vehicleParameters.tag), vehicleParameters.id, toString(vehicleParameters.departSpeed), toString(SUMO_ATTR_MAXSPEED)));
714
} else {
715
// create flow using vehicleParameters
716
GNEDemandElement* flow = new GNEVehicle(GNE_TAG_FLOW_JUNCTIONS, myNet, myFileBucket, type, fromJunction, toJunction, vehicleParameters);
717
if (myAllowUndoRedo) {
718
myNet->getUndoList()->begin(flow, TLF("add % '%'", flow->getTagStr(), vehicleParameters.id));
719
myNet->getUndoList()->add(new GNEChange_DemandElement(flow, true), true);
720
myNet->getUndoList()->end();
721
} else {
722
myNet->getAttributeCarriers()->insertDemandElement(flow);
723
// set vehicle as child of type
724
type->addChildElement(flow);
725
flow->incRef("buildFlow");
726
// add reference in all junctions
727
fromJunction->addChildElement(flow);
728
toJunction->addChildElement(flow);
729
}
730
return true;
731
}
732
}
733
}
734
}
735
736
737
bool
738
GNERouteHandler::buildFlowTAZs(const CommonXMLStructure::SumoBaseObject* /*sumoBaseObject*/, const SUMOVehicleParameter& vehicleParameters,
739
const std::string& fromTAZID, const std::string& toTAZID) {
740
// check conditions
741
const auto element = retrieveDemandElement(NamespaceIDs::vehicles, vehicleParameters.id);
742
if (!checkElement(GNE_TAG_FLOW_TAZS, element)) {
743
return false;
744
} else if (!checkValidDemandElementID(GNE_TAG_FLOW_TAZS, vehicleParameters.id)) {
745
return false;
746
} else {
747
// parse TAZs
748
const auto fromTAZ = parseTAZ(GNE_TAG_FLOW_TAZS, vehicleParameters.id, fromTAZID);
749
const auto toTAZ = parseTAZ(GNE_TAG_FLOW_TAZS, vehicleParameters.id, toTAZID);
750
if (!fromTAZ || !toTAZ) {
751
return false;
752
} else {
753
// obtain type
754
GNEDemandElement* type = getType(vehicleParameters.vtypeid);
755
if (type == nullptr) {
756
return writeErrorInvalidParent(GNE_TAG_FLOW_TAZS, vehicleParameters.id, {SUMO_TAG_VTYPE, SUMO_TAG_VTYPE_DISTRIBUTION}, vehicleParameters.vtypeid);
757
} else if (vehicleParameters.wasSet(VEHPARS_DEPARTLANE_SET) && ((vehicleParameters.departLaneProcedure == DepartLaneDefinition::GIVEN)) && (vehicleParameters.departLane > 0)) {
758
return writeError(TLF("Invalid % used in % '%'. % is greater than number of lanes", toString(SUMO_ATTR_DEPARTLANE), toString(vehicleParameters.tag), vehicleParameters.id, toString(vehicleParameters.departLane)));
759
} else if (vehicleParameters.wasSet(VEHPARS_DEPARTSPEED_SET) && (vehicleParameters.departSpeedProcedure == DepartSpeedDefinition::GIVEN) && (type->getAttributeDouble(SUMO_ATTR_MAXSPEED) < vehicleParameters.departSpeed)) {
760
return writeError(TLF("Invalid % used in % '%'. % is greater than type %", toString(SUMO_ATTR_DEPARTSPEED), toString(vehicleParameters.tag), vehicleParameters.id, toString(vehicleParameters.departSpeed), toString(SUMO_ATTR_MAXSPEED)));
761
} else {
762
// create flow using vehicleParameters
763
GNEDemandElement* flow = new GNEVehicle(GNE_TAG_FLOW_TAZS, myNet, myFileBucket, type, fromTAZ, toTAZ, vehicleParameters);
764
if (myAllowUndoRedo) {
765
myNet->getUndoList()->begin(flow, TLF("add % '%'", flow->getTagStr(), vehicleParameters.id));
766
myNet->getUndoList()->add(new GNEChange_DemandElement(flow, true), true);
767
myNet->getUndoList()->end();
768
} else {
769
myNet->getAttributeCarriers()->insertDemandElement(flow);
770
// set vehicle as child of type
771
type->addChildElement(flow);
772
flow->incRef("buildFlow");
773
// add reference in all TAZs
774
fromTAZ->addChildElement(flow);
775
toTAZ->addChildElement(flow);
776
}
777
return true;
778
}
779
}
780
}
781
}
782
783
784
bool
785
GNERouteHandler::buildPerson(const CommonXMLStructure::SumoBaseObject* /*sumoBaseObject*/, const SUMOVehicleParameter& personParameters) {
786
// check conditions
787
const auto element = retrieveDemandElement(NamespaceIDs::persons, personParameters.id);
788
if (!checkElement(SUMO_TAG_PERSON, element)) {
789
return false;
790
} else if (!checkValidDemandElementID(SUMO_TAG_PERSON, personParameters.id)) {
791
return false;
792
} else {
793
// obtain type
794
GNEDemandElement* type = getType(personParameters.vtypeid);
795
if (type == nullptr) {
796
return writeErrorInvalidParent(SUMO_TAG_PERSON, personParameters.id, {SUMO_TAG_VTYPE}, personParameters.vtypeid);
797
} else {
798
// create person using personParameters
799
GNEDemandElement* person = new GNEPerson(SUMO_TAG_PERSON, myNet, myFileBucket, type, personParameters);
800
if (myAllowUndoRedo) {
801
myNet->getUndoList()->begin(person, TLF("add % '%'", person->getTagStr(), personParameters.id));
802
myNet->getUndoList()->add(new GNEChange_DemandElement(person, true), true);
803
myNet->getUndoList()->end();
804
} else {
805
myNet->getAttributeCarriers()->insertDemandElement(person);
806
// set person as child of type
807
type->addChildElement(person);
808
person->incRef("buildPerson");
809
}
810
// save in parent plan elements
811
myParentPlanElements.insert(person);
812
return true;
813
}
814
}
815
}
816
817
818
bool
819
GNERouteHandler::buildPersonFlow(const CommonXMLStructure::SumoBaseObject* /*sumoBaseObject*/, const SUMOVehicleParameter& personFlowParameters) {
820
// check conditions
821
const auto element = retrieveDemandElement(NamespaceIDs::persons, personFlowParameters.id);
822
if (!checkElement(SUMO_TAG_PERSONFLOW, element)) {
823
return false;
824
} else if (!checkValidDemandElementID(SUMO_TAG_PERSONFLOW, personFlowParameters.id)) {
825
return false;
826
} else {
827
// obtain type
828
GNEDemandElement* type = getType(personFlowParameters.vtypeid);
829
if (type == nullptr) {
830
return writeErrorInvalidParent(SUMO_TAG_PERSONFLOW, personFlowParameters.id, {SUMO_TAG_VTYPE}, personFlowParameters.vtypeid);
831
} else {
832
// create personFlow using personFlowParameters
833
GNEDemandElement* personFlow = new GNEPerson(SUMO_TAG_PERSONFLOW, myNet, myFileBucket, type, personFlowParameters);
834
if (myAllowUndoRedo) {
835
myNet->getUndoList()->begin(personFlow, TLF("add % '%'", personFlow->getTagStr(), personFlowParameters.id));
836
myNet->getUndoList()->add(new GNEChange_DemandElement(personFlow, true), true);
837
myNet->getUndoList()->end();
838
} else {
839
myNet->getAttributeCarriers()->insertDemandElement(personFlow);
840
// set personFlow as child of type
841
type->addChildElement(personFlow);
842
personFlow->incRef("buildPersonFlow");
843
}
844
// save in parent plan elements
845
myParentPlanElements.insert(personFlow);
846
return true;
847
}
848
}
849
}
850
851
852
bool
853
GNERouteHandler::buildPersonTrip(const CommonXMLStructure::SumoBaseObject* sumoBaseObject, const CommonXMLStructure::PlanParameters& planParameters,
854
const double arrivalPos, const std::vector<std::string>& types, const std::vector<std::string>& modes,
855
const std::vector<std::string>& lines, const double walkFactor, const std::string& group) {
856
// get values
857
GNEDemandElement* personParent = getPersonParent(sumoBaseObject);
858
const auto personTripTag = planParameters.getPersonTripTag();
859
GNEPlanParents planParents = GNEPlanParents(planParameters, myNet->getAttributeCarriers());
860
// check conditions
861
if (personParent == nullptr) {
862
return writeErrorInvalidParent(SUMO_TAG_PERSONTRIP, {SUMO_TAG_PERSON});
863
} else if (personTripTag == SUMO_TAG_NOTHING) {
864
return false;
865
} else if (planParents.checkIntegrity(personTripTag, personParent, planParameters)) {
866
// build person trip
867
GNEDemandElement* personTrip = new GNEPersonTrip(personTripTag, personParent, planParents,
868
arrivalPos, types, modes, lines, walkFactor, group);
869
// continue depending of undo.redo
870
if (myAllowUndoRedo) {
871
myNet->getUndoList()->begin(personTrip, TLF("add % in '%'", personTrip->getTagStr(), personParent->getID()));
872
myNet->getUndoList()->add(new GNEChange_DemandElement(personTrip, true), true);
873
myNet->getUndoList()->end();
874
} else {
875
myNet->getAttributeCarriers()->insertDemandElement(personTrip);
876
// set child references
877
personParent->addChildElement(personTrip);
878
planParents.addDemandElementChild(personTrip);
879
personTrip->incRef("buildPersonTrip");
880
}
881
return true;
882
} else {
883
return false;
884
}
885
}
886
887
888
bool
889
GNERouteHandler::buildWalk(const CommonXMLStructure::SumoBaseObject* sumoBaseObject, const CommonXMLStructure::PlanParameters& planParameters,
890
const double arrivalPos, const double speed, const SUMOTime duration) {
891
// get values
892
GNEDemandElement* personParent = getPersonParent(sumoBaseObject);
893
const auto walkTag = planParameters.getWalkTag();
894
GNEPlanParents planParents = GNEPlanParents(planParameters, myNet->getAttributeCarriers());
895
// check conditions
896
if (personParent == nullptr) {
897
return writeErrorInvalidParent(SUMO_TAG_WALK, {SUMO_TAG_PERSON});
898
} else if (walkTag == SUMO_TAG_NOTHING) {
899
return false;
900
} else if (!checkNegative(SUMO_TAG_WALK, personParent->getID(), SUMO_ATTR_SPEED, speed, true)) {
901
return false;
902
} else if (!checkNegative(SUMO_TAG_WALK, personParent->getID(), SUMO_ATTR_DURATION, duration, true)) {
903
return false;
904
} else if (planParents.checkIntegrity(walkTag, personParent, planParameters)) {
905
// build person trip
906
GNEDemandElement* walk = new GNEWalk(walkTag, personParent, planParents, arrivalPos, speed, duration);
907
// continue depending of undo.redo
908
if (myAllowUndoRedo) {
909
myNet->getUndoList()->begin(walk, TLF("add % in '%'", walk->getTagStr(), personParent->getID()));
910
myNet->getUndoList()->add(new GNEChange_DemandElement(walk, true), true);
911
myNet->getUndoList()->end();
912
} else {
913
myNet->getAttributeCarriers()->insertDemandElement(walk);
914
// set child references
915
personParent->addChildElement(walk);
916
planParents.addDemandElementChild(walk);
917
walk->incRef("buildWalk");
918
}
919
return true;
920
} else {
921
return false;
922
}
923
}
924
925
926
bool
927
GNERouteHandler::buildRide(const CommonXMLStructure::SumoBaseObject* sumoBaseObject, const CommonXMLStructure::PlanParameters& planParameters,
928
const double arrivalPos, const std::vector<std::string>& lines, const std::string& group) {
929
// get values
930
GNEDemandElement* personParent = getPersonParent(sumoBaseObject);
931
const auto rideTag = planParameters.getRideTag();
932
GNEPlanParents planParents = GNEPlanParents(planParameters, myNet->getAttributeCarriers());
933
// check conditions
934
if (personParent == nullptr) {
935
return writeErrorInvalidParent(SUMO_TAG_RIDE, {SUMO_TAG_PERSON});
936
} else if (rideTag == SUMO_TAG_NOTHING) {
937
return false;
938
} else if (planParents.checkIntegrity(rideTag, personParent, planParameters)) {
939
// build ride
940
GNEDemandElement* ride = new GNERide(rideTag, personParent, planParents, arrivalPos, lines, group);
941
// continue depending of undo-redo
942
if (myAllowUndoRedo) {
943
myNet->getUndoList()->begin(ride, TLF("add % in '%'", ride->getTagStr(), personParent->getID()));
944
myNet->getUndoList()->add(new GNEChange_DemandElement(ride, true), true);
945
myNet->getUndoList()->end();
946
} else {
947
myNet->getAttributeCarriers()->insertDemandElement(ride);
948
// set child references
949
personParent->addChildElement(ride);
950
planParents.addDemandElementChild(ride);
951
ride->incRef("buildRide");
952
}
953
return true;
954
} else {
955
return false;
956
}
957
}
958
959
960
bool
961
GNERouteHandler::buildContainer(const CommonXMLStructure::SumoBaseObject* /*sumoBaseObject*/, const SUMOVehicleParameter& containerParameters) {
962
// check conditions
963
const auto element = retrieveDemandElement(NamespaceIDs::containers, containerParameters.id);
964
if (!checkElement(SUMO_TAG_CONTAINER, element)) {
965
return false;
966
} else if (!checkValidDemandElementID(SUMO_TAG_CONTAINER, containerParameters.id)) {
967
return false;
968
} else {
969
// obtain type
970
GNEDemandElement* type = getType(containerParameters.vtypeid);
971
if (type == nullptr) {
972
return writeError(TLF("Invalid vehicle type '%' used in % '%'.", containerParameters.vtypeid, toString(containerParameters.tag), containerParameters.id));
973
} else {
974
// create container using containerParameters
975
GNEDemandElement* container = new GNEContainer(SUMO_TAG_CONTAINER, myNet, myFileBucket, type, containerParameters);
976
if (myAllowUndoRedo) {
977
myNet->getUndoList()->begin(container, TLF("add % '%'", container->getTagStr(), container->getID()));
978
myNet->getUndoList()->add(new GNEChange_DemandElement(container, true), true);
979
myNet->getUndoList()->end();
980
} else {
981
myNet->getAttributeCarriers()->insertDemandElement(container);
982
// set container as child of type
983
type->addChildElement(container);
984
container->incRef("buildContainer");
985
}
986
// save in parent plan elements
987
myParentPlanElements.insert(container);
988
return true;
989
}
990
}
991
}
992
993
994
bool
995
GNERouteHandler::buildContainerFlow(const CommonXMLStructure::SumoBaseObject* /*sumoBaseObject*/, const SUMOVehicleParameter& containerFlowParameters) {
996
// check conditions
997
const auto element = retrieveDemandElement(NamespaceIDs::containers, containerFlowParameters.id);
998
if (!checkElement(SUMO_TAG_CONTAINERFLOW, element)) {
999
return false;
1000
} else if (!checkValidDemandElementID(SUMO_TAG_CONTAINERFLOW, containerFlowParameters.id)) {
1001
return false;
1002
} else {
1003
// obtain type
1004
GNEDemandElement* type = getType(containerFlowParameters.vtypeid);
1005
if (type == nullptr) {
1006
return writeError(TLF("Invalid vehicle type '%' used in % '%'.", containerFlowParameters.vtypeid, toString(containerFlowParameters.tag), containerFlowParameters.id));
1007
} else {
1008
// create containerFlow using containerFlowParameters
1009
GNEDemandElement* containerFlow = new GNEContainer(SUMO_TAG_CONTAINERFLOW, myNet, myFileBucket, type, containerFlowParameters);
1010
if (myAllowUndoRedo) {
1011
myNet->getUndoList()->begin(containerFlow, TLF("add % '%'", containerFlow->getTagStr(), containerFlow->getID()));
1012
myNet->getUndoList()->add(new GNEChange_DemandElement(containerFlow, true), true);
1013
myNet->getUndoList()->end();
1014
} else {
1015
myNet->getAttributeCarriers()->insertDemandElement(containerFlow);
1016
// set containerFlow as child of type
1017
type->addChildElement(containerFlow);
1018
containerFlow->incRef("buildContainerFlow");
1019
}
1020
// save in parent plan elements
1021
myParentPlanElements.insert(containerFlow);
1022
return true;
1023
}
1024
}
1025
}
1026
1027
1028
bool
1029
GNERouteHandler::buildTransport(const CommonXMLStructure::SumoBaseObject* sumoBaseObject, const CommonXMLStructure::PlanParameters& planParameters,
1030
const double arrivalPos, const std::vector<std::string>& lines, const std::string& group) {
1031
// get values
1032
GNEDemandElement* containerParent = getContainerParent(sumoBaseObject);
1033
const auto transportTag = planParameters.getTransportTag();
1034
GNEPlanParents planParents = GNEPlanParents(planParameters, myNet->getAttributeCarriers());
1035
// check conditions
1036
if (containerParent == nullptr) {
1037
return writeErrorInvalidParent(SUMO_TAG_TRANSPORT, {SUMO_TAG_CONTAINER});
1038
} else if (transportTag == SUMO_TAG_NOTHING) {
1039
return false;
1040
} else if (planParents.checkIntegrity(transportTag, containerParent, planParameters)) {
1041
// build transport
1042
GNEDemandElement* transport = new GNETransport(transportTag, containerParent, planParents, arrivalPos, lines, group);
1043
// continue depending of undo-redo
1044
if (myAllowUndoRedo) {
1045
myNet->getUndoList()->begin(transport, TLF("add % in '%'", transport->getTagStr(), containerParent->getID()));
1046
myNet->getUndoList()->add(new GNEChange_DemandElement(transport, true), true);
1047
myNet->getUndoList()->end();
1048
} else {
1049
myNet->getAttributeCarriers()->insertDemandElement(transport);
1050
// set child references
1051
containerParent->addChildElement(transport);
1052
planParents.addDemandElementChild(transport);
1053
transport->incRef("buildTransport");
1054
}
1055
return true;
1056
} else {
1057
return false;
1058
}
1059
}
1060
1061
1062
bool
1063
GNERouteHandler::buildTranship(const CommonXMLStructure::SumoBaseObject* sumoBaseObject, const CommonXMLStructure::PlanParameters& planParameters,
1064
const double arrivalPosition, const double departPosition, const double speed, const SUMOTime duration) {
1065
// get values
1066
GNEDemandElement* containerParent = getContainerParent(sumoBaseObject);
1067
const auto transhipTag = planParameters.getTranshipTag();
1068
GNEPlanParents planParents = GNEPlanParents(planParameters, myNet->getAttributeCarriers());
1069
// check conditions
1070
if (containerParent == nullptr) {
1071
return writeErrorInvalidParent(SUMO_TAG_TRANSHIP, {SUMO_TAG_CONTAINER});
1072
} else if (transhipTag == SUMO_TAG_NOTHING) {
1073
return false;
1074
} else if (!checkNegative(SUMO_TAG_TRANSHIP, containerParent->getID(), SUMO_ATTR_SPEED, speed, true)) {
1075
return false;
1076
} else if (!checkNegative(SUMO_TAG_TRANSHIP, containerParent->getID(), SUMO_ATTR_DURATION, duration, true)) {
1077
return false;
1078
} else if (planParents.checkIntegrity(transhipTag, containerParent, planParameters)) {
1079
// build tranship
1080
GNEDemandElement* tranship = new GNETranship(transhipTag, containerParent, planParents,
1081
departPosition, arrivalPosition, speed, duration);
1082
// continue depending of undo-redo
1083
if (myAllowUndoRedo) {
1084
myNet->getUndoList()->begin(tranship, TLF("add % in '%'", tranship->getTagStr(), containerParent->getID()));
1085
myNet->getUndoList()->add(new GNEChange_DemandElement(tranship, true), true);
1086
myNet->getUndoList()->end();
1087
} else {
1088
myNet->getAttributeCarriers()->insertDemandElement(tranship);
1089
// set child references
1090
containerParent->addChildElement(tranship);
1091
planParents.addDemandElementChild(tranship);
1092
tranship->incRef("buildTranship");
1093
}
1094
return true;
1095
} else {
1096
return false;
1097
}
1098
}
1099
1100
1101
bool
1102
GNERouteHandler::buildPersonStop(const CommonXMLStructure::SumoBaseObject* sumoBaseObject, const CommonXMLStructure::PlanParameters& planParameters,
1103
const double endPos, const SUMOTime duration, const SUMOTime until,
1104
const std::string& actType, const bool friendlyPos, const int parameterSet) {
1105
// get values
1106
GNEDemandElement* personParent = getPersonParent(sumoBaseObject);
1107
const auto personStopTag = planParameters.getPersonStopTag();
1108
GNEPlanParents planParents = GNEPlanParents(planParameters, myNet->getAttributeCarriers());
1109
// check conditions
1110
if (personParent == nullptr) {
1111
return writeErrorInvalidParent(SUMO_TAG_STOP, {SUMO_TAG_PERSON});
1112
} else if (personStopTag == SUMO_TAG_NOTHING) {
1113
return false;
1114
} else if (planParents.checkIntegrity(personStopTag, personParent, planParameters)) {
1115
// build person stop
1116
GNEDemandElement* stopPlan = new GNEStopPlan(personStopTag, personParent, planParents,
1117
endPos, duration, until, actType, friendlyPos, parameterSet);
1118
// continue depending of undo-redo
1119
if (myAllowUndoRedo) {
1120
myNet->getUndoList()->begin(stopPlan, TLF("add % in '%'", stopPlan->getTagStr(), personParent->getID()));
1121
myNet->getUndoList()->add(new GNEChange_DemandElement(stopPlan, true), true);
1122
myNet->getUndoList()->end();
1123
} else {
1124
myNet->getAttributeCarriers()->insertDemandElement(stopPlan);
1125
// set child references
1126
personParent->addChildElement(stopPlan);
1127
planParents.addDemandElementChild(stopPlan);
1128
stopPlan->incRef("buildPersonStop");
1129
}
1130
return true;
1131
} else {
1132
return false;
1133
}
1134
}
1135
1136
1137
bool
1138
GNERouteHandler::buildContainerStop(const CommonXMLStructure::SumoBaseObject* sumoBaseObject, const CommonXMLStructure::PlanParameters& planParameters,
1139
const double endPos, const SUMOTime duration,
1140
const SUMOTime until, const std::string& actType, const bool friendlyPos, const int parameterSet) {
1141
// get values
1142
GNEDemandElement* containerParent = getContainerParent(sumoBaseObject);
1143
const auto containerStopTag = planParameters.getContainerStopTag();
1144
GNEPlanParents planParents = GNEPlanParents(planParameters, myNet->getAttributeCarriers());
1145
// check conditions
1146
if (containerParent == nullptr) {
1147
return writeErrorInvalidParent(SUMO_TAG_STOP, {SUMO_TAG_CONTAINER});
1148
} else if (containerStopTag == SUMO_TAG_NOTHING) {
1149
return false;
1150
} else if (planParents.checkIntegrity(containerStopTag, containerParent, planParameters)) {
1151
// build container stop
1152
GNEDemandElement* stopPlan = new GNEStopPlan(containerStopTag, containerParent, planParents,
1153
endPos, duration, until, actType, friendlyPos, parameterSet);
1154
// continue depending of undo-redo
1155
if (myAllowUndoRedo) {
1156
myNet->getUndoList()->begin(stopPlan, TLF("add % in '%'", stopPlan->getTagStr(), containerParent->getID()));
1157
myNet->getUndoList()->add(new GNEChange_DemandElement(stopPlan, true), true);
1158
myNet->getUndoList()->end();
1159
} else {
1160
myNet->getAttributeCarriers()->insertDemandElement(stopPlan);
1161
// set child references
1162
containerParent->addChildElement(stopPlan);
1163
planParents.addDemandElementChild(stopPlan);
1164
stopPlan->incRef("buildContainerStop");
1165
}
1166
return true;
1167
} else {
1168
return false;
1169
}
1170
}
1171
1172
1173
bool
1174
GNERouteHandler::buildStop(const CommonXMLStructure::SumoBaseObject* sumoBaseObject, const CommonXMLStructure::PlanParameters& planParameters,
1175
const SUMOVehicleParameter::Stop& stopParameters) {
1176
// get obj parent
1177
const auto objParent = sumoBaseObject->getParentSumoBaseObject();
1178
// continue depending of objParent
1179
if (objParent == nullptr) {
1180
return writeErrorInvalidParent(SUMO_TAG_STOP, {SUMO_TAG_VEHICLE});
1181
} else if ((objParent->getTag() == SUMO_TAG_PERSON) || (objParent->getTag() == SUMO_TAG_PERSONFLOW)) {
1182
return buildPersonStop(sumoBaseObject, planParameters, stopParameters.endPos,
1183
stopParameters.duration, stopParameters.until, stopParameters.actType, stopParameters.friendlyPos, stopParameters.parametersSet);
1184
} else if ((objParent->getTag() == SUMO_TAG_CONTAINER) || (objParent->getTag() == SUMO_TAG_CONTAINERFLOW)) {
1185
return buildContainerStop(sumoBaseObject, planParameters, stopParameters.endPos,
1186
stopParameters.duration, stopParameters.until, stopParameters.actType, stopParameters.friendlyPos, stopParameters.parametersSet);
1187
} else {
1188
// get vehicle tag
1189
SumoXMLTag vehicleTag = objParent->getTag();
1190
if (vehicleTag == SUMO_TAG_VEHICLE) {
1191
// check if vehicle is placed over route or with embedded route
1192
if (!objParent->hasStringAttribute(SUMO_ATTR_ROUTE)) {
1193
vehicleTag = GNE_TAG_VEHICLE_WITHROUTE;
1194
}
1195
} else if (vehicleTag == SUMO_TAG_FLOW) {
1196
if (objParent->hasStringAttribute(SUMO_ATTR_ROUTE)) {
1197
vehicleTag = GNE_TAG_FLOW_ROUTE;
1198
} else if (objParent->hasStringAttribute(SUMO_ATTR_FROM) && objParent->hasStringAttribute(SUMO_ATTR_TO)) {
1199
vehicleTag = SUMO_TAG_FLOW;
1200
} else {
1201
vehicleTag = GNE_TAG_FLOW_WITHROUTE;
1202
}
1203
}
1204
// get stop parent
1205
GNEDemandElement* stopParent = myNet->getAttributeCarriers()->retrieveDemandElement(vehicleTag, objParent->getStringAttribute(SUMO_ATTR_ID), false);
1206
// check if stopParent exist
1207
if (stopParent) {
1208
// flag for waypoint (is like a stop, but with extra attribute speed)
1209
bool waypoint = false;
1210
// abool waypoints for person and containers
1211
if (!stopParent->getTagProperty()->isPerson() && !stopParent->getTagProperty()->isContainer()) {
1212
waypoint = (sumoBaseObject->getStopParameter().parametersSet & STOP_SPEED_SET) || (sumoBaseObject->getStopParameter().speed > 0);
1213
}
1214
// declare pointers to parent elements
1215
GNEAdditional* stoppingPlace = nullptr;
1216
GNELane* lane = nullptr;
1217
GNEEdge* edge = nullptr;
1218
// declare stopTagType
1219
SumoXMLTag stopTagType = SUMO_TAG_NOTHING;
1220
// check conditions
1221
if (stopParameters.busstop.size() > 0) {
1222
stoppingPlace = myNet->getAttributeCarriers()->retrieveAdditional(SUMO_TAG_BUS_STOP, stopParameters.busstop, false);
1223
stopTagType = waypoint ? GNE_TAG_WAYPOINT_BUSSTOP : GNE_TAG_STOP_BUSSTOP;
1224
// check if is a train stop
1225
if (stoppingPlace == nullptr) {
1226
stoppingPlace = myNet->getAttributeCarriers()->retrieveAdditional(SUMO_TAG_TRAIN_STOP, stopParameters.busstop, false);
1227
stopTagType = waypoint ? GNE_TAG_WAYPOINT_TRAINSTOP : GNE_TAG_STOP_TRAINSTOP;
1228
}
1229
// containers cannot stops in busStops
1230
if (stopParent->getTagProperty()->isContainer()) {
1231
return writeError(TL("Containers don't support stops at busStops or trainStops"));
1232
}
1233
} else if (stopParameters.containerstop.size() > 0) {
1234
stoppingPlace = myNet->getAttributeCarriers()->retrieveAdditional(SUMO_TAG_CONTAINER_STOP, stopParameters.containerstop, false);
1235
stopTagType = waypoint ? GNE_TAG_WAYPOINT_CONTAINERSTOP : GNE_TAG_STOP_CONTAINERSTOP;
1236
// persons cannot stops in containerStops
1237
if (stopParent->getTagProperty()->isPerson()) {
1238
return writeError(TL("Persons don't support stops at containerStops"));
1239
}
1240
} else if (stopParameters.chargingStation.size() > 0) {
1241
stoppingPlace = myNet->getAttributeCarriers()->retrieveAdditional(SUMO_TAG_CHARGING_STATION, stopParameters.chargingStation, false);
1242
stopTagType = waypoint ? GNE_TAG_WAYPOINT_CHARGINGSTATION : GNE_TAG_STOP_CHARGINGSTATION;
1243
// check person and containers
1244
if (stopParent->getTagProperty()->isPerson()) {
1245
return writeError(TL("Persons don't support stops at chargingStations"));
1246
} else if (stopParent->getTagProperty()->isContainer()) {
1247
return writeError(TL("Containers don't support stops at chargingStations"));
1248
}
1249
} else if (stopParameters.parkingarea.size() > 0) {
1250
stoppingPlace = myNet->getAttributeCarriers()->retrieveAdditional(SUMO_TAG_PARKING_AREA, stopParameters.parkingarea, false);
1251
stopTagType = waypoint ? GNE_TAG_WAYPOINT_PARKINGAREA : GNE_TAG_STOP_PARKINGAREA;
1252
// check person and containers
1253
if (stopParent->getTagProperty()->isPerson()) {
1254
return writeError(TL("Persons don't support stops at parkingAreas"));
1255
} else if (stopParent->getTagProperty()->isContainer()) {
1256
return writeError(TL("Containers don't support stops at parkingAreas"));
1257
}
1258
} else if (stopParameters.lane.size() > 0) {
1259
lane = myNet->getAttributeCarriers()->retrieveLane(stopParameters.lane, false);
1260
stopTagType = waypoint ? GNE_TAG_WAYPOINT_LANE : GNE_TAG_STOP_LANE;
1261
} else if (stopParameters.edge.size() > 0) {
1262
edge = myNet->getAttributeCarriers()->retrieveEdge(stopParameters.edge, false);
1263
// check vehicles
1264
if (stopParent->getTagProperty()->isVehicle()) {
1265
return writeError(TL("vehicles don't support stops at edges"));
1266
}
1267
}
1268
// overwrite lane with edge parent if we're handling a personStop
1269
if (lane && (stopParent->getTagProperty()->isPerson() || stopParent->getTagProperty()->isContainer())) {
1270
edge = lane->getParentEdge();
1271
lane = nullptr;
1272
}
1273
// check if values are correct
1274
if (stoppingPlace && lane && edge) {
1275
return writeError(TL("A stop must be defined either over a stoppingPlace, a edge or a lane"));
1276
} else if (!stoppingPlace && !lane && !edge) {
1277
return writeError(TL("A stop requires only a stoppingPlace, edge or lane"));
1278
} else if (stoppingPlace) {
1279
// create stop using stopParameters and stoppingPlace
1280
GNEDemandElement* stop = nullptr;
1281
if (stopParent->getTagProperty()->isPerson()) {
1282
if (stoppingPlace->getTagProperty()->getTag() == SUMO_TAG_BUS_STOP) {
1283
stop = new GNEStop(GNE_TAG_STOPPERSON_BUSSTOP, stopParent, stoppingPlace, stopParameters);
1284
} else {
1285
stop = new GNEStop(GNE_TAG_STOPPERSON_TRAINSTOP, stopParent, stoppingPlace, stopParameters);
1286
}
1287
} else if (stopParent->getTagProperty()->isContainer()) {
1288
stop = new GNEStop(GNE_TAG_STOPCONTAINER_CONTAINERSTOP, stopParent, stoppingPlace, stopParameters);
1289
} else {
1290
stop = new GNEStop(stopTagType, stopParent, stoppingPlace, stopParameters);
1291
}
1292
// add it depending of undoDemandElements
1293
if (myAllowUndoRedo) {
1294
myNet->getUndoList()->begin(stop, TLF("add % in '%'", stop->getTagStr(), stopParent->getID()));
1295
myNet->getUndoList()->add(new GNEChange_DemandElement(stop, true), true);
1296
myNet->getUndoList()->end();
1297
} else {
1298
myNet->getAttributeCarriers()->insertDemandElement(stop);
1299
stoppingPlace->addChildElement(stop);
1300
stopParent->addChildElement(stop);
1301
stop->incRef("buildStoppingPlaceStop");
1302
}
1303
return true;
1304
} else if (lane) {
1305
// create stop using stopParameters and lane (only for vehicles)
1306
GNEDemandElement* stop = new GNEStop(stopTagType, stopParent, lane, stopParameters);
1307
// add it depending of undoDemandElements
1308
if (myAllowUndoRedo) {
1309
myNet->getUndoList()->begin(stop, TLF("add % in '%'", stop->getTagStr(), stopParent->getID()));
1310
myNet->getUndoList()->add(new GNEChange_DemandElement(stop, true), true);
1311
myNet->getUndoList()->end();
1312
} else {
1313
myNet->getAttributeCarriers()->insertDemandElement(stop);
1314
lane->addChildElement(stop);
1315
stopParent->addChildElement(stop);
1316
stop->incRef("buildLaneStop");
1317
}
1318
return true;
1319
} else {
1320
return false;
1321
}
1322
} else {
1323
return false;
1324
}
1325
}
1326
}
1327
1328
1329
bool
1330
GNERouteHandler::buildPersonPlan(const GNEDemandElement* planTemplate, GNEDemandElement* personParent,
1331
GNEAttributesEditor* personPlanAttributesEditor, GNEPlanCreator* planCreator,
1332
const bool centerAfterCreation) {
1333
// first check if person is valid
1334
if (personParent == nullptr) {
1335
return false;
1336
}
1337
// clear and set person object
1338
myPlanObject->clear();
1339
myPlanObject->setTag(personParent->getTagProperty()->getTag());
1340
myPlanObject->addStringAttribute(SUMO_ATTR_ID, personParent->getID());
1341
// declare personPlan object
1342
CommonXMLStructure::SumoBaseObject* personPlanObject = new CommonXMLStructure::SumoBaseObject(myPlanObject);
1343
// get person plan attributes
1344
personPlanAttributesEditor->fillSumoBaseObject(personPlanObject);
1345
// get attributes
1346
const std::vector<std::string> types = personPlanObject->hasStringListAttribute(SUMO_ATTR_VTYPES) ? personPlanObject->getStringListAttribute(SUMO_ATTR_VTYPES) :
1347
personPlanObject->hasStringAttribute(SUMO_ATTR_VTYPES) ? GNEAttributeCarrier::parse<std::vector<std::string> >(personPlanObject->getStringAttribute(SUMO_ATTR_VTYPES)) :
1348
std::vector<std::string>();
1349
const std::vector<std::string> modes = personPlanObject->hasStringListAttribute(SUMO_ATTR_MODES) ? personPlanObject->getStringListAttribute(SUMO_ATTR_MODES) :
1350
personPlanObject->hasStringAttribute(SUMO_ATTR_MODES) ? GNEAttributeCarrier::parse<std::vector<std::string> >(personPlanObject->getStringAttribute(SUMO_ATTR_MODES)) :
1351
std::vector<std::string>();
1352
const std::vector<std::string> lines = personPlanObject->hasStringListAttribute(SUMO_ATTR_LINES) ? personPlanObject->getStringListAttribute(SUMO_ATTR_LINES) :
1353
personPlanObject->hasStringAttribute(SUMO_ATTR_LINES) ? GNEAttributeCarrier::parse<std::vector<std::string> >(personPlanObject->getStringAttribute(SUMO_ATTR_LINES)) :
1354
std::vector<std::string>();
1355
const double arrivalPos = personPlanObject->hasDoubleAttribute(SUMO_ATTR_ARRIVALPOS) ? personPlanObject->getDoubleAttribute(SUMO_ATTR_ARRIVALPOS) :
1356
personPlanObject->hasStringAttribute(SUMO_ATTR_ARRIVALPOS) ? GNEAttributeCarrier::parse<double>(personPlanObject->getStringAttribute(SUMO_ATTR_ARRIVALPOS)) :
1357
-1;
1358
const double endPos = personPlanObject->hasDoubleAttribute(SUMO_ATTR_ENDPOS) ? personPlanObject->getDoubleAttribute(SUMO_ATTR_ENDPOS) :
1359
personPlanObject->hasStringAttribute(SUMO_ATTR_ENDPOS) ? GNEAttributeCarrier::parse<double>(personPlanObject->getStringAttribute(SUMO_ATTR_ENDPOS)) :
1360
planCreator->getClickedPositionOverLane();
1361
const SUMOTime duration = personPlanObject->hasTimeAttribute(SUMO_ATTR_DURATION) ? personPlanObject->getTimeAttribute(SUMO_ATTR_DURATION) :
1362
personPlanObject->hasStringAttribute(SUMO_ATTR_DURATION) ? GNEAttributeCarrier::parse<SUMOTime>(personPlanObject->getStringAttribute(SUMO_ATTR_DURATION)) :
1363
0;
1364
const SUMOTime until = personPlanObject->hasTimeAttribute(SUMO_ATTR_UNTIL) ? personPlanObject->getTimeAttribute(SUMO_ATTR_UNTIL) :
1365
personPlanObject->hasStringAttribute(SUMO_ATTR_UNTIL) ? GNEAttributeCarrier::parse<SUMOTime>(personPlanObject->getStringAttribute(SUMO_ATTR_UNTIL)) :
1366
0;
1367
const std::string actType = personPlanObject->hasStringAttribute(SUMO_ATTR_ACTTYPE) ? personPlanObject->getStringAttribute(SUMO_ATTR_ACTTYPE) : "";
1368
const bool friendlyPos = personPlanObject->hasBoolAttribute(SUMO_ATTR_FRIENDLY_POS) ? personPlanObject->getBoolAttribute(SUMO_ATTR_FRIENDLY_POS) :
1369
personPlanObject->hasStringAttribute(SUMO_ATTR_FRIENDLY_POS) ? GNEAttributeCarrier::parse<bool>(personPlanObject->getStringAttribute(SUMO_ATTR_FRIENDLY_POS)) :
1370
false;
1371
const double walkFactor = personPlanObject->hasDoubleAttribute(SUMO_ATTR_WALKFACTOR) ? personPlanObject->getDoubleAttribute(SUMO_ATTR_WALKFACTOR) : 0;
1372
const std::string group = personPlanObject->hasStringAttribute(SUMO_ATTR_GROUP) ? personPlanObject->getStringAttribute(SUMO_ATTR_GROUP) : "";
1373
const double speed = personPlanObject->hasDoubleAttribute(SUMO_ATTR_SPEED) ? personPlanObject->getDoubleAttribute(SUMO_ATTR_SPEED) : 0;
1374
// build depending of plan type
1375
if (planTemplate->getTagProperty()->isPlanWalk()) {
1376
buildWalk(personPlanObject, planCreator->getPlanParameteres(), arrivalPos, speed, duration);
1377
} else if (planTemplate->getTagProperty()->isPlanPersonTrip()) {
1378
buildPersonTrip(personPlanObject, planCreator->getPlanParameteres(), arrivalPos, types, modes, lines, walkFactor, group);
1379
} else if (planTemplate->getTagProperty()->isPlanRide()) {
1380
buildRide(personPlanObject, planCreator->getPlanParameteres(), arrivalPos, lines, group);
1381
} else if (planTemplate->getTagProperty()->isPlanStopPerson()) {
1382
// set specific stop parameters
1383
int parameterSet = 0;
1384
if (personPlanObject->hasTimeAttribute(SUMO_ATTR_DURATION)) {
1385
parameterSet |= STOP_DURATION_SET;
1386
}
1387
if (personPlanObject->hasTimeAttribute(SUMO_ATTR_UNTIL)) {
1388
parameterSet |= STOP_UNTIL_SET;
1389
}
1390
buildPersonStop(personPlanObject, planCreator->getPlanParameteres(), endPos, duration, until, actType, friendlyPos, parameterSet);
1391
}
1392
// get person
1393
const auto person = myNet->getAttributeCarriers()->retrieveDemandElement(personPlanObject->getParentSumoBaseObject()->getTag(),
1394
personPlanObject->getParentSumoBaseObject()->getStringAttribute(SUMO_ATTR_ID), false);
1395
if (person) {
1396
// center view after creation
1397
if (centerAfterCreation && !myNet->getViewNet()->getVisibleBoundary().around(person->getPositionInView())) {
1398
myNet->getViewNet()->centerTo(person->getPositionInView(), false);
1399
}
1400
}
1401
delete personPlanObject;
1402
return true;
1403
}
1404
1405
1406
bool
1407
GNERouteHandler::buildContainerPlan(const GNEDemandElement* planTemplate, GNEDemandElement* containerParent,
1408
GNEAttributesEditor* containerPlanAttributesEditor, GNEPlanCreator* planCreator,
1409
const bool centerAfterCreation) {
1410
// first check if container is valid
1411
if (containerParent == nullptr) {
1412
return false;
1413
}
1414
// clear and set container object
1415
myPlanObject->clear();
1416
myPlanObject->setTag(containerParent->getTagProperty()->getTag());
1417
myPlanObject->addStringAttribute(SUMO_ATTR_ID, containerParent->getID());
1418
// declare containerPlan object
1419
CommonXMLStructure::SumoBaseObject* containerPlanObject = new CommonXMLStructure::SumoBaseObject(myPlanObject);
1420
// get container plan attributes
1421
containerPlanAttributesEditor->fillSumoBaseObject(containerPlanObject);
1422
// get attributes
1423
const double speed = containerPlanObject->hasDoubleAttribute(SUMO_ATTR_SPEED) ? containerPlanObject->getDoubleAttribute(SUMO_ATTR_SPEED) :
1424
containerPlanObject->hasStringAttribute(SUMO_ATTR_SPEED) ? GNEAttributeCarrier::parse<double>(containerPlanObject->getStringAttribute(SUMO_ATTR_SPEED)) :
1425
0;
1426
const std::vector<std::string> lines = containerPlanObject->hasStringListAttribute(SUMO_ATTR_LINES) ? containerPlanObject->getStringListAttribute(SUMO_ATTR_LINES) :
1427
containerPlanObject->hasStringAttribute(SUMO_ATTR_LINES) ? GNEAttributeCarrier::parse<std::vector<std::string> >(containerPlanObject->getStringAttribute(SUMO_ATTR_LINES)) :
1428
std::vector<std::string>();
1429
const double departPos = containerPlanObject->hasDoubleAttribute(SUMO_ATTR_DEPARTPOS) ? containerPlanObject->getDoubleAttribute(SUMO_ATTR_DEPARTPOS) :
1430
containerPlanObject->hasStringAttribute(SUMO_ATTR_DEPARTPOS) ? GNEAttributeCarrier::parse<double>(containerPlanObject->getStringAttribute(SUMO_ATTR_DEPARTPOS)) :
1431
-1;
1432
const double arrivalPos = containerPlanObject->hasDoubleAttribute(SUMO_ATTR_ARRIVALPOS) ? containerPlanObject->getDoubleAttribute(SUMO_ATTR_ARRIVALPOS) :
1433
containerPlanObject->hasStringAttribute(SUMO_ATTR_ARRIVALPOS) ? GNEAttributeCarrier::parse<double>(containerPlanObject->getStringAttribute(SUMO_ATTR_ARRIVALPOS)) :
1434
-1;
1435
const double endPos = containerPlanObject->hasDoubleAttribute(SUMO_ATTR_ENDPOS) ? containerPlanObject->getDoubleAttribute(SUMO_ATTR_ENDPOS) :
1436
containerPlanObject->hasStringAttribute(SUMO_ATTR_ENDPOS) ? GNEAttributeCarrier::parse<double>(containerPlanObject->getStringAttribute(SUMO_ATTR_ENDPOS)) :
1437
planCreator->getClickedPositionOverLane();
1438
const SUMOTime duration = containerPlanObject->hasTimeAttribute(SUMO_ATTR_DURATION) ? containerPlanObject->getTimeAttribute(SUMO_ATTR_DURATION) :
1439
containerPlanObject->hasStringAttribute(SUMO_ATTR_DURATION) ? GNEAttributeCarrier::parse<SUMOTime>(containerPlanObject->getStringAttribute(SUMO_ATTR_DURATION)) :
1440
0;
1441
const SUMOTime until = containerPlanObject->hasTimeAttribute(SUMO_ATTR_UNTIL) ? containerPlanObject->getTimeAttribute(SUMO_ATTR_UNTIL) :
1442
containerPlanObject->hasStringAttribute(SUMO_ATTR_UNTIL) ? GNEAttributeCarrier::parse<SUMOTime>(containerPlanObject->getStringAttribute(SUMO_ATTR_UNTIL)) :
1443
0;
1444
const std::string actType = containerPlanObject->hasStringAttribute(SUMO_ATTR_ACTTYPE) ? containerPlanObject->getStringAttribute(SUMO_ATTR_ACTTYPE) : "";
1445
const bool friendlyPos = containerPlanObject->hasBoolAttribute(SUMO_ATTR_FRIENDLY_POS) ? containerPlanObject->getBoolAttribute(SUMO_ATTR_FRIENDLY_POS) :
1446
containerPlanObject->hasStringAttribute(SUMO_ATTR_FRIENDLY_POS) ? GNEAttributeCarrier::parse<bool>(containerPlanObject->getStringAttribute(SUMO_ATTR_FRIENDLY_POS)) :
1447
false;
1448
const std::string group = containerPlanObject->hasStringAttribute(SUMO_ATTR_GROUP) ? containerPlanObject->getStringAttribute(SUMO_ATTR_GROUP) : "";
1449
// build depending of plan type
1450
if (planTemplate->getTagProperty()->isPlanTranship()) {
1451
buildTranship(containerPlanObject, planCreator->getPlanParameteres(), arrivalPos, departPos, speed, duration);
1452
} else if (planTemplate->getTagProperty()->isPlanTransport()) {
1453
buildTransport(containerPlanObject, planCreator->getPlanParameteres(), arrivalPos, lines, group);
1454
} else if (planTemplate->getTagProperty()->isPlanStopContainer()) {
1455
// set stops specific parameters
1456
int parameterSet = 0;
1457
if (containerPlanObject->hasTimeAttribute(SUMO_ATTR_DURATION)) {
1458
parameterSet |= STOP_DURATION_SET;
1459
}
1460
if (containerPlanObject->hasTimeAttribute(SUMO_ATTR_UNTIL)) {
1461
parameterSet |= STOP_UNTIL_SET;
1462
}
1463
buildContainerStop(containerPlanObject, planCreator->getPlanParameteres(), endPos, duration, until, actType, friendlyPos, parameterSet);
1464
}
1465
// get container
1466
const auto container = myNet->getAttributeCarriers()->retrieveDemandElement(containerPlanObject->getParentSumoBaseObject()->getTag(),
1467
containerPlanObject->getParentSumoBaseObject()->getStringAttribute(SUMO_ATTR_ID), false);
1468
if (container) {
1469
// center view after creation
1470
if (centerAfterCreation && !myNet->getViewNet()->getVisibleBoundary().around(container->getPositionInView())) {
1471
myNet->getViewNet()->centerTo(container->getPositionInView(), false);
1472
}
1473
}
1474
delete containerPlanObject;
1475
return true;
1476
}
1477
1478
1479
void
1480
GNERouteHandler::duplicatePlan(const GNEDemandElement* originalPlan, GNEDemandElement* newParent) {
1481
const auto tagProperty = originalPlan->getTagProperty();
1482
// clear and set container object
1483
myPlanObject->clear();
1484
myPlanObject->setTag(newParent->getTagProperty()->getTag());
1485
myPlanObject->addStringAttribute(SUMO_ATTR_ID, newParent->getID());
1486
// declare personPlan object for adding all attributes
1487
CommonXMLStructure::SumoBaseObject* planObject = new CommonXMLStructure::SumoBaseObject(myPlanObject);
1488
planObject->setTag(tagProperty->getTag());
1489
// declare parameters
1490
CommonXMLStructure::PlanParameters planParameters;
1491
// from-to elements
1492
if (tagProperty->planFromEdge()) {
1493
planParameters.fromEdge = originalPlan->getAttribute(SUMO_ATTR_FROM);
1494
}
1495
if (tagProperty->planToEdge()) {
1496
planParameters.toEdge = originalPlan->getAttribute(SUMO_ATTR_TO);
1497
}
1498
if (tagProperty->planFromJunction()) {
1499
planParameters.fromJunction = originalPlan->getAttribute(SUMO_ATTR_FROM_JUNCTION);
1500
}
1501
if (tagProperty->planToJunction()) {
1502
planParameters.toJunction = originalPlan->getAttribute(SUMO_ATTR_TO_JUNCTION);
1503
}
1504
if (tagProperty->planFromTAZ()) {
1505
planParameters.fromTAZ = originalPlan->getAttribute(SUMO_ATTR_FROM_TAZ);
1506
}
1507
if (tagProperty->planToTAZ()) {
1508
planParameters.toTAZ = originalPlan->getAttribute(SUMO_ATTR_TO_TAZ);
1509
}
1510
if (tagProperty->planFromBusStop()) {
1511
planParameters.fromBusStop = originalPlan->getAttribute(GNE_ATTR_FROM_BUSSTOP);
1512
}
1513
if (tagProperty->planToBusStop()) {
1514
planParameters.toBusStop = originalPlan->getAttribute(SUMO_ATTR_BUS_STOP);
1515
}
1516
if (tagProperty->planFromTrainStop()) {
1517
planParameters.fromTrainStop = originalPlan->getAttribute(GNE_ATTR_FROM_TRAINSTOP);
1518
}
1519
if (tagProperty->planToTrainStop()) {
1520
planParameters.toTrainStop = originalPlan->getAttribute(SUMO_ATTR_TRAIN_STOP);
1521
}
1522
if (tagProperty->planFromContainerStop()) {
1523
planParameters.fromContainerStop = originalPlan->getAttribute(GNE_ATTR_FROM_CONTAINERSTOP);
1524
}
1525
if (tagProperty->planToContainerStop()) {
1526
planParameters.toContainerStop = originalPlan->getAttribute(SUMO_ATTR_CONTAINER_STOP);
1527
}
1528
// single elements
1529
if (tagProperty->planEdge()) {
1530
planParameters.toEdge = originalPlan->getAttribute(SUMO_ATTR_EDGE);
1531
}
1532
if (tagProperty->planBusStop()) {
1533
planParameters.toBusStop = originalPlan->getAttribute(SUMO_ATTR_BUS_STOP);
1534
}
1535
if (tagProperty->planTrainStop()) {
1536
planParameters.toTrainStop = originalPlan->getAttribute(SUMO_ATTR_TRAIN_STOP);
1537
}
1538
if (tagProperty->planContainerStop()) {
1539
planParameters.toContainerStop = originalPlan->getAttribute(SUMO_ATTR_CONTAINER_STOP);
1540
}
1541
// route
1542
if (tagProperty->planRoute()) {
1543
planParameters.toRoute = originalPlan->getAttribute(SUMO_ATTR_ROUTE);
1544
}
1545
// path
1546
if (tagProperty->planConsecutiveEdges()) {
1547
planParameters.consecutiveEdges = GNEAttributeCarrier::parse<std::vector<std::string> >(originalPlan->getAttribute(SUMO_ATTR_EDGES));
1548
}
1549
// other elements
1550
planObject->addTimeAttribute(SUMO_ATTR_DURATION, 60);
1551
planObject->addTimeAttribute(SUMO_ATTR_UNTIL, 0);
1552
planObject->addDoubleAttribute(SUMO_ATTR_DEPARTPOS, 0);
1553
planObject->addDoubleAttribute(SUMO_ATTR_ARRIVALPOS, -1);
1554
planObject->addDoubleAttribute(SUMO_ATTR_ENDPOS, 0);
1555
planObject->addDoubleAttribute(SUMO_ATTR_SPEED, 1.39);
1556
planObject->addBoolAttribute(SUMO_ATTR_FRIENDLY_POS, false);
1557
// add rest of attributes
1558
for (const auto& attrProperty : tagProperty->getAttributeProperties()) {
1559
if (!planObject->hasStringAttribute(attrProperty->getAttr())) {
1560
if (attrProperty->isFloat()) {
1561
if (!originalPlan->getAttribute(attrProperty->getAttr()).empty()) {
1562
planObject->addDoubleAttribute(attrProperty->getAttr(), originalPlan->getAttributeDouble(attrProperty->getAttr()));
1563
}
1564
} else if (attrProperty->isSUMOTime()) {
1565
if (!originalPlan->getAttribute(attrProperty->getAttr()).empty()) {
1566
planObject->addTimeAttribute(attrProperty->getAttr(), GNEAttributeCarrier::parse<SUMOTime>(originalPlan->getAttribute(attrProperty->getAttr())));
1567
}
1568
} else if (attrProperty->isBool()) {
1569
planObject->addBoolAttribute(attrProperty->getAttr(), GNEAttributeCarrier::parse<bool>(originalPlan->getAttribute(attrProperty->getAttr())));
1570
} else if (attrProperty->isList()) {
1571
planObject->addStringListAttribute(attrProperty->getAttr(), GNEAttributeCarrier::parse<std::vector<std::string> >(originalPlan->getAttribute(attrProperty->getAttr())));
1572
} else {
1573
planObject->addStringAttribute(attrProperty->getAttr(), originalPlan->getAttribute(attrProperty->getAttr()));
1574
}
1575
}
1576
}
1577
// create plan
1578
if (tagProperty->isPlanPersonTrip()) {
1579
buildPersonTrip(planObject, planParameters,
1580
planObject->getDoubleAttribute(SUMO_ATTR_ARRIVALPOS),
1581
planObject->getStringListAttribute(SUMO_ATTR_VTYPES),
1582
planObject->getStringListAttribute(SUMO_ATTR_MODES),
1583
planObject->getStringListAttribute(SUMO_ATTR_LINES),
1584
planObject->getDoubleAttribute(SUMO_ATTR_WALKFACTOR),
1585
planObject->getStringAttribute(SUMO_ATTR_GROUP));
1586
} else if (tagProperty->isPlanWalk()) {
1587
buildWalk(planObject, planParameters,
1588
planObject->getDoubleAttribute(SUMO_ATTR_ARRIVALPOS),
1589
planObject->getDoubleAttribute(SUMO_ATTR_SPEED),
1590
planObject->getTimeAttribute(SUMO_ATTR_DURATION));
1591
} else if (tagProperty->isPlanRide()) {
1592
buildRide(planObject, planParameters,
1593
planObject->getDoubleAttribute(SUMO_ATTR_ARRIVALPOS),
1594
planObject->getStringListAttribute(SUMO_ATTR_LINES),
1595
planObject->getStringAttribute(SUMO_ATTR_GROUP));
1596
} else if (tagProperty->isPlanStopPerson()) {
1597
// set parameters
1598
int parameterSet = 0;
1599
if (planObject->hasTimeAttribute(SUMO_ATTR_DURATION)) {
1600
parameterSet |= STOP_DURATION_SET;
1601
}
1602
if (planObject->hasTimeAttribute(SUMO_ATTR_UNTIL)) {
1603
parameterSet |= STOP_UNTIL_SET;
1604
}
1605
buildPersonStop(planObject, planParameters,
1606
planObject->getDoubleAttribute(SUMO_ATTR_ENDPOS),
1607
planObject->getTimeAttribute(SUMO_ATTR_DURATION),
1608
planObject->getTimeAttribute(SUMO_ATTR_UNTIL),
1609
planObject->getStringAttribute(SUMO_ATTR_ACTTYPE),
1610
planObject->getBoolAttribute(SUMO_ATTR_FRIENDLY_POS),
1611
parameterSet);
1612
} else if (tagProperty->isPlanTransport()) {
1613
buildTransport(planObject, planParameters,
1614
planObject->getDoubleAttribute(SUMO_ATTR_ARRIVALPOS),
1615
planObject->getStringListAttribute(SUMO_ATTR_LINES),
1616
planObject->getStringAttribute(SUMO_ATTR_GROUP));
1617
} else if (tagProperty->isPlanTranship()) {
1618
buildTranship(planObject, planParameters,
1619
planObject->getDoubleAttribute(SUMO_ATTR_ARRIVALPOS),
1620
planObject->getDoubleAttribute(SUMO_ATTR_DEPARTPOS),
1621
planObject->getDoubleAttribute(SUMO_ATTR_SPEED),
1622
planObject->getTimeAttribute(SUMO_ATTR_DURATION));
1623
} else if (tagProperty->isPlanStopContainer()) {
1624
// set parameters
1625
int parameterSet = 0;
1626
if (planObject->hasTimeAttribute(SUMO_ATTR_DURATION)) {
1627
parameterSet |= STOP_DURATION_SET;
1628
}
1629
if (planObject->hasTimeAttribute(SUMO_ATTR_UNTIL)) {
1630
parameterSet |= STOP_UNTIL_SET;
1631
}
1632
buildContainerStop(planObject, planParameters,
1633
planObject->getDoubleAttribute(SUMO_ATTR_ENDPOS),
1634
planObject->getTimeAttribute(SUMO_ATTR_DURATION),
1635
planObject->getTimeAttribute(SUMO_ATTR_UNTIL),
1636
planObject->getStringAttribute(SUMO_ATTR_ACTTYPE),
1637
planObject->getBoolAttribute(SUMO_ATTR_FRIENDLY_POS),
1638
parameterSet);
1639
} else {
1640
throw ProcessError("Invalid plan for duplicating");
1641
}
1642
}
1643
1644
1645
bool
1646
GNERouteHandler::checkViaAttribute(const SumoXMLTag tag, const std::string& id, const std::vector<std::string>& via) {
1647
for (const auto& edgeID : via) {
1648
if (myNet->getAttributeCarriers()->retrieveEdge(edgeID, false) == nullptr) {
1649
return writeError(TLF("Could not build % with ID '%' in netedit; via % with ID '%' doesn't exist.", toString(tag), id, toString(SUMO_TAG_EDGE), edgeID));
1650
}
1651
}
1652
return true;
1653
}
1654
1655
1656
void
1657
GNERouteHandler::transformToVehicle(GNEVehicle* originalVehicle, bool createEmbeddedRoute) {
1658
auto GNEApp = originalVehicle->getNet()->getGNEApplicationWindow();
1659
// get pointer to net
1660
GNENet* net = originalVehicle->getNet();
1661
// check if transform after creation
1662
const bool inspectAfterTransform = net->getViewNet()->getInspectedElements().isACInspected(originalVehicle);
1663
// declare route handler
1664
GNERouteHandler routeHandler(net, originalVehicle->getFileBucket(), GNEApp->isUndoRedoAllowed(), true);
1665
// make a copy of the vehicle parameters
1666
SUMOVehicleParameter vehicleParameters = *originalVehicle;
1667
// obtain vClass
1668
const auto vClass = originalVehicle->getVClass();
1669
// set "yellow" as original route color
1670
RGBColor routeColor = RGBColor::YELLOW;
1671
// declare edges
1672
GNEDemandElement* originalRoute = nullptr;
1673
std::vector<GNEEdge*> routeEdges;
1674
// obtain edges depending of tag
1675
if (originalVehicle->getTagProperty()->vehicleRoute()) {
1676
// get route edges
1677
originalRoute = originalVehicle->getParentDemandElements().at(1);
1678
} else if (originalVehicle->getTagProperty()->vehicleRouteEmbedded()) {
1679
// get embedded route edges
1680
routeEdges = originalVehicle->getChildDemandElements().front()->getParentEdges();
1681
} else if (originalVehicle->getTagProperty()->vehicleEdges()) {
1682
// calculate path using from-via-to edges
1683
routeEdges = originalVehicle->getNet()->getDemandPathManager()->getPathCalculator()->calculateDijkstraPath(originalVehicle->getVClass(), originalVehicle->getParentEdges());
1684
}
1685
// declare edge IDs
1686
std::vector<std::string> edgeIDs;
1687
for (const auto& edge : routeEdges) {
1688
edgeIDs.push_back(edge->getID());
1689
}
1690
// only continue if edges are valid
1691
if (!originalRoute && routeEdges.empty()) {
1692
// declare header
1693
const std::string header = "Problem transforming to vehicle";
1694
// declare message
1695
const std::string message = "Vehicle cannot be transformed. Invalid number of edges";
1696
// open message box
1697
GNEWarningBasicDialog(GNEApp, header, message);
1698
} else {
1699
// begin undo-redo operation
1700
net->getViewNet()->getUndoList()->begin(originalVehicle, "transform " + originalVehicle->getTagStr() + " to " + toString(SUMO_TAG_VEHICLE));
1701
// first delete vehicle
1702
net->deleteDemandElement(originalVehicle, net->getViewNet()->getUndoList());
1703
// check if new vehicle must have an embedded route
1704
if (createEmbeddedRoute) {
1705
// change tag in vehicle parameters
1706
vehicleParameters.tag = GNE_TAG_VEHICLE_WITHROUTE;
1707
// build embedded route
1708
if (originalRoute) {
1709
for (const auto& edge : originalRoute->getParentEdges()) {
1710
edgeIDs.push_back(edge->getID());
1711
}
1712
routeHandler.buildVehicleEmbeddedRoute(nullptr, vehicleParameters, edgeIDs, RGBColor::INVISIBLE, 0, 0, {});
1713
} else {
1714
routeHandler.buildVehicleEmbeddedRoute(nullptr, vehicleParameters, edgeIDs, RGBColor::INVISIBLE, 0, 0, {});
1715
}
1716
} else if (originalRoute) {
1717
// set route ID in vehicle parameters
1718
vehicleParameters.routeid = originalRoute->getID();
1719
// create vehicle
1720
routeHandler.buildVehicleOverRoute(nullptr, vehicleParameters);
1721
} else {
1722
// change tag in vehicle parameters
1723
vehicleParameters.tag = SUMO_TAG_VEHICLE;
1724
// generate route ID
1725
const std::string routeID = net->getAttributeCarriers()->generateDemandElementID(SUMO_TAG_ROUTE);
1726
// build route
1727
routeHandler.buildRoute(nullptr, routeID, vClass, edgeIDs, routeColor, 0, 0, DEFAULT_VEH_PROB, {});
1728
// set route ID in vehicle parameters
1729
vehicleParameters.routeid = routeID;
1730
// create vehicle
1731
routeHandler.buildVehicleOverRoute(nullptr, vehicleParameters);
1732
}
1733
// end undo-redo operation
1734
net->getViewNet()->getUndoList()->end();
1735
// check if inspect
1736
if (inspectAfterTransform) {
1737
// get created element
1738
auto transformedVehicle = net->getAttributeCarriers()->retrieveDemandElement(vehicleParameters.tag, vehicleParameters.id);
1739
// inspect it
1740
net->getViewNet()->getViewParent()->getInspectorFrame()->inspectElement(transformedVehicle);
1741
}
1742
}
1743
}
1744
1745
1746
void
1747
GNERouteHandler::transformToRouteFlow(GNEVehicle* originalVehicle, bool createEmbeddedRoute) {
1748
auto GNEApp = originalVehicle->getNet()->getGNEApplicationWindow();
1749
// get pointer to net
1750
GNENet* net = originalVehicle->getNet();
1751
// check if transform after creation
1752
const bool inspectAfterTransform = net->getViewNet()->getInspectedElements().isACInspected(originalVehicle);
1753
// declare route handler
1754
GNERouteHandler routeHandler(net, originalVehicle->getFileBucket(), GNEApp->isUndoRedoAllowed(), true);
1755
// obtain vehicle parameters
1756
SUMOVehicleParameter vehicleParameters = *originalVehicle;
1757
// obtain vClass
1758
const auto vClass = originalVehicle->getVClass();
1759
// set "yellow" as original route color
1760
RGBColor routeColor = RGBColor::YELLOW;
1761
// declare edges
1762
GNEDemandElement* originalRoute = nullptr;
1763
std::vector<GNEEdge*> routeEdges;
1764
// obtain edges depending of tag
1765
if (originalVehicle->getTagProperty()->vehicleRoute()) {
1766
// get original route
1767
originalRoute = originalVehicle->getParentDemandElements().back();
1768
} else if (originalVehicle->getTagProperty()->vehicleRouteEmbedded()) {
1769
// get embedded route edges
1770
routeEdges = originalVehicle->getChildDemandElements().front()->getParentEdges();
1771
} else if (originalVehicle->getTagProperty()->vehicleEdges()) {
1772
// calculate path using from-via-to edges
1773
routeEdges = originalVehicle->getNet()->getDemandPathManager()->getPathCalculator()->calculateDijkstraPath(originalVehicle->getVClass(), originalVehicle->getParentEdges());
1774
}
1775
// declare edge IDs
1776
std::vector<std::string> edgeIDs;
1777
for (const auto& edge : routeEdges) {
1778
edgeIDs.push_back(edge->getID());
1779
}
1780
// only continue if edges are valid
1781
if (!originalRoute && routeEdges.empty()) {
1782
// declare header
1783
const std::string header = "Problem transforming to vehicle";
1784
// declare message
1785
const std::string message = "Vehicle cannot be transformed. Invalid number of edges";
1786
// open message box
1787
GNEWarningBasicDialog(GNEApp, header, message);
1788
} else {
1789
// begin undo-redo operation
1790
net->getViewNet()->getUndoList()->begin(originalVehicle, "transform " + originalVehicle->getTagStr() + " to " + toString(GNE_TAG_FLOW_ROUTE));
1791
// first delete vehicle
1792
net->deleteDemandElement(originalVehicle, net->getViewNet()->getUndoList());
1793
// change depart
1794
if (!originalVehicle->getTagProperty()->isFlow()) {
1795
// get template flow
1796
const auto templateFlow = net->getViewNet()->getNet()->getACTemplates()->getTemplateAC(GNE_TAG_FLOW_ROUTE);
1797
// set flow parameters
1798
vehicleParameters.repetitionEnd = vehicleParameters.depart + string2time("3600");
1799
vehicleParameters.repetitionNumber = GNEAttributeCarrier::parse<int>(templateFlow->getAttribute(SUMO_ATTR_NUMBER));
1800
vehicleParameters.repetitionOffset = string2time(templateFlow->getAttribute(SUMO_ATTR_PERIOD));
1801
vehicleParameters.repetitionProbability = GNEAttributeCarrier::parse<double>(templateFlow->getAttribute(SUMO_ATTR_PROB));
1802
// by default, number and end enabled
1803
vehicleParameters.parametersSet = GNEAttributeCarrier::parse<int>(templateFlow->getAttribute(GNE_ATTR_FLOWPARAMETERS));
1804
}
1805
// check if new vehicle must have an embedded route
1806
if (createEmbeddedRoute) {
1807
// change tag in vehicle parameters
1808
vehicleParameters.tag = GNE_TAG_FLOW_WITHROUTE;
1809
// build embedded route
1810
if (originalRoute) {
1811
for (const auto& edge : originalRoute->getParentEdges()) {
1812
edgeIDs.push_back(edge->getID());
1813
}
1814
routeHandler.buildFlowEmbeddedRoute(nullptr, vehicleParameters, edgeIDs, RGBColor::INVISIBLE, 0, 0, {});
1815
} else {
1816
routeHandler.buildFlowEmbeddedRoute(nullptr, vehicleParameters, edgeIDs, RGBColor::INVISIBLE, 0, 0, {});
1817
}
1818
} else if (originalRoute) {
1819
// set route ID in vehicle parameters
1820
vehicleParameters.routeid = originalRoute->getID();
1821
// create vehicle
1822
routeHandler.buildFlowOverRoute(nullptr, vehicleParameters);
1823
} else {
1824
// change tag in vehicle parameters
1825
vehicleParameters.tag = GNE_TAG_FLOW_ROUTE;
1826
// generate a new route id
1827
const std::string routeID = net->getAttributeCarriers()->generateDemandElementID(SUMO_TAG_ROUTE);
1828
// build route
1829
routeHandler.buildRoute(nullptr, routeID, vClass, edgeIDs, routeColor, 0, 0, DEFAULT_VEH_PROB, {});
1830
// set route ID in vehicle parameters
1831
vehicleParameters.routeid = routeID;
1832
// create vehicle
1833
routeHandler.buildFlowOverRoute(nullptr, vehicleParameters);
1834
}
1835
1836
// end undo-redo operation
1837
net->getViewNet()->getUndoList()->end();
1838
// check if inspect
1839
if (inspectAfterTransform) {
1840
// get created element
1841
auto transformedVehicle = net->getAttributeCarriers()->retrieveDemandElement(vehicleParameters.tag, vehicleParameters.id);
1842
// inspect it
1843
net->getViewNet()->getViewParent()->getInspectorFrame()->inspectElement(transformedVehicle);
1844
}
1845
}
1846
}
1847
1848
1849
void
1850
GNERouteHandler::transformToTrip(GNEVehicle* originalVehicle) {
1851
auto GNEApp = originalVehicle->getNet()->getGNEApplicationWindow();
1852
// get pointer to net
1853
GNENet* net = originalVehicle->getNet();
1854
// check if transform after creation
1855
const bool inspectAfterTransform = net->getViewNet()->getInspectedElements().isACInspected(originalVehicle);
1856
// declare route handler
1857
GNERouteHandler routeHandler(net, originalVehicle->getFileBucket(), GNEApp->isUndoRedoAllowed(), true);
1858
// obtain vehicle parameters
1859
SUMOVehicleParameter vehicleParameters = *originalVehicle;
1860
// get route
1861
GNEDemandElement* route = nullptr;
1862
// declare edges
1863
std::vector<GNEEdge*> edges;
1864
// obtain edges depending of tag
1865
if (originalVehicle->getTagProperty()->vehicleRoute()) {
1866
// set route
1867
route = originalVehicle->getParentDemandElements().back();
1868
// get route edges
1869
edges = route->getParentEdges();
1870
} else if (originalVehicle->getTagProperty()->vehicleRouteEmbedded()) {
1871
// get embedded route edges
1872
edges = originalVehicle->getChildDemandElements().front()->getParentEdges();
1873
} else if (originalVehicle->getTagProperty()->vehicleEdges()) {
1874
// just take parent edges (from and to)
1875
edges = originalVehicle->getParentEdges();
1876
}
1877
// only continue if edges are valid
1878
if (edges.size() < 2) {
1879
// declare header
1880
const std::string header = "Problem transforming to vehicle";
1881
// declare message
1882
const std::string message = "Vehicle cannot be transformed. Invalid number of edges";
1883
// open message box
1884
GNEWarningBasicDialog(GNEApp, header, message);
1885
} else {
1886
// begin undo-redo operation
1887
net->getViewNet()->getUndoList()->begin(originalVehicle, "transform " + originalVehicle->getTagStr() + " to " + toString(SUMO_TAG_TRIP));
1888
// first delete vehicle
1889
net->deleteDemandElement(originalVehicle, net->getViewNet()->getUndoList());
1890
// check if route has to be deleted
1891
if (route && route->getChildDemandElements().empty()) {
1892
net->deleteDemandElement(route, net->getViewNet()->getUndoList());
1893
}
1894
// change tag in vehicle parameters
1895
vehicleParameters.tag = SUMO_TAG_TRIP;
1896
// create trip
1897
routeHandler.buildTrip(nullptr, vehicleParameters, edges.front()->getID(), edges.back()->getID());
1898
// end undo-redo operation
1899
net->getViewNet()->getUndoList()->end();
1900
// check if inspect
1901
if (inspectAfterTransform) {
1902
// get created element
1903
auto transformedVehicle = net->getAttributeCarriers()->retrieveDemandElement(vehicleParameters.tag, vehicleParameters.id);
1904
// inspect it
1905
net->getViewNet()->getViewParent()->getInspectorFrame()->inspectElement(transformedVehicle);
1906
}
1907
}
1908
}
1909
1910
1911
void
1912
GNERouteHandler::transformToFlow(GNEVehicle* originalVehicle) {
1913
auto GNEApp = originalVehicle->getNet()->getGNEApplicationWindow();
1914
// get pointer to net
1915
GNENet* net = originalVehicle->getNet();
1916
// check if transform after creation
1917
const bool inspectAfterTransform = net->getViewNet()->getInspectedElements().isACInspected(originalVehicle);
1918
// declare route handler
1919
GNERouteHandler routeHandler(net, originalVehicle->getFileBucket(), GNEApp->isUndoRedoAllowed(), true);
1920
// obtain vehicle parameters
1921
SUMOVehicleParameter vehicleParameters = *originalVehicle;
1922
// declare route
1923
GNEDemandElement* route = nullptr;
1924
// declare edges
1925
std::vector<GNEEdge*> edges;
1926
// obtain edges depending of tag
1927
if (originalVehicle->getTagProperty()->vehicleRoute()) {
1928
// set route
1929
route = originalVehicle->getParentDemandElements().back();
1930
// get route edges
1931
edges = route->getParentEdges();
1932
} else if (originalVehicle->getTagProperty()->vehicleRouteEmbedded()) {
1933
// get embedded route edges
1934
edges = originalVehicle->getChildDemandElements().front()->getParentEdges();
1935
} else if (originalVehicle->getTagProperty()->vehicleEdges()) {
1936
// just take parent edges (from and to)
1937
edges = originalVehicle->getParentEdges();
1938
}
1939
// only continue if edges are valid
1940
if (edges.empty()) {
1941
// declare header
1942
const std::string header = "Problem transforming to vehicle";
1943
// declare message
1944
const std::string message = "Vehicle cannot be transformed. Invalid number of edges";
1945
// open message box
1946
GNEWarningBasicDialog(GNEApp, header, message);
1947
} else {
1948
// begin undo-redo operation
1949
net->getViewNet()->getUndoList()->begin(originalVehicle, "transform " + originalVehicle->getTagStr() + " to " + toString(SUMO_TAG_VEHICLE));
1950
// first delete vehicle
1951
net->deleteDemandElement(originalVehicle, net->getViewNet()->getUndoList());
1952
// check if route has to be deleted
1953
if (route && route->getChildDemandElements().empty()) {
1954
net->deleteDemandElement(route, net->getViewNet()->getUndoList());
1955
}
1956
// change depart
1957
if (!originalVehicle->getTagProperty()->isFlow()) {
1958
// get template flow
1959
const auto templateFlow = net->getViewNet()->getNet()->getACTemplates()->getTemplateAC(GNE_TAG_FLOW_ROUTE);
1960
// set flow parameters
1961
vehicleParameters.repetitionEnd = vehicleParameters.depart + string2time("3600");
1962
vehicleParameters.repetitionNumber = GNEAttributeCarrier::parse<int>(templateFlow->getAttribute(SUMO_ATTR_NUMBER));
1963
vehicleParameters.repetitionOffset = string2time(templateFlow->getAttribute(SUMO_ATTR_PERIOD));
1964
vehicleParameters.repetitionProbability = GNEAttributeCarrier::parse<double>(templateFlow->getAttribute(SUMO_ATTR_PROB));
1965
// by default, number and end enabled
1966
vehicleParameters.parametersSet = GNEAttributeCarrier::parse<int>(templateFlow->getAttribute(GNE_ATTR_FLOWPARAMETERS));
1967
}
1968
// change tag in vehicle parameters
1969
vehicleParameters.tag = SUMO_TAG_FLOW;
1970
// create flow
1971
routeHandler.buildFlow(nullptr, vehicleParameters, edges.front()->getID(), edges.back()->getID());
1972
// end undo-redo operation
1973
net->getViewNet()->getUndoList()->end();
1974
// check if inspect
1975
if (inspectAfterTransform) {
1976
// get created element
1977
auto transformedVehicle = net->getAttributeCarriers()->retrieveDemandElement(vehicleParameters.tag, vehicleParameters.id);
1978
// inspect it
1979
net->getViewNet()->getViewParent()->getInspectorFrame()->inspectElement(transformedVehicle);
1980
}
1981
}
1982
}
1983
1984
1985
void
1986
GNERouteHandler::transformToTripJunctions(GNEVehicle* originalVehicle) {
1987
auto GNEApp = originalVehicle->getNet()->getGNEApplicationWindow();
1988
// only continue if number of junctions are valid
1989
if (originalVehicle->getParentJunctions().empty()) {
1990
// declare header
1991
const std::string header = "Problem transforming to trip over junctions";
1992
// declare message
1993
const std::string message = "Vehicle cannot be transformed. Invalid number of junctions";
1994
// open message box
1995
GNEWarningBasicDialog(GNEApp, header, message);
1996
} else {
1997
// get pointer to net
1998
GNENet* net = originalVehicle->getNet();
1999
// get TAZs before deleting vehicle
2000
const auto fromJunction = originalVehicle->getParentJunctions().front()->getID();
2001
const auto toJunction = originalVehicle->getParentJunctions().back()->getID();
2002
// check if transform after creation
2003
const bool inspectAfterTransform = net->getViewNet()->getInspectedElements().isACInspected(originalVehicle);
2004
// declare route handler
2005
GNERouteHandler routeHandler(net, originalVehicle->getFileBucket(), GNEApp->isUndoRedoAllowed(), true);
2006
// obtain vehicle parameters
2007
SUMOVehicleParameter vehicleParameters = *originalVehicle;
2008
// begin undo-redo operation
2009
net->getViewNet()->getUndoList()->begin(originalVehicle, "transform " + originalVehicle->getTagStr() + " to " + toString(GNE_TAG_TRIP_JUNCTIONS));
2010
// first delete vehicle
2011
net->deleteDemandElement(originalVehicle, net->getViewNet()->getUndoList());
2012
// change tag in vehicle parameters
2013
vehicleParameters.tag = GNE_TAG_TRIP_JUNCTIONS;
2014
// create trip
2015
routeHandler.buildTripJunctions(nullptr, vehicleParameters, fromJunction, toJunction);
2016
// end undo-redo operation
2017
net->getViewNet()->getUndoList()->end();
2018
// check if inspect
2019
if (inspectAfterTransform) {
2020
// get created element
2021
auto transformedVehicle = net->getAttributeCarriers()->retrieveDemandElement(vehicleParameters.tag, vehicleParameters.id);
2022
// inspect it
2023
net->getViewNet()->getViewParent()->getInspectorFrame()->inspectElement(transformedVehicle);
2024
}
2025
}
2026
}
2027
2028
2029
void
2030
GNERouteHandler::transformToFlowJunctions(GNEVehicle* originalVehicle) {
2031
auto GNEApp = originalVehicle->getNet()->getGNEApplicationWindow();
2032
// only continue if number of junctions are valid
2033
if (originalVehicle->getParentJunctions().empty()) {
2034
// declare header
2035
const std::string header = "Problem transforming to flow over junctions";
2036
// declare message
2037
const std::string message = "Vehicle cannot be transformed. Invalid number of junctions";
2038
// open message box
2039
GNEWarningBasicDialog(GNEApp, header, message);
2040
} else {
2041
// get pointer to net
2042
GNENet* net = originalVehicle->getNet();
2043
// get TAZs before deleting vehicle
2044
const auto fromJunction = originalVehicle->getParentJunctions().front()->getID();
2045
const auto toJunction = originalVehicle->getParentJunctions().back()->getID();
2046
// check if transform after creation
2047
const bool inspectAfterTransform = net->getViewNet()->getInspectedElements().isACInspected(originalVehicle);
2048
// declare route handler
2049
GNERouteHandler routeHandler(net, originalVehicle->getFileBucket(), GNEApp->isUndoRedoAllowed(), true);
2050
// obtain vehicle parameters
2051
SUMOVehicleParameter vehicleParameters = *originalVehicle;
2052
// begin undo-redo operation
2053
net->getViewNet()->getUndoList()->begin(originalVehicle, "transform " + originalVehicle->getTagStr() + " to " + toString(GNE_TAG_FLOW_JUNCTIONS));
2054
// first delete vehicle
2055
net->deleteDemandElement(originalVehicle, net->getViewNet()->getUndoList());
2056
// get template flow
2057
const auto templateFlow = net->getViewNet()->getNet()->getACTemplates()->getTemplateAC(GNE_TAG_FLOW_JUNCTIONS);
2058
// set flow parameters
2059
vehicleParameters.repetitionEnd = vehicleParameters.depart + string2time("3600");
2060
vehicleParameters.repetitionNumber = GNEAttributeCarrier::parse<int>(templateFlow->getAttribute(SUMO_ATTR_NUMBER));
2061
vehicleParameters.repetitionOffset = string2time(templateFlow->getAttribute(SUMO_ATTR_PERIOD));
2062
vehicleParameters.repetitionProbability = GNEAttributeCarrier::parse<double>(templateFlow->getAttribute(SUMO_ATTR_PROB));
2063
// by default, number and end enabled
2064
vehicleParameters.parametersSet = GNEAttributeCarrier::parse<int>(templateFlow->getAttribute(GNE_ATTR_FLOWPARAMETERS));
2065
// change tag in vehicle parameters
2066
vehicleParameters.tag = GNE_TAG_FLOW_JUNCTIONS;
2067
// create flow
2068
routeHandler.buildFlowJunctions(nullptr, vehicleParameters, fromJunction, toJunction);
2069
// end undo-redo operation
2070
net->getViewNet()->getUndoList()->end();
2071
// check if inspect
2072
if (inspectAfterTransform) {
2073
// get created element
2074
auto transformedVehicle = net->getAttributeCarriers()->retrieveDemandElement(vehicleParameters.tag, vehicleParameters.id);
2075
// inspect it
2076
net->getViewNet()->getViewParent()->getInspectorFrame()->inspectElement(transformedVehicle);
2077
}
2078
}
2079
}
2080
2081
2082
void
2083
GNERouteHandler::transformToTripTAZs(GNEVehicle* originalVehicle) {
2084
auto GNEApp = originalVehicle->getNet()->getGNEApplicationWindow();
2085
// only continue if number of junctions are valid
2086
if (originalVehicle->getParentAdditionals().empty()) {
2087
// declare header
2088
const std::string header = "Problem transforming to trip over TAZs";
2089
// declare message
2090
const std::string message = "Vehicle cannot be transformed. Invalid number of TAZs";
2091
// open message box
2092
GNEWarningBasicDialog(GNEApp, header, message);
2093
} else {
2094
// get pointer to net
2095
GNENet* net = originalVehicle->getNet();
2096
// get TAZs before deleting vehicle
2097
const auto fromTAZ = originalVehicle->getParentAdditionals().front()->getID();
2098
const auto toTAZ = originalVehicle->getParentAdditionals().back()->getID();
2099
// check if transform after creation
2100
const bool inspectAfterTransform = net->getViewNet()->getInspectedElements().isACInspected(originalVehicle);
2101
// declare route handler
2102
GNERouteHandler routeHandler(net, originalVehicle->getFileBucket(), GNEApp->isUndoRedoAllowed(), true);
2103
// obtain vehicle parameters
2104
SUMOVehicleParameter vehicleParameters = *originalVehicle;
2105
// begin undo-redo operation
2106
net->getViewNet()->getUndoList()->begin(originalVehicle, "transform " + originalVehicle->getTagStr() + " to " + toString(GNE_TAG_TRIP_TAZS));
2107
// first delete vehicle
2108
net->deleteDemandElement(originalVehicle, net->getViewNet()->getUndoList());
2109
// change tag in vehicle parameters
2110
vehicleParameters.tag = GNE_TAG_TRIP_TAZS;
2111
// create trip
2112
routeHandler.buildTripTAZs(nullptr, vehicleParameters, fromTAZ, toTAZ);
2113
// end undo-redo operation
2114
net->getViewNet()->getUndoList()->end();
2115
// check if inspect
2116
if (inspectAfterTransform) {
2117
// get created element
2118
auto transformedVehicle = net->getAttributeCarriers()->retrieveDemandElement(vehicleParameters.tag, vehicleParameters.id);
2119
// inspect it
2120
net->getViewNet()->getViewParent()->getInspectorFrame()->inspectElement(transformedVehicle);
2121
}
2122
}
2123
}
2124
2125
2126
void
2127
GNERouteHandler::transformToFlowTAZs(GNEVehicle* originalVehicle) {
2128
auto GNEApp = originalVehicle->getNet()->getGNEApplicationWindow();
2129
// only continue if number of junctions are valid
2130
if (originalVehicle->getParentAdditionals().empty()) {
2131
// declare header
2132
const std::string header = "Problem transforming to flow over TAZs";
2133
// declare message
2134
const std::string message = "Vehicle cannot be transformed. Invalid number of TAZs";
2135
// open message box
2136
GNEWarningBasicDialog(GNEApp, header, message);
2137
} else {
2138
// get pointer to net
2139
GNENet* net = originalVehicle->getNet();
2140
// get TAZs before deleting vehicle
2141
const auto fromTAZ = originalVehicle->getParentAdditionals().front()->getID();
2142
const auto toTAZ = originalVehicle->getParentAdditionals().back()->getID();
2143
// check if transform after creation
2144
const bool inspectAfterTransform = net->getViewNet()->getInspectedElements().isACInspected(originalVehicle);
2145
// declare route handler
2146
GNERouteHandler routeHandler(net, originalVehicle->getFileBucket(), GNEApp->isUndoRedoAllowed(), true);
2147
// obtain vehicle parameters
2148
SUMOVehicleParameter vehicleParameters = *originalVehicle;
2149
// begin undo-redo operation
2150
net->getViewNet()->getUndoList()->begin(originalVehicle, "transform " + originalVehicle->getTagStr() + " to " + toString(GNE_TAG_FLOW_TAZS));
2151
// first delete vehicle
2152
net->deleteDemandElement(originalVehicle, net->getViewNet()->getUndoList());
2153
// get template flow
2154
const auto templateFlow = net->getViewNet()->getNet()->getACTemplates()->getTemplateAC(GNE_TAG_FLOW_TAZS);
2155
// set flow parameters
2156
vehicleParameters.repetitionEnd = vehicleParameters.depart + string2time("3600");
2157
vehicleParameters.repetitionNumber = GNEAttributeCarrier::parse<int>(templateFlow->getAttribute(SUMO_ATTR_NUMBER));
2158
vehicleParameters.repetitionOffset = string2time(templateFlow->getAttribute(SUMO_ATTR_PERIOD));
2159
vehicleParameters.repetitionProbability = GNEAttributeCarrier::parse<double>(templateFlow->getAttribute(SUMO_ATTR_PROB));
2160
// by default, number and end enabled
2161
vehicleParameters.parametersSet = GNEAttributeCarrier::parse<int>(templateFlow->getAttribute(GNE_ATTR_FLOWPARAMETERS));
2162
// change tag in vehicle parameters
2163
vehicleParameters.tag = GNE_TAG_FLOW_TAZS;
2164
// create flow
2165
routeHandler.buildFlowTAZs(nullptr, vehicleParameters, fromTAZ, toTAZ);
2166
// end undo-redo operation
2167
net->getViewNet()->getUndoList()->end();
2168
// check if inspect
2169
if (inspectAfterTransform) {
2170
// get created element
2171
auto transformedVehicle = net->getAttributeCarriers()->retrieveDemandElement(vehicleParameters.tag, vehicleParameters.id);
2172
// inspect it
2173
net->getViewNet()->getViewParent()->getInspectorFrame()->inspectElement(transformedVehicle);
2174
}
2175
}
2176
}
2177
2178
2179
void
2180
GNERouteHandler::transformToPerson(GNEPerson* originalPerson) {
2181
// get pointer to net
2182
GNENet* net = originalPerson->getNet();
2183
// check if transform after creation
2184
const bool inspectAfterTransform = net->getViewNet()->getInspectedElements().isACInspected(originalPerson);
2185
// declare route handler
2186
GNERouteHandler routeHandler(net, originalPerson->getFileBucket(), net->getGNEApplicationWindow()->isUndoRedoAllowed(), false);
2187
// obtain person parameters
2188
SUMOVehicleParameter personParameters = *originalPerson;
2189
// save ID
2190
const auto ID = personParameters.id;
2191
// set dummy ID
2192
personParameters.id = "%dummyID%";
2193
// begin undo-redo operation
2194
net->getViewNet()->getUndoList()->begin(originalPerson, "transform " + originalPerson->getTagStr() + " to " + toString(SUMO_TAG_PERSON));
2195
// create personFlow and get it
2196
routeHandler.buildPerson(nullptr, personParameters);
2197
auto newPerson = net->getAttributeCarriers()->retrieveDemandElement(SUMO_TAG_PERSON, "%dummyID%");
2198
// duplicate plans in new person
2199
for (const auto& personPlan : originalPerson->getChildDemandElements()) {
2200
routeHandler.duplicatePlan(personPlan, newPerson);
2201
}
2202
// delete original person plan
2203
net->deleteDemandElement(originalPerson, net->getViewNet()->getUndoList());
2204
// restore ID of new person plan
2205
newPerson->setAttribute(SUMO_ATTR_ID, ID, net->getViewNet()->getUndoList());
2206
// finish undoList
2207
net->getViewNet()->getUndoList()->end();
2208
// check if inspect
2209
if (inspectAfterTransform) {
2210
net->getViewNet()->getViewParent()->getInspectorFrame()->inspectElement(newPerson);
2211
}
2212
}
2213
2214
2215
void
2216
GNERouteHandler::transformToPersonFlow(GNEPerson* originalPerson) {
2217
// get pointer to net
2218
GNENet* net = originalPerson->getNet();
2219
// check if transform after creation
2220
const bool inspectAfterTransform = net->getViewNet()->getInspectedElements().isACInspected(originalPerson);
2221
// declare route handler
2222
GNERouteHandler routeHandler(net, originalPerson->getFileBucket(), net->getGNEApplicationWindow()->isUndoRedoAllowed(), false);
2223
// obtain person parameters
2224
SUMOVehicleParameter personParameters = *originalPerson;
2225
// get person plans
2226
const auto personPlans = originalPerson->getChildDemandElements();
2227
// save ID
2228
const auto ID = personParameters.id;
2229
// set dummy ID
2230
personParameters.id = "%dummyID%";
2231
// begin undo-redo operation
2232
net->getViewNet()->getUndoList()->begin(originalPerson, "transform " + originalPerson->getTagStr() + " to " + toString(SUMO_TAG_PERSONFLOW));
2233
// create personFlow and get it
2234
routeHandler.buildPersonFlow(nullptr, personParameters);
2235
auto newPerson = net->getAttributeCarriers()->retrieveDemandElement(SUMO_TAG_PERSONFLOW, "%dummyID%");
2236
// move all person plans to new person
2237
for (const auto& personPlan : personPlans) {
2238
routeHandler.duplicatePlan(personPlan, newPerson);
2239
}
2240
// delete original person plan
2241
net->deleteDemandElement(originalPerson, net->getViewNet()->getUndoList());
2242
// restore ID of new person plan
2243
newPerson->setAttribute(SUMO_ATTR_ID, ID, net->getViewNet()->getUndoList());
2244
// enable attributes
2245
newPerson->enableAttribute(SUMO_ATTR_END, net->getViewNet()->getUndoList());
2246
newPerson->enableAttribute(SUMO_ATTR_PERSONSPERHOUR, net->getViewNet()->getUndoList());
2247
// finish undoList
2248
net->getViewNet()->getUndoList()->end();
2249
// check if inspect
2250
if (inspectAfterTransform) {
2251
net->getViewNet()->getViewParent()->getInspectorFrame()->inspectElement(newPerson);
2252
}
2253
}
2254
2255
2256
void
2257
GNERouteHandler::transformToContainer(GNEContainer* originalContainer) {
2258
// get pointer to net
2259
GNENet* net = originalContainer->getNet();
2260
// check if transform after creation
2261
const bool inspectAfterTransform = net->getViewNet()->getInspectedElements().isACInspected(originalContainer);
2262
// declare route handler
2263
GNERouteHandler routeHandler(net, originalContainer->getFileBucket(), net->getGNEApplicationWindow()->isUndoRedoAllowed(), false);
2264
// obtain container parameters
2265
SUMOVehicleParameter containerParameters = *originalContainer;
2266
// get container plans
2267
const auto containerPlans = originalContainer->getChildDemandElements();
2268
// save ID
2269
const auto ID = containerParameters.id;
2270
// set dummy ID
2271
containerParameters.id = "%dummyID%";
2272
// begin undo-redo operation
2273
net->getViewNet()->getUndoList()->begin(originalContainer, "transform " + originalContainer->getTagStr() + " to " + toString(SUMO_TAG_CONTAINER));
2274
// create containerFlow
2275
routeHandler.buildContainer(nullptr, containerParameters);
2276
// move all container plans to new container
2277
for (const auto& containerPlan : containerPlans) {
2278
containerPlan->setAttribute(GNE_ATTR_PARENT, "%dummyID%", net->getViewNet()->getUndoList());
2279
}
2280
// delete original container plan
2281
net->deleteDemandElement(originalContainer, net->getViewNet()->getUndoList());
2282
// restore ID of new container plan
2283
auto newContainer = net->getAttributeCarriers()->retrieveDemandElement(SUMO_TAG_CONTAINER, "%dummyID%");
2284
newContainer->setAttribute(SUMO_ATTR_ID, ID, net->getViewNet()->getUndoList());
2285
// finish undoList
2286
net->getViewNet()->getUndoList()->end();
2287
// check if inspect
2288
if (inspectAfterTransform) {
2289
net->getViewNet()->getViewParent()->getInspectorFrame()->inspectElement(newContainer);
2290
}
2291
}
2292
2293
2294
void
2295
GNERouteHandler::transformToContainerFlow(GNEContainer* originalContainer) {
2296
// get pointer to net
2297
GNENet* net = originalContainer->getNet();
2298
// check if transform after creation
2299
const bool inspectAfterTransform = net->getViewNet()->getInspectedElements().isACInspected(originalContainer);
2300
// declare route handler
2301
GNERouteHandler routeHandler(net, originalContainer->getFileBucket(), net->getGNEApplicationWindow()->isUndoRedoAllowed(), false);
2302
// obtain container parameters
2303
SUMOVehicleParameter containerParameters = *originalContainer;
2304
// get container plans
2305
const auto containerPlans = originalContainer->getChildDemandElements();
2306
// save ID
2307
const auto ID = containerParameters.id;
2308
// set dummy ID
2309
containerParameters.id = "%dummyID%";
2310
// begin undo-redo operation
2311
net->getViewNet()->getUndoList()->begin(originalContainer, "transform " + originalContainer->getTagStr() + " to " + toString(SUMO_TAG_CONTAINERFLOW));
2312
// create containerFlow
2313
routeHandler.buildContainerFlow(nullptr, containerParameters);
2314
// move all container plans to new container
2315
for (const auto& containerPlan : containerPlans) {
2316
containerPlan->setAttribute(GNE_ATTR_PARENT, "%dummyID%", net->getViewNet()->getUndoList());
2317
}
2318
// delete original container plan
2319
net->deleteDemandElement(originalContainer, net->getViewNet()->getUndoList());
2320
// restore ID of new container plan
2321
auto newContainer = net->getAttributeCarriers()->retrieveDemandElement(SUMO_TAG_CONTAINERFLOW, "%dummyID%");
2322
newContainer->setAttribute(SUMO_ATTR_ID, ID, net->getViewNet()->getUndoList());
2323
// enable attributes
2324
newContainer->enableAttribute(SUMO_ATTR_END, net->getViewNet()->getUndoList());
2325
newContainer->enableAttribute(SUMO_ATTR_CONTAINERSPERHOUR, net->getViewNet()->getUndoList());
2326
// finish undoList
2327
net->getViewNet()->getUndoList()->end();
2328
// check if inspect
2329
if (inspectAfterTransform) {
2330
net->getViewNet()->getViewParent()->getInspectorFrame()->inspectElement(newContainer);
2331
}
2332
}
2333
2334
2335
bool
2336
GNERouteHandler::canReverse(const GNEDemandElement* element) {
2337
// continue depending of element
2338
if (element->getTagProperty()->getTag() == SUMO_TAG_ROUTE) {
2339
return canReverse(element->getNet(), SVC_PEDESTRIAN, element->getParentEdges());
2340
} else if (element->getTagProperty()->vehicleRoute()) {
2341
return canReverse(element->getNet(), element->getVClass(), element->getParentDemandElements().at(1)->getParentEdges());
2342
} else if (element->getTagProperty()->vehicleRouteEmbedded()) {
2343
return canReverse(element->getNet(), element->getVClass(), element->getChildDemandElements().front()->getParentEdges());
2344
} else if (element->getTagProperty()->vehicleEdges()) {
2345
return canReverse(element->getNet(), element->getVClass(), element->getParentEdges());
2346
} else if (element->getTagProperty()->vehicleJunctions()) {
2347
return (element->getNet()->getDemandPathManager()->getPathCalculator()->calculateDijkstraPath(element->getVClass(),
2348
element->getParentJunctions().back(), element->getParentJunctions().front()).size() > 0);
2349
} else if (element->getTagProperty()->vehicleTAZs()) {
2350
return true;
2351
} else {
2352
return false;
2353
}
2354
}
2355
2356
2357
bool
2358
GNERouteHandler::canReverse(GNENet* net, SUMOVehicleClass vClass, const std::vector<GNEEdge*>& edges) {
2359
if (edges.empty()) {
2360
return false;
2361
} else {
2362
// obtain opposite edges
2363
std::vector<GNEEdge*> reverseEdges;
2364
for (const auto& edge : edges) {
2365
const auto oppositeEdges = edge->getOppositeEdges();
2366
// stop if there isn't opposite edges for the current edge
2367
if (oppositeEdges.empty()) {
2368
return false;
2369
} else {
2370
reverseEdges.push_back(oppositeEdges.front());
2371
}
2372
}
2373
// reverse edges
2374
std::reverse(reverseEdges.begin(), reverseEdges.end());
2375
// now check if exist a path
2376
return (net->getDemandPathManager()->getPathCalculator()->calculateDijkstraPath(vClass, edges).size() > 0);
2377
}
2378
}
2379
2380
2381
void
2382
GNERouteHandler::reverse(GNEDemandElement* element) {
2383
// get undo list
2384
auto undoList = element->getNet()->getUndoList();
2385
// continue depending of element
2386
if (element->getTagProperty()->vehicleRoute()) {
2387
// reverse parent route
2388
reverse(element->getParentDemandElements().at(1));
2389
} else if (element->getTagProperty()->vehicleRouteEmbedded()) {
2390
// reverse embedded route
2391
reverse(element->getChildDemandElements().front());
2392
} else if (element->getTagProperty()->vehicleJunctions()) {
2393
// get from to junctions
2394
const auto fromJunction = element->getAttribute(SUMO_ATTR_FROM_JUNCTION);
2395
const auto toJunction = element->getAttribute(SUMO_ATTR_TO_JUNCTION);
2396
// swap both attributes
2397
element->setAttribute(SUMO_ATTR_FROM_JUNCTION, toJunction, undoList);
2398
element->setAttribute(SUMO_ATTR_TO_JUNCTION, fromJunction, undoList);
2399
} else if (element->getTagProperty()->vehicleTAZs()) {
2400
// get from to TAZs
2401
const auto fromTAZ = element->getAttribute(SUMO_ATTR_FROM_TAZ);
2402
const auto toTAZ = element->getAttribute(SUMO_ATTR_TO_TAZ);
2403
// swap both attributes
2404
element->setAttribute(SUMO_ATTR_FROM_TAZ, toTAZ, undoList);
2405
element->setAttribute(SUMO_ATTR_TO_TAZ, fromTAZ, undoList);
2406
} else {
2407
// extract and reverse opposite edges
2408
std::vector<GNEEdge*> oppositeEdges;
2409
for (const auto& edge : element->getParentEdges()) {
2410
oppositeEdges.push_back(edge->getOppositeEdges().front());
2411
}
2412
std::reverse(oppositeEdges.begin(), oppositeEdges.end());
2413
if (element->isRoute()) {
2414
element->setAttribute(SUMO_ATTR_EDGES, GNEAttributeCarrier::parseIDs(oppositeEdges), undoList);
2415
} else {
2416
// set from and to
2417
element->setAttribute(SUMO_ATTR_FROM, oppositeEdges.front()->getID(), undoList);
2418
element->setAttribute(SUMO_ATTR_TO, oppositeEdges.back()->getID(), undoList);
2419
// check if add via attribute
2420
oppositeEdges.erase(oppositeEdges.begin());
2421
oppositeEdges.pop_back();
2422
if (oppositeEdges.size() > 0) {
2423
element->setAttribute(SUMO_ATTR_VIA, GNEAttributeCarrier::parseIDs(oppositeEdges), undoList);
2424
}
2425
}
2426
}
2427
}
2428
2429
2430
void
2431
GNERouteHandler::addReverse(GNEDemandElement* element) {
2432
GNEDemandElement* elementCopy = nullptr;
2433
if (element->getTagProperty()->getTag() == SUMO_TAG_ROUTE) {
2434
// make a copy of the route and reverse
2435
elementCopy = GNERoute::copyRoute(dynamic_cast<GNERoute*>(element));
2436
} else if (element->getTagProperty()->isVehicle()) {
2437
// make a copy of the vehicle
2438
elementCopy = GNEVehicle::copyVehicle(dynamic_cast<GNEVehicle*>(element));
2439
}
2440
// reverse copied element
2441
reverse(elementCopy);
2442
}
2443
2444
// ===========================================================================
2445
// protected
2446
// ===========================================================================
2447
2448
GNEJunction*
2449
GNERouteHandler::parseJunction(const SumoXMLTag tag, const std::string& id, const std::string& junctionID) {
2450
GNEJunction* junction = myNet->getAttributeCarriers()->retrieveJunction(junctionID, false);
2451
// empty junctions aren't allowed. If junction is empty, write error, clear junctions and stop
2452
if (junction == nullptr) {
2453
writeErrorInvalidParent(tag, id, {SUMO_TAG_JUNCTION}, junctionID);
2454
}
2455
return junction;
2456
}
2457
2458
2459
GNEAdditional*
2460
GNERouteHandler::parseTAZ(const SumoXMLTag tag, const std::string& id, const std::string& TAZID) {
2461
GNEAdditional* TAZ = myNet->getAttributeCarriers()->retrieveAdditional(SUMO_TAG_TAZ, TAZID, false);
2462
// empty TAZs aren't allowed. If TAZ is empty, write error, clear TAZs and stop
2463
if (TAZ == nullptr) {
2464
writeErrorInvalidParent(tag, id, {SUMO_TAG_TAZ}, TAZID);
2465
}
2466
return TAZ;
2467
}
2468
2469
2470
GNEEdge*
2471
GNERouteHandler::parseEdge(const SumoXMLTag tag, const std::string& id, const std::string& edgeID,
2472
const CommonXMLStructure::SumoBaseObject* sumoBaseObject,
2473
const bool firstEdge) {
2474
GNEEdge* edge = nullptr;
2475
if (edgeID.empty()) {
2476
if (sumoBaseObject->getSumoBaseObjectChildren().size() > 0) {
2477
const auto frontTag = sumoBaseObject->getSumoBaseObjectChildren().front()->getTag();
2478
const auto backTag = sumoBaseObject->getSumoBaseObjectChildren().back()->getTag();
2479
if (firstEdge && ((frontTag == SUMO_TAG_STOP) || (frontTag == SUMO_TAG_TRAIN_STOP) ||
2480
(frontTag == SUMO_TAG_CONTAINER_STOP) || (frontTag == SUMO_TAG_CHARGING_STATION) ||
2481
(frontTag == SUMO_TAG_PARKING_AREA))) {
2482
edge = parseStopEdge(sumoBaseObject->getSumoBaseObjectChildren().front());
2483
} else if (!firstEdge && ((backTag == SUMO_TAG_STOP) || (backTag == SUMO_TAG_TRAIN_STOP) ||
2484
(backTag == SUMO_TAG_CONTAINER_STOP) || (backTag == SUMO_TAG_CHARGING_STATION) ||
2485
(backTag == SUMO_TAG_PARKING_AREA))) {
2486
edge = parseStopEdge(sumoBaseObject->getSumoBaseObjectChildren().back());
2487
}
2488
}
2489
} else {
2490
edge = myNet->getAttributeCarriers()->retrieveEdge(edgeID, false);
2491
}
2492
// write info if edge doesn't exist
2493
if (edge == nullptr) {
2494
writeErrorInvalidParent(tag, id, {SUMO_TAG_EDGE}, edgeID);
2495
}
2496
return edge;
2497
}
2498
2499
2500
GNEEdge*
2501
GNERouteHandler::parseStopEdge(const CommonXMLStructure::SumoBaseObject* sumoBaseObject) const {
2502
if (sumoBaseObject->hasStringAttribute(SUMO_ATTR_EDGE)) {
2503
return myNet->getAttributeCarriers()->retrieveEdge(sumoBaseObject->getStringAttribute(SUMO_ATTR_EDGE), false);
2504
} else if (sumoBaseObject->hasStringAttribute(SUMO_ATTR_LANE)) {
2505
return parseEdgeFromLaneID(sumoBaseObject->getStringAttribute(SUMO_ATTR_LANE));
2506
} else if (sumoBaseObject->hasStringAttribute(SUMO_ATTR_BUS_STOP)) {
2507
const auto busStop = myNet->getAttributeCarriers()->retrieveAdditional(SUMO_TAG_BUS_STOP, sumoBaseObject->getStringAttribute(SUMO_ATTR_BUS_STOP), false);
2508
const auto trainStop = myNet->getAttributeCarriers()->retrieveAdditional(SUMO_TAG_TRAIN_STOP, sumoBaseObject->getStringAttribute(SUMO_ATTR_BUS_STOP), false);
2509
if (busStop != nullptr) {
2510
return busStop->getParentLanes().front()->getParentEdge();
2511
} else if (trainStop != nullptr) {
2512
return trainStop->getParentLanes().front()->getParentEdge();
2513
} else {
2514
return nullptr;
2515
}
2516
} else if (sumoBaseObject->hasStringAttribute(SUMO_ATTR_TRAIN_STOP)) {
2517
const auto busStop = myNet->getAttributeCarriers()->retrieveAdditional(SUMO_TAG_BUS_STOP, sumoBaseObject->getStringAttribute(SUMO_ATTR_TRAIN_STOP), false);
2518
const auto trainStop = myNet->getAttributeCarriers()->retrieveAdditional(SUMO_TAG_TRAIN_STOP, sumoBaseObject->getStringAttribute(SUMO_ATTR_TRAIN_STOP), false);
2519
if (busStop != nullptr) {
2520
return busStop->getParentLanes().front()->getParentEdge();
2521
} else if (trainStop != nullptr) {
2522
return trainStop->getParentLanes().front()->getParentEdge();
2523
} else {
2524
return nullptr;
2525
}
2526
} else if (sumoBaseObject->hasStringAttribute(SUMO_ATTR_CONTAINER_STOP)) {
2527
const auto containerStop = myNet->getAttributeCarriers()->retrieveAdditional(SUMO_TAG_CONTAINER_STOP, sumoBaseObject->getStringAttribute(SUMO_ATTR_CONTAINER_STOP), false);
2528
if (containerStop != nullptr) {
2529
return containerStop->getParentLanes().front()->getParentEdge();
2530
} else {
2531
return nullptr;
2532
}
2533
2534
} else if (sumoBaseObject->hasStringAttribute(SUMO_ATTR_CHARGING_STATION)) {
2535
const auto containerStop = myNet->getAttributeCarriers()->retrieveAdditional(SUMO_TAG_CHARGING_STATION, sumoBaseObject->getStringAttribute(SUMO_ATTR_CHARGING_STATION), false);
2536
if (containerStop != nullptr) {
2537
return containerStop->getParentLanes().front()->getParentEdge();
2538
} else {
2539
return nullptr;
2540
}
2541
2542
} else if (sumoBaseObject->hasStringAttribute(SUMO_ATTR_PARKING_AREA)) {
2543
const auto parkingArea = myNet->getAttributeCarriers()->retrieveAdditional(SUMO_TAG_PARKING_AREA, sumoBaseObject->getStringAttribute(SUMO_ATTR_PARKING_AREA), false);
2544
if (parkingArea != nullptr) {
2545
return parkingArea->getParentLanes().front()->getParentEdge();
2546
} else {
2547
return nullptr;
2548
}
2549
} else {
2550
return nullptr;
2551
}
2552
}
2553
2554
2555
GNEEdge*
2556
GNERouteHandler::parseEdgeFromLaneID(const std::string& laneID) const {
2557
std::string edgeID = laneID;
2558
for (int i = ((int)laneID.size() - 1); (i >= 0) && (laneID[i + 1] != '_'); i--) {
2559
edgeID.pop_back();
2560
}
2561
return myNet->getAttributeCarriers()->retrieveEdge(edgeID, false);
2562
}
2563
2564
2565
std::vector<GNEEdge*>
2566
GNERouteHandler::parseEdges(const SumoXMLTag tag, const std::string& id, const std::vector<std::string>& edgeIDs) {
2567
std::vector<GNEEdge*> edges;
2568
for (const auto& edgeID : edgeIDs) {
2569
GNEEdge* edge = myNet->getAttributeCarriers()->retrieveEdge(edgeID, false);
2570
// empty edges aren't allowed. If edge is empty, write error, clear edges and stop
2571
if (edge == nullptr) {
2572
writeError(TLF("Could not build % with ID '%' in netedit; % with ID '%' doesn't exist.", toString(tag), id, toString(SUMO_TAG_EDGE), edgeID));
2573
edges.clear();
2574
return edges;
2575
} else {
2576
edges.push_back(edge);
2577
}
2578
}
2579
return edges;
2580
}
2581
2582
2583
GNEDemandElement*
2584
GNERouteHandler::getType(const std::string& id) const {
2585
GNEDemandElement* type = myNet->getAttributeCarriers()->retrieveDemandElement(SUMO_TAG_VTYPE, id, false);
2586
if (type == nullptr) {
2587
return myNet->getAttributeCarriers()->retrieveDemandElement(SUMO_TAG_VTYPE_DISTRIBUTION, id, false);
2588
} else {
2589
return type;
2590
}
2591
}
2592
2593
2594
GNEDemandElement*
2595
GNERouteHandler::getRoute(const std::string& id) const {
2596
GNEDemandElement* type = myNet->getAttributeCarriers()->retrieveDemandElement(SUMO_TAG_ROUTE, id, false);
2597
if (type == nullptr) {
2598
return myNet->getAttributeCarriers()->retrieveDemandElement(SUMO_TAG_ROUTE_DISTRIBUTION, id, false);
2599
} else {
2600
return type;
2601
}
2602
}
2603
2604
2605
GNEDemandElement*
2606
GNERouteHandler::getPersonParent(const CommonXMLStructure::SumoBaseObject* sumoBaseObject) const {
2607
// check that sumoBaseObject has parent
2608
if (sumoBaseObject->getParentSumoBaseObject() == nullptr) {
2609
return nullptr;
2610
}
2611
if ((sumoBaseObject->getParentSumoBaseObject()->getTag() != SUMO_TAG_PERSON) &&
2612
(sumoBaseObject->getParentSumoBaseObject()->getTag() != SUMO_TAG_PERSONFLOW)) {
2613
return nullptr;
2614
}
2615
// try it with person
2616
GNEDemandElement* personParent = myNet->getAttributeCarriers()->retrieveDemandElement(SUMO_TAG_PERSON, sumoBaseObject->getParentSumoBaseObject()->getStringAttribute(SUMO_ATTR_ID), false);
2617
// if empty, try it with personFlow
2618
if (personParent == nullptr) {
2619
return myNet->getAttributeCarriers()->retrieveDemandElement(SUMO_TAG_PERSONFLOW, sumoBaseObject->getParentSumoBaseObject()->getStringAttribute(SUMO_ATTR_ID), false);
2620
} else {
2621
return personParent;
2622
}
2623
}
2624
2625
2626
GNEDemandElement*
2627
GNERouteHandler::getContainerParent(const CommonXMLStructure::SumoBaseObject* sumoBaseObject) const {
2628
// check that sumoBaseObject has parent
2629
if (sumoBaseObject->getParentSumoBaseObject() == nullptr) {
2630
return nullptr;
2631
}
2632
if ((sumoBaseObject->getParentSumoBaseObject()->getTag() != SUMO_TAG_CONTAINER) &&
2633
(sumoBaseObject->getParentSumoBaseObject()->getTag() != SUMO_TAG_CONTAINERFLOW)) {
2634
return nullptr;
2635
}
2636
// try it with container
2637
GNEDemandElement* containerParent = myNet->getAttributeCarriers()->retrieveDemandElement(SUMO_TAG_CONTAINER, sumoBaseObject->getParentSumoBaseObject()->getStringAttribute(SUMO_ATTR_ID), false);
2638
// if empty, try it with containerFlow
2639
if (containerParent == nullptr) {
2640
return myNet->getAttributeCarriers()->retrieveDemandElement(SUMO_TAG_CONTAINERFLOW, sumoBaseObject->getParentSumoBaseObject()->getStringAttribute(SUMO_ATTR_ID), false);
2641
} else {
2642
return containerParent;
2643
}
2644
}
2645
2646
2647
GNEDemandElement*
2648
GNERouteHandler::getRouteDistributionParent(const CommonXMLStructure::SumoBaseObject* sumoBaseObject) const {
2649
// check that sumoBaseObject has parent
2650
if (sumoBaseObject->getParentSumoBaseObject() == nullptr) {
2651
return nullptr;
2652
}
2653
if (sumoBaseObject->getParentSumoBaseObject()->getTag() != SUMO_TAG_ROUTE_DISTRIBUTION) {
2654
return nullptr;
2655
}
2656
return myNet->getAttributeCarriers()->retrieveDemandElement(SUMO_TAG_ROUTE_DISTRIBUTION, sumoBaseObject->getParentSumoBaseObject()->getStringAttribute(SUMO_ATTR_ID), false);
2657
}
2658
2659
2660
GNEDemandElement*
2661
GNERouteHandler::getVTypeDistributionParent(const CommonXMLStructure::SumoBaseObject* sumoBaseObject) const {
2662
// check that sumoBaseObject has parent
2663
if (sumoBaseObject->getParentSumoBaseObject() == nullptr) {
2664
return nullptr;
2665
}
2666
if (sumoBaseObject->getParentSumoBaseObject()->getTag() != SUMO_TAG_VTYPE_DISTRIBUTION) {
2667
return nullptr;
2668
}
2669
return myNet->getAttributeCarriers()->retrieveDemandElement(SUMO_TAG_VTYPE_DISTRIBUTION, sumoBaseObject->getParentSumoBaseObject()->getStringAttribute(SUMO_ATTR_ID), false);
2670
}
2671
2672
2673
bool
2674
GNERouteHandler::getDistributionElements(const CommonXMLStructure::SumoBaseObject* sumoBaseObject, SumoXMLTag distributionElementTag,
2675
const std::vector<std::string>& distributionElementIDs, const std::vector<double>& probabilities,
2676
std::vector<const GNEDemandElement*>& elements) {
2677
// get distribution tag and ID
2678
std::string distributionTag = toString(sumoBaseObject->getTag());
2679
std::string distributionID = sumoBaseObject->getStringAttribute(SUMO_ATTR_ID);
2680
// first parse vType IDs
2681
for (const auto& distributionElementID : distributionElementIDs) {
2682
auto distributionElement = myNet->getAttributeCarriers()->retrieveDemandElement(distributionElementTag, distributionElementID, false);
2683
if (distributionElement) {
2684
elements.push_back(distributionElement);
2685
} else {
2686
return writeError(TLF("% with id '%' doesn't exist in % '%'", toString(distributionElementTag), distributionElementID, distributionTag, distributionID));
2687
}
2688
}
2689
// check probabilities
2690
for (const auto& probability : probabilities) {
2691
if (probability < 0) {
2692
return writeError(TLF("invalid probability % in % '%'", toString(probability), distributionTag, distributionID));
2693
}
2694
}
2695
// check that number of elements and probabilities is the same
2696
if (elements.size() != probabilities.size()) {
2697
return writeError(TLF("Invalid type distribution probabilities in % '%'. Must have the same number of elements", distributionTag, distributionID));
2698
} else {
2699
return true;
2700
}
2701
}
2702
2703
2704
GNEDemandElement*
2705
GNERouteHandler::retrieveDemandElement(const std::vector<SumoXMLTag> tags, const std::string& id) {
2706
for (const auto& tag : tags) {
2707
// retrieve demand element
2708
auto demandElement = myNet->getAttributeCarriers()->retrieveDemandElement(tag, id, false);
2709
if (demandElement) {
2710
return demandElement;
2711
}
2712
}
2713
return nullptr;
2714
}
2715
2716
2717
bool
2718
GNERouteHandler::checkElement(const SumoXMLTag tag, GNEDemandElement* demandElement) {
2719
if (demandElement) {
2720
if (myOverwriteElements) {
2721
// delete element
2722
myNet->deleteDemandElement(demandElement, myNet->getUndoList());
2723
} else if (myRemainElements) {
2724
// duplicated demand
2725
return writeWarningDuplicated(tag, demandElement->getID(), demandElement->getTagProperty()->getTag());
2726
} else {
2727
// open overwrite dialog
2728
GNEOverwriteElement overwriteElementDialog(this, demandElement);
2729
// continue depending of result
2730
if (overwriteElementDialog.getResult() == GNEOverwriteElement::Result::ACCEPT) {
2731
// delete element
2732
myNet->deleteDemandElement(demandElement, myNet->getUndoList());
2733
} else if (overwriteElementDialog.getResult() == GNEOverwriteElement::Result::CANCEL) {
2734
// duplicated demand
2735
return writeWarningDuplicated(tag, demandElement->getID(), demandElement->getTagProperty()->getTag());
2736
} else {
2737
return false;
2738
}
2739
}
2740
}
2741
return true;
2742
}
2743
2744
/****************************************************************************/
2745
2746