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