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