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